diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000..f9a8b1f29
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,12 @@
+# Default Linux style
+BasedOnStyle: LLVM
+IndentWidth: 4
+UseTab: Never
+BreakBeforeBraces: Linux
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+
+# From CodingReadme
+TabWidth: 4
+ContinuationIndentWidth: 2
+ColumnLimit: 150
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..01caaf812
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,16 @@
+# Editor config file, see http://editorconfig.org/
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{h,cc,tcl}]
+indent_style = space
+indent_size = 4
+
+[*.{v,sv}]
+indent_style = space
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index bfeca7e24..ae742ddb7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1 +1,11 @@
-/.gitcommit export-subst
+/.gitcommit export-subst
+
+# Settings to improve linguist data reporting (used by GitHub)
+*.v                     linguist-language=Verilog
+*.vh                    linguist-language=Verilog
+*.sql                   linguist-language=SQL
+
+third_party/**          linguist-vendored
+
+# FIXME: All vendor files should be under third_party
+yosys-plugins/xdc/tests/minilitex_ddr_arty/**     linguist-vendored
diff --git a/.github/scripts/build-and-test.sh b/.github/scripts/build-and-test.sh
new file mode 100755
index 000000000..958c79792
--- /dev/null
+++ b/.github/scripts/build-and-test.sh
@@ -0,0 +1,50 @@
+#! /bin/bash
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+set -e
+
+source .github/scripts/common.sh
+
+##########################################################################
+
+start_section Building
+
+export CXXFLAGS=-Werror
+make -C yosys-plugins UHDM_INSTALL_DIR=`pwd`/yosys-plugins/env/conda/envs/yosys-plugins/ plugins -j`nproc`
+unset CXXFLAGS
+
+end_section
+
+##########################################################################
+
+start_section Installing
+make -C yosys-plugins install -j`nproc`
+end_section
+
+##########################################################################
+
+start_section Testing
+make -C yosys-plugins test -j`nproc`
+end_section
+
+##########################################################################
+
+start_section Cleanup
+make -C yosys-plugins plugins_clean -j`nproc`
+end_section
+
+##########################################################################
diff --git a/.github/scripts/common.sh b/.github/scripts/common.sh
new file mode 100644
index 000000000..3da7cb093
--- /dev/null
+++ b/.github/scripts/common.sh
@@ -0,0 +1,54 @@
+#! /bin/bash
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# Look for location binaries first
+export PATH="$HOME/.local-bin/bin:$PATH"
+
+# OS X specific common setup
+if [[ "x${OS}" == "xmacOS" ]]; then
+	export PATH="/usr/local/opt/ccache/libexec:$PATH"
+fi
+
+# Parallel builds!
+MAKEFLAGS="-j 2"
+
+function action_fold() {
+	if [ "$1" = "start" ]; then
+		echo "::group::$2"
+		SECONDS=0
+	else
+		duration=$SECONDS
+		echo "::endgroup::"
+		printf "${GRAY}took $(($duration / 60)) min $(($duration % 60)) sec.${NC}\n"
+	fi
+	return 0;
+}
+
+function start_section() {
+	action_fold start "$1"
+	echo -e "${PURPLE}SymbiFlow Yosys Plugins${NC}: - $2${NC}"
+	echo -e "${GRAY}-------------------------------------------------------------------${NC}"
+}
+
+export -f start_section
+
+function end_section() {
+	echo -e "${GRAY}-------------------------------------------------------------------${NC}"
+	action_fold end "$1"
+}
+
+export -f end_section
diff --git a/.github/scripts/setup.sh b/.github/scripts/setup.sh
new file mode 100644
index 000000000..29bcb847a
--- /dev/null
+++ b/.github/scripts/setup.sh
@@ -0,0 +1,69 @@
+#! /bin/bash
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+set -e
+
+source .github/scripts/common.sh
+
+##########################################################################
+
+# Output status information.
+start_section Status
+(
+    set +e
+    set -x
+    git status
+    git branch -v
+    git log -n 5 --graph
+    git log --format=oneline -n 20 --graph
+)
+end_section
+
+##########################################################################
+
+# Update submodules
+start_section Submodules
+(
+    git submodule update --init --recursive
+)
+end_section
+
+##########################################################################
+
+#Install yosys
+start_section Install-Yosys
+(
+    echo '================================='
+    echo 'Making env with Yosys and Surelog'
+    echo '================================='
+    make -C yosys-plugins env
+    source yosys-plugins/env/conda/bin/activate yosys-plugins
+    conda list
+)
+end_section
+
+##########################################################################
+
+start_section Yosys-Version
+(
+    source yosys-plugins/env/conda/bin/activate yosys-plugins
+    echo $(which yosys)
+    echo $(which yosys-config)
+    echo $(yosys --version)
+    echo $(yosys-config --datdir)
+)
+end_section
diff --git a/.github/workflows/Pipeline.yml b/.github/workflows/Pipeline.yml
index 707b2de5c..f1540fe42 100644
--- a/.github/workflows/Pipeline.yml
+++ b/.github/workflows/Pipeline.yml
@@ -35,6 +35,13 @@ jobs:
 
       - name: Check Licenses
         uses: SymbiFlow/actions/checks@main
+        with:
+          exclude_license: |
+            ./yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.v
+            ./third_party/minilitex_ddr_arty/minilitex_ddr_arty.v
+            ./third_party/VexRiscv_Lite/VexRiscv_Lite.v
+          #third_party: |
+          #  ./third_party/googletest/
 
 
   Format:
@@ -276,3 +283,62 @@ jobs:
         run: |
           PYTHONPATH=$(pwd) python3 -m f4pga
           PYTHONPATH=$(pwd) python3 -m f4pga -h
+
+
+  Yosys-plugins:
+    name: 🔌 Plugins
+    runs-on: ubuntu-latest
+
+    steps:
+
+      - name: 🧰 Checkout
+        uses: actions/checkout@v3
+        with:
+          submodules: recursive
+
+      - name: 🐍 Setup Python
+        uses: actions/setup-python@v4
+
+      - name: 🔧 Install
+        run: |
+          sudo apt-get update
+          sudo apt-get install \
+            bison \
+            build-essential \
+            clang-format-8 \
+            cmake \
+            flex \
+            g++-9 \
+            gawk \
+            git \
+            graphviz \
+            libffi-dev \
+            libboost-system-dev \
+            libboost-python-dev \
+            libboost-filesystem-dev \
+            libreadline-dev \
+            pkg-config \
+            tcl-dev \
+            xdot \
+            zlib1g-dev
+
+      - name: Format
+        run: |
+          set -e
+          source .github/scripts/common.sh
+          make -C yosys-plugins format -j`nproc`
+          test $(git status --porcelain | wc -l) -eq 0 || { git diff; false; }
+
+      - name: ccache
+        uses: hendrikmuhs/ccache-action@v1
+
+      - name: 🔧 Install Yosys
+        run: |
+          export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
+          source .github/scripts/setup.sh
+
+      - name: 🚧 Build and test plugins
+        run: |
+          export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
+          source yosys-plugins/env/conda/bin/activate yosys-plugins
+          source .github/scripts/build-and-test.sh
diff --git a/.gitignore b/.gitignore
index 8310e6d86..8e043df08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,10 @@
 *.pyc
 *.sw*
 /f4pga/build/
+
+*.d
+*.o
+*.so
+*.swp
+*.log
+yosys-plugins/ql-qlf/pmgen/*
diff --git a/.gitmodules b/.gitmodules
index 1b8cf5c03..5163c4a72 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "third_party/make-env"]
 	path = third_party/make-env
-	url = https://github.com/SymbiFlow/make-env/
+	url = https://github.com/SymbiFlow/make-env
+[submodule "third_party/googletest"]
+	path = third_party/googletest
+	url = https://github.com/google/googletest
\ No newline at end of file
diff --git a/third_party/VexRiscv_Lite/LICENSE b/third_party/VexRiscv_Lite/LICENSE
new file mode 100644
index 000000000..0675e4424
--- /dev/null
+++ b/third_party/VexRiscv_Lite/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Spinal HDL contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/third_party/VexRiscv_Lite/README.yosys-symbiflow-plugins b/third_party/VexRiscv_Lite/README.yosys-symbiflow-plugins
new file mode 100644
index 000000000..534dcfa66
--- /dev/null
+++ b/third_party/VexRiscv_Lite/README.yosys-symbiflow-plugins
@@ -0,0 +1,9 @@
+Name: This repository hosts a RISC-V implementation written in SpinalHDL.
+Short Name: VexRiscv
+URL: https://github.com/SpinalHDL/VexRiscv
+Version: 0
+Date: 16/06/2019
+License: MIT License
+
+Description:
+This package is used as stimuli in some test cases that verify that the Yosys plugins produce expected results.
diff --git a/third_party/VexRiscv_Lite/VexRiscv_Lite.v b/third_party/VexRiscv_Lite/VexRiscv_Lite.v
new file mode 100644
index 000000000..2dc7b989c
--- /dev/null
+++ b/third_party/VexRiscv_Lite/VexRiscv_Lite.v
@@ -0,0 +1,4819 @@
+// Generator : SpinalHDL v1.3.6    git head : 9bf01e7f360e003fac1dd5ca8b8f4bffec0e52b8
+// Date      : 16/06/2019, 23:18:37
+// Component : VexRiscv
+
+
+`define AluCtrlEnum_defaultEncoding_type [1:0]
+`define AluCtrlEnum_defaultEncoding_ADD_SUB 2'b00
+`define AluCtrlEnum_defaultEncoding_SLT_SLTU 2'b01
+`define AluCtrlEnum_defaultEncoding_BITWISE 2'b10
+
+`define AluBitwiseCtrlEnum_defaultEncoding_type [1:0]
+`define AluBitwiseCtrlEnum_defaultEncoding_XOR_1 2'b00
+`define AluBitwiseCtrlEnum_defaultEncoding_OR_1 2'b01
+`define AluBitwiseCtrlEnum_defaultEncoding_AND_1 2'b10
+
+`define Src2CtrlEnum_defaultEncoding_type [1:0]
+`define Src2CtrlEnum_defaultEncoding_RS 2'b00
+`define Src2CtrlEnum_defaultEncoding_IMI 2'b01
+`define Src2CtrlEnum_defaultEncoding_IMS 2'b10
+`define Src2CtrlEnum_defaultEncoding_PC 2'b11
+
+`define BranchCtrlEnum_defaultEncoding_type [1:0]
+`define BranchCtrlEnum_defaultEncoding_INC 2'b00
+`define BranchCtrlEnum_defaultEncoding_B 2'b01
+`define BranchCtrlEnum_defaultEncoding_JAL 2'b10
+`define BranchCtrlEnum_defaultEncoding_JALR 2'b11
+
+`define Src1CtrlEnum_defaultEncoding_type [1:0]
+`define Src1CtrlEnum_defaultEncoding_RS 2'b00
+`define Src1CtrlEnum_defaultEncoding_IMU 2'b01
+`define Src1CtrlEnum_defaultEncoding_PC_INCREMENT 2'b10
+`define Src1CtrlEnum_defaultEncoding_URS1 2'b11
+
+`define EnvCtrlEnum_defaultEncoding_type [0:0]
+`define EnvCtrlEnum_defaultEncoding_NONE 1'b0
+`define EnvCtrlEnum_defaultEncoding_XRET 1'b1
+
+`define ShiftCtrlEnum_defaultEncoding_type [1:0]
+`define ShiftCtrlEnum_defaultEncoding_DISABLE_1 2'b00
+`define ShiftCtrlEnum_defaultEncoding_SLL_1 2'b01
+`define ShiftCtrlEnum_defaultEncoding_SRL_1 2'b10
+`define ShiftCtrlEnum_defaultEncoding_SRA_1 2'b11
+
+module InstructionCache (
+      input   io_flush,
+      input   io_cpu_prefetch_isValid,
+      output reg  io_cpu_prefetch_haltIt,
+      input  [31:0] io_cpu_prefetch_pc,
+      input   io_cpu_fetch_isValid,
+      input   io_cpu_fetch_isStuck,
+      input   io_cpu_fetch_isRemoved,
+      input  [31:0] io_cpu_fetch_pc,
+      output [31:0] io_cpu_fetch_data,
+      input   io_cpu_fetch_dataBypassValid,
+      input  [31:0] io_cpu_fetch_dataBypass,
+      output  io_cpu_fetch_mmuBus_cmd_isValid,
+      output [31:0] io_cpu_fetch_mmuBus_cmd_virtualAddress,
+      output  io_cpu_fetch_mmuBus_cmd_bypassTranslation,
+      input  [31:0] io_cpu_fetch_mmuBus_rsp_physicalAddress,
+      input   io_cpu_fetch_mmuBus_rsp_isIoAccess,
+      input   io_cpu_fetch_mmuBus_rsp_allowRead,
+      input   io_cpu_fetch_mmuBus_rsp_allowWrite,
+      input   io_cpu_fetch_mmuBus_rsp_allowExecute,
+      input   io_cpu_fetch_mmuBus_rsp_exception,
+      input   io_cpu_fetch_mmuBus_rsp_refilling,
+      output  io_cpu_fetch_mmuBus_end,
+      input   io_cpu_fetch_mmuBus_busy,
+      output [31:0] io_cpu_fetch_physicalAddress,
+      output  io_cpu_fetch_haltIt,
+      input   io_cpu_decode_isValid,
+      input   io_cpu_decode_isStuck,
+      input  [31:0] io_cpu_decode_pc,
+      output [31:0] io_cpu_decode_physicalAddress,
+      output [31:0] io_cpu_decode_data,
+      output  io_cpu_decode_cacheMiss,
+      output  io_cpu_decode_error,
+      output  io_cpu_decode_mmuRefilling,
+      output  io_cpu_decode_mmuException,
+      input   io_cpu_decode_isUser,
+      input   io_cpu_fill_valid,
+      input  [31:0] io_cpu_fill_payload,
+      output  io_mem_cmd_valid,
+      input   io_mem_cmd_ready,
+      output [31:0] io_mem_cmd_payload_address,
+      output [2:0] io_mem_cmd_payload_size,
+      input   io_mem_rsp_valid,
+      input  [31:0] io_mem_rsp_payload_data,
+      input   io_mem_rsp_payload_error,
+      input   clk,
+      input   reset);
+  reg [22:0] _zz_10_;
+  reg [31:0] _zz_11_;
+  wire  _zz_12_;
+  wire  _zz_13_;
+  wire [0:0] _zz_14_;
+  wire [0:0] _zz_15_;
+  wire [22:0] _zz_16_;
+  reg  _zz_1_;
+  reg  _zz_2_;
+  reg  lineLoader_fire;
+  reg  lineLoader_valid;
+  reg [31:0] lineLoader_address;
+  reg  lineLoader_hadError;
+  reg  lineLoader_flushPending;
+  reg [6:0] lineLoader_flushCounter;
+  reg  _zz_3_;
+  reg  lineLoader_cmdSent;
+  reg  lineLoader_wayToAllocate_willIncrement;
+  wire  lineLoader_wayToAllocate_willClear;
+  wire  lineLoader_wayToAllocate_willOverflowIfInc;
+  wire  lineLoader_wayToAllocate_willOverflow;
+  reg [2:0] lineLoader_wordIndex;
+  wire  lineLoader_write_tag_0_valid;
+  wire [5:0] lineLoader_write_tag_0_payload_address;
+  wire  lineLoader_write_tag_0_payload_data_valid;
+  wire  lineLoader_write_tag_0_payload_data_error;
+  wire [20:0] lineLoader_write_tag_0_payload_data_address;
+  wire  lineLoader_write_data_0_valid;
+  wire [8:0] lineLoader_write_data_0_payload_address;
+  wire [31:0] lineLoader_write_data_0_payload_data;
+  wire  _zz_4_;
+  wire [5:0] _zz_5_;
+  wire  _zz_6_;
+  wire  fetchStage_read_waysValues_0_tag_valid;
+  wire  fetchStage_read_waysValues_0_tag_error;
+  wire [20:0] fetchStage_read_waysValues_0_tag_address;
+  wire [22:0] _zz_7_;
+  wire [8:0] _zz_8_;
+  wire  _zz_9_;
+  wire [31:0] fetchStage_read_waysValues_0_data;
+  wire  fetchStage_hit_hits_0;
+  wire  fetchStage_hit_valid;
+  wire  fetchStage_hit_error;
+  wire [31:0] fetchStage_hit_data;
+  wire [31:0] fetchStage_hit_word;
+  reg [31:0] io_cpu_fetch_data_regNextWhen;
+  reg [31:0] decodeStage_mmuRsp_physicalAddress;
+  reg  decodeStage_mmuRsp_isIoAccess;
+  reg  decodeStage_mmuRsp_allowRead;
+  reg  decodeStage_mmuRsp_allowWrite;
+  reg  decodeStage_mmuRsp_allowExecute;
+  reg  decodeStage_mmuRsp_exception;
+  reg  decodeStage_mmuRsp_refilling;
+  reg  decodeStage_hit_valid;
+  reg  decodeStage_hit_error;
+  (* ram_style = "block" *) reg [22:0] ways_0_tags [0:63];
+  (* ram_style = "block" *) reg [31:0] ways_0_datas [0:511];
+  assign _zz_12_ = (! lineLoader_flushCounter[6]);
+  assign _zz_13_ = (lineLoader_flushPending && (! (lineLoader_valid || io_cpu_fetch_isValid)));
+  assign _zz_14_ = _zz_7_[0 : 0];
+  assign _zz_15_ = _zz_7_[1 : 1];
+  assign _zz_16_ = {lineLoader_write_tag_0_payload_data_address,{lineLoader_write_tag_0_payload_data_error,lineLoader_write_tag_0_payload_data_valid}};
+  always @ (posedge clk) begin
+    if(_zz_2_) begin
+      ways_0_tags[lineLoader_write_tag_0_payload_address] <= _zz_16_;
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(_zz_6_) begin
+      _zz_10_ <= ways_0_tags[_zz_5_];
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(_zz_1_) begin
+      ways_0_datas[lineLoader_write_data_0_payload_address] <= lineLoader_write_data_0_payload_data;
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(_zz_9_) begin
+      _zz_11_ <= ways_0_datas[_zz_8_];
+    end
+  end
+
+  always @ (*) begin
+    _zz_1_ = 1'b0;
+    if(lineLoader_write_data_0_valid)begin
+      _zz_1_ = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    _zz_2_ = 1'b0;
+    if(lineLoader_write_tag_0_valid)begin
+      _zz_2_ = 1'b1;
+    end
+  end
+
+  assign io_cpu_fetch_haltIt = io_cpu_fetch_mmuBus_busy;
+  always @ (*) begin
+    lineLoader_fire = 1'b0;
+    if(io_mem_rsp_valid)begin
+      if((lineLoader_wordIndex == (3'b111)))begin
+        lineLoader_fire = 1'b1;
+      end
+    end
+  end
+
+  always @ (*) begin
+    io_cpu_prefetch_haltIt = (lineLoader_valid || lineLoader_flushPending);
+    if(_zz_12_)begin
+      io_cpu_prefetch_haltIt = 1'b1;
+    end
+    if((! _zz_3_))begin
+      io_cpu_prefetch_haltIt = 1'b1;
+    end
+    if(io_flush)begin
+      io_cpu_prefetch_haltIt = 1'b1;
+    end
+  end
+
+  assign io_mem_cmd_valid = (lineLoader_valid && (! lineLoader_cmdSent));
+  assign io_mem_cmd_payload_address = {lineLoader_address[31 : 5],(5'b00000)};
+  assign io_mem_cmd_payload_size = (3'b101);
+  always @ (*) begin
+    lineLoader_wayToAllocate_willIncrement = 1'b0;
+    if((! lineLoader_valid))begin
+      lineLoader_wayToAllocate_willIncrement = 1'b1;
+    end
+  end
+
+  assign lineLoader_wayToAllocate_willClear = 1'b0;
+  assign lineLoader_wayToAllocate_willOverflowIfInc = 1'b1;
+  assign lineLoader_wayToAllocate_willOverflow = (lineLoader_wayToAllocate_willOverflowIfInc && lineLoader_wayToAllocate_willIncrement);
+  assign _zz_4_ = 1'b1;
+  assign lineLoader_write_tag_0_valid = ((_zz_4_ && lineLoader_fire) || (! lineLoader_flushCounter[6]));
+  assign lineLoader_write_tag_0_payload_address = (lineLoader_flushCounter[6] ? lineLoader_address[10 : 5] : lineLoader_flushCounter[5 : 0]);
+  assign lineLoader_write_tag_0_payload_data_valid = lineLoader_flushCounter[6];
+  assign lineLoader_write_tag_0_payload_data_error = (lineLoader_hadError || io_mem_rsp_payload_error);
+  assign lineLoader_write_tag_0_payload_data_address = lineLoader_address[31 : 11];
+  assign lineLoader_write_data_0_valid = (io_mem_rsp_valid && _zz_4_);
+  assign lineLoader_write_data_0_payload_address = {lineLoader_address[10 : 5],lineLoader_wordIndex};
+  assign lineLoader_write_data_0_payload_data = io_mem_rsp_payload_data;
+  assign _zz_5_ = io_cpu_prefetch_pc[10 : 5];
+  assign _zz_6_ = (! io_cpu_fetch_isStuck);
+  assign _zz_7_ = _zz_10_;
+  assign fetchStage_read_waysValues_0_tag_valid = _zz_14_[0];
+  assign fetchStage_read_waysValues_0_tag_error = _zz_15_[0];
+  assign fetchStage_read_waysValues_0_tag_address = _zz_7_[22 : 2];
+  assign _zz_8_ = io_cpu_prefetch_pc[10 : 2];
+  assign _zz_9_ = (! io_cpu_fetch_isStuck);
+  assign fetchStage_read_waysValues_0_data = _zz_11_;
+  assign fetchStage_hit_hits_0 = (fetchStage_read_waysValues_0_tag_valid && (fetchStage_read_waysValues_0_tag_address == io_cpu_fetch_mmuBus_rsp_physicalAddress[31 : 11]));
+  assign fetchStage_hit_valid = (fetchStage_hit_hits_0 != (1'b0));
+  assign fetchStage_hit_error = fetchStage_read_waysValues_0_tag_error;
+  assign fetchStage_hit_data = fetchStage_read_waysValues_0_data;
+  assign fetchStage_hit_word = fetchStage_hit_data[31 : 0];
+  assign io_cpu_fetch_data = (io_cpu_fetch_dataBypassValid ? io_cpu_fetch_dataBypass : fetchStage_hit_word);
+  assign io_cpu_decode_data = io_cpu_fetch_data_regNextWhen;
+  assign io_cpu_fetch_mmuBus_cmd_isValid = io_cpu_fetch_isValid;
+  assign io_cpu_fetch_mmuBus_cmd_virtualAddress = io_cpu_fetch_pc;
+  assign io_cpu_fetch_mmuBus_cmd_bypassTranslation = 1'b0;
+  assign io_cpu_fetch_mmuBus_end = ((! io_cpu_fetch_isStuck) || io_cpu_fetch_isRemoved);
+  assign io_cpu_fetch_physicalAddress = io_cpu_fetch_mmuBus_rsp_physicalAddress;
+  assign io_cpu_decode_cacheMiss = (! decodeStage_hit_valid);
+  assign io_cpu_decode_error = decodeStage_hit_error;
+  assign io_cpu_decode_mmuRefilling = decodeStage_mmuRsp_refilling;
+  assign io_cpu_decode_mmuException = ((! decodeStage_mmuRsp_refilling) && (decodeStage_mmuRsp_exception || (! decodeStage_mmuRsp_allowExecute)));
+  assign io_cpu_decode_physicalAddress = decodeStage_mmuRsp_physicalAddress;
+  always @ (posedge clk) begin
+    if(reset) begin
+      lineLoader_valid <= 1'b0;
+      lineLoader_hadError <= 1'b0;
+      lineLoader_flushPending <= 1'b1;
+      lineLoader_cmdSent <= 1'b0;
+      lineLoader_wordIndex <= (3'b000);
+    end else begin
+      if(lineLoader_fire)begin
+        lineLoader_valid <= 1'b0;
+      end
+      if(lineLoader_fire)begin
+        lineLoader_hadError <= 1'b0;
+      end
+      if(io_cpu_fill_valid)begin
+        lineLoader_valid <= 1'b1;
+      end
+      if(io_flush)begin
+        lineLoader_flushPending <= 1'b1;
+      end
+      if(_zz_13_)begin
+        lineLoader_flushPending <= 1'b0;
+      end
+      if((io_mem_cmd_valid && io_mem_cmd_ready))begin
+        lineLoader_cmdSent <= 1'b1;
+      end
+      if(lineLoader_fire)begin
+        lineLoader_cmdSent <= 1'b0;
+      end
+      if(io_mem_rsp_valid)begin
+        lineLoader_wordIndex <= (lineLoader_wordIndex + (3'b001));
+        if(io_mem_rsp_payload_error)begin
+          lineLoader_hadError <= 1'b1;
+        end
+      end
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(io_cpu_fill_valid)begin
+      lineLoader_address <= io_cpu_fill_payload;
+    end
+    if(_zz_12_)begin
+      lineLoader_flushCounter <= (lineLoader_flushCounter + (7'b0000001));
+    end
+    _zz_3_ <= lineLoader_flushCounter[6];
+    if(_zz_13_)begin
+      lineLoader_flushCounter <= (7'b0000000);
+    end
+    if((! io_cpu_decode_isStuck))begin
+      io_cpu_fetch_data_regNextWhen <= io_cpu_fetch_data;
+    end
+    if((! io_cpu_decode_isStuck))begin
+      decodeStage_mmuRsp_physicalAddress <= io_cpu_fetch_mmuBus_rsp_physicalAddress;
+      decodeStage_mmuRsp_isIoAccess <= io_cpu_fetch_mmuBus_rsp_isIoAccess;
+      decodeStage_mmuRsp_allowRead <= io_cpu_fetch_mmuBus_rsp_allowRead;
+      decodeStage_mmuRsp_allowWrite <= io_cpu_fetch_mmuBus_rsp_allowWrite;
+      decodeStage_mmuRsp_allowExecute <= io_cpu_fetch_mmuBus_rsp_allowExecute;
+      decodeStage_mmuRsp_exception <= io_cpu_fetch_mmuBus_rsp_exception;
+      decodeStage_mmuRsp_refilling <= io_cpu_fetch_mmuBus_rsp_refilling;
+    end
+    if((! io_cpu_decode_isStuck))begin
+      decodeStage_hit_valid <= fetchStage_hit_valid;
+    end
+    if((! io_cpu_decode_isStuck))begin
+      decodeStage_hit_error <= fetchStage_hit_error;
+    end
+  end
+
+endmodule
+
+module VexRiscv (
+      input  [31:0] externalResetVector,
+      input   timerInterrupt,
+      input   softwareInterrupt,
+      input  [31:0] externalInterruptArray,
+      output reg  iBusWishbone_CYC,
+      output reg  iBusWishbone_STB,
+      input   iBusWishbone_ACK,
+      output  iBusWishbone_WE,
+      output [29:0] iBusWishbone_ADR,
+      input  [31:0] iBusWishbone_DAT_MISO,
+      output [31:0] iBusWishbone_DAT_MOSI,
+      output [3:0] iBusWishbone_SEL,
+      input   iBusWishbone_ERR,
+      output [1:0] iBusWishbone_BTE,
+      output [2:0] iBusWishbone_CTI,
+      output  dBusWishbone_CYC,
+      output  dBusWishbone_STB,
+      input   dBusWishbone_ACK,
+      output  dBusWishbone_WE,
+      output [29:0] dBusWishbone_ADR,
+      input  [31:0] dBusWishbone_DAT_MISO,
+      output [31:0] dBusWishbone_DAT_MOSI,
+      output reg [3:0] dBusWishbone_SEL,
+      input   dBusWishbone_ERR,
+      output [1:0] dBusWishbone_BTE,
+      output [2:0] dBusWishbone_CTI,
+      input   clk,
+      input   reset);
+  wire  _zz_205_;
+  wire  _zz_206_;
+  wire  _zz_207_;
+  wire  _zz_208_;
+  wire [31:0] _zz_209_;
+  wire  _zz_210_;
+  wire  _zz_211_;
+  wire  _zz_212_;
+  reg  _zz_213_;
+  reg [31:0] _zz_214_;
+  reg [31:0] _zz_215_;
+  reg [31:0] _zz_216_;
+  wire  IBusCachedPlugin_cache_io_cpu_prefetch_haltIt;
+  wire [31:0] IBusCachedPlugin_cache_io_cpu_fetch_data;
+  wire [31:0] IBusCachedPlugin_cache_io_cpu_fetch_physicalAddress;
+  wire  IBusCachedPlugin_cache_io_cpu_fetch_haltIt;
+  wire  IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_isValid;
+  wire [31:0] IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_virtualAddress;
+  wire  IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_bypassTranslation;
+  wire  IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_end;
+  wire  IBusCachedPlugin_cache_io_cpu_decode_error;
+  wire  IBusCachedPlugin_cache_io_cpu_decode_mmuRefilling;
+  wire  IBusCachedPlugin_cache_io_cpu_decode_mmuException;
+  wire [31:0] IBusCachedPlugin_cache_io_cpu_decode_data;
+  wire  IBusCachedPlugin_cache_io_cpu_decode_cacheMiss;
+  wire [31:0] IBusCachedPlugin_cache_io_cpu_decode_physicalAddress;
+  wire  IBusCachedPlugin_cache_io_mem_cmd_valid;
+  wire [31:0] IBusCachedPlugin_cache_io_mem_cmd_payload_address;
+  wire [2:0] IBusCachedPlugin_cache_io_mem_cmd_payload_size;
+  wire  _zz_217_;
+  wire  _zz_218_;
+  wire  _zz_219_;
+  wire  _zz_220_;
+  wire  _zz_221_;
+  wire  _zz_222_;
+  wire  _zz_223_;
+  wire  _zz_224_;
+  wire  _zz_225_;
+  wire  _zz_226_;
+  wire  _zz_227_;
+  wire  _zz_228_;
+  wire  _zz_229_;
+  wire  _zz_230_;
+  wire  _zz_231_;
+  wire  _zz_232_;
+  wire  _zz_233_;
+  wire  _zz_234_;
+  wire  _zz_235_;
+  wire [1:0] _zz_236_;
+  wire  _zz_237_;
+  wire  _zz_238_;
+  wire  _zz_239_;
+  wire  _zz_240_;
+  wire  _zz_241_;
+  wire  _zz_242_;
+  wire  _zz_243_;
+  wire  _zz_244_;
+  wire  _zz_245_;
+  wire  _zz_246_;
+  wire  _zz_247_;
+  wire  _zz_248_;
+  wire  _zz_249_;
+  wire  _zz_250_;
+  wire  _zz_251_;
+  wire  _zz_252_;
+  wire [1:0] _zz_253_;
+  wire  _zz_254_;
+  wire [4:0] _zz_255_;
+  wire [2:0] _zz_256_;
+  wire [31:0] _zz_257_;
+  wire [11:0] _zz_258_;
+  wire [31:0] _zz_259_;
+  wire [19:0] _zz_260_;
+  wire [11:0] _zz_261_;
+  wire [31:0] _zz_262_;
+  wire [31:0] _zz_263_;
+  wire [19:0] _zz_264_;
+  wire [11:0] _zz_265_;
+  wire [2:0] _zz_266_;
+  wire [0:0] _zz_267_;
+  wire [0:0] _zz_268_;
+  wire [0:0] _zz_269_;
+  wire [0:0] _zz_270_;
+  wire [0:0] _zz_271_;
+  wire [0:0] _zz_272_;
+  wire [0:0] _zz_273_;
+  wire [0:0] _zz_274_;
+  wire [0:0] _zz_275_;
+  wire [0:0] _zz_276_;
+  wire [0:0] _zz_277_;
+  wire [0:0] _zz_278_;
+  wire [0:0] _zz_279_;
+  wire [0:0] _zz_280_;
+  wire [0:0] _zz_281_;
+  wire [0:0] _zz_282_;
+  wire [0:0] _zz_283_;
+  wire [2:0] _zz_284_;
+  wire [4:0] _zz_285_;
+  wire [11:0] _zz_286_;
+  wire [11:0] _zz_287_;
+  wire [31:0] _zz_288_;
+  wire [31:0] _zz_289_;
+  wire [31:0] _zz_290_;
+  wire [31:0] _zz_291_;
+  wire [31:0] _zz_292_;
+  wire [31:0] _zz_293_;
+  wire [31:0] _zz_294_;
+  wire [31:0] _zz_295_;
+  wire [32:0] _zz_296_;
+  wire [11:0] _zz_297_;
+  wire [19:0] _zz_298_;
+  wire [11:0] _zz_299_;
+  wire [31:0] _zz_300_;
+  wire [31:0] _zz_301_;
+  wire [31:0] _zz_302_;
+  wire [11:0] _zz_303_;
+  wire [19:0] _zz_304_;
+  wire [11:0] _zz_305_;
+  wire [2:0] _zz_306_;
+  wire [1:0] _zz_307_;
+  wire [1:0] _zz_308_;
+  wire [1:0] _zz_309_;
+  wire [1:0] _zz_310_;
+  wire [0:0] _zz_311_;
+  wire [5:0] _zz_312_;
+  wire [33:0] _zz_313_;
+  wire [32:0] _zz_314_;
+  wire [33:0] _zz_315_;
+  wire [32:0] _zz_316_;
+  wire [33:0] _zz_317_;
+  wire [32:0] _zz_318_;
+  wire [0:0] _zz_319_;
+  wire [5:0] _zz_320_;
+  wire [32:0] _zz_321_;
+  wire [32:0] _zz_322_;
+  wire [31:0] _zz_323_;
+  wire [31:0] _zz_324_;
+  wire [32:0] _zz_325_;
+  wire [32:0] _zz_326_;
+  wire [32:0] _zz_327_;
+  wire [0:0] _zz_328_;
+  wire [32:0] _zz_329_;
+  wire [0:0] _zz_330_;
+  wire [32:0] _zz_331_;
+  wire [0:0] _zz_332_;
+  wire [31:0] _zz_333_;
+  wire [0:0] _zz_334_;
+  wire [0:0] _zz_335_;
+  wire [0:0] _zz_336_;
+  wire [0:0] _zz_337_;
+  wire [0:0] _zz_338_;
+  wire [0:0] _zz_339_;
+  wire [26:0] _zz_340_;
+  wire [6:0] _zz_341_;
+  wire  _zz_342_;
+  wire  _zz_343_;
+  wire [2:0] _zz_344_;
+  wire  _zz_345_;
+  wire  _zz_346_;
+  wire  _zz_347_;
+  wire  _zz_348_;
+  wire [0:0] _zz_349_;
+  wire [0:0] _zz_350_;
+  wire [0:0] _zz_351_;
+  wire [0:0] _zz_352_;
+  wire  _zz_353_;
+  wire [0:0] _zz_354_;
+  wire [23:0] _zz_355_;
+  wire [31:0] _zz_356_;
+  wire [31:0] _zz_357_;
+  wire  _zz_358_;
+  wire [0:0] _zz_359_;
+  wire [0:0] _zz_360_;
+  wire [0:0] _zz_361_;
+  wire [0:0] _zz_362_;
+  wire [1:0] _zz_363_;
+  wire [1:0] _zz_364_;
+  wire  _zz_365_;
+  wire [0:0] _zz_366_;
+  wire [20:0] _zz_367_;
+  wire [31:0] _zz_368_;
+  wire [31:0] _zz_369_;
+  wire [31:0] _zz_370_;
+  wire [31:0] _zz_371_;
+  wire  _zz_372_;
+  wire [0:0] _zz_373_;
+  wire [1:0] _zz_374_;
+  wire [0:0] _zz_375_;
+  wire [0:0] _zz_376_;
+  wire  _zz_377_;
+  wire [0:0] _zz_378_;
+  wire [17:0] _zz_379_;
+  wire [31:0] _zz_380_;
+  wire [31:0] _zz_381_;
+  wire [31:0] _zz_382_;
+  wire [31:0] _zz_383_;
+  wire [31:0] _zz_384_;
+  wire [31:0] _zz_385_;
+  wire [31:0] _zz_386_;
+  wire [31:0] _zz_387_;
+  wire [0:0] _zz_388_;
+  wire [0:0] _zz_389_;
+  wire [5:0] _zz_390_;
+  wire [5:0] _zz_391_;
+  wire  _zz_392_;
+  wire [0:0] _zz_393_;
+  wire [14:0] _zz_394_;
+  wire [31:0] _zz_395_;
+  wire [31:0] _zz_396_;
+  wire  _zz_397_;
+  wire [0:0] _zz_398_;
+  wire [2:0] _zz_399_;
+  wire  _zz_400_;
+  wire  _zz_401_;
+  wire [0:0] _zz_402_;
+  wire [2:0] _zz_403_;
+  wire [0:0] _zz_404_;
+  wire [0:0] _zz_405_;
+  wire  _zz_406_;
+  wire [0:0] _zz_407_;
+  wire [11:0] _zz_408_;
+  wire [31:0] _zz_409_;
+  wire [31:0] _zz_410_;
+  wire [31:0] _zz_411_;
+  wire  _zz_412_;
+  wire [0:0] _zz_413_;
+  wire [0:0] _zz_414_;
+  wire [31:0] _zz_415_;
+  wire [31:0] _zz_416_;
+  wire [31:0] _zz_417_;
+  wire [31:0] _zz_418_;
+  wire  _zz_419_;
+  wire [0:0] _zz_420_;
+  wire [0:0] _zz_421_;
+  wire [31:0] _zz_422_;
+  wire [31:0] _zz_423_;
+  wire [0:0] _zz_424_;
+  wire [0:0] _zz_425_;
+  wire [0:0] _zz_426_;
+  wire [0:0] _zz_427_;
+  wire  _zz_428_;
+  wire [0:0] _zz_429_;
+  wire [9:0] _zz_430_;
+  wire [31:0] _zz_431_;
+  wire [31:0] _zz_432_;
+  wire [31:0] _zz_433_;
+  wire [31:0] _zz_434_;
+  wire [31:0] _zz_435_;
+  wire [31:0] _zz_436_;
+  wire [31:0] _zz_437_;
+  wire [31:0] _zz_438_;
+  wire [31:0] _zz_439_;
+  wire [31:0] _zz_440_;
+  wire [31:0] _zz_441_;
+  wire [31:0] _zz_442_;
+  wire [31:0] _zz_443_;
+  wire [31:0] _zz_444_;
+  wire  _zz_445_;
+  wire [0:0] _zz_446_;
+  wire [0:0] _zz_447_;
+  wire  _zz_448_;
+  wire [0:0] _zz_449_;
+  wire [7:0] _zz_450_;
+  wire  _zz_451_;
+  wire [0:0] _zz_452_;
+  wire [0:0] _zz_453_;
+  wire [0:0] _zz_454_;
+  wire [0:0] _zz_455_;
+  wire [0:0] _zz_456_;
+  wire [0:0] _zz_457_;
+  wire  _zz_458_;
+  wire [0:0] _zz_459_;
+  wire [3:0] _zz_460_;
+  wire [31:0] _zz_461_;
+  wire [31:0] _zz_462_;
+  wire [31:0] _zz_463_;
+  wire [31:0] _zz_464_;
+  wire [31:0] _zz_465_;
+  wire  _zz_466_;
+  wire  _zz_467_;
+  wire [0:0] _zz_468_;
+  wire [1:0] _zz_469_;
+  wire [2:0] _zz_470_;
+  wire [2:0] _zz_471_;
+  wire  _zz_472_;
+  wire [0:0] _zz_473_;
+  wire [0:0] _zz_474_;
+  wire [31:0] _zz_475_;
+  wire [31:0] _zz_476_;
+  wire [31:0] _zz_477_;
+  wire [31:0] _zz_478_;
+  wire [31:0] _zz_479_;
+  wire  _zz_480_;
+  wire  _zz_481_;
+  wire [31:0] _zz_482_;
+  wire [31:0] _zz_483_;
+  wire [0:0] _zz_484_;
+  wire [0:0] _zz_485_;
+  wire  _zz_486_;
+  wire [31:0] _zz_487_;
+  wire [31:0] _zz_488_;
+  wire [31:0] _zz_489_;
+  wire  _zz_490_;
+  wire [0:0] _zz_491_;
+  wire [10:0] _zz_492_;
+  wire [31:0] _zz_493_;
+  wire [31:0] _zz_494_;
+  wire [31:0] _zz_495_;
+  wire  _zz_496_;
+  wire [0:0] _zz_497_;
+  wire [4:0] _zz_498_;
+  wire [31:0] _zz_499_;
+  wire [31:0] _zz_500_;
+  wire [31:0] _zz_501_;
+  wire [31:0] _zz_502_;
+  wire [31:0] _zz_503_;
+  wire  _zz_504_;
+  wire  _zz_505_;
+  wire  _zz_506_;
+  wire `AluCtrlEnum_defaultEncoding_type decode_ALU_CTRL;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_1_;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_2_;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_3_;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type decode_ALU_BITWISE_CTRL;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_4_;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_5_;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_6_;
+  wire `Src2CtrlEnum_defaultEncoding_type decode_SRC2_CTRL;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_7_;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_8_;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_9_;
+  wire  decode_IS_RS2_SIGNED;
+  wire  decode_BYPASSABLE_EXECUTE_STAGE;
+  wire  decode_IS_RS1_SIGNED;
+  wire  decode_CSR_READ_OPCODE;
+  wire  decode_IS_DIV;
+  wire [1:0] memory_MEMORY_ADDRESS_LOW;
+  wire [1:0] execute_MEMORY_ADDRESS_LOW;
+  wire  decode_IS_MUL;
+  wire [31:0] execute_BRANCH_CALC;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_10_;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_11_;
+  wire `Src1CtrlEnum_defaultEncoding_type decode_SRC1_CTRL;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_12_;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_13_;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_14_;
+  wire  execute_BYPASSABLE_MEMORY_STAGE;
+  wire  decode_BYPASSABLE_MEMORY_STAGE;
+  wire  decode_SRC2_FORCE_ZERO;
+  wire  decode_CSR_WRITE_OPCODE;
+  wire [31:0] writeBack_REGFILE_WRITE_DATA;
+  wire [31:0] execute_REGFILE_WRITE_DATA;
+  wire  execute_BRANCH_DO;
+  wire  decode_SRC_LESS_UNSIGNED;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_15_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_16_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_17_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_18_;
+  wire `EnvCtrlEnum_defaultEncoding_type decode_ENV_CTRL;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_19_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_20_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_21_;
+  wire [31:0] writeBack_FORMAL_PC_NEXT;
+  wire [31:0] memory_FORMAL_PC_NEXT;
+  wire [31:0] execute_FORMAL_PC_NEXT;
+  wire [31:0] decode_FORMAL_PC_NEXT;
+  wire  decode_MEMORY_STORE;
+  wire  decode_PREDICTION_HAD_BRANCHED2;
+  wire  decode_IS_CSR;
+  wire `ShiftCtrlEnum_defaultEncoding_type decode_SHIFT_CTRL;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_22_;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_23_;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_24_;
+  wire [31:0] memory_MEMORY_READ_DATA;
+  wire  execute_IS_RS1_SIGNED;
+  wire  execute_IS_DIV;
+  wire  execute_IS_MUL;
+  wire  execute_IS_RS2_SIGNED;
+  wire  memory_IS_DIV;
+  wire  memory_IS_MUL;
+  wire  execute_CSR_READ_OPCODE;
+  wire  execute_CSR_WRITE_OPCODE;
+  wire  execute_IS_CSR;
+  wire `EnvCtrlEnum_defaultEncoding_type memory_ENV_CTRL;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_25_;
+  wire `EnvCtrlEnum_defaultEncoding_type execute_ENV_CTRL;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_26_;
+  wire  _zz_27_;
+  wire  _zz_28_;
+  wire `EnvCtrlEnum_defaultEncoding_type writeBack_ENV_CTRL;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_29_;
+  wire [31:0] memory_BRANCH_CALC;
+  wire  memory_BRANCH_DO;
+  wire [31:0] _zz_30_;
+  wire [31:0] execute_PC;
+  wire  execute_PREDICTION_HAD_BRANCHED2;
+  wire  _zz_31_;
+  wire [31:0] execute_RS1;
+  wire  execute_BRANCH_COND_RESULT;
+  wire `BranchCtrlEnum_defaultEncoding_type execute_BRANCH_CTRL;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_32_;
+  wire  _zz_33_;
+  wire  _zz_34_;
+  wire  decode_RS2_USE;
+  wire  decode_RS1_USE;
+  wire  execute_REGFILE_WRITE_VALID;
+  wire  execute_BYPASSABLE_EXECUTE_STAGE;
+  reg [31:0] _zz_35_;
+  wire  memory_REGFILE_WRITE_VALID;
+  wire [31:0] memory_INSTRUCTION;
+  wire  memory_BYPASSABLE_MEMORY_STAGE;
+  wire  writeBack_REGFILE_WRITE_VALID;
+  reg [31:0] decode_RS2;
+  reg [31:0] decode_RS1;
+  reg [31:0] _zz_36_;
+  wire `ShiftCtrlEnum_defaultEncoding_type execute_SHIFT_CTRL;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_37_;
+  wire  _zz_38_;
+  wire [31:0] _zz_39_;
+  wire [31:0] _zz_40_;
+  wire  execute_SRC_LESS_UNSIGNED;
+  wire  execute_SRC2_FORCE_ZERO;
+  wire  execute_SRC_USE_SUB_LESS;
+  wire [31:0] _zz_41_;
+  wire `Src2CtrlEnum_defaultEncoding_type execute_SRC2_CTRL;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_42_;
+  wire [31:0] _zz_43_;
+  wire `Src1CtrlEnum_defaultEncoding_type execute_SRC1_CTRL;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_44_;
+  wire [31:0] _zz_45_;
+  wire  decode_SRC_USE_SUB_LESS;
+  wire  decode_SRC_ADD_ZERO;
+  wire  _zz_46_;
+  wire [31:0] execute_SRC_ADD_SUB;
+  wire  execute_SRC_LESS;
+  wire `AluCtrlEnum_defaultEncoding_type execute_ALU_CTRL;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_47_;
+  wire [31:0] _zz_48_;
+  wire [31:0] execute_SRC2;
+  wire [31:0] execute_SRC1;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type execute_ALU_BITWISE_CTRL;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_49_;
+  wire [31:0] _zz_50_;
+  wire  _zz_51_;
+  reg  _zz_52_;
+  wire [31:0] _zz_53_;
+  wire [31:0] _zz_54_;
+  wire [31:0] decode_INSTRUCTION_ANTICIPATED;
+  reg  decode_REGFILE_WRITE_VALID;
+  wire  decode_LEGAL_INSTRUCTION;
+  wire  decode_INSTRUCTION_READY;
+  wire  _zz_55_;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_56_;
+  wire  _zz_57_;
+  wire  _zz_58_;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_59_;
+  wire  _zz_60_;
+  wire  _zz_61_;
+  wire  _zz_62_;
+  wire  _zz_63_;
+  wire  _zz_64_;
+  wire  _zz_65_;
+  wire  _zz_66_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_67_;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_68_;
+  wire  _zz_69_;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_70_;
+  wire  _zz_71_;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_72_;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_73_;
+  wire  _zz_74_;
+  wire  _zz_75_;
+  wire  _zz_76_;
+  wire  _zz_77_;
+  wire  _zz_78_;
+  wire  writeBack_MEMORY_STORE;
+  reg [31:0] _zz_79_;
+  wire  writeBack_MEMORY_ENABLE;
+  wire [1:0] writeBack_MEMORY_ADDRESS_LOW;
+  wire [31:0] writeBack_MEMORY_READ_DATA;
+  wire  memory_MMU_FAULT;
+  wire [31:0] memory_MMU_RSP_physicalAddress;
+  wire  memory_MMU_RSP_isIoAccess;
+  wire  memory_MMU_RSP_allowRead;
+  wire  memory_MMU_RSP_allowWrite;
+  wire  memory_MMU_RSP_allowExecute;
+  wire  memory_MMU_RSP_exception;
+  wire  memory_MMU_RSP_refilling;
+  wire [31:0] memory_PC;
+  wire  memory_ALIGNEMENT_FAULT;
+  wire [31:0] memory_REGFILE_WRITE_DATA;
+  wire  memory_MEMORY_STORE;
+  wire  memory_MEMORY_ENABLE;
+  wire [31:0] _zz_80_;
+  wire [31:0] _zz_81_;
+  wire  _zz_82_;
+  wire  _zz_83_;
+  wire  _zz_84_;
+  wire  _zz_85_;
+  wire  _zz_86_;
+  wire  _zz_87_;
+  wire  execute_MMU_FAULT;
+  wire [31:0] execute_MMU_RSP_physicalAddress;
+  wire  execute_MMU_RSP_isIoAccess;
+  wire  execute_MMU_RSP_allowRead;
+  wire  execute_MMU_RSP_allowWrite;
+  wire  execute_MMU_RSP_allowExecute;
+  wire  execute_MMU_RSP_exception;
+  wire  execute_MMU_RSP_refilling;
+  wire  _zz_88_;
+  wire [31:0] execute_SRC_ADD;
+  wire [1:0] _zz_89_;
+  wire [31:0] execute_RS2;
+  wire [31:0] execute_INSTRUCTION;
+  wire  execute_MEMORY_STORE;
+  wire  execute_MEMORY_ENABLE;
+  wire  execute_ALIGNEMENT_FAULT;
+  wire  _zz_90_;
+  wire  decode_MEMORY_ENABLE;
+  wire  decode_FLUSH_ALL;
+  reg  IBusCachedPlugin_rsp_issueDetected;
+  reg  _zz_91_;
+  reg  _zz_92_;
+  reg  _zz_93_;
+  wire [31:0] _zz_94_;
+  wire `BranchCtrlEnum_defaultEncoding_type decode_BRANCH_CTRL;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_95_;
+  wire [31:0] decode_INSTRUCTION;
+  reg [31:0] _zz_96_;
+  reg [31:0] _zz_97_;
+  wire [31:0] decode_PC;
+  wire [31:0] _zz_98_;
+  wire [31:0] _zz_99_;
+  wire [31:0] _zz_100_;
+  wire [31:0] writeBack_PC;
+  wire [31:0] writeBack_INSTRUCTION;
+  reg  decode_arbitration_haltItself;
+  reg  decode_arbitration_haltByOther;
+  reg  decode_arbitration_removeIt;
+  wire  decode_arbitration_flushIt;
+  reg  decode_arbitration_flushNext;
+  wire  decode_arbitration_isValid;
+  wire  decode_arbitration_isStuck;
+  wire  decode_arbitration_isStuckByOthers;
+  wire  decode_arbitration_isFlushed;
+  wire  decode_arbitration_isMoving;
+  wire  decode_arbitration_isFiring;
+  reg  execute_arbitration_haltItself;
+  wire  execute_arbitration_haltByOther;
+  reg  execute_arbitration_removeIt;
+  wire  execute_arbitration_flushIt;
+  wire  execute_arbitration_flushNext;
+  reg  execute_arbitration_isValid;
+  wire  execute_arbitration_isStuck;
+  wire  execute_arbitration_isStuckByOthers;
+  wire  execute_arbitration_isFlushed;
+  wire  execute_arbitration_isMoving;
+  wire  execute_arbitration_isFiring;
+  reg  memory_arbitration_haltItself;
+  wire  memory_arbitration_haltByOther;
+  reg  memory_arbitration_removeIt;
+  reg  memory_arbitration_flushIt;
+  reg  memory_arbitration_flushNext;
+  reg  memory_arbitration_isValid;
+  wire  memory_arbitration_isStuck;
+  wire  memory_arbitration_isStuckByOthers;
+  wire  memory_arbitration_isFlushed;
+  wire  memory_arbitration_isMoving;
+  wire  memory_arbitration_isFiring;
+  wire  writeBack_arbitration_haltItself;
+  wire  writeBack_arbitration_haltByOther;
+  reg  writeBack_arbitration_removeIt;
+  wire  writeBack_arbitration_flushIt;
+  reg  writeBack_arbitration_flushNext;
+  reg  writeBack_arbitration_isValid;
+  wire  writeBack_arbitration_isStuck;
+  wire  writeBack_arbitration_isStuckByOthers;
+  wire  writeBack_arbitration_isFlushed;
+  wire  writeBack_arbitration_isMoving;
+  wire  writeBack_arbitration_isFiring;
+  wire [31:0] lastStageInstruction /* verilator public */ ;
+  wire [31:0] lastStagePc /* verilator public */ ;
+  wire  lastStageIsValid /* verilator public */ ;
+  wire  lastStageIsFiring /* verilator public */ ;
+  reg  IBusCachedPlugin_fetcherHalt;
+  reg  IBusCachedPlugin_fetcherflushIt;
+  reg  IBusCachedPlugin_incomingInstruction;
+  wire  IBusCachedPlugin_predictionJumpInterface_valid;
+  (* syn_keep , keep *) wire [31:0] IBusCachedPlugin_predictionJumpInterface_payload /* synthesis syn_keep = 1 */ ;
+  reg  IBusCachedPlugin_decodePrediction_cmd_hadBranch;
+  wire  IBusCachedPlugin_decodePrediction_rsp_wasWrong;
+  wire  IBusCachedPlugin_pcValids_0;
+  wire  IBusCachedPlugin_pcValids_1;
+  wire  IBusCachedPlugin_pcValids_2;
+  wire  IBusCachedPlugin_pcValids_3;
+  wire  IBusCachedPlugin_redoBranch_valid;
+  wire [31:0] IBusCachedPlugin_redoBranch_payload;
+  reg  IBusCachedPlugin_decodeExceptionPort_valid;
+  reg [3:0] IBusCachedPlugin_decodeExceptionPort_payload_code;
+  wire [31:0] IBusCachedPlugin_decodeExceptionPort_payload_badAddr;
+  wire  IBusCachedPlugin_mmuBus_cmd_isValid;
+  wire [31:0] IBusCachedPlugin_mmuBus_cmd_virtualAddress;
+  wire  IBusCachedPlugin_mmuBus_cmd_bypassTranslation;
+  wire [31:0] IBusCachedPlugin_mmuBus_rsp_physicalAddress;
+  wire  IBusCachedPlugin_mmuBus_rsp_isIoAccess;
+  wire  IBusCachedPlugin_mmuBus_rsp_allowRead;
+  wire  IBusCachedPlugin_mmuBus_rsp_allowWrite;
+  wire  IBusCachedPlugin_mmuBus_rsp_allowExecute;
+  wire  IBusCachedPlugin_mmuBus_rsp_exception;
+  wire  IBusCachedPlugin_mmuBus_rsp_refilling;
+  wire  IBusCachedPlugin_mmuBus_end;
+  wire  IBusCachedPlugin_mmuBus_busy;
+  reg  DBusSimplePlugin_memoryExceptionPort_valid;
+  reg [3:0] DBusSimplePlugin_memoryExceptionPort_payload_code;
+  wire [31:0] DBusSimplePlugin_memoryExceptionPort_payload_badAddr;
+  wire  DBusSimplePlugin_mmuBus_cmd_isValid;
+  wire [31:0] DBusSimplePlugin_mmuBus_cmd_virtualAddress;
+  wire  DBusSimplePlugin_mmuBus_cmd_bypassTranslation;
+  wire [31:0] DBusSimplePlugin_mmuBus_rsp_physicalAddress;
+  wire  DBusSimplePlugin_mmuBus_rsp_isIoAccess;
+  wire  DBusSimplePlugin_mmuBus_rsp_allowRead;
+  wire  DBusSimplePlugin_mmuBus_rsp_allowWrite;
+  wire  DBusSimplePlugin_mmuBus_rsp_allowExecute;
+  wire  DBusSimplePlugin_mmuBus_rsp_exception;
+  wire  DBusSimplePlugin_mmuBus_rsp_refilling;
+  wire  DBusSimplePlugin_mmuBus_end;
+  wire  DBusSimplePlugin_mmuBus_busy;
+  reg  DBusSimplePlugin_redoBranch_valid;
+  wire [31:0] DBusSimplePlugin_redoBranch_payload;
+  wire  decodeExceptionPort_valid;
+  wire [3:0] decodeExceptionPort_payload_code;
+  wire [31:0] decodeExceptionPort_payload_badAddr;
+  wire  BranchPlugin_jumpInterface_valid;
+  wire [31:0] BranchPlugin_jumpInterface_payload;
+  wire  BranchPlugin_branchExceptionPort_valid;
+  wire [3:0] BranchPlugin_branchExceptionPort_payload_code;
+  wire [31:0] BranchPlugin_branchExceptionPort_payload_badAddr;
+  reg  CsrPlugin_jumpInterface_valid;
+  reg [31:0] CsrPlugin_jumpInterface_payload;
+  wire  CsrPlugin_exceptionPendings_0;
+  wire  CsrPlugin_exceptionPendings_1;
+  wire  CsrPlugin_exceptionPendings_2;
+  wire  CsrPlugin_exceptionPendings_3;
+  wire  externalInterrupt;
+  wire  contextSwitching;
+  reg [1:0] CsrPlugin_privilege;
+  wire  CsrPlugin_forceMachineWire;
+  wire  CsrPlugin_allowInterrupts;
+  wire  CsrPlugin_allowException;
+  wire  IBusCachedPlugin_jump_pcLoad_valid;
+  wire [31:0] IBusCachedPlugin_jump_pcLoad_payload;
+  wire [4:0] _zz_101_;
+  wire [4:0] _zz_102_;
+  wire  _zz_103_;
+  wire  _zz_104_;
+  wire  _zz_105_;
+  wire  _zz_106_;
+  wire  IBusCachedPlugin_fetchPc_output_valid;
+  wire  IBusCachedPlugin_fetchPc_output_ready;
+  wire [31:0] IBusCachedPlugin_fetchPc_output_payload;
+  reg [31:0] IBusCachedPlugin_fetchPc_pcReg /* verilator public */ ;
+  reg  IBusCachedPlugin_fetchPc_corrected;
+  reg  IBusCachedPlugin_fetchPc_pcRegPropagate;
+  reg  IBusCachedPlugin_fetchPc_booted;
+  reg  IBusCachedPlugin_fetchPc_inc;
+  reg [31:0] IBusCachedPlugin_fetchPc_pc;
+  wire  IBusCachedPlugin_iBusRsp_stages_0_input_valid;
+  wire  IBusCachedPlugin_iBusRsp_stages_0_input_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_stages_0_input_payload;
+  wire  IBusCachedPlugin_iBusRsp_stages_0_output_valid;
+  wire  IBusCachedPlugin_iBusRsp_stages_0_output_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_stages_0_output_payload;
+  reg  IBusCachedPlugin_iBusRsp_stages_0_halt;
+  wire  IBusCachedPlugin_iBusRsp_stages_0_inputSample;
+  wire  IBusCachedPlugin_iBusRsp_stages_1_input_valid;
+  wire  IBusCachedPlugin_iBusRsp_stages_1_input_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_stages_1_input_payload;
+  wire  IBusCachedPlugin_iBusRsp_stages_1_output_valid;
+  wire  IBusCachedPlugin_iBusRsp_stages_1_output_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_stages_1_output_payload;
+  reg  IBusCachedPlugin_iBusRsp_stages_1_halt;
+  wire  IBusCachedPlugin_iBusRsp_stages_1_inputSample;
+  wire  IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_valid;
+  wire  IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload;
+  wire  IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_valid;
+  wire  IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_payload;
+  reg  IBusCachedPlugin_iBusRsp_cacheRspArbitration_halt;
+  wire  IBusCachedPlugin_iBusRsp_cacheRspArbitration_inputSample;
+  wire  _zz_107_;
+  wire  _zz_108_;
+  wire  _zz_109_;
+  wire  _zz_110_;
+  wire  _zz_111_;
+  reg  _zz_112_;
+  wire  _zz_113_;
+  reg  _zz_114_;
+  reg [31:0] _zz_115_;
+  reg  IBusCachedPlugin_iBusRsp_readyForError;
+  wire  IBusCachedPlugin_iBusRsp_decodeInput_valid;
+  wire  IBusCachedPlugin_iBusRsp_decodeInput_ready;
+  wire [31:0] IBusCachedPlugin_iBusRsp_decodeInput_payload_pc;
+  wire  IBusCachedPlugin_iBusRsp_decodeInput_payload_rsp_error;
+  wire [31:0] IBusCachedPlugin_iBusRsp_decodeInput_payload_rsp_inst;
+  wire  IBusCachedPlugin_iBusRsp_decodeInput_payload_isRvc;
+  reg  IBusCachedPlugin_injector_nextPcCalc_valids_0;
+  reg  IBusCachedPlugin_injector_nextPcCalc_valids_1;
+  reg  IBusCachedPlugin_injector_nextPcCalc_valids_2;
+  reg  IBusCachedPlugin_injector_nextPcCalc_valids_3;
+  reg  IBusCachedPlugin_injector_nextPcCalc_valids_4;
+  reg  IBusCachedPlugin_injector_decodeRemoved;
+  wire  _zz_116_;
+  reg [18:0] _zz_117_;
+  wire  _zz_118_;
+  reg [10:0] _zz_119_;
+  wire  _zz_120_;
+  reg [18:0] _zz_121_;
+  reg  _zz_122_;
+  wire  _zz_123_;
+  reg [10:0] _zz_124_;
+  wire  _zz_125_;
+  reg [18:0] _zz_126_;
+  wire  iBus_cmd_valid;
+  wire  iBus_cmd_ready;
+  reg [31:0] iBus_cmd_payload_address;
+  wire [2:0] iBus_cmd_payload_size;
+  wire  iBus_rsp_valid;
+  wire [31:0] iBus_rsp_payload_data;
+  wire  iBus_rsp_payload_error;
+  wire [31:0] _zz_127_;
+  reg [31:0] IBusCachedPlugin_rspCounter;
+  wire  IBusCachedPlugin_s0_tightlyCoupledHit;
+  reg  IBusCachedPlugin_s1_tightlyCoupledHit;
+  reg  IBusCachedPlugin_s2_tightlyCoupledHit;
+  wire  IBusCachedPlugin_rsp_iBusRspOutputHalt;
+  reg  IBusCachedPlugin_rsp_redoFetch;
+  wire  dBus_cmd_valid;
+  wire  dBus_cmd_ready;
+  wire  dBus_cmd_payload_wr;
+  wire [31:0] dBus_cmd_payload_address;
+  wire [31:0] dBus_cmd_payload_data;
+  wire [1:0] dBus_cmd_payload_size;
+  wire  dBus_rsp_ready;
+  wire  dBus_rsp_error;
+  wire [31:0] dBus_rsp_data;
+  wire  _zz_128_;
+  reg  execute_DBusSimplePlugin_skipCmd;
+  reg [31:0] _zz_129_;
+  reg [3:0] _zz_130_;
+  wire [3:0] execute_DBusSimplePlugin_formalMask;
+  reg [31:0] writeBack_DBusSimplePlugin_rspShifted;
+  wire  _zz_131_;
+  reg [31:0] _zz_132_;
+  wire  _zz_133_;
+  reg [31:0] _zz_134_;
+  reg [31:0] writeBack_DBusSimplePlugin_rspFormated;
+  wire [29:0] _zz_135_;
+  wire  _zz_136_;
+  wire  _zz_137_;
+  wire  _zz_138_;
+  wire  _zz_139_;
+  wire  _zz_140_;
+  wire  _zz_141_;
+  wire `ShiftCtrlEnum_defaultEncoding_type _zz_142_;
+  wire `AluCtrlEnum_defaultEncoding_type _zz_143_;
+  wire `AluBitwiseCtrlEnum_defaultEncoding_type _zz_144_;
+  wire `BranchCtrlEnum_defaultEncoding_type _zz_145_;
+  wire `EnvCtrlEnum_defaultEncoding_type _zz_146_;
+  wire `Src2CtrlEnum_defaultEncoding_type _zz_147_;
+  wire `Src1CtrlEnum_defaultEncoding_type _zz_148_;
+  wire [4:0] decode_RegFilePlugin_regFileReadAddress1;
+  wire [4:0] decode_RegFilePlugin_regFileReadAddress2;
+  wire [31:0] decode_RegFilePlugin_rs1Data;
+  wire [31:0] decode_RegFilePlugin_rs2Data;
+  reg  lastStageRegFileWrite_valid /* verilator public */ ;
+  wire [4:0] lastStageRegFileWrite_payload_address /* verilator public */ ;
+  wire [31:0] lastStageRegFileWrite_payload_data /* verilator public */ ;
+  reg  _zz_149_;
+  reg [31:0] execute_IntAluPlugin_bitwise;
+  reg [31:0] _zz_150_;
+  reg [31:0] _zz_151_;
+  wire  _zz_152_;
+  reg [19:0] _zz_153_;
+  wire  _zz_154_;
+  reg [19:0] _zz_155_;
+  reg [31:0] _zz_156_;
+  reg [31:0] execute_SrcPlugin_addSub;
+  wire  execute_SrcPlugin_less;
+  reg  execute_LightShifterPlugin_isActive;
+  wire  execute_LightShifterPlugin_isShift;
+  reg [4:0] execute_LightShifterPlugin_amplitudeReg;
+  wire [4:0] execute_LightShifterPlugin_amplitude;
+  wire [31:0] execute_LightShifterPlugin_shiftInput;
+  wire  execute_LightShifterPlugin_done;
+  reg [31:0] _zz_157_;
+  reg  _zz_158_;
+  reg  _zz_159_;
+  wire  _zz_160_;
+  reg  _zz_161_;
+  reg [4:0] _zz_162_;
+  reg [31:0] _zz_163_;
+  wire  _zz_164_;
+  wire  _zz_165_;
+  wire  _zz_166_;
+  wire  _zz_167_;
+  wire  _zz_168_;
+  wire  _zz_169_;
+  wire  execute_BranchPlugin_eq;
+  wire [2:0] _zz_170_;
+  reg  _zz_171_;
+  reg  _zz_172_;
+  wire  _zz_173_;
+  reg [19:0] _zz_174_;
+  wire  _zz_175_;
+  reg [10:0] _zz_176_;
+  wire  _zz_177_;
+  reg [18:0] _zz_178_;
+  reg  _zz_179_;
+  wire  execute_BranchPlugin_missAlignedTarget;
+  reg [31:0] execute_BranchPlugin_branch_src1;
+  reg [31:0] execute_BranchPlugin_branch_src2;
+  wire  _zz_180_;
+  reg [19:0] _zz_181_;
+  wire  _zz_182_;
+  reg [10:0] _zz_183_;
+  wire  _zz_184_;
+  reg [18:0] _zz_185_;
+  wire [31:0] execute_BranchPlugin_branchAdder;
+  wire [1:0] CsrPlugin_misa_base;
+  wire [25:0] CsrPlugin_misa_extensions;
+  reg [1:0] CsrPlugin_mtvec_mode;
+  reg [29:0] CsrPlugin_mtvec_base;
+  reg [31:0] CsrPlugin_mepc;
+  reg  CsrPlugin_mstatus_MIE;
+  reg  CsrPlugin_mstatus_MPIE;
+  reg [1:0] CsrPlugin_mstatus_MPP;
+  reg  CsrPlugin_mip_MEIP;
+  reg  CsrPlugin_mip_MTIP;
+  reg  CsrPlugin_mip_MSIP;
+  reg  CsrPlugin_mie_MEIE;
+  reg  CsrPlugin_mie_MTIE;
+  reg  CsrPlugin_mie_MSIE;
+  reg  CsrPlugin_mcause_interrupt;
+  reg [3:0] CsrPlugin_mcause_exceptionCode;
+  reg [31:0] CsrPlugin_mtval;
+  reg [63:0] CsrPlugin_mcycle = 64'b0000000000000000000000000000000000000000000000000000000000000000;
+  reg [63:0] CsrPlugin_minstret = 64'b0000000000000000000000000000000000000000000000000000000000000000;
+  wire  _zz_186_;
+  wire  _zz_187_;
+  wire  _zz_188_;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValids_decode;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValids_execute;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValids_memory;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory;
+  reg  CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack;
+  reg [3:0] CsrPlugin_exceptionPortCtrl_exceptionContext_code;
+  reg [31:0] CsrPlugin_exceptionPortCtrl_exceptionContext_badAddr;
+  wire [1:0] CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilegeUncapped;
+  wire [1:0] CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilege;
+  wire [1:0] _zz_189_;
+  wire  _zz_190_;
+  wire [1:0] _zz_191_;
+  wire  _zz_192_;
+  reg  CsrPlugin_interrupt_valid;
+  reg [3:0] CsrPlugin_interrupt_code /* verilator public */ ;
+  reg [1:0] CsrPlugin_interrupt_targetPrivilege;
+  wire  CsrPlugin_exception;
+  wire  CsrPlugin_lastStageWasWfi;
+  reg  CsrPlugin_pipelineLiberator_done;
+  wire  CsrPlugin_interruptJump /* verilator public */ ;
+  reg  CsrPlugin_hadException;
+  reg [1:0] CsrPlugin_targetPrivilege;
+  reg [3:0] CsrPlugin_trapCause;
+  reg [1:0] CsrPlugin_xtvec_mode;
+  reg [29:0] CsrPlugin_xtvec_base;
+  wire  execute_CsrPlugin_inWfi /* verilator public */ ;
+  reg  execute_CsrPlugin_wfiWake;
+  wire  execute_CsrPlugin_blockedBySideEffects;
+  reg  execute_CsrPlugin_illegalAccess;
+  reg  execute_CsrPlugin_illegalInstruction;
+  reg [31:0] execute_CsrPlugin_readData;
+  wire  execute_CsrPlugin_writeInstruction;
+  wire  execute_CsrPlugin_readInstruction;
+  wire  execute_CsrPlugin_writeEnable;
+  wire  execute_CsrPlugin_readEnable;
+  wire [31:0] execute_CsrPlugin_readToWriteData;
+  reg [31:0] execute_CsrPlugin_writeData;
+  wire [11:0] execute_CsrPlugin_csrAddress;
+  reg [32:0] memory_MulDivIterativePlugin_rs1;
+  reg [31:0] memory_MulDivIterativePlugin_rs2;
+  reg [64:0] memory_MulDivIterativePlugin_accumulator;
+  reg  memory_MulDivIterativePlugin_mul_counter_willIncrement;
+  reg  memory_MulDivIterativePlugin_mul_counter_willClear;
+  reg [5:0] memory_MulDivIterativePlugin_mul_counter_valueNext;
+  reg [5:0] memory_MulDivIterativePlugin_mul_counter_value;
+  wire  memory_MulDivIterativePlugin_mul_willOverflowIfInc;
+  wire  memory_MulDivIterativePlugin_mul_counter_willOverflow;
+  reg  memory_MulDivIterativePlugin_div_needRevert;
+  reg  memory_MulDivIterativePlugin_div_counter_willIncrement;
+  reg  memory_MulDivIterativePlugin_div_counter_willClear;
+  reg [5:0] memory_MulDivIterativePlugin_div_counter_valueNext;
+  reg [5:0] memory_MulDivIterativePlugin_div_counter_value;
+  wire  memory_MulDivIterativePlugin_div_counter_willOverflowIfInc;
+  wire  memory_MulDivIterativePlugin_div_counter_willOverflow;
+  reg  memory_MulDivIterativePlugin_div_done;
+  reg [31:0] memory_MulDivIterativePlugin_div_result;
+  wire [31:0] _zz_193_;
+  wire [32:0] _zz_194_;
+  wire [32:0] _zz_195_;
+  wire [31:0] _zz_196_;
+  wire  _zz_197_;
+  wire  _zz_198_;
+  reg [32:0] _zz_199_;
+  reg [31:0] externalInterruptArray_regNext;
+  reg [31:0] _zz_200_;
+  wire [31:0] _zz_201_;
+  reg [31:0] decode_to_execute_INSTRUCTION;
+  reg [31:0] execute_to_memory_INSTRUCTION;
+  reg [31:0] memory_to_writeBack_INSTRUCTION;
+  reg  execute_to_memory_ALIGNEMENT_FAULT;
+  reg [31:0] memory_to_writeBack_MEMORY_READ_DATA;
+  reg `ShiftCtrlEnum_defaultEncoding_type decode_to_execute_SHIFT_CTRL;
+  reg  decode_to_execute_IS_CSR;
+  reg [31:0] decode_to_execute_PC;
+  reg [31:0] execute_to_memory_PC;
+  reg [31:0] memory_to_writeBack_PC;
+  reg  decode_to_execute_PREDICTION_HAD_BRANCHED2;
+  reg  decode_to_execute_MEMORY_STORE;
+  reg  execute_to_memory_MEMORY_STORE;
+  reg  memory_to_writeBack_MEMORY_STORE;
+  reg [31:0] decode_to_execute_FORMAL_PC_NEXT;
+  reg [31:0] execute_to_memory_FORMAL_PC_NEXT;
+  reg [31:0] memory_to_writeBack_FORMAL_PC_NEXT;
+  reg `EnvCtrlEnum_defaultEncoding_type decode_to_execute_ENV_CTRL;
+  reg `EnvCtrlEnum_defaultEncoding_type execute_to_memory_ENV_CTRL;
+  reg `EnvCtrlEnum_defaultEncoding_type memory_to_writeBack_ENV_CTRL;
+  reg  decode_to_execute_REGFILE_WRITE_VALID;
+  reg  execute_to_memory_REGFILE_WRITE_VALID;
+  reg  memory_to_writeBack_REGFILE_WRITE_VALID;
+  reg  decode_to_execute_SRC_LESS_UNSIGNED;
+  reg  execute_to_memory_BRANCH_DO;
+  reg [31:0] execute_to_memory_REGFILE_WRITE_DATA;
+  reg [31:0] memory_to_writeBack_REGFILE_WRITE_DATA;
+  reg  decode_to_execute_CSR_WRITE_OPCODE;
+  reg [31:0] decode_to_execute_RS1;
+  reg  decode_to_execute_SRC2_FORCE_ZERO;
+  reg  decode_to_execute_BYPASSABLE_MEMORY_STAGE;
+  reg  execute_to_memory_BYPASSABLE_MEMORY_STAGE;
+  reg `Src1CtrlEnum_defaultEncoding_type decode_to_execute_SRC1_CTRL;
+  reg `BranchCtrlEnum_defaultEncoding_type decode_to_execute_BRANCH_CTRL;
+  reg  decode_to_execute_MEMORY_ENABLE;
+  reg  execute_to_memory_MEMORY_ENABLE;
+  reg  memory_to_writeBack_MEMORY_ENABLE;
+  reg  decode_to_execute_SRC_USE_SUB_LESS;
+  reg  execute_to_memory_MMU_FAULT;
+  reg [31:0] execute_to_memory_BRANCH_CALC;
+  reg [31:0] decode_to_execute_RS2;
+  reg  decode_to_execute_IS_MUL;
+  reg  execute_to_memory_IS_MUL;
+  reg [1:0] execute_to_memory_MEMORY_ADDRESS_LOW;
+  reg [1:0] memory_to_writeBack_MEMORY_ADDRESS_LOW;
+  reg  decode_to_execute_IS_DIV;
+  reg  execute_to_memory_IS_DIV;
+  reg  decode_to_execute_CSR_READ_OPCODE;
+  reg  decode_to_execute_IS_RS1_SIGNED;
+  reg  decode_to_execute_BYPASSABLE_EXECUTE_STAGE;
+  reg [31:0] execute_to_memory_MMU_RSP_physicalAddress;
+  reg  execute_to_memory_MMU_RSP_isIoAccess;
+  reg  execute_to_memory_MMU_RSP_allowRead;
+  reg  execute_to_memory_MMU_RSP_allowWrite;
+  reg  execute_to_memory_MMU_RSP_allowExecute;
+  reg  execute_to_memory_MMU_RSP_exception;
+  reg  execute_to_memory_MMU_RSP_refilling;
+  reg  decode_to_execute_IS_RS2_SIGNED;
+  reg `Src2CtrlEnum_defaultEncoding_type decode_to_execute_SRC2_CTRL;
+  reg `AluBitwiseCtrlEnum_defaultEncoding_type decode_to_execute_ALU_BITWISE_CTRL;
+  reg `AluCtrlEnum_defaultEncoding_type decode_to_execute_ALU_CTRL;
+  reg [2:0] _zz_202_;
+  reg  _zz_203_;
+  reg [31:0] iBusWishbone_DAT_MISO_regNext;
+  wire  dBus_cmd_halfPipe_valid;
+  wire  dBus_cmd_halfPipe_ready;
+  wire  dBus_cmd_halfPipe_payload_wr;
+  wire [31:0] dBus_cmd_halfPipe_payload_address;
+  wire [31:0] dBus_cmd_halfPipe_payload_data;
+  wire [1:0] dBus_cmd_halfPipe_payload_size;
+  reg  dBus_cmd_halfPipe_regs_valid;
+  reg  dBus_cmd_halfPipe_regs_ready;
+  reg  dBus_cmd_halfPipe_regs_payload_wr;
+  reg [31:0] dBus_cmd_halfPipe_regs_payload_address;
+  reg [31:0] dBus_cmd_halfPipe_regs_payload_data;
+  reg [1:0] dBus_cmd_halfPipe_regs_payload_size;
+  reg [3:0] _zz_204_;
+  `ifndef SYNTHESIS
+  reg [63:0] decode_ALU_CTRL_string;
+  reg [63:0] _zz_1__string;
+  reg [63:0] _zz_2__string;
+  reg [63:0] _zz_3__string;
+  reg [39:0] decode_ALU_BITWISE_CTRL_string;
+  reg [39:0] _zz_4__string;
+  reg [39:0] _zz_5__string;
+  reg [39:0] _zz_6__string;
+  reg [23:0] decode_SRC2_CTRL_string;
+  reg [23:0] _zz_7__string;
+  reg [23:0] _zz_8__string;
+  reg [23:0] _zz_9__string;
+  reg [31:0] _zz_10__string;
+  reg [31:0] _zz_11__string;
+  reg [95:0] decode_SRC1_CTRL_string;
+  reg [95:0] _zz_12__string;
+  reg [95:0] _zz_13__string;
+  reg [95:0] _zz_14__string;
+  reg [31:0] _zz_15__string;
+  reg [31:0] _zz_16__string;
+  reg [31:0] _zz_17__string;
+  reg [31:0] _zz_18__string;
+  reg [31:0] decode_ENV_CTRL_string;
+  reg [31:0] _zz_19__string;
+  reg [31:0] _zz_20__string;
+  reg [31:0] _zz_21__string;
+  reg [71:0] decode_SHIFT_CTRL_string;
+  reg [71:0] _zz_22__string;
+  reg [71:0] _zz_23__string;
+  reg [71:0] _zz_24__string;
+  reg [31:0] memory_ENV_CTRL_string;
+  reg [31:0] _zz_25__string;
+  reg [31:0] execute_ENV_CTRL_string;
+  reg [31:0] _zz_26__string;
+  reg [31:0] writeBack_ENV_CTRL_string;
+  reg [31:0] _zz_29__string;
+  reg [31:0] execute_BRANCH_CTRL_string;
+  reg [31:0] _zz_32__string;
+  reg [71:0] execute_SHIFT_CTRL_string;
+  reg [71:0] _zz_37__string;
+  reg [23:0] execute_SRC2_CTRL_string;
+  reg [23:0] _zz_42__string;
+  reg [95:0] execute_SRC1_CTRL_string;
+  reg [95:0] _zz_44__string;
+  reg [63:0] execute_ALU_CTRL_string;
+  reg [63:0] _zz_47__string;
+  reg [39:0] execute_ALU_BITWISE_CTRL_string;
+  reg [39:0] _zz_49__string;
+  reg [95:0] _zz_56__string;
+  reg [23:0] _zz_59__string;
+  reg [31:0] _zz_67__string;
+  reg [31:0] _zz_68__string;
+  reg [39:0] _zz_70__string;
+  reg [63:0] _zz_72__string;
+  reg [71:0] _zz_73__string;
+  reg [31:0] decode_BRANCH_CTRL_string;
+  reg [31:0] _zz_95__string;
+  reg [71:0] _zz_142__string;
+  reg [63:0] _zz_143__string;
+  reg [39:0] _zz_144__string;
+  reg [31:0] _zz_145__string;
+  reg [31:0] _zz_146__string;
+  reg [23:0] _zz_147__string;
+  reg [95:0] _zz_148__string;
+  reg [71:0] decode_to_execute_SHIFT_CTRL_string;
+  reg [31:0] decode_to_execute_ENV_CTRL_string;
+  reg [31:0] execute_to_memory_ENV_CTRL_string;
+  reg [31:0] memory_to_writeBack_ENV_CTRL_string;
+  reg [95:0] decode_to_execute_SRC1_CTRL_string;
+  reg [31:0] decode_to_execute_BRANCH_CTRL_string;
+  reg [23:0] decode_to_execute_SRC2_CTRL_string;
+  reg [39:0] decode_to_execute_ALU_BITWISE_CTRL_string;
+  reg [63:0] decode_to_execute_ALU_CTRL_string;
+  `endif
+
+  (* ram_style = "block" *) reg [31:0] RegFilePlugin_regFile [0:31] /* verilator public */ ;
+  assign _zz_217_ = (memory_arbitration_isValid && memory_IS_MUL);
+  assign _zz_218_ = (memory_arbitration_isValid && memory_IS_DIV);
+  assign _zz_219_ = (writeBack_arbitration_isValid && writeBack_REGFILE_WRITE_VALID);
+  assign _zz_220_ = 1'b1;
+  assign _zz_221_ = (memory_arbitration_isValid && memory_REGFILE_WRITE_VALID);
+  assign _zz_222_ = (execute_arbitration_isValid && execute_REGFILE_WRITE_VALID);
+  assign _zz_223_ = ((execute_arbitration_isValid && execute_LightShifterPlugin_isShift) && (execute_SRC2[4 : 0] != (5'b00000)));
+  assign _zz_224_ = (execute_arbitration_isValid && execute_IS_CSR);
+  assign _zz_225_ = ((_zz_210_ && IBusCachedPlugin_cache_io_cpu_decode_error) && (! _zz_91_));
+  assign _zz_226_ = ((_zz_210_ && IBusCachedPlugin_cache_io_cpu_decode_cacheMiss) && (! _zz_92_));
+  assign _zz_227_ = ((_zz_210_ && IBusCachedPlugin_cache_io_cpu_decode_mmuException) && (! _zz_93_));
+  assign _zz_228_ = ((_zz_210_ && IBusCachedPlugin_cache_io_cpu_decode_mmuRefilling) && (! 1'b0));
+  assign _zz_229_ = ({decodeExceptionPort_valid,IBusCachedPlugin_decodeExceptionPort_valid} != (2'b00));
+  assign _zz_230_ = (! execute_arbitration_isStuckByOthers);
+  assign _zz_231_ = (! memory_MulDivIterativePlugin_mul_willOverflowIfInc);
+  assign _zz_232_ = (! memory_MulDivIterativePlugin_div_done);
+  assign _zz_233_ = ({BranchPlugin_branchExceptionPort_valid,DBusSimplePlugin_memoryExceptionPort_valid} != (2'b00));
+  assign _zz_234_ = (CsrPlugin_hadException || CsrPlugin_interruptJump);
+  assign _zz_235_ = (writeBack_arbitration_isValid && (writeBack_ENV_CTRL == `EnvCtrlEnum_defaultEncoding_XRET));
+  assign _zz_236_ = writeBack_INSTRUCTION[29 : 28];
+  assign _zz_237_ = (! IBusCachedPlugin_iBusRsp_readyForError);
+  assign _zz_238_ = ((dBus_rsp_ready && dBus_rsp_error) && (! memory_MEMORY_STORE));
+  assign _zz_239_ = (! ((memory_arbitration_isValid && memory_MEMORY_ENABLE) && (1'b1 || (! memory_arbitration_isStuckByOthers))));
+  assign _zz_240_ = (writeBack_arbitration_isValid && writeBack_REGFILE_WRITE_VALID);
+  assign _zz_241_ = (1'b0 || (! 1'b1));
+  assign _zz_242_ = (memory_arbitration_isValid && memory_REGFILE_WRITE_VALID);
+  assign _zz_243_ = (1'b0 || (! memory_BYPASSABLE_MEMORY_STAGE));
+  assign _zz_244_ = (execute_arbitration_isValid && execute_REGFILE_WRITE_VALID);
+  assign _zz_245_ = (1'b0 || (! execute_BYPASSABLE_EXECUTE_STAGE));
+  assign _zz_246_ = (! memory_arbitration_isStuck);
+  assign _zz_247_ = (iBus_cmd_valid || (_zz_202_ != (3'b000)));
+  assign _zz_248_ = (CsrPlugin_mstatus_MIE || (CsrPlugin_privilege < (2'b11)));
+  assign _zz_249_ = ((_zz_186_ && 1'b1) && (! 1'b0));
+  assign _zz_250_ = ((_zz_187_ && 1'b1) && (! 1'b0));
+  assign _zz_251_ = ((_zz_188_ && 1'b1) && (! 1'b0));
+  assign _zz_252_ = (! dBus_cmd_halfPipe_regs_valid);
+  assign _zz_253_ = writeBack_INSTRUCTION[13 : 12];
+  assign _zz_254_ = execute_INSTRUCTION[13];
+  assign _zz_255_ = (_zz_101_ - (5'b00001));
+  assign _zz_256_ = {IBusCachedPlugin_fetchPc_inc,(2'b00)};
+  assign _zz_257_ = {29'd0, _zz_256_};
+  assign _zz_258_ = {{{decode_INSTRUCTION[31],decode_INSTRUCTION[7]},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]};
+  assign _zz_259_ = {{_zz_117_,{{{decode_INSTRUCTION[31],decode_INSTRUCTION[7]},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]}},1'b0};
+  assign _zz_260_ = {{{decode_INSTRUCTION[31],decode_INSTRUCTION[19 : 12]},decode_INSTRUCTION[20]},decode_INSTRUCTION[30 : 21]};
+  assign _zz_261_ = {{{decode_INSTRUCTION[31],decode_INSTRUCTION[7]},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]};
+  assign _zz_262_ = {{_zz_119_,{{{decode_INSTRUCTION[31],decode_INSTRUCTION[19 : 12]},decode_INSTRUCTION[20]},decode_INSTRUCTION[30 : 21]}},1'b0};
+  assign _zz_263_ = {{_zz_121_,{{{decode_INSTRUCTION[31],decode_INSTRUCTION[7]},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]}},1'b0};
+  assign _zz_264_ = {{{decode_INSTRUCTION[31],decode_INSTRUCTION[19 : 12]},decode_INSTRUCTION[20]},decode_INSTRUCTION[30 : 21]};
+  assign _zz_265_ = {{{decode_INSTRUCTION[31],decode_INSTRUCTION[7]},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]};
+  assign _zz_266_ = (memory_MEMORY_STORE ? (3'b110) : (3'b100));
+  assign _zz_267_ = _zz_135_[0 : 0];
+  assign _zz_268_ = _zz_135_[1 : 1];
+  assign _zz_269_ = _zz_135_[2 : 2];
+  assign _zz_270_ = _zz_135_[3 : 3];
+  assign _zz_271_ = _zz_135_[8 : 8];
+  assign _zz_272_ = _zz_135_[11 : 11];
+  assign _zz_273_ = _zz_135_[15 : 15];
+  assign _zz_274_ = _zz_135_[16 : 16];
+  assign _zz_275_ = _zz_135_[17 : 17];
+  assign _zz_276_ = _zz_135_[18 : 18];
+  assign _zz_277_ = _zz_135_[19 : 19];
+  assign _zz_278_ = _zz_135_[20 : 20];
+  assign _zz_279_ = _zz_135_[21 : 21];
+  assign _zz_280_ = _zz_135_[24 : 24];
+  assign _zz_281_ = _zz_135_[26 : 26];
+  assign _zz_282_ = _zz_135_[29 : 29];
+  assign _zz_283_ = execute_SRC_LESS;
+  assign _zz_284_ = (3'b100);
+  assign _zz_285_ = execute_INSTRUCTION[19 : 15];
+  assign _zz_286_ = execute_INSTRUCTION[31 : 20];
+  assign _zz_287_ = {execute_INSTRUCTION[31 : 25],execute_INSTRUCTION[11 : 7]};
+  assign _zz_288_ = ($signed(_zz_289_) + $signed(_zz_292_));
+  assign _zz_289_ = ($signed(_zz_290_) + $signed(_zz_291_));
+  assign _zz_290_ = execute_SRC1;
+  assign _zz_291_ = (execute_SRC_USE_SUB_LESS ? (~ execute_SRC2) : execute_SRC2);
+  assign _zz_292_ = (execute_SRC_USE_SUB_LESS ? _zz_293_ : _zz_294_);
+  assign _zz_293_ = (32'b00000000000000000000000000000001);
+  assign _zz_294_ = (32'b00000000000000000000000000000000);
+  assign _zz_295_ = (_zz_296_ >>> 1);
+  assign _zz_296_ = {((execute_SHIFT_CTRL == `ShiftCtrlEnum_defaultEncoding_SRA_1) && execute_LightShifterPlugin_shiftInput[31]),execute_LightShifterPlugin_shiftInput};
+  assign _zz_297_ = execute_INSTRUCTION[31 : 20];
+  assign _zz_298_ = {{{execute_INSTRUCTION[31],execute_INSTRUCTION[19 : 12]},execute_INSTRUCTION[20]},execute_INSTRUCTION[30 : 21]};
+  assign _zz_299_ = {{{execute_INSTRUCTION[31],execute_INSTRUCTION[7]},execute_INSTRUCTION[30 : 25]},execute_INSTRUCTION[11 : 8]};
+  assign _zz_300_ = {_zz_174_,execute_INSTRUCTION[31 : 20]};
+  assign _zz_301_ = {{_zz_176_,{{{execute_INSTRUCTION[31],execute_INSTRUCTION[19 : 12]},execute_INSTRUCTION[20]},execute_INSTRUCTION[30 : 21]}},1'b0};
+  assign _zz_302_ = {{_zz_178_,{{{execute_INSTRUCTION[31],execute_INSTRUCTION[7]},execute_INSTRUCTION[30 : 25]},execute_INSTRUCTION[11 : 8]}},1'b0};
+  assign _zz_303_ = execute_INSTRUCTION[31 : 20];
+  assign _zz_304_ = {{{execute_INSTRUCTION[31],execute_INSTRUCTION[19 : 12]},execute_INSTRUCTION[20]},execute_INSTRUCTION[30 : 21]};
+  assign _zz_305_ = {{{execute_INSTRUCTION[31],execute_INSTRUCTION[7]},execute_INSTRUCTION[30 : 25]},execute_INSTRUCTION[11 : 8]};
+  assign _zz_306_ = (3'b100);
+  assign _zz_307_ = (_zz_189_ & (~ _zz_308_));
+  assign _zz_308_ = (_zz_189_ - (2'b01));
+  assign _zz_309_ = (_zz_191_ & (~ _zz_310_));
+  assign _zz_310_ = (_zz_191_ - (2'b01));
+  assign _zz_311_ = memory_MulDivIterativePlugin_mul_counter_willIncrement;
+  assign _zz_312_ = {5'd0, _zz_311_};
+  assign _zz_313_ = (_zz_315_ + _zz_317_);
+  assign _zz_314_ = (memory_MulDivIterativePlugin_rs2[0] ? memory_MulDivIterativePlugin_rs1 : (33'b000000000000000000000000000000000));
+  assign _zz_315_ = {{1{_zz_314_[32]}}, _zz_314_};
+  assign _zz_316_ = _zz_318_;
+  assign _zz_317_ = {{1{_zz_316_[32]}}, _zz_316_};
+  assign _zz_318_ = (memory_MulDivIterativePlugin_accumulator >>> 32);
+  assign _zz_319_ = memory_MulDivIterativePlugin_div_counter_willIncrement;
+  assign _zz_320_ = {5'd0, _zz_319_};
+  assign _zz_321_ = {1'd0, memory_MulDivIterativePlugin_rs2};
+  assign _zz_322_ = {_zz_193_,(! _zz_195_[32])};
+  assign _zz_323_ = _zz_195_[31:0];
+  assign _zz_324_ = _zz_194_[31:0];
+  assign _zz_325_ = _zz_326_;
+  assign _zz_326_ = _zz_327_;
+  assign _zz_327_ = ({1'b0,(memory_MulDivIterativePlugin_div_needRevert ? (~ _zz_196_) : _zz_196_)} + _zz_329_);
+  assign _zz_328_ = memory_MulDivIterativePlugin_div_needRevert;
+  assign _zz_329_ = {32'd0, _zz_328_};
+  assign _zz_330_ = _zz_198_;
+  assign _zz_331_ = {32'd0, _zz_330_};
+  assign _zz_332_ = _zz_197_;
+  assign _zz_333_ = {31'd0, _zz_332_};
+  assign _zz_334_ = execute_CsrPlugin_writeData[7 : 7];
+  assign _zz_335_ = execute_CsrPlugin_writeData[3 : 3];
+  assign _zz_336_ = execute_CsrPlugin_writeData[3 : 3];
+  assign _zz_337_ = execute_CsrPlugin_writeData[11 : 11];
+  assign _zz_338_ = execute_CsrPlugin_writeData[7 : 7];
+  assign _zz_339_ = execute_CsrPlugin_writeData[3 : 3];
+  assign _zz_340_ = (iBus_cmd_payload_address >>> 5);
+  assign _zz_341_ = ({3'd0,_zz_204_} <<< dBus_cmd_halfPipe_payload_address[1 : 0]);
+  assign _zz_342_ = 1'b1;
+  assign _zz_343_ = 1'b1;
+  assign _zz_344_ = {_zz_104_,{_zz_106_,_zz_105_}};
+  assign _zz_345_ = decode_INSTRUCTION[31];
+  assign _zz_346_ = decode_INSTRUCTION[31];
+  assign _zz_347_ = decode_INSTRUCTION[7];
+  assign _zz_348_ = ((decode_INSTRUCTION & (32'b00000000000000000000000000010100)) == (32'b00000000000000000000000000000100));
+  assign _zz_349_ = ((decode_INSTRUCTION & _zz_356_) == (32'b00000000000000000000000000000100));
+  assign _zz_350_ = _zz_141_;
+  assign _zz_351_ = ((decode_INSTRUCTION & _zz_357_) == (32'b00000010000000000100000000100000));
+  assign _zz_352_ = (1'b0);
+  assign _zz_353_ = ({_zz_358_,{_zz_359_,_zz_360_}} != (3'b000));
+  assign _zz_354_ = ({_zz_361_,_zz_362_} != (2'b00));
+  assign _zz_355_ = {(_zz_363_ != _zz_364_),{_zz_365_,{_zz_366_,_zz_367_}}};
+  assign _zz_356_ = (32'b00000000000000000000000001000100);
+  assign _zz_357_ = (32'b00000010000000000100000001100100);
+  assign _zz_358_ = ((decode_INSTRUCTION & (32'b00000000000000000000000001010000)) == (32'b00000000000000000000000001000000));
+  assign _zz_359_ = ((decode_INSTRUCTION & _zz_368_) == (32'b00000000000000000000000001000000));
+  assign _zz_360_ = ((decode_INSTRUCTION & _zz_369_) == (32'b00000000000000000000000000000000));
+  assign _zz_361_ = _zz_140_;
+  assign _zz_362_ = _zz_139_;
+  assign _zz_363_ = {_zz_136_,(_zz_370_ == _zz_371_)};
+  assign _zz_364_ = (2'b00);
+  assign _zz_365_ = ({_zz_136_,_zz_372_} != (2'b00));
+  assign _zz_366_ = ({_zz_373_,_zz_374_} != (3'b000));
+  assign _zz_367_ = {(_zz_375_ != _zz_376_),{_zz_377_,{_zz_378_,_zz_379_}}};
+  assign _zz_368_ = (32'b00000000000000000011000001000000);
+  assign _zz_369_ = (32'b00000000000000000000000000111000);
+  assign _zz_370_ = (decode_INSTRUCTION & (32'b00000000000000000000000001110000));
+  assign _zz_371_ = (32'b00000000000000000000000000100000);
+  assign _zz_372_ = ((decode_INSTRUCTION & (32'b00000000000000000000000000100000)) == (32'b00000000000000000000000000000000));
+  assign _zz_373_ = ((decode_INSTRUCTION & _zz_380_) == (32'b00000000000000000000000001000000));
+  assign _zz_374_ = {(_zz_381_ == _zz_382_),(_zz_383_ == _zz_384_)};
+  assign _zz_375_ = ((decode_INSTRUCTION & _zz_385_) == (32'b00000000000000000000000000100000));
+  assign _zz_376_ = (1'b0);
+  assign _zz_377_ = ((_zz_386_ == _zz_387_) != (1'b0));
+  assign _zz_378_ = ({_zz_388_,_zz_389_} != (2'b00));
+  assign _zz_379_ = {(_zz_390_ != _zz_391_),{_zz_392_,{_zz_393_,_zz_394_}}};
+  assign _zz_380_ = (32'b00000000000000000000000001000100);
+  assign _zz_381_ = (decode_INSTRUCTION & (32'b00000000000000000010000000010100));
+  assign _zz_382_ = (32'b00000000000000000010000000010000);
+  assign _zz_383_ = (decode_INSTRUCTION & (32'b01000000000000000100000000110100));
+  assign _zz_384_ = (32'b01000000000000000000000000110000);
+  assign _zz_385_ = (32'b00000000000000000000000000100000);
+  assign _zz_386_ = (decode_INSTRUCTION & (32'b00000000000000000001000001001000));
+  assign _zz_387_ = (32'b00000000000000000001000000001000);
+  assign _zz_388_ = ((decode_INSTRUCTION & _zz_395_) == (32'b00000000000000000000000000100000));
+  assign _zz_389_ = ((decode_INSTRUCTION & _zz_396_) == (32'b00000000000000000000000000100000));
+  assign _zz_390_ = {_zz_138_,{_zz_397_,{_zz_398_,_zz_399_}}};
+  assign _zz_391_ = (6'b000000);
+  assign _zz_392_ = ({_zz_400_,_zz_401_} != (2'b00));
+  assign _zz_393_ = ({_zz_402_,_zz_403_} != (4'b0000));
+  assign _zz_394_ = {(_zz_404_ != _zz_405_),{_zz_406_,{_zz_407_,_zz_408_}}};
+  assign _zz_395_ = (32'b00000000000000000000000000110100);
+  assign _zz_396_ = (32'b00000000000000000000000001100100);
+  assign _zz_397_ = ((decode_INSTRUCTION & _zz_409_) == (32'b00000000000000000001000000010000));
+  assign _zz_398_ = (_zz_410_ == _zz_411_);
+  assign _zz_399_ = {_zz_412_,{_zz_413_,_zz_414_}};
+  assign _zz_400_ = ((decode_INSTRUCTION & _zz_415_) == (32'b00000000000000000010000000000000));
+  assign _zz_401_ = ((decode_INSTRUCTION & _zz_416_) == (32'b00000000000000000001000000000000));
+  assign _zz_402_ = (_zz_417_ == _zz_418_);
+  assign _zz_403_ = {_zz_419_,{_zz_420_,_zz_421_}};
+  assign _zz_404_ = (_zz_422_ == _zz_423_);
+  assign _zz_405_ = (1'b0);
+  assign _zz_406_ = ({_zz_424_,_zz_425_} != (2'b00));
+  assign _zz_407_ = (_zz_426_ != _zz_427_);
+  assign _zz_408_ = {_zz_428_,{_zz_429_,_zz_430_}};
+  assign _zz_409_ = (32'b00000000000000000001000000010000);
+  assign _zz_410_ = (decode_INSTRUCTION & (32'b00000000000000000010000000010000));
+  assign _zz_411_ = (32'b00000000000000000010000000010000);
+  assign _zz_412_ = ((decode_INSTRUCTION & _zz_431_) == (32'b00000000000000000000000000010000));
+  assign _zz_413_ = (_zz_432_ == _zz_433_);
+  assign _zz_414_ = (_zz_434_ == _zz_435_);
+  assign _zz_415_ = (32'b00000000000000000010000000010000);
+  assign _zz_416_ = (32'b00000000000000000101000000000000);
+  assign _zz_417_ = (decode_INSTRUCTION & (32'b00000000000000000000000001000100));
+  assign _zz_418_ = (32'b00000000000000000000000000000000);
+  assign _zz_419_ = ((decode_INSTRUCTION & _zz_436_) == (32'b00000000000000000000000000000000));
+  assign _zz_420_ = (_zz_437_ == _zz_438_);
+  assign _zz_421_ = (_zz_439_ == _zz_440_);
+  assign _zz_422_ = (decode_INSTRUCTION & (32'b00000000000000000011000001010000));
+  assign _zz_423_ = (32'b00000000000000000000000001010000);
+  assign _zz_424_ = _zz_138_;
+  assign _zz_425_ = (_zz_441_ == _zz_442_);
+  assign _zz_426_ = (_zz_443_ == _zz_444_);
+  assign _zz_427_ = (1'b0);
+  assign _zz_428_ = (_zz_445_ != (1'b0));
+  assign _zz_429_ = (_zz_446_ != _zz_447_);
+  assign _zz_430_ = {_zz_448_,{_zz_449_,_zz_450_}};
+  assign _zz_431_ = (32'b00000000000000000000000001010000);
+  assign _zz_432_ = (decode_INSTRUCTION & (32'b00000000000000000000000000001100));
+  assign _zz_433_ = (32'b00000000000000000000000000000100);
+  assign _zz_434_ = (decode_INSTRUCTION & (32'b00000000000000000000000000101000));
+  assign _zz_435_ = (32'b00000000000000000000000000000000);
+  assign _zz_436_ = (32'b00000000000000000000000000011000);
+  assign _zz_437_ = (decode_INSTRUCTION & (32'b00000000000000000110000000000100));
+  assign _zz_438_ = (32'b00000000000000000010000000000000);
+  assign _zz_439_ = (decode_INSTRUCTION & (32'b00000000000000000101000000000100));
+  assign _zz_440_ = (32'b00000000000000000001000000000000);
+  assign _zz_441_ = (decode_INSTRUCTION & (32'b00000000000000000000000000011100));
+  assign _zz_442_ = (32'b00000000000000000000000000000100);
+  assign _zz_443_ = (decode_INSTRUCTION & (32'b00000000000000000000000001011000));
+  assign _zz_444_ = (32'b00000000000000000000000001000000);
+  assign _zz_445_ = ((decode_INSTRUCTION & (32'b00000010000000000100000001110100)) == (32'b00000010000000000000000000110000));
+  assign _zz_446_ = ((decode_INSTRUCTION & (32'b00000000000000000001000000000000)) == (32'b00000000000000000001000000000000));
+  assign _zz_447_ = (1'b0);
+  assign _zz_448_ = (_zz_137_ != (1'b0));
+  assign _zz_449_ = ({_zz_451_,{_zz_452_,_zz_453_}} != (3'b000));
+  assign _zz_450_ = {({_zz_454_,_zz_455_} != (2'b00)),{(_zz_456_ != _zz_457_),{_zz_458_,{_zz_459_,_zz_460_}}}};
+  assign _zz_451_ = ((decode_INSTRUCTION & (32'b00000000000000000000000001100100)) == (32'b00000000000000000000000000100100));
+  assign _zz_452_ = ((decode_INSTRUCTION & _zz_461_) == (32'b00000000000000000001000000010000));
+  assign _zz_453_ = ((decode_INSTRUCTION & _zz_462_) == (32'b00000000000000000001000000010000));
+  assign _zz_454_ = ((decode_INSTRUCTION & _zz_463_) == (32'b00000000000000000110000000010000));
+  assign _zz_455_ = ((decode_INSTRUCTION & _zz_464_) == (32'b00000000000000000100000000010000));
+  assign _zz_456_ = ((decode_INSTRUCTION & _zz_465_) == (32'b00000000000000000010000000010000));
+  assign _zz_457_ = (1'b0);
+  assign _zz_458_ = ({_zz_466_,_zz_467_} != (2'b00));
+  assign _zz_459_ = ({_zz_468_,_zz_469_} != (3'b000));
+  assign _zz_460_ = {(_zz_470_ != _zz_471_),{_zz_472_,{_zz_473_,_zz_474_}}};
+  assign _zz_461_ = (32'b00000000000000000011000000110100);
+  assign _zz_462_ = (32'b00000010000000000011000001010100);
+  assign _zz_463_ = (32'b00000000000000000110000000010100);
+  assign _zz_464_ = (32'b00000000000000000101000000010100);
+  assign _zz_465_ = (32'b00000000000000000110000000010100);
+  assign _zz_466_ = ((decode_INSTRUCTION & (32'b00000000000000000111000000110100)) == (32'b00000000000000000101000000010000));
+  assign _zz_467_ = ((decode_INSTRUCTION & (32'b00000010000000000111000001100100)) == (32'b00000000000000000101000000100000));
+  assign _zz_468_ = ((decode_INSTRUCTION & _zz_475_) == (32'b01000000000000000001000000010000));
+  assign _zz_469_ = {(_zz_476_ == _zz_477_),(_zz_478_ == _zz_479_)};
+  assign _zz_470_ = {_zz_136_,{_zz_480_,_zz_481_}};
+  assign _zz_471_ = (3'b000);
+  assign _zz_472_ = ((_zz_482_ == _zz_483_) != (1'b0));
+  assign _zz_473_ = ({_zz_484_,_zz_485_} != (2'b00));
+  assign _zz_474_ = (_zz_486_ != (1'b0));
+  assign _zz_475_ = (32'b01000000000000000011000001010100);
+  assign _zz_476_ = (decode_INSTRUCTION & (32'b00000000000000000111000000110100));
+  assign _zz_477_ = (32'b00000000000000000001000000010000);
+  assign _zz_478_ = (decode_INSTRUCTION & (32'b00000010000000000111000001010100));
+  assign _zz_479_ = (32'b00000000000000000001000000010000);
+  assign _zz_480_ = ((decode_INSTRUCTION & (32'b00000000000000000000000000110000)) == (32'b00000000000000000000000000010000));
+  assign _zz_481_ = ((decode_INSTRUCTION & (32'b00000010000000000000000001100000)) == (32'b00000000000000000000000000100000));
+  assign _zz_482_ = (decode_INSTRUCTION & (32'b00000000000000000000000001011000));
+  assign _zz_483_ = (32'b00000000000000000000000000000000);
+  assign _zz_484_ = ((decode_INSTRUCTION & (32'b00000000000000000001000001010000)) == (32'b00000000000000000001000001010000));
+  assign _zz_485_ = ((decode_INSTRUCTION & (32'b00000000000000000010000001010000)) == (32'b00000000000000000010000001010000));
+  assign _zz_486_ = ((decode_INSTRUCTION & (32'b00000000000000000000000000010000)) == (32'b00000000000000000000000000010000));
+  assign _zz_487_ = (32'b00000000000000000001000001111111);
+  assign _zz_488_ = (decode_INSTRUCTION & (32'b00000000000000000010000001111111));
+  assign _zz_489_ = (32'b00000000000000000010000001110011);
+  assign _zz_490_ = ((decode_INSTRUCTION & (32'b00000000000000000100000001111111)) == (32'b00000000000000000100000001100011));
+  assign _zz_491_ = ((decode_INSTRUCTION & (32'b00000000000000000010000001111111)) == (32'b00000000000000000010000000010011));
+  assign _zz_492_ = {((decode_INSTRUCTION & (32'b00000000000000000110000000111111)) == (32'b00000000000000000000000000100011)),{((decode_INSTRUCTION & (32'b00000000000000000010000001111111)) == (32'b00000000000000000000000000000011)),{((decode_INSTRUCTION & _zz_493_) == (32'b00000000000000000000000000000011)),{(_zz_494_ == _zz_495_),{_zz_496_,{_zz_497_,_zz_498_}}}}}};
+  assign _zz_493_ = (32'b00000000000000000101000001011111);
+  assign _zz_494_ = (decode_INSTRUCTION & (32'b00000000000000000111000001111011));
+  assign _zz_495_ = (32'b00000000000000000000000001100011);
+  assign _zz_496_ = ((decode_INSTRUCTION & (32'b00000000000000000110000001111111)) == (32'b00000000000000000000000000001111));
+  assign _zz_497_ = ((decode_INSTRUCTION & (32'b11111100000000000000000001111111)) == (32'b00000000000000000000000000110011));
+  assign _zz_498_ = {((decode_INSTRUCTION & (32'b11111100000000000011000001011111)) == (32'b00000000000000000001000000010011)),{((decode_INSTRUCTION & (32'b10111100000000000111000001111111)) == (32'b00000000000000000101000000010011)),{((decode_INSTRUCTION & _zz_499_) == (32'b00000000000000000101000000110011)),{(_zz_500_ == _zz_501_),(_zz_502_ == _zz_503_)}}}};
+  assign _zz_499_ = (32'b10111110000000000111000001111111);
+  assign _zz_500_ = (decode_INSTRUCTION & (32'b10111110000000000111000001111111));
+  assign _zz_501_ = (32'b00000000000000000000000000110011);
+  assign _zz_502_ = (decode_INSTRUCTION & (32'b11011111111111111111111111111111));
+  assign _zz_503_ = (32'b00010000001000000000000001110011);
+  assign _zz_504_ = execute_INSTRUCTION[31];
+  assign _zz_505_ = execute_INSTRUCTION[31];
+  assign _zz_506_ = execute_INSTRUCTION[7];
+  always @ (posedge clk) begin
+    if(_zz_52_) begin
+      RegFilePlugin_regFile[lastStageRegFileWrite_payload_address] <= lastStageRegFileWrite_payload_data;
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(_zz_342_) begin
+      _zz_214_ <= RegFilePlugin_regFile[decode_RegFilePlugin_regFileReadAddress1];
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(_zz_343_) begin
+      _zz_215_ <= RegFilePlugin_regFile[decode_RegFilePlugin_regFileReadAddress2];
+    end
+  end
+
+  InstructionCache IBusCachedPlugin_cache ( 
+    .io_flush(_zz_205_),
+    .io_cpu_prefetch_isValid(_zz_206_),
+    .io_cpu_prefetch_haltIt(IBusCachedPlugin_cache_io_cpu_prefetch_haltIt),
+    .io_cpu_prefetch_pc(IBusCachedPlugin_iBusRsp_stages_0_input_payload),
+    .io_cpu_fetch_isValid(_zz_207_),
+    .io_cpu_fetch_isStuck(_zz_208_),
+    .io_cpu_fetch_isRemoved(IBusCachedPlugin_fetcherflushIt),
+    .io_cpu_fetch_pc(IBusCachedPlugin_iBusRsp_stages_1_input_payload),
+    .io_cpu_fetch_data(IBusCachedPlugin_cache_io_cpu_fetch_data),
+    .io_cpu_fetch_dataBypassValid(IBusCachedPlugin_s1_tightlyCoupledHit),
+    .io_cpu_fetch_dataBypass(_zz_209_),
+    .io_cpu_fetch_mmuBus_cmd_isValid(IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_isValid),
+    .io_cpu_fetch_mmuBus_cmd_virtualAddress(IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_virtualAddress),
+    .io_cpu_fetch_mmuBus_cmd_bypassTranslation(IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_bypassTranslation),
+    .io_cpu_fetch_mmuBus_rsp_physicalAddress(IBusCachedPlugin_mmuBus_rsp_physicalAddress),
+    .io_cpu_fetch_mmuBus_rsp_isIoAccess(IBusCachedPlugin_mmuBus_rsp_isIoAccess),
+    .io_cpu_fetch_mmuBus_rsp_allowRead(IBusCachedPlugin_mmuBus_rsp_allowRead),
+    .io_cpu_fetch_mmuBus_rsp_allowWrite(IBusCachedPlugin_mmuBus_rsp_allowWrite),
+    .io_cpu_fetch_mmuBus_rsp_allowExecute(IBusCachedPlugin_mmuBus_rsp_allowExecute),
+    .io_cpu_fetch_mmuBus_rsp_exception(IBusCachedPlugin_mmuBus_rsp_exception),
+    .io_cpu_fetch_mmuBus_rsp_refilling(IBusCachedPlugin_mmuBus_rsp_refilling),
+    .io_cpu_fetch_mmuBus_end(IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_end),
+    .io_cpu_fetch_mmuBus_busy(IBusCachedPlugin_mmuBus_busy),
+    .io_cpu_fetch_physicalAddress(IBusCachedPlugin_cache_io_cpu_fetch_physicalAddress),
+    .io_cpu_fetch_haltIt(IBusCachedPlugin_cache_io_cpu_fetch_haltIt),
+    .io_cpu_decode_isValid(_zz_210_),
+    .io_cpu_decode_isStuck(_zz_211_),
+    .io_cpu_decode_pc(IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload),
+    .io_cpu_decode_physicalAddress(IBusCachedPlugin_cache_io_cpu_decode_physicalAddress),
+    .io_cpu_decode_data(IBusCachedPlugin_cache_io_cpu_decode_data),
+    .io_cpu_decode_cacheMiss(IBusCachedPlugin_cache_io_cpu_decode_cacheMiss),
+    .io_cpu_decode_error(IBusCachedPlugin_cache_io_cpu_decode_error),
+    .io_cpu_decode_mmuRefilling(IBusCachedPlugin_cache_io_cpu_decode_mmuRefilling),
+    .io_cpu_decode_mmuException(IBusCachedPlugin_cache_io_cpu_decode_mmuException),
+    .io_cpu_decode_isUser(_zz_212_),
+    .io_cpu_fill_valid(_zz_213_),
+    .io_cpu_fill_payload(IBusCachedPlugin_cache_io_cpu_decode_physicalAddress),
+    .io_mem_cmd_valid(IBusCachedPlugin_cache_io_mem_cmd_valid),
+    .io_mem_cmd_ready(iBus_cmd_ready),
+    .io_mem_cmd_payload_address(IBusCachedPlugin_cache_io_mem_cmd_payload_address),
+    .io_mem_cmd_payload_size(IBusCachedPlugin_cache_io_mem_cmd_payload_size),
+    .io_mem_rsp_valid(iBus_rsp_valid),
+    .io_mem_rsp_payload_data(iBus_rsp_payload_data),
+    .io_mem_rsp_payload_error(iBus_rsp_payload_error),
+    .clk(clk),
+    .reset(reset) 
+  );
+  always @(*) begin
+    case(_zz_344_)
+      3'b000 : begin
+        _zz_216_ = CsrPlugin_jumpInterface_payload;
+      end
+      3'b001 : begin
+        _zz_216_ = DBusSimplePlugin_redoBranch_payload;
+      end
+      3'b010 : begin
+        _zz_216_ = BranchPlugin_jumpInterface_payload;
+      end
+      3'b011 : begin
+        _zz_216_ = IBusCachedPlugin_redoBranch_payload;
+      end
+      default : begin
+        _zz_216_ = IBusCachedPlugin_predictionJumpInterface_payload;
+      end
+    endcase
+  end
+
+  `ifndef SYNTHESIS
+  always @(*) begin
+    case(decode_ALU_CTRL)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : decode_ALU_CTRL_string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : decode_ALU_CTRL_string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : decode_ALU_CTRL_string = "BITWISE ";
+      default : decode_ALU_CTRL_string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_1_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_1__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_1__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_1__string = "BITWISE ";
+      default : _zz_1__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_2_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_2__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_2__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_2__string = "BITWISE ";
+      default : _zz_2__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_3_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_3__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_3__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_3__string = "BITWISE ";
+      default : _zz_3__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_ALU_BITWISE_CTRL)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : decode_ALU_BITWISE_CTRL_string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : decode_ALU_BITWISE_CTRL_string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : decode_ALU_BITWISE_CTRL_string = "AND_1";
+      default : decode_ALU_BITWISE_CTRL_string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_4_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_4__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_4__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_4__string = "AND_1";
+      default : _zz_4__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_5_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_5__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_5__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_5__string = "AND_1";
+      default : _zz_5__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_6_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_6__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_6__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_6__string = "AND_1";
+      default : _zz_6__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_SRC2_CTRL)
+      `Src2CtrlEnum_defaultEncoding_RS : decode_SRC2_CTRL_string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : decode_SRC2_CTRL_string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : decode_SRC2_CTRL_string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : decode_SRC2_CTRL_string = "PC ";
+      default : decode_SRC2_CTRL_string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_7_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_7__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_7__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_7__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_7__string = "PC ";
+      default : _zz_7__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_8_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_8__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_8__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_8__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_8__string = "PC ";
+      default : _zz_8__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_9_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_9__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_9__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_9__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_9__string = "PC ";
+      default : _zz_9__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_10_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_10__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_10__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_10__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_10__string = "JALR";
+      default : _zz_10__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_11_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_11__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_11__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_11__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_11__string = "JALR";
+      default : _zz_11__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_SRC1_CTRL)
+      `Src1CtrlEnum_defaultEncoding_RS : decode_SRC1_CTRL_string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : decode_SRC1_CTRL_string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : decode_SRC1_CTRL_string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : decode_SRC1_CTRL_string = "URS1        ";
+      default : decode_SRC1_CTRL_string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_12_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_12__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_12__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_12__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_12__string = "URS1        ";
+      default : _zz_12__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_13_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_13__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_13__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_13__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_13__string = "URS1        ";
+      default : _zz_13__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_14_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_14__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_14__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_14__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_14__string = "URS1        ";
+      default : _zz_14__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_15_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_15__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_15__string = "XRET";
+      default : _zz_15__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_16_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_16__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_16__string = "XRET";
+      default : _zz_16__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_17_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_17__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_17__string = "XRET";
+      default : _zz_17__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_18_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_18__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_18__string = "XRET";
+      default : _zz_18__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : decode_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : decode_ENV_CTRL_string = "XRET";
+      default : decode_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_19_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_19__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_19__string = "XRET";
+      default : _zz_19__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_20_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_20__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_20__string = "XRET";
+      default : _zz_20__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_21_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_21__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_21__string = "XRET";
+      default : _zz_21__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_SHIFT_CTRL)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : decode_SHIFT_CTRL_string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : decode_SHIFT_CTRL_string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : decode_SHIFT_CTRL_string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : decode_SHIFT_CTRL_string = "SRA_1    ";
+      default : decode_SHIFT_CTRL_string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_22_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_22__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_22__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_22__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_22__string = "SRA_1    ";
+      default : _zz_22__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_23_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_23__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_23__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_23__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_23__string = "SRA_1    ";
+      default : _zz_23__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_24_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_24__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_24__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_24__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_24__string = "SRA_1    ";
+      default : _zz_24__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(memory_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : memory_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : memory_ENV_CTRL_string = "XRET";
+      default : memory_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_25_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_25__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_25__string = "XRET";
+      default : _zz_25__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : execute_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : execute_ENV_CTRL_string = "XRET";
+      default : execute_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_26_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_26__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_26__string = "XRET";
+      default : _zz_26__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(writeBack_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : writeBack_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : writeBack_ENV_CTRL_string = "XRET";
+      default : writeBack_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_29_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_29__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_29__string = "XRET";
+      default : _zz_29__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_INC : execute_BRANCH_CTRL_string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : execute_BRANCH_CTRL_string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : execute_BRANCH_CTRL_string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : execute_BRANCH_CTRL_string = "JALR";
+      default : execute_BRANCH_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_32_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_32__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_32__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_32__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_32__string = "JALR";
+      default : _zz_32__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_SHIFT_CTRL)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : execute_SHIFT_CTRL_string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : execute_SHIFT_CTRL_string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : execute_SHIFT_CTRL_string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : execute_SHIFT_CTRL_string = "SRA_1    ";
+      default : execute_SHIFT_CTRL_string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_37_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_37__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_37__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_37__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_37__string = "SRA_1    ";
+      default : _zz_37__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_SRC2_CTRL)
+      `Src2CtrlEnum_defaultEncoding_RS : execute_SRC2_CTRL_string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : execute_SRC2_CTRL_string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : execute_SRC2_CTRL_string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : execute_SRC2_CTRL_string = "PC ";
+      default : execute_SRC2_CTRL_string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_42_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_42__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_42__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_42__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_42__string = "PC ";
+      default : _zz_42__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(execute_SRC1_CTRL)
+      `Src1CtrlEnum_defaultEncoding_RS : execute_SRC1_CTRL_string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : execute_SRC1_CTRL_string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : execute_SRC1_CTRL_string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : execute_SRC1_CTRL_string = "URS1        ";
+      default : execute_SRC1_CTRL_string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_44_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_44__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_44__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_44__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_44__string = "URS1        ";
+      default : _zz_44__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_ALU_CTRL)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : execute_ALU_CTRL_string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : execute_ALU_CTRL_string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : execute_ALU_CTRL_string = "BITWISE ";
+      default : execute_ALU_CTRL_string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_47_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_47__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_47__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_47__string = "BITWISE ";
+      default : _zz_47__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_ALU_BITWISE_CTRL)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : execute_ALU_BITWISE_CTRL_string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : execute_ALU_BITWISE_CTRL_string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : execute_ALU_BITWISE_CTRL_string = "AND_1";
+      default : execute_ALU_BITWISE_CTRL_string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_49_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_49__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_49__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_49__string = "AND_1";
+      default : _zz_49__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_56_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_56__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_56__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_56__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_56__string = "URS1        ";
+      default : _zz_56__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_59_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_59__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_59__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_59__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_59__string = "PC ";
+      default : _zz_59__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_67_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_67__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_67__string = "XRET";
+      default : _zz_67__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_68_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_68__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_68__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_68__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_68__string = "JALR";
+      default : _zz_68__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_70_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_70__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_70__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_70__string = "AND_1";
+      default : _zz_70__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_72_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_72__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_72__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_72__string = "BITWISE ";
+      default : _zz_72__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_73_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_73__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_73__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_73__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_73__string = "SRA_1    ";
+      default : _zz_73__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_INC : decode_BRANCH_CTRL_string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : decode_BRANCH_CTRL_string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : decode_BRANCH_CTRL_string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : decode_BRANCH_CTRL_string = "JALR";
+      default : decode_BRANCH_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_95_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_95__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_95__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_95__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_95__string = "JALR";
+      default : _zz_95__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_142_)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : _zz_142__string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : _zz_142__string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : _zz_142__string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : _zz_142__string = "SRA_1    ";
+      default : _zz_142__string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_143_)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : _zz_143__string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : _zz_143__string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : _zz_143__string = "BITWISE ";
+      default : _zz_143__string = "????????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_144_)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : _zz_144__string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : _zz_144__string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : _zz_144__string = "AND_1";
+      default : _zz_144__string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_145_)
+      `BranchCtrlEnum_defaultEncoding_INC : _zz_145__string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : _zz_145__string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : _zz_145__string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : _zz_145__string = "JALR";
+      default : _zz_145__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_146_)
+      `EnvCtrlEnum_defaultEncoding_NONE : _zz_146__string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : _zz_146__string = "XRET";
+      default : _zz_146__string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_147_)
+      `Src2CtrlEnum_defaultEncoding_RS : _zz_147__string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : _zz_147__string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : _zz_147__string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : _zz_147__string = "PC ";
+      default : _zz_147__string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(_zz_148_)
+      `Src1CtrlEnum_defaultEncoding_RS : _zz_148__string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : _zz_148__string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : _zz_148__string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : _zz_148__string = "URS1        ";
+      default : _zz_148__string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_SHIFT_CTRL)
+      `ShiftCtrlEnum_defaultEncoding_DISABLE_1 : decode_to_execute_SHIFT_CTRL_string = "DISABLE_1";
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : decode_to_execute_SHIFT_CTRL_string = "SLL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRL_1 : decode_to_execute_SHIFT_CTRL_string = "SRL_1    ";
+      `ShiftCtrlEnum_defaultEncoding_SRA_1 : decode_to_execute_SHIFT_CTRL_string = "SRA_1    ";
+      default : decode_to_execute_SHIFT_CTRL_string = "?????????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : decode_to_execute_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : decode_to_execute_ENV_CTRL_string = "XRET";
+      default : decode_to_execute_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(execute_to_memory_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : execute_to_memory_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : execute_to_memory_ENV_CTRL_string = "XRET";
+      default : execute_to_memory_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(memory_to_writeBack_ENV_CTRL)
+      `EnvCtrlEnum_defaultEncoding_NONE : memory_to_writeBack_ENV_CTRL_string = "NONE";
+      `EnvCtrlEnum_defaultEncoding_XRET : memory_to_writeBack_ENV_CTRL_string = "XRET";
+      default : memory_to_writeBack_ENV_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_SRC1_CTRL)
+      `Src1CtrlEnum_defaultEncoding_RS : decode_to_execute_SRC1_CTRL_string = "RS          ";
+      `Src1CtrlEnum_defaultEncoding_IMU : decode_to_execute_SRC1_CTRL_string = "IMU         ";
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : decode_to_execute_SRC1_CTRL_string = "PC_INCREMENT";
+      `Src1CtrlEnum_defaultEncoding_URS1 : decode_to_execute_SRC1_CTRL_string = "URS1        ";
+      default : decode_to_execute_SRC1_CTRL_string = "????????????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_INC : decode_to_execute_BRANCH_CTRL_string = "INC ";
+      `BranchCtrlEnum_defaultEncoding_B : decode_to_execute_BRANCH_CTRL_string = "B   ";
+      `BranchCtrlEnum_defaultEncoding_JAL : decode_to_execute_BRANCH_CTRL_string = "JAL ";
+      `BranchCtrlEnum_defaultEncoding_JALR : decode_to_execute_BRANCH_CTRL_string = "JALR";
+      default : decode_to_execute_BRANCH_CTRL_string = "????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_SRC2_CTRL)
+      `Src2CtrlEnum_defaultEncoding_RS : decode_to_execute_SRC2_CTRL_string = "RS ";
+      `Src2CtrlEnum_defaultEncoding_IMI : decode_to_execute_SRC2_CTRL_string = "IMI";
+      `Src2CtrlEnum_defaultEncoding_IMS : decode_to_execute_SRC2_CTRL_string = "IMS";
+      `Src2CtrlEnum_defaultEncoding_PC : decode_to_execute_SRC2_CTRL_string = "PC ";
+      default : decode_to_execute_SRC2_CTRL_string = "???";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_ALU_BITWISE_CTRL)
+      `AluBitwiseCtrlEnum_defaultEncoding_XOR_1 : decode_to_execute_ALU_BITWISE_CTRL_string = "XOR_1";
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : decode_to_execute_ALU_BITWISE_CTRL_string = "OR_1 ";
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : decode_to_execute_ALU_BITWISE_CTRL_string = "AND_1";
+      default : decode_to_execute_ALU_BITWISE_CTRL_string = "?????";
+    endcase
+  end
+  always @(*) begin
+    case(decode_to_execute_ALU_CTRL)
+      `AluCtrlEnum_defaultEncoding_ADD_SUB : decode_to_execute_ALU_CTRL_string = "ADD_SUB ";
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : decode_to_execute_ALU_CTRL_string = "SLT_SLTU";
+      `AluCtrlEnum_defaultEncoding_BITWISE : decode_to_execute_ALU_CTRL_string = "BITWISE ";
+      default : decode_to_execute_ALU_CTRL_string = "????????";
+    endcase
+  end
+  `endif
+
+  assign decode_ALU_CTRL = _zz_1_;
+  assign _zz_2_ = _zz_3_;
+  assign decode_ALU_BITWISE_CTRL = _zz_4_;
+  assign _zz_5_ = _zz_6_;
+  assign decode_SRC2_CTRL = _zz_7_;
+  assign _zz_8_ = _zz_9_;
+  assign decode_IS_RS2_SIGNED = _zz_58_;
+  assign decode_BYPASSABLE_EXECUTE_STAGE = _zz_74_;
+  assign decode_IS_RS1_SIGNED = _zz_55_;
+  assign decode_CSR_READ_OPCODE = _zz_27_;
+  assign decode_IS_DIV = _zz_57_;
+  assign memory_MEMORY_ADDRESS_LOW = execute_to_memory_MEMORY_ADDRESS_LOW;
+  assign execute_MEMORY_ADDRESS_LOW = _zz_89_;
+  assign decode_IS_MUL = _zz_69_;
+  assign execute_BRANCH_CALC = _zz_30_;
+  assign _zz_10_ = _zz_11_;
+  assign decode_SRC1_CTRL = _zz_12_;
+  assign _zz_13_ = _zz_14_;
+  assign execute_BYPASSABLE_MEMORY_STAGE = decode_to_execute_BYPASSABLE_MEMORY_STAGE;
+  assign decode_BYPASSABLE_MEMORY_STAGE = _zz_77_;
+  assign decode_SRC2_FORCE_ZERO = _zz_46_;
+  assign decode_CSR_WRITE_OPCODE = _zz_28_;
+  assign writeBack_REGFILE_WRITE_DATA = memory_to_writeBack_REGFILE_WRITE_DATA;
+  assign execute_REGFILE_WRITE_DATA = _zz_48_;
+  assign execute_BRANCH_DO = _zz_31_;
+  assign decode_SRC_LESS_UNSIGNED = _zz_65_;
+  assign _zz_15_ = _zz_16_;
+  assign _zz_17_ = _zz_18_;
+  assign decode_ENV_CTRL = _zz_19_;
+  assign _zz_20_ = _zz_21_;
+  assign writeBack_FORMAL_PC_NEXT = memory_to_writeBack_FORMAL_PC_NEXT;
+  assign memory_FORMAL_PC_NEXT = execute_to_memory_FORMAL_PC_NEXT;
+  assign execute_FORMAL_PC_NEXT = decode_to_execute_FORMAL_PC_NEXT;
+  assign decode_FORMAL_PC_NEXT = _zz_98_;
+  assign decode_MEMORY_STORE = _zz_61_;
+  assign decode_PREDICTION_HAD_BRANCHED2 = _zz_34_;
+  assign decode_IS_CSR = _zz_76_;
+  assign decode_SHIFT_CTRL = _zz_22_;
+  assign _zz_23_ = _zz_24_;
+  assign memory_MEMORY_READ_DATA = _zz_80_;
+  assign execute_IS_RS1_SIGNED = decode_to_execute_IS_RS1_SIGNED;
+  assign execute_IS_DIV = decode_to_execute_IS_DIV;
+  assign execute_IS_MUL = decode_to_execute_IS_MUL;
+  assign execute_IS_RS2_SIGNED = decode_to_execute_IS_RS2_SIGNED;
+  assign memory_IS_DIV = execute_to_memory_IS_DIV;
+  assign memory_IS_MUL = execute_to_memory_IS_MUL;
+  assign execute_CSR_READ_OPCODE = decode_to_execute_CSR_READ_OPCODE;
+  assign execute_CSR_WRITE_OPCODE = decode_to_execute_CSR_WRITE_OPCODE;
+  assign execute_IS_CSR = decode_to_execute_IS_CSR;
+  assign memory_ENV_CTRL = _zz_25_;
+  assign execute_ENV_CTRL = _zz_26_;
+  assign writeBack_ENV_CTRL = _zz_29_;
+  assign memory_BRANCH_CALC = execute_to_memory_BRANCH_CALC;
+  assign memory_BRANCH_DO = execute_to_memory_BRANCH_DO;
+  assign execute_PC = decode_to_execute_PC;
+  assign execute_PREDICTION_HAD_BRANCHED2 = decode_to_execute_PREDICTION_HAD_BRANCHED2;
+  assign execute_RS1 = decode_to_execute_RS1;
+  assign execute_BRANCH_COND_RESULT = _zz_33_;
+  assign execute_BRANCH_CTRL = _zz_32_;
+  assign decode_RS2_USE = _zz_63_;
+  assign decode_RS1_USE = _zz_66_;
+  assign execute_REGFILE_WRITE_VALID = decode_to_execute_REGFILE_WRITE_VALID;
+  assign execute_BYPASSABLE_EXECUTE_STAGE = decode_to_execute_BYPASSABLE_EXECUTE_STAGE;
+  always @ (*) begin
+    _zz_35_ = memory_REGFILE_WRITE_DATA;
+    if(_zz_217_)begin
+      _zz_35_ = ((memory_INSTRUCTION[13 : 12] == (2'b00)) ? memory_MulDivIterativePlugin_accumulator[31 : 0] : memory_MulDivIterativePlugin_accumulator[63 : 32]);
+    end
+    if(_zz_218_)begin
+      _zz_35_ = memory_MulDivIterativePlugin_div_result;
+    end
+  end
+
+  assign memory_REGFILE_WRITE_VALID = execute_to_memory_REGFILE_WRITE_VALID;
+  assign memory_INSTRUCTION = execute_to_memory_INSTRUCTION;
+  assign memory_BYPASSABLE_MEMORY_STAGE = execute_to_memory_BYPASSABLE_MEMORY_STAGE;
+  assign writeBack_REGFILE_WRITE_VALID = memory_to_writeBack_REGFILE_WRITE_VALID;
+  always @ (*) begin
+    decode_RS2 = _zz_53_;
+    if(_zz_161_)begin
+      if((_zz_162_ == decode_INSTRUCTION[24 : 20]))begin
+        decode_RS2 = _zz_163_;
+      end
+    end
+    if(_zz_219_)begin
+      if(_zz_220_)begin
+        if(_zz_165_)begin
+          decode_RS2 = _zz_79_;
+        end
+      end
+    end
+    if(_zz_221_)begin
+      if(memory_BYPASSABLE_MEMORY_STAGE)begin
+        if(_zz_167_)begin
+          decode_RS2 = _zz_35_;
+        end
+      end
+    end
+    if(_zz_222_)begin
+      if(execute_BYPASSABLE_EXECUTE_STAGE)begin
+        if(_zz_169_)begin
+          decode_RS2 = _zz_36_;
+        end
+      end
+    end
+  end
+
+  always @ (*) begin
+    decode_RS1 = _zz_54_;
+    if(_zz_161_)begin
+      if((_zz_162_ == decode_INSTRUCTION[19 : 15]))begin
+        decode_RS1 = _zz_163_;
+      end
+    end
+    if(_zz_219_)begin
+      if(_zz_220_)begin
+        if(_zz_164_)begin
+          decode_RS1 = _zz_79_;
+        end
+      end
+    end
+    if(_zz_221_)begin
+      if(memory_BYPASSABLE_MEMORY_STAGE)begin
+        if(_zz_166_)begin
+          decode_RS1 = _zz_35_;
+        end
+      end
+    end
+    if(_zz_222_)begin
+      if(execute_BYPASSABLE_EXECUTE_STAGE)begin
+        if(_zz_168_)begin
+          decode_RS1 = _zz_36_;
+        end
+      end
+    end
+  end
+
+  always @ (*) begin
+    _zz_36_ = execute_REGFILE_WRITE_DATA;
+    if(_zz_223_)begin
+      _zz_36_ = _zz_157_;
+    end
+    if(_zz_224_)begin
+      _zz_36_ = execute_CsrPlugin_readData;
+    end
+  end
+
+  assign execute_SHIFT_CTRL = _zz_37_;
+  assign execute_SRC_LESS_UNSIGNED = decode_to_execute_SRC_LESS_UNSIGNED;
+  assign execute_SRC2_FORCE_ZERO = decode_to_execute_SRC2_FORCE_ZERO;
+  assign execute_SRC_USE_SUB_LESS = decode_to_execute_SRC_USE_SUB_LESS;
+  assign _zz_41_ = execute_PC;
+  assign execute_SRC2_CTRL = _zz_42_;
+  assign execute_SRC1_CTRL = _zz_44_;
+  assign decode_SRC_USE_SUB_LESS = _zz_60_;
+  assign decode_SRC_ADD_ZERO = _zz_71_;
+  assign execute_SRC_ADD_SUB = _zz_40_;
+  assign execute_SRC_LESS = _zz_38_;
+  assign execute_ALU_CTRL = _zz_47_;
+  assign execute_SRC2 = _zz_43_;
+  assign execute_SRC1 = _zz_45_;
+  assign execute_ALU_BITWISE_CTRL = _zz_49_;
+  assign _zz_50_ = writeBack_INSTRUCTION;
+  assign _zz_51_ = writeBack_REGFILE_WRITE_VALID;
+  always @ (*) begin
+    _zz_52_ = 1'b0;
+    if(lastStageRegFileWrite_valid)begin
+      _zz_52_ = 1'b1;
+    end
+  end
+
+  assign decode_INSTRUCTION_ANTICIPATED = _zz_94_;
+  always @ (*) begin
+    decode_REGFILE_WRITE_VALID = _zz_64_;
+    if((decode_INSTRUCTION[11 : 7] == (5'b00000)))begin
+      decode_REGFILE_WRITE_VALID = 1'b0;
+    end
+  end
+
+  assign decode_LEGAL_INSTRUCTION = _zz_78_;
+  assign decode_INSTRUCTION_READY = 1'b1;
+  assign writeBack_MEMORY_STORE = memory_to_writeBack_MEMORY_STORE;
+  always @ (*) begin
+    _zz_79_ = writeBack_REGFILE_WRITE_DATA;
+    if((writeBack_arbitration_isValid && writeBack_MEMORY_ENABLE))begin
+      _zz_79_ = writeBack_DBusSimplePlugin_rspFormated;
+    end
+  end
+
+  assign writeBack_MEMORY_ENABLE = memory_to_writeBack_MEMORY_ENABLE;
+  assign writeBack_MEMORY_ADDRESS_LOW = memory_to_writeBack_MEMORY_ADDRESS_LOW;
+  assign writeBack_MEMORY_READ_DATA = memory_to_writeBack_MEMORY_READ_DATA;
+  assign memory_MMU_FAULT = execute_to_memory_MMU_FAULT;
+  assign memory_MMU_RSP_physicalAddress = execute_to_memory_MMU_RSP_physicalAddress;
+  assign memory_MMU_RSP_isIoAccess = execute_to_memory_MMU_RSP_isIoAccess;
+  assign memory_MMU_RSP_allowRead = execute_to_memory_MMU_RSP_allowRead;
+  assign memory_MMU_RSP_allowWrite = execute_to_memory_MMU_RSP_allowWrite;
+  assign memory_MMU_RSP_allowExecute = execute_to_memory_MMU_RSP_allowExecute;
+  assign memory_MMU_RSP_exception = execute_to_memory_MMU_RSP_exception;
+  assign memory_MMU_RSP_refilling = execute_to_memory_MMU_RSP_refilling;
+  assign memory_PC = execute_to_memory_PC;
+  assign memory_ALIGNEMENT_FAULT = execute_to_memory_ALIGNEMENT_FAULT;
+  assign memory_REGFILE_WRITE_DATA = execute_to_memory_REGFILE_WRITE_DATA;
+  assign memory_MEMORY_STORE = execute_to_memory_MEMORY_STORE;
+  assign memory_MEMORY_ENABLE = execute_to_memory_MEMORY_ENABLE;
+  assign execute_MMU_FAULT = _zz_88_;
+  assign execute_MMU_RSP_physicalAddress = _zz_81_;
+  assign execute_MMU_RSP_isIoAccess = _zz_82_;
+  assign execute_MMU_RSP_allowRead = _zz_83_;
+  assign execute_MMU_RSP_allowWrite = _zz_84_;
+  assign execute_MMU_RSP_allowExecute = _zz_85_;
+  assign execute_MMU_RSP_exception = _zz_86_;
+  assign execute_MMU_RSP_refilling = _zz_87_;
+  assign execute_SRC_ADD = _zz_39_;
+  assign execute_RS2 = decode_to_execute_RS2;
+  assign execute_INSTRUCTION = decode_to_execute_INSTRUCTION;
+  assign execute_MEMORY_STORE = decode_to_execute_MEMORY_STORE;
+  assign execute_MEMORY_ENABLE = decode_to_execute_MEMORY_ENABLE;
+  assign execute_ALIGNEMENT_FAULT = _zz_90_;
+  assign decode_MEMORY_ENABLE = _zz_75_;
+  assign decode_FLUSH_ALL = _zz_62_;
+  always @ (*) begin
+    IBusCachedPlugin_rsp_issueDetected = _zz_91_;
+    if(_zz_225_)begin
+      IBusCachedPlugin_rsp_issueDetected = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    _zz_91_ = _zz_92_;
+    if(_zz_226_)begin
+      _zz_91_ = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    _zz_92_ = _zz_93_;
+    if(_zz_227_)begin
+      _zz_92_ = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    _zz_93_ = 1'b0;
+    if(_zz_228_)begin
+      _zz_93_ = 1'b1;
+    end
+  end
+
+  assign decode_BRANCH_CTRL = _zz_95_;
+  assign decode_INSTRUCTION = _zz_99_;
+  always @ (*) begin
+    _zz_96_ = memory_FORMAL_PC_NEXT;
+    if(DBusSimplePlugin_redoBranch_valid)begin
+      _zz_96_ = DBusSimplePlugin_redoBranch_payload;
+    end
+    if(BranchPlugin_jumpInterface_valid)begin
+      _zz_96_ = BranchPlugin_jumpInterface_payload;
+    end
+  end
+
+  always @ (*) begin
+    _zz_97_ = decode_FORMAL_PC_NEXT;
+    if(IBusCachedPlugin_predictionJumpInterface_valid)begin
+      _zz_97_ = IBusCachedPlugin_predictionJumpInterface_payload;
+    end
+    if(IBusCachedPlugin_redoBranch_valid)begin
+      _zz_97_ = IBusCachedPlugin_redoBranch_payload;
+    end
+  end
+
+  assign decode_PC = _zz_100_;
+  assign writeBack_PC = memory_to_writeBack_PC;
+  assign writeBack_INSTRUCTION = memory_to_writeBack_INSTRUCTION;
+  always @ (*) begin
+    decode_arbitration_haltItself = 1'b0;
+    if(((DBusSimplePlugin_mmuBus_busy && decode_arbitration_isValid) && decode_MEMORY_ENABLE))begin
+      decode_arbitration_haltItself = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    decode_arbitration_haltByOther = 1'b0;
+    if((decode_arbitration_isValid && (_zz_158_ || _zz_159_)))begin
+      decode_arbitration_haltByOther = 1'b1;
+    end
+    if((CsrPlugin_interrupt_valid && CsrPlugin_allowInterrupts))begin
+      decode_arbitration_haltByOther = decode_arbitration_isValid;
+    end
+    if(({(writeBack_arbitration_isValid && (writeBack_ENV_CTRL == `EnvCtrlEnum_defaultEncoding_XRET)),{(memory_arbitration_isValid && (memory_ENV_CTRL == `EnvCtrlEnum_defaultEncoding_XRET)),(execute_arbitration_isValid && (execute_ENV_CTRL == `EnvCtrlEnum_defaultEncoding_XRET))}} != (3'b000)))begin
+      decode_arbitration_haltByOther = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    decode_arbitration_removeIt = 1'b0;
+    if(_zz_229_)begin
+      decode_arbitration_removeIt = 1'b1;
+    end
+    if(decode_arbitration_isFlushed)begin
+      decode_arbitration_removeIt = 1'b1;
+    end
+  end
+
+  assign decode_arbitration_flushIt = 1'b0;
+  always @ (*) begin
+    decode_arbitration_flushNext = 1'b0;
+    if(IBusCachedPlugin_redoBranch_valid)begin
+      decode_arbitration_flushNext = 1'b1;
+    end
+    if(_zz_229_)begin
+      decode_arbitration_flushNext = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    execute_arbitration_haltItself = 1'b0;
+    if(((((execute_arbitration_isValid && execute_MEMORY_ENABLE) && (! dBus_cmd_ready)) && (! execute_DBusSimplePlugin_skipCmd)) && (! _zz_128_)))begin
+      execute_arbitration_haltItself = 1'b1;
+    end
+    if(_zz_223_)begin
+      if(_zz_230_)begin
+        if(! execute_LightShifterPlugin_done) begin
+          execute_arbitration_haltItself = 1'b1;
+        end
+      end
+    end
+    if(_zz_224_)begin
+      if(execute_CsrPlugin_blockedBySideEffects)begin
+        execute_arbitration_haltItself = 1'b1;
+      end
+    end
+  end
+
+  assign execute_arbitration_haltByOther = 1'b0;
+  always @ (*) begin
+    execute_arbitration_removeIt = 1'b0;
+    if(execute_arbitration_isFlushed)begin
+      execute_arbitration_removeIt = 1'b1;
+    end
+  end
+
+  assign execute_arbitration_flushIt = 1'b0;
+  assign execute_arbitration_flushNext = 1'b0;
+  always @ (*) begin
+    memory_arbitration_haltItself = 1'b0;
+    if((((memory_arbitration_isValid && memory_MEMORY_ENABLE) && (! memory_MEMORY_STORE)) && ((! dBus_rsp_ready) || 1'b0)))begin
+      memory_arbitration_haltItself = 1'b1;
+    end
+    if(_zz_217_)begin
+      if(_zz_231_)begin
+        memory_arbitration_haltItself = 1'b1;
+      end
+    end
+    if(_zz_218_)begin
+      if(_zz_232_)begin
+        memory_arbitration_haltItself = 1'b1;
+      end
+    end
+  end
+
+  assign memory_arbitration_haltByOther = 1'b0;
+  always @ (*) begin
+    memory_arbitration_removeIt = 1'b0;
+    if(_zz_233_)begin
+      memory_arbitration_removeIt = 1'b1;
+    end
+    if(memory_arbitration_isFlushed)begin
+      memory_arbitration_removeIt = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    memory_arbitration_flushIt = 1'b0;
+    if(DBusSimplePlugin_redoBranch_valid)begin
+      memory_arbitration_flushIt = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    memory_arbitration_flushNext = 1'b0;
+    if(DBusSimplePlugin_redoBranch_valid)begin
+      memory_arbitration_flushNext = 1'b1;
+    end
+    if(BranchPlugin_jumpInterface_valid)begin
+      memory_arbitration_flushNext = 1'b1;
+    end
+    if(_zz_233_)begin
+      memory_arbitration_flushNext = 1'b1;
+    end
+  end
+
+  assign writeBack_arbitration_haltItself = 1'b0;
+  assign writeBack_arbitration_haltByOther = 1'b0;
+  always @ (*) begin
+    writeBack_arbitration_removeIt = 1'b0;
+    if(writeBack_arbitration_isFlushed)begin
+      writeBack_arbitration_removeIt = 1'b1;
+    end
+  end
+
+  assign writeBack_arbitration_flushIt = 1'b0;
+  always @ (*) begin
+    writeBack_arbitration_flushNext = 1'b0;
+    if(_zz_234_)begin
+      writeBack_arbitration_flushNext = 1'b1;
+    end
+    if(_zz_235_)begin
+      writeBack_arbitration_flushNext = 1'b1;
+    end
+  end
+
+  assign lastStageInstruction = writeBack_INSTRUCTION;
+  assign lastStagePc = writeBack_PC;
+  assign lastStageIsValid = writeBack_arbitration_isValid;
+  assign lastStageIsFiring = writeBack_arbitration_isFiring;
+  always @ (*) begin
+    IBusCachedPlugin_fetcherHalt = 1'b0;
+    if(({CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack,{CsrPlugin_exceptionPortCtrl_exceptionValids_memory,{CsrPlugin_exceptionPortCtrl_exceptionValids_execute,CsrPlugin_exceptionPortCtrl_exceptionValids_decode}}} != (4'b0000)))begin
+      IBusCachedPlugin_fetcherHalt = 1'b1;
+    end
+    if(_zz_234_)begin
+      IBusCachedPlugin_fetcherHalt = 1'b1;
+    end
+    if(_zz_235_)begin
+      IBusCachedPlugin_fetcherHalt = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_fetcherflushIt = 1'b0;
+    if(({writeBack_arbitration_flushNext,{memory_arbitration_flushNext,{execute_arbitration_flushNext,decode_arbitration_flushNext}}} != (4'b0000)))begin
+      IBusCachedPlugin_fetcherflushIt = 1'b1;
+    end
+    if((IBusCachedPlugin_predictionJumpInterface_valid && decode_arbitration_isFiring))begin
+      IBusCachedPlugin_fetcherflushIt = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_incomingInstruction = 1'b0;
+    if((IBusCachedPlugin_iBusRsp_stages_1_input_valid || IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_valid))begin
+      IBusCachedPlugin_incomingInstruction = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_jumpInterface_valid = 1'b0;
+    if(_zz_234_)begin
+      CsrPlugin_jumpInterface_valid = 1'b1;
+    end
+    if(_zz_235_)begin
+      CsrPlugin_jumpInterface_valid = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_jumpInterface_payload = (32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
+    if(_zz_234_)begin
+      CsrPlugin_jumpInterface_payload = {CsrPlugin_xtvec_base,(2'b00)};
+    end
+    if(_zz_235_)begin
+      case(_zz_236_)
+        2'b11 : begin
+          CsrPlugin_jumpInterface_payload = CsrPlugin_mepc;
+        end
+        default : begin
+        end
+      endcase
+    end
+  end
+
+  assign CsrPlugin_forceMachineWire = 1'b0;
+  assign CsrPlugin_allowInterrupts = 1'b1;
+  assign CsrPlugin_allowException = 1'b1;
+  assign IBusCachedPlugin_jump_pcLoad_valid = ({CsrPlugin_jumpInterface_valid,{BranchPlugin_jumpInterface_valid,{DBusSimplePlugin_redoBranch_valid,{IBusCachedPlugin_redoBranch_valid,IBusCachedPlugin_predictionJumpInterface_valid}}}} != (5'b00000));
+  assign _zz_101_ = {IBusCachedPlugin_predictionJumpInterface_valid,{IBusCachedPlugin_redoBranch_valid,{BranchPlugin_jumpInterface_valid,{DBusSimplePlugin_redoBranch_valid,CsrPlugin_jumpInterface_valid}}}};
+  assign _zz_102_ = (_zz_101_ & (~ _zz_255_));
+  assign _zz_103_ = _zz_102_[3];
+  assign _zz_104_ = _zz_102_[4];
+  assign _zz_105_ = (_zz_102_[1] || _zz_103_);
+  assign _zz_106_ = (_zz_102_[2] || _zz_103_);
+  assign IBusCachedPlugin_jump_pcLoad_payload = _zz_216_;
+  always @ (*) begin
+    IBusCachedPlugin_fetchPc_corrected = 1'b0;
+    if(IBusCachedPlugin_jump_pcLoad_valid)begin
+      IBusCachedPlugin_fetchPc_corrected = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_fetchPc_pcRegPropagate = 1'b0;
+    if(IBusCachedPlugin_iBusRsp_stages_1_input_ready)begin
+      IBusCachedPlugin_fetchPc_pcRegPropagate = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_fetchPc_pc = (IBusCachedPlugin_fetchPc_pcReg + _zz_257_);
+    if(IBusCachedPlugin_jump_pcLoad_valid)begin
+      IBusCachedPlugin_fetchPc_pc = IBusCachedPlugin_jump_pcLoad_payload;
+    end
+    IBusCachedPlugin_fetchPc_pc[0] = 1'b0;
+    IBusCachedPlugin_fetchPc_pc[1] = 1'b0;
+  end
+
+  assign IBusCachedPlugin_fetchPc_output_valid = ((! IBusCachedPlugin_fetcherHalt) && IBusCachedPlugin_fetchPc_booted);
+  assign IBusCachedPlugin_fetchPc_output_payload = IBusCachedPlugin_fetchPc_pc;
+  assign IBusCachedPlugin_iBusRsp_stages_0_input_valid = IBusCachedPlugin_fetchPc_output_valid;
+  assign IBusCachedPlugin_fetchPc_output_ready = IBusCachedPlugin_iBusRsp_stages_0_input_ready;
+  assign IBusCachedPlugin_iBusRsp_stages_0_input_payload = IBusCachedPlugin_fetchPc_output_payload;
+  assign IBusCachedPlugin_iBusRsp_stages_0_inputSample = 1'b1;
+  always @ (*) begin
+    IBusCachedPlugin_iBusRsp_stages_0_halt = 1'b0;
+    if(IBusCachedPlugin_cache_io_cpu_prefetch_haltIt)begin
+      IBusCachedPlugin_iBusRsp_stages_0_halt = 1'b1;
+    end
+  end
+
+  assign _zz_107_ = (! IBusCachedPlugin_iBusRsp_stages_0_halt);
+  assign IBusCachedPlugin_iBusRsp_stages_0_input_ready = (IBusCachedPlugin_iBusRsp_stages_0_output_ready && _zz_107_);
+  assign IBusCachedPlugin_iBusRsp_stages_0_output_valid = (IBusCachedPlugin_iBusRsp_stages_0_input_valid && _zz_107_);
+  assign IBusCachedPlugin_iBusRsp_stages_0_output_payload = IBusCachedPlugin_iBusRsp_stages_0_input_payload;
+  always @ (*) begin
+    IBusCachedPlugin_iBusRsp_stages_1_halt = 1'b0;
+    if(IBusCachedPlugin_cache_io_cpu_fetch_haltIt)begin
+      IBusCachedPlugin_iBusRsp_stages_1_halt = 1'b1;
+    end
+  end
+
+  assign _zz_108_ = (! IBusCachedPlugin_iBusRsp_stages_1_halt);
+  assign IBusCachedPlugin_iBusRsp_stages_1_input_ready = (IBusCachedPlugin_iBusRsp_stages_1_output_ready && _zz_108_);
+  assign IBusCachedPlugin_iBusRsp_stages_1_output_valid = (IBusCachedPlugin_iBusRsp_stages_1_input_valid && _zz_108_);
+  assign IBusCachedPlugin_iBusRsp_stages_1_output_payload = IBusCachedPlugin_iBusRsp_stages_1_input_payload;
+  always @ (*) begin
+    IBusCachedPlugin_iBusRsp_cacheRspArbitration_halt = 1'b0;
+    if((IBusCachedPlugin_rsp_issueDetected || IBusCachedPlugin_rsp_iBusRspOutputHalt))begin
+      IBusCachedPlugin_iBusRsp_cacheRspArbitration_halt = 1'b1;
+    end
+  end
+
+  assign _zz_109_ = (! IBusCachedPlugin_iBusRsp_cacheRspArbitration_halt);
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready = (IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_ready && _zz_109_);
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_valid = (IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_valid && _zz_109_);
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_payload = IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload;
+  assign IBusCachedPlugin_iBusRsp_stages_0_output_ready = _zz_110_;
+  assign _zz_110_ = ((1'b0 && (! _zz_111_)) || IBusCachedPlugin_iBusRsp_stages_1_input_ready);
+  assign _zz_111_ = _zz_112_;
+  assign IBusCachedPlugin_iBusRsp_stages_1_input_valid = _zz_111_;
+  assign IBusCachedPlugin_iBusRsp_stages_1_input_payload = IBusCachedPlugin_fetchPc_pcReg;
+  assign IBusCachedPlugin_iBusRsp_stages_1_output_ready = ((1'b0 && (! _zz_113_)) || IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready);
+  assign _zz_113_ = _zz_114_;
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_valid = _zz_113_;
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload = _zz_115_;
+  always @ (*) begin
+    IBusCachedPlugin_iBusRsp_readyForError = 1'b1;
+    if((! IBusCachedPlugin_pcValids_0))begin
+      IBusCachedPlugin_iBusRsp_readyForError = 1'b0;
+    end
+  end
+
+  assign IBusCachedPlugin_pcValids_0 = IBusCachedPlugin_injector_nextPcCalc_valids_1;
+  assign IBusCachedPlugin_pcValids_1 = IBusCachedPlugin_injector_nextPcCalc_valids_2;
+  assign IBusCachedPlugin_pcValids_2 = IBusCachedPlugin_injector_nextPcCalc_valids_3;
+  assign IBusCachedPlugin_pcValids_3 = IBusCachedPlugin_injector_nextPcCalc_valids_4;
+  assign IBusCachedPlugin_iBusRsp_decodeInput_ready = (! decode_arbitration_isStuck);
+  assign decode_arbitration_isValid = (IBusCachedPlugin_iBusRsp_decodeInput_valid && (! IBusCachedPlugin_injector_decodeRemoved));
+  assign _zz_100_ = IBusCachedPlugin_iBusRsp_decodeInput_payload_pc;
+  assign _zz_99_ = IBusCachedPlugin_iBusRsp_decodeInput_payload_rsp_inst;
+  assign _zz_98_ = (decode_PC + (32'b00000000000000000000000000000100));
+  assign _zz_116_ = _zz_258_[11];
+  always @ (*) begin
+    _zz_117_[18] = _zz_116_;
+    _zz_117_[17] = _zz_116_;
+    _zz_117_[16] = _zz_116_;
+    _zz_117_[15] = _zz_116_;
+    _zz_117_[14] = _zz_116_;
+    _zz_117_[13] = _zz_116_;
+    _zz_117_[12] = _zz_116_;
+    _zz_117_[11] = _zz_116_;
+    _zz_117_[10] = _zz_116_;
+    _zz_117_[9] = _zz_116_;
+    _zz_117_[8] = _zz_116_;
+    _zz_117_[7] = _zz_116_;
+    _zz_117_[6] = _zz_116_;
+    _zz_117_[5] = _zz_116_;
+    _zz_117_[4] = _zz_116_;
+    _zz_117_[3] = _zz_116_;
+    _zz_117_[2] = _zz_116_;
+    _zz_117_[1] = _zz_116_;
+    _zz_117_[0] = _zz_116_;
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_decodePrediction_cmd_hadBranch = ((decode_BRANCH_CTRL == `BranchCtrlEnum_defaultEncoding_JAL) || ((decode_BRANCH_CTRL == `BranchCtrlEnum_defaultEncoding_B) && _zz_259_[31]));
+    if(_zz_122_)begin
+      IBusCachedPlugin_decodePrediction_cmd_hadBranch = 1'b0;
+    end
+  end
+
+  assign _zz_118_ = _zz_260_[19];
+  always @ (*) begin
+    _zz_119_[10] = _zz_118_;
+    _zz_119_[9] = _zz_118_;
+    _zz_119_[8] = _zz_118_;
+    _zz_119_[7] = _zz_118_;
+    _zz_119_[6] = _zz_118_;
+    _zz_119_[5] = _zz_118_;
+    _zz_119_[4] = _zz_118_;
+    _zz_119_[3] = _zz_118_;
+    _zz_119_[2] = _zz_118_;
+    _zz_119_[1] = _zz_118_;
+    _zz_119_[0] = _zz_118_;
+  end
+
+  assign _zz_120_ = _zz_261_[11];
+  always @ (*) begin
+    _zz_121_[18] = _zz_120_;
+    _zz_121_[17] = _zz_120_;
+    _zz_121_[16] = _zz_120_;
+    _zz_121_[15] = _zz_120_;
+    _zz_121_[14] = _zz_120_;
+    _zz_121_[13] = _zz_120_;
+    _zz_121_[12] = _zz_120_;
+    _zz_121_[11] = _zz_120_;
+    _zz_121_[10] = _zz_120_;
+    _zz_121_[9] = _zz_120_;
+    _zz_121_[8] = _zz_120_;
+    _zz_121_[7] = _zz_120_;
+    _zz_121_[6] = _zz_120_;
+    _zz_121_[5] = _zz_120_;
+    _zz_121_[4] = _zz_120_;
+    _zz_121_[3] = _zz_120_;
+    _zz_121_[2] = _zz_120_;
+    _zz_121_[1] = _zz_120_;
+    _zz_121_[0] = _zz_120_;
+  end
+
+  always @ (*) begin
+    case(decode_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_JAL : begin
+        _zz_122_ = _zz_262_[1];
+      end
+      default : begin
+        _zz_122_ = _zz_263_[1];
+      end
+    endcase
+  end
+
+  assign IBusCachedPlugin_predictionJumpInterface_valid = (decode_arbitration_isValid && IBusCachedPlugin_decodePrediction_cmd_hadBranch);
+  assign _zz_123_ = _zz_264_[19];
+  always @ (*) begin
+    _zz_124_[10] = _zz_123_;
+    _zz_124_[9] = _zz_123_;
+    _zz_124_[8] = _zz_123_;
+    _zz_124_[7] = _zz_123_;
+    _zz_124_[6] = _zz_123_;
+    _zz_124_[5] = _zz_123_;
+    _zz_124_[4] = _zz_123_;
+    _zz_124_[3] = _zz_123_;
+    _zz_124_[2] = _zz_123_;
+    _zz_124_[1] = _zz_123_;
+    _zz_124_[0] = _zz_123_;
+  end
+
+  assign _zz_125_ = _zz_265_[11];
+  always @ (*) begin
+    _zz_126_[18] = _zz_125_;
+    _zz_126_[17] = _zz_125_;
+    _zz_126_[16] = _zz_125_;
+    _zz_126_[15] = _zz_125_;
+    _zz_126_[14] = _zz_125_;
+    _zz_126_[13] = _zz_125_;
+    _zz_126_[12] = _zz_125_;
+    _zz_126_[11] = _zz_125_;
+    _zz_126_[10] = _zz_125_;
+    _zz_126_[9] = _zz_125_;
+    _zz_126_[8] = _zz_125_;
+    _zz_126_[7] = _zz_125_;
+    _zz_126_[6] = _zz_125_;
+    _zz_126_[5] = _zz_125_;
+    _zz_126_[4] = _zz_125_;
+    _zz_126_[3] = _zz_125_;
+    _zz_126_[2] = _zz_125_;
+    _zz_126_[1] = _zz_125_;
+    _zz_126_[0] = _zz_125_;
+  end
+
+  assign IBusCachedPlugin_predictionJumpInterface_payload = (decode_PC + ((decode_BRANCH_CTRL == `BranchCtrlEnum_defaultEncoding_JAL) ? {{_zz_124_,{{{_zz_345_,decode_INSTRUCTION[19 : 12]},decode_INSTRUCTION[20]},decode_INSTRUCTION[30 : 21]}},1'b0} : {{_zz_126_,{{{_zz_346_,_zz_347_},decode_INSTRUCTION[30 : 25]},decode_INSTRUCTION[11 : 8]}},1'b0}));
+  assign iBus_cmd_valid = IBusCachedPlugin_cache_io_mem_cmd_valid;
+  always @ (*) begin
+    iBus_cmd_payload_address = IBusCachedPlugin_cache_io_mem_cmd_payload_address;
+    iBus_cmd_payload_address = IBusCachedPlugin_cache_io_mem_cmd_payload_address;
+  end
+
+  assign iBus_cmd_payload_size = IBusCachedPlugin_cache_io_mem_cmd_payload_size;
+  assign IBusCachedPlugin_s0_tightlyCoupledHit = 1'b0;
+  assign _zz_206_ = (IBusCachedPlugin_iBusRsp_stages_0_input_valid && (! IBusCachedPlugin_s0_tightlyCoupledHit));
+  assign _zz_209_ = (32'b00000000000000000000000000000000);
+  assign _zz_207_ = (IBusCachedPlugin_iBusRsp_stages_1_input_valid && (! IBusCachedPlugin_s1_tightlyCoupledHit));
+  assign _zz_208_ = (! IBusCachedPlugin_iBusRsp_stages_1_input_ready);
+  assign _zz_210_ = (IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_valid && (! IBusCachedPlugin_s2_tightlyCoupledHit));
+  assign _zz_211_ = (! IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready);
+  assign _zz_212_ = (CsrPlugin_privilege == (2'b00));
+  assign _zz_94_ = (decode_arbitration_isStuck ? decode_INSTRUCTION : IBusCachedPlugin_cache_io_cpu_fetch_data);
+  assign IBusCachedPlugin_rsp_iBusRspOutputHalt = 1'b0;
+  always @ (*) begin
+    IBusCachedPlugin_rsp_redoFetch = 1'b0;
+    if(_zz_228_)begin
+      IBusCachedPlugin_rsp_redoFetch = 1'b1;
+    end
+    if(_zz_226_)begin
+      IBusCachedPlugin_rsp_redoFetch = 1'b1;
+    end
+    if(_zz_237_)begin
+      IBusCachedPlugin_rsp_redoFetch = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    _zz_213_ = (IBusCachedPlugin_rsp_redoFetch && (! IBusCachedPlugin_cache_io_cpu_decode_mmuRefilling));
+    if(_zz_226_)begin
+      _zz_213_ = 1'b1;
+    end
+    if(_zz_237_)begin
+      _zz_213_ = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_decodeExceptionPort_valid = 1'b0;
+    if(_zz_227_)begin
+      IBusCachedPlugin_decodeExceptionPort_valid = IBusCachedPlugin_iBusRsp_readyForError;
+    end
+    if(_zz_225_)begin
+      IBusCachedPlugin_decodeExceptionPort_valid = IBusCachedPlugin_iBusRsp_readyForError;
+    end
+  end
+
+  always @ (*) begin
+    IBusCachedPlugin_decodeExceptionPort_payload_code = (4'bxxxx);
+    if(_zz_227_)begin
+      IBusCachedPlugin_decodeExceptionPort_payload_code = (4'b1100);
+    end
+    if(_zz_225_)begin
+      IBusCachedPlugin_decodeExceptionPort_payload_code = (4'b0001);
+    end
+  end
+
+  assign IBusCachedPlugin_decodeExceptionPort_payload_badAddr = {IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload[31 : 2],(2'b00)};
+  assign IBusCachedPlugin_redoBranch_valid = IBusCachedPlugin_rsp_redoFetch;
+  assign IBusCachedPlugin_redoBranch_payload = IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_payload;
+  assign IBusCachedPlugin_iBusRsp_decodeInput_valid = IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_valid;
+  assign IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_ready = IBusCachedPlugin_iBusRsp_decodeInput_ready;
+  assign IBusCachedPlugin_iBusRsp_decodeInput_payload_rsp_inst = IBusCachedPlugin_cache_io_cpu_decode_data;
+  assign IBusCachedPlugin_iBusRsp_decodeInput_payload_pc = IBusCachedPlugin_iBusRsp_cacheRspArbitration_output_payload;
+  assign IBusCachedPlugin_mmuBus_cmd_isValid = IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_isValid;
+  assign IBusCachedPlugin_mmuBus_cmd_virtualAddress = IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_virtualAddress;
+  assign IBusCachedPlugin_mmuBus_cmd_bypassTranslation = IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_cmd_bypassTranslation;
+  assign IBusCachedPlugin_mmuBus_end = IBusCachedPlugin_cache_io_cpu_fetch_mmuBus_end;
+  assign _zz_205_ = (decode_arbitration_isValid && decode_FLUSH_ALL);
+  assign _zz_128_ = 1'b0;
+  assign _zz_90_ = (((dBus_cmd_payload_size == (2'b10)) && (dBus_cmd_payload_address[1 : 0] != (2'b00))) || ((dBus_cmd_payload_size == (2'b01)) && (dBus_cmd_payload_address[0 : 0] != (1'b0))));
+  always @ (*) begin
+    execute_DBusSimplePlugin_skipCmd = 1'b0;
+    if(execute_ALIGNEMENT_FAULT)begin
+      execute_DBusSimplePlugin_skipCmd = 1'b1;
+    end
+    if((execute_MMU_FAULT || execute_MMU_RSP_refilling))begin
+      execute_DBusSimplePlugin_skipCmd = 1'b1;
+    end
+  end
+
+  assign dBus_cmd_valid = (((((execute_arbitration_isValid && execute_MEMORY_ENABLE) && (! execute_arbitration_isStuckByOthers)) && (! execute_arbitration_isFlushed)) && (! execute_DBusSimplePlugin_skipCmd)) && (! _zz_128_));
+  assign dBus_cmd_payload_wr = execute_MEMORY_STORE;
+  assign dBus_cmd_payload_size = execute_INSTRUCTION[13 : 12];
+  always @ (*) begin
+    case(dBus_cmd_payload_size)
+      2'b00 : begin
+        _zz_129_ = {{{execute_RS2[7 : 0],execute_RS2[7 : 0]},execute_RS2[7 : 0]},execute_RS2[7 : 0]};
+      end
+      2'b01 : begin
+        _zz_129_ = {execute_RS2[15 : 0],execute_RS2[15 : 0]};
+      end
+      default : begin
+        _zz_129_ = execute_RS2[31 : 0];
+      end
+    endcase
+  end
+
+  assign dBus_cmd_payload_data = _zz_129_;
+  assign _zz_89_ = dBus_cmd_payload_address[1 : 0];
+  always @ (*) begin
+    case(dBus_cmd_payload_size)
+      2'b00 : begin
+        _zz_130_ = (4'b0001);
+      end
+      2'b01 : begin
+        _zz_130_ = (4'b0011);
+      end
+      default : begin
+        _zz_130_ = (4'b1111);
+      end
+    endcase
+  end
+
+  assign execute_DBusSimplePlugin_formalMask = (_zz_130_ <<< dBus_cmd_payload_address[1 : 0]);
+  assign DBusSimplePlugin_mmuBus_cmd_isValid = (execute_arbitration_isValid && execute_MEMORY_ENABLE);
+  assign DBusSimplePlugin_mmuBus_cmd_virtualAddress = execute_SRC_ADD;
+  assign DBusSimplePlugin_mmuBus_cmd_bypassTranslation = 1'b0;
+  assign DBusSimplePlugin_mmuBus_end = ((! execute_arbitration_isStuck) || execute_arbitration_removeIt);
+  assign dBus_cmd_payload_address = DBusSimplePlugin_mmuBus_rsp_physicalAddress;
+  assign _zz_88_ = ((execute_MMU_RSP_exception || ((! execute_MMU_RSP_allowWrite) && execute_MEMORY_STORE)) || ((! execute_MMU_RSP_allowRead) && (! execute_MEMORY_STORE)));
+  assign _zz_81_ = DBusSimplePlugin_mmuBus_rsp_physicalAddress;
+  assign _zz_82_ = DBusSimplePlugin_mmuBus_rsp_isIoAccess;
+  assign _zz_83_ = DBusSimplePlugin_mmuBus_rsp_allowRead;
+  assign _zz_84_ = DBusSimplePlugin_mmuBus_rsp_allowWrite;
+  assign _zz_85_ = DBusSimplePlugin_mmuBus_rsp_allowExecute;
+  assign _zz_86_ = DBusSimplePlugin_mmuBus_rsp_exception;
+  assign _zz_87_ = DBusSimplePlugin_mmuBus_rsp_refilling;
+  assign _zz_80_ = dBus_rsp_data;
+  always @ (*) begin
+    DBusSimplePlugin_memoryExceptionPort_valid = 1'b0;
+    if(_zz_238_)begin
+      DBusSimplePlugin_memoryExceptionPort_valid = 1'b1;
+    end
+    if(memory_ALIGNEMENT_FAULT)begin
+      DBusSimplePlugin_memoryExceptionPort_valid = 1'b1;
+    end
+    if(memory_MMU_RSP_refilling)begin
+      DBusSimplePlugin_memoryExceptionPort_valid = 1'b0;
+    end else begin
+      if(memory_MMU_FAULT)begin
+        DBusSimplePlugin_memoryExceptionPort_valid = 1'b1;
+      end
+    end
+    if(_zz_239_)begin
+      DBusSimplePlugin_memoryExceptionPort_valid = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    DBusSimplePlugin_memoryExceptionPort_payload_code = (4'bxxxx);
+    if(_zz_238_)begin
+      DBusSimplePlugin_memoryExceptionPort_payload_code = (4'b0101);
+    end
+    if(memory_ALIGNEMENT_FAULT)begin
+      DBusSimplePlugin_memoryExceptionPort_payload_code = {1'd0, _zz_266_};
+    end
+    if(! memory_MMU_RSP_refilling) begin
+      if(memory_MMU_FAULT)begin
+        DBusSimplePlugin_memoryExceptionPort_payload_code = (memory_MEMORY_STORE ? (4'b1111) : (4'b1101));
+      end
+    end
+  end
+
+  assign DBusSimplePlugin_memoryExceptionPort_payload_badAddr = memory_REGFILE_WRITE_DATA;
+  always @ (*) begin
+    DBusSimplePlugin_redoBranch_valid = 1'b0;
+    if(memory_MMU_RSP_refilling)begin
+      DBusSimplePlugin_redoBranch_valid = 1'b1;
+    end
+    if(_zz_239_)begin
+      DBusSimplePlugin_redoBranch_valid = 1'b0;
+    end
+  end
+
+  assign DBusSimplePlugin_redoBranch_payload = memory_PC;
+  always @ (*) begin
+    writeBack_DBusSimplePlugin_rspShifted = writeBack_MEMORY_READ_DATA;
+    case(writeBack_MEMORY_ADDRESS_LOW)
+      2'b01 : begin
+        writeBack_DBusSimplePlugin_rspShifted[7 : 0] = writeBack_MEMORY_READ_DATA[15 : 8];
+      end
+      2'b10 : begin
+        writeBack_DBusSimplePlugin_rspShifted[15 : 0] = writeBack_MEMORY_READ_DATA[31 : 16];
+      end
+      2'b11 : begin
+        writeBack_DBusSimplePlugin_rspShifted[7 : 0] = writeBack_MEMORY_READ_DATA[31 : 24];
+      end
+      default : begin
+      end
+    endcase
+  end
+
+  assign _zz_131_ = (writeBack_DBusSimplePlugin_rspShifted[7] && (! writeBack_INSTRUCTION[14]));
+  always @ (*) begin
+    _zz_132_[31] = _zz_131_;
+    _zz_132_[30] = _zz_131_;
+    _zz_132_[29] = _zz_131_;
+    _zz_132_[28] = _zz_131_;
+    _zz_132_[27] = _zz_131_;
+    _zz_132_[26] = _zz_131_;
+    _zz_132_[25] = _zz_131_;
+    _zz_132_[24] = _zz_131_;
+    _zz_132_[23] = _zz_131_;
+    _zz_132_[22] = _zz_131_;
+    _zz_132_[21] = _zz_131_;
+    _zz_132_[20] = _zz_131_;
+    _zz_132_[19] = _zz_131_;
+    _zz_132_[18] = _zz_131_;
+    _zz_132_[17] = _zz_131_;
+    _zz_132_[16] = _zz_131_;
+    _zz_132_[15] = _zz_131_;
+    _zz_132_[14] = _zz_131_;
+    _zz_132_[13] = _zz_131_;
+    _zz_132_[12] = _zz_131_;
+    _zz_132_[11] = _zz_131_;
+    _zz_132_[10] = _zz_131_;
+    _zz_132_[9] = _zz_131_;
+    _zz_132_[8] = _zz_131_;
+    _zz_132_[7 : 0] = writeBack_DBusSimplePlugin_rspShifted[7 : 0];
+  end
+
+  assign _zz_133_ = (writeBack_DBusSimplePlugin_rspShifted[15] && (! writeBack_INSTRUCTION[14]));
+  always @ (*) begin
+    _zz_134_[31] = _zz_133_;
+    _zz_134_[30] = _zz_133_;
+    _zz_134_[29] = _zz_133_;
+    _zz_134_[28] = _zz_133_;
+    _zz_134_[27] = _zz_133_;
+    _zz_134_[26] = _zz_133_;
+    _zz_134_[25] = _zz_133_;
+    _zz_134_[24] = _zz_133_;
+    _zz_134_[23] = _zz_133_;
+    _zz_134_[22] = _zz_133_;
+    _zz_134_[21] = _zz_133_;
+    _zz_134_[20] = _zz_133_;
+    _zz_134_[19] = _zz_133_;
+    _zz_134_[18] = _zz_133_;
+    _zz_134_[17] = _zz_133_;
+    _zz_134_[16] = _zz_133_;
+    _zz_134_[15 : 0] = writeBack_DBusSimplePlugin_rspShifted[15 : 0];
+  end
+
+  always @ (*) begin
+    case(_zz_253_)
+      2'b00 : begin
+        writeBack_DBusSimplePlugin_rspFormated = _zz_132_;
+      end
+      2'b01 : begin
+        writeBack_DBusSimplePlugin_rspFormated = _zz_134_;
+      end
+      default : begin
+        writeBack_DBusSimplePlugin_rspFormated = writeBack_DBusSimplePlugin_rspShifted;
+      end
+    endcase
+  end
+
+  assign IBusCachedPlugin_mmuBus_rsp_physicalAddress = IBusCachedPlugin_mmuBus_cmd_virtualAddress;
+  assign IBusCachedPlugin_mmuBus_rsp_allowRead = 1'b1;
+  assign IBusCachedPlugin_mmuBus_rsp_allowWrite = 1'b1;
+  assign IBusCachedPlugin_mmuBus_rsp_allowExecute = 1'b1;
+  assign IBusCachedPlugin_mmuBus_rsp_isIoAccess = IBusCachedPlugin_mmuBus_rsp_physicalAddress[31];
+  assign IBusCachedPlugin_mmuBus_rsp_exception = 1'b0;
+  assign IBusCachedPlugin_mmuBus_rsp_refilling = 1'b0;
+  assign IBusCachedPlugin_mmuBus_busy = 1'b0;
+  assign DBusSimplePlugin_mmuBus_rsp_physicalAddress = DBusSimplePlugin_mmuBus_cmd_virtualAddress;
+  assign DBusSimplePlugin_mmuBus_rsp_allowRead = 1'b1;
+  assign DBusSimplePlugin_mmuBus_rsp_allowWrite = 1'b1;
+  assign DBusSimplePlugin_mmuBus_rsp_allowExecute = 1'b1;
+  assign DBusSimplePlugin_mmuBus_rsp_isIoAccess = DBusSimplePlugin_mmuBus_rsp_physicalAddress[31];
+  assign DBusSimplePlugin_mmuBus_rsp_exception = 1'b0;
+  assign DBusSimplePlugin_mmuBus_rsp_refilling = 1'b0;
+  assign DBusSimplePlugin_mmuBus_busy = 1'b0;
+  assign _zz_136_ = ((decode_INSTRUCTION & (32'b00000000000000000000000000000100)) == (32'b00000000000000000000000000000100));
+  assign _zz_137_ = ((decode_INSTRUCTION & (32'b00000000000000000011000000000000)) == (32'b00000000000000000010000000000000));
+  assign _zz_138_ = ((decode_INSTRUCTION & (32'b00000000000000000000000001001000)) == (32'b00000000000000000000000001001000));
+  assign _zz_139_ = ((decode_INSTRUCTION & (32'b00000000000000000111000000000000)) == (32'b00000000000000000001000000000000));
+  assign _zz_140_ = ((decode_INSTRUCTION & (32'b00000000000000000101000000000000)) == (32'b00000000000000000100000000000000));
+  assign _zz_141_ = ((decode_INSTRUCTION & (32'b00000000000000000100000001010000)) == (32'b00000000000000000100000001010000));
+  assign _zz_135_ = {({_zz_140_,{_zz_137_,_zz_139_}} != (3'b000)),{({_zz_348_,_zz_141_} != (2'b00)),{({_zz_349_,_zz_350_} != (2'b00)),{(_zz_351_ != _zz_352_),{_zz_353_,{_zz_354_,_zz_355_}}}}}};
+  assign _zz_78_ = ({((decode_INSTRUCTION & (32'b00000000000000000000000001011111)) == (32'b00000000000000000000000000010111)),{((decode_INSTRUCTION & (32'b00000000000000000000000001111111)) == (32'b00000000000000000000000001101111)),{((decode_INSTRUCTION & (32'b00000000000000000001000001101111)) == (32'b00000000000000000000000000000011)),{((decode_INSTRUCTION & _zz_487_) == (32'b00000000000000000001000001110011)),{(_zz_488_ == _zz_489_),{_zz_490_,{_zz_491_,_zz_492_}}}}}}} != (18'b000000000000000000));
+  assign _zz_77_ = _zz_267_[0];
+  assign _zz_76_ = _zz_268_[0];
+  assign _zz_75_ = _zz_269_[0];
+  assign _zz_74_ = _zz_270_[0];
+  assign _zz_142_ = _zz_135_[5 : 4];
+  assign _zz_73_ = _zz_142_;
+  assign _zz_143_ = _zz_135_[7 : 6];
+  assign _zz_72_ = _zz_143_;
+  assign _zz_71_ = _zz_271_[0];
+  assign _zz_144_ = _zz_135_[10 : 9];
+  assign _zz_70_ = _zz_144_;
+  assign _zz_69_ = _zz_272_[0];
+  assign _zz_145_ = _zz_135_[13 : 12];
+  assign _zz_68_ = _zz_145_;
+  assign _zz_146_ = _zz_135_[14 : 14];
+  assign _zz_67_ = _zz_146_;
+  assign _zz_66_ = _zz_273_[0];
+  assign _zz_65_ = _zz_274_[0];
+  assign _zz_64_ = _zz_275_[0];
+  assign _zz_63_ = _zz_276_[0];
+  assign _zz_62_ = _zz_277_[0];
+  assign _zz_61_ = _zz_278_[0];
+  assign _zz_60_ = _zz_279_[0];
+  assign _zz_147_ = _zz_135_[23 : 22];
+  assign _zz_59_ = _zz_147_;
+  assign _zz_58_ = _zz_280_[0];
+  assign _zz_57_ = _zz_281_[0];
+  assign _zz_148_ = _zz_135_[28 : 27];
+  assign _zz_56_ = _zz_148_;
+  assign _zz_55_ = _zz_282_[0];
+  assign decodeExceptionPort_valid = ((decode_arbitration_isValid && decode_INSTRUCTION_READY) && (! decode_LEGAL_INSTRUCTION));
+  assign decodeExceptionPort_payload_code = (4'b0010);
+  assign decodeExceptionPort_payload_badAddr = decode_INSTRUCTION;
+  assign decode_RegFilePlugin_regFileReadAddress1 = decode_INSTRUCTION_ANTICIPATED[19 : 15];
+  assign decode_RegFilePlugin_regFileReadAddress2 = decode_INSTRUCTION_ANTICIPATED[24 : 20];
+  assign decode_RegFilePlugin_rs1Data = _zz_214_;
+  assign decode_RegFilePlugin_rs2Data = _zz_215_;
+  assign _zz_54_ = decode_RegFilePlugin_rs1Data;
+  assign _zz_53_ = decode_RegFilePlugin_rs2Data;
+  always @ (*) begin
+    lastStageRegFileWrite_valid = (_zz_51_ && writeBack_arbitration_isFiring);
+    if(_zz_149_)begin
+      lastStageRegFileWrite_valid = 1'b1;
+    end
+  end
+
+  assign lastStageRegFileWrite_payload_address = _zz_50_[11 : 7];
+  assign lastStageRegFileWrite_payload_data = _zz_79_;
+  always @ (*) begin
+    case(execute_ALU_BITWISE_CTRL)
+      `AluBitwiseCtrlEnum_defaultEncoding_AND_1 : begin
+        execute_IntAluPlugin_bitwise = (execute_SRC1 & execute_SRC2);
+      end
+      `AluBitwiseCtrlEnum_defaultEncoding_OR_1 : begin
+        execute_IntAluPlugin_bitwise = (execute_SRC1 | execute_SRC2);
+      end
+      default : begin
+        execute_IntAluPlugin_bitwise = (execute_SRC1 ^ execute_SRC2);
+      end
+    endcase
+  end
+
+  always @ (*) begin
+    case(execute_ALU_CTRL)
+      `AluCtrlEnum_defaultEncoding_BITWISE : begin
+        _zz_150_ = execute_IntAluPlugin_bitwise;
+      end
+      `AluCtrlEnum_defaultEncoding_SLT_SLTU : begin
+        _zz_150_ = {31'd0, _zz_283_};
+      end
+      default : begin
+        _zz_150_ = execute_SRC_ADD_SUB;
+      end
+    endcase
+  end
+
+  assign _zz_48_ = _zz_150_;
+  assign _zz_46_ = (decode_SRC_ADD_ZERO && (! decode_SRC_USE_SUB_LESS));
+  always @ (*) begin
+    case(execute_SRC1_CTRL)
+      `Src1CtrlEnum_defaultEncoding_RS : begin
+        _zz_151_ = execute_RS1;
+      end
+      `Src1CtrlEnum_defaultEncoding_PC_INCREMENT : begin
+        _zz_151_ = {29'd0, _zz_284_};
+      end
+      `Src1CtrlEnum_defaultEncoding_IMU : begin
+        _zz_151_ = {execute_INSTRUCTION[31 : 12],(12'b000000000000)};
+      end
+      default : begin
+        _zz_151_ = {27'd0, _zz_285_};
+      end
+    endcase
+  end
+
+  assign _zz_45_ = _zz_151_;
+  assign _zz_152_ = _zz_286_[11];
+  always @ (*) begin
+    _zz_153_[19] = _zz_152_;
+    _zz_153_[18] = _zz_152_;
+    _zz_153_[17] = _zz_152_;
+    _zz_153_[16] = _zz_152_;
+    _zz_153_[15] = _zz_152_;
+    _zz_153_[14] = _zz_152_;
+    _zz_153_[13] = _zz_152_;
+    _zz_153_[12] = _zz_152_;
+    _zz_153_[11] = _zz_152_;
+    _zz_153_[10] = _zz_152_;
+    _zz_153_[9] = _zz_152_;
+    _zz_153_[8] = _zz_152_;
+    _zz_153_[7] = _zz_152_;
+    _zz_153_[6] = _zz_152_;
+    _zz_153_[5] = _zz_152_;
+    _zz_153_[4] = _zz_152_;
+    _zz_153_[3] = _zz_152_;
+    _zz_153_[2] = _zz_152_;
+    _zz_153_[1] = _zz_152_;
+    _zz_153_[0] = _zz_152_;
+  end
+
+  assign _zz_154_ = _zz_287_[11];
+  always @ (*) begin
+    _zz_155_[19] = _zz_154_;
+    _zz_155_[18] = _zz_154_;
+    _zz_155_[17] = _zz_154_;
+    _zz_155_[16] = _zz_154_;
+    _zz_155_[15] = _zz_154_;
+    _zz_155_[14] = _zz_154_;
+    _zz_155_[13] = _zz_154_;
+    _zz_155_[12] = _zz_154_;
+    _zz_155_[11] = _zz_154_;
+    _zz_155_[10] = _zz_154_;
+    _zz_155_[9] = _zz_154_;
+    _zz_155_[8] = _zz_154_;
+    _zz_155_[7] = _zz_154_;
+    _zz_155_[6] = _zz_154_;
+    _zz_155_[5] = _zz_154_;
+    _zz_155_[4] = _zz_154_;
+    _zz_155_[3] = _zz_154_;
+    _zz_155_[2] = _zz_154_;
+    _zz_155_[1] = _zz_154_;
+    _zz_155_[0] = _zz_154_;
+  end
+
+  always @ (*) begin
+    case(execute_SRC2_CTRL)
+      `Src2CtrlEnum_defaultEncoding_RS : begin
+        _zz_156_ = execute_RS2;
+      end
+      `Src2CtrlEnum_defaultEncoding_IMI : begin
+        _zz_156_ = {_zz_153_,execute_INSTRUCTION[31 : 20]};
+      end
+      `Src2CtrlEnum_defaultEncoding_IMS : begin
+        _zz_156_ = {_zz_155_,{execute_INSTRUCTION[31 : 25],execute_INSTRUCTION[11 : 7]}};
+      end
+      default : begin
+        _zz_156_ = _zz_41_;
+      end
+    endcase
+  end
+
+  assign _zz_43_ = _zz_156_;
+  always @ (*) begin
+    execute_SrcPlugin_addSub = _zz_288_;
+    if(execute_SRC2_FORCE_ZERO)begin
+      execute_SrcPlugin_addSub = execute_SRC1;
+    end
+  end
+
+  assign execute_SrcPlugin_less = ((execute_SRC1[31] == execute_SRC2[31]) ? execute_SrcPlugin_addSub[31] : (execute_SRC_LESS_UNSIGNED ? execute_SRC2[31] : execute_SRC1[31]));
+  assign _zz_40_ = execute_SrcPlugin_addSub;
+  assign _zz_39_ = execute_SrcPlugin_addSub;
+  assign _zz_38_ = execute_SrcPlugin_less;
+  assign execute_LightShifterPlugin_isShift = (execute_SHIFT_CTRL != `ShiftCtrlEnum_defaultEncoding_DISABLE_1);
+  assign execute_LightShifterPlugin_amplitude = (execute_LightShifterPlugin_isActive ? execute_LightShifterPlugin_amplitudeReg : execute_SRC2[4 : 0]);
+  assign execute_LightShifterPlugin_shiftInput = (execute_LightShifterPlugin_isActive ? memory_REGFILE_WRITE_DATA : execute_SRC1);
+  assign execute_LightShifterPlugin_done = (execute_LightShifterPlugin_amplitude[4 : 1] == (4'b0000));
+  always @ (*) begin
+    case(execute_SHIFT_CTRL)
+      `ShiftCtrlEnum_defaultEncoding_SLL_1 : begin
+        _zz_157_ = (execute_LightShifterPlugin_shiftInput <<< 1);
+      end
+      default : begin
+        _zz_157_ = _zz_295_;
+      end
+    endcase
+  end
+
+  always @ (*) begin
+    _zz_158_ = 1'b0;
+    if(_zz_240_)begin
+      if(_zz_241_)begin
+        if(_zz_164_)begin
+          _zz_158_ = 1'b1;
+        end
+      end
+    end
+    if(_zz_242_)begin
+      if(_zz_243_)begin
+        if(_zz_166_)begin
+          _zz_158_ = 1'b1;
+        end
+      end
+    end
+    if(_zz_244_)begin
+      if(_zz_245_)begin
+        if(_zz_168_)begin
+          _zz_158_ = 1'b1;
+        end
+      end
+    end
+    if((! decode_RS1_USE))begin
+      _zz_158_ = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    _zz_159_ = 1'b0;
+    if(_zz_240_)begin
+      if(_zz_241_)begin
+        if(_zz_165_)begin
+          _zz_159_ = 1'b1;
+        end
+      end
+    end
+    if(_zz_242_)begin
+      if(_zz_243_)begin
+        if(_zz_167_)begin
+          _zz_159_ = 1'b1;
+        end
+      end
+    end
+    if(_zz_244_)begin
+      if(_zz_245_)begin
+        if(_zz_169_)begin
+          _zz_159_ = 1'b1;
+        end
+      end
+    end
+    if((! decode_RS2_USE))begin
+      _zz_159_ = 1'b0;
+    end
+  end
+
+  assign _zz_160_ = (_zz_51_ && writeBack_arbitration_isFiring);
+  assign _zz_164_ = (writeBack_INSTRUCTION[11 : 7] == decode_INSTRUCTION[19 : 15]);
+  assign _zz_165_ = (writeBack_INSTRUCTION[11 : 7] == decode_INSTRUCTION[24 : 20]);
+  assign _zz_166_ = (memory_INSTRUCTION[11 : 7] == decode_INSTRUCTION[19 : 15]);
+  assign _zz_167_ = (memory_INSTRUCTION[11 : 7] == decode_INSTRUCTION[24 : 20]);
+  assign _zz_168_ = (execute_INSTRUCTION[11 : 7] == decode_INSTRUCTION[19 : 15]);
+  assign _zz_169_ = (execute_INSTRUCTION[11 : 7] == decode_INSTRUCTION[24 : 20]);
+  assign _zz_34_ = IBusCachedPlugin_decodePrediction_cmd_hadBranch;
+  assign execute_BranchPlugin_eq = (execute_SRC1 == execute_SRC2);
+  assign _zz_170_ = execute_INSTRUCTION[14 : 12];
+  always @ (*) begin
+    if((_zz_170_ == (3'b000))) begin
+        _zz_171_ = execute_BranchPlugin_eq;
+    end else if((_zz_170_ == (3'b001))) begin
+        _zz_171_ = (! execute_BranchPlugin_eq);
+    end else if((((_zz_170_ & (3'b101)) == (3'b101)))) begin
+        _zz_171_ = (! execute_SRC_LESS);
+    end else begin
+        _zz_171_ = execute_SRC_LESS;
+    end
+  end
+
+  always @ (*) begin
+    case(execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_INC : begin
+        _zz_172_ = 1'b0;
+      end
+      `BranchCtrlEnum_defaultEncoding_JAL : begin
+        _zz_172_ = 1'b1;
+      end
+      `BranchCtrlEnum_defaultEncoding_JALR : begin
+        _zz_172_ = 1'b1;
+      end
+      default : begin
+        _zz_172_ = _zz_171_;
+      end
+    endcase
+  end
+
+  assign _zz_33_ = _zz_172_;
+  assign _zz_173_ = _zz_297_[11];
+  always @ (*) begin
+    _zz_174_[19] = _zz_173_;
+    _zz_174_[18] = _zz_173_;
+    _zz_174_[17] = _zz_173_;
+    _zz_174_[16] = _zz_173_;
+    _zz_174_[15] = _zz_173_;
+    _zz_174_[14] = _zz_173_;
+    _zz_174_[13] = _zz_173_;
+    _zz_174_[12] = _zz_173_;
+    _zz_174_[11] = _zz_173_;
+    _zz_174_[10] = _zz_173_;
+    _zz_174_[9] = _zz_173_;
+    _zz_174_[8] = _zz_173_;
+    _zz_174_[7] = _zz_173_;
+    _zz_174_[6] = _zz_173_;
+    _zz_174_[5] = _zz_173_;
+    _zz_174_[4] = _zz_173_;
+    _zz_174_[3] = _zz_173_;
+    _zz_174_[2] = _zz_173_;
+    _zz_174_[1] = _zz_173_;
+    _zz_174_[0] = _zz_173_;
+  end
+
+  assign _zz_175_ = _zz_298_[19];
+  always @ (*) begin
+    _zz_176_[10] = _zz_175_;
+    _zz_176_[9] = _zz_175_;
+    _zz_176_[8] = _zz_175_;
+    _zz_176_[7] = _zz_175_;
+    _zz_176_[6] = _zz_175_;
+    _zz_176_[5] = _zz_175_;
+    _zz_176_[4] = _zz_175_;
+    _zz_176_[3] = _zz_175_;
+    _zz_176_[2] = _zz_175_;
+    _zz_176_[1] = _zz_175_;
+    _zz_176_[0] = _zz_175_;
+  end
+
+  assign _zz_177_ = _zz_299_[11];
+  always @ (*) begin
+    _zz_178_[18] = _zz_177_;
+    _zz_178_[17] = _zz_177_;
+    _zz_178_[16] = _zz_177_;
+    _zz_178_[15] = _zz_177_;
+    _zz_178_[14] = _zz_177_;
+    _zz_178_[13] = _zz_177_;
+    _zz_178_[12] = _zz_177_;
+    _zz_178_[11] = _zz_177_;
+    _zz_178_[10] = _zz_177_;
+    _zz_178_[9] = _zz_177_;
+    _zz_178_[8] = _zz_177_;
+    _zz_178_[7] = _zz_177_;
+    _zz_178_[6] = _zz_177_;
+    _zz_178_[5] = _zz_177_;
+    _zz_178_[4] = _zz_177_;
+    _zz_178_[3] = _zz_177_;
+    _zz_178_[2] = _zz_177_;
+    _zz_178_[1] = _zz_177_;
+    _zz_178_[0] = _zz_177_;
+  end
+
+  always @ (*) begin
+    case(execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_JALR : begin
+        _zz_179_ = (_zz_300_[1] ^ execute_RS1[1]);
+      end
+      `BranchCtrlEnum_defaultEncoding_JAL : begin
+        _zz_179_ = _zz_301_[1];
+      end
+      default : begin
+        _zz_179_ = _zz_302_[1];
+      end
+    endcase
+  end
+
+  assign execute_BranchPlugin_missAlignedTarget = (execute_BRANCH_COND_RESULT && _zz_179_);
+  assign _zz_31_ = ((execute_PREDICTION_HAD_BRANCHED2 != execute_BRANCH_COND_RESULT) || execute_BranchPlugin_missAlignedTarget);
+  always @ (*) begin
+    case(execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_JALR : begin
+        execute_BranchPlugin_branch_src1 = execute_RS1;
+      end
+      default : begin
+        execute_BranchPlugin_branch_src1 = execute_PC;
+      end
+    endcase
+  end
+
+  assign _zz_180_ = _zz_303_[11];
+  always @ (*) begin
+    _zz_181_[19] = _zz_180_;
+    _zz_181_[18] = _zz_180_;
+    _zz_181_[17] = _zz_180_;
+    _zz_181_[16] = _zz_180_;
+    _zz_181_[15] = _zz_180_;
+    _zz_181_[14] = _zz_180_;
+    _zz_181_[13] = _zz_180_;
+    _zz_181_[12] = _zz_180_;
+    _zz_181_[11] = _zz_180_;
+    _zz_181_[10] = _zz_180_;
+    _zz_181_[9] = _zz_180_;
+    _zz_181_[8] = _zz_180_;
+    _zz_181_[7] = _zz_180_;
+    _zz_181_[6] = _zz_180_;
+    _zz_181_[5] = _zz_180_;
+    _zz_181_[4] = _zz_180_;
+    _zz_181_[3] = _zz_180_;
+    _zz_181_[2] = _zz_180_;
+    _zz_181_[1] = _zz_180_;
+    _zz_181_[0] = _zz_180_;
+  end
+
+  always @ (*) begin
+    case(execute_BRANCH_CTRL)
+      `BranchCtrlEnum_defaultEncoding_JALR : begin
+        execute_BranchPlugin_branch_src2 = {_zz_181_,execute_INSTRUCTION[31 : 20]};
+      end
+      default : begin
+        execute_BranchPlugin_branch_src2 = ((execute_BRANCH_CTRL == `BranchCtrlEnum_defaultEncoding_JAL) ? {{_zz_183_,{{{_zz_504_,execute_INSTRUCTION[19 : 12]},execute_INSTRUCTION[20]},execute_INSTRUCTION[30 : 21]}},1'b0} : {{_zz_185_,{{{_zz_505_,_zz_506_},execute_INSTRUCTION[30 : 25]},execute_INSTRUCTION[11 : 8]}},1'b0});
+        if(execute_PREDICTION_HAD_BRANCHED2)begin
+          execute_BranchPlugin_branch_src2 = {29'd0, _zz_306_};
+        end
+      end
+    endcase
+  end
+
+  assign _zz_182_ = _zz_304_[19];
+  always @ (*) begin
+    _zz_183_[10] = _zz_182_;
+    _zz_183_[9] = _zz_182_;
+    _zz_183_[8] = _zz_182_;
+    _zz_183_[7] = _zz_182_;
+    _zz_183_[6] = _zz_182_;
+    _zz_183_[5] = _zz_182_;
+    _zz_183_[4] = _zz_182_;
+    _zz_183_[3] = _zz_182_;
+    _zz_183_[2] = _zz_182_;
+    _zz_183_[1] = _zz_182_;
+    _zz_183_[0] = _zz_182_;
+  end
+
+  assign _zz_184_ = _zz_305_[11];
+  always @ (*) begin
+    _zz_185_[18] = _zz_184_;
+    _zz_185_[17] = _zz_184_;
+    _zz_185_[16] = _zz_184_;
+    _zz_185_[15] = _zz_184_;
+    _zz_185_[14] = _zz_184_;
+    _zz_185_[13] = _zz_184_;
+    _zz_185_[12] = _zz_184_;
+    _zz_185_[11] = _zz_184_;
+    _zz_185_[10] = _zz_184_;
+    _zz_185_[9] = _zz_184_;
+    _zz_185_[8] = _zz_184_;
+    _zz_185_[7] = _zz_184_;
+    _zz_185_[6] = _zz_184_;
+    _zz_185_[5] = _zz_184_;
+    _zz_185_[4] = _zz_184_;
+    _zz_185_[3] = _zz_184_;
+    _zz_185_[2] = _zz_184_;
+    _zz_185_[1] = _zz_184_;
+    _zz_185_[0] = _zz_184_;
+  end
+
+  assign execute_BranchPlugin_branchAdder = (execute_BranchPlugin_branch_src1 + execute_BranchPlugin_branch_src2);
+  assign _zz_30_ = {execute_BranchPlugin_branchAdder[31 : 1],(1'b0)};
+  assign BranchPlugin_jumpInterface_valid = ((memory_arbitration_isValid && memory_BRANCH_DO) && (! 1'b0));
+  assign BranchPlugin_jumpInterface_payload = memory_BRANCH_CALC;
+  assign BranchPlugin_branchExceptionPort_valid = (memory_arbitration_isValid && (memory_BRANCH_DO && memory_BRANCH_CALC[1]));
+  assign BranchPlugin_branchExceptionPort_payload_code = (4'b0000);
+  assign BranchPlugin_branchExceptionPort_payload_badAddr = memory_BRANCH_CALC;
+  assign IBusCachedPlugin_decodePrediction_rsp_wasWrong = BranchPlugin_jumpInterface_valid;
+  always @ (*) begin
+    CsrPlugin_privilege = (2'b11);
+    if(CsrPlugin_forceMachineWire)begin
+      CsrPlugin_privilege = (2'b11);
+    end
+  end
+
+  assign CsrPlugin_misa_base = (2'b01);
+  assign CsrPlugin_misa_extensions = (26'b00000000000000000001000010);
+  assign _zz_186_ = (CsrPlugin_mip_MTIP && CsrPlugin_mie_MTIE);
+  assign _zz_187_ = (CsrPlugin_mip_MSIP && CsrPlugin_mie_MSIE);
+  assign _zz_188_ = (CsrPlugin_mip_MEIP && CsrPlugin_mie_MEIE);
+  assign CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilegeUncapped = (2'b11);
+  assign CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilege = ((CsrPlugin_privilege < CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilegeUncapped) ? CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilegeUncapped : CsrPlugin_privilege);
+  assign _zz_189_ = {decodeExceptionPort_valid,IBusCachedPlugin_decodeExceptionPort_valid};
+  assign _zz_190_ = _zz_307_[0];
+  assign _zz_191_ = {BranchPlugin_branchExceptionPort_valid,DBusSimplePlugin_memoryExceptionPort_valid};
+  assign _zz_192_ = _zz_309_[0];
+  always @ (*) begin
+    CsrPlugin_exceptionPortCtrl_exceptionValids_decode = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode;
+    if(_zz_229_)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_decode = 1'b1;
+    end
+    if(decode_arbitration_isFlushed)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_decode = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_exceptionPortCtrl_exceptionValids_execute = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute;
+    if(execute_arbitration_isFlushed)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_execute = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_exceptionPortCtrl_exceptionValids_memory = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory;
+    if(_zz_233_)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_memory = 1'b1;
+    end
+    if(memory_arbitration_isFlushed)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_memory = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack;
+    if(writeBack_arbitration_isFlushed)begin
+      CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack = 1'b0;
+    end
+  end
+
+  assign CsrPlugin_exceptionPendings_0 = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode;
+  assign CsrPlugin_exceptionPendings_1 = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute;
+  assign CsrPlugin_exceptionPendings_2 = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory;
+  assign CsrPlugin_exceptionPendings_3 = CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack;
+  assign CsrPlugin_exception = (CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack && CsrPlugin_allowException);
+  assign CsrPlugin_lastStageWasWfi = 1'b0;
+  always @ (*) begin
+    CsrPlugin_pipelineLiberator_done = ((! ({writeBack_arbitration_isValid,{memory_arbitration_isValid,execute_arbitration_isValid}} != (3'b000))) && IBusCachedPlugin_pcValids_3);
+    if(({CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack,{CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory,CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute}} != (3'b000)))begin
+      CsrPlugin_pipelineLiberator_done = 1'b0;
+    end
+    if(CsrPlugin_hadException)begin
+      CsrPlugin_pipelineLiberator_done = 1'b0;
+    end
+  end
+
+  assign CsrPlugin_interruptJump = ((CsrPlugin_interrupt_valid && CsrPlugin_pipelineLiberator_done) && CsrPlugin_allowInterrupts);
+  always @ (*) begin
+    CsrPlugin_targetPrivilege = CsrPlugin_interrupt_targetPrivilege;
+    if(CsrPlugin_hadException)begin
+      CsrPlugin_targetPrivilege = CsrPlugin_exceptionPortCtrl_exceptionTargetPrivilege;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_trapCause = CsrPlugin_interrupt_code;
+    if(CsrPlugin_hadException)begin
+      CsrPlugin_trapCause = CsrPlugin_exceptionPortCtrl_exceptionContext_code;
+    end
+  end
+
+  always @ (*) begin
+    CsrPlugin_xtvec_mode = (2'bxx);
+    case(CsrPlugin_targetPrivilege)
+      2'b11 : begin
+        CsrPlugin_xtvec_mode = CsrPlugin_mtvec_mode;
+      end
+      default : begin
+      end
+    endcase
+  end
+
+  always @ (*) begin
+    CsrPlugin_xtvec_base = (30'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
+    case(CsrPlugin_targetPrivilege)
+      2'b11 : begin
+        CsrPlugin_xtvec_base = CsrPlugin_mtvec_base;
+      end
+      default : begin
+      end
+    endcase
+  end
+
+  assign contextSwitching = CsrPlugin_jumpInterface_valid;
+  assign _zz_28_ = (! (((decode_INSTRUCTION[14 : 13] == (2'b01)) && (decode_INSTRUCTION[19 : 15] == (5'b00000))) || ((decode_INSTRUCTION[14 : 13] == (2'b11)) && (decode_INSTRUCTION[19 : 15] == (5'b00000)))));
+  assign _zz_27_ = (decode_INSTRUCTION[13 : 7] != (7'b0100000));
+  assign execute_CsrPlugin_inWfi = 1'b0;
+  assign execute_CsrPlugin_blockedBySideEffects = ({writeBack_arbitration_isValid,memory_arbitration_isValid} != (2'b00));
+  always @ (*) begin
+    execute_CsrPlugin_illegalAccess = 1'b1;
+    case(execute_CsrPlugin_csrAddress)
+      12'b101111000000 : begin
+        execute_CsrPlugin_illegalAccess = 1'b0;
+      end
+      12'b001100000000 : begin
+        execute_CsrPlugin_illegalAccess = 1'b0;
+      end
+      12'b001101000001 : begin
+        execute_CsrPlugin_illegalAccess = 1'b0;
+      end
+      12'b001100000101 : begin
+        if(execute_CSR_WRITE_OPCODE)begin
+          execute_CsrPlugin_illegalAccess = 1'b0;
+        end
+      end
+      12'b001101000100 : begin
+        execute_CsrPlugin_illegalAccess = 1'b0;
+      end
+      12'b001101000011 : begin
+        if(execute_CSR_READ_OPCODE)begin
+          execute_CsrPlugin_illegalAccess = 1'b0;
+        end
+      end
+      12'b111111000000 : begin
+        if(execute_CSR_READ_OPCODE)begin
+          execute_CsrPlugin_illegalAccess = 1'b0;
+        end
+      end
+      12'b001100000100 : begin
+        execute_CsrPlugin_illegalAccess = 1'b0;
+      end
+      12'b001101000010 : begin
+        if(execute_CSR_READ_OPCODE)begin
+          execute_CsrPlugin_illegalAccess = 1'b0;
+        end
+      end
+      default : begin
+      end
+    endcase
+    if((CsrPlugin_privilege < execute_CsrPlugin_csrAddress[9 : 8]))begin
+      execute_CsrPlugin_illegalAccess = 1'b1;
+    end
+    if(((! execute_arbitration_isValid) || (! execute_IS_CSR)))begin
+      execute_CsrPlugin_illegalAccess = 1'b0;
+    end
+  end
+
+  always @ (*) begin
+    execute_CsrPlugin_illegalInstruction = 1'b0;
+    if((execute_arbitration_isValid && (execute_ENV_CTRL == `EnvCtrlEnum_defaultEncoding_XRET)))begin
+      if((CsrPlugin_privilege < execute_INSTRUCTION[29 : 28]))begin
+        execute_CsrPlugin_illegalInstruction = 1'b1;
+      end
+    end
+  end
+
+  always @ (*) begin
+    execute_CsrPlugin_readData = (32'b00000000000000000000000000000000);
+    case(execute_CsrPlugin_csrAddress)
+      12'b101111000000 : begin
+        execute_CsrPlugin_readData[31 : 0] = _zz_200_;
+      end
+      12'b001100000000 : begin
+        execute_CsrPlugin_readData[12 : 11] = CsrPlugin_mstatus_MPP;
+        execute_CsrPlugin_readData[7 : 7] = CsrPlugin_mstatus_MPIE;
+        execute_CsrPlugin_readData[3 : 3] = CsrPlugin_mstatus_MIE;
+      end
+      12'b001101000001 : begin
+        execute_CsrPlugin_readData[31 : 0] = CsrPlugin_mepc;
+      end
+      12'b001100000101 : begin
+      end
+      12'b001101000100 : begin
+        execute_CsrPlugin_readData[11 : 11] = CsrPlugin_mip_MEIP;
+        execute_CsrPlugin_readData[7 : 7] = CsrPlugin_mip_MTIP;
+        execute_CsrPlugin_readData[3 : 3] = CsrPlugin_mip_MSIP;
+      end
+      12'b001101000011 : begin
+        execute_CsrPlugin_readData[31 : 0] = CsrPlugin_mtval;
+      end
+      12'b111111000000 : begin
+        execute_CsrPlugin_readData[31 : 0] = _zz_201_;
+      end
+      12'b001100000100 : begin
+        execute_CsrPlugin_readData[11 : 11] = CsrPlugin_mie_MEIE;
+        execute_CsrPlugin_readData[7 : 7] = CsrPlugin_mie_MTIE;
+        execute_CsrPlugin_readData[3 : 3] = CsrPlugin_mie_MSIE;
+      end
+      12'b001101000010 : begin
+        execute_CsrPlugin_readData[31 : 31] = CsrPlugin_mcause_interrupt;
+        execute_CsrPlugin_readData[3 : 0] = CsrPlugin_mcause_exceptionCode;
+      end
+      default : begin
+      end
+    endcase
+  end
+
+  assign execute_CsrPlugin_writeInstruction = ((execute_arbitration_isValid && execute_IS_CSR) && execute_CSR_WRITE_OPCODE);
+  assign execute_CsrPlugin_readInstruction = ((execute_arbitration_isValid && execute_IS_CSR) && execute_CSR_READ_OPCODE);
+  assign execute_CsrPlugin_writeEnable = ((execute_CsrPlugin_writeInstruction && (! execute_CsrPlugin_blockedBySideEffects)) && (! execute_arbitration_isStuckByOthers));
+  assign execute_CsrPlugin_readEnable = ((execute_CsrPlugin_readInstruction && (! execute_CsrPlugin_blockedBySideEffects)) && (! execute_arbitration_isStuckByOthers));
+  assign execute_CsrPlugin_readToWriteData = execute_CsrPlugin_readData;
+  always @ (*) begin
+    case(_zz_254_)
+      1'b0 : begin
+        execute_CsrPlugin_writeData = execute_SRC1;
+      end
+      default : begin
+        execute_CsrPlugin_writeData = (execute_INSTRUCTION[12] ? (execute_CsrPlugin_readToWriteData & (~ execute_SRC1)) : (execute_CsrPlugin_readToWriteData | execute_SRC1));
+      end
+    endcase
+  end
+
+  assign execute_CsrPlugin_csrAddress = execute_INSTRUCTION[31 : 20];
+  always @ (*) begin
+    memory_MulDivIterativePlugin_mul_counter_willIncrement = 1'b0;
+    if(_zz_217_)begin
+      if(_zz_231_)begin
+        memory_MulDivIterativePlugin_mul_counter_willIncrement = 1'b1;
+      end
+    end
+  end
+
+  always @ (*) begin
+    memory_MulDivIterativePlugin_mul_counter_willClear = 1'b0;
+    if((! memory_arbitration_isStuck))begin
+      memory_MulDivIterativePlugin_mul_counter_willClear = 1'b1;
+    end
+  end
+
+  assign memory_MulDivIterativePlugin_mul_willOverflowIfInc = (memory_MulDivIterativePlugin_mul_counter_value == (6'b100000));
+  assign memory_MulDivIterativePlugin_mul_counter_willOverflow = (memory_MulDivIterativePlugin_mul_willOverflowIfInc && memory_MulDivIterativePlugin_mul_counter_willIncrement);
+  always @ (*) begin
+    if(memory_MulDivIterativePlugin_mul_counter_willOverflow)begin
+      memory_MulDivIterativePlugin_mul_counter_valueNext = (6'b000000);
+    end else begin
+      memory_MulDivIterativePlugin_mul_counter_valueNext = (memory_MulDivIterativePlugin_mul_counter_value + _zz_312_);
+    end
+    if(memory_MulDivIterativePlugin_mul_counter_willClear)begin
+      memory_MulDivIterativePlugin_mul_counter_valueNext = (6'b000000);
+    end
+  end
+
+  always @ (*) begin
+    memory_MulDivIterativePlugin_div_counter_willIncrement = 1'b0;
+    if(_zz_218_)begin
+      if(_zz_232_)begin
+        memory_MulDivIterativePlugin_div_counter_willIncrement = 1'b1;
+      end
+    end
+  end
+
+  always @ (*) begin
+    memory_MulDivIterativePlugin_div_counter_willClear = 1'b0;
+    if(_zz_246_)begin
+      memory_MulDivIterativePlugin_div_counter_willClear = 1'b1;
+    end
+  end
+
+  assign memory_MulDivIterativePlugin_div_counter_willOverflowIfInc = (memory_MulDivIterativePlugin_div_counter_value == (6'b100001));
+  assign memory_MulDivIterativePlugin_div_counter_willOverflow = (memory_MulDivIterativePlugin_div_counter_willOverflowIfInc && memory_MulDivIterativePlugin_div_counter_willIncrement);
+  always @ (*) begin
+    if(memory_MulDivIterativePlugin_div_counter_willOverflow)begin
+      memory_MulDivIterativePlugin_div_counter_valueNext = (6'b000000);
+    end else begin
+      memory_MulDivIterativePlugin_div_counter_valueNext = (memory_MulDivIterativePlugin_div_counter_value + _zz_320_);
+    end
+    if(memory_MulDivIterativePlugin_div_counter_willClear)begin
+      memory_MulDivIterativePlugin_div_counter_valueNext = (6'b000000);
+    end
+  end
+
+  assign _zz_193_ = memory_MulDivIterativePlugin_rs1[31 : 0];
+  assign _zz_194_ = {memory_MulDivIterativePlugin_accumulator[31 : 0],_zz_193_[31]};
+  assign _zz_195_ = (_zz_194_ - _zz_321_);
+  assign _zz_196_ = (memory_INSTRUCTION[13] ? memory_MulDivIterativePlugin_accumulator[31 : 0] : memory_MulDivIterativePlugin_rs1[31 : 0]);
+  assign _zz_197_ = (execute_RS2[31] && execute_IS_RS2_SIGNED);
+  assign _zz_198_ = ((execute_IS_MUL && _zz_197_) || ((execute_IS_DIV && execute_RS1[31]) && execute_IS_RS1_SIGNED));
+  always @ (*) begin
+    _zz_199_[32] = (execute_IS_RS1_SIGNED && execute_RS1[31]);
+    _zz_199_[31 : 0] = execute_RS1;
+  end
+
+  assign _zz_201_ = (_zz_200_ & externalInterruptArray_regNext);
+  assign externalInterrupt = (_zz_201_ != (32'b00000000000000000000000000000000));
+  assign _zz_24_ = decode_SHIFT_CTRL;
+  assign _zz_22_ = _zz_73_;
+  assign _zz_37_ = decode_to_execute_SHIFT_CTRL;
+  assign _zz_21_ = decode_ENV_CTRL;
+  assign _zz_18_ = execute_ENV_CTRL;
+  assign _zz_16_ = memory_ENV_CTRL;
+  assign _zz_19_ = _zz_67_;
+  assign _zz_26_ = decode_to_execute_ENV_CTRL;
+  assign _zz_25_ = execute_to_memory_ENV_CTRL;
+  assign _zz_29_ = memory_to_writeBack_ENV_CTRL;
+  assign _zz_14_ = decode_SRC1_CTRL;
+  assign _zz_12_ = _zz_56_;
+  assign _zz_44_ = decode_to_execute_SRC1_CTRL;
+  assign _zz_11_ = decode_BRANCH_CTRL;
+  assign _zz_95_ = _zz_68_;
+  assign _zz_32_ = decode_to_execute_BRANCH_CTRL;
+  assign _zz_9_ = decode_SRC2_CTRL;
+  assign _zz_7_ = _zz_59_;
+  assign _zz_42_ = decode_to_execute_SRC2_CTRL;
+  assign _zz_6_ = decode_ALU_BITWISE_CTRL;
+  assign _zz_4_ = _zz_70_;
+  assign _zz_49_ = decode_to_execute_ALU_BITWISE_CTRL;
+  assign _zz_3_ = decode_ALU_CTRL;
+  assign _zz_1_ = _zz_72_;
+  assign _zz_47_ = decode_to_execute_ALU_CTRL;
+  assign decode_arbitration_isFlushed = (({writeBack_arbitration_flushNext,{memory_arbitration_flushNext,execute_arbitration_flushNext}} != (3'b000)) || ({writeBack_arbitration_flushIt,{memory_arbitration_flushIt,{execute_arbitration_flushIt,decode_arbitration_flushIt}}} != (4'b0000)));
+  assign execute_arbitration_isFlushed = (({writeBack_arbitration_flushNext,memory_arbitration_flushNext} != (2'b00)) || ({writeBack_arbitration_flushIt,{memory_arbitration_flushIt,execute_arbitration_flushIt}} != (3'b000)));
+  assign memory_arbitration_isFlushed = ((writeBack_arbitration_flushNext != (1'b0)) || ({writeBack_arbitration_flushIt,memory_arbitration_flushIt} != (2'b00)));
+  assign writeBack_arbitration_isFlushed = (1'b0 || (writeBack_arbitration_flushIt != (1'b0)));
+  assign decode_arbitration_isStuckByOthers = (decode_arbitration_haltByOther || (((1'b0 || execute_arbitration_isStuck) || memory_arbitration_isStuck) || writeBack_arbitration_isStuck));
+  assign decode_arbitration_isStuck = (decode_arbitration_haltItself || decode_arbitration_isStuckByOthers);
+  assign decode_arbitration_isMoving = ((! decode_arbitration_isStuck) && (! decode_arbitration_removeIt));
+  assign decode_arbitration_isFiring = ((decode_arbitration_isValid && (! decode_arbitration_isStuck)) && (! decode_arbitration_removeIt));
+  assign execute_arbitration_isStuckByOthers = (execute_arbitration_haltByOther || ((1'b0 || memory_arbitration_isStuck) || writeBack_arbitration_isStuck));
+  assign execute_arbitration_isStuck = (execute_arbitration_haltItself || execute_arbitration_isStuckByOthers);
+  assign execute_arbitration_isMoving = ((! execute_arbitration_isStuck) && (! execute_arbitration_removeIt));
+  assign execute_arbitration_isFiring = ((execute_arbitration_isValid && (! execute_arbitration_isStuck)) && (! execute_arbitration_removeIt));
+  assign memory_arbitration_isStuckByOthers = (memory_arbitration_haltByOther || (1'b0 || writeBack_arbitration_isStuck));
+  assign memory_arbitration_isStuck = (memory_arbitration_haltItself || memory_arbitration_isStuckByOthers);
+  assign memory_arbitration_isMoving = ((! memory_arbitration_isStuck) && (! memory_arbitration_removeIt));
+  assign memory_arbitration_isFiring = ((memory_arbitration_isValid && (! memory_arbitration_isStuck)) && (! memory_arbitration_removeIt));
+  assign writeBack_arbitration_isStuckByOthers = (writeBack_arbitration_haltByOther || 1'b0);
+  assign writeBack_arbitration_isStuck = (writeBack_arbitration_haltItself || writeBack_arbitration_isStuckByOthers);
+  assign writeBack_arbitration_isMoving = ((! writeBack_arbitration_isStuck) && (! writeBack_arbitration_removeIt));
+  assign writeBack_arbitration_isFiring = ((writeBack_arbitration_isValid && (! writeBack_arbitration_isStuck)) && (! writeBack_arbitration_removeIt));
+  assign iBusWishbone_ADR = {_zz_340_,_zz_202_};
+  assign iBusWishbone_CTI = ((_zz_202_ == (3'b111)) ? (3'b111) : (3'b010));
+  assign iBusWishbone_BTE = (2'b00);
+  assign iBusWishbone_SEL = (4'b1111);
+  assign iBusWishbone_WE = 1'b0;
+  assign iBusWishbone_DAT_MOSI = (32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx);
+  always @ (*) begin
+    iBusWishbone_CYC = 1'b0;
+    if(_zz_247_)begin
+      iBusWishbone_CYC = 1'b1;
+    end
+  end
+
+  always @ (*) begin
+    iBusWishbone_STB = 1'b0;
+    if(_zz_247_)begin
+      iBusWishbone_STB = 1'b1;
+    end
+  end
+
+  assign iBus_cmd_ready = (iBus_cmd_valid && iBusWishbone_ACK);
+  assign iBus_rsp_valid = _zz_203_;
+  assign iBus_rsp_payload_data = iBusWishbone_DAT_MISO_regNext;
+  assign iBus_rsp_payload_error = 1'b0;
+  assign dBus_cmd_halfPipe_valid = dBus_cmd_halfPipe_regs_valid;
+  assign dBus_cmd_halfPipe_payload_wr = dBus_cmd_halfPipe_regs_payload_wr;
+  assign dBus_cmd_halfPipe_payload_address = dBus_cmd_halfPipe_regs_payload_address;
+  assign dBus_cmd_halfPipe_payload_data = dBus_cmd_halfPipe_regs_payload_data;
+  assign dBus_cmd_halfPipe_payload_size = dBus_cmd_halfPipe_regs_payload_size;
+  assign dBus_cmd_ready = dBus_cmd_halfPipe_regs_ready;
+  assign dBusWishbone_ADR = (dBus_cmd_halfPipe_payload_address >>> 2);
+  assign dBusWishbone_CTI = (3'b000);
+  assign dBusWishbone_BTE = (2'b00);
+  always @ (*) begin
+    case(dBus_cmd_halfPipe_payload_size)
+      2'b00 : begin
+        _zz_204_ = (4'b0001);
+      end
+      2'b01 : begin
+        _zz_204_ = (4'b0011);
+      end
+      default : begin
+        _zz_204_ = (4'b1111);
+      end
+    endcase
+  end
+
+  always @ (*) begin
+    dBusWishbone_SEL = _zz_341_[3:0];
+    if((! dBus_cmd_halfPipe_payload_wr))begin
+      dBusWishbone_SEL = (4'b1111);
+    end
+  end
+
+  assign dBusWishbone_WE = dBus_cmd_halfPipe_payload_wr;
+  assign dBusWishbone_DAT_MOSI = dBus_cmd_halfPipe_payload_data;
+  assign dBus_cmd_halfPipe_ready = (dBus_cmd_halfPipe_valid && dBusWishbone_ACK);
+  assign dBusWishbone_CYC = dBus_cmd_halfPipe_valid;
+  assign dBusWishbone_STB = dBus_cmd_halfPipe_valid;
+  assign dBus_rsp_ready = ((dBus_cmd_halfPipe_valid && (! dBusWishbone_WE)) && dBusWishbone_ACK);
+  assign dBus_rsp_data = dBusWishbone_DAT_MISO;
+  assign dBus_rsp_error = 1'b0;
+  always @ (posedge clk) begin
+    if(reset) begin
+      IBusCachedPlugin_fetchPc_pcReg <= externalResetVector;
+      IBusCachedPlugin_fetchPc_booted <= 1'b0;
+      IBusCachedPlugin_fetchPc_inc <= 1'b0;
+      _zz_112_ <= 1'b0;
+      _zz_114_ <= 1'b0;
+      IBusCachedPlugin_injector_nextPcCalc_valids_0 <= 1'b0;
+      IBusCachedPlugin_injector_nextPcCalc_valids_1 <= 1'b0;
+      IBusCachedPlugin_injector_nextPcCalc_valids_2 <= 1'b0;
+      IBusCachedPlugin_injector_nextPcCalc_valids_3 <= 1'b0;
+      IBusCachedPlugin_injector_nextPcCalc_valids_4 <= 1'b0;
+      IBusCachedPlugin_injector_decodeRemoved <= 1'b0;
+      IBusCachedPlugin_rspCounter <= _zz_127_;
+      IBusCachedPlugin_rspCounter <= (32'b00000000000000000000000000000000);
+      _zz_149_ <= 1'b1;
+      execute_LightShifterPlugin_isActive <= 1'b0;
+      _zz_161_ <= 1'b0;
+      CsrPlugin_mstatus_MIE <= 1'b0;
+      CsrPlugin_mstatus_MPIE <= 1'b0;
+      CsrPlugin_mstatus_MPP <= (2'b11);
+      CsrPlugin_mie_MEIE <= 1'b0;
+      CsrPlugin_mie_MTIE <= 1'b0;
+      CsrPlugin_mie_MSIE <= 1'b0;
+      CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode <= 1'b0;
+      CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute <= 1'b0;
+      CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory <= 1'b0;
+      CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack <= 1'b0;
+      CsrPlugin_interrupt_valid <= 1'b0;
+      CsrPlugin_hadException <= 1'b0;
+      execute_CsrPlugin_wfiWake <= 1'b0;
+      memory_MulDivIterativePlugin_mul_counter_value <= (6'b000000);
+      memory_MulDivIterativePlugin_div_counter_value <= (6'b000000);
+      _zz_200_ <= (32'b00000000000000000000000000000000);
+      execute_arbitration_isValid <= 1'b0;
+      memory_arbitration_isValid <= 1'b0;
+      writeBack_arbitration_isValid <= 1'b0;
+      memory_to_writeBack_REGFILE_WRITE_DATA <= (32'b00000000000000000000000000000000);
+      memory_to_writeBack_INSTRUCTION <= (32'b00000000000000000000000000000000);
+      _zz_202_ <= (3'b000);
+      _zz_203_ <= 1'b0;
+      dBus_cmd_halfPipe_regs_valid <= 1'b0;
+      dBus_cmd_halfPipe_regs_ready <= 1'b1;
+    end else begin
+      IBusCachedPlugin_fetchPc_booted <= 1'b1;
+      if((IBusCachedPlugin_fetchPc_corrected || IBusCachedPlugin_fetchPc_pcRegPropagate))begin
+        IBusCachedPlugin_fetchPc_inc <= 1'b0;
+      end
+      if((IBusCachedPlugin_fetchPc_output_valid && IBusCachedPlugin_fetchPc_output_ready))begin
+        IBusCachedPlugin_fetchPc_inc <= 1'b1;
+      end
+      if(((! IBusCachedPlugin_fetchPc_output_valid) && IBusCachedPlugin_fetchPc_output_ready))begin
+        IBusCachedPlugin_fetchPc_inc <= 1'b0;
+      end
+      if((IBusCachedPlugin_fetchPc_booted && ((IBusCachedPlugin_fetchPc_output_ready || IBusCachedPlugin_fetcherflushIt) || IBusCachedPlugin_fetchPc_pcRegPropagate)))begin
+        IBusCachedPlugin_fetchPc_pcReg <= IBusCachedPlugin_fetchPc_pc;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        _zz_112_ <= 1'b0;
+      end
+      if(_zz_110_)begin
+        _zz_112_ <= IBusCachedPlugin_iBusRsp_stages_0_output_valid;
+      end
+      if(IBusCachedPlugin_iBusRsp_stages_1_output_ready)begin
+        _zz_114_ <= IBusCachedPlugin_iBusRsp_stages_1_output_valid;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        _zz_114_ <= 1'b0;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_0 <= 1'b0;
+      end
+      if((! (! IBusCachedPlugin_iBusRsp_stages_1_input_ready)))begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_0 <= 1'b1;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_1 <= 1'b0;
+      end
+      if((! (! IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready)))begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_1 <= IBusCachedPlugin_injector_nextPcCalc_valids_0;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_1 <= 1'b0;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_2 <= 1'b0;
+      end
+      if((! execute_arbitration_isStuck))begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_2 <= IBusCachedPlugin_injector_nextPcCalc_valids_1;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_2 <= 1'b0;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_3 <= 1'b0;
+      end
+      if((! memory_arbitration_isStuck))begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_3 <= IBusCachedPlugin_injector_nextPcCalc_valids_2;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_3 <= 1'b0;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_4 <= 1'b0;
+      end
+      if((! writeBack_arbitration_isStuck))begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_4 <= IBusCachedPlugin_injector_nextPcCalc_valids_3;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_nextPcCalc_valids_4 <= 1'b0;
+      end
+      if(decode_arbitration_removeIt)begin
+        IBusCachedPlugin_injector_decodeRemoved <= 1'b1;
+      end
+      if(IBusCachedPlugin_fetcherflushIt)begin
+        IBusCachedPlugin_injector_decodeRemoved <= 1'b0;
+      end
+      if(iBus_rsp_valid)begin
+        IBusCachedPlugin_rspCounter <= (IBusCachedPlugin_rspCounter + (32'b00000000000000000000000000000001));
+      end
+      _zz_149_ <= 1'b0;
+      if(_zz_223_)begin
+        if(_zz_230_)begin
+          execute_LightShifterPlugin_isActive <= 1'b1;
+          if(execute_LightShifterPlugin_done)begin
+            execute_LightShifterPlugin_isActive <= 1'b0;
+          end
+        end
+      end
+      if(execute_arbitration_removeIt)begin
+        execute_LightShifterPlugin_isActive <= 1'b0;
+      end
+      _zz_161_ <= _zz_160_;
+      if((! decode_arbitration_isStuck))begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode <= 1'b0;
+      end else begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_decode <= CsrPlugin_exceptionPortCtrl_exceptionValids_decode;
+      end
+      if((! execute_arbitration_isStuck))begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute <= (CsrPlugin_exceptionPortCtrl_exceptionValids_decode && (! decode_arbitration_isStuck));
+      end else begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_execute <= CsrPlugin_exceptionPortCtrl_exceptionValids_execute;
+      end
+      if((! memory_arbitration_isStuck))begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory <= (CsrPlugin_exceptionPortCtrl_exceptionValids_execute && (! execute_arbitration_isStuck));
+      end else begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_memory <= CsrPlugin_exceptionPortCtrl_exceptionValids_memory;
+      end
+      if((! writeBack_arbitration_isStuck))begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack <= (CsrPlugin_exceptionPortCtrl_exceptionValids_memory && (! memory_arbitration_isStuck));
+      end else begin
+        CsrPlugin_exceptionPortCtrl_exceptionValidsRegs_writeBack <= 1'b0;
+      end
+      CsrPlugin_interrupt_valid <= 1'b0;
+      if(_zz_248_)begin
+        if(_zz_249_)begin
+          CsrPlugin_interrupt_valid <= 1'b1;
+        end
+        if(_zz_250_)begin
+          CsrPlugin_interrupt_valid <= 1'b1;
+        end
+        if(_zz_251_)begin
+          CsrPlugin_interrupt_valid <= 1'b1;
+        end
+      end
+      CsrPlugin_hadException <= CsrPlugin_exception;
+      if(_zz_234_)begin
+        case(CsrPlugin_targetPrivilege)
+          2'b11 : begin
+            CsrPlugin_mstatus_MIE <= 1'b0;
+            CsrPlugin_mstatus_MPIE <= CsrPlugin_mstatus_MIE;
+            CsrPlugin_mstatus_MPP <= CsrPlugin_privilege;
+          end
+          default : begin
+          end
+        endcase
+      end
+      if(_zz_235_)begin
+        case(_zz_236_)
+          2'b11 : begin
+            CsrPlugin_mstatus_MPP <= (2'b00);
+            CsrPlugin_mstatus_MIE <= CsrPlugin_mstatus_MPIE;
+            CsrPlugin_mstatus_MPIE <= 1'b1;
+          end
+          default : begin
+          end
+        endcase
+      end
+      execute_CsrPlugin_wfiWake <= ({_zz_188_,{_zz_187_,_zz_186_}} != (3'b000));
+      memory_MulDivIterativePlugin_mul_counter_value <= memory_MulDivIterativePlugin_mul_counter_valueNext;
+      memory_MulDivIterativePlugin_div_counter_value <= memory_MulDivIterativePlugin_div_counter_valueNext;
+      if((! writeBack_arbitration_isStuck))begin
+        memory_to_writeBack_INSTRUCTION <= memory_INSTRUCTION;
+      end
+      if((! writeBack_arbitration_isStuck))begin
+        memory_to_writeBack_REGFILE_WRITE_DATA <= _zz_35_;
+      end
+      if(((! execute_arbitration_isStuck) || execute_arbitration_removeIt))begin
+        execute_arbitration_isValid <= 1'b0;
+      end
+      if(((! decode_arbitration_isStuck) && (! decode_arbitration_removeIt)))begin
+        execute_arbitration_isValid <= decode_arbitration_isValid;
+      end
+      if(((! memory_arbitration_isStuck) || memory_arbitration_removeIt))begin
+        memory_arbitration_isValid <= 1'b0;
+      end
+      if(((! execute_arbitration_isStuck) && (! execute_arbitration_removeIt)))begin
+        memory_arbitration_isValid <= execute_arbitration_isValid;
+      end
+      if(((! writeBack_arbitration_isStuck) || writeBack_arbitration_removeIt))begin
+        writeBack_arbitration_isValid <= 1'b0;
+      end
+      if(((! memory_arbitration_isStuck) && (! memory_arbitration_removeIt)))begin
+        writeBack_arbitration_isValid <= memory_arbitration_isValid;
+      end
+      case(execute_CsrPlugin_csrAddress)
+        12'b101111000000 : begin
+          if(execute_CsrPlugin_writeEnable)begin
+            _zz_200_ <= execute_CsrPlugin_writeData[31 : 0];
+          end
+        end
+        12'b001100000000 : begin
+          if(execute_CsrPlugin_writeEnable)begin
+            CsrPlugin_mstatus_MPP <= execute_CsrPlugin_writeData[12 : 11];
+            CsrPlugin_mstatus_MPIE <= _zz_334_[0];
+            CsrPlugin_mstatus_MIE <= _zz_335_[0];
+          end
+        end
+        12'b001101000001 : begin
+        end
+        12'b001100000101 : begin
+        end
+        12'b001101000100 : begin
+        end
+        12'b001101000011 : begin
+        end
+        12'b111111000000 : begin
+        end
+        12'b001100000100 : begin
+          if(execute_CsrPlugin_writeEnable)begin
+            CsrPlugin_mie_MEIE <= _zz_337_[0];
+            CsrPlugin_mie_MTIE <= _zz_338_[0];
+            CsrPlugin_mie_MSIE <= _zz_339_[0];
+          end
+        end
+        12'b001101000010 : begin
+        end
+        default : begin
+        end
+      endcase
+      if(_zz_247_)begin
+        if(iBusWishbone_ACK)begin
+          _zz_202_ <= (_zz_202_ + (3'b001));
+        end
+      end
+      _zz_203_ <= (iBusWishbone_CYC && iBusWishbone_ACK);
+      if(_zz_252_)begin
+        dBus_cmd_halfPipe_regs_valid <= dBus_cmd_valid;
+        dBus_cmd_halfPipe_regs_ready <= (! dBus_cmd_valid);
+      end else begin
+        dBus_cmd_halfPipe_regs_valid <= (! dBus_cmd_halfPipe_ready);
+        dBus_cmd_halfPipe_regs_ready <= dBus_cmd_halfPipe_ready;
+      end
+    end
+  end
+
+  always @ (posedge clk) begin
+    if(IBusCachedPlugin_iBusRsp_stages_1_output_ready)begin
+      _zz_115_ <= IBusCachedPlugin_iBusRsp_stages_1_output_payload;
+    end
+    if(IBusCachedPlugin_iBusRsp_stages_1_input_ready)begin
+      IBusCachedPlugin_s1_tightlyCoupledHit <= IBusCachedPlugin_s0_tightlyCoupledHit;
+    end
+    if(IBusCachedPlugin_iBusRsp_cacheRspArbitration_input_ready)begin
+      IBusCachedPlugin_s2_tightlyCoupledHit <= IBusCachedPlugin_s1_tightlyCoupledHit;
+    end
+    if(!(! (((dBus_rsp_ready && memory_MEMORY_ENABLE) && memory_arbitration_isValid) && memory_arbitration_isStuck))) begin
+      $display("ERROR DBusSimplePlugin doesn't allow memory stage stall when read happend");
+    end
+    if(!(! (((writeBack_arbitration_isValid && writeBack_MEMORY_ENABLE) && (! writeBack_MEMORY_STORE)) && writeBack_arbitration_isStuck))) begin
+      $display("ERROR DBusSimplePlugin doesn't allow writeback stage stall when read happend");
+    end
+    if(_zz_223_)begin
+      if(_zz_230_)begin
+        execute_LightShifterPlugin_amplitudeReg <= (execute_LightShifterPlugin_amplitude - (5'b00001));
+      end
+    end
+    if(_zz_160_)begin
+      _zz_162_ <= _zz_50_[11 : 7];
+      _zz_163_ <= _zz_79_;
+    end
+    CsrPlugin_mip_MEIP <= externalInterrupt;
+    CsrPlugin_mip_MTIP <= timerInterrupt;
+    CsrPlugin_mip_MSIP <= softwareInterrupt;
+    CsrPlugin_mcycle <= (CsrPlugin_mcycle + (64'b0000000000000000000000000000000000000000000000000000000000000001));
+    if(writeBack_arbitration_isFiring)begin
+      CsrPlugin_minstret <= (CsrPlugin_minstret + (64'b0000000000000000000000000000000000000000000000000000000000000001));
+    end
+    if(_zz_229_)begin
+      CsrPlugin_exceptionPortCtrl_exceptionContext_code <= (_zz_190_ ? IBusCachedPlugin_decodeExceptionPort_payload_code : decodeExceptionPort_payload_code);
+      CsrPlugin_exceptionPortCtrl_exceptionContext_badAddr <= (_zz_190_ ? IBusCachedPlugin_decodeExceptionPort_payload_badAddr : decodeExceptionPort_payload_badAddr);
+    end
+    if(_zz_233_)begin
+      CsrPlugin_exceptionPortCtrl_exceptionContext_code <= (_zz_192_ ? DBusSimplePlugin_memoryExceptionPort_payload_code : BranchPlugin_branchExceptionPort_payload_code);
+      CsrPlugin_exceptionPortCtrl_exceptionContext_badAddr <= (_zz_192_ ? DBusSimplePlugin_memoryExceptionPort_payload_badAddr : BranchPlugin_branchExceptionPort_payload_badAddr);
+    end
+    if(_zz_248_)begin
+      if(_zz_249_)begin
+        CsrPlugin_interrupt_code <= (4'b0111);
+        CsrPlugin_interrupt_targetPrivilege <= (2'b11);
+      end
+      if(_zz_250_)begin
+        CsrPlugin_interrupt_code <= (4'b0011);
+        CsrPlugin_interrupt_targetPrivilege <= (2'b11);
+      end
+      if(_zz_251_)begin
+        CsrPlugin_interrupt_code <= (4'b1011);
+        CsrPlugin_interrupt_targetPrivilege <= (2'b11);
+      end
+    end
+    if(_zz_234_)begin
+      case(CsrPlugin_targetPrivilege)
+        2'b11 : begin
+          CsrPlugin_mcause_interrupt <= (! CsrPlugin_hadException);
+          CsrPlugin_mcause_exceptionCode <= CsrPlugin_trapCause;
+          CsrPlugin_mepc <= writeBack_PC;
+          if(CsrPlugin_hadException)begin
+            CsrPlugin_mtval <= CsrPlugin_exceptionPortCtrl_exceptionContext_badAddr;
+          end
+        end
+        default : begin
+        end
+      endcase
+    end
+    if(_zz_217_)begin
+      if(_zz_231_)begin
+        memory_MulDivIterativePlugin_rs2 <= (memory_MulDivIterativePlugin_rs2 >>> 1);
+        memory_MulDivIterativePlugin_accumulator <= ({_zz_313_,memory_MulDivIterativePlugin_accumulator[31 : 0]} >>> 1);
+      end
+    end
+    if((memory_MulDivIterativePlugin_div_counter_value == (6'b100000)))begin
+      memory_MulDivIterativePlugin_div_done <= 1'b1;
+    end
+    if((! memory_arbitration_isStuck))begin
+      memory_MulDivIterativePlugin_div_done <= 1'b0;
+    end
+    if(_zz_218_)begin
+      if(_zz_232_)begin
+        memory_MulDivIterativePlugin_rs1[31 : 0] <= _zz_322_[31:0];
+        memory_MulDivIterativePlugin_accumulator[31 : 0] <= ((! _zz_195_[32]) ? _zz_323_ : _zz_324_);
+        if((memory_MulDivIterativePlugin_div_counter_value == (6'b100000)))begin
+          memory_MulDivIterativePlugin_div_result <= _zz_325_[31:0];
+        end
+      end
+    end
+    if(_zz_246_)begin
+      memory_MulDivIterativePlugin_accumulator <= (65'b00000000000000000000000000000000000000000000000000000000000000000);
+      memory_MulDivIterativePlugin_rs1 <= ((_zz_198_ ? (~ _zz_199_) : _zz_199_) + _zz_331_);
+      memory_MulDivIterativePlugin_rs2 <= ((_zz_197_ ? (~ execute_RS2) : execute_RS2) + _zz_333_);
+      memory_MulDivIterativePlugin_div_needRevert <= ((_zz_198_ ^ (_zz_197_ && (! execute_INSTRUCTION[13]))) && (! (((execute_RS2 == (32'b00000000000000000000000000000000)) && execute_IS_RS2_SIGNED) && (! execute_INSTRUCTION[13]))));
+    end
+    externalInterruptArray_regNext <= externalInterruptArray;
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_INSTRUCTION <= decode_INSTRUCTION;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_INSTRUCTION <= execute_INSTRUCTION;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_ALIGNEMENT_FAULT <= execute_ALIGNEMENT_FAULT;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_MEMORY_READ_DATA <= memory_MEMORY_READ_DATA;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SHIFT_CTRL <= _zz_23_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_IS_CSR <= decode_IS_CSR;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_PC <= decode_PC;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_PC <= _zz_41_;
+    end
+    if(((! writeBack_arbitration_isStuck) && (! CsrPlugin_exceptionPortCtrl_exceptionValids_writeBack)))begin
+      memory_to_writeBack_PC <= memory_PC;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_PREDICTION_HAD_BRANCHED2 <= decode_PREDICTION_HAD_BRANCHED2;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_MEMORY_STORE <= decode_MEMORY_STORE;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_MEMORY_STORE <= execute_MEMORY_STORE;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_MEMORY_STORE <= memory_MEMORY_STORE;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_FORMAL_PC_NEXT <= _zz_97_;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_FORMAL_PC_NEXT <= execute_FORMAL_PC_NEXT;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_FORMAL_PC_NEXT <= _zz_96_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_ENV_CTRL <= _zz_20_;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_ENV_CTRL <= _zz_17_;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_ENV_CTRL <= _zz_15_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_REGFILE_WRITE_VALID <= decode_REGFILE_WRITE_VALID;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_REGFILE_WRITE_VALID <= execute_REGFILE_WRITE_VALID;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_REGFILE_WRITE_VALID <= memory_REGFILE_WRITE_VALID;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SRC_LESS_UNSIGNED <= decode_SRC_LESS_UNSIGNED;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_BRANCH_DO <= execute_BRANCH_DO;
+    end
+    if(((! memory_arbitration_isStuck) && (! execute_arbitration_isStuckByOthers)))begin
+      execute_to_memory_REGFILE_WRITE_DATA <= _zz_36_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_CSR_WRITE_OPCODE <= decode_CSR_WRITE_OPCODE;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_RS1 <= decode_RS1;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SRC2_FORCE_ZERO <= decode_SRC2_FORCE_ZERO;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_BYPASSABLE_MEMORY_STAGE <= decode_BYPASSABLE_MEMORY_STAGE;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_BYPASSABLE_MEMORY_STAGE <= execute_BYPASSABLE_MEMORY_STAGE;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SRC1_CTRL <= _zz_13_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_BRANCH_CTRL <= _zz_10_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_MEMORY_ENABLE <= decode_MEMORY_ENABLE;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_MEMORY_ENABLE <= execute_MEMORY_ENABLE;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_MEMORY_ENABLE <= memory_MEMORY_ENABLE;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SRC_USE_SUB_LESS <= decode_SRC_USE_SUB_LESS;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_MMU_FAULT <= execute_MMU_FAULT;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_BRANCH_CALC <= execute_BRANCH_CALC;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_RS2 <= decode_RS2;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_IS_MUL <= decode_IS_MUL;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_IS_MUL <= execute_IS_MUL;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_MEMORY_ADDRESS_LOW <= execute_MEMORY_ADDRESS_LOW;
+    end
+    if((! writeBack_arbitration_isStuck))begin
+      memory_to_writeBack_MEMORY_ADDRESS_LOW <= memory_MEMORY_ADDRESS_LOW;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_IS_DIV <= decode_IS_DIV;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_IS_DIV <= execute_IS_DIV;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_CSR_READ_OPCODE <= decode_CSR_READ_OPCODE;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_IS_RS1_SIGNED <= decode_IS_RS1_SIGNED;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_BYPASSABLE_EXECUTE_STAGE <= decode_BYPASSABLE_EXECUTE_STAGE;
+    end
+    if((! memory_arbitration_isStuck))begin
+      execute_to_memory_MMU_RSP_physicalAddress <= execute_MMU_RSP_physicalAddress;
+      execute_to_memory_MMU_RSP_isIoAccess <= execute_MMU_RSP_isIoAccess;
+      execute_to_memory_MMU_RSP_allowRead <= execute_MMU_RSP_allowRead;
+      execute_to_memory_MMU_RSP_allowWrite <= execute_MMU_RSP_allowWrite;
+      execute_to_memory_MMU_RSP_allowExecute <= execute_MMU_RSP_allowExecute;
+      execute_to_memory_MMU_RSP_exception <= execute_MMU_RSP_exception;
+      execute_to_memory_MMU_RSP_refilling <= execute_MMU_RSP_refilling;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_IS_RS2_SIGNED <= decode_IS_RS2_SIGNED;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_SRC2_CTRL <= _zz_8_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_ALU_BITWISE_CTRL <= _zz_5_;
+    end
+    if((! execute_arbitration_isStuck))begin
+      decode_to_execute_ALU_CTRL <= _zz_2_;
+    end
+    case(execute_CsrPlugin_csrAddress)
+      12'b101111000000 : begin
+      end
+      12'b001100000000 : begin
+      end
+      12'b001101000001 : begin
+        if(execute_CsrPlugin_writeEnable)begin
+          CsrPlugin_mepc <= execute_CsrPlugin_writeData[31 : 0];
+        end
+      end
+      12'b001100000101 : begin
+        if(execute_CsrPlugin_writeEnable)begin
+          CsrPlugin_mtvec_base <= execute_CsrPlugin_writeData[31 : 2];
+          CsrPlugin_mtvec_mode <= execute_CsrPlugin_writeData[1 : 0];
+        end
+      end
+      12'b001101000100 : begin
+        if(execute_CsrPlugin_writeEnable)begin
+          CsrPlugin_mip_MSIP <= _zz_336_[0];
+        end
+      end
+      12'b001101000011 : begin
+      end
+      12'b111111000000 : begin
+      end
+      12'b001100000100 : begin
+      end
+      12'b001101000010 : begin
+      end
+      default : begin
+      end
+    endcase
+    iBusWishbone_DAT_MISO_regNext <= iBusWishbone_DAT_MISO;
+    if(_zz_252_)begin
+      dBus_cmd_halfPipe_regs_payload_wr <= dBus_cmd_payload_wr;
+      dBus_cmd_halfPipe_regs_payload_address <= dBus_cmd_payload_address;
+      dBus_cmd_halfPipe_regs_payload_data <= dBus_cmd_payload_data;
+      dBus_cmd_halfPipe_regs_payload_size <= dBus_cmd_payload_size;
+    end
+  end
+
+endmodule
+
diff --git a/third_party/googletest b/third_party/googletest
new file mode 160000
index 000000000..e2239ee60
--- /dev/null
+++ b/third_party/googletest
@@ -0,0 +1 @@
+Subproject commit e2239ee6043f73722e7aa812a459f54a28552929
diff --git a/third_party/minilitex_ddr_arty/LICENSE b/third_party/minilitex_ddr_arty/LICENSE
new file mode 100644
index 000000000..46276032e
--- /dev/null
+++ b/third_party/minilitex_ddr_arty/LICENSE
@@ -0,0 +1,34 @@
+LiteX is a Migen/MiSoC based Core/SoC builder that provides the infrastructure to
+easily create Cores/SoCs.
+
+Unless otherwise noted, LiteX is copyright (C) 2012-2020 Enjoy-Digital.
+Unless otherwise noted, MiSoC is copyright (C) 2012-2015 Enjoy-Digital.
+Unless otherwise noted, MiSoC is copyright (C) 2007-2015 M-Labs Ltd.
+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.
+
+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 OWNER 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.
+
+
+Other authors retain ownership of their contributions. If a submission can
+reasonably be considered independently copyrightable, it's yours and we
+encourage you to claim it with appropriate copyright notices. This submission
+then falls under the "otherwise noted" category. All submissions are strongly
+encouraged to use the two-clause BSD license reproduced above.
diff --git a/third_party/minilitex_ddr_arty/README.yosys-symbiflow-plugins b/third_party/minilitex_ddr_arty/README.yosys-symbiflow-plugins
new file mode 100644
index 000000000..0bc2bf14e
--- /dev/null
+++ b/third_party/minilitex_ddr_arty/README.yosys-symbiflow-plugins
@@ -0,0 +1,12 @@
+Name: LiteX is a Migen/MiSoC based Core/SoC builder that provides the infrastructure to easily create Cores/SoCs (with or without CPU).
+Short Name: litex
+URL: https://github.com/enjoy-digital/litex
+Version: 0
+Revision: 9b11e919
+License: BSD-2-Clause
+
+Description:
+This package is used as stimuli in some test cases that verify that the Yosys plugins produce expected results.
+
+Local Modifications:
+Adjustments for testing purposes to the generated netlist.
diff --git a/third_party/minilitex_ddr_arty/minilitex_ddr_arty.v b/third_party/minilitex_ddr_arty/minilitex_ddr_arty.v
new file mode 100644
index 000000000..a207088c5
--- /dev/null
+++ b/third_party/minilitex_ddr_arty/minilitex_ddr_arty.v
@@ -0,0 +1,12721 @@
+//--------------------------------------------------------------------------------
+// Auto-generated by Migen (--------) & LiteX (9b11e919) on 2020-02-25 16:47:33
+//--------------------------------------------------------------------------------
+module top (
+    output reg serial_tx,
+    input serial_rx,
+    (* dont_touch = "true" *) input clk100,
+    input cpu_reset,
+    output [13:0] ddram_a,
+    output [2:0] ddram_ba,
+    output ddram_ras_n,
+    output ddram_cas_n,
+    output ddram_we_n,
+    output ddram_cs_n,
+    output [1:0] ddram_dm,
+    inout [15:0] ddram_dq,
+    output [1:0] ddram_dqs_p,
+    output [1:0] ddram_dqs_n,
+    output ddram_clk_p,
+    output ddram_clk_n,
+    output ddram_cke,
+    output ddram_odt,
+    output ddram_reset_n,
+    output [3:0] led
+);
+
+  wire [3:0] led;
+
+  assign led[0] = main_locked;
+  assign led[1] = idelayctl_rdy;
+  assign led[2] = 0;
+  assign led[3] = 0;
+
+  // Manually inserted OBUFs
+  wire [13:0] ddram_a_iob;
+  wire [ 2:0] ddram_ba_iob;
+  wire        ddram_ras_n_iob;
+  wire        ddram_cas_n_iob;
+  wire        ddram_we_n_iob;
+  wire        ddram_cs_n_iob;
+  wire [ 1:0] ddram_dm_iob;
+  wire        ddram_cke_iob;
+  wire        ddram_odt_iob;
+  wire        ddram_reset_n_iob;
+
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a0 (
+      .I(ddram_a_iob[0]),
+      .O(ddram_a[0])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a1 (
+      .I(ddram_a_iob[1]),
+      .O(ddram_a[1])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a2 (
+      .I(ddram_a_iob[2]),
+      .O(ddram_a[2])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a3 (
+      .I(ddram_a_iob[3]),
+      .O(ddram_a[3])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a4 (
+      .I(ddram_a_iob[4]),
+      .O(ddram_a[4])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a5 (
+      .I(ddram_a_iob[5]),
+      .O(ddram_a[5])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a6 (
+      .I(ddram_a_iob[6]),
+      .O(ddram_a[6])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a7 (
+      .I(ddram_a_iob[7]),
+      .O(ddram_a[7])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a8 (
+      .I(ddram_a_iob[8]),
+      .O(ddram_a[8])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a9 (
+      .I(ddram_a_iob[9]),
+      .O(ddram_a[9])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a10 (
+      .I(ddram_a_iob[10]),
+      .O(ddram_a[10])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a11 (
+      .I(ddram_a_iob[11]),
+      .O(ddram_a[11])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a12 (
+      .I(ddram_a_iob[12]),
+      .O(ddram_a[12])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_a13 (
+      .I(ddram_a_iob[13]),
+      .O(ddram_a[13])
+  );
+
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_ba0 (
+      .I(ddram_ba_iob[0]),
+      .O(ddram_ba[0])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_ba1 (
+      .I(ddram_ba_iob[1]),
+      .O(ddram_ba[1])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_ba2 (
+      .I(ddram_ba_iob[2]),
+      .O(ddram_ba[2])
+  );
+
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_dm0 (
+      .I(ddram_dm_iob[0]),
+      .O(ddram_dm[0])
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_dm1 (
+      .I(ddram_dm_iob[1]),
+      .O(ddram_dm[1])
+  );
+
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_ras (
+      .I(ddram_ras_n_iob),
+      .O(ddram_ras_n)
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_cas (
+      .I(ddram_cas_n_iob),
+      .O(ddram_cas_n)
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_we (
+      .I(ddram_we_n_iob),
+      .O(ddram_we_n)
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_cs (
+      .I(ddram_cs_n_iob),
+      .O(ddram_cs_n)
+  );
+
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_cke (
+      .I(ddram_cke_iob),
+      .O(ddram_cke)
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_odt (
+      .I(ddram_odt_iob),
+      .O(ddram_odt)
+  );
+  OBUF #(
+      .IOSTANDARD("SSTL135"),
+      .SLEW("FAST")
+  ) obuf_rst (
+      .I(ddram_reset_n_iob),
+      .O(ddram_reset_n)
+  );
+
+  // End manually inserted OBUFs
+
+  wire idelayctl_rdy;
+  reg main_minsoc_ctrl_reset_storage = 1'd0;
+  reg main_minsoc_ctrl_reset_re = 1'd0;
+  reg [31:0] main_minsoc_ctrl_scratch_storage = 32'd305419896;
+  reg main_minsoc_ctrl_scratch_re = 1'd0;
+  wire [31:0] main_minsoc_ctrl_bus_errors_status;
+  wire main_minsoc_ctrl_bus_errors_we;
+  wire main_minsoc_ctrl_reset;
+  wire main_minsoc_ctrl_bus_error;
+  reg [31:0] main_minsoc_ctrl_bus_errors = 32'd0;
+  wire main_minsoc_cpu_reset;
+  wire [29:0] main_minsoc_cpu_ibus_adr;
+  wire [31:0] main_minsoc_cpu_ibus_dat_w;
+  wire [31:0] main_minsoc_cpu_ibus_dat_r;
+  wire [3:0] main_minsoc_cpu_ibus_sel;
+  wire main_minsoc_cpu_ibus_cyc;
+  wire main_minsoc_cpu_ibus_stb;
+  wire main_minsoc_cpu_ibus_ack;
+  wire main_minsoc_cpu_ibus_we;
+  wire [2:0] main_minsoc_cpu_ibus_cti;
+  wire [1:0] main_minsoc_cpu_ibus_bte;
+  wire main_minsoc_cpu_ibus_err;
+  wire [29:0] main_minsoc_cpu_dbus_adr;
+  wire [31:0] main_minsoc_cpu_dbus_dat_w;
+  wire [31:0] main_minsoc_cpu_dbus_dat_r;
+  wire [3:0] main_minsoc_cpu_dbus_sel;
+  wire main_minsoc_cpu_dbus_cyc;
+  wire main_minsoc_cpu_dbus_stb;
+  wire main_minsoc_cpu_dbus_ack;
+  wire main_minsoc_cpu_dbus_we;
+  wire [2:0] main_minsoc_cpu_dbus_cti;
+  wire [1:0] main_minsoc_cpu_dbus_bte;
+  wire main_minsoc_cpu_dbus_err;
+  reg [31:0] main_minsoc_cpu_interrupt = 32'd0;
+  reg [31:0] main_minsoc_vexriscv = 32'd0;
+  wire [29:0] main_minsoc_interface0_soc_bus_adr;
+  wire [31:0] main_minsoc_interface0_soc_bus_dat_w;
+  wire [31:0] main_minsoc_interface0_soc_bus_dat_r;
+  wire [3:0] main_minsoc_interface0_soc_bus_sel;
+  wire main_minsoc_interface0_soc_bus_cyc;
+  wire main_minsoc_interface0_soc_bus_stb;
+  wire main_minsoc_interface0_soc_bus_ack;
+  wire main_minsoc_interface0_soc_bus_we;
+  wire [2:0] main_minsoc_interface0_soc_bus_cti;
+  wire [1:0] main_minsoc_interface0_soc_bus_bte;
+  wire main_minsoc_interface0_soc_bus_err;
+  wire [29:0] main_minsoc_interface1_soc_bus_adr;
+  wire [31:0] main_minsoc_interface1_soc_bus_dat_w;
+  wire [31:0] main_minsoc_interface1_soc_bus_dat_r;
+  wire [3:0] main_minsoc_interface1_soc_bus_sel;
+  wire main_minsoc_interface1_soc_bus_cyc;
+  wire main_minsoc_interface1_soc_bus_stb;
+  wire main_minsoc_interface1_soc_bus_ack;
+  wire main_minsoc_interface1_soc_bus_we;
+  wire [2:0] main_minsoc_interface1_soc_bus_cti;
+  wire [1:0] main_minsoc_interface1_soc_bus_bte;
+  wire main_minsoc_interface1_soc_bus_err;
+  wire [29:0] main_minsoc_rom_bus_adr;
+  wire [31:0] main_minsoc_rom_bus_dat_w;
+  wire [31:0] main_minsoc_rom_bus_dat_r;
+  wire [3:0] main_minsoc_rom_bus_sel;
+  wire main_minsoc_rom_bus_cyc;
+  wire main_minsoc_rom_bus_stb;
+  reg main_minsoc_rom_bus_ack = 1'd0;
+  wire main_minsoc_rom_bus_we;
+  wire [2:0] main_minsoc_rom_bus_cti;
+  wire [1:0] main_minsoc_rom_bus_bte;
+  reg main_minsoc_rom_bus_err = 1'd0;
+  wire [12:0] main_minsoc_rom_adr;
+  wire [31:0] main_minsoc_rom_dat_r;
+  wire [29:0] main_minsoc_sram_bus_adr;
+  wire [31:0] main_minsoc_sram_bus_dat_w;
+  wire [31:0] main_minsoc_sram_bus_dat_r;
+  wire [3:0] main_minsoc_sram_bus_sel;
+  wire main_minsoc_sram_bus_cyc;
+  wire main_minsoc_sram_bus_stb;
+  reg main_minsoc_sram_bus_ack = 1'd0;
+  wire main_minsoc_sram_bus_we;
+  wire [2:0] main_minsoc_sram_bus_cti;
+  wire [1:0] main_minsoc_sram_bus_bte;
+  reg main_minsoc_sram_bus_err = 1'd0;
+  wire [9:0] main_minsoc_sram_adr;
+  wire [31:0] main_minsoc_sram_dat_r;
+  reg [3:0] main_minsoc_sram_we = 4'd0;
+  wire [31:0] main_minsoc_sram_dat_w;
+  reg [31:0] main_minsoc_storage = 32'd8246337;
+  reg main_minsoc_re = 1'd0;
+  wire main_minsoc_sink_valid;
+  reg main_minsoc_sink_ready = 1'd0;
+  wire main_minsoc_sink_first;
+  wire main_minsoc_sink_last;
+  wire [7:0] main_minsoc_sink_payload_data;
+  reg main_minsoc_uart_clk_txen = 1'd0;
+  reg [31:0] main_minsoc_phase_accumulator_tx = 32'd0;
+  reg [7:0] main_minsoc_tx_reg = 8'd0;
+  reg [3:0] main_minsoc_tx_bitcount = 4'd0;
+  reg main_minsoc_tx_busy = 1'd0;
+  reg main_minsoc_source_valid = 1'd0;
+  wire main_minsoc_source_ready;
+  reg main_minsoc_source_first = 1'd0;
+  reg main_minsoc_source_last = 1'd0;
+  reg [7:0] main_minsoc_source_payload_data = 8'd0;
+  reg main_minsoc_uart_clk_rxen = 1'd0;
+  reg [31:0] main_minsoc_phase_accumulator_rx = 32'd0;
+  wire main_minsoc_rx;
+  reg main_minsoc_rx_r = 1'd0;
+  reg [7:0] main_minsoc_rx_reg = 8'd0;
+  reg [3:0] main_minsoc_rx_bitcount = 4'd0;
+  reg main_minsoc_rx_busy = 1'd0;
+  wire main_minsoc_uart_rxtx_re;
+  wire [7:0] main_minsoc_uart_rxtx_r;
+  wire main_minsoc_uart_rxtx_we;
+  wire [7:0] main_minsoc_uart_rxtx_w;
+  wire main_minsoc_uart_txfull_status;
+  wire main_minsoc_uart_txfull_we;
+  wire main_minsoc_uart_rxempty_status;
+  wire main_minsoc_uart_rxempty_we;
+  wire main_minsoc_uart_irq;
+  wire main_minsoc_uart_tx_status;
+  reg main_minsoc_uart_tx_pending = 1'd0;
+  wire main_minsoc_uart_tx_trigger;
+  reg main_minsoc_uart_tx_clear = 1'd0;
+  reg main_minsoc_uart_tx_old_trigger = 1'd0;
+  wire main_minsoc_uart_rx_status;
+  reg main_minsoc_uart_rx_pending = 1'd0;
+  wire main_minsoc_uart_rx_trigger;
+  reg main_minsoc_uart_rx_clear = 1'd0;
+  reg main_minsoc_uart_rx_old_trigger = 1'd0;
+  wire main_minsoc_uart_eventmanager_status_re;
+  wire [1:0] main_minsoc_uart_eventmanager_status_r;
+  wire main_minsoc_uart_eventmanager_status_we;
+  reg [1:0] main_minsoc_uart_eventmanager_status_w = 2'd0;
+  wire main_minsoc_uart_eventmanager_pending_re;
+  wire [1:0] main_minsoc_uart_eventmanager_pending_r;
+  wire main_minsoc_uart_eventmanager_pending_we;
+  reg [1:0] main_minsoc_uart_eventmanager_pending_w = 2'd0;
+  reg [1:0] main_minsoc_uart_eventmanager_storage = 2'd0;
+  reg main_minsoc_uart_eventmanager_re = 1'd0;
+  wire main_minsoc_uart_uart_sink_valid;
+  wire main_minsoc_uart_uart_sink_ready;
+  wire main_minsoc_uart_uart_sink_first;
+  wire main_minsoc_uart_uart_sink_last;
+  wire [7:0] main_minsoc_uart_uart_sink_payload_data;
+  wire main_minsoc_uart_uart_source_valid;
+  wire main_minsoc_uart_uart_source_ready;
+  wire main_minsoc_uart_uart_source_first;
+  wire main_minsoc_uart_uart_source_last;
+  wire [7:0] main_minsoc_uart_uart_source_payload_data;
+  wire main_minsoc_uart_tx_fifo_sink_valid;
+  wire main_minsoc_uart_tx_fifo_sink_ready;
+  reg main_minsoc_uart_tx_fifo_sink_first = 1'd0;
+  reg main_minsoc_uart_tx_fifo_sink_last = 1'd0;
+  wire [7:0] main_minsoc_uart_tx_fifo_sink_payload_data;
+  wire main_minsoc_uart_tx_fifo_source_valid;
+  wire main_minsoc_uart_tx_fifo_source_ready;
+  wire main_minsoc_uart_tx_fifo_source_first;
+  wire main_minsoc_uart_tx_fifo_source_last;
+  wire [7:0] main_minsoc_uart_tx_fifo_source_payload_data;
+  wire main_minsoc_uart_tx_fifo_re;
+  reg main_minsoc_uart_tx_fifo_readable = 1'd0;
+  wire main_minsoc_uart_tx_fifo_syncfifo_we;
+  wire main_minsoc_uart_tx_fifo_syncfifo_writable;
+  wire main_minsoc_uart_tx_fifo_syncfifo_re;
+  wire main_minsoc_uart_tx_fifo_syncfifo_readable;
+  wire [9:0] main_minsoc_uart_tx_fifo_syncfifo_din;
+  wire [9:0] main_minsoc_uart_tx_fifo_syncfifo_dout;
+  reg [4:0] main_minsoc_uart_tx_fifo_level0 = 5'd0;
+  reg main_minsoc_uart_tx_fifo_replace = 1'd0;
+  reg [3:0] main_minsoc_uart_tx_fifo_produce = 4'd0;
+  reg [3:0] main_minsoc_uart_tx_fifo_consume = 4'd0;
+  reg [3:0] main_minsoc_uart_tx_fifo_wrport_adr = 4'd0;
+  wire [9:0] main_minsoc_uart_tx_fifo_wrport_dat_r;
+  wire main_minsoc_uart_tx_fifo_wrport_we;
+  wire [9:0] main_minsoc_uart_tx_fifo_wrport_dat_w;
+  wire main_minsoc_uart_tx_fifo_do_read;
+  wire [3:0] main_minsoc_uart_tx_fifo_rdport_adr;
+  wire [9:0] main_minsoc_uart_tx_fifo_rdport_dat_r;
+  wire main_minsoc_uart_tx_fifo_rdport_re;
+  wire [4:0] main_minsoc_uart_tx_fifo_level1;
+  wire [7:0] main_minsoc_uart_tx_fifo_fifo_in_payload_data;
+  wire main_minsoc_uart_tx_fifo_fifo_in_first;
+  wire main_minsoc_uart_tx_fifo_fifo_in_last;
+  wire [7:0] main_minsoc_uart_tx_fifo_fifo_out_payload_data;
+  wire main_minsoc_uart_tx_fifo_fifo_out_first;
+  wire main_minsoc_uart_tx_fifo_fifo_out_last;
+  wire main_minsoc_uart_rx_fifo_sink_valid;
+  wire main_minsoc_uart_rx_fifo_sink_ready;
+  wire main_minsoc_uart_rx_fifo_sink_first;
+  wire main_minsoc_uart_rx_fifo_sink_last;
+  wire [7:0] main_minsoc_uart_rx_fifo_sink_payload_data;
+  wire main_minsoc_uart_rx_fifo_source_valid;
+  wire main_minsoc_uart_rx_fifo_source_ready;
+  wire main_minsoc_uart_rx_fifo_source_first;
+  wire main_minsoc_uart_rx_fifo_source_last;
+  wire [7:0] main_minsoc_uart_rx_fifo_source_payload_data;
+  wire main_minsoc_uart_rx_fifo_re;
+  reg main_minsoc_uart_rx_fifo_readable = 1'd0;
+  wire main_minsoc_uart_rx_fifo_syncfifo_we;
+  wire main_minsoc_uart_rx_fifo_syncfifo_writable;
+  wire main_minsoc_uart_rx_fifo_syncfifo_re;
+  wire main_minsoc_uart_rx_fifo_syncfifo_readable;
+  wire [9:0] main_minsoc_uart_rx_fifo_syncfifo_din;
+  wire [9:0] main_minsoc_uart_rx_fifo_syncfifo_dout;
+  reg [4:0] main_minsoc_uart_rx_fifo_level0 = 5'd0;
+  reg main_minsoc_uart_rx_fifo_replace = 1'd0;
+  reg [3:0] main_minsoc_uart_rx_fifo_produce = 4'd0;
+  reg [3:0] main_minsoc_uart_rx_fifo_consume = 4'd0;
+  reg [3:0] main_minsoc_uart_rx_fifo_wrport_adr = 4'd0;
+  wire [9:0] main_minsoc_uart_rx_fifo_wrport_dat_r;
+  wire main_minsoc_uart_rx_fifo_wrport_we;
+  wire [9:0] main_minsoc_uart_rx_fifo_wrport_dat_w;
+  wire main_minsoc_uart_rx_fifo_do_read;
+  wire [3:0] main_minsoc_uart_rx_fifo_rdport_adr;
+  wire [9:0] main_minsoc_uart_rx_fifo_rdport_dat_r;
+  wire main_minsoc_uart_rx_fifo_rdport_re;
+  wire [4:0] main_minsoc_uart_rx_fifo_level1;
+  wire [7:0] main_minsoc_uart_rx_fifo_fifo_in_payload_data;
+  wire main_minsoc_uart_rx_fifo_fifo_in_first;
+  wire main_minsoc_uart_rx_fifo_fifo_in_last;
+  wire [7:0] main_minsoc_uart_rx_fifo_fifo_out_payload_data;
+  wire main_minsoc_uart_rx_fifo_fifo_out_first;
+  wire main_minsoc_uart_rx_fifo_fifo_out_last;
+  reg main_minsoc_uart_reset = 1'd0;
+  reg [31:0] main_minsoc_timer0_load_storage = 32'd0;
+  reg main_minsoc_timer0_load_re = 1'd0;
+  reg [31:0] main_minsoc_timer0_reload_storage = 32'd0;
+  reg main_minsoc_timer0_reload_re = 1'd0;
+  reg main_minsoc_timer0_en_storage = 1'd0;
+  reg main_minsoc_timer0_en_re = 1'd0;
+  reg main_minsoc_timer0_update_value_storage = 1'd0;
+  reg main_minsoc_timer0_update_value_re = 1'd0;
+  reg [31:0] main_minsoc_timer0_value_status = 32'd0;
+  wire main_minsoc_timer0_value_we;
+  wire main_minsoc_timer0_irq;
+  wire main_minsoc_timer0_zero_status;
+  reg main_minsoc_timer0_zero_pending = 1'd0;
+  wire main_minsoc_timer0_zero_trigger;
+  reg main_minsoc_timer0_zero_clear = 1'd0;
+  reg main_minsoc_timer0_zero_old_trigger = 1'd0;
+  wire main_minsoc_timer0_eventmanager_status_re;
+  wire main_minsoc_timer0_eventmanager_status_r;
+  wire main_minsoc_timer0_eventmanager_status_we;
+  wire main_minsoc_timer0_eventmanager_status_w;
+  wire main_minsoc_timer0_eventmanager_pending_re;
+  wire main_minsoc_timer0_eventmanager_pending_r;
+  wire main_minsoc_timer0_eventmanager_pending_we;
+  wire main_minsoc_timer0_eventmanager_pending_w;
+  reg main_minsoc_timer0_eventmanager_storage = 1'd0;
+  reg main_minsoc_timer0_eventmanager_re = 1'd0;
+  reg [31:0] main_minsoc_timer0_value = 32'd0;
+  reg [13:0] main_minsoc_interface_adr = 14'd0;
+  reg main_minsoc_interface_we = 1'd0;
+  wire [7:0] main_minsoc_interface_dat_w;
+  wire [7:0] main_minsoc_interface_dat_r;
+  wire [29:0] main_minsoc_bus_wishbone_adr;
+  wire [31:0] main_minsoc_bus_wishbone_dat_w;
+  wire [31:0] main_minsoc_bus_wishbone_dat_r;
+  wire [3:0] main_minsoc_bus_wishbone_sel;
+  wire main_minsoc_bus_wishbone_cyc;
+  wire main_minsoc_bus_wishbone_stb;
+  reg main_minsoc_bus_wishbone_ack = 1'd0;
+  wire main_minsoc_bus_wishbone_we;
+  wire [2:0] main_minsoc_bus_wishbone_cti;
+  wire [1:0] main_minsoc_bus_wishbone_bte;
+  reg main_minsoc_bus_wishbone_err = 1'd0;
+  wire [29:0] main_interface0_wb_sdram_adr;
+  wire [31:0] main_interface0_wb_sdram_dat_w;
+  reg [31:0] main_interface0_wb_sdram_dat_r = 32'd0;
+  wire [3:0] main_interface0_wb_sdram_sel;
+  wire main_interface0_wb_sdram_cyc;
+  wire main_interface0_wb_sdram_stb;
+  reg main_interface0_wb_sdram_ack = 1'd0;
+  wire main_interface0_wb_sdram_we;
+  wire [2:0] main_interface0_wb_sdram_cti;
+  wire [1:0] main_interface0_wb_sdram_bte;
+  reg main_interface0_wb_sdram_err = 1'd0;
+  wire sys_clk;
+  wire sys_rst;
+  wire sys4x_clk;
+  wire sys4x_dqs_clk;
+  wire clk200_clk;
+  wire clk200_rst;
+  wire main_pll_clkin;
+  wire main_reset;
+  wire main_locked;
+  wire main_clkout0;
+  wire main_clkout1;
+  wire main_clkout2;
+  wire main_clkout3;
+  reg [3:0] main_reset_counter = 4'd15;
+  reg main_ic_reset = 1'd1;
+  reg [4:0] main_a7ddrphy_half_sys8x_taps_storage = 5'd13;
+  reg main_a7ddrphy_half_sys8x_taps_re = 1'd0;
+  wire main_a7ddrphy_cdly_rst_re;
+  wire main_a7ddrphy_cdly_rst_r;
+  wire main_a7ddrphy_cdly_rst_we;
+  reg main_a7ddrphy_cdly_rst_w = 1'd0;
+  wire main_a7ddrphy_cdly_inc_re;
+  wire main_a7ddrphy_cdly_inc_r;
+  wire main_a7ddrphy_cdly_inc_we;
+  reg main_a7ddrphy_cdly_inc_w = 1'd0;
+  reg [1:0] main_a7ddrphy_dly_sel_storage = 2'd0;
+  reg main_a7ddrphy_dly_sel_re = 1'd0;
+  wire main_a7ddrphy_rdly_dq_rst_re;
+  wire main_a7ddrphy_rdly_dq_rst_r;
+  wire main_a7ddrphy_rdly_dq_rst_we;
+  reg main_a7ddrphy_rdly_dq_rst_w = 1'd0;
+  wire main_a7ddrphy_rdly_dq_inc_re;
+  wire main_a7ddrphy_rdly_dq_inc_r;
+  wire main_a7ddrphy_rdly_dq_inc_we;
+  reg main_a7ddrphy_rdly_dq_inc_w = 1'd0;
+  wire main_a7ddrphy_rdly_dq_bitslip_rst_re;
+  wire main_a7ddrphy_rdly_dq_bitslip_rst_r;
+  wire main_a7ddrphy_rdly_dq_bitslip_rst_we;
+  reg main_a7ddrphy_rdly_dq_bitslip_rst_w = 1'd0;
+  wire main_a7ddrphy_rdly_dq_bitslip_re;
+  wire main_a7ddrphy_rdly_dq_bitslip_r;
+  wire main_a7ddrphy_rdly_dq_bitslip_we;
+  reg main_a7ddrphy_rdly_dq_bitslip_w = 1'd0;
+  wire [13:0] main_a7ddrphy_dfi_p0_address;
+  wire [2:0] main_a7ddrphy_dfi_p0_bank;
+  wire main_a7ddrphy_dfi_p0_cas_n;
+  wire main_a7ddrphy_dfi_p0_cs_n;
+  wire main_a7ddrphy_dfi_p0_ras_n;
+  wire main_a7ddrphy_dfi_p0_we_n;
+  wire main_a7ddrphy_dfi_p0_cke;
+  wire main_a7ddrphy_dfi_p0_odt;
+  wire main_a7ddrphy_dfi_p0_reset_n;
+  wire main_a7ddrphy_dfi_p0_act_n;
+  wire [31:0] main_a7ddrphy_dfi_p0_wrdata;
+  wire main_a7ddrphy_dfi_p0_wrdata_en;
+  wire [3:0] main_a7ddrphy_dfi_p0_wrdata_mask;
+  wire main_a7ddrphy_dfi_p0_rddata_en;
+  reg [31:0] main_a7ddrphy_dfi_p0_rddata = 32'd0;
+  reg main_a7ddrphy_dfi_p0_rddata_valid = 1'd0;
+  wire [13:0] main_a7ddrphy_dfi_p1_address;
+  wire [2:0] main_a7ddrphy_dfi_p1_bank;
+  wire main_a7ddrphy_dfi_p1_cas_n;
+  wire main_a7ddrphy_dfi_p1_cs_n;
+  wire main_a7ddrphy_dfi_p1_ras_n;
+  wire main_a7ddrphy_dfi_p1_we_n;
+  wire main_a7ddrphy_dfi_p1_cke;
+  wire main_a7ddrphy_dfi_p1_odt;
+  wire main_a7ddrphy_dfi_p1_reset_n;
+  wire main_a7ddrphy_dfi_p1_act_n;
+  wire [31:0] main_a7ddrphy_dfi_p1_wrdata;
+  wire main_a7ddrphy_dfi_p1_wrdata_en;
+  wire [3:0] main_a7ddrphy_dfi_p1_wrdata_mask;
+  wire main_a7ddrphy_dfi_p1_rddata_en;
+  reg [31:0] main_a7ddrphy_dfi_p1_rddata = 32'd0;
+  reg main_a7ddrphy_dfi_p1_rddata_valid = 1'd0;
+  wire [13:0] main_a7ddrphy_dfi_p2_address;
+  wire [2:0] main_a7ddrphy_dfi_p2_bank;
+  wire main_a7ddrphy_dfi_p2_cas_n;
+  wire main_a7ddrphy_dfi_p2_cs_n;
+  wire main_a7ddrphy_dfi_p2_ras_n;
+  wire main_a7ddrphy_dfi_p2_we_n;
+  wire main_a7ddrphy_dfi_p2_cke;
+  wire main_a7ddrphy_dfi_p2_odt;
+  wire main_a7ddrphy_dfi_p2_reset_n;
+  wire main_a7ddrphy_dfi_p2_act_n;
+  wire [31:0] main_a7ddrphy_dfi_p2_wrdata;
+  wire main_a7ddrphy_dfi_p2_wrdata_en;
+  wire [3:0] main_a7ddrphy_dfi_p2_wrdata_mask;
+  wire main_a7ddrphy_dfi_p2_rddata_en;
+  reg [31:0] main_a7ddrphy_dfi_p2_rddata = 32'd0;
+  reg main_a7ddrphy_dfi_p2_rddata_valid = 1'd0;
+  wire [13:0] main_a7ddrphy_dfi_p3_address;
+  wire [2:0] main_a7ddrphy_dfi_p3_bank;
+  wire main_a7ddrphy_dfi_p3_cas_n;
+  wire main_a7ddrphy_dfi_p3_cs_n;
+  wire main_a7ddrphy_dfi_p3_ras_n;
+  wire main_a7ddrphy_dfi_p3_we_n;
+  wire main_a7ddrphy_dfi_p3_cke;
+  wire main_a7ddrphy_dfi_p3_odt;
+  wire main_a7ddrphy_dfi_p3_reset_n;
+  wire main_a7ddrphy_dfi_p3_act_n;
+  wire [31:0] main_a7ddrphy_dfi_p3_wrdata;
+  wire main_a7ddrphy_dfi_p3_wrdata_en;
+  wire [3:0] main_a7ddrphy_dfi_p3_wrdata_mask;
+  wire main_a7ddrphy_dfi_p3_rddata_en;
+  reg [31:0] main_a7ddrphy_dfi_p3_rddata = 32'd0;
+  reg main_a7ddrphy_dfi_p3_rddata_valid = 1'd0;
+  wire main_a7ddrphy_sd_clk_se_nodelay;
+  reg main_a7ddrphy_oe_dqs = 1'd0;
+  wire main_a7ddrphy_dqs_preamble;
+  wire main_a7ddrphy_dqs_postamble;
+  reg [7:0] main_a7ddrphy_dqs_serdes_pattern = 8'd85;
+  wire main_a7ddrphy_dqs_nodelay0;
+  wire main_a7ddrphy_dqs_t0;
+  wire main_a7ddrphy0;
+  wire main_a7ddrphy_dqs_nodelay1;
+  wire main_a7ddrphy_dqs_t1;
+  wire main_a7ddrphy1;
+  reg main_a7ddrphy_oe_dq = 1'd0;
+  wire main_a7ddrphy_dq_o_nodelay0;
+  wire main_a7ddrphy_dq_i_nodelay0;
+  wire main_a7ddrphy_dq_i_delayed0;
+  wire main_a7ddrphy_dq_t0;
+  wire [7:0] main_a7ddrphy_dq_i_data0;
+  wire [7:0] main_a7ddrphy_bitslip0_i;
+  reg [7:0] main_a7ddrphy_bitslip0_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip0_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip0_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay1;
+  wire main_a7ddrphy_dq_i_nodelay1;
+  wire main_a7ddrphy_dq_i_delayed1;
+  wire main_a7ddrphy_dq_t1;
+  wire [7:0] main_a7ddrphy_dq_i_data1;
+  wire [7:0] main_a7ddrphy_bitslip1_i;
+  reg [7:0] main_a7ddrphy_bitslip1_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip1_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip1_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay2;
+  wire main_a7ddrphy_dq_i_nodelay2;
+  wire main_a7ddrphy_dq_i_delayed2;
+  wire main_a7ddrphy_dq_t2;
+  wire [7:0] main_a7ddrphy_dq_i_data2;
+  wire [7:0] main_a7ddrphy_bitslip2_i;
+  reg [7:0] main_a7ddrphy_bitslip2_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip2_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip2_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay3;
+  wire main_a7ddrphy_dq_i_nodelay3;
+  wire main_a7ddrphy_dq_i_delayed3;
+  wire main_a7ddrphy_dq_t3;
+  wire [7:0] main_a7ddrphy_dq_i_data3;
+  wire [7:0] main_a7ddrphy_bitslip3_i;
+  reg [7:0] main_a7ddrphy_bitslip3_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip3_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip3_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay4;
+  wire main_a7ddrphy_dq_i_nodelay4;
+  wire main_a7ddrphy_dq_i_delayed4;
+  wire main_a7ddrphy_dq_t4;
+  wire [7:0] main_a7ddrphy_dq_i_data4;
+  wire [7:0] main_a7ddrphy_bitslip4_i;
+  reg [7:0] main_a7ddrphy_bitslip4_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip4_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip4_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay5;
+  wire main_a7ddrphy_dq_i_nodelay5;
+  wire main_a7ddrphy_dq_i_delayed5;
+  wire main_a7ddrphy_dq_t5;
+  wire [7:0] main_a7ddrphy_dq_i_data5;
+  wire [7:0] main_a7ddrphy_bitslip5_i;
+  reg [7:0] main_a7ddrphy_bitslip5_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip5_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip5_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay6;
+  wire main_a7ddrphy_dq_i_nodelay6;
+  wire main_a7ddrphy_dq_i_delayed6;
+  wire main_a7ddrphy_dq_t6;
+  wire [7:0] main_a7ddrphy_dq_i_data6;
+  wire [7:0] main_a7ddrphy_bitslip6_i;
+  reg [7:0] main_a7ddrphy_bitslip6_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip6_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip6_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay7;
+  wire main_a7ddrphy_dq_i_nodelay7;
+  wire main_a7ddrphy_dq_i_delayed7;
+  wire main_a7ddrphy_dq_t7;
+  wire [7:0] main_a7ddrphy_dq_i_data7;
+  wire [7:0] main_a7ddrphy_bitslip7_i;
+  reg [7:0] main_a7ddrphy_bitslip7_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip7_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip7_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay8;
+  wire main_a7ddrphy_dq_i_nodelay8;
+  wire main_a7ddrphy_dq_i_delayed8;
+  wire main_a7ddrphy_dq_t8;
+  wire [7:0] main_a7ddrphy_dq_i_data8;
+  wire [7:0] main_a7ddrphy_bitslip8_i;
+  reg [7:0] main_a7ddrphy_bitslip8_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip8_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip8_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay9;
+  wire main_a7ddrphy_dq_i_nodelay9;
+  wire main_a7ddrphy_dq_i_delayed9;
+  wire main_a7ddrphy_dq_t9;
+  wire [7:0] main_a7ddrphy_dq_i_data9;
+  wire [7:0] main_a7ddrphy_bitslip9_i;
+  reg [7:0] main_a7ddrphy_bitslip9_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip9_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip9_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay10;
+  wire main_a7ddrphy_dq_i_nodelay10;
+  wire main_a7ddrphy_dq_i_delayed10;
+  wire main_a7ddrphy_dq_t10;
+  wire [7:0] main_a7ddrphy_dq_i_data10;
+  wire [7:0] main_a7ddrphy_bitslip10_i;
+  reg [7:0] main_a7ddrphy_bitslip10_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip10_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip10_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay11;
+  wire main_a7ddrphy_dq_i_nodelay11;
+  wire main_a7ddrphy_dq_i_delayed11;
+  wire main_a7ddrphy_dq_t11;
+  wire [7:0] main_a7ddrphy_dq_i_data11;
+  wire [7:0] main_a7ddrphy_bitslip11_i;
+  reg [7:0] main_a7ddrphy_bitslip11_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip11_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip11_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay12;
+  wire main_a7ddrphy_dq_i_nodelay12;
+  wire main_a7ddrphy_dq_i_delayed12;
+  wire main_a7ddrphy_dq_t12;
+  wire [7:0] main_a7ddrphy_dq_i_data12;
+  wire [7:0] main_a7ddrphy_bitslip12_i;
+  reg [7:0] main_a7ddrphy_bitslip12_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip12_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip12_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay13;
+  wire main_a7ddrphy_dq_i_nodelay13;
+  wire main_a7ddrphy_dq_i_delayed13;
+  wire main_a7ddrphy_dq_t13;
+  wire [7:0] main_a7ddrphy_dq_i_data13;
+  wire [7:0] main_a7ddrphy_bitslip13_i;
+  reg [7:0] main_a7ddrphy_bitslip13_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip13_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip13_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay14;
+  wire main_a7ddrphy_dq_i_nodelay14;
+  wire main_a7ddrphy_dq_i_delayed14;
+  wire main_a7ddrphy_dq_t14;
+  wire [7:0] main_a7ddrphy_dq_i_data14;
+  wire [7:0] main_a7ddrphy_bitslip14_i;
+  reg [7:0] main_a7ddrphy_bitslip14_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip14_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip14_r = 16'd0;
+  wire main_a7ddrphy_dq_o_nodelay15;
+  wire main_a7ddrphy_dq_i_nodelay15;
+  wire main_a7ddrphy_dq_i_delayed15;
+  wire main_a7ddrphy_dq_t15;
+  wire [7:0] main_a7ddrphy_dq_i_data15;
+  wire [7:0] main_a7ddrphy_bitslip15_i;
+  reg [7:0] main_a7ddrphy_bitslip15_o = 8'd0;
+  reg [2:0] main_a7ddrphy_bitslip15_value = 3'd0;
+  reg [15:0] main_a7ddrphy_bitslip15_r = 16'd0;
+  reg main_a7ddrphy_n_rddata_en0 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en1 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en2 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en3 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en4 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en5 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en6 = 1'd0;
+  reg main_a7ddrphy_n_rddata_en7 = 1'd0;
+  wire main_a7ddrphy_oe;
+  reg [3:0] main_a7ddrphy_last_wrdata_en = 4'd0;
+  wire [13:0] main_sdram_inti_p0_address;
+  wire [2:0] main_sdram_inti_p0_bank;
+  reg main_sdram_inti_p0_cas_n = 1'd1;
+  reg main_sdram_inti_p0_cs_n = 1'd1;
+  reg main_sdram_inti_p0_ras_n = 1'd1;
+  reg main_sdram_inti_p0_we_n = 1'd1;
+  wire main_sdram_inti_p0_cke;
+  wire main_sdram_inti_p0_odt;
+  wire main_sdram_inti_p0_reset_n;
+  reg main_sdram_inti_p0_act_n = 1'd1;
+  wire [31:0] main_sdram_inti_p0_wrdata;
+  wire main_sdram_inti_p0_wrdata_en;
+  wire [3:0] main_sdram_inti_p0_wrdata_mask;
+  wire main_sdram_inti_p0_rddata_en;
+  reg [31:0] main_sdram_inti_p0_rddata = 32'd0;
+  reg main_sdram_inti_p0_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_inti_p1_address;
+  wire [2:0] main_sdram_inti_p1_bank;
+  reg main_sdram_inti_p1_cas_n = 1'd1;
+  reg main_sdram_inti_p1_cs_n = 1'd1;
+  reg main_sdram_inti_p1_ras_n = 1'd1;
+  reg main_sdram_inti_p1_we_n = 1'd1;
+  wire main_sdram_inti_p1_cke;
+  wire main_sdram_inti_p1_odt;
+  wire main_sdram_inti_p1_reset_n;
+  reg main_sdram_inti_p1_act_n = 1'd1;
+  wire [31:0] main_sdram_inti_p1_wrdata;
+  wire main_sdram_inti_p1_wrdata_en;
+  wire [3:0] main_sdram_inti_p1_wrdata_mask;
+  wire main_sdram_inti_p1_rddata_en;
+  reg [31:0] main_sdram_inti_p1_rddata = 32'd0;
+  reg main_sdram_inti_p1_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_inti_p2_address;
+  wire [2:0] main_sdram_inti_p2_bank;
+  reg main_sdram_inti_p2_cas_n = 1'd1;
+  reg main_sdram_inti_p2_cs_n = 1'd1;
+  reg main_sdram_inti_p2_ras_n = 1'd1;
+  reg main_sdram_inti_p2_we_n = 1'd1;
+  wire main_sdram_inti_p2_cke;
+  wire main_sdram_inti_p2_odt;
+  wire main_sdram_inti_p2_reset_n;
+  reg main_sdram_inti_p2_act_n = 1'd1;
+  wire [31:0] main_sdram_inti_p2_wrdata;
+  wire main_sdram_inti_p2_wrdata_en;
+  wire [3:0] main_sdram_inti_p2_wrdata_mask;
+  wire main_sdram_inti_p2_rddata_en;
+  reg [31:0] main_sdram_inti_p2_rddata = 32'd0;
+  reg main_sdram_inti_p2_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_inti_p3_address;
+  wire [2:0] main_sdram_inti_p3_bank;
+  reg main_sdram_inti_p3_cas_n = 1'd1;
+  reg main_sdram_inti_p3_cs_n = 1'd1;
+  reg main_sdram_inti_p3_ras_n = 1'd1;
+  reg main_sdram_inti_p3_we_n = 1'd1;
+  wire main_sdram_inti_p3_cke;
+  wire main_sdram_inti_p3_odt;
+  wire main_sdram_inti_p3_reset_n;
+  reg main_sdram_inti_p3_act_n = 1'd1;
+  wire [31:0] main_sdram_inti_p3_wrdata;
+  wire main_sdram_inti_p3_wrdata_en;
+  wire [3:0] main_sdram_inti_p3_wrdata_mask;
+  wire main_sdram_inti_p3_rddata_en;
+  reg [31:0] main_sdram_inti_p3_rddata = 32'd0;
+  reg main_sdram_inti_p3_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_slave_p0_address;
+  wire [2:0] main_sdram_slave_p0_bank;
+  wire main_sdram_slave_p0_cas_n;
+  wire main_sdram_slave_p0_cs_n;
+  wire main_sdram_slave_p0_ras_n;
+  wire main_sdram_slave_p0_we_n;
+  wire main_sdram_slave_p0_cke;
+  wire main_sdram_slave_p0_odt;
+  wire main_sdram_slave_p0_reset_n;
+  wire main_sdram_slave_p0_act_n;
+  wire [31:0] main_sdram_slave_p0_wrdata;
+  wire main_sdram_slave_p0_wrdata_en;
+  wire [3:0] main_sdram_slave_p0_wrdata_mask;
+  wire main_sdram_slave_p0_rddata_en;
+  reg [31:0] main_sdram_slave_p0_rddata = 32'd0;
+  reg main_sdram_slave_p0_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_slave_p1_address;
+  wire [2:0] main_sdram_slave_p1_bank;
+  wire main_sdram_slave_p1_cas_n;
+  wire main_sdram_slave_p1_cs_n;
+  wire main_sdram_slave_p1_ras_n;
+  wire main_sdram_slave_p1_we_n;
+  wire main_sdram_slave_p1_cke;
+  wire main_sdram_slave_p1_odt;
+  wire main_sdram_slave_p1_reset_n;
+  wire main_sdram_slave_p1_act_n;
+  wire [31:0] main_sdram_slave_p1_wrdata;
+  wire main_sdram_slave_p1_wrdata_en;
+  wire [3:0] main_sdram_slave_p1_wrdata_mask;
+  wire main_sdram_slave_p1_rddata_en;
+  reg [31:0] main_sdram_slave_p1_rddata = 32'd0;
+  reg main_sdram_slave_p1_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_slave_p2_address;
+  wire [2:0] main_sdram_slave_p2_bank;
+  wire main_sdram_slave_p2_cas_n;
+  wire main_sdram_slave_p2_cs_n;
+  wire main_sdram_slave_p2_ras_n;
+  wire main_sdram_slave_p2_we_n;
+  wire main_sdram_slave_p2_cke;
+  wire main_sdram_slave_p2_odt;
+  wire main_sdram_slave_p2_reset_n;
+  wire main_sdram_slave_p2_act_n;
+  wire [31:0] main_sdram_slave_p2_wrdata;
+  wire main_sdram_slave_p2_wrdata_en;
+  wire [3:0] main_sdram_slave_p2_wrdata_mask;
+  wire main_sdram_slave_p2_rddata_en;
+  reg [31:0] main_sdram_slave_p2_rddata = 32'd0;
+  reg main_sdram_slave_p2_rddata_valid = 1'd0;
+  wire [13:0] main_sdram_slave_p3_address;
+  wire [2:0] main_sdram_slave_p3_bank;
+  wire main_sdram_slave_p3_cas_n;
+  wire main_sdram_slave_p3_cs_n;
+  wire main_sdram_slave_p3_ras_n;
+  wire main_sdram_slave_p3_we_n;
+  wire main_sdram_slave_p3_cke;
+  wire main_sdram_slave_p3_odt;
+  wire main_sdram_slave_p3_reset_n;
+  wire main_sdram_slave_p3_act_n;
+  wire [31:0] main_sdram_slave_p3_wrdata;
+  wire main_sdram_slave_p3_wrdata_en;
+  wire [3:0] main_sdram_slave_p3_wrdata_mask;
+  wire main_sdram_slave_p3_rddata_en;
+  reg [31:0] main_sdram_slave_p3_rddata = 32'd0;
+  reg main_sdram_slave_p3_rddata_valid = 1'd0;
+  reg [13:0] main_sdram_master_p0_address = 14'd0;
+  reg [2:0] main_sdram_master_p0_bank = 3'd0;
+  reg main_sdram_master_p0_cas_n = 1'd1;
+  reg main_sdram_master_p0_cs_n = 1'd1;
+  reg main_sdram_master_p0_ras_n = 1'd1;
+  reg main_sdram_master_p0_we_n = 1'd1;
+  reg main_sdram_master_p0_cke = 1'd0;
+  reg main_sdram_master_p0_odt = 1'd0;
+  reg main_sdram_master_p0_reset_n = 1'd0;
+  reg main_sdram_master_p0_act_n = 1'd1;
+  reg [31:0] main_sdram_master_p0_wrdata = 32'd0;
+  reg main_sdram_master_p0_wrdata_en = 1'd0;
+  reg [3:0] main_sdram_master_p0_wrdata_mask = 4'd0;
+  reg main_sdram_master_p0_rddata_en = 1'd0;
+  wire [31:0] main_sdram_master_p0_rddata;
+  wire main_sdram_master_p0_rddata_valid;
+  reg [13:0] main_sdram_master_p1_address = 14'd0;
+  reg [2:0] main_sdram_master_p1_bank = 3'd0;
+  reg main_sdram_master_p1_cas_n = 1'd1;
+  reg main_sdram_master_p1_cs_n = 1'd1;
+  reg main_sdram_master_p1_ras_n = 1'd1;
+  reg main_sdram_master_p1_we_n = 1'd1;
+  reg main_sdram_master_p1_cke = 1'd0;
+  reg main_sdram_master_p1_odt = 1'd0;
+  reg main_sdram_master_p1_reset_n = 1'd0;
+  reg main_sdram_master_p1_act_n = 1'd1;
+  reg [31:0] main_sdram_master_p1_wrdata = 32'd0;
+  reg main_sdram_master_p1_wrdata_en = 1'd0;
+  reg [3:0] main_sdram_master_p1_wrdata_mask = 4'd0;
+  reg main_sdram_master_p1_rddata_en = 1'd0;
+  wire [31:0] main_sdram_master_p1_rddata;
+  wire main_sdram_master_p1_rddata_valid;
+  reg [13:0] main_sdram_master_p2_address = 14'd0;
+  reg [2:0] main_sdram_master_p2_bank = 3'd0;
+  reg main_sdram_master_p2_cas_n = 1'd1;
+  reg main_sdram_master_p2_cs_n = 1'd1;
+  reg main_sdram_master_p2_ras_n = 1'd1;
+  reg main_sdram_master_p2_we_n = 1'd1;
+  reg main_sdram_master_p2_cke = 1'd0;
+  reg main_sdram_master_p2_odt = 1'd0;
+  reg main_sdram_master_p2_reset_n = 1'd0;
+  reg main_sdram_master_p2_act_n = 1'd1;
+  reg [31:0] main_sdram_master_p2_wrdata = 32'd0;
+  reg main_sdram_master_p2_wrdata_en = 1'd0;
+  reg [3:0] main_sdram_master_p2_wrdata_mask = 4'd0;
+  reg main_sdram_master_p2_rddata_en = 1'd0;
+  wire [31:0] main_sdram_master_p2_rddata;
+  wire main_sdram_master_p2_rddata_valid;
+  reg [13:0] main_sdram_master_p3_address = 14'd0;
+  reg [2:0] main_sdram_master_p3_bank = 3'd0;
+  reg main_sdram_master_p3_cas_n = 1'd1;
+  reg main_sdram_master_p3_cs_n = 1'd1;
+  reg main_sdram_master_p3_ras_n = 1'd1;
+  reg main_sdram_master_p3_we_n = 1'd1;
+  reg main_sdram_master_p3_cke = 1'd0;
+  reg main_sdram_master_p3_odt = 1'd0;
+  reg main_sdram_master_p3_reset_n = 1'd0;
+  reg main_sdram_master_p3_act_n = 1'd1;
+  reg [31:0] main_sdram_master_p3_wrdata = 32'd0;
+  reg main_sdram_master_p3_wrdata_en = 1'd0;
+  reg [3:0] main_sdram_master_p3_wrdata_mask = 4'd0;
+  reg main_sdram_master_p3_rddata_en = 1'd0;
+  wire [31:0] main_sdram_master_p3_rddata;
+  wire main_sdram_master_p3_rddata_valid;
+  reg [3:0] main_sdram_storage = 4'd0;
+  reg main_sdram_re = 1'd0;
+  reg [5:0] main_sdram_phaseinjector0_command_storage = 6'd0;
+  reg main_sdram_phaseinjector0_command_re = 1'd0;
+  wire main_sdram_phaseinjector0_command_issue_re;
+  wire main_sdram_phaseinjector0_command_issue_r;
+  wire main_sdram_phaseinjector0_command_issue_we;
+  reg main_sdram_phaseinjector0_command_issue_w = 1'd0;
+  reg [13:0] main_sdram_phaseinjector0_address_storage = 14'd0;
+  reg main_sdram_phaseinjector0_address_re = 1'd0;
+  reg [2:0] main_sdram_phaseinjector0_baddress_storage = 3'd0;
+  reg main_sdram_phaseinjector0_baddress_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector0_wrdata_storage = 32'd0;
+  reg main_sdram_phaseinjector0_wrdata_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector0_status = 32'd0;
+  wire main_sdram_phaseinjector0_we;
+  reg [5:0] main_sdram_phaseinjector1_command_storage = 6'd0;
+  reg main_sdram_phaseinjector1_command_re = 1'd0;
+  wire main_sdram_phaseinjector1_command_issue_re;
+  wire main_sdram_phaseinjector1_command_issue_r;
+  wire main_sdram_phaseinjector1_command_issue_we;
+  reg main_sdram_phaseinjector1_command_issue_w = 1'd0;
+  reg [13:0] main_sdram_phaseinjector1_address_storage = 14'd0;
+  reg main_sdram_phaseinjector1_address_re = 1'd0;
+  reg [2:0] main_sdram_phaseinjector1_baddress_storage = 3'd0;
+  reg main_sdram_phaseinjector1_baddress_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector1_wrdata_storage = 32'd0;
+  reg main_sdram_phaseinjector1_wrdata_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector1_status = 32'd0;
+  wire main_sdram_phaseinjector1_we;
+  reg [5:0] main_sdram_phaseinjector2_command_storage = 6'd0;
+  reg main_sdram_phaseinjector2_command_re = 1'd0;
+  wire main_sdram_phaseinjector2_command_issue_re;
+  wire main_sdram_phaseinjector2_command_issue_r;
+  wire main_sdram_phaseinjector2_command_issue_we;
+  reg main_sdram_phaseinjector2_command_issue_w = 1'd0;
+  reg [13:0] main_sdram_phaseinjector2_address_storage = 14'd0;
+  reg main_sdram_phaseinjector2_address_re = 1'd0;
+  reg [2:0] main_sdram_phaseinjector2_baddress_storage = 3'd0;
+  reg main_sdram_phaseinjector2_baddress_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector2_wrdata_storage = 32'd0;
+  reg main_sdram_phaseinjector2_wrdata_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector2_status = 32'd0;
+  wire main_sdram_phaseinjector2_we;
+  reg [5:0] main_sdram_phaseinjector3_command_storage = 6'd0;
+  reg main_sdram_phaseinjector3_command_re = 1'd0;
+  wire main_sdram_phaseinjector3_command_issue_re;
+  wire main_sdram_phaseinjector3_command_issue_r;
+  wire main_sdram_phaseinjector3_command_issue_we;
+  reg main_sdram_phaseinjector3_command_issue_w = 1'd0;
+  reg [13:0] main_sdram_phaseinjector3_address_storage = 14'd0;
+  reg main_sdram_phaseinjector3_address_re = 1'd0;
+  reg [2:0] main_sdram_phaseinjector3_baddress_storage = 3'd0;
+  reg main_sdram_phaseinjector3_baddress_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector3_wrdata_storage = 32'd0;
+  reg main_sdram_phaseinjector3_wrdata_re = 1'd0;
+  reg [31:0] main_sdram_phaseinjector3_status = 32'd0;
+  wire main_sdram_phaseinjector3_we;
+  wire main_sdram_interface_bank0_valid;
+  wire main_sdram_interface_bank0_ready;
+  wire main_sdram_interface_bank0_we;
+  wire [20:0] main_sdram_interface_bank0_addr;
+  wire main_sdram_interface_bank0_lock;
+  wire main_sdram_interface_bank0_wdata_ready;
+  wire main_sdram_interface_bank0_rdata_valid;
+  wire main_sdram_interface_bank1_valid;
+  wire main_sdram_interface_bank1_ready;
+  wire main_sdram_interface_bank1_we;
+  wire [20:0] main_sdram_interface_bank1_addr;
+  wire main_sdram_interface_bank1_lock;
+  wire main_sdram_interface_bank1_wdata_ready;
+  wire main_sdram_interface_bank1_rdata_valid;
+  wire main_sdram_interface_bank2_valid;
+  wire main_sdram_interface_bank2_ready;
+  wire main_sdram_interface_bank2_we;
+  wire [20:0] main_sdram_interface_bank2_addr;
+  wire main_sdram_interface_bank2_lock;
+  wire main_sdram_interface_bank2_wdata_ready;
+  wire main_sdram_interface_bank2_rdata_valid;
+  wire main_sdram_interface_bank3_valid;
+  wire main_sdram_interface_bank3_ready;
+  wire main_sdram_interface_bank3_we;
+  wire [20:0] main_sdram_interface_bank3_addr;
+  wire main_sdram_interface_bank3_lock;
+  wire main_sdram_interface_bank3_wdata_ready;
+  wire main_sdram_interface_bank3_rdata_valid;
+  wire main_sdram_interface_bank4_valid;
+  wire main_sdram_interface_bank4_ready;
+  wire main_sdram_interface_bank4_we;
+  wire [20:0] main_sdram_interface_bank4_addr;
+  wire main_sdram_interface_bank4_lock;
+  wire main_sdram_interface_bank4_wdata_ready;
+  wire main_sdram_interface_bank4_rdata_valid;
+  wire main_sdram_interface_bank5_valid;
+  wire main_sdram_interface_bank5_ready;
+  wire main_sdram_interface_bank5_we;
+  wire [20:0] main_sdram_interface_bank5_addr;
+  wire main_sdram_interface_bank5_lock;
+  wire main_sdram_interface_bank5_wdata_ready;
+  wire main_sdram_interface_bank5_rdata_valid;
+  wire main_sdram_interface_bank6_valid;
+  wire main_sdram_interface_bank6_ready;
+  wire main_sdram_interface_bank6_we;
+  wire [20:0] main_sdram_interface_bank6_addr;
+  wire main_sdram_interface_bank6_lock;
+  wire main_sdram_interface_bank6_wdata_ready;
+  wire main_sdram_interface_bank6_rdata_valid;
+  wire main_sdram_interface_bank7_valid;
+  wire main_sdram_interface_bank7_ready;
+  wire main_sdram_interface_bank7_we;
+  wire [20:0] main_sdram_interface_bank7_addr;
+  wire main_sdram_interface_bank7_lock;
+  wire main_sdram_interface_bank7_wdata_ready;
+  wire main_sdram_interface_bank7_rdata_valid;
+  reg [127:0] main_sdram_interface_wdata = 128'd0;
+  reg [15:0] main_sdram_interface_wdata_we = 16'd0;
+  wire [127:0] main_sdram_interface_rdata;
+  reg [13:0] main_sdram_dfi_p0_address = 14'd0;
+  reg [2:0] main_sdram_dfi_p0_bank = 3'd0;
+  reg main_sdram_dfi_p0_cas_n = 1'd1;
+  reg main_sdram_dfi_p0_cs_n = 1'd1;
+  reg main_sdram_dfi_p0_ras_n = 1'd1;
+  reg main_sdram_dfi_p0_we_n = 1'd1;
+  wire main_sdram_dfi_p0_cke;
+  wire main_sdram_dfi_p0_odt;
+  wire main_sdram_dfi_p0_reset_n;
+  reg main_sdram_dfi_p0_act_n = 1'd1;
+  wire [31:0] main_sdram_dfi_p0_wrdata;
+  reg main_sdram_dfi_p0_wrdata_en = 1'd0;
+  wire [3:0] main_sdram_dfi_p0_wrdata_mask;
+  reg main_sdram_dfi_p0_rddata_en = 1'd0;
+  wire [31:0] main_sdram_dfi_p0_rddata;
+  wire main_sdram_dfi_p0_rddata_valid;
+  reg [13:0] main_sdram_dfi_p1_address = 14'd0;
+  reg [2:0] main_sdram_dfi_p1_bank = 3'd0;
+  reg main_sdram_dfi_p1_cas_n = 1'd1;
+  reg main_sdram_dfi_p1_cs_n = 1'd1;
+  reg main_sdram_dfi_p1_ras_n = 1'd1;
+  reg main_sdram_dfi_p1_we_n = 1'd1;
+  wire main_sdram_dfi_p1_cke;
+  wire main_sdram_dfi_p1_odt;
+  wire main_sdram_dfi_p1_reset_n;
+  reg main_sdram_dfi_p1_act_n = 1'd1;
+  wire [31:0] main_sdram_dfi_p1_wrdata;
+  reg main_sdram_dfi_p1_wrdata_en = 1'd0;
+  wire [3:0] main_sdram_dfi_p1_wrdata_mask;
+  reg main_sdram_dfi_p1_rddata_en = 1'd0;
+  wire [31:0] main_sdram_dfi_p1_rddata;
+  wire main_sdram_dfi_p1_rddata_valid;
+  reg [13:0] main_sdram_dfi_p2_address = 14'd0;
+  reg [2:0] main_sdram_dfi_p2_bank = 3'd0;
+  reg main_sdram_dfi_p2_cas_n = 1'd1;
+  reg main_sdram_dfi_p2_cs_n = 1'd1;
+  reg main_sdram_dfi_p2_ras_n = 1'd1;
+  reg main_sdram_dfi_p2_we_n = 1'd1;
+  wire main_sdram_dfi_p2_cke;
+  wire main_sdram_dfi_p2_odt;
+  wire main_sdram_dfi_p2_reset_n;
+  reg main_sdram_dfi_p2_act_n = 1'd1;
+  wire [31:0] main_sdram_dfi_p2_wrdata;
+  reg main_sdram_dfi_p2_wrdata_en = 1'd0;
+  wire [3:0] main_sdram_dfi_p2_wrdata_mask;
+  reg main_sdram_dfi_p2_rddata_en = 1'd0;
+  wire [31:0] main_sdram_dfi_p2_rddata;
+  wire main_sdram_dfi_p2_rddata_valid;
+  reg [13:0] main_sdram_dfi_p3_address = 14'd0;
+  reg [2:0] main_sdram_dfi_p3_bank = 3'd0;
+  reg main_sdram_dfi_p3_cas_n = 1'd1;
+  reg main_sdram_dfi_p3_cs_n = 1'd1;
+  reg main_sdram_dfi_p3_ras_n = 1'd1;
+  reg main_sdram_dfi_p3_we_n = 1'd1;
+  wire main_sdram_dfi_p3_cke;
+  wire main_sdram_dfi_p3_odt;
+  wire main_sdram_dfi_p3_reset_n;
+  reg main_sdram_dfi_p3_act_n = 1'd1;
+  wire [31:0] main_sdram_dfi_p3_wrdata;
+  reg main_sdram_dfi_p3_wrdata_en = 1'd0;
+  wire [3:0] main_sdram_dfi_p3_wrdata_mask;
+  reg main_sdram_dfi_p3_rddata_en = 1'd0;
+  wire [31:0] main_sdram_dfi_p3_rddata;
+  wire main_sdram_dfi_p3_rddata_valid;
+  reg main_sdram_cmd_valid = 1'd0;
+  reg main_sdram_cmd_ready = 1'd0;
+  reg main_sdram_cmd_last = 1'd0;
+  reg [13:0] main_sdram_cmd_payload_a = 14'd0;
+  reg [2:0] main_sdram_cmd_payload_ba = 3'd0;
+  reg main_sdram_cmd_payload_cas = 1'd0;
+  reg main_sdram_cmd_payload_ras = 1'd0;
+  reg main_sdram_cmd_payload_we = 1'd0;
+  reg main_sdram_cmd_payload_is_read = 1'd0;
+  reg main_sdram_cmd_payload_is_write = 1'd0;
+  wire main_sdram_wants_refresh;
+  wire main_sdram_wants_zqcs;
+  wire main_sdram_timer_wait;
+  wire main_sdram_timer_done0;
+  wire [8:0] main_sdram_timer_count0;
+  wire main_sdram_timer_done1;
+  reg [8:0] main_sdram_timer_count1 = 9'd468;
+  wire main_sdram_postponer_req_i;
+  reg main_sdram_postponer_req_o = 1'd0;
+  reg main_sdram_postponer_count = 1'd0;
+  reg main_sdram_sequencer_start0 = 1'd0;
+  wire main_sdram_sequencer_done0;
+  wire main_sdram_sequencer_start1;
+  reg main_sdram_sequencer_done1 = 1'd0;
+  reg [5:0] main_sdram_sequencer_counter = 6'd0;
+  reg main_sdram_sequencer_count = 1'd0;
+  wire main_sdram_zqcs_timer_wait;
+  wire main_sdram_zqcs_timer_done0;
+  wire [25:0] main_sdram_zqcs_timer_count0;
+  wire main_sdram_zqcs_timer_done1;
+  reg [25:0] main_sdram_zqcs_timer_count1 = 26'd59999999;
+  reg main_sdram_zqcs_executer_start = 1'd0;
+  reg main_sdram_zqcs_executer_done = 1'd0;
+  reg [4:0] main_sdram_zqcs_executer_counter = 5'd0;
+  wire main_sdram_bankmachine0_req_valid;
+  wire main_sdram_bankmachine0_req_ready;
+  wire main_sdram_bankmachine0_req_we;
+  wire [20:0] main_sdram_bankmachine0_req_addr;
+  wire main_sdram_bankmachine0_req_lock;
+  reg main_sdram_bankmachine0_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine0_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine0_refresh_req;
+  reg main_sdram_bankmachine0_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine0_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine0_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine0_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine0_cmd_payload_ba;
+  reg main_sdram_bankmachine0_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine0_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine0_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine0_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine0_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine0_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine0_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine0_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine0_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_we;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_re;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_readable;
+  wire [23:0] main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_din;
+  wire [23:0] main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_dout;
+  reg [3:0] main_sdram_bankmachine0_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine0_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine0_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine0_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine0_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine0_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine0_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine0_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine0_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine0_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine0_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine0_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine0_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine0_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine0_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine0_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine0_row = 14'd0;
+  reg main_sdram_bankmachine0_row_opened = 1'd0;
+  wire main_sdram_bankmachine0_row_hit;
+  reg main_sdram_bankmachine0_row_open = 1'd0;
+  reg main_sdram_bankmachine0_row_close = 1'd0;
+  reg main_sdram_bankmachine0_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine0_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine0_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine0_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine0_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine0_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine0_trccon_count = 2'd0;
+  wire main_sdram_bankmachine0_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine0_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine0_trascon_count = 2'd0;
+  wire main_sdram_bankmachine1_req_valid;
+  wire main_sdram_bankmachine1_req_ready;
+  wire main_sdram_bankmachine1_req_we;
+  wire [20:0] main_sdram_bankmachine1_req_addr;
+  wire main_sdram_bankmachine1_req_lock;
+  reg main_sdram_bankmachine1_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine1_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine1_refresh_req;
+  reg main_sdram_bankmachine1_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine1_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine1_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine1_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine1_cmd_payload_ba;
+  reg main_sdram_bankmachine1_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine1_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine1_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine1_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine1_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine1_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine1_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine1_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine1_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_we;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_re;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_readable;
+  wire [23:0] main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_din;
+  wire [23:0] main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_dout;
+  reg [3:0] main_sdram_bankmachine1_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine1_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine1_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine1_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine1_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine1_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine1_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine1_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine1_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine1_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine1_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine1_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine1_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine1_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine1_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine1_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine1_row = 14'd0;
+  reg main_sdram_bankmachine1_row_opened = 1'd0;
+  wire main_sdram_bankmachine1_row_hit;
+  reg main_sdram_bankmachine1_row_open = 1'd0;
+  reg main_sdram_bankmachine1_row_close = 1'd0;
+  reg main_sdram_bankmachine1_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine1_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine1_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine1_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine1_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine1_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine1_trccon_count = 2'd0;
+  wire main_sdram_bankmachine1_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine1_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine1_trascon_count = 2'd0;
+  wire main_sdram_bankmachine2_req_valid;
+  wire main_sdram_bankmachine2_req_ready;
+  wire main_sdram_bankmachine2_req_we;
+  wire [20:0] main_sdram_bankmachine2_req_addr;
+  wire main_sdram_bankmachine2_req_lock;
+  reg main_sdram_bankmachine2_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine2_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine2_refresh_req;
+  reg main_sdram_bankmachine2_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine2_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine2_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine2_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine2_cmd_payload_ba;
+  reg main_sdram_bankmachine2_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine2_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine2_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine2_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine2_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine2_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine2_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine2_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine2_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_we;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_re;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_readable;
+  wire [23:0] main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_din;
+  wire [23:0] main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_dout;
+  reg [3:0] main_sdram_bankmachine2_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine2_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine2_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine2_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine2_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine2_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine2_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine2_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine2_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine2_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine2_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine2_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine2_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine2_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine2_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine2_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine2_row = 14'd0;
+  reg main_sdram_bankmachine2_row_opened = 1'd0;
+  wire main_sdram_bankmachine2_row_hit;
+  reg main_sdram_bankmachine2_row_open = 1'd0;
+  reg main_sdram_bankmachine2_row_close = 1'd0;
+  reg main_sdram_bankmachine2_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine2_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine2_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine2_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine2_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine2_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine2_trccon_count = 2'd0;
+  wire main_sdram_bankmachine2_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine2_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine2_trascon_count = 2'd0;
+  wire main_sdram_bankmachine3_req_valid;
+  wire main_sdram_bankmachine3_req_ready;
+  wire main_sdram_bankmachine3_req_we;
+  wire [20:0] main_sdram_bankmachine3_req_addr;
+  wire main_sdram_bankmachine3_req_lock;
+  reg main_sdram_bankmachine3_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine3_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine3_refresh_req;
+  reg main_sdram_bankmachine3_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine3_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine3_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine3_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine3_cmd_payload_ba;
+  reg main_sdram_bankmachine3_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine3_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine3_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine3_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine3_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine3_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine3_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine3_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine3_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_we;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_re;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_readable;
+  wire [23:0] main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_din;
+  wire [23:0] main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_dout;
+  reg [3:0] main_sdram_bankmachine3_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine3_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine3_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine3_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine3_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine3_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine3_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine3_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine3_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine3_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine3_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine3_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine3_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine3_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine3_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine3_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine3_row = 14'd0;
+  reg main_sdram_bankmachine3_row_opened = 1'd0;
+  wire main_sdram_bankmachine3_row_hit;
+  reg main_sdram_bankmachine3_row_open = 1'd0;
+  reg main_sdram_bankmachine3_row_close = 1'd0;
+  reg main_sdram_bankmachine3_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine3_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine3_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine3_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine3_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine3_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine3_trccon_count = 2'd0;
+  wire main_sdram_bankmachine3_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine3_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine3_trascon_count = 2'd0;
+  wire main_sdram_bankmachine4_req_valid;
+  wire main_sdram_bankmachine4_req_ready;
+  wire main_sdram_bankmachine4_req_we;
+  wire [20:0] main_sdram_bankmachine4_req_addr;
+  wire main_sdram_bankmachine4_req_lock;
+  reg main_sdram_bankmachine4_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine4_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine4_refresh_req;
+  reg main_sdram_bankmachine4_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine4_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine4_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine4_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine4_cmd_payload_ba;
+  reg main_sdram_bankmachine4_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine4_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine4_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine4_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine4_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine4_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine4_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine4_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine4_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_we;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_re;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_readable;
+  wire [23:0] main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_din;
+  wire [23:0] main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_dout;
+  reg [3:0] main_sdram_bankmachine4_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine4_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine4_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine4_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine4_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine4_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine4_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine4_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine4_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine4_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine4_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine4_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine4_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine4_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine4_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine4_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine4_row = 14'd0;
+  reg main_sdram_bankmachine4_row_opened = 1'd0;
+  wire main_sdram_bankmachine4_row_hit;
+  reg main_sdram_bankmachine4_row_open = 1'd0;
+  reg main_sdram_bankmachine4_row_close = 1'd0;
+  reg main_sdram_bankmachine4_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine4_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine4_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine4_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine4_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine4_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine4_trccon_count = 2'd0;
+  wire main_sdram_bankmachine4_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine4_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine4_trascon_count = 2'd0;
+  wire main_sdram_bankmachine5_req_valid;
+  wire main_sdram_bankmachine5_req_ready;
+  wire main_sdram_bankmachine5_req_we;
+  wire [20:0] main_sdram_bankmachine5_req_addr;
+  wire main_sdram_bankmachine5_req_lock;
+  reg main_sdram_bankmachine5_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine5_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine5_refresh_req;
+  reg main_sdram_bankmachine5_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine5_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine5_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine5_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine5_cmd_payload_ba;
+  reg main_sdram_bankmachine5_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine5_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine5_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine5_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine5_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine5_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine5_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine5_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine5_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_we;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_re;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_readable;
+  wire [23:0] main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_din;
+  wire [23:0] main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_dout;
+  reg [3:0] main_sdram_bankmachine5_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine5_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine5_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine5_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine5_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine5_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine5_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine5_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine5_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine5_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine5_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine5_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine5_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine5_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine5_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine5_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine5_row = 14'd0;
+  reg main_sdram_bankmachine5_row_opened = 1'd0;
+  wire main_sdram_bankmachine5_row_hit;
+  reg main_sdram_bankmachine5_row_open = 1'd0;
+  reg main_sdram_bankmachine5_row_close = 1'd0;
+  reg main_sdram_bankmachine5_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine5_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine5_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine5_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine5_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine5_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine5_trccon_count = 2'd0;
+  wire main_sdram_bankmachine5_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine5_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine5_trascon_count = 2'd0;
+  wire main_sdram_bankmachine6_req_valid;
+  wire main_sdram_bankmachine6_req_ready;
+  wire main_sdram_bankmachine6_req_we;
+  wire [20:0] main_sdram_bankmachine6_req_addr;
+  wire main_sdram_bankmachine6_req_lock;
+  reg main_sdram_bankmachine6_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine6_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine6_refresh_req;
+  reg main_sdram_bankmachine6_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine6_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine6_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine6_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine6_cmd_payload_ba;
+  reg main_sdram_bankmachine6_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine6_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine6_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine6_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine6_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine6_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine6_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine6_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine6_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_we;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_re;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_readable;
+  wire [23:0] main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_din;
+  wire [23:0] main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_dout;
+  reg [3:0] main_sdram_bankmachine6_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine6_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine6_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine6_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine6_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine6_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine6_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine6_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine6_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine6_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine6_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine6_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine6_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine6_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine6_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine6_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine6_row = 14'd0;
+  reg main_sdram_bankmachine6_row_opened = 1'd0;
+  wire main_sdram_bankmachine6_row_hit;
+  reg main_sdram_bankmachine6_row_open = 1'd0;
+  reg main_sdram_bankmachine6_row_close = 1'd0;
+  reg main_sdram_bankmachine6_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine6_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine6_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine6_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine6_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine6_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine6_trccon_count = 2'd0;
+  wire main_sdram_bankmachine6_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine6_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine6_trascon_count = 2'd0;
+  wire main_sdram_bankmachine7_req_valid;
+  wire main_sdram_bankmachine7_req_ready;
+  wire main_sdram_bankmachine7_req_we;
+  wire [20:0] main_sdram_bankmachine7_req_addr;
+  wire main_sdram_bankmachine7_req_lock;
+  reg main_sdram_bankmachine7_req_wdata_ready = 1'd0;
+  reg main_sdram_bankmachine7_req_rdata_valid = 1'd0;
+  wire main_sdram_bankmachine7_refresh_req;
+  reg main_sdram_bankmachine7_refresh_gnt = 1'd0;
+  reg main_sdram_bankmachine7_cmd_valid = 1'd0;
+  reg main_sdram_bankmachine7_cmd_ready = 1'd0;
+  reg [13:0] main_sdram_bankmachine7_cmd_payload_a = 14'd0;
+  wire [2:0] main_sdram_bankmachine7_cmd_payload_ba;
+  reg main_sdram_bankmachine7_cmd_payload_cas = 1'd0;
+  reg main_sdram_bankmachine7_cmd_payload_ras = 1'd0;
+  reg main_sdram_bankmachine7_cmd_payload_we = 1'd0;
+  reg main_sdram_bankmachine7_cmd_payload_is_cmd = 1'd0;
+  reg main_sdram_bankmachine7_cmd_payload_is_read = 1'd0;
+  reg main_sdram_bankmachine7_cmd_payload_is_write = 1'd0;
+  reg main_sdram_bankmachine7_auto_precharge = 1'd0;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_sink_valid;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_sink_ready;
+  reg main_sdram_bankmachine7_cmd_buffer_lookahead_sink_first = 1'd0;
+  reg main_sdram_bankmachine7_cmd_buffer_lookahead_sink_last = 1'd0;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_addr;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_source_valid;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_source_ready;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_source_first;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_source_last;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_we;
+  wire [20:0] main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_addr;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_we;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_re;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_readable;
+  wire [23:0] main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_din;
+  wire [23:0] main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_dout;
+  reg [3:0] main_sdram_bankmachine7_cmd_buffer_lookahead_level = 4'd0;
+  reg main_sdram_bankmachine7_cmd_buffer_lookahead_replace = 1'd0;
+  reg [2:0] main_sdram_bankmachine7_cmd_buffer_lookahead_produce = 3'd0;
+  reg [2:0] main_sdram_bankmachine7_cmd_buffer_lookahead_consume = 3'd0;
+  reg [2:0] main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr = 3'd0;
+  wire [23:0] main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_dat_r;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_we;
+  wire [23:0] main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_dat_w;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_do_read;
+  wire [2:0] main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_adr;
+  wire [23:0] main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_dat_r;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_we;
+  wire [20:0] main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_addr;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_first;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_last;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_we;
+  wire [20:0] main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_addr;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_first;
+  wire main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_last;
+  wire main_sdram_bankmachine7_cmd_buffer_sink_valid;
+  wire main_sdram_bankmachine7_cmd_buffer_sink_ready;
+  wire main_sdram_bankmachine7_cmd_buffer_sink_first;
+  wire main_sdram_bankmachine7_cmd_buffer_sink_last;
+  wire main_sdram_bankmachine7_cmd_buffer_sink_payload_we;
+  wire [20:0] main_sdram_bankmachine7_cmd_buffer_sink_payload_addr;
+  reg main_sdram_bankmachine7_cmd_buffer_source_valid = 1'd0;
+  wire main_sdram_bankmachine7_cmd_buffer_source_ready;
+  reg main_sdram_bankmachine7_cmd_buffer_source_first = 1'd0;
+  reg main_sdram_bankmachine7_cmd_buffer_source_last = 1'd0;
+  reg main_sdram_bankmachine7_cmd_buffer_source_payload_we = 1'd0;
+  reg [20:0] main_sdram_bankmachine7_cmd_buffer_source_payload_addr = 21'd0;
+  reg [13:0] main_sdram_bankmachine7_row = 14'd0;
+  reg main_sdram_bankmachine7_row_opened = 1'd0;
+  wire main_sdram_bankmachine7_row_hit;
+  reg main_sdram_bankmachine7_row_open = 1'd0;
+  reg main_sdram_bankmachine7_row_close = 1'd0;
+  reg main_sdram_bankmachine7_row_col_n_addr_sel = 1'd0;
+  wire main_sdram_bankmachine7_twtpcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine7_twtpcon_ready = 1'd1;
+  reg [2:0] main_sdram_bankmachine7_twtpcon_count = 3'd0;
+  wire main_sdram_bankmachine7_trccon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine7_trccon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine7_trccon_count = 2'd0;
+  wire main_sdram_bankmachine7_trascon_valid;
+  (* dont_touch = "true" *) reg main_sdram_bankmachine7_trascon_ready = 1'd1;
+  reg [1:0] main_sdram_bankmachine7_trascon_count = 2'd0;
+  wire main_sdram_ras_allowed;
+  wire main_sdram_cas_allowed;
+  reg main_sdram_choose_cmd_want_reads = 1'd0;
+  reg main_sdram_choose_cmd_want_writes = 1'd0;
+  reg main_sdram_choose_cmd_want_cmds = 1'd0;
+  reg main_sdram_choose_cmd_want_activates = 1'd0;
+  wire main_sdram_choose_cmd_cmd_valid;
+  reg main_sdram_choose_cmd_cmd_ready = 1'd0;
+  wire [13:0] main_sdram_choose_cmd_cmd_payload_a;
+  wire [2:0] main_sdram_choose_cmd_cmd_payload_ba;
+  reg main_sdram_choose_cmd_cmd_payload_cas = 1'd0;
+  reg main_sdram_choose_cmd_cmd_payload_ras = 1'd0;
+  reg main_sdram_choose_cmd_cmd_payload_we = 1'd0;
+  wire main_sdram_choose_cmd_cmd_payload_is_cmd;
+  wire main_sdram_choose_cmd_cmd_payload_is_read;
+  wire main_sdram_choose_cmd_cmd_payload_is_write;
+  reg [7:0] main_sdram_choose_cmd_valids = 8'd0;
+  wire [7:0] main_sdram_choose_cmd_request;
+  reg [2:0] main_sdram_choose_cmd_grant = 3'd0;
+  wire main_sdram_choose_cmd_ce;
+  reg main_sdram_choose_req_want_reads = 1'd0;
+  reg main_sdram_choose_req_want_writes = 1'd0;
+  reg main_sdram_choose_req_want_cmds = 1'd0;
+  reg main_sdram_choose_req_want_activates = 1'd0;
+  wire main_sdram_choose_req_cmd_valid;
+  reg main_sdram_choose_req_cmd_ready = 1'd0;
+  wire [13:0] main_sdram_choose_req_cmd_payload_a;
+  wire [2:0] main_sdram_choose_req_cmd_payload_ba;
+  reg main_sdram_choose_req_cmd_payload_cas = 1'd0;
+  reg main_sdram_choose_req_cmd_payload_ras = 1'd0;
+  reg main_sdram_choose_req_cmd_payload_we = 1'd0;
+  wire main_sdram_choose_req_cmd_payload_is_cmd;
+  wire main_sdram_choose_req_cmd_payload_is_read;
+  wire main_sdram_choose_req_cmd_payload_is_write;
+  reg [7:0] main_sdram_choose_req_valids = 8'd0;
+  wire [7:0] main_sdram_choose_req_request;
+  reg [2:0] main_sdram_choose_req_grant = 3'd0;
+  wire main_sdram_choose_req_ce;
+  reg [13:0] main_sdram_nop_a = 14'd0;
+  reg [2:0] main_sdram_nop_ba = 3'd0;
+  reg [1:0] main_sdram_steerer_sel0 = 2'd0;
+  reg [1:0] main_sdram_steerer_sel1 = 2'd0;
+  reg [1:0] main_sdram_steerer_sel2 = 2'd0;
+  reg [1:0] main_sdram_steerer_sel3 = 2'd0;
+  reg main_sdram_steerer0 = 1'd1;
+  reg main_sdram_steerer1 = 1'd1;
+  reg main_sdram_steerer2 = 1'd1;
+  reg main_sdram_steerer3 = 1'd1;
+  reg main_sdram_steerer4 = 1'd1;
+  reg main_sdram_steerer5 = 1'd1;
+  reg main_sdram_steerer6 = 1'd1;
+  reg main_sdram_steerer7 = 1'd1;
+  wire main_sdram_trrdcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_trrdcon_ready = 1'd1;
+  reg main_sdram_trrdcon_count = 1'd0;
+  wire main_sdram_tfawcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_tfawcon_ready = 1'd1;
+  wire [1:0] main_sdram_tfawcon_count;
+  reg [3:0] main_sdram_tfawcon_window = 4'd0;
+  wire main_sdram_tccdcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_tccdcon_ready = 1'd1;
+  reg main_sdram_tccdcon_count = 1'd0;
+  wire main_sdram_twtrcon_valid;
+  (* dont_touch = "true" *) reg main_sdram_twtrcon_ready = 1'd1;
+  reg [2:0] main_sdram_twtrcon_count = 3'd0;
+  wire main_sdram_read_available;
+  wire main_sdram_write_available;
+  reg main_sdram_en0 = 1'd0;
+  wire main_sdram_max_time0;
+  reg [4:0] main_sdram_time0 = 5'd0;
+  reg main_sdram_en1 = 1'd0;
+  wire main_sdram_max_time1;
+  reg [3:0] main_sdram_time1 = 4'd0;
+  wire main_sdram_go_to_refresh;
+  reg main_port_cmd_valid = 1'd0;
+  wire main_port_cmd_ready;
+  reg main_port_cmd_payload_we = 1'd0;
+  reg [23:0] main_port_cmd_payload_addr = 24'd0;
+  wire main_port_wdata_valid;
+  wire main_port_wdata_ready;
+  wire main_port_wdata_first;
+  wire main_port_wdata_last;
+  wire [127:0] main_port_wdata_payload_data;
+  wire [15:0] main_port_wdata_payload_we;
+  wire main_port_rdata_valid;
+  wire main_port_rdata_ready;
+  reg main_port_rdata_first = 1'd0;
+  reg main_port_rdata_last = 1'd0;
+  wire [127:0] main_port_rdata_payload_data;
+  wire [29:0] main_interface1_wb_sdram_adr;
+  wire [31:0] main_interface1_wb_sdram_dat_w;
+  wire [31:0] main_interface1_wb_sdram_dat_r;
+  wire [3:0] main_interface1_wb_sdram_sel;
+  wire main_interface1_wb_sdram_cyc;
+  wire main_interface1_wb_sdram_stb;
+  wire main_interface1_wb_sdram_ack;
+  wire main_interface1_wb_sdram_we;
+  wire [2:0] main_interface1_wb_sdram_cti;
+  wire [1:0] main_interface1_wb_sdram_bte;
+  wire main_interface1_wb_sdram_err;
+  wire [29:0] main_adr;
+  wire [127:0] main_dat_w;
+  wire [127:0] main_dat_r;
+  wire [15:0] main_sel;
+  reg main_cyc = 1'd0;
+  reg main_stb = 1'd0;
+  reg main_ack = 1'd0;
+  reg main_we = 1'd0;
+  wire [8:0] main_data_port_adr;
+  wire [127:0] main_data_port_dat_r;
+  reg [15:0] main_data_port_we = 16'd0;
+  reg [127:0] main_data_port_dat_w = 128'd0;
+  reg main_write_from_slave = 1'd0;
+  reg [1:0] main_adr_offset_r = 2'd0;
+  wire [8:0] main_tag_port_adr;
+  wire [23:0] main_tag_port_dat_r;
+  reg main_tag_port_we = 1'd0;
+  wire [23:0] main_tag_port_dat_w;
+  wire [22:0] main_tag_do_tag;
+  wire main_tag_do_dirty;
+  wire [22:0] main_tag_di_tag;
+  reg main_tag_di_dirty = 1'd0;
+  reg main_word_clr = 1'd0;
+  reg main_word_inc = 1'd0;
+  wire main_wdata_converter_sink_valid;
+  wire main_wdata_converter_sink_ready;
+  reg main_wdata_converter_sink_first = 1'd0;
+  reg main_wdata_converter_sink_last = 1'd0;
+  wire [127:0] main_wdata_converter_sink_payload_data;
+  wire [15:0] main_wdata_converter_sink_payload_we;
+  wire main_wdata_converter_source_valid;
+  wire main_wdata_converter_source_ready;
+  wire main_wdata_converter_source_first;
+  wire main_wdata_converter_source_last;
+  wire [127:0] main_wdata_converter_source_payload_data;
+  wire [15:0] main_wdata_converter_source_payload_we;
+  wire main_wdata_converter_converter_sink_valid;
+  wire main_wdata_converter_converter_sink_ready;
+  wire main_wdata_converter_converter_sink_first;
+  wire main_wdata_converter_converter_sink_last;
+  wire [143:0] main_wdata_converter_converter_sink_payload_data;
+  wire main_wdata_converter_converter_source_valid;
+  wire main_wdata_converter_converter_source_ready;
+  wire main_wdata_converter_converter_source_first;
+  wire main_wdata_converter_converter_source_last;
+  wire [143:0] main_wdata_converter_converter_source_payload_data;
+  wire main_wdata_converter_converter_source_payload_valid_token_count;
+  wire main_wdata_converter_source_source_valid;
+  wire main_wdata_converter_source_source_ready;
+  wire main_wdata_converter_source_source_first;
+  wire main_wdata_converter_source_source_last;
+  wire [143:0] main_wdata_converter_source_source_payload_data;
+  wire main_rdata_converter_sink_valid;
+  wire main_rdata_converter_sink_ready;
+  wire main_rdata_converter_sink_first;
+  wire main_rdata_converter_sink_last;
+  wire [127:0] main_rdata_converter_sink_payload_data;
+  wire main_rdata_converter_source_valid;
+  wire main_rdata_converter_source_ready;
+  wire main_rdata_converter_source_first;
+  wire main_rdata_converter_source_last;
+  wire [127:0] main_rdata_converter_source_payload_data;
+  wire main_rdata_converter_converter_sink_valid;
+  wire main_rdata_converter_converter_sink_ready;
+  wire main_rdata_converter_converter_sink_first;
+  wire main_rdata_converter_converter_sink_last;
+  wire [127:0] main_rdata_converter_converter_sink_payload_data;
+  wire main_rdata_converter_converter_source_valid;
+  wire main_rdata_converter_converter_source_ready;
+  wire main_rdata_converter_converter_source_first;
+  wire main_rdata_converter_converter_source_last;
+  wire [127:0] main_rdata_converter_converter_source_payload_data;
+  wire main_rdata_converter_converter_source_payload_valid_token_count;
+  wire main_rdata_converter_source_source_valid;
+  wire main_rdata_converter_source_source_ready;
+  wire main_rdata_converter_source_source_first;
+  wire main_rdata_converter_source_source_last;
+  wire [127:0] main_rdata_converter_source_source_payload_data;
+  reg main_count = 1'd0;
+  reg builder_wb2csr_state = 1'd0;
+  reg builder_wb2csr_next_state = 1'd0;
+  wire builder_pll_fb;
+  reg [1:0] builder_refresher_state = 2'd0;
+  reg [1:0] builder_refresher_next_state = 2'd0;
+  reg [2:0] builder_bankmachine0_state = 3'd0;
+  reg [2:0] builder_bankmachine0_next_state = 3'd0;
+  reg [2:0] builder_bankmachine1_state = 3'd0;
+  reg [2:0] builder_bankmachine1_next_state = 3'd0;
+  reg [2:0] builder_bankmachine2_state = 3'd0;
+  reg [2:0] builder_bankmachine2_next_state = 3'd0;
+  reg [2:0] builder_bankmachine3_state = 3'd0;
+  reg [2:0] builder_bankmachine3_next_state = 3'd0;
+  reg [2:0] builder_bankmachine4_state = 3'd0;
+  reg [2:0] builder_bankmachine4_next_state = 3'd0;
+  reg [2:0] builder_bankmachine5_state = 3'd0;
+  reg [2:0] builder_bankmachine5_next_state = 3'd0;
+  reg [2:0] builder_bankmachine6_state = 3'd0;
+  reg [2:0] builder_bankmachine6_next_state = 3'd0;
+  reg [2:0] builder_bankmachine7_state = 3'd0;
+  reg [2:0] builder_bankmachine7_next_state = 3'd0;
+  reg [3:0] builder_multiplexer_state = 4'd0;
+  reg [3:0] builder_multiplexer_next_state = 4'd0;
+  wire builder_roundrobin0_request;
+  wire builder_roundrobin0_grant;
+  wire builder_roundrobin0_ce;
+  wire builder_roundrobin1_request;
+  wire builder_roundrobin1_grant;
+  wire builder_roundrobin1_ce;
+  wire builder_roundrobin2_request;
+  wire builder_roundrobin2_grant;
+  wire builder_roundrobin2_ce;
+  wire builder_roundrobin3_request;
+  wire builder_roundrobin3_grant;
+  wire builder_roundrobin3_ce;
+  wire builder_roundrobin4_request;
+  wire builder_roundrobin4_grant;
+  wire builder_roundrobin4_ce;
+  wire builder_roundrobin5_request;
+  wire builder_roundrobin5_grant;
+  wire builder_roundrobin5_ce;
+  wire builder_roundrobin6_request;
+  wire builder_roundrobin6_grant;
+  wire builder_roundrobin6_ce;
+  wire builder_roundrobin7_request;
+  wire builder_roundrobin7_grant;
+  wire builder_roundrobin7_ce;
+  reg [2:0] builder_rbank = 3'd0;
+  reg [2:0] builder_wbank = 3'd0;
+  reg builder_locked0 = 1'd0;
+  reg builder_locked1 = 1'd0;
+  reg builder_locked2 = 1'd0;
+  reg builder_locked3 = 1'd0;
+  reg builder_locked4 = 1'd0;
+  reg builder_locked5 = 1'd0;
+  reg builder_locked6 = 1'd0;
+  reg builder_locked7 = 1'd0;
+  reg builder_new_master_wdata_ready0 = 1'd0;
+  reg builder_new_master_wdata_ready1 = 1'd0;
+  reg builder_new_master_wdata_ready2 = 1'd0;
+  reg builder_new_master_rdata_valid0 = 1'd0;
+  reg builder_new_master_rdata_valid1 = 1'd0;
+  reg builder_new_master_rdata_valid2 = 1'd0;
+  reg builder_new_master_rdata_valid3 = 1'd0;
+  reg builder_new_master_rdata_valid4 = 1'd0;
+  reg builder_new_master_rdata_valid5 = 1'd0;
+  reg builder_new_master_rdata_valid6 = 1'd0;
+  reg builder_new_master_rdata_valid7 = 1'd0;
+  reg builder_new_master_rdata_valid8 = 1'd0;
+  reg builder_new_master_rdata_valid9 = 1'd0;
+  reg [1:0] builder_fullmemorywe_state = 2'd0;
+  reg [1:0] builder_fullmemorywe_next_state = 2'd0;
+  reg [1:0] builder_litedramwishbone2native_state = 2'd0;
+  reg [1:0] builder_litedramwishbone2native_next_state = 2'd0;
+  reg main_count_next_value = 1'd0;
+  reg main_count_next_value_ce = 1'd0;
+  wire builder_wb_sdram_con_request;
+  wire builder_wb_sdram_con_grant;
+  wire [29:0] builder_minsoc_shared_adr;
+  wire [31:0] builder_minsoc_shared_dat_w;
+  reg [31:0] builder_minsoc_shared_dat_r = 32'd0;
+  wire [3:0] builder_minsoc_shared_sel;
+  wire builder_minsoc_shared_cyc;
+  wire builder_minsoc_shared_stb;
+  reg builder_minsoc_shared_ack = 1'd0;
+  wire builder_minsoc_shared_we;
+  wire [2:0] builder_minsoc_shared_cti;
+  wire [1:0] builder_minsoc_shared_bte;
+  wire builder_minsoc_shared_err;
+  wire [1:0] builder_minsoc_request;
+  reg builder_minsoc_grant = 1'd0;
+  reg [3:0] builder_minsoc_slave_sel = 4'd0;
+  reg [3:0] builder_minsoc_slave_sel_r = 4'd0;
+  reg builder_minsoc_error = 1'd0;
+  wire builder_minsoc_wait;
+  wire builder_minsoc_done;
+  reg [19:0] builder_minsoc_count = 20'd1000000;
+  wire [13:0] builder_minsoc_interface0_bank_bus_adr;
+  wire builder_minsoc_interface0_bank_bus_we;
+  wire [7:0] builder_minsoc_interface0_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface0_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank0_reset0_re;
+  wire builder_minsoc_csrbank0_reset0_r;
+  wire builder_minsoc_csrbank0_reset0_we;
+  wire builder_minsoc_csrbank0_reset0_w;
+  wire builder_minsoc_csrbank0_scratch3_re;
+  wire [7:0] builder_minsoc_csrbank0_scratch3_r;
+  wire builder_minsoc_csrbank0_scratch3_we;
+  wire [7:0] builder_minsoc_csrbank0_scratch3_w;
+  wire builder_minsoc_csrbank0_scratch2_re;
+  wire [7:0] builder_minsoc_csrbank0_scratch2_r;
+  wire builder_minsoc_csrbank0_scratch2_we;
+  wire [7:0] builder_minsoc_csrbank0_scratch2_w;
+  wire builder_minsoc_csrbank0_scratch1_re;
+  wire [7:0] builder_minsoc_csrbank0_scratch1_r;
+  wire builder_minsoc_csrbank0_scratch1_we;
+  wire [7:0] builder_minsoc_csrbank0_scratch1_w;
+  wire builder_minsoc_csrbank0_scratch0_re;
+  wire [7:0] builder_minsoc_csrbank0_scratch0_r;
+  wire builder_minsoc_csrbank0_scratch0_we;
+  wire [7:0] builder_minsoc_csrbank0_scratch0_w;
+  wire builder_minsoc_csrbank0_bus_errors3_re;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors3_r;
+  wire builder_minsoc_csrbank0_bus_errors3_we;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors3_w;
+  wire builder_minsoc_csrbank0_bus_errors2_re;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors2_r;
+  wire builder_minsoc_csrbank0_bus_errors2_we;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors2_w;
+  wire builder_minsoc_csrbank0_bus_errors1_re;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors1_r;
+  wire builder_minsoc_csrbank0_bus_errors1_we;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors1_w;
+  wire builder_minsoc_csrbank0_bus_errors0_re;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors0_r;
+  wire builder_minsoc_csrbank0_bus_errors0_we;
+  wire [7:0] builder_minsoc_csrbank0_bus_errors0_w;
+  wire builder_minsoc_csrbank0_sel;
+  wire [13:0] builder_minsoc_interface1_bank_bus_adr;
+  wire builder_minsoc_interface1_bank_bus_we;
+  wire [7:0] builder_minsoc_interface1_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface1_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank1_half_sys8x_taps0_re;
+  wire [4:0] builder_minsoc_csrbank1_half_sys8x_taps0_r;
+  wire builder_minsoc_csrbank1_half_sys8x_taps0_we;
+  wire [4:0] builder_minsoc_csrbank1_half_sys8x_taps0_w;
+  wire builder_minsoc_csrbank1_dly_sel0_re;
+  wire [1:0] builder_minsoc_csrbank1_dly_sel0_r;
+  wire builder_minsoc_csrbank1_dly_sel0_we;
+  wire [1:0] builder_minsoc_csrbank1_dly_sel0_w;
+  wire builder_minsoc_csrbank1_sel;
+  wire [13:0] builder_minsoc_interface2_bank_bus_adr;
+  wire builder_minsoc_interface2_bank_bus_we;
+  wire [7:0] builder_minsoc_interface2_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface2_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank2_dfii_control0_re;
+  wire [3:0] builder_minsoc_csrbank2_dfii_control0_r;
+  wire builder_minsoc_csrbank2_dfii_control0_we;
+  wire [3:0] builder_minsoc_csrbank2_dfii_control0_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_command0_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi0_command0_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_command0_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi0_command0_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_address1_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi0_address1_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_address1_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi0_address1_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_address0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_address0_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_address0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_address0_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_baddress0_re;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi0_baddress0_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_baddress0_we;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi0_baddress0_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_wrdata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_wrdata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi0_rddata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi0_rddata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_command0_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi1_command0_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_command0_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi1_command0_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_address1_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi1_address1_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_address1_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi1_address1_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_address0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_address0_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_address0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_address0_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_baddress0_re;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi1_baddress0_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_baddress0_we;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi1_baddress0_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_wrdata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_wrdata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi1_rddata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi1_rddata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_command0_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi2_command0_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_command0_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi2_command0_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_address1_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi2_address1_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_address1_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi2_address1_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_address0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_address0_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_address0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_address0_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_baddress0_re;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi2_baddress0_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_baddress0_we;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi2_baddress0_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_wrdata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_wrdata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi2_rddata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi2_rddata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_command0_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi3_command0_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_command0_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi3_command0_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_address1_re;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi3_address1_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_address1_we;
+  wire [5:0] builder_minsoc_csrbank2_dfii_pi3_address1_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_address0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_address0_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_address0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_address0_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_baddress0_re;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi3_baddress0_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_baddress0_we;
+  wire [2:0] builder_minsoc_csrbank2_dfii_pi3_baddress0_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_wrdata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_wrdata0_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata3_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata3_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata3_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata3_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata2_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata2_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata2_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata2_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata1_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata1_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata1_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata1_w;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata0_re;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata0_r;
+  wire builder_minsoc_csrbank2_dfii_pi3_rddata0_we;
+  wire [7:0] builder_minsoc_csrbank2_dfii_pi3_rddata0_w;
+  wire builder_minsoc_csrbank2_sel;
+  wire [13:0] builder_minsoc_interface3_bank_bus_adr;
+  wire builder_minsoc_interface3_bank_bus_we;
+  wire [7:0] builder_minsoc_interface3_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface3_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank3_load3_re;
+  wire [7:0] builder_minsoc_csrbank3_load3_r;
+  wire builder_minsoc_csrbank3_load3_we;
+  wire [7:0] builder_minsoc_csrbank3_load3_w;
+  wire builder_minsoc_csrbank3_load2_re;
+  wire [7:0] builder_minsoc_csrbank3_load2_r;
+  wire builder_minsoc_csrbank3_load2_we;
+  wire [7:0] builder_minsoc_csrbank3_load2_w;
+  wire builder_minsoc_csrbank3_load1_re;
+  wire [7:0] builder_minsoc_csrbank3_load1_r;
+  wire builder_minsoc_csrbank3_load1_we;
+  wire [7:0] builder_minsoc_csrbank3_load1_w;
+  wire builder_minsoc_csrbank3_load0_re;
+  wire [7:0] builder_minsoc_csrbank3_load0_r;
+  wire builder_minsoc_csrbank3_load0_we;
+  wire [7:0] builder_minsoc_csrbank3_load0_w;
+  wire builder_minsoc_csrbank3_reload3_re;
+  wire [7:0] builder_minsoc_csrbank3_reload3_r;
+  wire builder_minsoc_csrbank3_reload3_we;
+  wire [7:0] builder_minsoc_csrbank3_reload3_w;
+  wire builder_minsoc_csrbank3_reload2_re;
+  wire [7:0] builder_minsoc_csrbank3_reload2_r;
+  wire builder_minsoc_csrbank3_reload2_we;
+  wire [7:0] builder_minsoc_csrbank3_reload2_w;
+  wire builder_minsoc_csrbank3_reload1_re;
+  wire [7:0] builder_minsoc_csrbank3_reload1_r;
+  wire builder_minsoc_csrbank3_reload1_we;
+  wire [7:0] builder_minsoc_csrbank3_reload1_w;
+  wire builder_minsoc_csrbank3_reload0_re;
+  wire [7:0] builder_minsoc_csrbank3_reload0_r;
+  wire builder_minsoc_csrbank3_reload0_we;
+  wire [7:0] builder_minsoc_csrbank3_reload0_w;
+  wire builder_minsoc_csrbank3_en0_re;
+  wire builder_minsoc_csrbank3_en0_r;
+  wire builder_minsoc_csrbank3_en0_we;
+  wire builder_minsoc_csrbank3_en0_w;
+  wire builder_minsoc_csrbank3_update_value0_re;
+  wire builder_minsoc_csrbank3_update_value0_r;
+  wire builder_minsoc_csrbank3_update_value0_we;
+  wire builder_minsoc_csrbank3_update_value0_w;
+  wire builder_minsoc_csrbank3_value3_re;
+  wire [7:0] builder_minsoc_csrbank3_value3_r;
+  wire builder_minsoc_csrbank3_value3_we;
+  wire [7:0] builder_minsoc_csrbank3_value3_w;
+  wire builder_minsoc_csrbank3_value2_re;
+  wire [7:0] builder_minsoc_csrbank3_value2_r;
+  wire builder_minsoc_csrbank3_value2_we;
+  wire [7:0] builder_minsoc_csrbank3_value2_w;
+  wire builder_minsoc_csrbank3_value1_re;
+  wire [7:0] builder_minsoc_csrbank3_value1_r;
+  wire builder_minsoc_csrbank3_value1_we;
+  wire [7:0] builder_minsoc_csrbank3_value1_w;
+  wire builder_minsoc_csrbank3_value0_re;
+  wire [7:0] builder_minsoc_csrbank3_value0_r;
+  wire builder_minsoc_csrbank3_value0_we;
+  wire [7:0] builder_minsoc_csrbank3_value0_w;
+  wire builder_minsoc_csrbank3_ev_enable0_re;
+  wire builder_minsoc_csrbank3_ev_enable0_r;
+  wire builder_minsoc_csrbank3_ev_enable0_we;
+  wire builder_minsoc_csrbank3_ev_enable0_w;
+  wire builder_minsoc_csrbank3_sel;
+  wire [13:0] builder_minsoc_interface4_bank_bus_adr;
+  wire builder_minsoc_interface4_bank_bus_we;
+  wire [7:0] builder_minsoc_interface4_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface4_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank4_txfull_re;
+  wire builder_minsoc_csrbank4_txfull_r;
+  wire builder_minsoc_csrbank4_txfull_we;
+  wire builder_minsoc_csrbank4_txfull_w;
+  wire builder_minsoc_csrbank4_rxempty_re;
+  wire builder_minsoc_csrbank4_rxempty_r;
+  wire builder_minsoc_csrbank4_rxempty_we;
+  wire builder_minsoc_csrbank4_rxempty_w;
+  wire builder_minsoc_csrbank4_ev_enable0_re;
+  wire [1:0] builder_minsoc_csrbank4_ev_enable0_r;
+  wire builder_minsoc_csrbank4_ev_enable0_we;
+  wire [1:0] builder_minsoc_csrbank4_ev_enable0_w;
+  wire builder_minsoc_csrbank4_sel;
+  wire [13:0] builder_minsoc_interface5_bank_bus_adr;
+  wire builder_minsoc_interface5_bank_bus_we;
+  wire [7:0] builder_minsoc_interface5_bank_bus_dat_w;
+  reg [7:0] builder_minsoc_interface5_bank_bus_dat_r = 8'd0;
+  wire builder_minsoc_csrbank5_tuning_word3_re;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word3_r;
+  wire builder_minsoc_csrbank5_tuning_word3_we;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word3_w;
+  wire builder_minsoc_csrbank5_tuning_word2_re;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word2_r;
+  wire builder_minsoc_csrbank5_tuning_word2_we;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word2_w;
+  wire builder_minsoc_csrbank5_tuning_word1_re;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word1_r;
+  wire builder_minsoc_csrbank5_tuning_word1_we;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word1_w;
+  wire builder_minsoc_csrbank5_tuning_word0_re;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word0_r;
+  wire builder_minsoc_csrbank5_tuning_word0_we;
+  wire [7:0] builder_minsoc_csrbank5_tuning_word0_w;
+  wire builder_minsoc_csrbank5_sel;
+  wire [13:0] builder_minsoc_adr;
+  wire builder_minsoc_we;
+  wire [7:0] builder_minsoc_dat_w;
+  wire [7:0] builder_minsoc_dat_r;
+  reg builder_rhs_array_muxed0 = 1'd0;
+  reg [13:0] builder_rhs_array_muxed1 = 14'd0;
+  reg [2:0] builder_rhs_array_muxed2 = 3'd0;
+  reg builder_rhs_array_muxed3 = 1'd0;
+  reg builder_rhs_array_muxed4 = 1'd0;
+  reg builder_rhs_array_muxed5 = 1'd0;
+  reg builder_t_array_muxed0 = 1'd0;
+  reg builder_t_array_muxed1 = 1'd0;
+  reg builder_t_array_muxed2 = 1'd0;
+  reg builder_rhs_array_muxed6 = 1'd0;
+  reg [13:0] builder_rhs_array_muxed7 = 14'd0;
+  reg [2:0] builder_rhs_array_muxed8 = 3'd0;
+  reg builder_rhs_array_muxed9 = 1'd0;
+  reg builder_rhs_array_muxed10 = 1'd0;
+  reg builder_rhs_array_muxed11 = 1'd0;
+  reg builder_t_array_muxed3 = 1'd0;
+  reg builder_t_array_muxed4 = 1'd0;
+  reg builder_t_array_muxed5 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed12 = 21'd0;
+  reg builder_rhs_array_muxed13 = 1'd0;
+  reg builder_rhs_array_muxed14 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed15 = 21'd0;
+  reg builder_rhs_array_muxed16 = 1'd0;
+  reg builder_rhs_array_muxed17 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed18 = 21'd0;
+  reg builder_rhs_array_muxed19 = 1'd0;
+  reg builder_rhs_array_muxed20 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed21 = 21'd0;
+  reg builder_rhs_array_muxed22 = 1'd0;
+  reg builder_rhs_array_muxed23 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed24 = 21'd0;
+  reg builder_rhs_array_muxed25 = 1'd0;
+  reg builder_rhs_array_muxed26 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed27 = 21'd0;
+  reg builder_rhs_array_muxed28 = 1'd0;
+  reg builder_rhs_array_muxed29 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed30 = 21'd0;
+  reg builder_rhs_array_muxed31 = 1'd0;
+  reg builder_rhs_array_muxed32 = 1'd0;
+  reg [20:0] builder_rhs_array_muxed33 = 21'd0;
+  reg builder_rhs_array_muxed34 = 1'd0;
+  reg builder_rhs_array_muxed35 = 1'd0;
+  reg [29:0] builder_rhs_array_muxed36 = 30'd0;
+  reg [31:0] builder_rhs_array_muxed37 = 32'd0;
+  reg [3:0] builder_rhs_array_muxed38 = 4'd0;
+  reg builder_rhs_array_muxed39 = 1'd0;
+  reg builder_rhs_array_muxed40 = 1'd0;
+  reg builder_rhs_array_muxed41 = 1'd0;
+  reg [2:0] builder_rhs_array_muxed42 = 3'd0;
+  reg [1:0] builder_rhs_array_muxed43 = 2'd0;
+  reg [29:0] builder_rhs_array_muxed44 = 30'd0;
+  reg [31:0] builder_rhs_array_muxed45 = 32'd0;
+  reg [3:0] builder_rhs_array_muxed46 = 4'd0;
+  reg builder_rhs_array_muxed47 = 1'd0;
+  reg builder_rhs_array_muxed48 = 1'd0;
+  reg builder_rhs_array_muxed49 = 1'd0;
+  reg [2:0] builder_rhs_array_muxed50 = 3'd0;
+  reg [1:0] builder_rhs_array_muxed51 = 2'd0;
+  reg [2:0] builder_array_muxed0 = 3'd0;
+  reg [13:0] builder_array_muxed1 = 14'd0;
+  reg builder_array_muxed2 = 1'd0;
+  reg builder_array_muxed3 = 1'd0;
+  reg builder_array_muxed4 = 1'd0;
+  reg builder_array_muxed5 = 1'd0;
+  reg builder_array_muxed6 = 1'd0;
+  reg [2:0] builder_array_muxed7 = 3'd0;
+  reg [13:0] builder_array_muxed8 = 14'd0;
+  reg builder_array_muxed9 = 1'd0;
+  reg builder_array_muxed10 = 1'd0;
+  reg builder_array_muxed11 = 1'd0;
+  reg builder_array_muxed12 = 1'd0;
+  reg builder_array_muxed13 = 1'd0;
+  reg [2:0] builder_array_muxed14 = 3'd0;
+  reg [13:0] builder_array_muxed15 = 14'd0;
+  reg builder_array_muxed16 = 1'd0;
+  reg builder_array_muxed17 = 1'd0;
+  reg builder_array_muxed18 = 1'd0;
+  reg builder_array_muxed19 = 1'd0;
+  reg builder_array_muxed20 = 1'd0;
+  reg [2:0] builder_array_muxed21 = 3'd0;
+  reg [13:0] builder_array_muxed22 = 14'd0;
+  reg builder_array_muxed23 = 1'd0;
+  reg builder_array_muxed24 = 1'd0;
+  reg builder_array_muxed25 = 1'd0;
+  reg builder_array_muxed26 = 1'd0;
+  reg builder_array_muxed27 = 1'd0;
+  (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) reg builder_regs0 = 1'd0;
+  (* async_reg = "true", dont_touch = "true" *) reg builder_regs1 = 1'd0;
+  wire builder_xilinxasyncresetsynchronizerimpl0;
+  wire builder_xilinxasyncresetsynchronizerimpl0_rst_meta;
+  wire builder_xilinxasyncresetsynchronizerimpl1;
+  wire builder_xilinxasyncresetsynchronizerimpl1_rst_meta;
+  wire builder_xilinxasyncresetsynchronizerimpl1_expr;
+  wire builder_xilinxasyncresetsynchronizerimpl2;
+  wire builder_xilinxasyncresetsynchronizerimpl2_rst_meta;
+  wire builder_xilinxasyncresetsynchronizerimpl2_expr;
+  wire builder_xilinxasyncresetsynchronizerimpl3;
+  wire builder_xilinxasyncresetsynchronizerimpl3_rst_meta;
+
+  assign main_minsoc_cpu_reset = main_minsoc_ctrl_reset;
+  assign main_minsoc_ctrl_bus_error = builder_minsoc_error;
+  always @(*) begin
+    main_minsoc_cpu_interrupt <= 32'd0;
+    main_minsoc_cpu_interrupt[1] <= main_minsoc_timer0_irq;
+    main_minsoc_cpu_interrupt[0] <= main_minsoc_uart_irq;
+  end
+  assign main_minsoc_ctrl_reset = main_minsoc_ctrl_reset_re;
+  assign main_minsoc_ctrl_bus_errors_status = main_minsoc_ctrl_bus_errors;
+  assign main_minsoc_interface0_soc_bus_adr = main_minsoc_cpu_ibus_adr;
+  assign main_minsoc_interface0_soc_bus_dat_w = main_minsoc_cpu_ibus_dat_w;
+  assign main_minsoc_cpu_ibus_dat_r = main_minsoc_interface0_soc_bus_dat_r;
+  assign main_minsoc_interface0_soc_bus_sel = main_minsoc_cpu_ibus_sel;
+  assign main_minsoc_interface0_soc_bus_cyc = main_minsoc_cpu_ibus_cyc;
+  assign main_minsoc_interface0_soc_bus_stb = main_minsoc_cpu_ibus_stb;
+  assign main_minsoc_cpu_ibus_ack = main_minsoc_interface0_soc_bus_ack;
+  assign main_minsoc_interface0_soc_bus_we = main_minsoc_cpu_ibus_we;
+  assign main_minsoc_interface0_soc_bus_cti = main_minsoc_cpu_ibus_cti;
+  assign main_minsoc_interface0_soc_bus_bte = main_minsoc_cpu_ibus_bte;
+  assign main_minsoc_cpu_ibus_err = main_minsoc_interface0_soc_bus_err;
+  assign main_minsoc_interface1_soc_bus_adr = main_minsoc_cpu_dbus_adr;
+  assign main_minsoc_interface1_soc_bus_dat_w = main_minsoc_cpu_dbus_dat_w;
+  assign main_minsoc_cpu_dbus_dat_r = main_minsoc_interface1_soc_bus_dat_r;
+  assign main_minsoc_interface1_soc_bus_sel = main_minsoc_cpu_dbus_sel;
+  assign main_minsoc_interface1_soc_bus_cyc = main_minsoc_cpu_dbus_cyc;
+  assign main_minsoc_interface1_soc_bus_stb = main_minsoc_cpu_dbus_stb;
+  assign main_minsoc_cpu_dbus_ack = main_minsoc_interface1_soc_bus_ack;
+  assign main_minsoc_interface1_soc_bus_we = main_minsoc_cpu_dbus_we;
+  assign main_minsoc_interface1_soc_bus_cti = main_minsoc_cpu_dbus_cti;
+  assign main_minsoc_interface1_soc_bus_bte = main_minsoc_cpu_dbus_bte;
+  assign main_minsoc_cpu_dbus_err = main_minsoc_interface1_soc_bus_err;
+  assign main_minsoc_rom_adr = main_minsoc_rom_bus_adr[12:0];
+  assign main_minsoc_rom_bus_dat_r = main_minsoc_rom_dat_r;
+  always @(*) begin
+    main_minsoc_sram_we <= 4'd0;
+    main_minsoc_sram_we[0] <= (((main_minsoc_sram_bus_cyc & main_minsoc_sram_bus_stb) & main_minsoc_sram_bus_we) & main_minsoc_sram_bus_sel[0]);
+    main_minsoc_sram_we[1] <= (((main_minsoc_sram_bus_cyc & main_minsoc_sram_bus_stb) & main_minsoc_sram_bus_we) & main_minsoc_sram_bus_sel[1]);
+    main_minsoc_sram_we[2] <= (((main_minsoc_sram_bus_cyc & main_minsoc_sram_bus_stb) & main_minsoc_sram_bus_we) & main_minsoc_sram_bus_sel[2]);
+    main_minsoc_sram_we[3] <= (((main_minsoc_sram_bus_cyc & main_minsoc_sram_bus_stb) & main_minsoc_sram_bus_we) & main_minsoc_sram_bus_sel[3]);
+  end
+  assign main_minsoc_sram_adr = main_minsoc_sram_bus_adr[9:0];
+  assign main_minsoc_sram_bus_dat_r = main_minsoc_sram_dat_r;
+  assign main_minsoc_sram_dat_w = main_minsoc_sram_bus_dat_w;
+  assign main_minsoc_uart_uart_sink_valid = main_minsoc_source_valid;
+  assign main_minsoc_source_ready = main_minsoc_uart_uart_sink_ready;
+  assign main_minsoc_uart_uart_sink_first = main_minsoc_source_first;
+  assign main_minsoc_uart_uart_sink_last = main_minsoc_source_last;
+  assign main_minsoc_uart_uart_sink_payload_data = main_minsoc_source_payload_data;
+  assign main_minsoc_sink_valid = main_minsoc_uart_uart_source_valid;
+  assign main_minsoc_uart_uart_source_ready = main_minsoc_sink_ready;
+  assign main_minsoc_sink_first = main_minsoc_uart_uart_source_first;
+  assign main_minsoc_sink_last = main_minsoc_uart_uart_source_last;
+  assign main_minsoc_sink_payload_data = main_minsoc_uart_uart_source_payload_data;
+  assign main_minsoc_uart_tx_fifo_sink_valid = main_minsoc_uart_rxtx_re;
+  assign main_minsoc_uart_tx_fifo_sink_payload_data = main_minsoc_uart_rxtx_r;
+  assign main_minsoc_uart_txfull_status = (~main_minsoc_uart_tx_fifo_sink_ready);
+  assign main_minsoc_uart_uart_source_valid = main_minsoc_uart_tx_fifo_source_valid;
+  assign main_minsoc_uart_tx_fifo_source_ready = main_minsoc_uart_uart_source_ready;
+  assign main_minsoc_uart_uart_source_first = main_minsoc_uart_tx_fifo_source_first;
+  assign main_minsoc_uart_uart_source_last = main_minsoc_uart_tx_fifo_source_last;
+  assign main_minsoc_uart_uart_source_payload_data = main_minsoc_uart_tx_fifo_source_payload_data;
+  assign main_minsoc_uart_tx_trigger = (~main_minsoc_uart_tx_fifo_sink_ready);
+  assign main_minsoc_uart_rx_fifo_sink_valid = main_minsoc_uart_uart_sink_valid;
+  assign main_minsoc_uart_uart_sink_ready = main_minsoc_uart_rx_fifo_sink_ready;
+  assign main_minsoc_uart_rx_fifo_sink_first = main_minsoc_uart_uart_sink_first;
+  assign main_minsoc_uart_rx_fifo_sink_last = main_minsoc_uart_uart_sink_last;
+  assign main_minsoc_uart_rx_fifo_sink_payload_data = main_minsoc_uart_uart_sink_payload_data;
+  assign main_minsoc_uart_rxempty_status = (~main_minsoc_uart_rx_fifo_source_valid);
+  assign main_minsoc_uart_rxtx_w = main_minsoc_uart_rx_fifo_source_payload_data;
+  assign main_minsoc_uart_rx_fifo_source_ready = (main_minsoc_uart_rx_clear | (1'd0 & main_minsoc_uart_rxtx_we));
+  assign main_minsoc_uart_rx_trigger = (~main_minsoc_uart_rx_fifo_source_valid);
+  always @(*) begin
+    main_minsoc_uart_tx_clear <= 1'd0;
+    if ((main_minsoc_uart_eventmanager_pending_re & main_minsoc_uart_eventmanager_pending_r[0])) begin
+      main_minsoc_uart_tx_clear <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_minsoc_uart_eventmanager_status_w <= 2'd0;
+    main_minsoc_uart_eventmanager_status_w[0] <= main_minsoc_uart_tx_status;
+    main_minsoc_uart_eventmanager_status_w[1] <= main_minsoc_uart_rx_status;
+  end
+  always @(*) begin
+    main_minsoc_uart_rx_clear <= 1'd0;
+    if ((main_minsoc_uart_eventmanager_pending_re & main_minsoc_uart_eventmanager_pending_r[1])) begin
+      main_minsoc_uart_rx_clear <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_minsoc_uart_eventmanager_pending_w <= 2'd0;
+    main_minsoc_uart_eventmanager_pending_w[0] <= main_minsoc_uart_tx_pending;
+    main_minsoc_uart_eventmanager_pending_w[1] <= main_minsoc_uart_rx_pending;
+  end
+  assign main_minsoc_uart_irq = ((main_minsoc_uart_eventmanager_pending_w[0] & main_minsoc_uart_eventmanager_storage[0]) | (main_minsoc_uart_eventmanager_pending_w[1] & main_minsoc_uart_eventmanager_storage[1]));
+  assign main_minsoc_uart_tx_status = main_minsoc_uart_tx_trigger;
+  assign main_minsoc_uart_rx_status = main_minsoc_uart_rx_trigger;
+  assign main_minsoc_uart_tx_fifo_syncfifo_din = {
+    main_minsoc_uart_tx_fifo_fifo_in_last,
+    main_minsoc_uart_tx_fifo_fifo_in_first,
+    main_minsoc_uart_tx_fifo_fifo_in_payload_data
+  };
+  assign {main_minsoc_uart_tx_fifo_fifo_out_last, main_minsoc_uart_tx_fifo_fifo_out_first, main_minsoc_uart_tx_fifo_fifo_out_payload_data} = main_minsoc_uart_tx_fifo_syncfifo_dout;
+  assign main_minsoc_uart_tx_fifo_sink_ready = main_minsoc_uart_tx_fifo_syncfifo_writable;
+  assign main_minsoc_uart_tx_fifo_syncfifo_we = main_minsoc_uart_tx_fifo_sink_valid;
+  assign main_minsoc_uart_tx_fifo_fifo_in_first = main_minsoc_uart_tx_fifo_sink_first;
+  assign main_minsoc_uart_tx_fifo_fifo_in_last = main_minsoc_uart_tx_fifo_sink_last;
+  assign main_minsoc_uart_tx_fifo_fifo_in_payload_data = main_minsoc_uart_tx_fifo_sink_payload_data;
+  assign main_minsoc_uart_tx_fifo_source_valid = main_minsoc_uart_tx_fifo_readable;
+  assign main_minsoc_uart_tx_fifo_source_first = main_minsoc_uart_tx_fifo_fifo_out_first;
+  assign main_minsoc_uart_tx_fifo_source_last = main_minsoc_uart_tx_fifo_fifo_out_last;
+  assign main_minsoc_uart_tx_fifo_source_payload_data = main_minsoc_uart_tx_fifo_fifo_out_payload_data;
+  assign main_minsoc_uart_tx_fifo_re = main_minsoc_uart_tx_fifo_source_ready;
+  assign main_minsoc_uart_tx_fifo_syncfifo_re = (main_minsoc_uart_tx_fifo_syncfifo_readable & ((~main_minsoc_uart_tx_fifo_readable) | main_minsoc_uart_tx_fifo_re));
+  assign main_minsoc_uart_tx_fifo_level1 = (main_minsoc_uart_tx_fifo_level0 + main_minsoc_uart_tx_fifo_readable);
+  always @(*) begin
+    main_minsoc_uart_tx_fifo_wrport_adr <= 4'd0;
+    if (main_minsoc_uart_tx_fifo_replace) begin
+      main_minsoc_uart_tx_fifo_wrport_adr <= (main_minsoc_uart_tx_fifo_produce - 1'd1);
+    end else begin
+      main_minsoc_uart_tx_fifo_wrport_adr <= main_minsoc_uart_tx_fifo_produce;
+    end
+  end
+  assign main_minsoc_uart_tx_fifo_wrport_dat_w = main_minsoc_uart_tx_fifo_syncfifo_din;
+  assign main_minsoc_uart_tx_fifo_wrport_we = (main_minsoc_uart_tx_fifo_syncfifo_we & (main_minsoc_uart_tx_fifo_syncfifo_writable | main_minsoc_uart_tx_fifo_replace));
+  assign main_minsoc_uart_tx_fifo_do_read = (main_minsoc_uart_tx_fifo_syncfifo_readable & main_minsoc_uart_tx_fifo_syncfifo_re);
+  assign main_minsoc_uart_tx_fifo_rdport_adr = main_minsoc_uart_tx_fifo_consume;
+  assign main_minsoc_uart_tx_fifo_syncfifo_dout = main_minsoc_uart_tx_fifo_rdport_dat_r;
+  assign main_minsoc_uart_tx_fifo_rdport_re = main_minsoc_uart_tx_fifo_do_read;
+  assign main_minsoc_uart_tx_fifo_syncfifo_writable = (main_minsoc_uart_tx_fifo_level0 != 5'd16);
+  assign main_minsoc_uart_tx_fifo_syncfifo_readable = (main_minsoc_uart_tx_fifo_level0 != 1'd0);
+  assign main_minsoc_uart_rx_fifo_syncfifo_din = {
+    main_minsoc_uart_rx_fifo_fifo_in_last,
+    main_minsoc_uart_rx_fifo_fifo_in_first,
+    main_minsoc_uart_rx_fifo_fifo_in_payload_data
+  };
+  assign {main_minsoc_uart_rx_fifo_fifo_out_last, main_minsoc_uart_rx_fifo_fifo_out_first, main_minsoc_uart_rx_fifo_fifo_out_payload_data} = main_minsoc_uart_rx_fifo_syncfifo_dout;
+  assign main_minsoc_uart_rx_fifo_sink_ready = main_minsoc_uart_rx_fifo_syncfifo_writable;
+  assign main_minsoc_uart_rx_fifo_syncfifo_we = main_minsoc_uart_rx_fifo_sink_valid;
+  assign main_minsoc_uart_rx_fifo_fifo_in_first = main_minsoc_uart_rx_fifo_sink_first;
+  assign main_minsoc_uart_rx_fifo_fifo_in_last = main_minsoc_uart_rx_fifo_sink_last;
+  assign main_minsoc_uart_rx_fifo_fifo_in_payload_data = main_minsoc_uart_rx_fifo_sink_payload_data;
+  assign main_minsoc_uart_rx_fifo_source_valid = main_minsoc_uart_rx_fifo_readable;
+  assign main_minsoc_uart_rx_fifo_source_first = main_minsoc_uart_rx_fifo_fifo_out_first;
+  assign main_minsoc_uart_rx_fifo_source_last = main_minsoc_uart_rx_fifo_fifo_out_last;
+  assign main_minsoc_uart_rx_fifo_source_payload_data = main_minsoc_uart_rx_fifo_fifo_out_payload_data;
+  assign main_minsoc_uart_rx_fifo_re = main_minsoc_uart_rx_fifo_source_ready;
+  assign main_minsoc_uart_rx_fifo_syncfifo_re = (main_minsoc_uart_rx_fifo_syncfifo_readable & ((~main_minsoc_uart_rx_fifo_readable) | main_minsoc_uart_rx_fifo_re));
+  assign main_minsoc_uart_rx_fifo_level1 = (main_minsoc_uart_rx_fifo_level0 + main_minsoc_uart_rx_fifo_readable);
+  always @(*) begin
+    main_minsoc_uart_rx_fifo_wrport_adr <= 4'd0;
+    if (main_minsoc_uart_rx_fifo_replace) begin
+      main_minsoc_uart_rx_fifo_wrport_adr <= (main_minsoc_uart_rx_fifo_produce - 1'd1);
+    end else begin
+      main_minsoc_uart_rx_fifo_wrport_adr <= main_minsoc_uart_rx_fifo_produce;
+    end
+  end
+  assign main_minsoc_uart_rx_fifo_wrport_dat_w = main_minsoc_uart_rx_fifo_syncfifo_din;
+  assign main_minsoc_uart_rx_fifo_wrport_we = (main_minsoc_uart_rx_fifo_syncfifo_we & (main_minsoc_uart_rx_fifo_syncfifo_writable | main_minsoc_uart_rx_fifo_replace));
+  assign main_minsoc_uart_rx_fifo_do_read = (main_minsoc_uart_rx_fifo_syncfifo_readable & main_minsoc_uart_rx_fifo_syncfifo_re);
+  assign main_minsoc_uart_rx_fifo_rdport_adr = main_minsoc_uart_rx_fifo_consume;
+  assign main_minsoc_uart_rx_fifo_syncfifo_dout = main_minsoc_uart_rx_fifo_rdport_dat_r;
+  assign main_minsoc_uart_rx_fifo_rdport_re = main_minsoc_uart_rx_fifo_do_read;
+  assign main_minsoc_uart_rx_fifo_syncfifo_writable = (main_minsoc_uart_rx_fifo_level0 != 5'd16);
+  assign main_minsoc_uart_rx_fifo_syncfifo_readable = (main_minsoc_uart_rx_fifo_level0 != 1'd0);
+  assign main_minsoc_timer0_zero_trigger = (main_minsoc_timer0_value != 1'd0);
+  assign main_minsoc_timer0_eventmanager_status_w = main_minsoc_timer0_zero_status;
+  always @(*) begin
+    main_minsoc_timer0_zero_clear <= 1'd0;
+    if ((main_minsoc_timer0_eventmanager_pending_re & main_minsoc_timer0_eventmanager_pending_r)) begin
+      main_minsoc_timer0_zero_clear <= 1'd1;
+    end
+  end
+  assign main_minsoc_timer0_eventmanager_pending_w = main_minsoc_timer0_zero_pending;
+  assign main_minsoc_timer0_irq = (main_minsoc_timer0_eventmanager_pending_w & main_minsoc_timer0_eventmanager_storage);
+  assign main_minsoc_timer0_zero_status = main_minsoc_timer0_zero_trigger;
+  assign main_minsoc_interface_dat_w = main_minsoc_bus_wishbone_dat_w;
+  assign main_minsoc_bus_wishbone_dat_r = main_minsoc_interface_dat_r;
+  always @(*) begin
+    main_minsoc_interface_adr <= 14'd0;
+    main_minsoc_interface_we <= 1'd0;
+    builder_wb2csr_next_state <= 1'd0;
+    main_minsoc_bus_wishbone_ack <= 1'd0;
+    builder_wb2csr_next_state <= builder_wb2csr_state;
+    case (builder_wb2csr_state)
+      1'd1: begin
+        main_minsoc_bus_wishbone_ack <= 1'd1;
+        builder_wb2csr_next_state <= 1'd0;
+      end
+      default: begin
+        if ((main_minsoc_bus_wishbone_cyc & main_minsoc_bus_wishbone_stb)) begin
+          main_minsoc_interface_adr <= main_minsoc_bus_wishbone_adr;
+          main_minsoc_interface_we  <= main_minsoc_bus_wishbone_we;
+          builder_wb2csr_next_state <= 1'd1;
+        end
+      end
+    endcase
+  end
+  assign main_reset = (~cpu_reset);
+  always @(*) begin
+    main_a7ddrphy_dqs_serdes_pattern <= 8'd85;
+    main_a7ddrphy_dqs_serdes_pattern <= 7'd85;
+    if ((main_a7ddrphy_dqs_preamble | main_a7ddrphy_dqs_postamble)) begin
+      main_a7ddrphy_dqs_serdes_pattern <= 1'd0;
+    end
+  end
+  assign main_a7ddrphy_bitslip0_i  = main_a7ddrphy_dq_i_data0;
+  assign main_a7ddrphy_bitslip1_i  = main_a7ddrphy_dq_i_data1;
+  assign main_a7ddrphy_bitslip2_i  = main_a7ddrphy_dq_i_data2;
+  assign main_a7ddrphy_bitslip3_i  = main_a7ddrphy_dq_i_data3;
+  assign main_a7ddrphy_bitslip4_i  = main_a7ddrphy_dq_i_data4;
+  assign main_a7ddrphy_bitslip5_i  = main_a7ddrphy_dq_i_data5;
+  assign main_a7ddrphy_bitslip6_i  = main_a7ddrphy_dq_i_data6;
+  assign main_a7ddrphy_bitslip7_i  = main_a7ddrphy_dq_i_data7;
+  assign main_a7ddrphy_bitslip8_i  = main_a7ddrphy_dq_i_data8;
+  assign main_a7ddrphy_bitslip9_i  = main_a7ddrphy_dq_i_data9;
+  assign main_a7ddrphy_bitslip10_i = main_a7ddrphy_dq_i_data10;
+  assign main_a7ddrphy_bitslip11_i = main_a7ddrphy_dq_i_data11;
+  assign main_a7ddrphy_bitslip12_i = main_a7ddrphy_dq_i_data12;
+  assign main_a7ddrphy_bitslip13_i = main_a7ddrphy_dq_i_data13;
+  assign main_a7ddrphy_bitslip14_i = main_a7ddrphy_dq_i_data14;
+  assign main_a7ddrphy_bitslip15_i = main_a7ddrphy_dq_i_data15;
+  always @(*) begin
+    main_a7ddrphy_dfi_p0_rddata <= 32'd0;
+    main_a7ddrphy_dfi_p0_rddata[0] <= main_a7ddrphy_bitslip0_o[0];
+    main_a7ddrphy_dfi_p0_rddata[16] <= main_a7ddrphy_bitslip0_o[1];
+    main_a7ddrphy_dfi_p0_rddata[1] <= main_a7ddrphy_bitslip1_o[0];
+    main_a7ddrphy_dfi_p0_rddata[17] <= main_a7ddrphy_bitslip1_o[1];
+    main_a7ddrphy_dfi_p0_rddata[2] <= main_a7ddrphy_bitslip2_o[0];
+    main_a7ddrphy_dfi_p0_rddata[18] <= main_a7ddrphy_bitslip2_o[1];
+    main_a7ddrphy_dfi_p0_rddata[3] <= main_a7ddrphy_bitslip3_o[0];
+    main_a7ddrphy_dfi_p0_rddata[19] <= main_a7ddrphy_bitslip3_o[1];
+    main_a7ddrphy_dfi_p0_rddata[4] <= main_a7ddrphy_bitslip4_o[0];
+    main_a7ddrphy_dfi_p0_rddata[20] <= main_a7ddrphy_bitslip4_o[1];
+    main_a7ddrphy_dfi_p0_rddata[5] <= main_a7ddrphy_bitslip5_o[0];
+    main_a7ddrphy_dfi_p0_rddata[21] <= main_a7ddrphy_bitslip5_o[1];
+    main_a7ddrphy_dfi_p0_rddata[6] <= main_a7ddrphy_bitslip6_o[0];
+    main_a7ddrphy_dfi_p0_rddata[22] <= main_a7ddrphy_bitslip6_o[1];
+    main_a7ddrphy_dfi_p0_rddata[7] <= main_a7ddrphy_bitslip7_o[0];
+    main_a7ddrphy_dfi_p0_rddata[23] <= main_a7ddrphy_bitslip7_o[1];
+    main_a7ddrphy_dfi_p0_rddata[8] <= main_a7ddrphy_bitslip8_o[0];
+    main_a7ddrphy_dfi_p0_rddata[24] <= main_a7ddrphy_bitslip8_o[1];
+    main_a7ddrphy_dfi_p0_rddata[9] <= main_a7ddrphy_bitslip9_o[0];
+    main_a7ddrphy_dfi_p0_rddata[25] <= main_a7ddrphy_bitslip9_o[1];
+    main_a7ddrphy_dfi_p0_rddata[10] <= main_a7ddrphy_bitslip10_o[0];
+    main_a7ddrphy_dfi_p0_rddata[26] <= main_a7ddrphy_bitslip10_o[1];
+    main_a7ddrphy_dfi_p0_rddata[11] <= main_a7ddrphy_bitslip11_o[0];
+    main_a7ddrphy_dfi_p0_rddata[27] <= main_a7ddrphy_bitslip11_o[1];
+    main_a7ddrphy_dfi_p0_rddata[12] <= main_a7ddrphy_bitslip12_o[0];
+    main_a7ddrphy_dfi_p0_rddata[28] <= main_a7ddrphy_bitslip12_o[1];
+    main_a7ddrphy_dfi_p0_rddata[13] <= main_a7ddrphy_bitslip13_o[0];
+    main_a7ddrphy_dfi_p0_rddata[29] <= main_a7ddrphy_bitslip13_o[1];
+    main_a7ddrphy_dfi_p0_rddata[14] <= main_a7ddrphy_bitslip14_o[0];
+    main_a7ddrphy_dfi_p0_rddata[30] <= main_a7ddrphy_bitslip14_o[1];
+    main_a7ddrphy_dfi_p0_rddata[15] <= main_a7ddrphy_bitslip15_o[0];
+    main_a7ddrphy_dfi_p0_rddata[31] <= main_a7ddrphy_bitslip15_o[1];
+  end
+  always @(*) begin
+    main_a7ddrphy_dfi_p1_rddata <= 32'd0;
+    main_a7ddrphy_dfi_p1_rddata[0] <= main_a7ddrphy_bitslip0_o[2];
+    main_a7ddrphy_dfi_p1_rddata[16] <= main_a7ddrphy_bitslip0_o[3];
+    main_a7ddrphy_dfi_p1_rddata[1] <= main_a7ddrphy_bitslip1_o[2];
+    main_a7ddrphy_dfi_p1_rddata[17] <= main_a7ddrphy_bitslip1_o[3];
+    main_a7ddrphy_dfi_p1_rddata[2] <= main_a7ddrphy_bitslip2_o[2];
+    main_a7ddrphy_dfi_p1_rddata[18] <= main_a7ddrphy_bitslip2_o[3];
+    main_a7ddrphy_dfi_p1_rddata[3] <= main_a7ddrphy_bitslip3_o[2];
+    main_a7ddrphy_dfi_p1_rddata[19] <= main_a7ddrphy_bitslip3_o[3];
+    main_a7ddrphy_dfi_p1_rddata[4] <= main_a7ddrphy_bitslip4_o[2];
+    main_a7ddrphy_dfi_p1_rddata[20] <= main_a7ddrphy_bitslip4_o[3];
+    main_a7ddrphy_dfi_p1_rddata[5] <= main_a7ddrphy_bitslip5_o[2];
+    main_a7ddrphy_dfi_p1_rddata[21] <= main_a7ddrphy_bitslip5_o[3];
+    main_a7ddrphy_dfi_p1_rddata[6] <= main_a7ddrphy_bitslip6_o[2];
+    main_a7ddrphy_dfi_p1_rddata[22] <= main_a7ddrphy_bitslip6_o[3];
+    main_a7ddrphy_dfi_p1_rddata[7] <= main_a7ddrphy_bitslip7_o[2];
+    main_a7ddrphy_dfi_p1_rddata[23] <= main_a7ddrphy_bitslip7_o[3];
+    main_a7ddrphy_dfi_p1_rddata[8] <= main_a7ddrphy_bitslip8_o[2];
+    main_a7ddrphy_dfi_p1_rddata[24] <= main_a7ddrphy_bitslip8_o[3];
+    main_a7ddrphy_dfi_p1_rddata[9] <= main_a7ddrphy_bitslip9_o[2];
+    main_a7ddrphy_dfi_p1_rddata[25] <= main_a7ddrphy_bitslip9_o[3];
+    main_a7ddrphy_dfi_p1_rddata[10] <= main_a7ddrphy_bitslip10_o[2];
+    main_a7ddrphy_dfi_p1_rddata[26] <= main_a7ddrphy_bitslip10_o[3];
+    main_a7ddrphy_dfi_p1_rddata[11] <= main_a7ddrphy_bitslip11_o[2];
+    main_a7ddrphy_dfi_p1_rddata[27] <= main_a7ddrphy_bitslip11_o[3];
+    main_a7ddrphy_dfi_p1_rddata[12] <= main_a7ddrphy_bitslip12_o[2];
+    main_a7ddrphy_dfi_p1_rddata[28] <= main_a7ddrphy_bitslip12_o[3];
+    main_a7ddrphy_dfi_p1_rddata[13] <= main_a7ddrphy_bitslip13_o[2];
+    main_a7ddrphy_dfi_p1_rddata[29] <= main_a7ddrphy_bitslip13_o[3];
+    main_a7ddrphy_dfi_p1_rddata[14] <= main_a7ddrphy_bitslip14_o[2];
+    main_a7ddrphy_dfi_p1_rddata[30] <= main_a7ddrphy_bitslip14_o[3];
+    main_a7ddrphy_dfi_p1_rddata[15] <= main_a7ddrphy_bitslip15_o[2];
+    main_a7ddrphy_dfi_p1_rddata[31] <= main_a7ddrphy_bitslip15_o[3];
+  end
+  always @(*) begin
+    main_a7ddrphy_dfi_p2_rddata <= 32'd0;
+    main_a7ddrphy_dfi_p2_rddata[0] <= main_a7ddrphy_bitslip0_o[4];
+    main_a7ddrphy_dfi_p2_rddata[16] <= main_a7ddrphy_bitslip0_o[5];
+    main_a7ddrphy_dfi_p2_rddata[1] <= main_a7ddrphy_bitslip1_o[4];
+    main_a7ddrphy_dfi_p2_rddata[17] <= main_a7ddrphy_bitslip1_o[5];
+    main_a7ddrphy_dfi_p2_rddata[2] <= main_a7ddrphy_bitslip2_o[4];
+    main_a7ddrphy_dfi_p2_rddata[18] <= main_a7ddrphy_bitslip2_o[5];
+    main_a7ddrphy_dfi_p2_rddata[3] <= main_a7ddrphy_bitslip3_o[4];
+    main_a7ddrphy_dfi_p2_rddata[19] <= main_a7ddrphy_bitslip3_o[5];
+    main_a7ddrphy_dfi_p2_rddata[4] <= main_a7ddrphy_bitslip4_o[4];
+    main_a7ddrphy_dfi_p2_rddata[20] <= main_a7ddrphy_bitslip4_o[5];
+    main_a7ddrphy_dfi_p2_rddata[5] <= main_a7ddrphy_bitslip5_o[4];
+    main_a7ddrphy_dfi_p2_rddata[21] <= main_a7ddrphy_bitslip5_o[5];
+    main_a7ddrphy_dfi_p2_rddata[6] <= main_a7ddrphy_bitslip6_o[4];
+    main_a7ddrphy_dfi_p2_rddata[22] <= main_a7ddrphy_bitslip6_o[5];
+    main_a7ddrphy_dfi_p2_rddata[7] <= main_a7ddrphy_bitslip7_o[4];
+    main_a7ddrphy_dfi_p2_rddata[23] <= main_a7ddrphy_bitslip7_o[5];
+    main_a7ddrphy_dfi_p2_rddata[8] <= main_a7ddrphy_bitslip8_o[4];
+    main_a7ddrphy_dfi_p2_rddata[24] <= main_a7ddrphy_bitslip8_o[5];
+    main_a7ddrphy_dfi_p2_rddata[9] <= main_a7ddrphy_bitslip9_o[4];
+    main_a7ddrphy_dfi_p2_rddata[25] <= main_a7ddrphy_bitslip9_o[5];
+    main_a7ddrphy_dfi_p2_rddata[10] <= main_a7ddrphy_bitslip10_o[4];
+    main_a7ddrphy_dfi_p2_rddata[26] <= main_a7ddrphy_bitslip10_o[5];
+    main_a7ddrphy_dfi_p2_rddata[11] <= main_a7ddrphy_bitslip11_o[4];
+    main_a7ddrphy_dfi_p2_rddata[27] <= main_a7ddrphy_bitslip11_o[5];
+    main_a7ddrphy_dfi_p2_rddata[12] <= main_a7ddrphy_bitslip12_o[4];
+    main_a7ddrphy_dfi_p2_rddata[28] <= main_a7ddrphy_bitslip12_o[5];
+    main_a7ddrphy_dfi_p2_rddata[13] <= main_a7ddrphy_bitslip13_o[4];
+    main_a7ddrphy_dfi_p2_rddata[29] <= main_a7ddrphy_bitslip13_o[5];
+    main_a7ddrphy_dfi_p2_rddata[14] <= main_a7ddrphy_bitslip14_o[4];
+    main_a7ddrphy_dfi_p2_rddata[30] <= main_a7ddrphy_bitslip14_o[5];
+    main_a7ddrphy_dfi_p2_rddata[15] <= main_a7ddrphy_bitslip15_o[4];
+    main_a7ddrphy_dfi_p2_rddata[31] <= main_a7ddrphy_bitslip15_o[5];
+  end
+  always @(*) begin
+    main_a7ddrphy_dfi_p3_rddata <= 32'd0;
+    main_a7ddrphy_dfi_p3_rddata[0] <= main_a7ddrphy_bitslip0_o[6];
+    main_a7ddrphy_dfi_p3_rddata[16] <= main_a7ddrphy_bitslip0_o[7];
+    main_a7ddrphy_dfi_p3_rddata[1] <= main_a7ddrphy_bitslip1_o[6];
+    main_a7ddrphy_dfi_p3_rddata[17] <= main_a7ddrphy_bitslip1_o[7];
+    main_a7ddrphy_dfi_p3_rddata[2] <= main_a7ddrphy_bitslip2_o[6];
+    main_a7ddrphy_dfi_p3_rddata[18] <= main_a7ddrphy_bitslip2_o[7];
+    main_a7ddrphy_dfi_p3_rddata[3] <= main_a7ddrphy_bitslip3_o[6];
+    main_a7ddrphy_dfi_p3_rddata[19] <= main_a7ddrphy_bitslip3_o[7];
+    main_a7ddrphy_dfi_p3_rddata[4] <= main_a7ddrphy_bitslip4_o[6];
+    main_a7ddrphy_dfi_p3_rddata[20] <= main_a7ddrphy_bitslip4_o[7];
+    main_a7ddrphy_dfi_p3_rddata[5] <= main_a7ddrphy_bitslip5_o[6];
+    main_a7ddrphy_dfi_p3_rddata[21] <= main_a7ddrphy_bitslip5_o[7];
+    main_a7ddrphy_dfi_p3_rddata[6] <= main_a7ddrphy_bitslip6_o[6];
+    main_a7ddrphy_dfi_p3_rddata[22] <= main_a7ddrphy_bitslip6_o[7];
+    main_a7ddrphy_dfi_p3_rddata[7] <= main_a7ddrphy_bitslip7_o[6];
+    main_a7ddrphy_dfi_p3_rddata[23] <= main_a7ddrphy_bitslip7_o[7];
+    main_a7ddrphy_dfi_p3_rddata[8] <= main_a7ddrphy_bitslip8_o[6];
+    main_a7ddrphy_dfi_p3_rddata[24] <= main_a7ddrphy_bitslip8_o[7];
+    main_a7ddrphy_dfi_p3_rddata[9] <= main_a7ddrphy_bitslip9_o[6];
+    main_a7ddrphy_dfi_p3_rddata[25] <= main_a7ddrphy_bitslip9_o[7];
+    main_a7ddrphy_dfi_p3_rddata[10] <= main_a7ddrphy_bitslip10_o[6];
+    main_a7ddrphy_dfi_p3_rddata[26] <= main_a7ddrphy_bitslip10_o[7];
+    main_a7ddrphy_dfi_p3_rddata[11] <= main_a7ddrphy_bitslip11_o[6];
+    main_a7ddrphy_dfi_p3_rddata[27] <= main_a7ddrphy_bitslip11_o[7];
+    main_a7ddrphy_dfi_p3_rddata[12] <= main_a7ddrphy_bitslip12_o[6];
+    main_a7ddrphy_dfi_p3_rddata[28] <= main_a7ddrphy_bitslip12_o[7];
+    main_a7ddrphy_dfi_p3_rddata[13] <= main_a7ddrphy_bitslip13_o[6];
+    main_a7ddrphy_dfi_p3_rddata[29] <= main_a7ddrphy_bitslip13_o[7];
+    main_a7ddrphy_dfi_p3_rddata[14] <= main_a7ddrphy_bitslip14_o[6];
+    main_a7ddrphy_dfi_p3_rddata[30] <= main_a7ddrphy_bitslip14_o[7];
+    main_a7ddrphy_dfi_p3_rddata[15] <= main_a7ddrphy_bitslip15_o[6];
+    main_a7ddrphy_dfi_p3_rddata[31] <= main_a7ddrphy_bitslip15_o[7];
+  end
+  assign main_a7ddrphy_oe = ((main_a7ddrphy_last_wrdata_en[1] | main_a7ddrphy_last_wrdata_en[2]) | main_a7ddrphy_last_wrdata_en[3]);
+  assign main_a7ddrphy_dqs_preamble = (main_a7ddrphy_last_wrdata_en[1] & (~main_a7ddrphy_last_wrdata_en[2]));
+  assign main_a7ddrphy_dqs_postamble = (main_a7ddrphy_last_wrdata_en[3] & (~main_a7ddrphy_last_wrdata_en[2]));
+  assign main_a7ddrphy_dfi_p0_address = main_sdram_master_p0_address;
+  assign main_a7ddrphy_dfi_p0_bank = main_sdram_master_p0_bank;
+  assign main_a7ddrphy_dfi_p0_cas_n = main_sdram_master_p0_cas_n;
+  assign main_a7ddrphy_dfi_p0_cs_n = main_sdram_master_p0_cs_n;
+  assign main_a7ddrphy_dfi_p0_ras_n = main_sdram_master_p0_ras_n;
+  assign main_a7ddrphy_dfi_p0_we_n = main_sdram_master_p0_we_n;
+  assign main_a7ddrphy_dfi_p0_cke = main_sdram_master_p0_cke;
+  assign main_a7ddrphy_dfi_p0_odt = main_sdram_master_p0_odt;
+  assign main_a7ddrphy_dfi_p0_reset_n = main_sdram_master_p0_reset_n;
+  assign main_a7ddrphy_dfi_p0_act_n = main_sdram_master_p0_act_n;
+  assign main_a7ddrphy_dfi_p0_wrdata = main_sdram_master_p0_wrdata;
+  assign main_a7ddrphy_dfi_p0_wrdata_en = main_sdram_master_p0_wrdata_en;
+  assign main_a7ddrphy_dfi_p0_wrdata_mask = main_sdram_master_p0_wrdata_mask;
+  assign main_a7ddrphy_dfi_p0_rddata_en = main_sdram_master_p0_rddata_en;
+  assign main_sdram_master_p0_rddata = main_a7ddrphy_dfi_p0_rddata;
+  assign main_sdram_master_p0_rddata_valid = main_a7ddrphy_dfi_p0_rddata_valid;
+  assign main_a7ddrphy_dfi_p1_address = main_sdram_master_p1_address;
+  assign main_a7ddrphy_dfi_p1_bank = main_sdram_master_p1_bank;
+  assign main_a7ddrphy_dfi_p1_cas_n = main_sdram_master_p1_cas_n;
+  assign main_a7ddrphy_dfi_p1_cs_n = main_sdram_master_p1_cs_n;
+  assign main_a7ddrphy_dfi_p1_ras_n = main_sdram_master_p1_ras_n;
+  assign main_a7ddrphy_dfi_p1_we_n = main_sdram_master_p1_we_n;
+  assign main_a7ddrphy_dfi_p1_cke = main_sdram_master_p1_cke;
+  assign main_a7ddrphy_dfi_p1_odt = main_sdram_master_p1_odt;
+  assign main_a7ddrphy_dfi_p1_reset_n = main_sdram_master_p1_reset_n;
+  assign main_a7ddrphy_dfi_p1_act_n = main_sdram_master_p1_act_n;
+  assign main_a7ddrphy_dfi_p1_wrdata = main_sdram_master_p1_wrdata;
+  assign main_a7ddrphy_dfi_p1_wrdata_en = main_sdram_master_p1_wrdata_en;
+  assign main_a7ddrphy_dfi_p1_wrdata_mask = main_sdram_master_p1_wrdata_mask;
+  assign main_a7ddrphy_dfi_p1_rddata_en = main_sdram_master_p1_rddata_en;
+  assign main_sdram_master_p1_rddata = main_a7ddrphy_dfi_p1_rddata;
+  assign main_sdram_master_p1_rddata_valid = main_a7ddrphy_dfi_p1_rddata_valid;
+  assign main_a7ddrphy_dfi_p2_address = main_sdram_master_p2_address;
+  assign main_a7ddrphy_dfi_p2_bank = main_sdram_master_p2_bank;
+  assign main_a7ddrphy_dfi_p2_cas_n = main_sdram_master_p2_cas_n;
+  assign main_a7ddrphy_dfi_p2_cs_n = main_sdram_master_p2_cs_n;
+  assign main_a7ddrphy_dfi_p2_ras_n = main_sdram_master_p2_ras_n;
+  assign main_a7ddrphy_dfi_p2_we_n = main_sdram_master_p2_we_n;
+  assign main_a7ddrphy_dfi_p2_cke = main_sdram_master_p2_cke;
+  assign main_a7ddrphy_dfi_p2_odt = main_sdram_master_p2_odt;
+  assign main_a7ddrphy_dfi_p2_reset_n = main_sdram_master_p2_reset_n;
+  assign main_a7ddrphy_dfi_p2_act_n = main_sdram_master_p2_act_n;
+  assign main_a7ddrphy_dfi_p2_wrdata = main_sdram_master_p2_wrdata;
+  assign main_a7ddrphy_dfi_p2_wrdata_en = main_sdram_master_p2_wrdata_en;
+  assign main_a7ddrphy_dfi_p2_wrdata_mask = main_sdram_master_p2_wrdata_mask;
+  assign main_a7ddrphy_dfi_p2_rddata_en = main_sdram_master_p2_rddata_en;
+  assign main_sdram_master_p2_rddata = main_a7ddrphy_dfi_p2_rddata;
+  assign main_sdram_master_p2_rddata_valid = main_a7ddrphy_dfi_p2_rddata_valid;
+  assign main_a7ddrphy_dfi_p3_address = main_sdram_master_p3_address;
+  assign main_a7ddrphy_dfi_p3_bank = main_sdram_master_p3_bank;
+  assign main_a7ddrphy_dfi_p3_cas_n = main_sdram_master_p3_cas_n;
+  assign main_a7ddrphy_dfi_p3_cs_n = main_sdram_master_p3_cs_n;
+  assign main_a7ddrphy_dfi_p3_ras_n = main_sdram_master_p3_ras_n;
+  assign main_a7ddrphy_dfi_p3_we_n = main_sdram_master_p3_we_n;
+  assign main_a7ddrphy_dfi_p3_cke = main_sdram_master_p3_cke;
+  assign main_a7ddrphy_dfi_p3_odt = main_sdram_master_p3_odt;
+  assign main_a7ddrphy_dfi_p3_reset_n = main_sdram_master_p3_reset_n;
+  assign main_a7ddrphy_dfi_p3_act_n = main_sdram_master_p3_act_n;
+  assign main_a7ddrphy_dfi_p3_wrdata = main_sdram_master_p3_wrdata;
+  assign main_a7ddrphy_dfi_p3_wrdata_en = main_sdram_master_p3_wrdata_en;
+  assign main_a7ddrphy_dfi_p3_wrdata_mask = main_sdram_master_p3_wrdata_mask;
+  assign main_a7ddrphy_dfi_p3_rddata_en = main_sdram_master_p3_rddata_en;
+  assign main_sdram_master_p3_rddata = main_a7ddrphy_dfi_p3_rddata;
+  assign main_sdram_master_p3_rddata_valid = main_a7ddrphy_dfi_p3_rddata_valid;
+  assign main_sdram_slave_p0_address = main_sdram_dfi_p0_address;
+  assign main_sdram_slave_p0_bank = main_sdram_dfi_p0_bank;
+  assign main_sdram_slave_p0_cas_n = main_sdram_dfi_p0_cas_n;
+  assign main_sdram_slave_p0_cs_n = main_sdram_dfi_p0_cs_n;
+  assign main_sdram_slave_p0_ras_n = main_sdram_dfi_p0_ras_n;
+  assign main_sdram_slave_p0_we_n = main_sdram_dfi_p0_we_n;
+  assign main_sdram_slave_p0_cke = main_sdram_dfi_p0_cke;
+  assign main_sdram_slave_p0_odt = main_sdram_dfi_p0_odt;
+  assign main_sdram_slave_p0_reset_n = main_sdram_dfi_p0_reset_n;
+  assign main_sdram_slave_p0_act_n = main_sdram_dfi_p0_act_n;
+  assign main_sdram_slave_p0_wrdata = main_sdram_dfi_p0_wrdata;
+  assign main_sdram_slave_p0_wrdata_en = main_sdram_dfi_p0_wrdata_en;
+  assign main_sdram_slave_p0_wrdata_mask = main_sdram_dfi_p0_wrdata_mask;
+  assign main_sdram_slave_p0_rddata_en = main_sdram_dfi_p0_rddata_en;
+  assign main_sdram_dfi_p0_rddata = main_sdram_slave_p0_rddata;
+  assign main_sdram_dfi_p0_rddata_valid = main_sdram_slave_p0_rddata_valid;
+  assign main_sdram_slave_p1_address = main_sdram_dfi_p1_address;
+  assign main_sdram_slave_p1_bank = main_sdram_dfi_p1_bank;
+  assign main_sdram_slave_p1_cas_n = main_sdram_dfi_p1_cas_n;
+  assign main_sdram_slave_p1_cs_n = main_sdram_dfi_p1_cs_n;
+  assign main_sdram_slave_p1_ras_n = main_sdram_dfi_p1_ras_n;
+  assign main_sdram_slave_p1_we_n = main_sdram_dfi_p1_we_n;
+  assign main_sdram_slave_p1_cke = main_sdram_dfi_p1_cke;
+  assign main_sdram_slave_p1_odt = main_sdram_dfi_p1_odt;
+  assign main_sdram_slave_p1_reset_n = main_sdram_dfi_p1_reset_n;
+  assign main_sdram_slave_p1_act_n = main_sdram_dfi_p1_act_n;
+  assign main_sdram_slave_p1_wrdata = main_sdram_dfi_p1_wrdata;
+  assign main_sdram_slave_p1_wrdata_en = main_sdram_dfi_p1_wrdata_en;
+  assign main_sdram_slave_p1_wrdata_mask = main_sdram_dfi_p1_wrdata_mask;
+  assign main_sdram_slave_p1_rddata_en = main_sdram_dfi_p1_rddata_en;
+  assign main_sdram_dfi_p1_rddata = main_sdram_slave_p1_rddata;
+  assign main_sdram_dfi_p1_rddata_valid = main_sdram_slave_p1_rddata_valid;
+  assign main_sdram_slave_p2_address = main_sdram_dfi_p2_address;
+  assign main_sdram_slave_p2_bank = main_sdram_dfi_p2_bank;
+  assign main_sdram_slave_p2_cas_n = main_sdram_dfi_p2_cas_n;
+  assign main_sdram_slave_p2_cs_n = main_sdram_dfi_p2_cs_n;
+  assign main_sdram_slave_p2_ras_n = main_sdram_dfi_p2_ras_n;
+  assign main_sdram_slave_p2_we_n = main_sdram_dfi_p2_we_n;
+  assign main_sdram_slave_p2_cke = main_sdram_dfi_p2_cke;
+  assign main_sdram_slave_p2_odt = main_sdram_dfi_p2_odt;
+  assign main_sdram_slave_p2_reset_n = main_sdram_dfi_p2_reset_n;
+  assign main_sdram_slave_p2_act_n = main_sdram_dfi_p2_act_n;
+  assign main_sdram_slave_p2_wrdata = main_sdram_dfi_p2_wrdata;
+  assign main_sdram_slave_p2_wrdata_en = main_sdram_dfi_p2_wrdata_en;
+  assign main_sdram_slave_p2_wrdata_mask = main_sdram_dfi_p2_wrdata_mask;
+  assign main_sdram_slave_p2_rddata_en = main_sdram_dfi_p2_rddata_en;
+  assign main_sdram_dfi_p2_rddata = main_sdram_slave_p2_rddata;
+  assign main_sdram_dfi_p2_rddata_valid = main_sdram_slave_p2_rddata_valid;
+  assign main_sdram_slave_p3_address = main_sdram_dfi_p3_address;
+  assign main_sdram_slave_p3_bank = main_sdram_dfi_p3_bank;
+  assign main_sdram_slave_p3_cas_n = main_sdram_dfi_p3_cas_n;
+  assign main_sdram_slave_p3_cs_n = main_sdram_dfi_p3_cs_n;
+  assign main_sdram_slave_p3_ras_n = main_sdram_dfi_p3_ras_n;
+  assign main_sdram_slave_p3_we_n = main_sdram_dfi_p3_we_n;
+  assign main_sdram_slave_p3_cke = main_sdram_dfi_p3_cke;
+  assign main_sdram_slave_p3_odt = main_sdram_dfi_p3_odt;
+  assign main_sdram_slave_p3_reset_n = main_sdram_dfi_p3_reset_n;
+  assign main_sdram_slave_p3_act_n = main_sdram_dfi_p3_act_n;
+  assign main_sdram_slave_p3_wrdata = main_sdram_dfi_p3_wrdata;
+  assign main_sdram_slave_p3_wrdata_en = main_sdram_dfi_p3_wrdata_en;
+  assign main_sdram_slave_p3_wrdata_mask = main_sdram_dfi_p3_wrdata_mask;
+  assign main_sdram_slave_p3_rddata_en = main_sdram_dfi_p3_rddata_en;
+  assign main_sdram_dfi_p3_rddata = main_sdram_slave_p3_rddata;
+  assign main_sdram_dfi_p3_rddata_valid = main_sdram_slave_p3_rddata_valid;
+  always @(*) begin
+    main_sdram_slave_p1_rddata <= 32'd0;
+    main_sdram_slave_p1_rddata_valid <= 1'd0;
+    main_sdram_slave_p2_rddata <= 32'd0;
+    main_sdram_slave_p2_rddata_valid <= 1'd0;
+    main_sdram_slave_p3_rddata <= 32'd0;
+    main_sdram_slave_p3_rddata_valid <= 1'd0;
+    main_sdram_inti_p0_rddata <= 32'd0;
+    main_sdram_inti_p0_rddata_valid <= 1'd0;
+    main_sdram_master_p0_address <= 14'd0;
+    main_sdram_master_p0_bank <= 3'd0;
+    main_sdram_master_p0_cas_n <= 1'd1;
+    main_sdram_master_p0_cs_n <= 1'd1;
+    main_sdram_master_p0_ras_n <= 1'd1;
+    main_sdram_master_p0_we_n <= 1'd1;
+    main_sdram_master_p0_cke <= 1'd0;
+    main_sdram_master_p0_odt <= 1'd0;
+    main_sdram_master_p0_reset_n <= 1'd0;
+    main_sdram_master_p0_act_n <= 1'd1;
+    main_sdram_inti_p1_rddata <= 32'd0;
+    main_sdram_master_p0_wrdata <= 32'd0;
+    main_sdram_inti_p1_rddata_valid <= 1'd0;
+    main_sdram_master_p0_wrdata_en <= 1'd0;
+    main_sdram_master_p0_wrdata_mask <= 4'd0;
+    main_sdram_master_p0_rddata_en <= 1'd0;
+    main_sdram_master_p1_address <= 14'd0;
+    main_sdram_master_p1_bank <= 3'd0;
+    main_sdram_master_p1_cas_n <= 1'd1;
+    main_sdram_master_p1_cs_n <= 1'd1;
+    main_sdram_master_p1_ras_n <= 1'd1;
+    main_sdram_master_p1_we_n <= 1'd1;
+    main_sdram_master_p1_cke <= 1'd0;
+    main_sdram_master_p1_odt <= 1'd0;
+    main_sdram_master_p1_reset_n <= 1'd0;
+    main_sdram_master_p1_act_n <= 1'd1;
+    main_sdram_master_p1_wrdata <= 32'd0;
+    main_sdram_inti_p2_rddata <= 32'd0;
+    main_sdram_master_p1_wrdata_en <= 1'd0;
+    main_sdram_inti_p2_rddata_valid <= 1'd0;
+    main_sdram_master_p1_wrdata_mask <= 4'd0;
+    main_sdram_master_p1_rddata_en <= 1'd0;
+    main_sdram_master_p2_address <= 14'd0;
+    main_sdram_master_p2_bank <= 3'd0;
+    main_sdram_master_p2_cas_n <= 1'd1;
+    main_sdram_master_p2_cs_n <= 1'd1;
+    main_sdram_master_p2_ras_n <= 1'd1;
+    main_sdram_master_p2_we_n <= 1'd1;
+    main_sdram_master_p2_cke <= 1'd0;
+    main_sdram_master_p2_odt <= 1'd0;
+    main_sdram_master_p2_reset_n <= 1'd0;
+    main_sdram_master_p2_act_n <= 1'd1;
+    main_sdram_master_p2_wrdata <= 32'd0;
+    main_sdram_inti_p3_rddata <= 32'd0;
+    main_sdram_master_p2_wrdata_en <= 1'd0;
+    main_sdram_inti_p3_rddata_valid <= 1'd0;
+    main_sdram_master_p2_wrdata_mask <= 4'd0;
+    main_sdram_master_p2_rddata_en <= 1'd0;
+    main_sdram_master_p3_address <= 14'd0;
+    main_sdram_master_p3_bank <= 3'd0;
+    main_sdram_master_p3_cas_n <= 1'd1;
+    main_sdram_master_p3_cs_n <= 1'd1;
+    main_sdram_master_p3_ras_n <= 1'd1;
+    main_sdram_master_p3_we_n <= 1'd1;
+    main_sdram_master_p3_cke <= 1'd0;
+    main_sdram_master_p3_odt <= 1'd0;
+    main_sdram_master_p3_reset_n <= 1'd0;
+    main_sdram_master_p3_act_n <= 1'd1;
+    main_sdram_master_p3_wrdata <= 32'd0;
+    main_sdram_master_p3_wrdata_en <= 1'd0;
+    main_sdram_master_p3_wrdata_mask <= 4'd0;
+    main_sdram_master_p3_rddata_en <= 1'd0;
+    main_sdram_slave_p0_rddata <= 32'd0;
+    main_sdram_slave_p0_rddata_valid <= 1'd0;
+    if (main_sdram_storage[0]) begin
+      main_sdram_master_p0_address <= main_sdram_slave_p0_address;
+      main_sdram_master_p0_bank <= main_sdram_slave_p0_bank;
+      main_sdram_master_p0_cas_n <= main_sdram_slave_p0_cas_n;
+      main_sdram_master_p0_cs_n <= main_sdram_slave_p0_cs_n;
+      main_sdram_master_p0_ras_n <= main_sdram_slave_p0_ras_n;
+      main_sdram_master_p0_we_n <= main_sdram_slave_p0_we_n;
+      main_sdram_master_p0_cke <= main_sdram_slave_p0_cke;
+      main_sdram_master_p0_odt <= main_sdram_slave_p0_odt;
+      main_sdram_master_p0_reset_n <= main_sdram_slave_p0_reset_n;
+      main_sdram_master_p0_act_n <= main_sdram_slave_p0_act_n;
+      main_sdram_master_p0_wrdata <= main_sdram_slave_p0_wrdata;
+      main_sdram_master_p0_wrdata_en <= main_sdram_slave_p0_wrdata_en;
+      main_sdram_master_p0_wrdata_mask <= main_sdram_slave_p0_wrdata_mask;
+      main_sdram_master_p0_rddata_en <= main_sdram_slave_p0_rddata_en;
+      main_sdram_slave_p0_rddata <= main_sdram_master_p0_rddata;
+      main_sdram_slave_p0_rddata_valid <= main_sdram_master_p0_rddata_valid;
+      main_sdram_master_p1_address <= main_sdram_slave_p1_address;
+      main_sdram_master_p1_bank <= main_sdram_slave_p1_bank;
+      main_sdram_master_p1_cas_n <= main_sdram_slave_p1_cas_n;
+      main_sdram_master_p1_cs_n <= main_sdram_slave_p1_cs_n;
+      main_sdram_master_p1_ras_n <= main_sdram_slave_p1_ras_n;
+      main_sdram_master_p1_we_n <= main_sdram_slave_p1_we_n;
+      main_sdram_master_p1_cke <= main_sdram_slave_p1_cke;
+      main_sdram_master_p1_odt <= main_sdram_slave_p1_odt;
+      main_sdram_master_p1_reset_n <= main_sdram_slave_p1_reset_n;
+      main_sdram_master_p1_act_n <= main_sdram_slave_p1_act_n;
+      main_sdram_master_p1_wrdata <= main_sdram_slave_p1_wrdata;
+      main_sdram_master_p1_wrdata_en <= main_sdram_slave_p1_wrdata_en;
+      main_sdram_master_p1_wrdata_mask <= main_sdram_slave_p1_wrdata_mask;
+      main_sdram_master_p1_rddata_en <= main_sdram_slave_p1_rddata_en;
+      main_sdram_slave_p1_rddata <= main_sdram_master_p1_rddata;
+      main_sdram_slave_p1_rddata_valid <= main_sdram_master_p1_rddata_valid;
+      main_sdram_master_p2_address <= main_sdram_slave_p2_address;
+      main_sdram_master_p2_bank <= main_sdram_slave_p2_bank;
+      main_sdram_master_p2_cas_n <= main_sdram_slave_p2_cas_n;
+      main_sdram_master_p2_cs_n <= main_sdram_slave_p2_cs_n;
+      main_sdram_master_p2_ras_n <= main_sdram_slave_p2_ras_n;
+      main_sdram_master_p2_we_n <= main_sdram_slave_p2_we_n;
+      main_sdram_master_p2_cke <= main_sdram_slave_p2_cke;
+      main_sdram_master_p2_odt <= main_sdram_slave_p2_odt;
+      main_sdram_master_p2_reset_n <= main_sdram_slave_p2_reset_n;
+      main_sdram_master_p2_act_n <= main_sdram_slave_p2_act_n;
+      main_sdram_master_p2_wrdata <= main_sdram_slave_p2_wrdata;
+      main_sdram_master_p2_wrdata_en <= main_sdram_slave_p2_wrdata_en;
+      main_sdram_master_p2_wrdata_mask <= main_sdram_slave_p2_wrdata_mask;
+      main_sdram_master_p2_rddata_en <= main_sdram_slave_p2_rddata_en;
+      main_sdram_slave_p2_rddata <= main_sdram_master_p2_rddata;
+      main_sdram_slave_p2_rddata_valid <= main_sdram_master_p2_rddata_valid;
+      main_sdram_master_p3_address <= main_sdram_slave_p3_address;
+      main_sdram_master_p3_bank <= main_sdram_slave_p3_bank;
+      main_sdram_master_p3_cas_n <= main_sdram_slave_p3_cas_n;
+      main_sdram_master_p3_cs_n <= main_sdram_slave_p3_cs_n;
+      main_sdram_master_p3_ras_n <= main_sdram_slave_p3_ras_n;
+      main_sdram_master_p3_we_n <= main_sdram_slave_p3_we_n;
+      main_sdram_master_p3_cke <= main_sdram_slave_p3_cke;
+      main_sdram_master_p3_odt <= main_sdram_slave_p3_odt;
+      main_sdram_master_p3_reset_n <= main_sdram_slave_p3_reset_n;
+      main_sdram_master_p3_act_n <= main_sdram_slave_p3_act_n;
+      main_sdram_master_p3_wrdata <= main_sdram_slave_p3_wrdata;
+      main_sdram_master_p3_wrdata_en <= main_sdram_slave_p3_wrdata_en;
+      main_sdram_master_p3_wrdata_mask <= main_sdram_slave_p3_wrdata_mask;
+      main_sdram_master_p3_rddata_en <= main_sdram_slave_p3_rddata_en;
+      main_sdram_slave_p3_rddata <= main_sdram_master_p3_rddata;
+      main_sdram_slave_p3_rddata_valid <= main_sdram_master_p3_rddata_valid;
+    end else begin
+      main_sdram_master_p0_address <= main_sdram_inti_p0_address;
+      main_sdram_master_p0_bank <= main_sdram_inti_p0_bank;
+      main_sdram_master_p0_cas_n <= main_sdram_inti_p0_cas_n;
+      main_sdram_master_p0_cs_n <= main_sdram_inti_p0_cs_n;
+      main_sdram_master_p0_ras_n <= main_sdram_inti_p0_ras_n;
+      main_sdram_master_p0_we_n <= main_sdram_inti_p0_we_n;
+      main_sdram_master_p0_cke <= main_sdram_inti_p0_cke;
+      main_sdram_master_p0_odt <= main_sdram_inti_p0_odt;
+      main_sdram_master_p0_reset_n <= main_sdram_inti_p0_reset_n;
+      main_sdram_master_p0_act_n <= main_sdram_inti_p0_act_n;
+      main_sdram_master_p0_wrdata <= main_sdram_inti_p0_wrdata;
+      main_sdram_master_p0_wrdata_en <= main_sdram_inti_p0_wrdata_en;
+      main_sdram_master_p0_wrdata_mask <= main_sdram_inti_p0_wrdata_mask;
+      main_sdram_master_p0_rddata_en <= main_sdram_inti_p0_rddata_en;
+      main_sdram_inti_p0_rddata <= main_sdram_master_p0_rddata;
+      main_sdram_inti_p0_rddata_valid <= main_sdram_master_p0_rddata_valid;
+      main_sdram_master_p1_address <= main_sdram_inti_p1_address;
+      main_sdram_master_p1_bank <= main_sdram_inti_p1_bank;
+      main_sdram_master_p1_cas_n <= main_sdram_inti_p1_cas_n;
+      main_sdram_master_p1_cs_n <= main_sdram_inti_p1_cs_n;
+      main_sdram_master_p1_ras_n <= main_sdram_inti_p1_ras_n;
+      main_sdram_master_p1_we_n <= main_sdram_inti_p1_we_n;
+      main_sdram_master_p1_cke <= main_sdram_inti_p1_cke;
+      main_sdram_master_p1_odt <= main_sdram_inti_p1_odt;
+      main_sdram_master_p1_reset_n <= main_sdram_inti_p1_reset_n;
+      main_sdram_master_p1_act_n <= main_sdram_inti_p1_act_n;
+      main_sdram_master_p1_wrdata <= main_sdram_inti_p1_wrdata;
+      main_sdram_master_p1_wrdata_en <= main_sdram_inti_p1_wrdata_en;
+      main_sdram_master_p1_wrdata_mask <= main_sdram_inti_p1_wrdata_mask;
+      main_sdram_master_p1_rddata_en <= main_sdram_inti_p1_rddata_en;
+      main_sdram_inti_p1_rddata <= main_sdram_master_p1_rddata;
+      main_sdram_inti_p1_rddata_valid <= main_sdram_master_p1_rddata_valid;
+      main_sdram_master_p2_address <= main_sdram_inti_p2_address;
+      main_sdram_master_p2_bank <= main_sdram_inti_p2_bank;
+      main_sdram_master_p2_cas_n <= main_sdram_inti_p2_cas_n;
+      main_sdram_master_p2_cs_n <= main_sdram_inti_p2_cs_n;
+      main_sdram_master_p2_ras_n <= main_sdram_inti_p2_ras_n;
+      main_sdram_master_p2_we_n <= main_sdram_inti_p2_we_n;
+      main_sdram_master_p2_cke <= main_sdram_inti_p2_cke;
+      main_sdram_master_p2_odt <= main_sdram_inti_p2_odt;
+      main_sdram_master_p2_reset_n <= main_sdram_inti_p2_reset_n;
+      main_sdram_master_p2_act_n <= main_sdram_inti_p2_act_n;
+      main_sdram_master_p2_wrdata <= main_sdram_inti_p2_wrdata;
+      main_sdram_master_p2_wrdata_en <= main_sdram_inti_p2_wrdata_en;
+      main_sdram_master_p2_wrdata_mask <= main_sdram_inti_p2_wrdata_mask;
+      main_sdram_master_p2_rddata_en <= main_sdram_inti_p2_rddata_en;
+      main_sdram_inti_p2_rddata <= main_sdram_master_p2_rddata;
+      main_sdram_inti_p2_rddata_valid <= main_sdram_master_p2_rddata_valid;
+      main_sdram_master_p3_address <= main_sdram_inti_p3_address;
+      main_sdram_master_p3_bank <= main_sdram_inti_p3_bank;
+      main_sdram_master_p3_cas_n <= main_sdram_inti_p3_cas_n;
+      main_sdram_master_p3_cs_n <= main_sdram_inti_p3_cs_n;
+      main_sdram_master_p3_ras_n <= main_sdram_inti_p3_ras_n;
+      main_sdram_master_p3_we_n <= main_sdram_inti_p3_we_n;
+      main_sdram_master_p3_cke <= main_sdram_inti_p3_cke;
+      main_sdram_master_p3_odt <= main_sdram_inti_p3_odt;
+      main_sdram_master_p3_reset_n <= main_sdram_inti_p3_reset_n;
+      main_sdram_master_p3_act_n <= main_sdram_inti_p3_act_n;
+      main_sdram_master_p3_wrdata <= main_sdram_inti_p3_wrdata;
+      main_sdram_master_p3_wrdata_en <= main_sdram_inti_p3_wrdata_en;
+      main_sdram_master_p3_wrdata_mask <= main_sdram_inti_p3_wrdata_mask;
+      main_sdram_master_p3_rddata_en <= main_sdram_inti_p3_rddata_en;
+      main_sdram_inti_p3_rddata <= main_sdram_master_p3_rddata;
+      main_sdram_inti_p3_rddata_valid <= main_sdram_master_p3_rddata_valid;
+    end
+  end
+  assign main_sdram_inti_p0_cke = main_sdram_storage[1];
+  assign main_sdram_inti_p1_cke = main_sdram_storage[1];
+  assign main_sdram_inti_p2_cke = main_sdram_storage[1];
+  assign main_sdram_inti_p3_cke = main_sdram_storage[1];
+  assign main_sdram_inti_p0_odt = main_sdram_storage[2];
+  assign main_sdram_inti_p1_odt = main_sdram_storage[2];
+  assign main_sdram_inti_p2_odt = main_sdram_storage[2];
+  assign main_sdram_inti_p3_odt = main_sdram_storage[2];
+  assign main_sdram_inti_p0_reset_n = main_sdram_storage[3];
+  assign main_sdram_inti_p1_reset_n = main_sdram_storage[3];
+  assign main_sdram_inti_p2_reset_n = main_sdram_storage[3];
+  assign main_sdram_inti_p3_reset_n = main_sdram_storage[3];
+  always @(*) begin
+    main_sdram_inti_p0_we_n  <= 1'd1;
+    main_sdram_inti_p0_cas_n <= 1'd1;
+    main_sdram_inti_p0_cs_n  <= 1'd1;
+    main_sdram_inti_p0_ras_n <= 1'd1;
+    if (main_sdram_phaseinjector0_command_issue_re) begin
+      main_sdram_inti_p0_cs_n  <= {1{(~main_sdram_phaseinjector0_command_storage[0])}};
+      main_sdram_inti_p0_we_n  <= (~main_sdram_phaseinjector0_command_storage[1]);
+      main_sdram_inti_p0_cas_n <= (~main_sdram_phaseinjector0_command_storage[2]);
+      main_sdram_inti_p0_ras_n <= (~main_sdram_phaseinjector0_command_storage[3]);
+    end else begin
+      main_sdram_inti_p0_cs_n  <= {1{1'd1}};
+      main_sdram_inti_p0_we_n  <= 1'd1;
+      main_sdram_inti_p0_cas_n <= 1'd1;
+      main_sdram_inti_p0_ras_n <= 1'd1;
+    end
+  end
+  assign main_sdram_inti_p0_address = main_sdram_phaseinjector0_address_storage;
+  assign main_sdram_inti_p0_bank = main_sdram_phaseinjector0_baddress_storage;
+  assign main_sdram_inti_p0_wrdata_en = (main_sdram_phaseinjector0_command_issue_re & main_sdram_phaseinjector0_command_storage[4]);
+  assign main_sdram_inti_p0_rddata_en = (main_sdram_phaseinjector0_command_issue_re & main_sdram_phaseinjector0_command_storage[5]);
+  assign main_sdram_inti_p0_wrdata = main_sdram_phaseinjector0_wrdata_storage;
+  assign main_sdram_inti_p0_wrdata_mask = 1'd0;
+  always @(*) begin
+    main_sdram_inti_p1_we_n  <= 1'd1;
+    main_sdram_inti_p1_cas_n <= 1'd1;
+    main_sdram_inti_p1_cs_n  <= 1'd1;
+    main_sdram_inti_p1_ras_n <= 1'd1;
+    if (main_sdram_phaseinjector1_command_issue_re) begin
+      main_sdram_inti_p1_cs_n  <= {1{(~main_sdram_phaseinjector1_command_storage[0])}};
+      main_sdram_inti_p1_we_n  <= (~main_sdram_phaseinjector1_command_storage[1]);
+      main_sdram_inti_p1_cas_n <= (~main_sdram_phaseinjector1_command_storage[2]);
+      main_sdram_inti_p1_ras_n <= (~main_sdram_phaseinjector1_command_storage[3]);
+    end else begin
+      main_sdram_inti_p1_cs_n  <= {1{1'd1}};
+      main_sdram_inti_p1_we_n  <= 1'd1;
+      main_sdram_inti_p1_cas_n <= 1'd1;
+      main_sdram_inti_p1_ras_n <= 1'd1;
+    end
+  end
+  assign main_sdram_inti_p1_address = main_sdram_phaseinjector1_address_storage;
+  assign main_sdram_inti_p1_bank = main_sdram_phaseinjector1_baddress_storage;
+  assign main_sdram_inti_p1_wrdata_en = (main_sdram_phaseinjector1_command_issue_re & main_sdram_phaseinjector1_command_storage[4]);
+  assign main_sdram_inti_p1_rddata_en = (main_sdram_phaseinjector1_command_issue_re & main_sdram_phaseinjector1_command_storage[5]);
+  assign main_sdram_inti_p1_wrdata = main_sdram_phaseinjector1_wrdata_storage;
+  assign main_sdram_inti_p1_wrdata_mask = 1'd0;
+  always @(*) begin
+    main_sdram_inti_p2_we_n  <= 1'd1;
+    main_sdram_inti_p2_cas_n <= 1'd1;
+    main_sdram_inti_p2_cs_n  <= 1'd1;
+    main_sdram_inti_p2_ras_n <= 1'd1;
+    if (main_sdram_phaseinjector2_command_issue_re) begin
+      main_sdram_inti_p2_cs_n  <= {1{(~main_sdram_phaseinjector2_command_storage[0])}};
+      main_sdram_inti_p2_we_n  <= (~main_sdram_phaseinjector2_command_storage[1]);
+      main_sdram_inti_p2_cas_n <= (~main_sdram_phaseinjector2_command_storage[2]);
+      main_sdram_inti_p2_ras_n <= (~main_sdram_phaseinjector2_command_storage[3]);
+    end else begin
+      main_sdram_inti_p2_cs_n  <= {1{1'd1}};
+      main_sdram_inti_p2_we_n  <= 1'd1;
+      main_sdram_inti_p2_cas_n <= 1'd1;
+      main_sdram_inti_p2_ras_n <= 1'd1;
+    end
+  end
+  assign main_sdram_inti_p2_address = main_sdram_phaseinjector2_address_storage;
+  assign main_sdram_inti_p2_bank = main_sdram_phaseinjector2_baddress_storage;
+  assign main_sdram_inti_p2_wrdata_en = (main_sdram_phaseinjector2_command_issue_re & main_sdram_phaseinjector2_command_storage[4]);
+  assign main_sdram_inti_p2_rddata_en = (main_sdram_phaseinjector2_command_issue_re & main_sdram_phaseinjector2_command_storage[5]);
+  assign main_sdram_inti_p2_wrdata = main_sdram_phaseinjector2_wrdata_storage;
+  assign main_sdram_inti_p2_wrdata_mask = 1'd0;
+  always @(*) begin
+    main_sdram_inti_p3_we_n  <= 1'd1;
+    main_sdram_inti_p3_cas_n <= 1'd1;
+    main_sdram_inti_p3_cs_n  <= 1'd1;
+    main_sdram_inti_p3_ras_n <= 1'd1;
+    if (main_sdram_phaseinjector3_command_issue_re) begin
+      main_sdram_inti_p3_cs_n  <= {1{(~main_sdram_phaseinjector3_command_storage[0])}};
+      main_sdram_inti_p3_we_n  <= (~main_sdram_phaseinjector3_command_storage[1]);
+      main_sdram_inti_p3_cas_n <= (~main_sdram_phaseinjector3_command_storage[2]);
+      main_sdram_inti_p3_ras_n <= (~main_sdram_phaseinjector3_command_storage[3]);
+    end else begin
+      main_sdram_inti_p3_cs_n  <= {1{1'd1}};
+      main_sdram_inti_p3_we_n  <= 1'd1;
+      main_sdram_inti_p3_cas_n <= 1'd1;
+      main_sdram_inti_p3_ras_n <= 1'd1;
+    end
+  end
+  assign main_sdram_inti_p3_address = main_sdram_phaseinjector3_address_storage;
+  assign main_sdram_inti_p3_bank = main_sdram_phaseinjector3_baddress_storage;
+  assign main_sdram_inti_p3_wrdata_en = (main_sdram_phaseinjector3_command_issue_re & main_sdram_phaseinjector3_command_storage[4]);
+  assign main_sdram_inti_p3_rddata_en = (main_sdram_phaseinjector3_command_issue_re & main_sdram_phaseinjector3_command_storage[5]);
+  assign main_sdram_inti_p3_wrdata = main_sdram_phaseinjector3_wrdata_storage;
+  assign main_sdram_inti_p3_wrdata_mask = 1'd0;
+  assign main_sdram_bankmachine0_req_valid = main_sdram_interface_bank0_valid;
+  assign main_sdram_interface_bank0_ready = main_sdram_bankmachine0_req_ready;
+  assign main_sdram_bankmachine0_req_we = main_sdram_interface_bank0_we;
+  assign main_sdram_bankmachine0_req_addr = main_sdram_interface_bank0_addr;
+  assign main_sdram_interface_bank0_lock = main_sdram_bankmachine0_req_lock;
+  assign main_sdram_interface_bank0_wdata_ready = main_sdram_bankmachine0_req_wdata_ready;
+  assign main_sdram_interface_bank0_rdata_valid = main_sdram_bankmachine0_req_rdata_valid;
+  assign main_sdram_bankmachine1_req_valid = main_sdram_interface_bank1_valid;
+  assign main_sdram_interface_bank1_ready = main_sdram_bankmachine1_req_ready;
+  assign main_sdram_bankmachine1_req_we = main_sdram_interface_bank1_we;
+  assign main_sdram_bankmachine1_req_addr = main_sdram_interface_bank1_addr;
+  assign main_sdram_interface_bank1_lock = main_sdram_bankmachine1_req_lock;
+  assign main_sdram_interface_bank1_wdata_ready = main_sdram_bankmachine1_req_wdata_ready;
+  assign main_sdram_interface_bank1_rdata_valid = main_sdram_bankmachine1_req_rdata_valid;
+  assign main_sdram_bankmachine2_req_valid = main_sdram_interface_bank2_valid;
+  assign main_sdram_interface_bank2_ready = main_sdram_bankmachine2_req_ready;
+  assign main_sdram_bankmachine2_req_we = main_sdram_interface_bank2_we;
+  assign main_sdram_bankmachine2_req_addr = main_sdram_interface_bank2_addr;
+  assign main_sdram_interface_bank2_lock = main_sdram_bankmachine2_req_lock;
+  assign main_sdram_interface_bank2_wdata_ready = main_sdram_bankmachine2_req_wdata_ready;
+  assign main_sdram_interface_bank2_rdata_valid = main_sdram_bankmachine2_req_rdata_valid;
+  assign main_sdram_bankmachine3_req_valid = main_sdram_interface_bank3_valid;
+  assign main_sdram_interface_bank3_ready = main_sdram_bankmachine3_req_ready;
+  assign main_sdram_bankmachine3_req_we = main_sdram_interface_bank3_we;
+  assign main_sdram_bankmachine3_req_addr = main_sdram_interface_bank3_addr;
+  assign main_sdram_interface_bank3_lock = main_sdram_bankmachine3_req_lock;
+  assign main_sdram_interface_bank3_wdata_ready = main_sdram_bankmachine3_req_wdata_ready;
+  assign main_sdram_interface_bank3_rdata_valid = main_sdram_bankmachine3_req_rdata_valid;
+  assign main_sdram_bankmachine4_req_valid = main_sdram_interface_bank4_valid;
+  assign main_sdram_interface_bank4_ready = main_sdram_bankmachine4_req_ready;
+  assign main_sdram_bankmachine4_req_we = main_sdram_interface_bank4_we;
+  assign main_sdram_bankmachine4_req_addr = main_sdram_interface_bank4_addr;
+  assign main_sdram_interface_bank4_lock = main_sdram_bankmachine4_req_lock;
+  assign main_sdram_interface_bank4_wdata_ready = main_sdram_bankmachine4_req_wdata_ready;
+  assign main_sdram_interface_bank4_rdata_valid = main_sdram_bankmachine4_req_rdata_valid;
+  assign main_sdram_bankmachine5_req_valid = main_sdram_interface_bank5_valid;
+  assign main_sdram_interface_bank5_ready = main_sdram_bankmachine5_req_ready;
+  assign main_sdram_bankmachine5_req_we = main_sdram_interface_bank5_we;
+  assign main_sdram_bankmachine5_req_addr = main_sdram_interface_bank5_addr;
+  assign main_sdram_interface_bank5_lock = main_sdram_bankmachine5_req_lock;
+  assign main_sdram_interface_bank5_wdata_ready = main_sdram_bankmachine5_req_wdata_ready;
+  assign main_sdram_interface_bank5_rdata_valid = main_sdram_bankmachine5_req_rdata_valid;
+  assign main_sdram_bankmachine6_req_valid = main_sdram_interface_bank6_valid;
+  assign main_sdram_interface_bank6_ready = main_sdram_bankmachine6_req_ready;
+  assign main_sdram_bankmachine6_req_we = main_sdram_interface_bank6_we;
+  assign main_sdram_bankmachine6_req_addr = main_sdram_interface_bank6_addr;
+  assign main_sdram_interface_bank6_lock = main_sdram_bankmachine6_req_lock;
+  assign main_sdram_interface_bank6_wdata_ready = main_sdram_bankmachine6_req_wdata_ready;
+  assign main_sdram_interface_bank6_rdata_valid = main_sdram_bankmachine6_req_rdata_valid;
+  assign main_sdram_bankmachine7_req_valid = main_sdram_interface_bank7_valid;
+  assign main_sdram_interface_bank7_ready = main_sdram_bankmachine7_req_ready;
+  assign main_sdram_bankmachine7_req_we = main_sdram_interface_bank7_we;
+  assign main_sdram_bankmachine7_req_addr = main_sdram_interface_bank7_addr;
+  assign main_sdram_interface_bank7_lock = main_sdram_bankmachine7_req_lock;
+  assign main_sdram_interface_bank7_wdata_ready = main_sdram_bankmachine7_req_wdata_ready;
+  assign main_sdram_interface_bank7_rdata_valid = main_sdram_bankmachine7_req_rdata_valid;
+  assign main_sdram_timer_wait = (~main_sdram_timer_done0);
+  assign main_sdram_postponer_req_i = main_sdram_timer_done0;
+  assign main_sdram_wants_refresh = main_sdram_postponer_req_o;
+  assign main_sdram_wants_zqcs = main_sdram_zqcs_timer_done0;
+  assign main_sdram_zqcs_timer_wait = (~main_sdram_zqcs_executer_done);
+  assign main_sdram_timer_done1 = (main_sdram_timer_count1 == 1'd0);
+  assign main_sdram_timer_done0 = main_sdram_timer_done1;
+  assign main_sdram_timer_count0 = main_sdram_timer_count1;
+  assign main_sdram_sequencer_start1 = (main_sdram_sequencer_start0 | (main_sdram_sequencer_count != 1'd0));
+  assign main_sdram_sequencer_done0 = (main_sdram_sequencer_done1 & (main_sdram_sequencer_count == 1'd0));
+  assign main_sdram_zqcs_timer_done1 = (main_sdram_zqcs_timer_count1 == 1'd0);
+  assign main_sdram_zqcs_timer_done0 = main_sdram_zqcs_timer_done1;
+  assign main_sdram_zqcs_timer_count0 = main_sdram_zqcs_timer_count1;
+  always @(*) begin
+    main_sdram_cmd_valid <= 1'd0;
+    builder_refresher_next_state <= 2'd0;
+    main_sdram_zqcs_executer_start <= 1'd0;
+    main_sdram_cmd_last <= 1'd0;
+    main_sdram_sequencer_start0 <= 1'd0;
+    builder_refresher_next_state <= builder_refresher_state;
+    case (builder_refresher_state)
+      1'd1: begin
+        main_sdram_cmd_valid <= 1'd1;
+        if (main_sdram_cmd_ready) begin
+          main_sdram_sequencer_start0  <= 1'd1;
+          builder_refresher_next_state <= 2'd2;
+        end
+      end
+      2'd2: begin
+        main_sdram_cmd_valid <= 1'd1;
+        if (main_sdram_sequencer_done0) begin
+          if (main_sdram_wants_zqcs) begin
+            main_sdram_zqcs_executer_start <= 1'd1;
+            builder_refresher_next_state   <= 2'd3;
+          end else begin
+            main_sdram_cmd_valid <= 1'd0;
+            main_sdram_cmd_last <= 1'd1;
+            builder_refresher_next_state <= 1'd0;
+          end
+        end
+      end
+      2'd3: begin
+        main_sdram_cmd_valid <= 1'd1;
+        if (main_sdram_zqcs_executer_done) begin
+          main_sdram_cmd_valid <= 1'd0;
+          main_sdram_cmd_last <= 1'd1;
+          builder_refresher_next_state <= 1'd0;
+        end
+      end
+      default: begin
+        if (1'd1) begin
+          if (main_sdram_wants_refresh) begin
+            builder_refresher_next_state <= 1'd1;
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine0_req_valid;
+  assign main_sdram_bankmachine0_req_ready = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine0_req_we;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine0_req_addr;
+  assign main_sdram_bankmachine0_cmd_buffer_sink_valid = main_sdram_bankmachine0_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine0_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine0_cmd_buffer_sink_first = main_sdram_bankmachine0_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine0_cmd_buffer_sink_last = main_sdram_bankmachine0_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine0_cmd_buffer_sink_payload_we = main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine0_cmd_buffer_sink_payload_addr = main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine0_cmd_buffer_source_ready = (main_sdram_bankmachine0_req_wdata_ready | main_sdram_bankmachine0_req_rdata_valid);
+  assign main_sdram_bankmachine0_req_lock = (main_sdram_bankmachine0_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine0_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine0_row_hit = (main_sdram_bankmachine0_row == main_sdram_bankmachine0_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine0_cmd_payload_ba = 1'd0;
+  always @(*) begin
+    main_sdram_bankmachine0_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine0_row_col_n_addr_sel) begin
+      main_sdram_bankmachine0_cmd_payload_a <= main_sdram_bankmachine0_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine0_cmd_payload_a <= ((main_sdram_bankmachine0_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine0_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine0_twtpcon_valid = ((main_sdram_bankmachine0_cmd_valid & main_sdram_bankmachine0_cmd_ready) & main_sdram_bankmachine0_cmd_payload_is_write);
+  assign main_sdram_bankmachine0_trccon_valid = ((main_sdram_bankmachine0_cmd_valid & main_sdram_bankmachine0_cmd_ready) & main_sdram_bankmachine0_row_open);
+  assign main_sdram_bankmachine0_trascon_valid = ((main_sdram_bankmachine0_cmd_valid & main_sdram_bankmachine0_cmd_ready) & main_sdram_bankmachine0_row_open);
+  always @(*) begin
+    main_sdram_bankmachine0_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine0_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine0_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine0_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine0_auto_precharge <= (main_sdram_bankmachine0_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_din = {
+    main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_dout;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_we = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine0_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_readable;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_first = main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_last = main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine0_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_re = main_sdram_bankmachine0_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine0_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine0_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine0_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_din;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_we & (main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable | main_sdram_bankmachine0_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_readable & main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_re);
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine0_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_dout = main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable = (main_sdram_bankmachine0_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_readable = (main_sdram_bankmachine0_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine0_cmd_buffer_sink_ready = ((~main_sdram_bankmachine0_cmd_buffer_source_valid) | main_sdram_bankmachine0_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine0_row_open <= 1'd0;
+    main_sdram_bankmachine0_row_close <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine0_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine0_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine0_req_wdata_ready <= 1'd0;
+    builder_bankmachine0_next_state <= 3'd0;
+    main_sdram_bankmachine0_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine0_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine0_cmd_valid <= 1'd0;
+    builder_bankmachine0_next_state <= builder_bankmachine0_state;
+    case (builder_bankmachine0_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine0_twtpcon_ready & main_sdram_bankmachine0_trascon_ready)) begin
+          main_sdram_bankmachine0_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine0_cmd_ready) begin
+            builder_bankmachine0_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine0_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine0_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine0_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine0_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine0_twtpcon_ready & main_sdram_bankmachine0_trascon_ready)) begin
+          builder_bankmachine0_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine0_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine0_trccon_ready) begin
+          main_sdram_bankmachine0_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine0_row_open <= 1'd1;
+          main_sdram_bankmachine0_cmd_valid <= 1'd1;
+          main_sdram_bankmachine0_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine0_cmd_ready) begin
+            builder_bankmachine0_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine0_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine0_twtpcon_ready) begin
+          main_sdram_bankmachine0_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine0_row_close <= 1'd1;
+        main_sdram_bankmachine0_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine0_refresh_req)) begin
+          builder_bankmachine0_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine0_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine0_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine0_refresh_req) begin
+          builder_bankmachine0_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine0_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine0_row_opened) begin
+              if (main_sdram_bankmachine0_row_hit) begin
+                main_sdram_bankmachine0_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine0_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine0_req_wdata_ready <= main_sdram_bankmachine0_cmd_ready;
+                  main_sdram_bankmachine0_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine0_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine0_req_rdata_valid <= main_sdram_bankmachine0_cmd_ready;
+                  main_sdram_bankmachine0_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine0_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine0_cmd_ready & main_sdram_bankmachine0_auto_precharge)) begin
+                  builder_bankmachine0_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine0_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine0_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine1_req_valid;
+  assign main_sdram_bankmachine1_req_ready = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine1_req_we;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine1_req_addr;
+  assign main_sdram_bankmachine1_cmd_buffer_sink_valid = main_sdram_bankmachine1_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine1_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine1_cmd_buffer_sink_first = main_sdram_bankmachine1_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine1_cmd_buffer_sink_last = main_sdram_bankmachine1_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine1_cmd_buffer_sink_payload_we = main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine1_cmd_buffer_sink_payload_addr = main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine1_cmd_buffer_source_ready = (main_sdram_bankmachine1_req_wdata_ready | main_sdram_bankmachine1_req_rdata_valid);
+  assign main_sdram_bankmachine1_req_lock = (main_sdram_bankmachine1_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine1_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine1_row_hit = (main_sdram_bankmachine1_row == main_sdram_bankmachine1_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine1_cmd_payload_ba = 1'd1;
+  always @(*) begin
+    main_sdram_bankmachine1_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine1_row_col_n_addr_sel) begin
+      main_sdram_bankmachine1_cmd_payload_a <= main_sdram_bankmachine1_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine1_cmd_payload_a <= ((main_sdram_bankmachine1_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine1_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine1_twtpcon_valid = ((main_sdram_bankmachine1_cmd_valid & main_sdram_bankmachine1_cmd_ready) & main_sdram_bankmachine1_cmd_payload_is_write);
+  assign main_sdram_bankmachine1_trccon_valid = ((main_sdram_bankmachine1_cmd_valid & main_sdram_bankmachine1_cmd_ready) & main_sdram_bankmachine1_row_open);
+  assign main_sdram_bankmachine1_trascon_valid = ((main_sdram_bankmachine1_cmd_valid & main_sdram_bankmachine1_cmd_ready) & main_sdram_bankmachine1_row_open);
+  always @(*) begin
+    main_sdram_bankmachine1_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine1_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine1_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine1_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine1_auto_precharge <= (main_sdram_bankmachine1_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_din = {
+    main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_dout;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_we = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine1_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_readable;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_first = main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_last = main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine1_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_re = main_sdram_bankmachine1_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine1_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine1_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine1_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_din;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_we & (main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable | main_sdram_bankmachine1_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_readable & main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_re);
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine1_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_dout = main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable = (main_sdram_bankmachine1_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_readable = (main_sdram_bankmachine1_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine1_cmd_buffer_sink_ready = ((~main_sdram_bankmachine1_cmd_buffer_source_valid) | main_sdram_bankmachine1_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine1_row_open <= 1'd0;
+    main_sdram_bankmachine1_row_close <= 1'd0;
+    main_sdram_bankmachine1_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine1_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine1_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine1_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine1_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine1_cmd_payload_is_read <= 1'd0;
+    builder_bankmachine1_next_state <= 3'd0;
+    main_sdram_bankmachine1_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine1_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine1_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine1_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine1_cmd_valid <= 1'd0;
+    builder_bankmachine1_next_state <= builder_bankmachine1_state;
+    case (builder_bankmachine1_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine1_twtpcon_ready & main_sdram_bankmachine1_trascon_ready)) begin
+          main_sdram_bankmachine1_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine1_cmd_ready) begin
+            builder_bankmachine1_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine1_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine1_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine1_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine1_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine1_twtpcon_ready & main_sdram_bankmachine1_trascon_ready)) begin
+          builder_bankmachine1_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine1_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine1_trccon_ready) begin
+          main_sdram_bankmachine1_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine1_row_open <= 1'd1;
+          main_sdram_bankmachine1_cmd_valid <= 1'd1;
+          main_sdram_bankmachine1_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine1_cmd_ready) begin
+            builder_bankmachine1_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine1_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine1_twtpcon_ready) begin
+          main_sdram_bankmachine1_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine1_row_close <= 1'd1;
+        main_sdram_bankmachine1_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine1_refresh_req)) begin
+          builder_bankmachine1_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine1_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine1_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine1_refresh_req) begin
+          builder_bankmachine1_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine1_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine1_row_opened) begin
+              if (main_sdram_bankmachine1_row_hit) begin
+                main_sdram_bankmachine1_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine1_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine1_req_wdata_ready <= main_sdram_bankmachine1_cmd_ready;
+                  main_sdram_bankmachine1_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine1_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine1_req_rdata_valid <= main_sdram_bankmachine1_cmd_ready;
+                  main_sdram_bankmachine1_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine1_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine1_cmd_ready & main_sdram_bankmachine1_auto_precharge)) begin
+                  builder_bankmachine1_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine1_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine1_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine2_req_valid;
+  assign main_sdram_bankmachine2_req_ready = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine2_req_we;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine2_req_addr;
+  assign main_sdram_bankmachine2_cmd_buffer_sink_valid = main_sdram_bankmachine2_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine2_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine2_cmd_buffer_sink_first = main_sdram_bankmachine2_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine2_cmd_buffer_sink_last = main_sdram_bankmachine2_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine2_cmd_buffer_sink_payload_we = main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine2_cmd_buffer_sink_payload_addr = main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine2_cmd_buffer_source_ready = (main_sdram_bankmachine2_req_wdata_ready | main_sdram_bankmachine2_req_rdata_valid);
+  assign main_sdram_bankmachine2_req_lock = (main_sdram_bankmachine2_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine2_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine2_row_hit = (main_sdram_bankmachine2_row == main_sdram_bankmachine2_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine2_cmd_payload_ba = 2'd2;
+  always @(*) begin
+    main_sdram_bankmachine2_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine2_row_col_n_addr_sel) begin
+      main_sdram_bankmachine2_cmd_payload_a <= main_sdram_bankmachine2_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine2_cmd_payload_a <= ((main_sdram_bankmachine2_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine2_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine2_twtpcon_valid = ((main_sdram_bankmachine2_cmd_valid & main_sdram_bankmachine2_cmd_ready) & main_sdram_bankmachine2_cmd_payload_is_write);
+  assign main_sdram_bankmachine2_trccon_valid = ((main_sdram_bankmachine2_cmd_valid & main_sdram_bankmachine2_cmd_ready) & main_sdram_bankmachine2_row_open);
+  assign main_sdram_bankmachine2_trascon_valid = ((main_sdram_bankmachine2_cmd_valid & main_sdram_bankmachine2_cmd_ready) & main_sdram_bankmachine2_row_open);
+  always @(*) begin
+    main_sdram_bankmachine2_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine2_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine2_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine2_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine2_auto_precharge <= (main_sdram_bankmachine2_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_din = {
+    main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_dout;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_we = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine2_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_readable;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_first = main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_last = main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine2_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_re = main_sdram_bankmachine2_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine2_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine2_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine2_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_din;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_we & (main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable | main_sdram_bankmachine2_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_readable & main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_re);
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine2_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_dout = main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable = (main_sdram_bankmachine2_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_readable = (main_sdram_bankmachine2_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine2_cmd_buffer_sink_ready = ((~main_sdram_bankmachine2_cmd_buffer_source_valid) | main_sdram_bankmachine2_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine2_row_open <= 1'd0;
+    main_sdram_bankmachine2_row_close <= 1'd0;
+    main_sdram_bankmachine2_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine2_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine2_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine2_row_col_n_addr_sel <= 1'd0;
+    builder_bankmachine2_next_state <= 3'd0;
+    main_sdram_bankmachine2_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine2_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine2_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine2_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine2_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine2_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine2_cmd_valid <= 1'd0;
+    builder_bankmachine2_next_state <= builder_bankmachine2_state;
+    case (builder_bankmachine2_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine2_twtpcon_ready & main_sdram_bankmachine2_trascon_ready)) begin
+          main_sdram_bankmachine2_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine2_cmd_ready) begin
+            builder_bankmachine2_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine2_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine2_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine2_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine2_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine2_twtpcon_ready & main_sdram_bankmachine2_trascon_ready)) begin
+          builder_bankmachine2_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine2_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine2_trccon_ready) begin
+          main_sdram_bankmachine2_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine2_row_open <= 1'd1;
+          main_sdram_bankmachine2_cmd_valid <= 1'd1;
+          main_sdram_bankmachine2_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine2_cmd_ready) begin
+            builder_bankmachine2_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine2_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine2_twtpcon_ready) begin
+          main_sdram_bankmachine2_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine2_row_close <= 1'd1;
+        main_sdram_bankmachine2_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine2_refresh_req)) begin
+          builder_bankmachine2_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine2_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine2_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine2_refresh_req) begin
+          builder_bankmachine2_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine2_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine2_row_opened) begin
+              if (main_sdram_bankmachine2_row_hit) begin
+                main_sdram_bankmachine2_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine2_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine2_req_wdata_ready <= main_sdram_bankmachine2_cmd_ready;
+                  main_sdram_bankmachine2_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine2_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine2_req_rdata_valid <= main_sdram_bankmachine2_cmd_ready;
+                  main_sdram_bankmachine2_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine2_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine2_cmd_ready & main_sdram_bankmachine2_auto_precharge)) begin
+                  builder_bankmachine2_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine2_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine2_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine3_req_valid;
+  assign main_sdram_bankmachine3_req_ready = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine3_req_we;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine3_req_addr;
+  assign main_sdram_bankmachine3_cmd_buffer_sink_valid = main_sdram_bankmachine3_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine3_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine3_cmd_buffer_sink_first = main_sdram_bankmachine3_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine3_cmd_buffer_sink_last = main_sdram_bankmachine3_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine3_cmd_buffer_sink_payload_we = main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine3_cmd_buffer_sink_payload_addr = main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine3_cmd_buffer_source_ready = (main_sdram_bankmachine3_req_wdata_ready | main_sdram_bankmachine3_req_rdata_valid);
+  assign main_sdram_bankmachine3_req_lock = (main_sdram_bankmachine3_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine3_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine3_row_hit = (main_sdram_bankmachine3_row == main_sdram_bankmachine3_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine3_cmd_payload_ba = 2'd3;
+  always @(*) begin
+    main_sdram_bankmachine3_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine3_row_col_n_addr_sel) begin
+      main_sdram_bankmachine3_cmd_payload_a <= main_sdram_bankmachine3_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine3_cmd_payload_a <= ((main_sdram_bankmachine3_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine3_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine3_twtpcon_valid = ((main_sdram_bankmachine3_cmd_valid & main_sdram_bankmachine3_cmd_ready) & main_sdram_bankmachine3_cmd_payload_is_write);
+  assign main_sdram_bankmachine3_trccon_valid = ((main_sdram_bankmachine3_cmd_valid & main_sdram_bankmachine3_cmd_ready) & main_sdram_bankmachine3_row_open);
+  assign main_sdram_bankmachine3_trascon_valid = ((main_sdram_bankmachine3_cmd_valid & main_sdram_bankmachine3_cmd_ready) & main_sdram_bankmachine3_row_open);
+  always @(*) begin
+    main_sdram_bankmachine3_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine3_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine3_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine3_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine3_auto_precharge <= (main_sdram_bankmachine3_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_din = {
+    main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_dout;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_we = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine3_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_readable;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_first = main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_last = main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine3_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_re = main_sdram_bankmachine3_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine3_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine3_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine3_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_din;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_we & (main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable | main_sdram_bankmachine3_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_readable & main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_re);
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine3_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_dout = main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable = (main_sdram_bankmachine3_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_readable = (main_sdram_bankmachine3_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine3_cmd_buffer_sink_ready = ((~main_sdram_bankmachine3_cmd_buffer_source_valid) | main_sdram_bankmachine3_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine3_row_open <= 1'd0;
+    main_sdram_bankmachine3_row_close <= 1'd0;
+    main_sdram_bankmachine3_cmd_payload_cas <= 1'd0;
+    builder_bankmachine3_next_state <= 3'd0;
+    main_sdram_bankmachine3_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine3_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine3_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine3_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine3_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine3_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine3_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine3_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine3_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine3_cmd_valid <= 1'd0;
+    builder_bankmachine3_next_state <= builder_bankmachine3_state;
+    case (builder_bankmachine3_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine3_twtpcon_ready & main_sdram_bankmachine3_trascon_ready)) begin
+          main_sdram_bankmachine3_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine3_cmd_ready) begin
+            builder_bankmachine3_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine3_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine3_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine3_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine3_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine3_twtpcon_ready & main_sdram_bankmachine3_trascon_ready)) begin
+          builder_bankmachine3_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine3_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine3_trccon_ready) begin
+          main_sdram_bankmachine3_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine3_row_open <= 1'd1;
+          main_sdram_bankmachine3_cmd_valid <= 1'd1;
+          main_sdram_bankmachine3_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine3_cmd_ready) begin
+            builder_bankmachine3_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine3_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine3_twtpcon_ready) begin
+          main_sdram_bankmachine3_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine3_row_close <= 1'd1;
+        main_sdram_bankmachine3_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine3_refresh_req)) begin
+          builder_bankmachine3_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine3_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine3_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine3_refresh_req) begin
+          builder_bankmachine3_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine3_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine3_row_opened) begin
+              if (main_sdram_bankmachine3_row_hit) begin
+                main_sdram_bankmachine3_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine3_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine3_req_wdata_ready <= main_sdram_bankmachine3_cmd_ready;
+                  main_sdram_bankmachine3_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine3_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine3_req_rdata_valid <= main_sdram_bankmachine3_cmd_ready;
+                  main_sdram_bankmachine3_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine3_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine3_cmd_ready & main_sdram_bankmachine3_auto_precharge)) begin
+                  builder_bankmachine3_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine3_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine3_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine4_req_valid;
+  assign main_sdram_bankmachine4_req_ready = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine4_req_we;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine4_req_addr;
+  assign main_sdram_bankmachine4_cmd_buffer_sink_valid = main_sdram_bankmachine4_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine4_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine4_cmd_buffer_sink_first = main_sdram_bankmachine4_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine4_cmd_buffer_sink_last = main_sdram_bankmachine4_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine4_cmd_buffer_sink_payload_we = main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine4_cmd_buffer_sink_payload_addr = main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine4_cmd_buffer_source_ready = (main_sdram_bankmachine4_req_wdata_ready | main_sdram_bankmachine4_req_rdata_valid);
+  assign main_sdram_bankmachine4_req_lock = (main_sdram_bankmachine4_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine4_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine4_row_hit = (main_sdram_bankmachine4_row == main_sdram_bankmachine4_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine4_cmd_payload_ba = 3'd4;
+  always @(*) begin
+    main_sdram_bankmachine4_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine4_row_col_n_addr_sel) begin
+      main_sdram_bankmachine4_cmd_payload_a <= main_sdram_bankmachine4_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine4_cmd_payload_a <= ((main_sdram_bankmachine4_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine4_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine4_twtpcon_valid = ((main_sdram_bankmachine4_cmd_valid & main_sdram_bankmachine4_cmd_ready) & main_sdram_bankmachine4_cmd_payload_is_write);
+  assign main_sdram_bankmachine4_trccon_valid = ((main_sdram_bankmachine4_cmd_valid & main_sdram_bankmachine4_cmd_ready) & main_sdram_bankmachine4_row_open);
+  assign main_sdram_bankmachine4_trascon_valid = ((main_sdram_bankmachine4_cmd_valid & main_sdram_bankmachine4_cmd_ready) & main_sdram_bankmachine4_row_open);
+  always @(*) begin
+    main_sdram_bankmachine4_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine4_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine4_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine4_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine4_auto_precharge <= (main_sdram_bankmachine4_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_din = {
+    main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_dout;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_we = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine4_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_readable;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_first = main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_last = main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine4_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_re = main_sdram_bankmachine4_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine4_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine4_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine4_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_din;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_we & (main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable | main_sdram_bankmachine4_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_readable & main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_re);
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine4_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_dout = main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable = (main_sdram_bankmachine4_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_readable = (main_sdram_bankmachine4_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine4_cmd_buffer_sink_ready = ((~main_sdram_bankmachine4_cmd_buffer_source_valid) | main_sdram_bankmachine4_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine4_row_open <= 1'd0;
+    main_sdram_bankmachine4_row_close <= 1'd0;
+    builder_bankmachine4_next_state <= 3'd0;
+    main_sdram_bankmachine4_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine4_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine4_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine4_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine4_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine4_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine4_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine4_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine4_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine4_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine4_cmd_valid <= 1'd0;
+    builder_bankmachine4_next_state <= builder_bankmachine4_state;
+    case (builder_bankmachine4_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine4_twtpcon_ready & main_sdram_bankmachine4_trascon_ready)) begin
+          main_sdram_bankmachine4_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine4_cmd_ready) begin
+            builder_bankmachine4_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine4_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine4_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine4_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine4_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine4_twtpcon_ready & main_sdram_bankmachine4_trascon_ready)) begin
+          builder_bankmachine4_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine4_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine4_trccon_ready) begin
+          main_sdram_bankmachine4_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine4_row_open <= 1'd1;
+          main_sdram_bankmachine4_cmd_valid <= 1'd1;
+          main_sdram_bankmachine4_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine4_cmd_ready) begin
+            builder_bankmachine4_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine4_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine4_twtpcon_ready) begin
+          main_sdram_bankmachine4_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine4_row_close <= 1'd1;
+        main_sdram_bankmachine4_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine4_refresh_req)) begin
+          builder_bankmachine4_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine4_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine4_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine4_refresh_req) begin
+          builder_bankmachine4_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine4_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine4_row_opened) begin
+              if (main_sdram_bankmachine4_row_hit) begin
+                main_sdram_bankmachine4_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine4_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine4_req_wdata_ready <= main_sdram_bankmachine4_cmd_ready;
+                  main_sdram_bankmachine4_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine4_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine4_req_rdata_valid <= main_sdram_bankmachine4_cmd_ready;
+                  main_sdram_bankmachine4_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine4_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine4_cmd_ready & main_sdram_bankmachine4_auto_precharge)) begin
+                  builder_bankmachine4_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine4_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine4_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine5_req_valid;
+  assign main_sdram_bankmachine5_req_ready = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine5_req_we;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine5_req_addr;
+  assign main_sdram_bankmachine5_cmd_buffer_sink_valid = main_sdram_bankmachine5_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine5_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine5_cmd_buffer_sink_first = main_sdram_bankmachine5_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine5_cmd_buffer_sink_last = main_sdram_bankmachine5_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine5_cmd_buffer_sink_payload_we = main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine5_cmd_buffer_sink_payload_addr = main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine5_cmd_buffer_source_ready = (main_sdram_bankmachine5_req_wdata_ready | main_sdram_bankmachine5_req_rdata_valid);
+  assign main_sdram_bankmachine5_req_lock = (main_sdram_bankmachine5_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine5_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine5_row_hit = (main_sdram_bankmachine5_row == main_sdram_bankmachine5_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine5_cmd_payload_ba = 3'd5;
+  always @(*) begin
+    main_sdram_bankmachine5_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine5_row_col_n_addr_sel) begin
+      main_sdram_bankmachine5_cmd_payload_a <= main_sdram_bankmachine5_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine5_cmd_payload_a <= ((main_sdram_bankmachine5_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine5_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine5_twtpcon_valid = ((main_sdram_bankmachine5_cmd_valid & main_sdram_bankmachine5_cmd_ready) & main_sdram_bankmachine5_cmd_payload_is_write);
+  assign main_sdram_bankmachine5_trccon_valid = ((main_sdram_bankmachine5_cmd_valid & main_sdram_bankmachine5_cmd_ready) & main_sdram_bankmachine5_row_open);
+  assign main_sdram_bankmachine5_trascon_valid = ((main_sdram_bankmachine5_cmd_valid & main_sdram_bankmachine5_cmd_ready) & main_sdram_bankmachine5_row_open);
+  always @(*) begin
+    main_sdram_bankmachine5_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine5_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine5_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine5_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine5_auto_precharge <= (main_sdram_bankmachine5_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_din = {
+    main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_dout;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_we = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine5_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_readable;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_first = main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_last = main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine5_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_re = main_sdram_bankmachine5_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine5_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine5_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine5_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_din;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_we & (main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable | main_sdram_bankmachine5_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_readable & main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_re);
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine5_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_dout = main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable = (main_sdram_bankmachine5_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_readable = (main_sdram_bankmachine5_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine5_cmd_buffer_sink_ready = ((~main_sdram_bankmachine5_cmd_buffer_source_valid) | main_sdram_bankmachine5_cmd_buffer_source_ready);
+  always @(*) begin
+    builder_bankmachine5_next_state <= 3'd0;
+    main_sdram_bankmachine5_row_open <= 1'd0;
+    main_sdram_bankmachine5_row_close <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine5_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine5_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine5_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine5_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine5_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine5_cmd_valid <= 1'd0;
+    builder_bankmachine5_next_state <= builder_bankmachine5_state;
+    case (builder_bankmachine5_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine5_twtpcon_ready & main_sdram_bankmachine5_trascon_ready)) begin
+          main_sdram_bankmachine5_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine5_cmd_ready) begin
+            builder_bankmachine5_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine5_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine5_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine5_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine5_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine5_twtpcon_ready & main_sdram_bankmachine5_trascon_ready)) begin
+          builder_bankmachine5_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine5_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine5_trccon_ready) begin
+          main_sdram_bankmachine5_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine5_row_open <= 1'd1;
+          main_sdram_bankmachine5_cmd_valid <= 1'd1;
+          main_sdram_bankmachine5_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine5_cmd_ready) begin
+            builder_bankmachine5_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine5_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine5_twtpcon_ready) begin
+          main_sdram_bankmachine5_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine5_row_close <= 1'd1;
+        main_sdram_bankmachine5_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine5_refresh_req)) begin
+          builder_bankmachine5_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine5_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine5_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine5_refresh_req) begin
+          builder_bankmachine5_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine5_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine5_row_opened) begin
+              if (main_sdram_bankmachine5_row_hit) begin
+                main_sdram_bankmachine5_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine5_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine5_req_wdata_ready <= main_sdram_bankmachine5_cmd_ready;
+                  main_sdram_bankmachine5_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine5_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine5_req_rdata_valid <= main_sdram_bankmachine5_cmd_ready;
+                  main_sdram_bankmachine5_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine5_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine5_cmd_ready & main_sdram_bankmachine5_auto_precharge)) begin
+                  builder_bankmachine5_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine5_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine5_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine6_req_valid;
+  assign main_sdram_bankmachine6_req_ready = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine6_req_we;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine6_req_addr;
+  assign main_sdram_bankmachine6_cmd_buffer_sink_valid = main_sdram_bankmachine6_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine6_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine6_cmd_buffer_sink_first = main_sdram_bankmachine6_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine6_cmd_buffer_sink_last = main_sdram_bankmachine6_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine6_cmd_buffer_sink_payload_we = main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine6_cmd_buffer_sink_payload_addr = main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine6_cmd_buffer_source_ready = (main_sdram_bankmachine6_req_wdata_ready | main_sdram_bankmachine6_req_rdata_valid);
+  assign main_sdram_bankmachine6_req_lock = (main_sdram_bankmachine6_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine6_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine6_row_hit = (main_sdram_bankmachine6_row == main_sdram_bankmachine6_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine6_cmd_payload_ba = 3'd6;
+  always @(*) begin
+    main_sdram_bankmachine6_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine6_row_col_n_addr_sel) begin
+      main_sdram_bankmachine6_cmd_payload_a <= main_sdram_bankmachine6_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine6_cmd_payload_a <= ((main_sdram_bankmachine6_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine6_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine6_twtpcon_valid = ((main_sdram_bankmachine6_cmd_valid & main_sdram_bankmachine6_cmd_ready) & main_sdram_bankmachine6_cmd_payload_is_write);
+  assign main_sdram_bankmachine6_trccon_valid = ((main_sdram_bankmachine6_cmd_valid & main_sdram_bankmachine6_cmd_ready) & main_sdram_bankmachine6_row_open);
+  assign main_sdram_bankmachine6_trascon_valid = ((main_sdram_bankmachine6_cmd_valid & main_sdram_bankmachine6_cmd_ready) & main_sdram_bankmachine6_row_open);
+  always @(*) begin
+    main_sdram_bankmachine6_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine6_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine6_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine6_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine6_auto_precharge <= (main_sdram_bankmachine6_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_din = {
+    main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_dout;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_we = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine6_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_readable;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_first = main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_last = main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine6_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_re = main_sdram_bankmachine6_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine6_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine6_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine6_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_din;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_we & (main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable | main_sdram_bankmachine6_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_readable & main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_re);
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine6_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_dout = main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable = (main_sdram_bankmachine6_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_readable = (main_sdram_bankmachine6_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine6_cmd_buffer_sink_ready = ((~main_sdram_bankmachine6_cmd_buffer_source_valid) | main_sdram_bankmachine6_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine6_row_open <= 1'd0;
+    main_sdram_bankmachine6_row_close <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine6_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine6_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine6_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine6_req_rdata_valid <= 1'd0;
+    main_sdram_bankmachine6_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine6_cmd_valid <= 1'd0;
+    builder_bankmachine6_next_state <= 3'd0;
+    builder_bankmachine6_next_state <= builder_bankmachine6_state;
+    case (builder_bankmachine6_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine6_twtpcon_ready & main_sdram_bankmachine6_trascon_ready)) begin
+          main_sdram_bankmachine6_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine6_cmd_ready) begin
+            builder_bankmachine6_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine6_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine6_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine6_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine6_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine6_twtpcon_ready & main_sdram_bankmachine6_trascon_ready)) begin
+          builder_bankmachine6_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine6_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine6_trccon_ready) begin
+          main_sdram_bankmachine6_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine6_row_open <= 1'd1;
+          main_sdram_bankmachine6_cmd_valid <= 1'd1;
+          main_sdram_bankmachine6_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine6_cmd_ready) begin
+            builder_bankmachine6_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine6_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine6_twtpcon_ready) begin
+          main_sdram_bankmachine6_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine6_row_close <= 1'd1;
+        main_sdram_bankmachine6_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine6_refresh_req)) begin
+          builder_bankmachine6_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine6_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine6_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine6_refresh_req) begin
+          builder_bankmachine6_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine6_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine6_row_opened) begin
+              if (main_sdram_bankmachine6_row_hit) begin
+                main_sdram_bankmachine6_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine6_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine6_req_wdata_ready <= main_sdram_bankmachine6_cmd_ready;
+                  main_sdram_bankmachine6_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine6_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine6_req_rdata_valid <= main_sdram_bankmachine6_cmd_ready;
+                  main_sdram_bankmachine6_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine6_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine6_cmd_ready & main_sdram_bankmachine6_auto_precharge)) begin
+                  builder_bankmachine6_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine6_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine6_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_sink_valid = main_sdram_bankmachine7_req_valid;
+  assign main_sdram_bankmachine7_req_ready = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_ready;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_we = main_sdram_bankmachine7_req_we;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_addr = main_sdram_bankmachine7_req_addr;
+  assign main_sdram_bankmachine7_cmd_buffer_sink_valid = main_sdram_bankmachine7_cmd_buffer_lookahead_source_valid;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_ready = main_sdram_bankmachine7_cmd_buffer_sink_ready;
+  assign main_sdram_bankmachine7_cmd_buffer_sink_first = main_sdram_bankmachine7_cmd_buffer_lookahead_source_first;
+  assign main_sdram_bankmachine7_cmd_buffer_sink_last = main_sdram_bankmachine7_cmd_buffer_lookahead_source_last;
+  assign main_sdram_bankmachine7_cmd_buffer_sink_payload_we = main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_we;
+  assign main_sdram_bankmachine7_cmd_buffer_sink_payload_addr = main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_addr;
+  assign main_sdram_bankmachine7_cmd_buffer_source_ready = (main_sdram_bankmachine7_req_wdata_ready | main_sdram_bankmachine7_req_rdata_valid);
+  assign main_sdram_bankmachine7_req_lock = (main_sdram_bankmachine7_cmd_buffer_lookahead_source_valid | main_sdram_bankmachine7_cmd_buffer_source_valid);
+  assign main_sdram_bankmachine7_row_hit = (main_sdram_bankmachine7_row == main_sdram_bankmachine7_cmd_buffer_source_payload_addr[20:7]);
+  assign main_sdram_bankmachine7_cmd_payload_ba = 3'd7;
+  always @(*) begin
+    main_sdram_bankmachine7_cmd_payload_a <= 14'd0;
+    if (main_sdram_bankmachine7_row_col_n_addr_sel) begin
+      main_sdram_bankmachine7_cmd_payload_a <= main_sdram_bankmachine7_cmd_buffer_source_payload_addr[20:7];
+    end else begin
+      main_sdram_bankmachine7_cmd_payload_a <= ((main_sdram_bankmachine7_auto_precharge <<< 4'd10) | {
+        main_sdram_bankmachine7_cmd_buffer_source_payload_addr[6:0], {3{1'd0}}
+      });
+    end
+  end
+  assign main_sdram_bankmachine7_twtpcon_valid = ((main_sdram_bankmachine7_cmd_valid & main_sdram_bankmachine7_cmd_ready) & main_sdram_bankmachine7_cmd_payload_is_write);
+  assign main_sdram_bankmachine7_trccon_valid = ((main_sdram_bankmachine7_cmd_valid & main_sdram_bankmachine7_cmd_ready) & main_sdram_bankmachine7_row_open);
+  assign main_sdram_bankmachine7_trascon_valid = ((main_sdram_bankmachine7_cmd_valid & main_sdram_bankmachine7_cmd_ready) & main_sdram_bankmachine7_row_open);
+  always @(*) begin
+    main_sdram_bankmachine7_auto_precharge <= 1'd0;
+    if ((main_sdram_bankmachine7_cmd_buffer_lookahead_source_valid & main_sdram_bankmachine7_cmd_buffer_source_valid)) begin
+      if ((main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_addr[20:7] != main_sdram_bankmachine7_cmd_buffer_source_payload_addr[20:7])) begin
+        main_sdram_bankmachine7_auto_precharge <= (main_sdram_bankmachine7_row_close == 1'd0);
+      end
+    end
+  end
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_din = {
+    main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_last,
+    main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_first,
+    main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_addr,
+    main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_we
+  };
+  assign {main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_last, main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_first, main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_addr, main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_we} = main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_dout;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_sink_ready = main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_we = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_valid;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_first = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_first;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_last = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_last;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_we = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_we;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_in_payload_addr = main_sdram_bankmachine7_cmd_buffer_lookahead_sink_payload_addr;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_valid = main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_readable;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_first = main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_first;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_last = main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_last;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_we = main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_we;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_source_payload_addr = main_sdram_bankmachine7_cmd_buffer_lookahead_fifo_out_payload_addr;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_re = main_sdram_bankmachine7_cmd_buffer_lookahead_source_ready;
+  always @(*) begin
+    main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr <= 3'd0;
+    if (main_sdram_bankmachine7_cmd_buffer_lookahead_replace) begin
+      main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr <= (main_sdram_bankmachine7_cmd_buffer_lookahead_produce - 1'd1);
+    end else begin
+      main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr <= main_sdram_bankmachine7_cmd_buffer_lookahead_produce;
+    end
+  end
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_dat_w = main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_din;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_we = (main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_we & (main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable | main_sdram_bankmachine7_cmd_buffer_lookahead_replace));
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_do_read = (main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_readable & main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_re);
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_adr = main_sdram_bankmachine7_cmd_buffer_lookahead_consume;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_dout = main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_dat_r;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable = (main_sdram_bankmachine7_cmd_buffer_lookahead_level != 4'd8);
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_readable = (main_sdram_bankmachine7_cmd_buffer_lookahead_level != 1'd0);
+  assign main_sdram_bankmachine7_cmd_buffer_sink_ready = ((~main_sdram_bankmachine7_cmd_buffer_source_valid) | main_sdram_bankmachine7_cmd_buffer_source_ready);
+  always @(*) begin
+    main_sdram_bankmachine7_row_open <= 1'd0;
+    main_sdram_bankmachine7_row_close <= 1'd0;
+    main_sdram_bankmachine7_refresh_gnt <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_cas <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_ras <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_we <= 1'd0;
+    main_sdram_bankmachine7_row_col_n_addr_sel <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_is_cmd <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_is_read <= 1'd0;
+    main_sdram_bankmachine7_cmd_payload_is_write <= 1'd0;
+    main_sdram_bankmachine7_req_wdata_ready <= 1'd0;
+    main_sdram_bankmachine7_req_rdata_valid <= 1'd0;
+    builder_bankmachine7_next_state <= 3'd0;
+    main_sdram_bankmachine7_cmd_valid <= 1'd0;
+    builder_bankmachine7_next_state <= builder_bankmachine7_state;
+    case (builder_bankmachine7_state)
+      1'd1: begin
+        if ((main_sdram_bankmachine7_twtpcon_ready & main_sdram_bankmachine7_trascon_ready)) begin
+          main_sdram_bankmachine7_cmd_valid <= 1'd1;
+          if (main_sdram_bankmachine7_cmd_ready) begin
+            builder_bankmachine7_next_state <= 3'd5;
+          end
+          main_sdram_bankmachine7_cmd_payload_ras <= 1'd1;
+          main_sdram_bankmachine7_cmd_payload_we <= 1'd1;
+          main_sdram_bankmachine7_cmd_payload_is_cmd <= 1'd1;
+        end
+        main_sdram_bankmachine7_row_close <= 1'd1;
+      end
+      2'd2: begin
+        if ((main_sdram_bankmachine7_twtpcon_ready & main_sdram_bankmachine7_trascon_ready)) begin
+          builder_bankmachine7_next_state <= 3'd5;
+        end
+        main_sdram_bankmachine7_row_close <= 1'd1;
+      end
+      2'd3: begin
+        if (main_sdram_bankmachine7_trccon_ready) begin
+          main_sdram_bankmachine7_row_col_n_addr_sel <= 1'd1;
+          main_sdram_bankmachine7_row_open <= 1'd1;
+          main_sdram_bankmachine7_cmd_valid <= 1'd1;
+          main_sdram_bankmachine7_cmd_payload_is_cmd <= 1'd1;
+          if (main_sdram_bankmachine7_cmd_ready) begin
+            builder_bankmachine7_next_state <= 3'd6;
+          end
+          main_sdram_bankmachine7_cmd_payload_ras <= 1'd1;
+        end
+      end
+      3'd4: begin
+        if (main_sdram_bankmachine7_twtpcon_ready) begin
+          main_sdram_bankmachine7_refresh_gnt <= 1'd1;
+        end
+        main_sdram_bankmachine7_row_close <= 1'd1;
+        main_sdram_bankmachine7_cmd_payload_is_cmd <= 1'd1;
+        if ((~main_sdram_bankmachine7_refresh_req)) begin
+          builder_bankmachine7_next_state <= 1'd0;
+        end
+      end
+      3'd5: begin
+        builder_bankmachine7_next_state <= 2'd3;
+      end
+      3'd6: begin
+        builder_bankmachine7_next_state <= 1'd0;
+      end
+      default: begin
+        if (main_sdram_bankmachine7_refresh_req) begin
+          builder_bankmachine7_next_state <= 3'd4;
+        end else begin
+          if (main_sdram_bankmachine7_cmd_buffer_source_valid) begin
+            if (main_sdram_bankmachine7_row_opened) begin
+              if (main_sdram_bankmachine7_row_hit) begin
+                main_sdram_bankmachine7_cmd_valid <= 1'd1;
+                if (main_sdram_bankmachine7_cmd_buffer_source_payload_we) begin
+                  main_sdram_bankmachine7_req_wdata_ready <= main_sdram_bankmachine7_cmd_ready;
+                  main_sdram_bankmachine7_cmd_payload_is_write <= 1'd1;
+                  main_sdram_bankmachine7_cmd_payload_we <= 1'd1;
+                end else begin
+                  main_sdram_bankmachine7_req_rdata_valid <= main_sdram_bankmachine7_cmd_ready;
+                  main_sdram_bankmachine7_cmd_payload_is_read <= 1'd1;
+                end
+                main_sdram_bankmachine7_cmd_payload_cas <= 1'd1;
+                if ((main_sdram_bankmachine7_cmd_ready & main_sdram_bankmachine7_auto_precharge)) begin
+                  builder_bankmachine7_next_state <= 2'd2;
+                end
+              end else begin
+                builder_bankmachine7_next_state <= 1'd1;
+              end
+            end else begin
+              builder_bankmachine7_next_state <= 2'd3;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_sdram_trrdcon_valid = ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & ((main_sdram_choose_cmd_cmd_payload_ras & (~main_sdram_choose_cmd_cmd_payload_cas)) & (~main_sdram_choose_cmd_cmd_payload_we)));
+  assign main_sdram_tfawcon_valid = ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & ((main_sdram_choose_cmd_cmd_payload_ras & (~main_sdram_choose_cmd_cmd_payload_cas)) & (~main_sdram_choose_cmd_cmd_payload_we)));
+  assign main_sdram_ras_allowed = (main_sdram_trrdcon_ready & main_sdram_tfawcon_ready);
+  assign main_sdram_tccdcon_valid = ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_cmd_payload_is_write | main_sdram_choose_req_cmd_payload_is_read));
+  assign main_sdram_cas_allowed = main_sdram_tccdcon_ready;
+  assign main_sdram_twtrcon_valid = ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_write);
+  assign main_sdram_read_available = ((((((((main_sdram_bankmachine0_cmd_valid & main_sdram_bankmachine0_cmd_payload_is_read) | (main_sdram_bankmachine1_cmd_valid & main_sdram_bankmachine1_cmd_payload_is_read)) | (main_sdram_bankmachine2_cmd_valid & main_sdram_bankmachine2_cmd_payload_is_read)) | (main_sdram_bankmachine3_cmd_valid & main_sdram_bankmachine3_cmd_payload_is_read)) | (main_sdram_bankmachine4_cmd_valid & main_sdram_bankmachine4_cmd_payload_is_read)) | (main_sdram_bankmachine5_cmd_valid & main_sdram_bankmachine5_cmd_payload_is_read)) | (main_sdram_bankmachine6_cmd_valid & main_sdram_bankmachine6_cmd_payload_is_read)) | (main_sdram_bankmachine7_cmd_valid & main_sdram_bankmachine7_cmd_payload_is_read));
+  assign main_sdram_write_available = ((((((((main_sdram_bankmachine0_cmd_valid & main_sdram_bankmachine0_cmd_payload_is_write) | (main_sdram_bankmachine1_cmd_valid & main_sdram_bankmachine1_cmd_payload_is_write)) | (main_sdram_bankmachine2_cmd_valid & main_sdram_bankmachine2_cmd_payload_is_write)) | (main_sdram_bankmachine3_cmd_valid & main_sdram_bankmachine3_cmd_payload_is_write)) | (main_sdram_bankmachine4_cmd_valid & main_sdram_bankmachine4_cmd_payload_is_write)) | (main_sdram_bankmachine5_cmd_valid & main_sdram_bankmachine5_cmd_payload_is_write)) | (main_sdram_bankmachine6_cmd_valid & main_sdram_bankmachine6_cmd_payload_is_write)) | (main_sdram_bankmachine7_cmd_valid & main_sdram_bankmachine7_cmd_payload_is_write));
+  assign main_sdram_max_time0 = (main_sdram_time0 == 1'd0);
+  assign main_sdram_max_time1 = (main_sdram_time1 == 1'd0);
+  assign main_sdram_bankmachine0_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine1_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine2_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine3_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine4_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine5_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine6_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_bankmachine7_refresh_req = main_sdram_cmd_valid;
+  assign main_sdram_go_to_refresh = (((((((main_sdram_bankmachine0_refresh_gnt & main_sdram_bankmachine1_refresh_gnt) & main_sdram_bankmachine2_refresh_gnt) & main_sdram_bankmachine3_refresh_gnt) & main_sdram_bankmachine4_refresh_gnt) & main_sdram_bankmachine5_refresh_gnt) & main_sdram_bankmachine6_refresh_gnt) & main_sdram_bankmachine7_refresh_gnt);
+  assign main_sdram_interface_rdata = {
+    main_sdram_dfi_p3_rddata,
+    main_sdram_dfi_p2_rddata,
+    main_sdram_dfi_p1_rddata,
+    main_sdram_dfi_p0_rddata
+  };
+  assign {main_sdram_dfi_p3_wrdata, main_sdram_dfi_p2_wrdata, main_sdram_dfi_p1_wrdata, main_sdram_dfi_p0_wrdata} = main_sdram_interface_wdata;
+  assign {main_sdram_dfi_p3_wrdata_mask, main_sdram_dfi_p2_wrdata_mask, main_sdram_dfi_p1_wrdata_mask, main_sdram_dfi_p0_wrdata_mask} = (~main_sdram_interface_wdata_we);
+  always @(*) begin
+    main_sdram_choose_cmd_valids <= 8'd0;
+    main_sdram_choose_cmd_valids[0] <= (main_sdram_bankmachine0_cmd_valid & (((main_sdram_bankmachine0_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine0_cmd_payload_ras & (~main_sdram_bankmachine0_cmd_payload_cas)) & (~main_sdram_bankmachine0_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine0_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine0_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[1] <= (main_sdram_bankmachine1_cmd_valid & (((main_sdram_bankmachine1_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine1_cmd_payload_ras & (~main_sdram_bankmachine1_cmd_payload_cas)) & (~main_sdram_bankmachine1_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine1_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine1_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[2] <= (main_sdram_bankmachine2_cmd_valid & (((main_sdram_bankmachine2_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine2_cmd_payload_ras & (~main_sdram_bankmachine2_cmd_payload_cas)) & (~main_sdram_bankmachine2_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine2_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine2_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[3] <= (main_sdram_bankmachine3_cmd_valid & (((main_sdram_bankmachine3_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine3_cmd_payload_ras & (~main_sdram_bankmachine3_cmd_payload_cas)) & (~main_sdram_bankmachine3_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine3_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine3_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[4] <= (main_sdram_bankmachine4_cmd_valid & (((main_sdram_bankmachine4_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine4_cmd_payload_ras & (~main_sdram_bankmachine4_cmd_payload_cas)) & (~main_sdram_bankmachine4_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine4_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine4_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[5] <= (main_sdram_bankmachine5_cmd_valid & (((main_sdram_bankmachine5_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine5_cmd_payload_ras & (~main_sdram_bankmachine5_cmd_payload_cas)) & (~main_sdram_bankmachine5_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine5_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine5_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[6] <= (main_sdram_bankmachine6_cmd_valid & (((main_sdram_bankmachine6_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine6_cmd_payload_ras & (~main_sdram_bankmachine6_cmd_payload_cas)) & (~main_sdram_bankmachine6_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine6_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine6_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+    main_sdram_choose_cmd_valids[7] <= (main_sdram_bankmachine7_cmd_valid & (((main_sdram_bankmachine7_cmd_payload_is_cmd & main_sdram_choose_cmd_want_cmds) & ((~((main_sdram_bankmachine7_cmd_payload_ras & (~main_sdram_bankmachine7_cmd_payload_cas)) & (~main_sdram_bankmachine7_cmd_payload_we))) | main_sdram_choose_cmd_want_activates)) | ((main_sdram_bankmachine7_cmd_payload_is_read == main_sdram_choose_cmd_want_reads) & (main_sdram_bankmachine7_cmd_payload_is_write == main_sdram_choose_cmd_want_writes))));
+  end
+  assign main_sdram_choose_cmd_request = main_sdram_choose_cmd_valids;
+  assign main_sdram_choose_cmd_cmd_valid = builder_rhs_array_muxed0;
+  assign main_sdram_choose_cmd_cmd_payload_a = builder_rhs_array_muxed1;
+  assign main_sdram_choose_cmd_cmd_payload_ba = builder_rhs_array_muxed2;
+  assign main_sdram_choose_cmd_cmd_payload_is_read = builder_rhs_array_muxed3;
+  assign main_sdram_choose_cmd_cmd_payload_is_write = builder_rhs_array_muxed4;
+  assign main_sdram_choose_cmd_cmd_payload_is_cmd = builder_rhs_array_muxed5;
+  always @(*) begin
+    main_sdram_choose_cmd_cmd_payload_cas <= 1'd0;
+    if (main_sdram_choose_cmd_cmd_valid) begin
+      main_sdram_choose_cmd_cmd_payload_cas <= builder_t_array_muxed0;
+    end
+  end
+  always @(*) begin
+    main_sdram_choose_cmd_cmd_payload_ras <= 1'd0;
+    if (main_sdram_choose_cmd_cmd_valid) begin
+      main_sdram_choose_cmd_cmd_payload_ras <= builder_t_array_muxed1;
+    end
+  end
+  always @(*) begin
+    main_sdram_choose_cmd_cmd_payload_we <= 1'd0;
+    if (main_sdram_choose_cmd_cmd_valid) begin
+      main_sdram_choose_cmd_cmd_payload_we <= builder_t_array_muxed2;
+    end
+  end
+  assign main_sdram_choose_cmd_ce = (main_sdram_choose_cmd_cmd_ready | (~main_sdram_choose_cmd_cmd_valid));
+  always @(*) begin
+    main_sdram_choose_req_valids <= 8'd0;
+    main_sdram_choose_req_valids[0] <= (main_sdram_bankmachine0_cmd_valid & (((main_sdram_bankmachine0_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine0_cmd_payload_ras & (~main_sdram_bankmachine0_cmd_payload_cas)) & (~main_sdram_bankmachine0_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine0_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine0_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[1] <= (main_sdram_bankmachine1_cmd_valid & (((main_sdram_bankmachine1_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine1_cmd_payload_ras & (~main_sdram_bankmachine1_cmd_payload_cas)) & (~main_sdram_bankmachine1_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine1_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine1_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[2] <= (main_sdram_bankmachine2_cmd_valid & (((main_sdram_bankmachine2_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine2_cmd_payload_ras & (~main_sdram_bankmachine2_cmd_payload_cas)) & (~main_sdram_bankmachine2_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine2_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine2_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[3] <= (main_sdram_bankmachine3_cmd_valid & (((main_sdram_bankmachine3_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine3_cmd_payload_ras & (~main_sdram_bankmachine3_cmd_payload_cas)) & (~main_sdram_bankmachine3_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine3_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine3_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[4] <= (main_sdram_bankmachine4_cmd_valid & (((main_sdram_bankmachine4_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine4_cmd_payload_ras & (~main_sdram_bankmachine4_cmd_payload_cas)) & (~main_sdram_bankmachine4_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine4_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine4_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[5] <= (main_sdram_bankmachine5_cmd_valid & (((main_sdram_bankmachine5_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine5_cmd_payload_ras & (~main_sdram_bankmachine5_cmd_payload_cas)) & (~main_sdram_bankmachine5_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine5_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine5_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[6] <= (main_sdram_bankmachine6_cmd_valid & (((main_sdram_bankmachine6_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine6_cmd_payload_ras & (~main_sdram_bankmachine6_cmd_payload_cas)) & (~main_sdram_bankmachine6_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine6_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine6_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+    main_sdram_choose_req_valids[7] <= (main_sdram_bankmachine7_cmd_valid & (((main_sdram_bankmachine7_cmd_payload_is_cmd & main_sdram_choose_req_want_cmds) & ((~((main_sdram_bankmachine7_cmd_payload_ras & (~main_sdram_bankmachine7_cmd_payload_cas)) & (~main_sdram_bankmachine7_cmd_payload_we))) | main_sdram_choose_req_want_activates)) | ((main_sdram_bankmachine7_cmd_payload_is_read == main_sdram_choose_req_want_reads) & (main_sdram_bankmachine7_cmd_payload_is_write == main_sdram_choose_req_want_writes))));
+  end
+  assign main_sdram_choose_req_request = main_sdram_choose_req_valids;
+  assign main_sdram_choose_req_cmd_valid = builder_rhs_array_muxed6;
+  assign main_sdram_choose_req_cmd_payload_a = builder_rhs_array_muxed7;
+  assign main_sdram_choose_req_cmd_payload_ba = builder_rhs_array_muxed8;
+  assign main_sdram_choose_req_cmd_payload_is_read = builder_rhs_array_muxed9;
+  assign main_sdram_choose_req_cmd_payload_is_write = builder_rhs_array_muxed10;
+  assign main_sdram_choose_req_cmd_payload_is_cmd = builder_rhs_array_muxed11;
+  always @(*) begin
+    main_sdram_choose_req_cmd_payload_cas <= 1'd0;
+    if (main_sdram_choose_req_cmd_valid) begin
+      main_sdram_choose_req_cmd_payload_cas <= builder_t_array_muxed3;
+    end
+  end
+  always @(*) begin
+    main_sdram_choose_req_cmd_payload_ras <= 1'd0;
+    if (main_sdram_choose_req_cmd_valid) begin
+      main_sdram_choose_req_cmd_payload_ras <= builder_t_array_muxed4;
+    end
+  end
+  always @(*) begin
+    main_sdram_choose_req_cmd_payload_we <= 1'd0;
+    if (main_sdram_choose_req_cmd_valid) begin
+      main_sdram_choose_req_cmd_payload_we <= builder_t_array_muxed5;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine0_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 1'd0))) begin
+      main_sdram_bankmachine0_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 1'd0))) begin
+      main_sdram_bankmachine0_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine1_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 1'd1))) begin
+      main_sdram_bankmachine1_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 1'd1))) begin
+      main_sdram_bankmachine1_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine2_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 2'd2))) begin
+      main_sdram_bankmachine2_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 2'd2))) begin
+      main_sdram_bankmachine2_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine3_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 2'd3))) begin
+      main_sdram_bankmachine3_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 2'd3))) begin
+      main_sdram_bankmachine3_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine4_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 3'd4))) begin
+      main_sdram_bankmachine4_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 3'd4))) begin
+      main_sdram_bankmachine4_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine5_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 3'd5))) begin
+      main_sdram_bankmachine5_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 3'd5))) begin
+      main_sdram_bankmachine5_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine6_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 3'd6))) begin
+      main_sdram_bankmachine6_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 3'd6))) begin
+      main_sdram_bankmachine6_cmd_ready <= 1'd1;
+    end
+  end
+  always @(*) begin
+    main_sdram_bankmachine7_cmd_ready <= 1'd0;
+    if (((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & (main_sdram_choose_cmd_grant == 3'd7))) begin
+      main_sdram_bankmachine7_cmd_ready <= 1'd1;
+    end
+    if (((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & (main_sdram_choose_req_grant == 3'd7))) begin
+      main_sdram_bankmachine7_cmd_ready <= 1'd1;
+    end
+  end
+  assign main_sdram_choose_req_ce = (main_sdram_choose_req_cmd_ready | (~main_sdram_choose_req_cmd_valid));
+  assign main_sdram_dfi_p0_reset_n = 1'd1;
+  assign main_sdram_dfi_p0_cke = {1{main_sdram_steerer0}};
+  assign main_sdram_dfi_p0_odt = {1{main_sdram_steerer1}};
+  assign main_sdram_dfi_p1_reset_n = 1'd1;
+  assign main_sdram_dfi_p1_cke = {1{main_sdram_steerer2}};
+  assign main_sdram_dfi_p1_odt = {1{main_sdram_steerer3}};
+  assign main_sdram_dfi_p2_reset_n = 1'd1;
+  assign main_sdram_dfi_p2_cke = {1{main_sdram_steerer4}};
+  assign main_sdram_dfi_p2_odt = {1{main_sdram_steerer5}};
+  assign main_sdram_dfi_p3_reset_n = 1'd1;
+  assign main_sdram_dfi_p3_cke = {1{main_sdram_steerer6}};
+  assign main_sdram_dfi_p3_odt = {1{main_sdram_steerer7}};
+  assign main_sdram_tfawcon_count = (((main_sdram_tfawcon_window[0] + main_sdram_tfawcon_window[1]) + main_sdram_tfawcon_window[2]) + main_sdram_tfawcon_window[3]);
+  always @(*) begin
+    main_sdram_choose_req_cmd_ready <= 1'd0;
+    main_sdram_steerer_sel0 <= 2'd0;
+    main_sdram_steerer_sel1 <= 2'd0;
+    main_sdram_steerer_sel2 <= 2'd0;
+    main_sdram_choose_cmd_want_activates <= 1'd0;
+    main_sdram_en0 <= 1'd0;
+    main_sdram_steerer_sel3 <= 2'd0;
+    builder_multiplexer_next_state <= 4'd0;
+    main_sdram_choose_cmd_cmd_ready <= 1'd0;
+    main_sdram_choose_req_want_reads <= 1'd0;
+    main_sdram_cmd_ready <= 1'd0;
+    main_sdram_choose_req_want_writes <= 1'd0;
+    main_sdram_en1 <= 1'd0;
+    builder_multiplexer_next_state <= builder_multiplexer_state;
+    case (builder_multiplexer_state)
+      1'd1: begin
+        main_sdram_en1 <= 1'd1;
+        main_sdram_choose_req_want_writes <= 1'd1;
+        if (1'd0) begin
+          main_sdram_choose_req_cmd_ready <= (main_sdram_cas_allowed & ((~((main_sdram_choose_req_cmd_payload_ras & (~main_sdram_choose_req_cmd_payload_cas)) & (~main_sdram_choose_req_cmd_payload_we))) | main_sdram_ras_allowed));
+        end else begin
+          main_sdram_choose_cmd_want_activates <= main_sdram_ras_allowed;
+          main_sdram_choose_cmd_cmd_ready <= ((~((main_sdram_choose_cmd_cmd_payload_ras & (~main_sdram_choose_cmd_cmd_payload_cas)) & (~main_sdram_choose_cmd_cmd_payload_we))) | main_sdram_ras_allowed);
+          main_sdram_choose_req_cmd_ready <= main_sdram_cas_allowed;
+        end
+        main_sdram_steerer_sel0 <= 1'd0;
+        main_sdram_steerer_sel1 <= 1'd0;
+        main_sdram_steerer_sel2 <= 1'd1;
+        main_sdram_steerer_sel3 <= 2'd2;
+        if (main_sdram_read_available) begin
+          if (((~main_sdram_write_available) | main_sdram_max_time1)) begin
+            builder_multiplexer_next_state <= 2'd3;
+          end
+        end
+        if (main_sdram_go_to_refresh) begin
+          builder_multiplexer_next_state <= 2'd2;
+        end
+      end
+      2'd2: begin
+        main_sdram_steerer_sel0 <= 2'd3;
+        main_sdram_cmd_ready <= 1'd1;
+        if (main_sdram_cmd_last) begin
+          builder_multiplexer_next_state <= 1'd0;
+        end
+      end
+      2'd3: begin
+        if (main_sdram_twtrcon_ready) begin
+          builder_multiplexer_next_state <= 1'd0;
+        end
+      end
+      3'd4: begin
+        builder_multiplexer_next_state <= 3'd5;
+      end
+      3'd5: begin
+        builder_multiplexer_next_state <= 3'd6;
+      end
+      3'd6: begin
+        builder_multiplexer_next_state <= 3'd7;
+      end
+      3'd7: begin
+        builder_multiplexer_next_state <= 4'd8;
+      end
+      4'd8: begin
+        builder_multiplexer_next_state <= 4'd9;
+      end
+      4'd9: begin
+        builder_multiplexer_next_state <= 4'd10;
+      end
+      4'd10: begin
+        builder_multiplexer_next_state <= 4'd11;
+      end
+      4'd11: begin
+        builder_multiplexer_next_state <= 1'd1;
+      end
+      default: begin
+        main_sdram_en0 <= 1'd1;
+        main_sdram_choose_req_want_reads <= 1'd1;
+        if (1'd0) begin
+          main_sdram_choose_req_cmd_ready <= (main_sdram_cas_allowed & ((~((main_sdram_choose_req_cmd_payload_ras & (~main_sdram_choose_req_cmd_payload_cas)) & (~main_sdram_choose_req_cmd_payload_we))) | main_sdram_ras_allowed));
+        end else begin
+          main_sdram_choose_cmd_want_activates <= main_sdram_ras_allowed;
+          main_sdram_choose_cmd_cmd_ready <= ((~((main_sdram_choose_cmd_cmd_payload_ras & (~main_sdram_choose_cmd_cmd_payload_cas)) & (~main_sdram_choose_cmd_cmd_payload_we))) | main_sdram_ras_allowed);
+          main_sdram_choose_req_cmd_ready <= main_sdram_cas_allowed;
+        end
+        main_sdram_steerer_sel0 <= 1'd0;
+        main_sdram_steerer_sel1 <= 1'd1;
+        main_sdram_steerer_sel2 <= 2'd2;
+        main_sdram_steerer_sel3 <= 1'd0;
+        if (main_sdram_write_available) begin
+          if (((~main_sdram_read_available) | main_sdram_max_time0)) begin
+            builder_multiplexer_next_state <= 3'd4;
+          end
+        end
+        if (main_sdram_go_to_refresh) begin
+          builder_multiplexer_next_state <= 2'd2;
+        end
+      end
+    endcase
+  end
+  assign builder_roundrobin0_request = {
+    (((main_port_cmd_payload_addr[9:7] == 1'd0) & (~(((((((builder_locked0 | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin0_ce = ((~main_sdram_interface_bank0_valid) & (~main_sdram_interface_bank0_lock));
+  assign main_sdram_interface_bank0_addr = builder_rhs_array_muxed12;
+  assign main_sdram_interface_bank0_we = builder_rhs_array_muxed13;
+  assign main_sdram_interface_bank0_valid = builder_rhs_array_muxed14;
+  assign builder_roundrobin1_request = {
+    (((main_port_cmd_payload_addr[9:7] == 1'd1) & (~(((((((builder_locked1 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin1_ce = ((~main_sdram_interface_bank1_valid) & (~main_sdram_interface_bank1_lock));
+  assign main_sdram_interface_bank1_addr = builder_rhs_array_muxed15;
+  assign main_sdram_interface_bank1_we = builder_rhs_array_muxed16;
+  assign main_sdram_interface_bank1_valid = builder_rhs_array_muxed17;
+  assign builder_roundrobin2_request = {
+    (((main_port_cmd_payload_addr[9:7] == 2'd2) & (~(((((((builder_locked2 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin2_ce = ((~main_sdram_interface_bank2_valid) & (~main_sdram_interface_bank2_lock));
+  assign main_sdram_interface_bank2_addr = builder_rhs_array_muxed18;
+  assign main_sdram_interface_bank2_we = builder_rhs_array_muxed19;
+  assign main_sdram_interface_bank2_valid = builder_rhs_array_muxed20;
+  assign builder_roundrobin3_request = {
+    (((main_port_cmd_payload_addr[9:7] == 2'd3) & (~(((((((builder_locked3 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin3_ce = ((~main_sdram_interface_bank3_valid) & (~main_sdram_interface_bank3_lock));
+  assign main_sdram_interface_bank3_addr = builder_rhs_array_muxed21;
+  assign main_sdram_interface_bank3_we = builder_rhs_array_muxed22;
+  assign main_sdram_interface_bank3_valid = builder_rhs_array_muxed23;
+  assign builder_roundrobin4_request = {
+    (((main_port_cmd_payload_addr[9:7] == 3'd4) & (~(((((((builder_locked4 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin4_ce = ((~main_sdram_interface_bank4_valid) & (~main_sdram_interface_bank4_lock));
+  assign main_sdram_interface_bank4_addr = builder_rhs_array_muxed24;
+  assign main_sdram_interface_bank4_we = builder_rhs_array_muxed25;
+  assign main_sdram_interface_bank4_valid = builder_rhs_array_muxed26;
+  assign builder_roundrobin5_request = {
+    (((main_port_cmd_payload_addr[9:7] == 3'd5) & (~(((((((builder_locked5 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin5_ce = ((~main_sdram_interface_bank5_valid) & (~main_sdram_interface_bank5_lock));
+  assign main_sdram_interface_bank5_addr = builder_rhs_array_muxed27;
+  assign main_sdram_interface_bank5_we = builder_rhs_array_muxed28;
+  assign main_sdram_interface_bank5_valid = builder_rhs_array_muxed29;
+  assign builder_roundrobin6_request = {
+    (((main_port_cmd_payload_addr[9:7] == 3'd6) & (~(((((((builder_locked6 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin6_ce = ((~main_sdram_interface_bank6_valid) & (~main_sdram_interface_bank6_lock));
+  assign main_sdram_interface_bank6_addr = builder_rhs_array_muxed30;
+  assign main_sdram_interface_bank6_we = builder_rhs_array_muxed31;
+  assign main_sdram_interface_bank6_valid = builder_rhs_array_muxed32;
+  assign builder_roundrobin7_request = {
+    (((main_port_cmd_payload_addr[9:7] == 3'd7) & (~(((((((builder_locked7 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))))) & main_port_cmd_valid)
+  };
+  assign builder_roundrobin7_ce = ((~main_sdram_interface_bank7_valid) & (~main_sdram_interface_bank7_lock));
+  assign main_sdram_interface_bank7_addr = builder_rhs_array_muxed33;
+  assign main_sdram_interface_bank7_we = builder_rhs_array_muxed34;
+  assign main_sdram_interface_bank7_valid = builder_rhs_array_muxed35;
+  assign main_port_cmd_ready = ((((((((1'd0 | (((builder_roundrobin0_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 1'd0) & (~(((((((builder_locked0 | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank0_ready)) | (((builder_roundrobin1_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 1'd1) & (~(((((((builder_locked1 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank1_ready)) | (((builder_roundrobin2_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 2'd2) & (~(((((((builder_locked2 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank2_ready)) | (((builder_roundrobin3_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 2'd3) & (~(((((((builder_locked3 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank3_ready)) | (((builder_roundrobin4_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 3'd4) & (~(((((((builder_locked4 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank4_ready)) | (((builder_roundrobin5_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 3'd5) & (~(((((((builder_locked5 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank5_ready)) | (((builder_roundrobin6_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 3'd6) & (~(((((((builder_locked6 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0)))))) & main_sdram_interface_bank6_ready)) | (((builder_roundrobin7_grant == 1'd0) & ((main_port_cmd_payload_addr[9:7] == 3'd7) & (~(((((((builder_locked7 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0)))))) & main_sdram_interface_bank7_ready));
+  assign main_port_wdata_ready = builder_new_master_wdata_ready2;
+  assign main_port_rdata_valid = builder_new_master_rdata_valid9;
+  always @(*) begin
+    main_sdram_interface_wdata <= 128'd0;
+    main_sdram_interface_wdata_we <= 16'd0;
+    case ({
+      builder_new_master_wdata_ready2
+    })
+      1'd1: begin
+        main_sdram_interface_wdata <= main_port_wdata_payload_data;
+        main_sdram_interface_wdata_we <= main_port_wdata_payload_we;
+      end
+      default: begin
+        main_sdram_interface_wdata <= 1'd0;
+        main_sdram_interface_wdata_we <= 1'd0;
+      end
+    endcase
+  end
+  assign main_port_rdata_payload_data = main_sdram_interface_rdata;
+  assign builder_roundrobin0_grant = 1'd0;
+  assign builder_roundrobin1_grant = 1'd0;
+  assign builder_roundrobin2_grant = 1'd0;
+  assign builder_roundrobin3_grant = 1'd0;
+  assign builder_roundrobin4_grant = 1'd0;
+  assign builder_roundrobin5_grant = 1'd0;
+  assign builder_roundrobin6_grant = 1'd0;
+  assign builder_roundrobin7_grant = 1'd0;
+  assign main_data_port_adr = main_interface0_wb_sdram_adr[10:2];
+  always @(*) begin
+    main_data_port_we <= 16'd0;
+    main_data_port_dat_w <= 128'd0;
+    if (main_write_from_slave) begin
+      main_data_port_dat_w <= main_dat_r;
+      main_data_port_we <= {16{1'd1}};
+    end else begin
+      main_data_port_dat_w <= {4{main_interface0_wb_sdram_dat_w}};
+      if ((((main_interface0_wb_sdram_cyc & main_interface0_wb_sdram_stb) & main_interface0_wb_sdram_we) & main_interface0_wb_sdram_ack)) begin
+        main_data_port_we <= {
+          ({4{(main_interface0_wb_sdram_adr[1:0] == 1'd0)}} & main_interface0_wb_sdram_sel),
+          ({4{(main_interface0_wb_sdram_adr[1:0] == 1'd1)}} & main_interface0_wb_sdram_sel),
+          ({4{(main_interface0_wb_sdram_adr[1:0] == 2'd2)}} & main_interface0_wb_sdram_sel),
+          ({4{(main_interface0_wb_sdram_adr[1:0] == 2'd3)}} & main_interface0_wb_sdram_sel)
+        };
+      end
+    end
+  end
+  assign main_dat_w = main_data_port_dat_r;
+  assign main_sel   = 16'd65535;
+  always @(*) begin
+    main_interface0_wb_sdram_dat_r <= 32'd0;
+    case (main_adr_offset_r)
+      1'd0: begin
+        main_interface0_wb_sdram_dat_r <= main_data_port_dat_r[127:96];
+      end
+      1'd1: begin
+        main_interface0_wb_sdram_dat_r <= main_data_port_dat_r[95:64];
+      end
+      2'd2: begin
+        main_interface0_wb_sdram_dat_r <= main_data_port_dat_r[63:32];
+      end
+      default: begin
+        main_interface0_wb_sdram_dat_r <= main_data_port_dat_r[31:0];
+      end
+    endcase
+  end
+  assign {main_tag_do_dirty, main_tag_do_tag} = main_tag_port_dat_r;
+  assign main_tag_port_dat_w = {main_tag_di_dirty, main_tag_di_tag};
+  assign main_tag_port_adr = main_interface0_wb_sdram_adr[10:2];
+  assign main_tag_di_tag = main_interface0_wb_sdram_adr[29:11];
+  assign main_adr = {main_tag_do_tag, main_interface0_wb_sdram_adr[10:2]};
+  always @(*) begin
+    main_tag_di_dirty <= 1'd0;
+    main_interface0_wb_sdram_ack <= 1'd0;
+    main_word_clr <= 1'd0;
+    main_word_inc <= 1'd0;
+    main_write_from_slave <= 1'd0;
+    main_cyc <= 1'd0;
+    main_stb <= 1'd0;
+    main_tag_port_we <= 1'd0;
+    main_we <= 1'd0;
+    builder_fullmemorywe_next_state <= 2'd0;
+    builder_fullmemorywe_next_state <= builder_fullmemorywe_state;
+    case (builder_fullmemorywe_state)
+      1'd1: begin
+        main_word_clr <= 1'd1;
+        if ((main_tag_do_tag == main_interface0_wb_sdram_adr[29:11])) begin
+          main_interface0_wb_sdram_ack <= 1'd1;
+          if (main_interface0_wb_sdram_we) begin
+            main_tag_di_dirty <= 1'd1;
+            main_tag_port_we  <= 1'd1;
+          end
+          builder_fullmemorywe_next_state <= 1'd0;
+        end else begin
+          if (main_tag_do_dirty) begin
+            builder_fullmemorywe_next_state <= 2'd2;
+          end else begin
+            main_tag_port_we <= 1'd1;
+            main_word_clr <= 1'd1;
+            builder_fullmemorywe_next_state <= 2'd3;
+          end
+        end
+      end
+      2'd2: begin
+        main_stb <= 1'd1;
+        main_cyc <= 1'd1;
+        main_we  <= 1'd1;
+        if (main_ack) begin
+          main_word_inc <= 1'd1;
+          if (1'd1) begin
+            main_tag_port_we <= 1'd1;
+            main_word_clr <= 1'd1;
+            builder_fullmemorywe_next_state <= 2'd3;
+          end
+        end
+      end
+      2'd3: begin
+        main_stb <= 1'd1;
+        main_cyc <= 1'd1;
+        main_we  <= 1'd0;
+        if (main_ack) begin
+          main_write_from_slave <= 1'd1;
+          main_word_inc <= 1'd1;
+          if (1'd1) begin
+            builder_fullmemorywe_next_state <= 1'd1;
+          end else begin
+            builder_fullmemorywe_next_state <= 2'd3;
+          end
+        end
+      end
+      default: begin
+        if ((main_interface0_wb_sdram_cyc & main_interface0_wb_sdram_stb)) begin
+          builder_fullmemorywe_next_state <= 1'd1;
+        end
+      end
+    endcase
+  end
+  assign main_wdata_converter_sink_valid = ((main_cyc & main_stb) & main_we);
+  assign main_wdata_converter_sink_payload_data = main_dat_w;
+  assign main_wdata_converter_sink_payload_we = main_sel;
+  assign main_port_wdata_valid = main_wdata_converter_source_valid;
+  assign main_wdata_converter_source_ready = main_port_wdata_ready;
+  assign main_port_wdata_first = main_wdata_converter_source_first;
+  assign main_port_wdata_last = main_wdata_converter_source_last;
+  assign main_port_wdata_payload_data = main_wdata_converter_source_payload_data;
+  assign main_port_wdata_payload_we = main_wdata_converter_source_payload_we;
+  assign main_rdata_converter_sink_valid = main_port_rdata_valid;
+  assign main_port_rdata_ready = main_rdata_converter_sink_ready;
+  assign main_rdata_converter_sink_first = main_port_rdata_first;
+  assign main_rdata_converter_sink_last = main_port_rdata_last;
+  assign main_rdata_converter_sink_payload_data = main_port_rdata_payload_data;
+  assign main_rdata_converter_source_ready = 1'd1;
+  assign main_dat_r = main_rdata_converter_source_payload_data;
+  assign main_wdata_converter_converter_sink_valid = main_wdata_converter_sink_valid;
+  assign main_wdata_converter_converter_sink_first = main_wdata_converter_sink_first;
+  assign main_wdata_converter_converter_sink_last = main_wdata_converter_sink_last;
+  assign main_wdata_converter_sink_ready = main_wdata_converter_converter_sink_ready;
+  assign main_wdata_converter_converter_sink_payload_data = {
+    main_wdata_converter_sink_payload_we, main_wdata_converter_sink_payload_data
+  };
+  assign main_wdata_converter_source_valid = main_wdata_converter_source_source_valid;
+  assign main_wdata_converter_source_first = main_wdata_converter_source_source_first;
+  assign main_wdata_converter_source_last = main_wdata_converter_source_source_last;
+  assign main_wdata_converter_source_source_ready = main_wdata_converter_source_ready;
+  assign {main_wdata_converter_source_payload_we, main_wdata_converter_source_payload_data} = main_wdata_converter_source_source_payload_data;
+  assign main_wdata_converter_source_source_valid = main_wdata_converter_converter_source_valid;
+  assign main_wdata_converter_converter_source_ready = main_wdata_converter_source_source_ready;
+  assign main_wdata_converter_source_source_first = main_wdata_converter_converter_source_first;
+  assign main_wdata_converter_source_source_last = main_wdata_converter_converter_source_last;
+  assign main_wdata_converter_source_source_payload_data = main_wdata_converter_converter_source_payload_data;
+  assign main_wdata_converter_converter_source_valid = main_wdata_converter_converter_sink_valid;
+  assign main_wdata_converter_converter_sink_ready = main_wdata_converter_converter_source_ready;
+  assign main_wdata_converter_converter_source_first = main_wdata_converter_converter_sink_first;
+  assign main_wdata_converter_converter_source_last = main_wdata_converter_converter_sink_last;
+  assign main_wdata_converter_converter_source_payload_data = main_wdata_converter_converter_sink_payload_data;
+  assign main_wdata_converter_converter_source_payload_valid_token_count = 1'd1;
+  assign main_rdata_converter_converter_sink_valid = main_rdata_converter_sink_valid;
+  assign main_rdata_converter_converter_sink_first = main_rdata_converter_sink_first;
+  assign main_rdata_converter_converter_sink_last = main_rdata_converter_sink_last;
+  assign main_rdata_converter_sink_ready = main_rdata_converter_converter_sink_ready;
+  assign main_rdata_converter_converter_sink_payload_data = {
+    main_rdata_converter_sink_payload_data
+  };
+  assign main_rdata_converter_source_valid = main_rdata_converter_source_source_valid;
+  assign main_rdata_converter_source_first = main_rdata_converter_source_source_first;
+  assign main_rdata_converter_source_last = main_rdata_converter_source_source_last;
+  assign main_rdata_converter_source_source_ready = main_rdata_converter_source_ready;
+  assign {main_rdata_converter_source_payload_data} = main_rdata_converter_source_source_payload_data;
+  assign main_rdata_converter_source_source_valid = main_rdata_converter_converter_source_valid;
+  assign main_rdata_converter_converter_source_ready = main_rdata_converter_source_source_ready;
+  assign main_rdata_converter_source_source_first = main_rdata_converter_converter_source_first;
+  assign main_rdata_converter_source_source_last = main_rdata_converter_converter_source_last;
+  assign main_rdata_converter_source_source_payload_data = main_rdata_converter_converter_source_payload_data;
+  assign main_rdata_converter_converter_source_valid = main_rdata_converter_converter_sink_valid;
+  assign main_rdata_converter_converter_sink_ready = main_rdata_converter_converter_source_ready;
+  assign main_rdata_converter_converter_source_first = main_rdata_converter_converter_sink_first;
+  assign main_rdata_converter_converter_source_last = main_rdata_converter_converter_sink_last;
+  assign main_rdata_converter_converter_source_payload_data = main_rdata_converter_converter_sink_payload_data;
+  assign main_rdata_converter_converter_source_payload_valid_token_count = 1'd1;
+  always @(*) begin
+    builder_litedramwishbone2native_next_state <= 2'd0;
+    main_ack <= 1'd0;
+    main_port_cmd_payload_we <= 1'd0;
+    main_port_cmd_payload_addr <= 24'd0;
+    main_count_next_value <= 1'd0;
+    main_count_next_value_ce <= 1'd0;
+    main_port_cmd_valid <= 1'd0;
+    builder_litedramwishbone2native_next_state <= builder_litedramwishbone2native_state;
+    case (builder_litedramwishbone2native_state)
+      1'd1: begin
+        if (main_wdata_converter_sink_ready) begin
+          main_ack <= 1'd1;
+          builder_litedramwishbone2native_next_state <= 1'd0;
+        end
+      end
+      2'd2: begin
+        if (main_rdata_converter_source_valid) begin
+          main_ack <= 1'd1;
+          builder_litedramwishbone2native_next_state <= 1'd0;
+        end
+      end
+      default: begin
+        main_port_cmd_valid <= (main_cyc & main_stb);
+        main_port_cmd_payload_we <= main_we;
+        main_port_cmd_payload_addr <= (((main_adr * 1'd1) + main_count) - 1'd0);
+        if ((main_port_cmd_valid & main_port_cmd_ready)) begin
+          main_count_next_value <= (main_count + 1'd1);
+          main_count_next_value_ce <= 1'd1;
+          if ((main_count == 1'd0)) begin
+            main_count_next_value <= 1'd0;
+            main_count_next_value_ce <= 1'd1;
+            if (main_we) begin
+              builder_litedramwishbone2native_next_state <= 1'd1;
+            end else begin
+              builder_litedramwishbone2native_next_state <= 2'd2;
+            end
+          end
+        end
+      end
+    endcase
+  end
+  assign main_interface0_wb_sdram_adr = builder_rhs_array_muxed36;
+  assign main_interface0_wb_sdram_dat_w = builder_rhs_array_muxed37;
+  assign main_interface0_wb_sdram_sel = builder_rhs_array_muxed38;
+  assign main_interface0_wb_sdram_cyc = builder_rhs_array_muxed39;
+  assign main_interface0_wb_sdram_stb = builder_rhs_array_muxed40;
+  assign main_interface0_wb_sdram_we = builder_rhs_array_muxed41;
+  assign main_interface0_wb_sdram_cti = builder_rhs_array_muxed42;
+  assign main_interface0_wb_sdram_bte = builder_rhs_array_muxed43;
+  assign main_interface1_wb_sdram_dat_r = main_interface0_wb_sdram_dat_r;
+  assign main_interface1_wb_sdram_ack = (main_interface0_wb_sdram_ack & (builder_wb_sdram_con_grant == 1'd0));
+  assign main_interface1_wb_sdram_err = (main_interface0_wb_sdram_err & (builder_wb_sdram_con_grant == 1'd0));
+  assign builder_wb_sdram_con_request = {main_interface1_wb_sdram_cyc};
+  assign builder_wb_sdram_con_grant = 1'd0;
+  assign builder_minsoc_shared_adr = builder_rhs_array_muxed44;
+  assign builder_minsoc_shared_dat_w = builder_rhs_array_muxed45;
+  assign builder_minsoc_shared_sel = builder_rhs_array_muxed46;
+  assign builder_minsoc_shared_cyc = builder_rhs_array_muxed47;
+  assign builder_minsoc_shared_stb = builder_rhs_array_muxed48;
+  assign builder_minsoc_shared_we = builder_rhs_array_muxed49;
+  assign builder_minsoc_shared_cti = builder_rhs_array_muxed50;
+  assign builder_minsoc_shared_bte = builder_rhs_array_muxed51;
+  assign main_minsoc_interface0_soc_bus_dat_r = builder_minsoc_shared_dat_r;
+  assign main_minsoc_interface1_soc_bus_dat_r = builder_minsoc_shared_dat_r;
+  assign main_minsoc_interface0_soc_bus_ack = (builder_minsoc_shared_ack & (builder_minsoc_grant == 1'd0));
+  assign main_minsoc_interface1_soc_bus_ack = (builder_minsoc_shared_ack & (builder_minsoc_grant == 1'd1));
+  assign main_minsoc_interface0_soc_bus_err = (builder_minsoc_shared_err & (builder_minsoc_grant == 1'd0));
+  assign main_minsoc_interface1_soc_bus_err = (builder_minsoc_shared_err & (builder_minsoc_grant == 1'd1));
+  assign builder_minsoc_request = {
+    main_minsoc_interface1_soc_bus_cyc, main_minsoc_interface0_soc_bus_cyc
+  };
+  always @(*) begin
+    builder_minsoc_slave_sel <= 4'd0;
+    builder_minsoc_slave_sel[0] <= (builder_minsoc_shared_adr[28:13] == 1'd0);
+    builder_minsoc_slave_sel[1] <= (builder_minsoc_shared_adr[28:10] == 13'd4096);
+    builder_minsoc_slave_sel[2] <= (builder_minsoc_shared_adr[28:14] == 10'd512);
+    builder_minsoc_slave_sel[3] <= (builder_minsoc_shared_adr[28:26] == 3'd4);
+  end
+  assign main_minsoc_rom_bus_adr = builder_minsoc_shared_adr;
+  assign main_minsoc_rom_bus_dat_w = builder_minsoc_shared_dat_w;
+  assign main_minsoc_rom_bus_sel = builder_minsoc_shared_sel;
+  assign main_minsoc_rom_bus_stb = builder_minsoc_shared_stb;
+  assign main_minsoc_rom_bus_we = builder_minsoc_shared_we;
+  assign main_minsoc_rom_bus_cti = builder_minsoc_shared_cti;
+  assign main_minsoc_rom_bus_bte = builder_minsoc_shared_bte;
+  assign main_minsoc_sram_bus_adr = builder_minsoc_shared_adr;
+  assign main_minsoc_sram_bus_dat_w = builder_minsoc_shared_dat_w;
+  assign main_minsoc_sram_bus_sel = builder_minsoc_shared_sel;
+  assign main_minsoc_sram_bus_stb = builder_minsoc_shared_stb;
+  assign main_minsoc_sram_bus_we = builder_minsoc_shared_we;
+  assign main_minsoc_sram_bus_cti = builder_minsoc_shared_cti;
+  assign main_minsoc_sram_bus_bte = builder_minsoc_shared_bte;
+  assign main_minsoc_bus_wishbone_adr = builder_minsoc_shared_adr;
+  assign main_minsoc_bus_wishbone_dat_w = builder_minsoc_shared_dat_w;
+  assign main_minsoc_bus_wishbone_sel = builder_minsoc_shared_sel;
+  assign main_minsoc_bus_wishbone_stb = builder_minsoc_shared_stb;
+  assign main_minsoc_bus_wishbone_we = builder_minsoc_shared_we;
+  assign main_minsoc_bus_wishbone_cti = builder_minsoc_shared_cti;
+  assign main_minsoc_bus_wishbone_bte = builder_minsoc_shared_bte;
+  assign main_interface1_wb_sdram_adr = builder_minsoc_shared_adr;
+  assign main_interface1_wb_sdram_dat_w = builder_minsoc_shared_dat_w;
+  assign main_interface1_wb_sdram_sel = builder_minsoc_shared_sel;
+  assign main_interface1_wb_sdram_stb = builder_minsoc_shared_stb;
+  assign main_interface1_wb_sdram_we = builder_minsoc_shared_we;
+  assign main_interface1_wb_sdram_cti = builder_minsoc_shared_cti;
+  assign main_interface1_wb_sdram_bte = builder_minsoc_shared_bte;
+  assign main_minsoc_rom_bus_cyc = (builder_minsoc_shared_cyc & builder_minsoc_slave_sel[0]);
+  assign main_minsoc_sram_bus_cyc = (builder_minsoc_shared_cyc & builder_minsoc_slave_sel[1]);
+  assign main_minsoc_bus_wishbone_cyc = (builder_minsoc_shared_cyc & builder_minsoc_slave_sel[2]);
+  assign main_interface1_wb_sdram_cyc = (builder_minsoc_shared_cyc & builder_minsoc_slave_sel[3]);
+  assign builder_minsoc_shared_err = (((main_minsoc_rom_bus_err | main_minsoc_sram_bus_err) | main_minsoc_bus_wishbone_err) | main_interface1_wb_sdram_err);
+  assign builder_minsoc_wait = ((builder_minsoc_shared_stb & builder_minsoc_shared_cyc) & (~builder_minsoc_shared_ack));
+  always @(*) begin
+    builder_minsoc_shared_ack <= 1'd0;
+    builder_minsoc_error <= 1'd0;
+    builder_minsoc_shared_dat_r <= 32'd0;
+    builder_minsoc_shared_ack <= (((main_minsoc_rom_bus_ack | main_minsoc_sram_bus_ack) | main_minsoc_bus_wishbone_ack) | main_interface1_wb_sdram_ack);
+    builder_minsoc_shared_dat_r <= (((({32{builder_minsoc_slave_sel_r[0]}} & main_minsoc_rom_bus_dat_r) | ({32{builder_minsoc_slave_sel_r[1]}} & main_minsoc_sram_bus_dat_r)) | ({32{builder_minsoc_slave_sel_r[2]}} & main_minsoc_bus_wishbone_dat_r)) | ({32{builder_minsoc_slave_sel_r[3]}} & main_interface1_wb_sdram_dat_r));
+    if (builder_minsoc_done) begin
+      builder_minsoc_shared_dat_r <= 32'd4294967295;
+      builder_minsoc_shared_ack <= 1'd1;
+      builder_minsoc_error <= 1'd1;
+    end
+  end
+  assign builder_minsoc_done = (builder_minsoc_count == 1'd0);
+  assign builder_minsoc_csrbank0_sel = (builder_minsoc_interface0_bank_bus_adr[13:9] == 1'd0);
+  assign builder_minsoc_csrbank0_reset0_r = builder_minsoc_interface0_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank0_reset0_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 1'd0));
+  assign builder_minsoc_csrbank0_reset0_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 1'd0));
+  assign builder_minsoc_csrbank0_scratch3_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_scratch3_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 1'd1));
+  assign builder_minsoc_csrbank0_scratch3_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 1'd1));
+  assign builder_minsoc_csrbank0_scratch2_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_scratch2_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 2'd2));
+  assign builder_minsoc_csrbank0_scratch2_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 2'd2));
+  assign builder_minsoc_csrbank0_scratch1_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_scratch1_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 2'd3));
+  assign builder_minsoc_csrbank0_scratch1_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 2'd3));
+  assign builder_minsoc_csrbank0_scratch0_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_scratch0_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd4));
+  assign builder_minsoc_csrbank0_scratch0_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd4));
+  assign builder_minsoc_csrbank0_bus_errors3_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_bus_errors3_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd5));
+  assign builder_minsoc_csrbank0_bus_errors3_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd5));
+  assign builder_minsoc_csrbank0_bus_errors2_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_bus_errors2_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd6));
+  assign builder_minsoc_csrbank0_bus_errors2_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd6));
+  assign builder_minsoc_csrbank0_bus_errors1_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_bus_errors1_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd7));
+  assign builder_minsoc_csrbank0_bus_errors1_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 3'd7));
+  assign builder_minsoc_csrbank0_bus_errors0_r = builder_minsoc_interface0_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank0_bus_errors0_re = ((builder_minsoc_csrbank0_sel & builder_minsoc_interface0_bank_bus_we) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 4'd8));
+  assign builder_minsoc_csrbank0_bus_errors0_we = ((builder_minsoc_csrbank0_sel & (~builder_minsoc_interface0_bank_bus_we)) & (builder_minsoc_interface0_bank_bus_adr[3:0] == 4'd8));
+  assign builder_minsoc_csrbank0_reset0_w = main_minsoc_ctrl_reset_storage;
+  assign builder_minsoc_csrbank0_scratch3_w = main_minsoc_ctrl_scratch_storage[31:24];
+  assign builder_minsoc_csrbank0_scratch2_w = main_minsoc_ctrl_scratch_storage[23:16];
+  assign builder_minsoc_csrbank0_scratch1_w = main_minsoc_ctrl_scratch_storage[15:8];
+  assign builder_minsoc_csrbank0_scratch0_w = main_minsoc_ctrl_scratch_storage[7:0];
+  assign builder_minsoc_csrbank0_bus_errors3_w = main_minsoc_ctrl_bus_errors_status[31:24];
+  assign builder_minsoc_csrbank0_bus_errors2_w = main_minsoc_ctrl_bus_errors_status[23:16];
+  assign builder_minsoc_csrbank0_bus_errors1_w = main_minsoc_ctrl_bus_errors_status[15:8];
+  assign builder_minsoc_csrbank0_bus_errors0_w = main_minsoc_ctrl_bus_errors_status[7:0];
+  assign main_minsoc_ctrl_bus_errors_we = builder_minsoc_csrbank0_bus_errors0_we;
+  assign builder_minsoc_csrbank1_sel = (builder_minsoc_interface1_bank_bus_adr[13:9] == 3'd5);
+  assign builder_minsoc_csrbank1_half_sys8x_taps0_r = builder_minsoc_interface1_bank_bus_dat_w[4:0];
+  assign builder_minsoc_csrbank1_half_sys8x_taps0_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 1'd0));
+  assign builder_minsoc_csrbank1_half_sys8x_taps0_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 1'd0));
+  assign main_a7ddrphy_cdly_rst_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_cdly_rst_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 1'd1));
+  assign main_a7ddrphy_cdly_rst_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 1'd1));
+  assign main_a7ddrphy_cdly_inc_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_cdly_inc_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 2'd2));
+  assign main_a7ddrphy_cdly_inc_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 2'd2));
+  assign builder_minsoc_csrbank1_dly_sel0_r = builder_minsoc_interface1_bank_bus_dat_w[1:0];
+  assign builder_minsoc_csrbank1_dly_sel0_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 2'd3));
+  assign builder_minsoc_csrbank1_dly_sel0_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 2'd3));
+  assign main_a7ddrphy_rdly_dq_rst_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_rdly_dq_rst_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd4));
+  assign main_a7ddrphy_rdly_dq_rst_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd4));
+  assign main_a7ddrphy_rdly_dq_inc_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_rdly_dq_inc_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd5));
+  assign main_a7ddrphy_rdly_dq_inc_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd5));
+  assign main_a7ddrphy_rdly_dq_bitslip_rst_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_rdly_dq_bitslip_rst_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd6));
+  assign main_a7ddrphy_rdly_dq_bitslip_rst_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd6));
+  assign main_a7ddrphy_rdly_dq_bitslip_r = builder_minsoc_interface1_bank_bus_dat_w[0];
+  assign main_a7ddrphy_rdly_dq_bitslip_re = ((builder_minsoc_csrbank1_sel & builder_minsoc_interface1_bank_bus_we) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd7));
+  assign main_a7ddrphy_rdly_dq_bitslip_we = ((builder_minsoc_csrbank1_sel & (~builder_minsoc_interface1_bank_bus_we)) & (builder_minsoc_interface1_bank_bus_adr[2:0] == 3'd7));
+  assign builder_minsoc_csrbank1_half_sys8x_taps0_w = main_a7ddrphy_half_sys8x_taps_storage[4:0];
+  assign builder_minsoc_csrbank1_dly_sel0_w = main_a7ddrphy_dly_sel_storage[1:0];
+  assign builder_minsoc_csrbank2_sel = (builder_minsoc_interface2_bank_bus_adr[13:9] == 4'd8);
+  assign builder_minsoc_csrbank2_dfii_control0_r = builder_minsoc_interface2_bank_bus_dat_w[3:0];
+  assign builder_minsoc_csrbank2_dfii_control0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 1'd0));
+  assign builder_minsoc_csrbank2_dfii_control0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 1'd0));
+  assign builder_minsoc_csrbank2_dfii_pi0_command0_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_command0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 1'd1));
+  assign builder_minsoc_csrbank2_dfii_pi0_command0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 1'd1));
+  assign main_sdram_phaseinjector0_command_issue_r = builder_minsoc_interface2_bank_bus_dat_w[0];
+  assign main_sdram_phaseinjector0_command_issue_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 2'd2));
+  assign main_sdram_phaseinjector0_command_issue_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 2'd2));
+  assign builder_minsoc_csrbank2_dfii_pi0_address1_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_address1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 2'd3));
+  assign builder_minsoc_csrbank2_dfii_pi0_address1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 2'd3));
+  assign builder_minsoc_csrbank2_dfii_pi0_address0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_address0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd4));
+  assign builder_minsoc_csrbank2_dfii_pi0_address0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd4));
+  assign builder_minsoc_csrbank2_dfii_pi0_baddress0_r = builder_minsoc_interface2_bank_bus_dat_w[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_baddress0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd5));
+  assign builder_minsoc_csrbank2_dfii_pi0_baddress0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd5));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd6));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd6));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd7));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 3'd7));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd8));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd8));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd9));
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd9));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd10));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd10));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd11));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd11));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd12));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd12));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd13));
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd13));
+  assign builder_minsoc_csrbank2_dfii_pi1_command0_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_command0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd14));
+  assign builder_minsoc_csrbank2_dfii_pi1_command0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd14));
+  assign main_sdram_phaseinjector1_command_issue_r = builder_minsoc_interface2_bank_bus_dat_w[0];
+  assign main_sdram_phaseinjector1_command_issue_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd15));
+  assign main_sdram_phaseinjector1_command_issue_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 4'd15));
+  assign builder_minsoc_csrbank2_dfii_pi1_address1_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_address1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd16));
+  assign builder_minsoc_csrbank2_dfii_pi1_address1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd16));
+  assign builder_minsoc_csrbank2_dfii_pi1_address0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_address0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd17));
+  assign builder_minsoc_csrbank2_dfii_pi1_address0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd17));
+  assign builder_minsoc_csrbank2_dfii_pi1_baddress0_r = builder_minsoc_interface2_bank_bus_dat_w[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_baddress0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd18));
+  assign builder_minsoc_csrbank2_dfii_pi1_baddress0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd18));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd19));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd19));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd20));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd20));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd21));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd21));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd22));
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd22));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd23));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd23));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd24));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd24));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd25));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd25));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd26));
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd26));
+  assign builder_minsoc_csrbank2_dfii_pi2_command0_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_command0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd27));
+  assign builder_minsoc_csrbank2_dfii_pi2_command0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd27));
+  assign main_sdram_phaseinjector2_command_issue_r = builder_minsoc_interface2_bank_bus_dat_w[0];
+  assign main_sdram_phaseinjector2_command_issue_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd28));
+  assign main_sdram_phaseinjector2_command_issue_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd28));
+  assign builder_minsoc_csrbank2_dfii_pi2_address1_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_address1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd29));
+  assign builder_minsoc_csrbank2_dfii_pi2_address1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd29));
+  assign builder_minsoc_csrbank2_dfii_pi2_address0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_address0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd30));
+  assign builder_minsoc_csrbank2_dfii_pi2_address0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd30));
+  assign builder_minsoc_csrbank2_dfii_pi2_baddress0_r = builder_minsoc_interface2_bank_bus_dat_w[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_baddress0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd31));
+  assign builder_minsoc_csrbank2_dfii_pi2_baddress0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 5'd31));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd32));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd32));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd33));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd33));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd34));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd34));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd35));
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd35));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd36));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd36));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd37));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd37));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd38));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd38));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd39));
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd39));
+  assign builder_minsoc_csrbank2_dfii_pi3_command0_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_command0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd40));
+  assign builder_minsoc_csrbank2_dfii_pi3_command0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd40));
+  assign main_sdram_phaseinjector3_command_issue_r = builder_minsoc_interface2_bank_bus_dat_w[0];
+  assign main_sdram_phaseinjector3_command_issue_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd41));
+  assign main_sdram_phaseinjector3_command_issue_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd41));
+  assign builder_minsoc_csrbank2_dfii_pi3_address1_r = builder_minsoc_interface2_bank_bus_dat_w[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_address1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd42));
+  assign builder_minsoc_csrbank2_dfii_pi3_address1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd42));
+  assign builder_minsoc_csrbank2_dfii_pi3_address0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_address0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd43));
+  assign builder_minsoc_csrbank2_dfii_pi3_address0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd43));
+  assign builder_minsoc_csrbank2_dfii_pi3_baddress0_r = builder_minsoc_interface2_bank_bus_dat_w[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_baddress0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd44));
+  assign builder_minsoc_csrbank2_dfii_pi3_baddress0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd44));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd45));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd45));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd46));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd46));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd47));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd47));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd48));
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd48));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata3_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata3_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd49));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata3_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd49));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata2_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata2_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd50));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata2_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd50));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata1_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata1_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd51));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata1_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd51));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata0_r = builder_minsoc_interface2_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata0_re = ((builder_minsoc_csrbank2_sel & builder_minsoc_interface2_bank_bus_we) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd52));
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata0_we = ((builder_minsoc_csrbank2_sel & (~builder_minsoc_interface2_bank_bus_we)) & (builder_minsoc_interface2_bank_bus_adr[5:0] == 6'd52));
+  assign builder_minsoc_csrbank2_dfii_control0_w = main_sdram_storage[3:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_command0_w = main_sdram_phaseinjector0_command_storage[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_address1_w = main_sdram_phaseinjector0_address_storage[13:8];
+  assign builder_minsoc_csrbank2_dfii_pi0_address0_w = main_sdram_phaseinjector0_address_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_baddress0_w = main_sdram_phaseinjector0_baddress_storage[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata3_w = main_sdram_phaseinjector0_wrdata_storage[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata2_w = main_sdram_phaseinjector0_wrdata_storage[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata1_w = main_sdram_phaseinjector0_wrdata_storage[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi0_wrdata0_w = main_sdram_phaseinjector0_wrdata_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata3_w = main_sdram_phaseinjector0_status[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata2_w = main_sdram_phaseinjector0_status[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata1_w = main_sdram_phaseinjector0_status[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi0_rddata0_w = main_sdram_phaseinjector0_status[7:0];
+  assign main_sdram_phaseinjector0_we = builder_minsoc_csrbank2_dfii_pi0_rddata0_we;
+  assign builder_minsoc_csrbank2_dfii_pi1_command0_w = main_sdram_phaseinjector1_command_storage[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_address1_w = main_sdram_phaseinjector1_address_storage[13:8];
+  assign builder_minsoc_csrbank2_dfii_pi1_address0_w = main_sdram_phaseinjector1_address_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_baddress0_w = main_sdram_phaseinjector1_baddress_storage[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata3_w = main_sdram_phaseinjector1_wrdata_storage[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata2_w = main_sdram_phaseinjector1_wrdata_storage[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata1_w = main_sdram_phaseinjector1_wrdata_storage[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi1_wrdata0_w = main_sdram_phaseinjector1_wrdata_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata3_w = main_sdram_phaseinjector1_status[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata2_w = main_sdram_phaseinjector1_status[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata1_w = main_sdram_phaseinjector1_status[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi1_rddata0_w = main_sdram_phaseinjector1_status[7:0];
+  assign main_sdram_phaseinjector1_we = builder_minsoc_csrbank2_dfii_pi1_rddata0_we;
+  assign builder_minsoc_csrbank2_dfii_pi2_command0_w = main_sdram_phaseinjector2_command_storage[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_address1_w = main_sdram_phaseinjector2_address_storage[13:8];
+  assign builder_minsoc_csrbank2_dfii_pi2_address0_w = main_sdram_phaseinjector2_address_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_baddress0_w = main_sdram_phaseinjector2_baddress_storage[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata3_w = main_sdram_phaseinjector2_wrdata_storage[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata2_w = main_sdram_phaseinjector2_wrdata_storage[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata1_w = main_sdram_phaseinjector2_wrdata_storage[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi2_wrdata0_w = main_sdram_phaseinjector2_wrdata_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata3_w = main_sdram_phaseinjector2_status[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata2_w = main_sdram_phaseinjector2_status[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata1_w = main_sdram_phaseinjector2_status[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi2_rddata0_w = main_sdram_phaseinjector2_status[7:0];
+  assign main_sdram_phaseinjector2_we = builder_minsoc_csrbank2_dfii_pi2_rddata0_we;
+  assign builder_minsoc_csrbank2_dfii_pi3_command0_w = main_sdram_phaseinjector3_command_storage[5:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_address1_w = main_sdram_phaseinjector3_address_storage[13:8];
+  assign builder_minsoc_csrbank2_dfii_pi3_address0_w = main_sdram_phaseinjector3_address_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_baddress0_w = main_sdram_phaseinjector3_baddress_storage[2:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata3_w = main_sdram_phaseinjector3_wrdata_storage[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata2_w = main_sdram_phaseinjector3_wrdata_storage[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata1_w = main_sdram_phaseinjector3_wrdata_storage[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi3_wrdata0_w = main_sdram_phaseinjector3_wrdata_storage[7:0];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata3_w = main_sdram_phaseinjector3_status[31:24];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata2_w = main_sdram_phaseinjector3_status[23:16];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata1_w = main_sdram_phaseinjector3_status[15:8];
+  assign builder_minsoc_csrbank2_dfii_pi3_rddata0_w = main_sdram_phaseinjector3_status[7:0];
+  assign main_sdram_phaseinjector3_we = builder_minsoc_csrbank2_dfii_pi3_rddata0_we;
+  assign builder_minsoc_csrbank3_sel = (builder_minsoc_interface3_bank_bus_adr[13:9] == 3'd4);
+  assign builder_minsoc_csrbank3_load3_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_load3_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 1'd0));
+  assign builder_minsoc_csrbank3_load3_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 1'd0));
+  assign builder_minsoc_csrbank3_load2_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_load2_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 1'd1));
+  assign builder_minsoc_csrbank3_load2_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 1'd1));
+  assign builder_minsoc_csrbank3_load1_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_load1_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 2'd2));
+  assign builder_minsoc_csrbank3_load1_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 2'd2));
+  assign builder_minsoc_csrbank3_load0_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_load0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 2'd3));
+  assign builder_minsoc_csrbank3_load0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 2'd3));
+  assign builder_minsoc_csrbank3_reload3_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_reload3_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd4));
+  assign builder_minsoc_csrbank3_reload3_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd4));
+  assign builder_minsoc_csrbank3_reload2_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_reload2_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd5));
+  assign builder_minsoc_csrbank3_reload2_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd5));
+  assign builder_minsoc_csrbank3_reload1_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_reload1_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd6));
+  assign builder_minsoc_csrbank3_reload1_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd6));
+  assign builder_minsoc_csrbank3_reload0_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_reload0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd7));
+  assign builder_minsoc_csrbank3_reload0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 3'd7));
+  assign builder_minsoc_csrbank3_en0_r = builder_minsoc_interface3_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank3_en0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd8));
+  assign builder_minsoc_csrbank3_en0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd8));
+  assign builder_minsoc_csrbank3_update_value0_r = builder_minsoc_interface3_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank3_update_value0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd9));
+  assign builder_minsoc_csrbank3_update_value0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd9));
+  assign builder_minsoc_csrbank3_value3_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_value3_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd10));
+  assign builder_minsoc_csrbank3_value3_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd10));
+  assign builder_minsoc_csrbank3_value2_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_value2_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd11));
+  assign builder_minsoc_csrbank3_value2_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd11));
+  assign builder_minsoc_csrbank3_value1_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_value1_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd12));
+  assign builder_minsoc_csrbank3_value1_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd12));
+  assign builder_minsoc_csrbank3_value0_r = builder_minsoc_interface3_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank3_value0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd13));
+  assign builder_minsoc_csrbank3_value0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd13));
+  assign main_minsoc_timer0_eventmanager_status_r = builder_minsoc_interface3_bank_bus_dat_w[0];
+  assign main_minsoc_timer0_eventmanager_status_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd14));
+  assign main_minsoc_timer0_eventmanager_status_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd14));
+  assign main_minsoc_timer0_eventmanager_pending_r = builder_minsoc_interface3_bank_bus_dat_w[0];
+  assign main_minsoc_timer0_eventmanager_pending_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd15));
+  assign main_minsoc_timer0_eventmanager_pending_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 4'd15));
+  assign builder_minsoc_csrbank3_ev_enable0_r = builder_minsoc_interface3_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank3_ev_enable0_re = ((builder_minsoc_csrbank3_sel & builder_minsoc_interface3_bank_bus_we) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 5'd16));
+  assign builder_minsoc_csrbank3_ev_enable0_we = ((builder_minsoc_csrbank3_sel & (~builder_minsoc_interface3_bank_bus_we)) & (builder_minsoc_interface3_bank_bus_adr[4:0] == 5'd16));
+  assign builder_minsoc_csrbank3_load3_w = main_minsoc_timer0_load_storage[31:24];
+  assign builder_minsoc_csrbank3_load2_w = main_minsoc_timer0_load_storage[23:16];
+  assign builder_minsoc_csrbank3_load1_w = main_minsoc_timer0_load_storage[15:8];
+  assign builder_minsoc_csrbank3_load0_w = main_minsoc_timer0_load_storage[7:0];
+  assign builder_minsoc_csrbank3_reload3_w = main_minsoc_timer0_reload_storage[31:24];
+  assign builder_minsoc_csrbank3_reload2_w = main_minsoc_timer0_reload_storage[23:16];
+  assign builder_minsoc_csrbank3_reload1_w = main_minsoc_timer0_reload_storage[15:8];
+  assign builder_minsoc_csrbank3_reload0_w = main_minsoc_timer0_reload_storage[7:0];
+  assign builder_minsoc_csrbank3_en0_w = main_minsoc_timer0_en_storage;
+  assign builder_minsoc_csrbank3_update_value0_w = main_minsoc_timer0_update_value_storage;
+  assign builder_minsoc_csrbank3_value3_w = main_minsoc_timer0_value_status[31:24];
+  assign builder_minsoc_csrbank3_value2_w = main_minsoc_timer0_value_status[23:16];
+  assign builder_minsoc_csrbank3_value1_w = main_minsoc_timer0_value_status[15:8];
+  assign builder_minsoc_csrbank3_value0_w = main_minsoc_timer0_value_status[7:0];
+  assign main_minsoc_timer0_value_we = builder_minsoc_csrbank3_value0_we;
+  assign builder_minsoc_csrbank3_ev_enable0_w = main_minsoc_timer0_eventmanager_storage;
+  assign builder_minsoc_csrbank4_sel = (builder_minsoc_interface4_bank_bus_adr[13:9] == 2'd3);
+  assign main_minsoc_uart_rxtx_r = builder_minsoc_interface4_bank_bus_dat_w[7:0];
+  assign main_minsoc_uart_rxtx_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 1'd0));
+  assign main_minsoc_uart_rxtx_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 1'd0));
+  assign builder_minsoc_csrbank4_txfull_r = builder_minsoc_interface4_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank4_txfull_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 1'd1));
+  assign builder_minsoc_csrbank4_txfull_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 1'd1));
+  assign builder_minsoc_csrbank4_rxempty_r = builder_minsoc_interface4_bank_bus_dat_w[0];
+  assign builder_minsoc_csrbank4_rxempty_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 2'd2));
+  assign builder_minsoc_csrbank4_rxempty_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 2'd2));
+  assign main_minsoc_uart_eventmanager_status_r = builder_minsoc_interface4_bank_bus_dat_w[1:0];
+  assign main_minsoc_uart_eventmanager_status_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 2'd3));
+  assign main_minsoc_uart_eventmanager_status_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 2'd3));
+  assign main_minsoc_uart_eventmanager_pending_r = builder_minsoc_interface4_bank_bus_dat_w[1:0];
+  assign main_minsoc_uart_eventmanager_pending_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 3'd4));
+  assign main_minsoc_uart_eventmanager_pending_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 3'd4));
+  assign builder_minsoc_csrbank4_ev_enable0_r = builder_minsoc_interface4_bank_bus_dat_w[1:0];
+  assign builder_minsoc_csrbank4_ev_enable0_re = ((builder_minsoc_csrbank4_sel & builder_minsoc_interface4_bank_bus_we) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 3'd5));
+  assign builder_minsoc_csrbank4_ev_enable0_we = ((builder_minsoc_csrbank4_sel & (~builder_minsoc_interface4_bank_bus_we)) & (builder_minsoc_interface4_bank_bus_adr[2:0] == 3'd5));
+  assign builder_minsoc_csrbank4_txfull_w = main_minsoc_uart_txfull_status;
+  assign main_minsoc_uart_txfull_we = builder_minsoc_csrbank4_txfull_we;
+  assign builder_minsoc_csrbank4_rxempty_w = main_minsoc_uart_rxempty_status;
+  assign main_minsoc_uart_rxempty_we = builder_minsoc_csrbank4_rxempty_we;
+  assign builder_minsoc_csrbank4_ev_enable0_w = main_minsoc_uart_eventmanager_storage[1:0];
+  assign builder_minsoc_csrbank5_sel = (builder_minsoc_interface5_bank_bus_adr[13:9] == 2'd2);
+  assign builder_minsoc_csrbank5_tuning_word3_r = builder_minsoc_interface5_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank5_tuning_word3_re = ((builder_minsoc_csrbank5_sel & builder_minsoc_interface5_bank_bus_we) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 1'd0));
+  assign builder_minsoc_csrbank5_tuning_word3_we = ((builder_minsoc_csrbank5_sel & (~builder_minsoc_interface5_bank_bus_we)) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 1'd0));
+  assign builder_minsoc_csrbank5_tuning_word2_r = builder_minsoc_interface5_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank5_tuning_word2_re = ((builder_minsoc_csrbank5_sel & builder_minsoc_interface5_bank_bus_we) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 1'd1));
+  assign builder_minsoc_csrbank5_tuning_word2_we = ((builder_minsoc_csrbank5_sel & (~builder_minsoc_interface5_bank_bus_we)) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 1'd1));
+  assign builder_minsoc_csrbank5_tuning_word1_r = builder_minsoc_interface5_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank5_tuning_word1_re = ((builder_minsoc_csrbank5_sel & builder_minsoc_interface5_bank_bus_we) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 2'd2));
+  assign builder_minsoc_csrbank5_tuning_word1_we = ((builder_minsoc_csrbank5_sel & (~builder_minsoc_interface5_bank_bus_we)) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 2'd2));
+  assign builder_minsoc_csrbank5_tuning_word0_r = builder_minsoc_interface5_bank_bus_dat_w[7:0];
+  assign builder_minsoc_csrbank5_tuning_word0_re = ((builder_minsoc_csrbank5_sel & builder_minsoc_interface5_bank_bus_we) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 2'd3));
+  assign builder_minsoc_csrbank5_tuning_word0_we = ((builder_minsoc_csrbank5_sel & (~builder_minsoc_interface5_bank_bus_we)) & (builder_minsoc_interface5_bank_bus_adr[1:0] == 2'd3));
+  assign builder_minsoc_csrbank5_tuning_word3_w = main_minsoc_storage[31:24];
+  assign builder_minsoc_csrbank5_tuning_word2_w = main_minsoc_storage[23:16];
+  assign builder_minsoc_csrbank5_tuning_word1_w = main_minsoc_storage[15:8];
+  assign builder_minsoc_csrbank5_tuning_word0_w = main_minsoc_storage[7:0];
+  assign builder_minsoc_adr = main_minsoc_interface_adr;
+  assign builder_minsoc_we = main_minsoc_interface_we;
+  assign builder_minsoc_dat_w = main_minsoc_interface_dat_w;
+  assign main_minsoc_interface_dat_r = builder_minsoc_dat_r;
+  assign builder_minsoc_interface0_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface1_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface2_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface3_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface4_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface5_bank_bus_adr = builder_minsoc_adr;
+  assign builder_minsoc_interface0_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface1_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface2_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface3_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface4_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface5_bank_bus_we = builder_minsoc_we;
+  assign builder_minsoc_interface0_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_interface1_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_interface2_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_interface3_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_interface4_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_interface5_bank_bus_dat_w = builder_minsoc_dat_w;
+  assign builder_minsoc_dat_r = (((((builder_minsoc_interface0_bank_bus_dat_r | builder_minsoc_interface1_bank_bus_dat_r) | builder_minsoc_interface2_bank_bus_dat_r) | builder_minsoc_interface3_bank_bus_dat_r) | builder_minsoc_interface4_bank_bus_dat_r) | builder_minsoc_interface5_bank_bus_dat_r);
+  always @(*) begin
+    builder_rhs_array_muxed0 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[0];
+      end
+      1'd1: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[1];
+      end
+      2'd2: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[2];
+      end
+      2'd3: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[3];
+      end
+      3'd4: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[4];
+      end
+      3'd5: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[5];
+      end
+      3'd6: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[6];
+      end
+      default: begin
+        builder_rhs_array_muxed0 <= main_sdram_choose_cmd_valids[7];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed1 <= 14'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine0_cmd_payload_a;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine1_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine2_cmd_payload_a;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine3_cmd_payload_a;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine4_cmd_payload_a;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine5_cmd_payload_a;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine6_cmd_payload_a;
+      end
+      default: begin
+        builder_rhs_array_muxed1 <= main_sdram_bankmachine7_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed2 <= 3'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine0_cmd_payload_ba;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine1_cmd_payload_ba;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine2_cmd_payload_ba;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine3_cmd_payload_ba;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine4_cmd_payload_ba;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine5_cmd_payload_ba;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine6_cmd_payload_ba;
+      end
+      default: begin
+        builder_rhs_array_muxed2 <= main_sdram_bankmachine7_cmd_payload_ba;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed3 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine0_cmd_payload_is_read;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine1_cmd_payload_is_read;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine2_cmd_payload_is_read;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine3_cmd_payload_is_read;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine4_cmd_payload_is_read;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine5_cmd_payload_is_read;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine6_cmd_payload_is_read;
+      end
+      default: begin
+        builder_rhs_array_muxed3 <= main_sdram_bankmachine7_cmd_payload_is_read;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed4 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine0_cmd_payload_is_write;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine1_cmd_payload_is_write;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine2_cmd_payload_is_write;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine3_cmd_payload_is_write;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine4_cmd_payload_is_write;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine5_cmd_payload_is_write;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine6_cmd_payload_is_write;
+      end
+      default: begin
+        builder_rhs_array_muxed4 <= main_sdram_bankmachine7_cmd_payload_is_write;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed5 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine0_cmd_payload_is_cmd;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine1_cmd_payload_is_cmd;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine2_cmd_payload_is_cmd;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine3_cmd_payload_is_cmd;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine4_cmd_payload_is_cmd;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine5_cmd_payload_is_cmd;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine6_cmd_payload_is_cmd;
+      end
+      default: begin
+        builder_rhs_array_muxed5 <= main_sdram_bankmachine7_cmd_payload_is_cmd;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed0 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine0_cmd_payload_cas;
+      end
+      1'd1: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine1_cmd_payload_cas;
+      end
+      2'd2: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine2_cmd_payload_cas;
+      end
+      2'd3: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine3_cmd_payload_cas;
+      end
+      3'd4: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine4_cmd_payload_cas;
+      end
+      3'd5: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine5_cmd_payload_cas;
+      end
+      3'd6: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine6_cmd_payload_cas;
+      end
+      default: begin
+        builder_t_array_muxed0 <= main_sdram_bankmachine7_cmd_payload_cas;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed1 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine0_cmd_payload_ras;
+      end
+      1'd1: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine1_cmd_payload_ras;
+      end
+      2'd2: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine2_cmd_payload_ras;
+      end
+      2'd3: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine3_cmd_payload_ras;
+      end
+      3'd4: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine4_cmd_payload_ras;
+      end
+      3'd5: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine5_cmd_payload_ras;
+      end
+      3'd6: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine6_cmd_payload_ras;
+      end
+      default: begin
+        builder_t_array_muxed1 <= main_sdram_bankmachine7_cmd_payload_ras;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed2 <= 1'd0;
+    case (main_sdram_choose_cmd_grant)
+      1'd0: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine0_cmd_payload_we;
+      end
+      1'd1: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine1_cmd_payload_we;
+      end
+      2'd2: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine2_cmd_payload_we;
+      end
+      2'd3: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine3_cmd_payload_we;
+      end
+      3'd4: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine4_cmd_payload_we;
+      end
+      3'd5: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine5_cmd_payload_we;
+      end
+      3'd6: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine6_cmd_payload_we;
+      end
+      default: begin
+        builder_t_array_muxed2 <= main_sdram_bankmachine7_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed6 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[0];
+      end
+      1'd1: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[1];
+      end
+      2'd2: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[2];
+      end
+      2'd3: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[3];
+      end
+      3'd4: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[4];
+      end
+      3'd5: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[5];
+      end
+      3'd6: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[6];
+      end
+      default: begin
+        builder_rhs_array_muxed6 <= main_sdram_choose_req_valids[7];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed7 <= 14'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine0_cmd_payload_a;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine1_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine2_cmd_payload_a;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine3_cmd_payload_a;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine4_cmd_payload_a;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine5_cmd_payload_a;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine6_cmd_payload_a;
+      end
+      default: begin
+        builder_rhs_array_muxed7 <= main_sdram_bankmachine7_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed8 <= 3'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine0_cmd_payload_ba;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine1_cmd_payload_ba;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine2_cmd_payload_ba;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine3_cmd_payload_ba;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine4_cmd_payload_ba;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine5_cmd_payload_ba;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine6_cmd_payload_ba;
+      end
+      default: begin
+        builder_rhs_array_muxed8 <= main_sdram_bankmachine7_cmd_payload_ba;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed9 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine0_cmd_payload_is_read;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine1_cmd_payload_is_read;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine2_cmd_payload_is_read;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine3_cmd_payload_is_read;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine4_cmd_payload_is_read;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine5_cmd_payload_is_read;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine6_cmd_payload_is_read;
+      end
+      default: begin
+        builder_rhs_array_muxed9 <= main_sdram_bankmachine7_cmd_payload_is_read;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed10 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine0_cmd_payload_is_write;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine1_cmd_payload_is_write;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine2_cmd_payload_is_write;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine3_cmd_payload_is_write;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine4_cmd_payload_is_write;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine5_cmd_payload_is_write;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine6_cmd_payload_is_write;
+      end
+      default: begin
+        builder_rhs_array_muxed10 <= main_sdram_bankmachine7_cmd_payload_is_write;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed11 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine0_cmd_payload_is_cmd;
+      end
+      1'd1: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine1_cmd_payload_is_cmd;
+      end
+      2'd2: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine2_cmd_payload_is_cmd;
+      end
+      2'd3: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine3_cmd_payload_is_cmd;
+      end
+      3'd4: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine4_cmd_payload_is_cmd;
+      end
+      3'd5: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine5_cmd_payload_is_cmd;
+      end
+      3'd6: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine6_cmd_payload_is_cmd;
+      end
+      default: begin
+        builder_rhs_array_muxed11 <= main_sdram_bankmachine7_cmd_payload_is_cmd;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed3 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine0_cmd_payload_cas;
+      end
+      1'd1: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine1_cmd_payload_cas;
+      end
+      2'd2: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine2_cmd_payload_cas;
+      end
+      2'd3: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine3_cmd_payload_cas;
+      end
+      3'd4: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine4_cmd_payload_cas;
+      end
+      3'd5: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine5_cmd_payload_cas;
+      end
+      3'd6: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine6_cmd_payload_cas;
+      end
+      default: begin
+        builder_t_array_muxed3 <= main_sdram_bankmachine7_cmd_payload_cas;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed4 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine0_cmd_payload_ras;
+      end
+      1'd1: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine1_cmd_payload_ras;
+      end
+      2'd2: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine2_cmd_payload_ras;
+      end
+      2'd3: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine3_cmd_payload_ras;
+      end
+      3'd4: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine4_cmd_payload_ras;
+      end
+      3'd5: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine5_cmd_payload_ras;
+      end
+      3'd6: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine6_cmd_payload_ras;
+      end
+      default: begin
+        builder_t_array_muxed4 <= main_sdram_bankmachine7_cmd_payload_ras;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_t_array_muxed5 <= 1'd0;
+    case (main_sdram_choose_req_grant)
+      1'd0: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine0_cmd_payload_we;
+      end
+      1'd1: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine1_cmd_payload_we;
+      end
+      2'd2: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine2_cmd_payload_we;
+      end
+      2'd3: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine3_cmd_payload_we;
+      end
+      3'd4: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine4_cmd_payload_we;
+      end
+      3'd5: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine5_cmd_payload_we;
+      end
+      3'd6: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine6_cmd_payload_we;
+      end
+      default: begin
+        builder_t_array_muxed5 <= main_sdram_bankmachine7_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed12 <= 21'd0;
+    case (builder_roundrobin0_grant)
+      default: begin
+        builder_rhs_array_muxed12 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed13 <= 1'd0;
+    case (builder_roundrobin0_grant)
+      default: begin
+        builder_rhs_array_muxed13 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed14 <= 1'd0;
+    case (builder_roundrobin0_grant)
+      default: begin
+        builder_rhs_array_muxed14 <= (((main_port_cmd_payload_addr[9:7] == 1'd0) & (~(((((((builder_locked0 | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed15 <= 21'd0;
+    case (builder_roundrobin1_grant)
+      default: begin
+        builder_rhs_array_muxed15 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed16 <= 1'd0;
+    case (builder_roundrobin1_grant)
+      default: begin
+        builder_rhs_array_muxed16 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed17 <= 1'd0;
+    case (builder_roundrobin1_grant)
+      default: begin
+        builder_rhs_array_muxed17 <= (((main_port_cmd_payload_addr[9:7] == 1'd1) & (~(((((((builder_locked1 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed18 <= 21'd0;
+    case (builder_roundrobin2_grant)
+      default: begin
+        builder_rhs_array_muxed18 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed19 <= 1'd0;
+    case (builder_roundrobin2_grant)
+      default: begin
+        builder_rhs_array_muxed19 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed20 <= 1'd0;
+    case (builder_roundrobin2_grant)
+      default: begin
+        builder_rhs_array_muxed20 <= (((main_port_cmd_payload_addr[9:7] == 2'd2) & (~(((((((builder_locked2 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed21 <= 21'd0;
+    case (builder_roundrobin3_grant)
+      default: begin
+        builder_rhs_array_muxed21 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed22 <= 1'd0;
+    case (builder_roundrobin3_grant)
+      default: begin
+        builder_rhs_array_muxed22 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed23 <= 1'd0;
+    case (builder_roundrobin3_grant)
+      default: begin
+        builder_rhs_array_muxed23 <= (((main_port_cmd_payload_addr[9:7] == 2'd3) & (~(((((((builder_locked3 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed24 <= 21'd0;
+    case (builder_roundrobin4_grant)
+      default: begin
+        builder_rhs_array_muxed24 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed25 <= 1'd0;
+    case (builder_roundrobin4_grant)
+      default: begin
+        builder_rhs_array_muxed25 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed26 <= 1'd0;
+    case (builder_roundrobin4_grant)
+      default: begin
+        builder_rhs_array_muxed26 <= (((main_port_cmd_payload_addr[9:7] == 3'd4) & (~(((((((builder_locked4 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed27 <= 21'd0;
+    case (builder_roundrobin5_grant)
+      default: begin
+        builder_rhs_array_muxed27 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed28 <= 1'd0;
+    case (builder_roundrobin5_grant)
+      default: begin
+        builder_rhs_array_muxed28 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed29 <= 1'd0;
+    case (builder_roundrobin5_grant)
+      default: begin
+        builder_rhs_array_muxed29 <= (((main_port_cmd_payload_addr[9:7] == 3'd5) & (~(((((((builder_locked5 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed30 <= 21'd0;
+    case (builder_roundrobin6_grant)
+      default: begin
+        builder_rhs_array_muxed30 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed31 <= 1'd0;
+    case (builder_roundrobin6_grant)
+      default: begin
+        builder_rhs_array_muxed31 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed32 <= 1'd0;
+    case (builder_roundrobin6_grant)
+      default: begin
+        builder_rhs_array_muxed32 <= (((main_port_cmd_payload_addr[9:7] == 3'd6) & (~(((((((builder_locked6 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank7_lock & (builder_roundrobin7_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed33 <= 21'd0;
+    case (builder_roundrobin7_grant)
+      default: begin
+        builder_rhs_array_muxed33 <= {
+          main_port_cmd_payload_addr[23:10], main_port_cmd_payload_addr[6:0]
+        };
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed34 <= 1'd0;
+    case (builder_roundrobin7_grant)
+      default: begin
+        builder_rhs_array_muxed34 <= main_port_cmd_payload_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed35 <= 1'd0;
+    case (builder_roundrobin7_grant)
+      default: begin
+        builder_rhs_array_muxed35 <= (((main_port_cmd_payload_addr[9:7] == 3'd7) & (~(((((((builder_locked7 | (main_sdram_interface_bank0_lock & (builder_roundrobin0_grant == 1'd0))) | (main_sdram_interface_bank1_lock & (builder_roundrobin1_grant == 1'd0))) | (main_sdram_interface_bank2_lock & (builder_roundrobin2_grant == 1'd0))) | (main_sdram_interface_bank3_lock & (builder_roundrobin3_grant == 1'd0))) | (main_sdram_interface_bank4_lock & (builder_roundrobin4_grant == 1'd0))) | (main_sdram_interface_bank5_lock & (builder_roundrobin5_grant == 1'd0))) | (main_sdram_interface_bank6_lock & (builder_roundrobin6_grant == 1'd0))))) & main_port_cmd_valid);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed36 <= 30'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed36 <= main_interface1_wb_sdram_adr;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed37 <= 32'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed37 <= main_interface1_wb_sdram_dat_w;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed38 <= 4'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed38 <= main_interface1_wb_sdram_sel;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed39 <= 1'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed39 <= main_interface1_wb_sdram_cyc;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed40 <= 1'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed40 <= main_interface1_wb_sdram_stb;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed41 <= 1'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed41 <= main_interface1_wb_sdram_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed42 <= 3'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed42 <= main_interface1_wb_sdram_cti;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed43 <= 2'd0;
+    case (builder_wb_sdram_con_grant)
+      default: begin
+        builder_rhs_array_muxed43 <= main_interface1_wb_sdram_bte;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed44 <= 30'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed44 <= main_minsoc_interface0_soc_bus_adr;
+      end
+      default: begin
+        builder_rhs_array_muxed44 <= main_minsoc_interface1_soc_bus_adr;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed45 <= 32'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed45 <= main_minsoc_interface0_soc_bus_dat_w;
+      end
+      default: begin
+        builder_rhs_array_muxed45 <= main_minsoc_interface1_soc_bus_dat_w;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed46 <= 4'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed46 <= main_minsoc_interface0_soc_bus_sel;
+      end
+      default: begin
+        builder_rhs_array_muxed46 <= main_minsoc_interface1_soc_bus_sel;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed47 <= 1'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed47 <= main_minsoc_interface0_soc_bus_cyc;
+      end
+      default: begin
+        builder_rhs_array_muxed47 <= main_minsoc_interface1_soc_bus_cyc;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed48 <= 1'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed48 <= main_minsoc_interface0_soc_bus_stb;
+      end
+      default: begin
+        builder_rhs_array_muxed48 <= main_minsoc_interface1_soc_bus_stb;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed49 <= 1'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed49 <= main_minsoc_interface0_soc_bus_we;
+      end
+      default: begin
+        builder_rhs_array_muxed49 <= main_minsoc_interface1_soc_bus_we;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed50 <= 3'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed50 <= main_minsoc_interface0_soc_bus_cti;
+      end
+      default: begin
+        builder_rhs_array_muxed50 <= main_minsoc_interface1_soc_bus_cti;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_rhs_array_muxed51 <= 2'd0;
+    case (builder_minsoc_grant)
+      1'd0: begin
+        builder_rhs_array_muxed51 <= main_minsoc_interface0_soc_bus_bte;
+      end
+      default: begin
+        builder_rhs_array_muxed51 <= main_minsoc_interface1_soc_bus_bte;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed0 <= 3'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed0 <= main_sdram_nop_ba[2:0];
+      end
+      1'd1: begin
+        builder_array_muxed0 <= main_sdram_choose_cmd_cmd_payload_ba[2:0];
+      end
+      2'd2: begin
+        builder_array_muxed0 <= main_sdram_choose_req_cmd_payload_ba[2:0];
+      end
+      default: begin
+        builder_array_muxed0 <= main_sdram_cmd_payload_ba[2:0];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed1 <= 14'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed1 <= main_sdram_nop_a;
+      end
+      1'd1: begin
+        builder_array_muxed1 <= main_sdram_choose_cmd_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_array_muxed1 <= main_sdram_choose_req_cmd_payload_a;
+      end
+      default: begin
+        builder_array_muxed1 <= main_sdram_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed2 <= 1'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed2 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed2 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_cas);
+      end
+      2'd2: begin
+        builder_array_muxed2 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_cas);
+      end
+      default: begin
+        builder_array_muxed2 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_cas);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed3 <= 1'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed3 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed3 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_ras);
+      end
+      2'd2: begin
+        builder_array_muxed3 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_ras);
+      end
+      default: begin
+        builder_array_muxed3 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_ras);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed4 <= 1'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed4 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed4 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_we);
+      end
+      2'd2: begin
+        builder_array_muxed4 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_we);
+      end
+      default: begin
+        builder_array_muxed4 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_we);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed5 <= 1'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed5 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed5 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_read);
+      end
+      2'd2: begin
+        builder_array_muxed5 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_read);
+      end
+      default: begin
+        builder_array_muxed5 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_read);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed6 <= 1'd0;
+    case (main_sdram_steerer_sel0)
+      1'd0: begin
+        builder_array_muxed6 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed6 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_write);
+      end
+      2'd2: begin
+        builder_array_muxed6 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_write);
+      end
+      default: begin
+        builder_array_muxed6 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_write);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed7 <= 3'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed7 <= main_sdram_nop_ba[2:0];
+      end
+      1'd1: begin
+        builder_array_muxed7 <= main_sdram_choose_cmd_cmd_payload_ba[2:0];
+      end
+      2'd2: begin
+        builder_array_muxed7 <= main_sdram_choose_req_cmd_payload_ba[2:0];
+      end
+      default: begin
+        builder_array_muxed7 <= main_sdram_cmd_payload_ba[2:0];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed8 <= 14'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed8 <= main_sdram_nop_a;
+      end
+      1'd1: begin
+        builder_array_muxed8 <= main_sdram_choose_cmd_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_array_muxed8 <= main_sdram_choose_req_cmd_payload_a;
+      end
+      default: begin
+        builder_array_muxed8 <= main_sdram_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed9 <= 1'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed9 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed9 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_cas);
+      end
+      2'd2: begin
+        builder_array_muxed9 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_cas);
+      end
+      default: begin
+        builder_array_muxed9 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_cas);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed10 <= 1'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed10 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed10 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_ras);
+      end
+      2'd2: begin
+        builder_array_muxed10 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_ras);
+      end
+      default: begin
+        builder_array_muxed10 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_ras);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed11 <= 1'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed11 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed11 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_we);
+      end
+      2'd2: begin
+        builder_array_muxed11 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_we);
+      end
+      default: begin
+        builder_array_muxed11 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_we);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed12 <= 1'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed12 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed12 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_read);
+      end
+      2'd2: begin
+        builder_array_muxed12 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_read);
+      end
+      default: begin
+        builder_array_muxed12 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_read);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed13 <= 1'd0;
+    case (main_sdram_steerer_sel1)
+      1'd0: begin
+        builder_array_muxed13 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed13 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_write);
+      end
+      2'd2: begin
+        builder_array_muxed13 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_write);
+      end
+      default: begin
+        builder_array_muxed13 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_write);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed14 <= 3'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed14 <= main_sdram_nop_ba[2:0];
+      end
+      1'd1: begin
+        builder_array_muxed14 <= main_sdram_choose_cmd_cmd_payload_ba[2:0];
+      end
+      2'd2: begin
+        builder_array_muxed14 <= main_sdram_choose_req_cmd_payload_ba[2:0];
+      end
+      default: begin
+        builder_array_muxed14 <= main_sdram_cmd_payload_ba[2:0];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed15 <= 14'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed15 <= main_sdram_nop_a;
+      end
+      1'd1: begin
+        builder_array_muxed15 <= main_sdram_choose_cmd_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_array_muxed15 <= main_sdram_choose_req_cmd_payload_a;
+      end
+      default: begin
+        builder_array_muxed15 <= main_sdram_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed16 <= 1'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed16 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed16 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_cas);
+      end
+      2'd2: begin
+        builder_array_muxed16 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_cas);
+      end
+      default: begin
+        builder_array_muxed16 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_cas);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed17 <= 1'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed17 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed17 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_ras);
+      end
+      2'd2: begin
+        builder_array_muxed17 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_ras);
+      end
+      default: begin
+        builder_array_muxed17 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_ras);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed18 <= 1'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed18 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed18 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_we);
+      end
+      2'd2: begin
+        builder_array_muxed18 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_we);
+      end
+      default: begin
+        builder_array_muxed18 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_we);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed19 <= 1'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed19 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed19 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_read);
+      end
+      2'd2: begin
+        builder_array_muxed19 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_read);
+      end
+      default: begin
+        builder_array_muxed19 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_read);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed20 <= 1'd0;
+    case (main_sdram_steerer_sel2)
+      1'd0: begin
+        builder_array_muxed20 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed20 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_write);
+      end
+      2'd2: begin
+        builder_array_muxed20 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_write);
+      end
+      default: begin
+        builder_array_muxed20 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_write);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed21 <= 3'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed21 <= main_sdram_nop_ba[2:0];
+      end
+      1'd1: begin
+        builder_array_muxed21 <= main_sdram_choose_cmd_cmd_payload_ba[2:0];
+      end
+      2'd2: begin
+        builder_array_muxed21 <= main_sdram_choose_req_cmd_payload_ba[2:0];
+      end
+      default: begin
+        builder_array_muxed21 <= main_sdram_cmd_payload_ba[2:0];
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed22 <= 14'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed22 <= main_sdram_nop_a;
+      end
+      1'd1: begin
+        builder_array_muxed22 <= main_sdram_choose_cmd_cmd_payload_a;
+      end
+      2'd2: begin
+        builder_array_muxed22 <= main_sdram_choose_req_cmd_payload_a;
+      end
+      default: begin
+        builder_array_muxed22 <= main_sdram_cmd_payload_a;
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed23 <= 1'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed23 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed23 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_cas);
+      end
+      2'd2: begin
+        builder_array_muxed23 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_cas);
+      end
+      default: begin
+        builder_array_muxed23 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_cas);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed24 <= 1'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed24 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed24 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_ras);
+      end
+      2'd2: begin
+        builder_array_muxed24 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_ras);
+      end
+      default: begin
+        builder_array_muxed24 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_ras);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed25 <= 1'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed25 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed25 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_we);
+      end
+      2'd2: begin
+        builder_array_muxed25 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_we);
+      end
+      default: begin
+        builder_array_muxed25 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_we);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed26 <= 1'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed26 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed26 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_read);
+      end
+      2'd2: begin
+        builder_array_muxed26 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_read);
+      end
+      default: begin
+        builder_array_muxed26 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_read);
+      end
+    endcase
+  end
+  always @(*) begin
+    builder_array_muxed27 <= 1'd0;
+    case (main_sdram_steerer_sel3)
+      1'd0: begin
+        builder_array_muxed27 <= 1'd0;
+      end
+      1'd1: begin
+        builder_array_muxed27 <= ((main_sdram_choose_cmd_cmd_valid & main_sdram_choose_cmd_cmd_ready) & main_sdram_choose_cmd_cmd_payload_is_write);
+      end
+      2'd2: begin
+        builder_array_muxed27 <= ((main_sdram_choose_req_cmd_valid & main_sdram_choose_req_cmd_ready) & main_sdram_choose_req_cmd_payload_is_write);
+      end
+      default: begin
+        builder_array_muxed27 <= ((main_sdram_cmd_valid & main_sdram_cmd_ready) & main_sdram_cmd_payload_is_write);
+      end
+    endcase
+  end
+  assign main_minsoc_rx = builder_regs1;
+  assign builder_xilinxasyncresetsynchronizerimpl0 = ((~main_locked) | main_reset);
+  assign builder_xilinxasyncresetsynchronizerimpl1 = ((~main_locked) | main_reset);
+  assign builder_xilinxasyncresetsynchronizerimpl2 = ((~main_locked) | main_reset);
+  assign builder_xilinxasyncresetsynchronizerimpl3 = ((~main_locked) | main_reset);
+
+  always @(posedge clk200_clk) begin
+    if ((main_reset_counter != 1'd0)) begin
+      main_reset_counter <= (main_reset_counter - 1'd1);
+    end else begin
+      main_ic_reset <= 1'd0;
+    end
+    if (clk200_rst) begin
+      main_reset_counter <= 4'd15;
+      main_ic_reset <= 1'd1;
+    end
+  end
+
+  always @(posedge sys_clk) begin
+    if ((main_minsoc_ctrl_bus_errors != 32'd4294967295)) begin
+      if (main_minsoc_ctrl_bus_error) begin
+        main_minsoc_ctrl_bus_errors <= (main_minsoc_ctrl_bus_errors + 1'd1);
+      end
+    end
+    main_minsoc_rom_bus_ack <= 1'd0;
+    if (((main_minsoc_rom_bus_cyc & main_minsoc_rom_bus_stb) & (~main_minsoc_rom_bus_ack))) begin
+      main_minsoc_rom_bus_ack <= 1'd1;
+    end
+    main_minsoc_sram_bus_ack <= 1'd0;
+    if (((main_minsoc_sram_bus_cyc & main_minsoc_sram_bus_stb) & (~main_minsoc_sram_bus_ack))) begin
+      main_minsoc_sram_bus_ack <= 1'd1;
+    end
+    main_minsoc_sink_ready <= 1'd0;
+    if (((main_minsoc_sink_valid & (~main_minsoc_tx_busy)) & (~main_minsoc_sink_ready))) begin
+      main_minsoc_tx_reg <= main_minsoc_sink_payload_data;
+      main_minsoc_tx_bitcount <= 1'd0;
+      main_minsoc_tx_busy <= 1'd1;
+      serial_tx <= 1'd0;
+    end else begin
+      if ((main_minsoc_uart_clk_txen & main_minsoc_tx_busy)) begin
+        main_minsoc_tx_bitcount <= (main_minsoc_tx_bitcount + 1'd1);
+        if ((main_minsoc_tx_bitcount == 4'd8)) begin
+          serial_tx <= 1'd1;
+        end else begin
+          if ((main_minsoc_tx_bitcount == 4'd9)) begin
+            serial_tx <= 1'd1;
+            main_minsoc_tx_busy <= 1'd0;
+            main_minsoc_sink_ready <= 1'd1;
+          end else begin
+            serial_tx <= main_minsoc_tx_reg[0];
+            main_minsoc_tx_reg <= {1'd0, main_minsoc_tx_reg[7:1]};
+          end
+        end
+      end
+    end
+    if (main_minsoc_tx_busy) begin
+      {main_minsoc_uart_clk_txen, main_minsoc_phase_accumulator_tx} <= (main_minsoc_phase_accumulator_tx + main_minsoc_storage);
+    end else begin
+      {main_minsoc_uart_clk_txen, main_minsoc_phase_accumulator_tx} <= 1'd0;
+    end
+    main_minsoc_source_valid <= 1'd0;
+    main_minsoc_rx_r <= main_minsoc_rx;
+    if ((~main_minsoc_rx_busy)) begin
+      if (((~main_minsoc_rx) & main_minsoc_rx_r)) begin
+        main_minsoc_rx_busy <= 1'd1;
+        main_minsoc_rx_bitcount <= 1'd0;
+      end
+    end else begin
+      if (main_minsoc_uart_clk_rxen) begin
+        main_minsoc_rx_bitcount <= (main_minsoc_rx_bitcount + 1'd1);
+        if ((main_minsoc_rx_bitcount == 1'd0)) begin
+          if (main_minsoc_rx) begin
+            main_minsoc_rx_busy <= 1'd0;
+          end
+        end else begin
+          if ((main_minsoc_rx_bitcount == 4'd9)) begin
+            main_minsoc_rx_busy <= 1'd0;
+            if (main_minsoc_rx) begin
+              main_minsoc_source_payload_data <= main_minsoc_rx_reg;
+              main_minsoc_source_valid <= 1'd1;
+            end
+          end else begin
+            main_minsoc_rx_reg <= {main_minsoc_rx, main_minsoc_rx_reg[7:1]};
+          end
+        end
+      end
+    end
+    if (main_minsoc_rx_busy) begin
+      {main_minsoc_uart_clk_rxen, main_minsoc_phase_accumulator_rx} <= (main_minsoc_phase_accumulator_rx + main_minsoc_storage);
+    end else begin
+      {main_minsoc_uart_clk_rxen, main_minsoc_phase_accumulator_rx} <= 32'd2147483648;
+    end
+    if (main_minsoc_uart_tx_clear) begin
+      main_minsoc_uart_tx_pending <= 1'd0;
+    end
+    main_minsoc_uart_tx_old_trigger <= main_minsoc_uart_tx_trigger;
+    if (((~main_minsoc_uart_tx_trigger) & main_minsoc_uart_tx_old_trigger)) begin
+      main_minsoc_uart_tx_pending <= 1'd1;
+    end
+    if (main_minsoc_uart_rx_clear) begin
+      main_minsoc_uart_rx_pending <= 1'd0;
+    end
+    main_minsoc_uart_rx_old_trigger <= main_minsoc_uart_rx_trigger;
+    if (((~main_minsoc_uart_rx_trigger) & main_minsoc_uart_rx_old_trigger)) begin
+      main_minsoc_uart_rx_pending <= 1'd1;
+    end
+    if (main_minsoc_uart_tx_fifo_syncfifo_re) begin
+      main_minsoc_uart_tx_fifo_readable <= 1'd1;
+    end else begin
+      if (main_minsoc_uart_tx_fifo_re) begin
+        main_minsoc_uart_tx_fifo_readable <= 1'd0;
+      end
+    end
+    if (((main_minsoc_uart_tx_fifo_syncfifo_we & main_minsoc_uart_tx_fifo_syncfifo_writable) & (~main_minsoc_uart_tx_fifo_replace))) begin
+      main_minsoc_uart_tx_fifo_produce <= (main_minsoc_uart_tx_fifo_produce + 1'd1);
+    end
+    if (main_minsoc_uart_tx_fifo_do_read) begin
+      main_minsoc_uart_tx_fifo_consume <= (main_minsoc_uart_tx_fifo_consume + 1'd1);
+    end
+    if (((main_minsoc_uart_tx_fifo_syncfifo_we & main_minsoc_uart_tx_fifo_syncfifo_writable) & (~main_minsoc_uart_tx_fifo_replace))) begin
+      if ((~main_minsoc_uart_tx_fifo_do_read)) begin
+        main_minsoc_uart_tx_fifo_level0 <= (main_minsoc_uart_tx_fifo_level0 + 1'd1);
+      end
+    end else begin
+      if (main_minsoc_uart_tx_fifo_do_read) begin
+        main_minsoc_uart_tx_fifo_level0 <= (main_minsoc_uart_tx_fifo_level0 - 1'd1);
+      end
+    end
+    if (main_minsoc_uart_rx_fifo_syncfifo_re) begin
+      main_minsoc_uart_rx_fifo_readable <= 1'd1;
+    end else begin
+      if (main_minsoc_uart_rx_fifo_re) begin
+        main_minsoc_uart_rx_fifo_readable <= 1'd0;
+      end
+    end
+    if (((main_minsoc_uart_rx_fifo_syncfifo_we & main_minsoc_uart_rx_fifo_syncfifo_writable) & (~main_minsoc_uart_rx_fifo_replace))) begin
+      main_minsoc_uart_rx_fifo_produce <= (main_minsoc_uart_rx_fifo_produce + 1'd1);
+    end
+    if (main_minsoc_uart_rx_fifo_do_read) begin
+      main_minsoc_uart_rx_fifo_consume <= (main_minsoc_uart_rx_fifo_consume + 1'd1);
+    end
+    if (((main_minsoc_uart_rx_fifo_syncfifo_we & main_minsoc_uart_rx_fifo_syncfifo_writable) & (~main_minsoc_uart_rx_fifo_replace))) begin
+      if ((~main_minsoc_uart_rx_fifo_do_read)) begin
+        main_minsoc_uart_rx_fifo_level0 <= (main_minsoc_uart_rx_fifo_level0 + 1'd1);
+      end
+    end else begin
+      if (main_minsoc_uart_rx_fifo_do_read) begin
+        main_minsoc_uart_rx_fifo_level0 <= (main_minsoc_uart_rx_fifo_level0 - 1'd1);
+      end
+    end
+    if (main_minsoc_uart_reset) begin
+      main_minsoc_uart_tx_pending <= 1'd0;
+      main_minsoc_uart_tx_old_trigger <= 1'd0;
+      main_minsoc_uart_rx_pending <= 1'd0;
+      main_minsoc_uart_rx_old_trigger <= 1'd0;
+      main_minsoc_uart_tx_fifo_readable <= 1'd0;
+      main_minsoc_uart_tx_fifo_level0 <= 5'd0;
+      main_minsoc_uart_tx_fifo_produce <= 4'd0;
+      main_minsoc_uart_tx_fifo_consume <= 4'd0;
+      main_minsoc_uart_rx_fifo_readable <= 1'd0;
+      main_minsoc_uart_rx_fifo_level0 <= 5'd0;
+      main_minsoc_uart_rx_fifo_produce <= 4'd0;
+      main_minsoc_uart_rx_fifo_consume <= 4'd0;
+    end
+    if (main_minsoc_timer0_en_storage) begin
+      if ((main_minsoc_timer0_value == 1'd0)) begin
+        main_minsoc_timer0_value <= main_minsoc_timer0_reload_storage;
+      end else begin
+        main_minsoc_timer0_value <= (main_minsoc_timer0_value - 1'd1);
+      end
+    end else begin
+      main_minsoc_timer0_value <= main_minsoc_timer0_load_storage;
+    end
+    if (main_minsoc_timer0_update_value_re) begin
+      main_minsoc_timer0_value_status <= main_minsoc_timer0_value;
+    end
+    if (main_minsoc_timer0_zero_clear) begin
+      main_minsoc_timer0_zero_pending <= 1'd0;
+    end
+    main_minsoc_timer0_zero_old_trigger <= main_minsoc_timer0_zero_trigger;
+    if (((~main_minsoc_timer0_zero_trigger) & main_minsoc_timer0_zero_old_trigger)) begin
+      main_minsoc_timer0_zero_pending <= 1'd1;
+    end
+    builder_wb2csr_state <= builder_wb2csr_next_state;
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip0_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip0_value <= (main_a7ddrphy_bitslip0_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip1_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip1_value <= (main_a7ddrphy_bitslip1_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip2_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip2_value <= (main_a7ddrphy_bitslip2_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip3_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip3_value <= (main_a7ddrphy_bitslip3_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip4_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip4_value <= (main_a7ddrphy_bitslip4_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip5_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip5_value <= (main_a7ddrphy_bitslip5_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip6_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip6_value <= (main_a7ddrphy_bitslip6_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[0]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip7_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip7_value <= (main_a7ddrphy_bitslip7_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip8_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip8_value <= (main_a7ddrphy_bitslip8_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip9_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip9_value <= (main_a7ddrphy_bitslip9_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip10_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip10_value <= (main_a7ddrphy_bitslip10_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip11_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip11_value <= (main_a7ddrphy_bitslip11_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip12_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip12_value <= (main_a7ddrphy_bitslip12_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip13_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip13_value <= (main_a7ddrphy_bitslip13_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip14_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip14_value <= (main_a7ddrphy_bitslip14_value + 1'd1);
+        end
+      end
+    end
+    if (main_a7ddrphy_dly_sel_storage[1]) begin
+      if (main_a7ddrphy_rdly_dq_bitslip_rst_re) begin
+        main_a7ddrphy_bitslip15_value <= 1'd0;
+      end else begin
+        if (main_a7ddrphy_rdly_dq_bitslip_re) begin
+          main_a7ddrphy_bitslip15_value <= (main_a7ddrphy_bitslip15_value + 1'd1);
+        end
+      end
+    end
+    main_a7ddrphy_n_rddata_en0 <= main_a7ddrphy_dfi_p2_rddata_en;
+    main_a7ddrphy_n_rddata_en1 <= main_a7ddrphy_n_rddata_en0;
+    main_a7ddrphy_n_rddata_en2 <= main_a7ddrphy_n_rddata_en1;
+    main_a7ddrphy_n_rddata_en3 <= main_a7ddrphy_n_rddata_en2;
+    main_a7ddrphy_n_rddata_en4 <= main_a7ddrphy_n_rddata_en3;
+    main_a7ddrphy_n_rddata_en5 <= main_a7ddrphy_n_rddata_en4;
+    main_a7ddrphy_n_rddata_en6 <= main_a7ddrphy_n_rddata_en5;
+    main_a7ddrphy_n_rddata_en7 <= main_a7ddrphy_n_rddata_en6;
+    main_a7ddrphy_dfi_p0_rddata_valid <= main_a7ddrphy_n_rddata_en7;
+    main_a7ddrphy_dfi_p1_rddata_valid <= main_a7ddrphy_n_rddata_en7;
+    main_a7ddrphy_dfi_p2_rddata_valid <= main_a7ddrphy_n_rddata_en7;
+    main_a7ddrphy_dfi_p3_rddata_valid <= main_a7ddrphy_n_rddata_en7;
+    main_a7ddrphy_last_wrdata_en <= {
+      main_a7ddrphy_last_wrdata_en[2:0], main_a7ddrphy_dfi_p3_wrdata_en
+    };
+    main_a7ddrphy_oe_dqs <= main_a7ddrphy_oe;
+    main_a7ddrphy_oe_dq <= main_a7ddrphy_oe;
+    main_a7ddrphy_bitslip0_r <= {main_a7ddrphy_bitslip0_i, main_a7ddrphy_bitslip0_r[15:8]};
+    case (main_a7ddrphy_bitslip0_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip0_o <= main_a7ddrphy_bitslip0_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip1_r <= {main_a7ddrphy_bitslip1_i, main_a7ddrphy_bitslip1_r[15:8]};
+    case (main_a7ddrphy_bitslip1_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip1_o <= main_a7ddrphy_bitslip1_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip2_r <= {main_a7ddrphy_bitslip2_i, main_a7ddrphy_bitslip2_r[15:8]};
+    case (main_a7ddrphy_bitslip2_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip2_o <= main_a7ddrphy_bitslip2_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip3_r <= {main_a7ddrphy_bitslip3_i, main_a7ddrphy_bitslip3_r[15:8]};
+    case (main_a7ddrphy_bitslip3_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip3_o <= main_a7ddrphy_bitslip3_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip4_r <= {main_a7ddrphy_bitslip4_i, main_a7ddrphy_bitslip4_r[15:8]};
+    case (main_a7ddrphy_bitslip4_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip4_o <= main_a7ddrphy_bitslip4_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip5_r <= {main_a7ddrphy_bitslip5_i, main_a7ddrphy_bitslip5_r[15:8]};
+    case (main_a7ddrphy_bitslip5_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip5_o <= main_a7ddrphy_bitslip5_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip6_r <= {main_a7ddrphy_bitslip6_i, main_a7ddrphy_bitslip6_r[15:8]};
+    case (main_a7ddrphy_bitslip6_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip6_o <= main_a7ddrphy_bitslip6_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip7_r <= {main_a7ddrphy_bitslip7_i, main_a7ddrphy_bitslip7_r[15:8]};
+    case (main_a7ddrphy_bitslip7_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip7_o <= main_a7ddrphy_bitslip7_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip8_r <= {main_a7ddrphy_bitslip8_i, main_a7ddrphy_bitslip8_r[15:8]};
+    case (main_a7ddrphy_bitslip8_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip8_o <= main_a7ddrphy_bitslip8_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip9_r <= {main_a7ddrphy_bitslip9_i, main_a7ddrphy_bitslip9_r[15:8]};
+    case (main_a7ddrphy_bitslip9_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip9_o <= main_a7ddrphy_bitslip9_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip10_r <= {main_a7ddrphy_bitslip10_i, main_a7ddrphy_bitslip10_r[15:8]};
+    case (main_a7ddrphy_bitslip10_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip10_o <= main_a7ddrphy_bitslip10_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip11_r <= {main_a7ddrphy_bitslip11_i, main_a7ddrphy_bitslip11_r[15:8]};
+    case (main_a7ddrphy_bitslip11_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip11_o <= main_a7ddrphy_bitslip11_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip12_r <= {main_a7ddrphy_bitslip12_i, main_a7ddrphy_bitslip12_r[15:8]};
+    case (main_a7ddrphy_bitslip12_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip12_o <= main_a7ddrphy_bitslip12_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip13_r <= {main_a7ddrphy_bitslip13_i, main_a7ddrphy_bitslip13_r[15:8]};
+    case (main_a7ddrphy_bitslip13_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip13_o <= main_a7ddrphy_bitslip13_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip14_r <= {main_a7ddrphy_bitslip14_i, main_a7ddrphy_bitslip14_r[15:8]};
+    case (main_a7ddrphy_bitslip14_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip14_o <= main_a7ddrphy_bitslip14_r[14:7];
+      end
+    endcase
+    main_a7ddrphy_bitslip15_r <= {main_a7ddrphy_bitslip15_i, main_a7ddrphy_bitslip15_r[15:8]};
+    case (main_a7ddrphy_bitslip15_value)
+      1'd0: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[7:0];
+      end
+      1'd1: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[8:1];
+      end
+      2'd2: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[9:2];
+      end
+      2'd3: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[10:3];
+      end
+      3'd4: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[11:4];
+      end
+      3'd5: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[12:5];
+      end
+      3'd6: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[13:6];
+      end
+      3'd7: begin
+        main_a7ddrphy_bitslip15_o <= main_a7ddrphy_bitslip15_r[14:7];
+      end
+    endcase
+    if (main_sdram_inti_p0_rddata_valid) begin
+      main_sdram_phaseinjector0_status <= main_sdram_inti_p0_rddata;
+    end
+    if (main_sdram_inti_p1_rddata_valid) begin
+      main_sdram_phaseinjector1_status <= main_sdram_inti_p1_rddata;
+    end
+    if (main_sdram_inti_p2_rddata_valid) begin
+      main_sdram_phaseinjector2_status <= main_sdram_inti_p2_rddata;
+    end
+    if (main_sdram_inti_p3_rddata_valid) begin
+      main_sdram_phaseinjector3_status <= main_sdram_inti_p3_rddata;
+    end
+    if ((main_sdram_timer_wait & (~main_sdram_timer_done0))) begin
+      main_sdram_timer_count1 <= (main_sdram_timer_count1 - 1'd1);
+    end else begin
+      main_sdram_timer_count1 <= 9'd468;
+    end
+    main_sdram_postponer_req_o <= 1'd0;
+    if (main_sdram_postponer_req_i) begin
+      main_sdram_postponer_count <= (main_sdram_postponer_count - 1'd1);
+      if ((main_sdram_postponer_count == 1'd0)) begin
+        main_sdram_postponer_count <= 1'd0;
+        main_sdram_postponer_req_o <= 1'd1;
+      end
+    end
+    if (main_sdram_sequencer_start0) begin
+      main_sdram_sequencer_count <= 1'd0;
+    end else begin
+      if (main_sdram_sequencer_done1) begin
+        if ((main_sdram_sequencer_count != 1'd0)) begin
+          main_sdram_sequencer_count <= (main_sdram_sequencer_count - 1'd1);
+        end
+      end
+    end
+    main_sdram_cmd_payload_a   <= 1'd0;
+    main_sdram_cmd_payload_ba  <= 1'd0;
+    main_sdram_cmd_payload_cas <= 1'd0;
+    main_sdram_cmd_payload_ras <= 1'd0;
+    main_sdram_cmd_payload_we  <= 1'd0;
+    main_sdram_sequencer_done1 <= 1'd0;
+    if ((main_sdram_sequencer_start1 & (main_sdram_sequencer_counter == 1'd0))) begin
+      main_sdram_cmd_payload_a   <= 11'd1024;
+      main_sdram_cmd_payload_ba  <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd1;
+      main_sdram_cmd_payload_we  <= 1'd1;
+    end
+    if ((main_sdram_sequencer_counter == 2'd2)) begin
+      main_sdram_cmd_payload_a   <= 1'd0;
+      main_sdram_cmd_payload_ba  <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd1;
+      main_sdram_cmd_payload_ras <= 1'd1;
+      main_sdram_cmd_payload_we  <= 1'd0;
+    end
+    if ((main_sdram_sequencer_counter == 6'd34)) begin
+      main_sdram_cmd_payload_a   <= 1'd0;
+      main_sdram_cmd_payload_ba  <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd0;
+      main_sdram_cmd_payload_we  <= 1'd0;
+      main_sdram_sequencer_done1 <= 1'd1;
+    end
+    if ((main_sdram_sequencer_counter == 6'd34)) begin
+      main_sdram_sequencer_counter <= 1'd0;
+    end else begin
+      if ((main_sdram_sequencer_counter != 1'd0)) begin
+        main_sdram_sequencer_counter <= (main_sdram_sequencer_counter + 1'd1);
+      end else begin
+        if (main_sdram_sequencer_start1) begin
+          main_sdram_sequencer_counter <= 1'd1;
+        end
+      end
+    end
+    if ((main_sdram_zqcs_timer_wait & (~main_sdram_zqcs_timer_done0))) begin
+      main_sdram_zqcs_timer_count1 <= (main_sdram_zqcs_timer_count1 - 1'd1);
+    end else begin
+      main_sdram_zqcs_timer_count1 <= 26'd59999999;
+    end
+    main_sdram_zqcs_executer_done <= 1'd0;
+    if ((main_sdram_zqcs_executer_start & (main_sdram_zqcs_executer_counter == 1'd0))) begin
+      main_sdram_cmd_payload_a   <= 11'd1024;
+      main_sdram_cmd_payload_ba  <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd1;
+      main_sdram_cmd_payload_we  <= 1'd1;
+    end
+    if ((main_sdram_zqcs_executer_counter == 2'd2)) begin
+      main_sdram_cmd_payload_a   <= 1'd0;
+      main_sdram_cmd_payload_ba  <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd0;
+      main_sdram_cmd_payload_we  <= 1'd1;
+    end
+    if ((main_sdram_zqcs_executer_counter == 5'd18)) begin
+      main_sdram_cmd_payload_a <= 1'd0;
+      main_sdram_cmd_payload_ba <= 1'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd0;
+      main_sdram_cmd_payload_we <= 1'd0;
+      main_sdram_zqcs_executer_done <= 1'd1;
+    end
+    if ((main_sdram_zqcs_executer_counter == 5'd18)) begin
+      main_sdram_zqcs_executer_counter <= 1'd0;
+    end else begin
+      if ((main_sdram_zqcs_executer_counter != 1'd0)) begin
+        main_sdram_zqcs_executer_counter <= (main_sdram_zqcs_executer_counter + 1'd1);
+      end else begin
+        if (main_sdram_zqcs_executer_start) begin
+          main_sdram_zqcs_executer_counter <= 1'd1;
+        end
+      end
+    end
+    builder_refresher_state <= builder_refresher_next_state;
+    if (main_sdram_bankmachine0_row_close) begin
+      main_sdram_bankmachine0_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine0_row_open) begin
+        main_sdram_bankmachine0_row_opened <= 1'd1;
+        main_sdram_bankmachine0_row <= main_sdram_bankmachine0_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_we & main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable) & (~main_sdram_bankmachine0_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine0_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine0_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine0_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine0_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine0_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_we & main_sdram_bankmachine0_cmd_buffer_lookahead_syncfifo0_writable) & (~main_sdram_bankmachine0_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine0_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine0_cmd_buffer_lookahead_level <= (main_sdram_bankmachine0_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine0_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine0_cmd_buffer_lookahead_level <= (main_sdram_bankmachine0_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine0_cmd_buffer_source_valid) | main_sdram_bankmachine0_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine0_cmd_buffer_source_valid <= main_sdram_bankmachine0_cmd_buffer_sink_valid;
+      main_sdram_bankmachine0_cmd_buffer_source_first <= main_sdram_bankmachine0_cmd_buffer_sink_first;
+      main_sdram_bankmachine0_cmd_buffer_source_last <= main_sdram_bankmachine0_cmd_buffer_sink_last;
+      main_sdram_bankmachine0_cmd_buffer_source_payload_we <= main_sdram_bankmachine0_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine0_cmd_buffer_source_payload_addr <= main_sdram_bankmachine0_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine0_twtpcon_valid) begin
+      main_sdram_bankmachine0_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine0_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine0_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine0_twtpcon_ready)) begin
+        main_sdram_bankmachine0_twtpcon_count <= (main_sdram_bankmachine0_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine0_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine0_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine0_trccon_valid) begin
+      main_sdram_bankmachine0_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine0_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine0_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine0_trccon_ready)) begin
+        main_sdram_bankmachine0_trccon_count <= (main_sdram_bankmachine0_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine0_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine0_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine0_trascon_valid) begin
+      main_sdram_bankmachine0_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine0_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine0_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine0_trascon_ready)) begin
+        main_sdram_bankmachine0_trascon_count <= (main_sdram_bankmachine0_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine0_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine0_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine0_state <= builder_bankmachine0_next_state;
+    if (main_sdram_bankmachine1_row_close) begin
+      main_sdram_bankmachine1_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine1_row_open) begin
+        main_sdram_bankmachine1_row_opened <= 1'd1;
+        main_sdram_bankmachine1_row <= main_sdram_bankmachine1_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_we & main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable) & (~main_sdram_bankmachine1_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine1_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine1_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine1_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine1_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine1_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_we & main_sdram_bankmachine1_cmd_buffer_lookahead_syncfifo1_writable) & (~main_sdram_bankmachine1_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine1_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine1_cmd_buffer_lookahead_level <= (main_sdram_bankmachine1_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine1_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine1_cmd_buffer_lookahead_level <= (main_sdram_bankmachine1_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine1_cmd_buffer_source_valid) | main_sdram_bankmachine1_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine1_cmd_buffer_source_valid <= main_sdram_bankmachine1_cmd_buffer_sink_valid;
+      main_sdram_bankmachine1_cmd_buffer_source_first <= main_sdram_bankmachine1_cmd_buffer_sink_first;
+      main_sdram_bankmachine1_cmd_buffer_source_last <= main_sdram_bankmachine1_cmd_buffer_sink_last;
+      main_sdram_bankmachine1_cmd_buffer_source_payload_we <= main_sdram_bankmachine1_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine1_cmd_buffer_source_payload_addr <= main_sdram_bankmachine1_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine1_twtpcon_valid) begin
+      main_sdram_bankmachine1_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine1_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine1_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine1_twtpcon_ready)) begin
+        main_sdram_bankmachine1_twtpcon_count <= (main_sdram_bankmachine1_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine1_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine1_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine1_trccon_valid) begin
+      main_sdram_bankmachine1_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine1_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine1_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine1_trccon_ready)) begin
+        main_sdram_bankmachine1_trccon_count <= (main_sdram_bankmachine1_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine1_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine1_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine1_trascon_valid) begin
+      main_sdram_bankmachine1_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine1_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine1_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine1_trascon_ready)) begin
+        main_sdram_bankmachine1_trascon_count <= (main_sdram_bankmachine1_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine1_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine1_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine1_state <= builder_bankmachine1_next_state;
+    if (main_sdram_bankmachine2_row_close) begin
+      main_sdram_bankmachine2_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine2_row_open) begin
+        main_sdram_bankmachine2_row_opened <= 1'd1;
+        main_sdram_bankmachine2_row <= main_sdram_bankmachine2_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_we & main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable) & (~main_sdram_bankmachine2_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine2_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine2_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine2_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine2_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine2_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_we & main_sdram_bankmachine2_cmd_buffer_lookahead_syncfifo2_writable) & (~main_sdram_bankmachine2_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine2_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine2_cmd_buffer_lookahead_level <= (main_sdram_bankmachine2_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine2_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine2_cmd_buffer_lookahead_level <= (main_sdram_bankmachine2_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine2_cmd_buffer_source_valid) | main_sdram_bankmachine2_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine2_cmd_buffer_source_valid <= main_sdram_bankmachine2_cmd_buffer_sink_valid;
+      main_sdram_bankmachine2_cmd_buffer_source_first <= main_sdram_bankmachine2_cmd_buffer_sink_first;
+      main_sdram_bankmachine2_cmd_buffer_source_last <= main_sdram_bankmachine2_cmd_buffer_sink_last;
+      main_sdram_bankmachine2_cmd_buffer_source_payload_we <= main_sdram_bankmachine2_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine2_cmd_buffer_source_payload_addr <= main_sdram_bankmachine2_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine2_twtpcon_valid) begin
+      main_sdram_bankmachine2_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine2_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine2_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine2_twtpcon_ready)) begin
+        main_sdram_bankmachine2_twtpcon_count <= (main_sdram_bankmachine2_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine2_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine2_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine2_trccon_valid) begin
+      main_sdram_bankmachine2_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine2_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine2_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine2_trccon_ready)) begin
+        main_sdram_bankmachine2_trccon_count <= (main_sdram_bankmachine2_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine2_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine2_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine2_trascon_valid) begin
+      main_sdram_bankmachine2_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine2_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine2_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine2_trascon_ready)) begin
+        main_sdram_bankmachine2_trascon_count <= (main_sdram_bankmachine2_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine2_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine2_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine2_state <= builder_bankmachine2_next_state;
+    if (main_sdram_bankmachine3_row_close) begin
+      main_sdram_bankmachine3_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine3_row_open) begin
+        main_sdram_bankmachine3_row_opened <= 1'd1;
+        main_sdram_bankmachine3_row <= main_sdram_bankmachine3_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_we & main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable) & (~main_sdram_bankmachine3_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine3_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine3_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine3_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine3_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine3_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_we & main_sdram_bankmachine3_cmd_buffer_lookahead_syncfifo3_writable) & (~main_sdram_bankmachine3_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine3_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine3_cmd_buffer_lookahead_level <= (main_sdram_bankmachine3_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine3_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine3_cmd_buffer_lookahead_level <= (main_sdram_bankmachine3_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine3_cmd_buffer_source_valid) | main_sdram_bankmachine3_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine3_cmd_buffer_source_valid <= main_sdram_bankmachine3_cmd_buffer_sink_valid;
+      main_sdram_bankmachine3_cmd_buffer_source_first <= main_sdram_bankmachine3_cmd_buffer_sink_first;
+      main_sdram_bankmachine3_cmd_buffer_source_last <= main_sdram_bankmachine3_cmd_buffer_sink_last;
+      main_sdram_bankmachine3_cmd_buffer_source_payload_we <= main_sdram_bankmachine3_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine3_cmd_buffer_source_payload_addr <= main_sdram_bankmachine3_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine3_twtpcon_valid) begin
+      main_sdram_bankmachine3_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine3_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine3_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine3_twtpcon_ready)) begin
+        main_sdram_bankmachine3_twtpcon_count <= (main_sdram_bankmachine3_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine3_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine3_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine3_trccon_valid) begin
+      main_sdram_bankmachine3_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine3_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine3_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine3_trccon_ready)) begin
+        main_sdram_bankmachine3_trccon_count <= (main_sdram_bankmachine3_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine3_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine3_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine3_trascon_valid) begin
+      main_sdram_bankmachine3_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine3_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine3_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine3_trascon_ready)) begin
+        main_sdram_bankmachine3_trascon_count <= (main_sdram_bankmachine3_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine3_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine3_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine3_state <= builder_bankmachine3_next_state;
+    if (main_sdram_bankmachine4_row_close) begin
+      main_sdram_bankmachine4_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine4_row_open) begin
+        main_sdram_bankmachine4_row_opened <= 1'd1;
+        main_sdram_bankmachine4_row <= main_sdram_bankmachine4_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_we & main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable) & (~main_sdram_bankmachine4_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine4_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine4_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine4_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine4_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine4_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_we & main_sdram_bankmachine4_cmd_buffer_lookahead_syncfifo4_writable) & (~main_sdram_bankmachine4_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine4_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine4_cmd_buffer_lookahead_level <= (main_sdram_bankmachine4_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine4_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine4_cmd_buffer_lookahead_level <= (main_sdram_bankmachine4_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine4_cmd_buffer_source_valid) | main_sdram_bankmachine4_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine4_cmd_buffer_source_valid <= main_sdram_bankmachine4_cmd_buffer_sink_valid;
+      main_sdram_bankmachine4_cmd_buffer_source_first <= main_sdram_bankmachine4_cmd_buffer_sink_first;
+      main_sdram_bankmachine4_cmd_buffer_source_last <= main_sdram_bankmachine4_cmd_buffer_sink_last;
+      main_sdram_bankmachine4_cmd_buffer_source_payload_we <= main_sdram_bankmachine4_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine4_cmd_buffer_source_payload_addr <= main_sdram_bankmachine4_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine4_twtpcon_valid) begin
+      main_sdram_bankmachine4_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine4_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine4_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine4_twtpcon_ready)) begin
+        main_sdram_bankmachine4_twtpcon_count <= (main_sdram_bankmachine4_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine4_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine4_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine4_trccon_valid) begin
+      main_sdram_bankmachine4_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine4_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine4_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine4_trccon_ready)) begin
+        main_sdram_bankmachine4_trccon_count <= (main_sdram_bankmachine4_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine4_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine4_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine4_trascon_valid) begin
+      main_sdram_bankmachine4_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine4_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine4_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine4_trascon_ready)) begin
+        main_sdram_bankmachine4_trascon_count <= (main_sdram_bankmachine4_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine4_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine4_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine4_state <= builder_bankmachine4_next_state;
+    if (main_sdram_bankmachine5_row_close) begin
+      main_sdram_bankmachine5_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine5_row_open) begin
+        main_sdram_bankmachine5_row_opened <= 1'd1;
+        main_sdram_bankmachine5_row <= main_sdram_bankmachine5_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_we & main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable) & (~main_sdram_bankmachine5_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine5_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine5_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine5_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine5_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine5_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_we & main_sdram_bankmachine5_cmd_buffer_lookahead_syncfifo5_writable) & (~main_sdram_bankmachine5_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine5_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine5_cmd_buffer_lookahead_level <= (main_sdram_bankmachine5_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine5_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine5_cmd_buffer_lookahead_level <= (main_sdram_bankmachine5_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine5_cmd_buffer_source_valid) | main_sdram_bankmachine5_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine5_cmd_buffer_source_valid <= main_sdram_bankmachine5_cmd_buffer_sink_valid;
+      main_sdram_bankmachine5_cmd_buffer_source_first <= main_sdram_bankmachine5_cmd_buffer_sink_first;
+      main_sdram_bankmachine5_cmd_buffer_source_last <= main_sdram_bankmachine5_cmd_buffer_sink_last;
+      main_sdram_bankmachine5_cmd_buffer_source_payload_we <= main_sdram_bankmachine5_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine5_cmd_buffer_source_payload_addr <= main_sdram_bankmachine5_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine5_twtpcon_valid) begin
+      main_sdram_bankmachine5_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine5_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine5_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine5_twtpcon_ready)) begin
+        main_sdram_bankmachine5_twtpcon_count <= (main_sdram_bankmachine5_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine5_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine5_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine5_trccon_valid) begin
+      main_sdram_bankmachine5_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine5_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine5_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine5_trccon_ready)) begin
+        main_sdram_bankmachine5_trccon_count <= (main_sdram_bankmachine5_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine5_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine5_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine5_trascon_valid) begin
+      main_sdram_bankmachine5_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine5_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine5_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine5_trascon_ready)) begin
+        main_sdram_bankmachine5_trascon_count <= (main_sdram_bankmachine5_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine5_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine5_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine5_state <= builder_bankmachine5_next_state;
+    if (main_sdram_bankmachine6_row_close) begin
+      main_sdram_bankmachine6_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine6_row_open) begin
+        main_sdram_bankmachine6_row_opened <= 1'd1;
+        main_sdram_bankmachine6_row <= main_sdram_bankmachine6_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_we & main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable) & (~main_sdram_bankmachine6_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine6_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine6_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine6_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine6_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine6_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_we & main_sdram_bankmachine6_cmd_buffer_lookahead_syncfifo6_writable) & (~main_sdram_bankmachine6_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine6_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine6_cmd_buffer_lookahead_level <= (main_sdram_bankmachine6_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine6_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine6_cmd_buffer_lookahead_level <= (main_sdram_bankmachine6_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine6_cmd_buffer_source_valid) | main_sdram_bankmachine6_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine6_cmd_buffer_source_valid <= main_sdram_bankmachine6_cmd_buffer_sink_valid;
+      main_sdram_bankmachine6_cmd_buffer_source_first <= main_sdram_bankmachine6_cmd_buffer_sink_first;
+      main_sdram_bankmachine6_cmd_buffer_source_last <= main_sdram_bankmachine6_cmd_buffer_sink_last;
+      main_sdram_bankmachine6_cmd_buffer_source_payload_we <= main_sdram_bankmachine6_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine6_cmd_buffer_source_payload_addr <= main_sdram_bankmachine6_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine6_twtpcon_valid) begin
+      main_sdram_bankmachine6_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine6_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine6_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine6_twtpcon_ready)) begin
+        main_sdram_bankmachine6_twtpcon_count <= (main_sdram_bankmachine6_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine6_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine6_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine6_trccon_valid) begin
+      main_sdram_bankmachine6_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine6_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine6_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine6_trccon_ready)) begin
+        main_sdram_bankmachine6_trccon_count <= (main_sdram_bankmachine6_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine6_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine6_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine6_trascon_valid) begin
+      main_sdram_bankmachine6_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine6_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine6_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine6_trascon_ready)) begin
+        main_sdram_bankmachine6_trascon_count <= (main_sdram_bankmachine6_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine6_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine6_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine6_state <= builder_bankmachine6_next_state;
+    if (main_sdram_bankmachine7_row_close) begin
+      main_sdram_bankmachine7_row_opened <= 1'd0;
+    end else begin
+      if (main_sdram_bankmachine7_row_open) begin
+        main_sdram_bankmachine7_row_opened <= 1'd1;
+        main_sdram_bankmachine7_row <= main_sdram_bankmachine7_cmd_buffer_source_payload_addr[20:7];
+      end
+    end
+    if (((main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_we & main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable) & (~main_sdram_bankmachine7_cmd_buffer_lookahead_replace))) begin
+      main_sdram_bankmachine7_cmd_buffer_lookahead_produce <= (main_sdram_bankmachine7_cmd_buffer_lookahead_produce + 1'd1);
+    end
+    if (main_sdram_bankmachine7_cmd_buffer_lookahead_do_read) begin
+      main_sdram_bankmachine7_cmd_buffer_lookahead_consume <= (main_sdram_bankmachine7_cmd_buffer_lookahead_consume + 1'd1);
+    end
+    if (((main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_we & main_sdram_bankmachine7_cmd_buffer_lookahead_syncfifo7_writable) & (~main_sdram_bankmachine7_cmd_buffer_lookahead_replace))) begin
+      if ((~main_sdram_bankmachine7_cmd_buffer_lookahead_do_read)) begin
+        main_sdram_bankmachine7_cmd_buffer_lookahead_level <= (main_sdram_bankmachine7_cmd_buffer_lookahead_level + 1'd1);
+      end
+    end else begin
+      if (main_sdram_bankmachine7_cmd_buffer_lookahead_do_read) begin
+        main_sdram_bankmachine7_cmd_buffer_lookahead_level <= (main_sdram_bankmachine7_cmd_buffer_lookahead_level - 1'd1);
+      end
+    end
+    if (((~main_sdram_bankmachine7_cmd_buffer_source_valid) | main_sdram_bankmachine7_cmd_buffer_source_ready)) begin
+      main_sdram_bankmachine7_cmd_buffer_source_valid <= main_sdram_bankmachine7_cmd_buffer_sink_valid;
+      main_sdram_bankmachine7_cmd_buffer_source_first <= main_sdram_bankmachine7_cmd_buffer_sink_first;
+      main_sdram_bankmachine7_cmd_buffer_source_last <= main_sdram_bankmachine7_cmd_buffer_sink_last;
+      main_sdram_bankmachine7_cmd_buffer_source_payload_we <= main_sdram_bankmachine7_cmd_buffer_sink_payload_we;
+      main_sdram_bankmachine7_cmd_buffer_source_payload_addr <= main_sdram_bankmachine7_cmd_buffer_sink_payload_addr;
+    end
+    if (main_sdram_bankmachine7_twtpcon_valid) begin
+      main_sdram_bankmachine7_twtpcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_bankmachine7_twtpcon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine7_twtpcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine7_twtpcon_ready)) begin
+        main_sdram_bankmachine7_twtpcon_count <= (main_sdram_bankmachine7_twtpcon_count - 1'd1);
+        if ((main_sdram_bankmachine7_twtpcon_count == 1'd1)) begin
+          main_sdram_bankmachine7_twtpcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine7_trccon_valid) begin
+      main_sdram_bankmachine7_trccon_count <= 2'd3;
+      if (1'd0) begin
+        main_sdram_bankmachine7_trccon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine7_trccon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine7_trccon_ready)) begin
+        main_sdram_bankmachine7_trccon_count <= (main_sdram_bankmachine7_trccon_count - 1'd1);
+        if ((main_sdram_bankmachine7_trccon_count == 1'd1)) begin
+          main_sdram_bankmachine7_trccon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_bankmachine7_trascon_valid) begin
+      main_sdram_bankmachine7_trascon_count <= 2'd2;
+      if (1'd0) begin
+        main_sdram_bankmachine7_trascon_ready <= 1'd1;
+      end else begin
+        main_sdram_bankmachine7_trascon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_bankmachine7_trascon_ready)) begin
+        main_sdram_bankmachine7_trascon_count <= (main_sdram_bankmachine7_trascon_count - 1'd1);
+        if ((main_sdram_bankmachine7_trascon_count == 1'd1)) begin
+          main_sdram_bankmachine7_trascon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_bankmachine7_state <= builder_bankmachine7_next_state;
+    if ((~main_sdram_en0)) begin
+      main_sdram_time0 <= 5'd31;
+    end else begin
+      if ((~main_sdram_max_time0)) begin
+        main_sdram_time0 <= (main_sdram_time0 - 1'd1);
+      end
+    end
+    if ((~main_sdram_en1)) begin
+      main_sdram_time1 <= 4'd15;
+    end else begin
+      if ((~main_sdram_max_time1)) begin
+        main_sdram_time1 <= (main_sdram_time1 - 1'd1);
+      end
+    end
+    if (main_sdram_choose_cmd_ce) begin
+      case (main_sdram_choose_cmd_grant)
+        1'd0: begin
+          if (main_sdram_choose_cmd_request[1]) begin
+            main_sdram_choose_cmd_grant <= 1'd1;
+          end else begin
+            if (main_sdram_choose_cmd_request[2]) begin
+              main_sdram_choose_cmd_grant <= 2'd2;
+            end else begin
+              if (main_sdram_choose_cmd_request[3]) begin
+                main_sdram_choose_cmd_grant <= 2'd3;
+              end else begin
+                if (main_sdram_choose_cmd_request[4]) begin
+                  main_sdram_choose_cmd_grant <= 3'd4;
+                end else begin
+                  if (main_sdram_choose_cmd_request[5]) begin
+                    main_sdram_choose_cmd_grant <= 3'd5;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[6]) begin
+                      main_sdram_choose_cmd_grant <= 3'd6;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[7]) begin
+                        main_sdram_choose_cmd_grant <= 3'd7;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        1'd1: begin
+          if (main_sdram_choose_cmd_request[2]) begin
+            main_sdram_choose_cmd_grant <= 2'd2;
+          end else begin
+            if (main_sdram_choose_cmd_request[3]) begin
+              main_sdram_choose_cmd_grant <= 2'd3;
+            end else begin
+              if (main_sdram_choose_cmd_request[4]) begin
+                main_sdram_choose_cmd_grant <= 3'd4;
+              end else begin
+                if (main_sdram_choose_cmd_request[5]) begin
+                  main_sdram_choose_cmd_grant <= 3'd5;
+                end else begin
+                  if (main_sdram_choose_cmd_request[6]) begin
+                    main_sdram_choose_cmd_grant <= 3'd6;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[7]) begin
+                      main_sdram_choose_cmd_grant <= 3'd7;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[0]) begin
+                        main_sdram_choose_cmd_grant <= 1'd0;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        2'd2: begin
+          if (main_sdram_choose_cmd_request[3]) begin
+            main_sdram_choose_cmd_grant <= 2'd3;
+          end else begin
+            if (main_sdram_choose_cmd_request[4]) begin
+              main_sdram_choose_cmd_grant <= 3'd4;
+            end else begin
+              if (main_sdram_choose_cmd_request[5]) begin
+                main_sdram_choose_cmd_grant <= 3'd5;
+              end else begin
+                if (main_sdram_choose_cmd_request[6]) begin
+                  main_sdram_choose_cmd_grant <= 3'd6;
+                end else begin
+                  if (main_sdram_choose_cmd_request[7]) begin
+                    main_sdram_choose_cmd_grant <= 3'd7;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[0]) begin
+                      main_sdram_choose_cmd_grant <= 1'd0;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[1]) begin
+                        main_sdram_choose_cmd_grant <= 1'd1;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        2'd3: begin
+          if (main_sdram_choose_cmd_request[4]) begin
+            main_sdram_choose_cmd_grant <= 3'd4;
+          end else begin
+            if (main_sdram_choose_cmd_request[5]) begin
+              main_sdram_choose_cmd_grant <= 3'd5;
+            end else begin
+              if (main_sdram_choose_cmd_request[6]) begin
+                main_sdram_choose_cmd_grant <= 3'd6;
+              end else begin
+                if (main_sdram_choose_cmd_request[7]) begin
+                  main_sdram_choose_cmd_grant <= 3'd7;
+                end else begin
+                  if (main_sdram_choose_cmd_request[0]) begin
+                    main_sdram_choose_cmd_grant <= 1'd0;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[1]) begin
+                      main_sdram_choose_cmd_grant <= 1'd1;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[2]) begin
+                        main_sdram_choose_cmd_grant <= 2'd2;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd4: begin
+          if (main_sdram_choose_cmd_request[5]) begin
+            main_sdram_choose_cmd_grant <= 3'd5;
+          end else begin
+            if (main_sdram_choose_cmd_request[6]) begin
+              main_sdram_choose_cmd_grant <= 3'd6;
+            end else begin
+              if (main_sdram_choose_cmd_request[7]) begin
+                main_sdram_choose_cmd_grant <= 3'd7;
+              end else begin
+                if (main_sdram_choose_cmd_request[0]) begin
+                  main_sdram_choose_cmd_grant <= 1'd0;
+                end else begin
+                  if (main_sdram_choose_cmd_request[1]) begin
+                    main_sdram_choose_cmd_grant <= 1'd1;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[2]) begin
+                      main_sdram_choose_cmd_grant <= 2'd2;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[3]) begin
+                        main_sdram_choose_cmd_grant <= 2'd3;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd5: begin
+          if (main_sdram_choose_cmd_request[6]) begin
+            main_sdram_choose_cmd_grant <= 3'd6;
+          end else begin
+            if (main_sdram_choose_cmd_request[7]) begin
+              main_sdram_choose_cmd_grant <= 3'd7;
+            end else begin
+              if (main_sdram_choose_cmd_request[0]) begin
+                main_sdram_choose_cmd_grant <= 1'd0;
+              end else begin
+                if (main_sdram_choose_cmd_request[1]) begin
+                  main_sdram_choose_cmd_grant <= 1'd1;
+                end else begin
+                  if (main_sdram_choose_cmd_request[2]) begin
+                    main_sdram_choose_cmd_grant <= 2'd2;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[3]) begin
+                      main_sdram_choose_cmd_grant <= 2'd3;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[4]) begin
+                        main_sdram_choose_cmd_grant <= 3'd4;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd6: begin
+          if (main_sdram_choose_cmd_request[7]) begin
+            main_sdram_choose_cmd_grant <= 3'd7;
+          end else begin
+            if (main_sdram_choose_cmd_request[0]) begin
+              main_sdram_choose_cmd_grant <= 1'd0;
+            end else begin
+              if (main_sdram_choose_cmd_request[1]) begin
+                main_sdram_choose_cmd_grant <= 1'd1;
+              end else begin
+                if (main_sdram_choose_cmd_request[2]) begin
+                  main_sdram_choose_cmd_grant <= 2'd2;
+                end else begin
+                  if (main_sdram_choose_cmd_request[3]) begin
+                    main_sdram_choose_cmd_grant <= 2'd3;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[4]) begin
+                      main_sdram_choose_cmd_grant <= 3'd4;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[5]) begin
+                        main_sdram_choose_cmd_grant <= 3'd5;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd7: begin
+          if (main_sdram_choose_cmd_request[0]) begin
+            main_sdram_choose_cmd_grant <= 1'd0;
+          end else begin
+            if (main_sdram_choose_cmd_request[1]) begin
+              main_sdram_choose_cmd_grant <= 1'd1;
+            end else begin
+              if (main_sdram_choose_cmd_request[2]) begin
+                main_sdram_choose_cmd_grant <= 2'd2;
+              end else begin
+                if (main_sdram_choose_cmd_request[3]) begin
+                  main_sdram_choose_cmd_grant <= 2'd3;
+                end else begin
+                  if (main_sdram_choose_cmd_request[4]) begin
+                    main_sdram_choose_cmd_grant <= 3'd4;
+                  end else begin
+                    if (main_sdram_choose_cmd_request[5]) begin
+                      main_sdram_choose_cmd_grant <= 3'd5;
+                    end else begin
+                      if (main_sdram_choose_cmd_request[6]) begin
+                        main_sdram_choose_cmd_grant <= 3'd6;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+      endcase
+    end
+    if (main_sdram_choose_req_ce) begin
+      case (main_sdram_choose_req_grant)
+        1'd0: begin
+          if (main_sdram_choose_req_request[1]) begin
+            main_sdram_choose_req_grant <= 1'd1;
+          end else begin
+            if (main_sdram_choose_req_request[2]) begin
+              main_sdram_choose_req_grant <= 2'd2;
+            end else begin
+              if (main_sdram_choose_req_request[3]) begin
+                main_sdram_choose_req_grant <= 2'd3;
+              end else begin
+                if (main_sdram_choose_req_request[4]) begin
+                  main_sdram_choose_req_grant <= 3'd4;
+                end else begin
+                  if (main_sdram_choose_req_request[5]) begin
+                    main_sdram_choose_req_grant <= 3'd5;
+                  end else begin
+                    if (main_sdram_choose_req_request[6]) begin
+                      main_sdram_choose_req_grant <= 3'd6;
+                    end else begin
+                      if (main_sdram_choose_req_request[7]) begin
+                        main_sdram_choose_req_grant <= 3'd7;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        1'd1: begin
+          if (main_sdram_choose_req_request[2]) begin
+            main_sdram_choose_req_grant <= 2'd2;
+          end else begin
+            if (main_sdram_choose_req_request[3]) begin
+              main_sdram_choose_req_grant <= 2'd3;
+            end else begin
+              if (main_sdram_choose_req_request[4]) begin
+                main_sdram_choose_req_grant <= 3'd4;
+              end else begin
+                if (main_sdram_choose_req_request[5]) begin
+                  main_sdram_choose_req_grant <= 3'd5;
+                end else begin
+                  if (main_sdram_choose_req_request[6]) begin
+                    main_sdram_choose_req_grant <= 3'd6;
+                  end else begin
+                    if (main_sdram_choose_req_request[7]) begin
+                      main_sdram_choose_req_grant <= 3'd7;
+                    end else begin
+                      if (main_sdram_choose_req_request[0]) begin
+                        main_sdram_choose_req_grant <= 1'd0;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        2'd2: begin
+          if (main_sdram_choose_req_request[3]) begin
+            main_sdram_choose_req_grant <= 2'd3;
+          end else begin
+            if (main_sdram_choose_req_request[4]) begin
+              main_sdram_choose_req_grant <= 3'd4;
+            end else begin
+              if (main_sdram_choose_req_request[5]) begin
+                main_sdram_choose_req_grant <= 3'd5;
+              end else begin
+                if (main_sdram_choose_req_request[6]) begin
+                  main_sdram_choose_req_grant <= 3'd6;
+                end else begin
+                  if (main_sdram_choose_req_request[7]) begin
+                    main_sdram_choose_req_grant <= 3'd7;
+                  end else begin
+                    if (main_sdram_choose_req_request[0]) begin
+                      main_sdram_choose_req_grant <= 1'd0;
+                    end else begin
+                      if (main_sdram_choose_req_request[1]) begin
+                        main_sdram_choose_req_grant <= 1'd1;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        2'd3: begin
+          if (main_sdram_choose_req_request[4]) begin
+            main_sdram_choose_req_grant <= 3'd4;
+          end else begin
+            if (main_sdram_choose_req_request[5]) begin
+              main_sdram_choose_req_grant <= 3'd5;
+            end else begin
+              if (main_sdram_choose_req_request[6]) begin
+                main_sdram_choose_req_grant <= 3'd6;
+              end else begin
+                if (main_sdram_choose_req_request[7]) begin
+                  main_sdram_choose_req_grant <= 3'd7;
+                end else begin
+                  if (main_sdram_choose_req_request[0]) begin
+                    main_sdram_choose_req_grant <= 1'd0;
+                  end else begin
+                    if (main_sdram_choose_req_request[1]) begin
+                      main_sdram_choose_req_grant <= 1'd1;
+                    end else begin
+                      if (main_sdram_choose_req_request[2]) begin
+                        main_sdram_choose_req_grant <= 2'd2;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd4: begin
+          if (main_sdram_choose_req_request[5]) begin
+            main_sdram_choose_req_grant <= 3'd5;
+          end else begin
+            if (main_sdram_choose_req_request[6]) begin
+              main_sdram_choose_req_grant <= 3'd6;
+            end else begin
+              if (main_sdram_choose_req_request[7]) begin
+                main_sdram_choose_req_grant <= 3'd7;
+              end else begin
+                if (main_sdram_choose_req_request[0]) begin
+                  main_sdram_choose_req_grant <= 1'd0;
+                end else begin
+                  if (main_sdram_choose_req_request[1]) begin
+                    main_sdram_choose_req_grant <= 1'd1;
+                  end else begin
+                    if (main_sdram_choose_req_request[2]) begin
+                      main_sdram_choose_req_grant <= 2'd2;
+                    end else begin
+                      if (main_sdram_choose_req_request[3]) begin
+                        main_sdram_choose_req_grant <= 2'd3;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd5: begin
+          if (main_sdram_choose_req_request[6]) begin
+            main_sdram_choose_req_grant <= 3'd6;
+          end else begin
+            if (main_sdram_choose_req_request[7]) begin
+              main_sdram_choose_req_grant <= 3'd7;
+            end else begin
+              if (main_sdram_choose_req_request[0]) begin
+                main_sdram_choose_req_grant <= 1'd0;
+              end else begin
+                if (main_sdram_choose_req_request[1]) begin
+                  main_sdram_choose_req_grant <= 1'd1;
+                end else begin
+                  if (main_sdram_choose_req_request[2]) begin
+                    main_sdram_choose_req_grant <= 2'd2;
+                  end else begin
+                    if (main_sdram_choose_req_request[3]) begin
+                      main_sdram_choose_req_grant <= 2'd3;
+                    end else begin
+                      if (main_sdram_choose_req_request[4]) begin
+                        main_sdram_choose_req_grant <= 3'd4;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd6: begin
+          if (main_sdram_choose_req_request[7]) begin
+            main_sdram_choose_req_grant <= 3'd7;
+          end else begin
+            if (main_sdram_choose_req_request[0]) begin
+              main_sdram_choose_req_grant <= 1'd0;
+            end else begin
+              if (main_sdram_choose_req_request[1]) begin
+                main_sdram_choose_req_grant <= 1'd1;
+              end else begin
+                if (main_sdram_choose_req_request[2]) begin
+                  main_sdram_choose_req_grant <= 2'd2;
+                end else begin
+                  if (main_sdram_choose_req_request[3]) begin
+                    main_sdram_choose_req_grant <= 2'd3;
+                  end else begin
+                    if (main_sdram_choose_req_request[4]) begin
+                      main_sdram_choose_req_grant <= 3'd4;
+                    end else begin
+                      if (main_sdram_choose_req_request[5]) begin
+                        main_sdram_choose_req_grant <= 3'd5;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+        3'd7: begin
+          if (main_sdram_choose_req_request[0]) begin
+            main_sdram_choose_req_grant <= 1'd0;
+          end else begin
+            if (main_sdram_choose_req_request[1]) begin
+              main_sdram_choose_req_grant <= 1'd1;
+            end else begin
+              if (main_sdram_choose_req_request[2]) begin
+                main_sdram_choose_req_grant <= 2'd2;
+              end else begin
+                if (main_sdram_choose_req_request[3]) begin
+                  main_sdram_choose_req_grant <= 2'd3;
+                end else begin
+                  if (main_sdram_choose_req_request[4]) begin
+                    main_sdram_choose_req_grant <= 3'd4;
+                  end else begin
+                    if (main_sdram_choose_req_request[5]) begin
+                      main_sdram_choose_req_grant <= 3'd5;
+                    end else begin
+                      if (main_sdram_choose_req_request[6]) begin
+                        main_sdram_choose_req_grant <= 3'd6;
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+        end
+      endcase
+    end
+    main_sdram_dfi_p0_cs_n <= 1'd0;
+    main_sdram_dfi_p0_bank <= builder_array_muxed0;
+    main_sdram_dfi_p0_address <= builder_array_muxed1;
+    main_sdram_dfi_p0_cas_n <= (~builder_array_muxed2);
+    main_sdram_dfi_p0_ras_n <= (~builder_array_muxed3);
+    main_sdram_dfi_p0_we_n <= (~builder_array_muxed4);
+    main_sdram_dfi_p0_rddata_en <= builder_array_muxed5;
+    main_sdram_dfi_p0_wrdata_en <= builder_array_muxed6;
+    main_sdram_dfi_p1_cs_n <= 1'd0;
+    main_sdram_dfi_p1_bank <= builder_array_muxed7;
+    main_sdram_dfi_p1_address <= builder_array_muxed8;
+    main_sdram_dfi_p1_cas_n <= (~builder_array_muxed9);
+    main_sdram_dfi_p1_ras_n <= (~builder_array_muxed10);
+    main_sdram_dfi_p1_we_n <= (~builder_array_muxed11);
+    main_sdram_dfi_p1_rddata_en <= builder_array_muxed12;
+    main_sdram_dfi_p1_wrdata_en <= builder_array_muxed13;
+    main_sdram_dfi_p2_cs_n <= 1'd0;
+    main_sdram_dfi_p2_bank <= builder_array_muxed14;
+    main_sdram_dfi_p2_address <= builder_array_muxed15;
+    main_sdram_dfi_p2_cas_n <= (~builder_array_muxed16);
+    main_sdram_dfi_p2_ras_n <= (~builder_array_muxed17);
+    main_sdram_dfi_p2_we_n <= (~builder_array_muxed18);
+    main_sdram_dfi_p2_rddata_en <= builder_array_muxed19;
+    main_sdram_dfi_p2_wrdata_en <= builder_array_muxed20;
+    main_sdram_dfi_p3_cs_n <= 1'd0;
+    main_sdram_dfi_p3_bank <= builder_array_muxed21;
+    main_sdram_dfi_p3_address <= builder_array_muxed22;
+    main_sdram_dfi_p3_cas_n <= (~builder_array_muxed23);
+    main_sdram_dfi_p3_ras_n <= (~builder_array_muxed24);
+    main_sdram_dfi_p3_we_n <= (~builder_array_muxed25);
+    main_sdram_dfi_p3_rddata_en <= builder_array_muxed26;
+    main_sdram_dfi_p3_wrdata_en <= builder_array_muxed27;
+    if (main_sdram_trrdcon_valid) begin
+      main_sdram_trrdcon_count <= 1'd1;
+      if (1'd0) begin
+        main_sdram_trrdcon_ready <= 1'd1;
+      end else begin
+        main_sdram_trrdcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_trrdcon_ready)) begin
+        main_sdram_trrdcon_count <= (main_sdram_trrdcon_count - 1'd1);
+        if ((main_sdram_trrdcon_count == 1'd1)) begin
+          main_sdram_trrdcon_ready <= 1'd1;
+        end
+      end
+    end
+    main_sdram_tfawcon_window <= {main_sdram_tfawcon_window, main_sdram_tfawcon_valid};
+    if ((main_sdram_tfawcon_count < 3'd4)) begin
+      if ((main_sdram_tfawcon_count == 2'd3)) begin
+        main_sdram_tfawcon_ready <= (~main_sdram_tfawcon_valid);
+      end else begin
+        main_sdram_tfawcon_ready <= 1'd1;
+      end
+    end
+    if (main_sdram_tccdcon_valid) begin
+      main_sdram_tccdcon_count <= 1'd0;
+      if (1'd1) begin
+        main_sdram_tccdcon_ready <= 1'd1;
+      end else begin
+        main_sdram_tccdcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_tccdcon_ready)) begin
+        main_sdram_tccdcon_count <= (main_sdram_tccdcon_count - 1'd1);
+        if ((main_sdram_tccdcon_count == 1'd1)) begin
+          main_sdram_tccdcon_ready <= 1'd1;
+        end
+      end
+    end
+    if (main_sdram_twtrcon_valid) begin
+      main_sdram_twtrcon_count <= 3'd4;
+      if (1'd0) begin
+        main_sdram_twtrcon_ready <= 1'd1;
+      end else begin
+        main_sdram_twtrcon_ready <= 1'd0;
+      end
+    end else begin
+      if ((~main_sdram_twtrcon_ready)) begin
+        main_sdram_twtrcon_count <= (main_sdram_twtrcon_count - 1'd1);
+        if ((main_sdram_twtrcon_count == 1'd1)) begin
+          main_sdram_twtrcon_ready <= 1'd1;
+        end
+      end
+    end
+    builder_multiplexer_state <= builder_multiplexer_next_state;
+    if (((builder_roundrobin0_grant == 1'd0) & main_sdram_interface_bank0_rdata_valid)) begin
+      builder_rbank <= 1'd0;
+    end
+    if (((builder_roundrobin0_grant == 1'd0) & main_sdram_interface_bank0_wdata_ready)) begin
+      builder_wbank <= 1'd0;
+    end
+    if (((builder_roundrobin1_grant == 1'd0) & main_sdram_interface_bank1_rdata_valid)) begin
+      builder_rbank <= 1'd1;
+    end
+    if (((builder_roundrobin1_grant == 1'd0) & main_sdram_interface_bank1_wdata_ready)) begin
+      builder_wbank <= 1'd1;
+    end
+    if (((builder_roundrobin2_grant == 1'd0) & main_sdram_interface_bank2_rdata_valid)) begin
+      builder_rbank <= 2'd2;
+    end
+    if (((builder_roundrobin2_grant == 1'd0) & main_sdram_interface_bank2_wdata_ready)) begin
+      builder_wbank <= 2'd2;
+    end
+    if (((builder_roundrobin3_grant == 1'd0) & main_sdram_interface_bank3_rdata_valid)) begin
+      builder_rbank <= 2'd3;
+    end
+    if (((builder_roundrobin3_grant == 1'd0) & main_sdram_interface_bank3_wdata_ready)) begin
+      builder_wbank <= 2'd3;
+    end
+    if (((builder_roundrobin4_grant == 1'd0) & main_sdram_interface_bank4_rdata_valid)) begin
+      builder_rbank <= 3'd4;
+    end
+    if (((builder_roundrobin4_grant == 1'd0) & main_sdram_interface_bank4_wdata_ready)) begin
+      builder_wbank <= 3'd4;
+    end
+    if (((builder_roundrobin5_grant == 1'd0) & main_sdram_interface_bank5_rdata_valid)) begin
+      builder_rbank <= 3'd5;
+    end
+    if (((builder_roundrobin5_grant == 1'd0) & main_sdram_interface_bank5_wdata_ready)) begin
+      builder_wbank <= 3'd5;
+    end
+    if (((builder_roundrobin6_grant == 1'd0) & main_sdram_interface_bank6_rdata_valid)) begin
+      builder_rbank <= 3'd6;
+    end
+    if (((builder_roundrobin6_grant == 1'd0) & main_sdram_interface_bank6_wdata_ready)) begin
+      builder_wbank <= 3'd6;
+    end
+    if (((builder_roundrobin7_grant == 1'd0) & main_sdram_interface_bank7_rdata_valid)) begin
+      builder_rbank <= 3'd7;
+    end
+    if (((builder_roundrobin7_grant == 1'd0) & main_sdram_interface_bank7_wdata_ready)) begin
+      builder_wbank <= 3'd7;
+    end
+    builder_new_master_wdata_ready0 <= ((((((((1'd0 | ((builder_roundrobin0_grant == 1'd0) & main_sdram_interface_bank0_wdata_ready)) | ((builder_roundrobin1_grant == 1'd0) & main_sdram_interface_bank1_wdata_ready)) | ((builder_roundrobin2_grant == 1'd0) & main_sdram_interface_bank2_wdata_ready)) | ((builder_roundrobin3_grant == 1'd0) & main_sdram_interface_bank3_wdata_ready)) | ((builder_roundrobin4_grant == 1'd0) & main_sdram_interface_bank4_wdata_ready)) | ((builder_roundrobin5_grant == 1'd0) & main_sdram_interface_bank5_wdata_ready)) | ((builder_roundrobin6_grant == 1'd0) & main_sdram_interface_bank6_wdata_ready)) | ((builder_roundrobin7_grant == 1'd0) & main_sdram_interface_bank7_wdata_ready));
+    builder_new_master_wdata_ready1 <= builder_new_master_wdata_ready0;
+    builder_new_master_wdata_ready2 <= builder_new_master_wdata_ready1;
+    builder_new_master_rdata_valid0 <= ((((((((1'd0 | ((builder_roundrobin0_grant == 1'd0) & main_sdram_interface_bank0_rdata_valid)) | ((builder_roundrobin1_grant == 1'd0) & main_sdram_interface_bank1_rdata_valid)) | ((builder_roundrobin2_grant == 1'd0) & main_sdram_interface_bank2_rdata_valid)) | ((builder_roundrobin3_grant == 1'd0) & main_sdram_interface_bank3_rdata_valid)) | ((builder_roundrobin4_grant == 1'd0) & main_sdram_interface_bank4_rdata_valid)) | ((builder_roundrobin5_grant == 1'd0) & main_sdram_interface_bank5_rdata_valid)) | ((builder_roundrobin6_grant == 1'd0) & main_sdram_interface_bank6_rdata_valid)) | ((builder_roundrobin7_grant == 1'd0) & main_sdram_interface_bank7_rdata_valid));
+    builder_new_master_rdata_valid1 <= builder_new_master_rdata_valid0;
+    builder_new_master_rdata_valid2 <= builder_new_master_rdata_valid1;
+    builder_new_master_rdata_valid3 <= builder_new_master_rdata_valid2;
+    builder_new_master_rdata_valid4 <= builder_new_master_rdata_valid3;
+    builder_new_master_rdata_valid5 <= builder_new_master_rdata_valid4;
+    builder_new_master_rdata_valid6 <= builder_new_master_rdata_valid5;
+    builder_new_master_rdata_valid7 <= builder_new_master_rdata_valid6;
+    builder_new_master_rdata_valid8 <= builder_new_master_rdata_valid7;
+    builder_new_master_rdata_valid9 <= builder_new_master_rdata_valid8;
+    main_adr_offset_r <= main_interface0_wb_sdram_adr[1:0];
+    builder_fullmemorywe_state <= builder_fullmemorywe_next_state;
+    builder_litedramwishbone2native_state <= builder_litedramwishbone2native_next_state;
+    if (main_count_next_value_ce) begin
+      main_count <= main_count_next_value;
+    end
+    case (builder_minsoc_grant)
+      1'd0: begin
+        if ((~builder_minsoc_request[0])) begin
+          if (builder_minsoc_request[1]) begin
+            builder_minsoc_grant <= 1'd1;
+          end
+        end
+      end
+      1'd1: begin
+        if ((~builder_minsoc_request[1])) begin
+          if (builder_minsoc_request[0]) begin
+            builder_minsoc_grant <= 1'd0;
+          end
+        end
+      end
+    endcase
+    builder_minsoc_slave_sel_r <= builder_minsoc_slave_sel;
+    if (builder_minsoc_wait) begin
+      if ((~builder_minsoc_done)) begin
+        builder_minsoc_count <= (builder_minsoc_count - 1'd1);
+      end
+    end else begin
+      builder_minsoc_count <= 20'd1000000;
+    end
+    builder_minsoc_interface0_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank0_sel) begin
+      case (builder_minsoc_interface0_bank_bus_adr[3:0])
+        1'd0: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_reset0_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_scratch3_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_scratch2_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_scratch1_w;
+        end
+        3'd4: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_scratch0_w;
+        end
+        3'd5: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_bus_errors3_w;
+        end
+        3'd6: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_bus_errors2_w;
+        end
+        3'd7: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_bus_errors1_w;
+        end
+        4'd8: begin
+          builder_minsoc_interface0_bank_bus_dat_r <= builder_minsoc_csrbank0_bus_errors0_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank0_reset0_re) begin
+      main_minsoc_ctrl_reset_storage <= builder_minsoc_csrbank0_reset0_r;
+    end
+    main_minsoc_ctrl_reset_re <= builder_minsoc_csrbank0_reset0_re;
+    if (builder_minsoc_csrbank0_scratch3_re) begin
+      main_minsoc_ctrl_scratch_storage[31:24] <= builder_minsoc_csrbank0_scratch3_r;
+    end
+    if (builder_minsoc_csrbank0_scratch2_re) begin
+      main_minsoc_ctrl_scratch_storage[23:16] <= builder_minsoc_csrbank0_scratch2_r;
+    end
+    if (builder_minsoc_csrbank0_scratch1_re) begin
+      main_minsoc_ctrl_scratch_storage[15:8] <= builder_minsoc_csrbank0_scratch1_r;
+    end
+    if (builder_minsoc_csrbank0_scratch0_re) begin
+      main_minsoc_ctrl_scratch_storage[7:0] <= builder_minsoc_csrbank0_scratch0_r;
+    end
+    main_minsoc_ctrl_scratch_re <= builder_minsoc_csrbank0_scratch0_re;
+    builder_minsoc_interface1_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank1_sel) begin
+      case (builder_minsoc_interface1_bank_bus_adr[2:0])
+        1'd0: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= builder_minsoc_csrbank1_half_sys8x_taps0_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_cdly_rst_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_cdly_inc_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= builder_minsoc_csrbank1_dly_sel0_w;
+        end
+        3'd4: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_rdly_dq_rst_w;
+        end
+        3'd5: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_rdly_dq_inc_w;
+        end
+        3'd6: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_rdly_dq_bitslip_rst_w;
+        end
+        3'd7: begin
+          builder_minsoc_interface1_bank_bus_dat_r <= main_a7ddrphy_rdly_dq_bitslip_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank1_half_sys8x_taps0_re) begin
+      main_a7ddrphy_half_sys8x_taps_storage[4:0] <= builder_minsoc_csrbank1_half_sys8x_taps0_r;
+    end
+    main_a7ddrphy_half_sys8x_taps_re <= builder_minsoc_csrbank1_half_sys8x_taps0_re;
+    if (builder_minsoc_csrbank1_dly_sel0_re) begin
+      main_a7ddrphy_dly_sel_storage[1:0] <= builder_minsoc_csrbank1_dly_sel0_r;
+    end
+    main_a7ddrphy_dly_sel_re <= builder_minsoc_csrbank1_dly_sel0_re;
+    builder_minsoc_interface2_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank2_sel) begin
+      case (builder_minsoc_interface2_bank_bus_adr[5:0])
+        1'd0: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_control0_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_command0_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= main_sdram_phaseinjector0_command_issue_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_address1_w;
+        end
+        3'd4: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_address0_w;
+        end
+        3'd5: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_baddress0_w;
+        end
+        3'd6: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_wrdata3_w;
+        end
+        3'd7: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_wrdata2_w;
+        end
+        4'd8: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_wrdata1_w;
+        end
+        4'd9: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_wrdata0_w;
+        end
+        4'd10: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_rddata3_w;
+        end
+        4'd11: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_rddata2_w;
+        end
+        4'd12: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_rddata1_w;
+        end
+        4'd13: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi0_rddata0_w;
+        end
+        4'd14: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_command0_w;
+        end
+        4'd15: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= main_sdram_phaseinjector1_command_issue_w;
+        end
+        5'd16: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_address1_w;
+        end
+        5'd17: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_address0_w;
+        end
+        5'd18: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_baddress0_w;
+        end
+        5'd19: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_wrdata3_w;
+        end
+        5'd20: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_wrdata2_w;
+        end
+        5'd21: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_wrdata1_w;
+        end
+        5'd22: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_wrdata0_w;
+        end
+        5'd23: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_rddata3_w;
+        end
+        5'd24: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_rddata2_w;
+        end
+        5'd25: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_rddata1_w;
+        end
+        5'd26: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi1_rddata0_w;
+        end
+        5'd27: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_command0_w;
+        end
+        5'd28: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= main_sdram_phaseinjector2_command_issue_w;
+        end
+        5'd29: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_address1_w;
+        end
+        5'd30: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_address0_w;
+        end
+        5'd31: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_baddress0_w;
+        end
+        6'd32: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_wrdata3_w;
+        end
+        6'd33: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_wrdata2_w;
+        end
+        6'd34: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_wrdata1_w;
+        end
+        6'd35: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_wrdata0_w;
+        end
+        6'd36: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_rddata3_w;
+        end
+        6'd37: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_rddata2_w;
+        end
+        6'd38: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_rddata1_w;
+        end
+        6'd39: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi2_rddata0_w;
+        end
+        6'd40: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_command0_w;
+        end
+        6'd41: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= main_sdram_phaseinjector3_command_issue_w;
+        end
+        6'd42: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_address1_w;
+        end
+        6'd43: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_address0_w;
+        end
+        6'd44: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_baddress0_w;
+        end
+        6'd45: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_wrdata3_w;
+        end
+        6'd46: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_wrdata2_w;
+        end
+        6'd47: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_wrdata1_w;
+        end
+        6'd48: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_wrdata0_w;
+        end
+        6'd49: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_rddata3_w;
+        end
+        6'd50: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_rddata2_w;
+        end
+        6'd51: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_rddata1_w;
+        end
+        6'd52: begin
+          builder_minsoc_interface2_bank_bus_dat_r <= builder_minsoc_csrbank2_dfii_pi3_rddata0_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank2_dfii_control0_re) begin
+      main_sdram_storage[3:0] <= builder_minsoc_csrbank2_dfii_control0_r;
+    end
+    main_sdram_re <= builder_minsoc_csrbank2_dfii_control0_re;
+    if (builder_minsoc_csrbank2_dfii_pi0_command0_re) begin
+      main_sdram_phaseinjector0_command_storage[5:0] <= builder_minsoc_csrbank2_dfii_pi0_command0_r;
+    end
+    main_sdram_phaseinjector0_command_re <= builder_minsoc_csrbank2_dfii_pi0_command0_re;
+    if (builder_minsoc_csrbank2_dfii_pi0_address1_re) begin
+      main_sdram_phaseinjector0_address_storage[13:8] <= builder_minsoc_csrbank2_dfii_pi0_address1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi0_address0_re) begin
+      main_sdram_phaseinjector0_address_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi0_address0_r;
+    end
+    main_sdram_phaseinjector0_address_re <= builder_minsoc_csrbank2_dfii_pi0_address0_re;
+    if (builder_minsoc_csrbank2_dfii_pi0_baddress0_re) begin
+      main_sdram_phaseinjector0_baddress_storage[2:0] <= builder_minsoc_csrbank2_dfii_pi0_baddress0_r;
+    end
+    main_sdram_phaseinjector0_baddress_re <= builder_minsoc_csrbank2_dfii_pi0_baddress0_re;
+    if (builder_minsoc_csrbank2_dfii_pi0_wrdata3_re) begin
+      main_sdram_phaseinjector0_wrdata_storage[31:24] <= builder_minsoc_csrbank2_dfii_pi0_wrdata3_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi0_wrdata2_re) begin
+      main_sdram_phaseinjector0_wrdata_storage[23:16] <= builder_minsoc_csrbank2_dfii_pi0_wrdata2_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi0_wrdata1_re) begin
+      main_sdram_phaseinjector0_wrdata_storage[15:8] <= builder_minsoc_csrbank2_dfii_pi0_wrdata1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi0_wrdata0_re) begin
+      main_sdram_phaseinjector0_wrdata_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi0_wrdata0_r;
+    end
+    main_sdram_phaseinjector0_wrdata_re <= builder_minsoc_csrbank2_dfii_pi0_wrdata0_re;
+    if (builder_minsoc_csrbank2_dfii_pi1_command0_re) begin
+      main_sdram_phaseinjector1_command_storage[5:0] <= builder_minsoc_csrbank2_dfii_pi1_command0_r;
+    end
+    main_sdram_phaseinjector1_command_re <= builder_minsoc_csrbank2_dfii_pi1_command0_re;
+    if (builder_minsoc_csrbank2_dfii_pi1_address1_re) begin
+      main_sdram_phaseinjector1_address_storage[13:8] <= builder_minsoc_csrbank2_dfii_pi1_address1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi1_address0_re) begin
+      main_sdram_phaseinjector1_address_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi1_address0_r;
+    end
+    main_sdram_phaseinjector1_address_re <= builder_minsoc_csrbank2_dfii_pi1_address0_re;
+    if (builder_minsoc_csrbank2_dfii_pi1_baddress0_re) begin
+      main_sdram_phaseinjector1_baddress_storage[2:0] <= builder_minsoc_csrbank2_dfii_pi1_baddress0_r;
+    end
+    main_sdram_phaseinjector1_baddress_re <= builder_minsoc_csrbank2_dfii_pi1_baddress0_re;
+    if (builder_minsoc_csrbank2_dfii_pi1_wrdata3_re) begin
+      main_sdram_phaseinjector1_wrdata_storage[31:24] <= builder_minsoc_csrbank2_dfii_pi1_wrdata3_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi1_wrdata2_re) begin
+      main_sdram_phaseinjector1_wrdata_storage[23:16] <= builder_minsoc_csrbank2_dfii_pi1_wrdata2_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi1_wrdata1_re) begin
+      main_sdram_phaseinjector1_wrdata_storage[15:8] <= builder_minsoc_csrbank2_dfii_pi1_wrdata1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi1_wrdata0_re) begin
+      main_sdram_phaseinjector1_wrdata_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi1_wrdata0_r;
+    end
+    main_sdram_phaseinjector1_wrdata_re <= builder_minsoc_csrbank2_dfii_pi1_wrdata0_re;
+    if (builder_minsoc_csrbank2_dfii_pi2_command0_re) begin
+      main_sdram_phaseinjector2_command_storage[5:0] <= builder_minsoc_csrbank2_dfii_pi2_command0_r;
+    end
+    main_sdram_phaseinjector2_command_re <= builder_minsoc_csrbank2_dfii_pi2_command0_re;
+    if (builder_minsoc_csrbank2_dfii_pi2_address1_re) begin
+      main_sdram_phaseinjector2_address_storage[13:8] <= builder_minsoc_csrbank2_dfii_pi2_address1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi2_address0_re) begin
+      main_sdram_phaseinjector2_address_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi2_address0_r;
+    end
+    main_sdram_phaseinjector2_address_re <= builder_minsoc_csrbank2_dfii_pi2_address0_re;
+    if (builder_minsoc_csrbank2_dfii_pi2_baddress0_re) begin
+      main_sdram_phaseinjector2_baddress_storage[2:0] <= builder_minsoc_csrbank2_dfii_pi2_baddress0_r;
+    end
+    main_sdram_phaseinjector2_baddress_re <= builder_minsoc_csrbank2_dfii_pi2_baddress0_re;
+    if (builder_minsoc_csrbank2_dfii_pi2_wrdata3_re) begin
+      main_sdram_phaseinjector2_wrdata_storage[31:24] <= builder_minsoc_csrbank2_dfii_pi2_wrdata3_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi2_wrdata2_re) begin
+      main_sdram_phaseinjector2_wrdata_storage[23:16] <= builder_minsoc_csrbank2_dfii_pi2_wrdata2_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi2_wrdata1_re) begin
+      main_sdram_phaseinjector2_wrdata_storage[15:8] <= builder_minsoc_csrbank2_dfii_pi2_wrdata1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi2_wrdata0_re) begin
+      main_sdram_phaseinjector2_wrdata_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi2_wrdata0_r;
+    end
+    main_sdram_phaseinjector2_wrdata_re <= builder_minsoc_csrbank2_dfii_pi2_wrdata0_re;
+    if (builder_minsoc_csrbank2_dfii_pi3_command0_re) begin
+      main_sdram_phaseinjector3_command_storage[5:0] <= builder_minsoc_csrbank2_dfii_pi3_command0_r;
+    end
+    main_sdram_phaseinjector3_command_re <= builder_minsoc_csrbank2_dfii_pi3_command0_re;
+    if (builder_minsoc_csrbank2_dfii_pi3_address1_re) begin
+      main_sdram_phaseinjector3_address_storage[13:8] <= builder_minsoc_csrbank2_dfii_pi3_address1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi3_address0_re) begin
+      main_sdram_phaseinjector3_address_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi3_address0_r;
+    end
+    main_sdram_phaseinjector3_address_re <= builder_minsoc_csrbank2_dfii_pi3_address0_re;
+    if (builder_minsoc_csrbank2_dfii_pi3_baddress0_re) begin
+      main_sdram_phaseinjector3_baddress_storage[2:0] <= builder_minsoc_csrbank2_dfii_pi3_baddress0_r;
+    end
+    main_sdram_phaseinjector3_baddress_re <= builder_minsoc_csrbank2_dfii_pi3_baddress0_re;
+    if (builder_minsoc_csrbank2_dfii_pi3_wrdata3_re) begin
+      main_sdram_phaseinjector3_wrdata_storage[31:24] <= builder_minsoc_csrbank2_dfii_pi3_wrdata3_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi3_wrdata2_re) begin
+      main_sdram_phaseinjector3_wrdata_storage[23:16] <= builder_minsoc_csrbank2_dfii_pi3_wrdata2_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi3_wrdata1_re) begin
+      main_sdram_phaseinjector3_wrdata_storage[15:8] <= builder_minsoc_csrbank2_dfii_pi3_wrdata1_r;
+    end
+    if (builder_minsoc_csrbank2_dfii_pi3_wrdata0_re) begin
+      main_sdram_phaseinjector3_wrdata_storage[7:0] <= builder_minsoc_csrbank2_dfii_pi3_wrdata0_r;
+    end
+    main_sdram_phaseinjector3_wrdata_re <= builder_minsoc_csrbank2_dfii_pi3_wrdata0_re;
+    builder_minsoc_interface3_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank3_sel) begin
+      case (builder_minsoc_interface3_bank_bus_adr[4:0])
+        1'd0: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_load3_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_load2_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_load1_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_load0_w;
+        end
+        3'd4: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_reload3_w;
+        end
+        3'd5: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_reload2_w;
+        end
+        3'd6: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_reload1_w;
+        end
+        3'd7: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_reload0_w;
+        end
+        4'd8: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_en0_w;
+        end
+        4'd9: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_update_value0_w;
+        end
+        4'd10: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_value3_w;
+        end
+        4'd11: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_value2_w;
+        end
+        4'd12: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_value1_w;
+        end
+        4'd13: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_value0_w;
+        end
+        4'd14: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= main_minsoc_timer0_eventmanager_status_w;
+        end
+        4'd15: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= main_minsoc_timer0_eventmanager_pending_w;
+        end
+        5'd16: begin
+          builder_minsoc_interface3_bank_bus_dat_r <= builder_minsoc_csrbank3_ev_enable0_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank3_load3_re) begin
+      main_minsoc_timer0_load_storage[31:24] <= builder_minsoc_csrbank3_load3_r;
+    end
+    if (builder_minsoc_csrbank3_load2_re) begin
+      main_minsoc_timer0_load_storage[23:16] <= builder_minsoc_csrbank3_load2_r;
+    end
+    if (builder_minsoc_csrbank3_load1_re) begin
+      main_minsoc_timer0_load_storage[15:8] <= builder_minsoc_csrbank3_load1_r;
+    end
+    if (builder_minsoc_csrbank3_load0_re) begin
+      main_minsoc_timer0_load_storage[7:0] <= builder_minsoc_csrbank3_load0_r;
+    end
+    main_minsoc_timer0_load_re <= builder_minsoc_csrbank3_load0_re;
+    if (builder_minsoc_csrbank3_reload3_re) begin
+      main_minsoc_timer0_reload_storage[31:24] <= builder_minsoc_csrbank3_reload3_r;
+    end
+    if (builder_minsoc_csrbank3_reload2_re) begin
+      main_minsoc_timer0_reload_storage[23:16] <= builder_minsoc_csrbank3_reload2_r;
+    end
+    if (builder_minsoc_csrbank3_reload1_re) begin
+      main_minsoc_timer0_reload_storage[15:8] <= builder_minsoc_csrbank3_reload1_r;
+    end
+    if (builder_minsoc_csrbank3_reload0_re) begin
+      main_minsoc_timer0_reload_storage[7:0] <= builder_minsoc_csrbank3_reload0_r;
+    end
+    main_minsoc_timer0_reload_re <= builder_minsoc_csrbank3_reload0_re;
+    if (builder_minsoc_csrbank3_en0_re) begin
+      main_minsoc_timer0_en_storage <= builder_minsoc_csrbank3_en0_r;
+    end
+    main_minsoc_timer0_en_re <= builder_minsoc_csrbank3_en0_re;
+    if (builder_minsoc_csrbank3_update_value0_re) begin
+      main_minsoc_timer0_update_value_storage <= builder_minsoc_csrbank3_update_value0_r;
+    end
+    main_minsoc_timer0_update_value_re <= builder_minsoc_csrbank3_update_value0_re;
+    if (builder_minsoc_csrbank3_ev_enable0_re) begin
+      main_minsoc_timer0_eventmanager_storage <= builder_minsoc_csrbank3_ev_enable0_r;
+    end
+    main_minsoc_timer0_eventmanager_re <= builder_minsoc_csrbank3_ev_enable0_re;
+    builder_minsoc_interface4_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank4_sel) begin
+      case (builder_minsoc_interface4_bank_bus_adr[2:0])
+        1'd0: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= main_minsoc_uart_rxtx_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= builder_minsoc_csrbank4_txfull_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= builder_minsoc_csrbank4_rxempty_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= main_minsoc_uart_eventmanager_status_w;
+        end
+        3'd4: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= main_minsoc_uart_eventmanager_pending_w;
+        end
+        3'd5: begin
+          builder_minsoc_interface4_bank_bus_dat_r <= builder_minsoc_csrbank4_ev_enable0_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank4_ev_enable0_re) begin
+      main_minsoc_uart_eventmanager_storage[1:0] <= builder_minsoc_csrbank4_ev_enable0_r;
+    end
+    main_minsoc_uart_eventmanager_re <= builder_minsoc_csrbank4_ev_enable0_re;
+    builder_minsoc_interface5_bank_bus_dat_r <= 1'd0;
+    if (builder_minsoc_csrbank5_sel) begin
+      case (builder_minsoc_interface5_bank_bus_adr[1:0])
+        1'd0: begin
+          builder_minsoc_interface5_bank_bus_dat_r <= builder_minsoc_csrbank5_tuning_word3_w;
+        end
+        1'd1: begin
+          builder_minsoc_interface5_bank_bus_dat_r <= builder_minsoc_csrbank5_tuning_word2_w;
+        end
+        2'd2: begin
+          builder_minsoc_interface5_bank_bus_dat_r <= builder_minsoc_csrbank5_tuning_word1_w;
+        end
+        2'd3: begin
+          builder_minsoc_interface5_bank_bus_dat_r <= builder_minsoc_csrbank5_tuning_word0_w;
+        end
+      endcase
+    end
+    if (builder_minsoc_csrbank5_tuning_word3_re) begin
+      main_minsoc_storage[31:24] <= builder_minsoc_csrbank5_tuning_word3_r;
+    end
+    if (builder_minsoc_csrbank5_tuning_word2_re) begin
+      main_minsoc_storage[23:16] <= builder_minsoc_csrbank5_tuning_word2_r;
+    end
+    if (builder_minsoc_csrbank5_tuning_word1_re) begin
+      main_minsoc_storage[15:8] <= builder_minsoc_csrbank5_tuning_word1_r;
+    end
+    if (builder_minsoc_csrbank5_tuning_word0_re) begin
+      main_minsoc_storage[7:0] <= builder_minsoc_csrbank5_tuning_word0_r;
+    end
+    main_minsoc_re <= builder_minsoc_csrbank5_tuning_word0_re;
+    if (sys_rst) begin
+      main_minsoc_ctrl_reset_storage <= 1'd0;
+      main_minsoc_ctrl_reset_re <= 1'd0;
+      main_minsoc_ctrl_scratch_storage <= 32'd305419896;
+      main_minsoc_ctrl_scratch_re <= 1'd0;
+      main_minsoc_ctrl_bus_errors <= 32'd0;
+      main_minsoc_rom_bus_ack <= 1'd0;
+      main_minsoc_sram_bus_ack <= 1'd0;
+      serial_tx <= 1'd1;
+      main_minsoc_storage <= 32'd8246337;
+      main_minsoc_re <= 1'd0;
+      main_minsoc_sink_ready <= 1'd0;
+      main_minsoc_uart_clk_txen <= 1'd0;
+      main_minsoc_phase_accumulator_tx <= 32'd0;
+      main_minsoc_tx_reg <= 8'd0;
+      main_minsoc_tx_bitcount <= 4'd0;
+      main_minsoc_tx_busy <= 1'd0;
+      main_minsoc_source_valid <= 1'd0;
+      main_minsoc_source_payload_data <= 8'd0;
+      main_minsoc_uart_clk_rxen <= 1'd0;
+      main_minsoc_phase_accumulator_rx <= 32'd0;
+      main_minsoc_rx_r <= 1'd0;
+      main_minsoc_rx_reg <= 8'd0;
+      main_minsoc_rx_bitcount <= 4'd0;
+      main_minsoc_rx_busy <= 1'd0;
+      main_minsoc_uart_tx_pending <= 1'd0;
+      main_minsoc_uart_tx_old_trigger <= 1'd0;
+      main_minsoc_uart_rx_pending <= 1'd0;
+      main_minsoc_uart_rx_old_trigger <= 1'd0;
+      main_minsoc_uart_eventmanager_storage <= 2'd0;
+      main_minsoc_uart_eventmanager_re <= 1'd0;
+      main_minsoc_uart_tx_fifo_readable <= 1'd0;
+      main_minsoc_uart_tx_fifo_level0 <= 5'd0;
+      main_minsoc_uart_tx_fifo_produce <= 4'd0;
+      main_minsoc_uart_tx_fifo_consume <= 4'd0;
+      main_minsoc_uart_rx_fifo_readable <= 1'd0;
+      main_minsoc_uart_rx_fifo_level0 <= 5'd0;
+      main_minsoc_uart_rx_fifo_produce <= 4'd0;
+      main_minsoc_uart_rx_fifo_consume <= 4'd0;
+      main_minsoc_timer0_load_storage <= 32'd0;
+      main_minsoc_timer0_load_re <= 1'd0;
+      main_minsoc_timer0_reload_storage <= 32'd0;
+      main_minsoc_timer0_reload_re <= 1'd0;
+      main_minsoc_timer0_en_storage <= 1'd0;
+      main_minsoc_timer0_en_re <= 1'd0;
+      main_minsoc_timer0_update_value_storage <= 1'd0;
+      main_minsoc_timer0_update_value_re <= 1'd0;
+      main_minsoc_timer0_value_status <= 32'd0;
+      main_minsoc_timer0_zero_pending <= 1'd0;
+      main_minsoc_timer0_zero_old_trigger <= 1'd0;
+      main_minsoc_timer0_eventmanager_storage <= 1'd0;
+      main_minsoc_timer0_eventmanager_re <= 1'd0;
+      main_minsoc_timer0_value <= 32'd0;
+      main_a7ddrphy_half_sys8x_taps_storage <= 5'd13;
+      main_a7ddrphy_half_sys8x_taps_re <= 1'd0;
+      main_a7ddrphy_dly_sel_storage <= 2'd0;
+      main_a7ddrphy_dly_sel_re <= 1'd0;
+      main_a7ddrphy_dfi_p0_rddata_valid <= 1'd0;
+      main_a7ddrphy_dfi_p1_rddata_valid <= 1'd0;
+      main_a7ddrphy_dfi_p2_rddata_valid <= 1'd0;
+      main_a7ddrphy_dfi_p3_rddata_valid <= 1'd0;
+      main_a7ddrphy_oe_dqs <= 1'd0;
+      main_a7ddrphy_oe_dq <= 1'd0;
+      main_a7ddrphy_bitslip0_o <= 8'd0;
+      main_a7ddrphy_bitslip0_value <= 3'd0;
+      main_a7ddrphy_bitslip0_r <= 16'd0;
+      main_a7ddrphy_bitslip1_o <= 8'd0;
+      main_a7ddrphy_bitslip1_value <= 3'd0;
+      main_a7ddrphy_bitslip1_r <= 16'd0;
+      main_a7ddrphy_bitslip2_o <= 8'd0;
+      main_a7ddrphy_bitslip2_value <= 3'd0;
+      main_a7ddrphy_bitslip2_r <= 16'd0;
+      main_a7ddrphy_bitslip3_o <= 8'd0;
+      main_a7ddrphy_bitslip3_value <= 3'd0;
+      main_a7ddrphy_bitslip3_r <= 16'd0;
+      main_a7ddrphy_bitslip4_o <= 8'd0;
+      main_a7ddrphy_bitslip4_value <= 3'd0;
+      main_a7ddrphy_bitslip4_r <= 16'd0;
+      main_a7ddrphy_bitslip5_o <= 8'd0;
+      main_a7ddrphy_bitslip5_value <= 3'd0;
+      main_a7ddrphy_bitslip5_r <= 16'd0;
+      main_a7ddrphy_bitslip6_o <= 8'd0;
+      main_a7ddrphy_bitslip6_value <= 3'd0;
+      main_a7ddrphy_bitslip6_r <= 16'd0;
+      main_a7ddrphy_bitslip7_o <= 8'd0;
+      main_a7ddrphy_bitslip7_value <= 3'd0;
+      main_a7ddrphy_bitslip7_r <= 16'd0;
+      main_a7ddrphy_bitslip8_o <= 8'd0;
+      main_a7ddrphy_bitslip8_value <= 3'd0;
+      main_a7ddrphy_bitslip8_r <= 16'd0;
+      main_a7ddrphy_bitslip9_o <= 8'd0;
+      main_a7ddrphy_bitslip9_value <= 3'd0;
+      main_a7ddrphy_bitslip9_r <= 16'd0;
+      main_a7ddrphy_bitslip10_o <= 8'd0;
+      main_a7ddrphy_bitslip10_value <= 3'd0;
+      main_a7ddrphy_bitslip10_r <= 16'd0;
+      main_a7ddrphy_bitslip11_o <= 8'd0;
+      main_a7ddrphy_bitslip11_value <= 3'd0;
+      main_a7ddrphy_bitslip11_r <= 16'd0;
+      main_a7ddrphy_bitslip12_o <= 8'd0;
+      main_a7ddrphy_bitslip12_value <= 3'd0;
+      main_a7ddrphy_bitslip12_r <= 16'd0;
+      main_a7ddrphy_bitslip13_o <= 8'd0;
+      main_a7ddrphy_bitslip13_value <= 3'd0;
+      main_a7ddrphy_bitslip13_r <= 16'd0;
+      main_a7ddrphy_bitslip14_o <= 8'd0;
+      main_a7ddrphy_bitslip14_value <= 3'd0;
+      main_a7ddrphy_bitslip14_r <= 16'd0;
+      main_a7ddrphy_bitslip15_o <= 8'd0;
+      main_a7ddrphy_bitslip15_value <= 3'd0;
+      main_a7ddrphy_bitslip15_r <= 16'd0;
+      main_a7ddrphy_n_rddata_en0 <= 1'd0;
+      main_a7ddrphy_n_rddata_en1 <= 1'd0;
+      main_a7ddrphy_n_rddata_en2 <= 1'd0;
+      main_a7ddrphy_n_rddata_en3 <= 1'd0;
+      main_a7ddrphy_n_rddata_en4 <= 1'd0;
+      main_a7ddrphy_n_rddata_en5 <= 1'd0;
+      main_a7ddrphy_n_rddata_en6 <= 1'd0;
+      main_a7ddrphy_n_rddata_en7 <= 1'd0;
+      main_a7ddrphy_last_wrdata_en <= 4'd0;
+      main_sdram_storage <= 4'd0;
+      main_sdram_re <= 1'd0;
+      main_sdram_phaseinjector0_command_storage <= 6'd0;
+      main_sdram_phaseinjector0_command_re <= 1'd0;
+      main_sdram_phaseinjector0_address_storage <= 14'd0;
+      main_sdram_phaseinjector0_address_re <= 1'd0;
+      main_sdram_phaseinjector0_baddress_storage <= 3'd0;
+      main_sdram_phaseinjector0_baddress_re <= 1'd0;
+      main_sdram_phaseinjector0_wrdata_storage <= 32'd0;
+      main_sdram_phaseinjector0_wrdata_re <= 1'd0;
+      main_sdram_phaseinjector0_status <= 32'd0;
+      main_sdram_phaseinjector1_command_storage <= 6'd0;
+      main_sdram_phaseinjector1_command_re <= 1'd0;
+      main_sdram_phaseinjector1_address_storage <= 14'd0;
+      main_sdram_phaseinjector1_address_re <= 1'd0;
+      main_sdram_phaseinjector1_baddress_storage <= 3'd0;
+      main_sdram_phaseinjector1_baddress_re <= 1'd0;
+      main_sdram_phaseinjector1_wrdata_storage <= 32'd0;
+      main_sdram_phaseinjector1_wrdata_re <= 1'd0;
+      main_sdram_phaseinjector1_status <= 32'd0;
+      main_sdram_phaseinjector2_command_storage <= 6'd0;
+      main_sdram_phaseinjector2_command_re <= 1'd0;
+      main_sdram_phaseinjector2_address_storage <= 14'd0;
+      main_sdram_phaseinjector2_address_re <= 1'd0;
+      main_sdram_phaseinjector2_baddress_storage <= 3'd0;
+      main_sdram_phaseinjector2_baddress_re <= 1'd0;
+      main_sdram_phaseinjector2_wrdata_storage <= 32'd0;
+      main_sdram_phaseinjector2_wrdata_re <= 1'd0;
+      main_sdram_phaseinjector2_status <= 32'd0;
+      main_sdram_phaseinjector3_command_storage <= 6'd0;
+      main_sdram_phaseinjector3_command_re <= 1'd0;
+      main_sdram_phaseinjector3_address_storage <= 14'd0;
+      main_sdram_phaseinjector3_address_re <= 1'd0;
+      main_sdram_phaseinjector3_baddress_storage <= 3'd0;
+      main_sdram_phaseinjector3_baddress_re <= 1'd0;
+      main_sdram_phaseinjector3_wrdata_storage <= 32'd0;
+      main_sdram_phaseinjector3_wrdata_re <= 1'd0;
+      main_sdram_phaseinjector3_status <= 32'd0;
+      main_sdram_dfi_p0_address <= 14'd0;
+      main_sdram_dfi_p0_bank <= 3'd0;
+      main_sdram_dfi_p0_cas_n <= 1'd1;
+      main_sdram_dfi_p0_cs_n <= 1'd1;
+      main_sdram_dfi_p0_ras_n <= 1'd1;
+      main_sdram_dfi_p0_we_n <= 1'd1;
+      main_sdram_dfi_p0_wrdata_en <= 1'd0;
+      main_sdram_dfi_p0_rddata_en <= 1'd0;
+      main_sdram_dfi_p1_address <= 14'd0;
+      main_sdram_dfi_p1_bank <= 3'd0;
+      main_sdram_dfi_p1_cas_n <= 1'd1;
+      main_sdram_dfi_p1_cs_n <= 1'd1;
+      main_sdram_dfi_p1_ras_n <= 1'd1;
+      main_sdram_dfi_p1_we_n <= 1'd1;
+      main_sdram_dfi_p1_wrdata_en <= 1'd0;
+      main_sdram_dfi_p1_rddata_en <= 1'd0;
+      main_sdram_dfi_p2_address <= 14'd0;
+      main_sdram_dfi_p2_bank <= 3'd0;
+      main_sdram_dfi_p2_cas_n <= 1'd1;
+      main_sdram_dfi_p2_cs_n <= 1'd1;
+      main_sdram_dfi_p2_ras_n <= 1'd1;
+      main_sdram_dfi_p2_we_n <= 1'd1;
+      main_sdram_dfi_p2_wrdata_en <= 1'd0;
+      main_sdram_dfi_p2_rddata_en <= 1'd0;
+      main_sdram_dfi_p3_address <= 14'd0;
+      main_sdram_dfi_p3_bank <= 3'd0;
+      main_sdram_dfi_p3_cas_n <= 1'd1;
+      main_sdram_dfi_p3_cs_n <= 1'd1;
+      main_sdram_dfi_p3_ras_n <= 1'd1;
+      main_sdram_dfi_p3_we_n <= 1'd1;
+      main_sdram_dfi_p3_wrdata_en <= 1'd0;
+      main_sdram_dfi_p3_rddata_en <= 1'd0;
+      main_sdram_cmd_payload_a <= 14'd0;
+      main_sdram_cmd_payload_ba <= 3'd0;
+      main_sdram_cmd_payload_cas <= 1'd0;
+      main_sdram_cmd_payload_ras <= 1'd0;
+      main_sdram_cmd_payload_we <= 1'd0;
+      main_sdram_timer_count1 <= 9'd468;
+      main_sdram_postponer_req_o <= 1'd0;
+      main_sdram_postponer_count <= 1'd0;
+      main_sdram_sequencer_done1 <= 1'd0;
+      main_sdram_sequencer_counter <= 6'd0;
+      main_sdram_sequencer_count <= 1'd0;
+      main_sdram_zqcs_timer_count1 <= 26'd59999999;
+      main_sdram_zqcs_executer_done <= 1'd0;
+      main_sdram_zqcs_executer_counter <= 5'd0;
+      main_sdram_bankmachine0_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine0_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine0_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine0_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine0_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine0_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine0_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine0_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine0_row <= 14'd0;
+      main_sdram_bankmachine0_row_opened <= 1'd0;
+      main_sdram_bankmachine0_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine0_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine0_trccon_ready <= 1'd1;
+      main_sdram_bankmachine0_trccon_count <= 2'd0;
+      main_sdram_bankmachine0_trascon_ready <= 1'd1;
+      main_sdram_bankmachine0_trascon_count <= 2'd0;
+      main_sdram_bankmachine1_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine1_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine1_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine1_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine1_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine1_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine1_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine1_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine1_row <= 14'd0;
+      main_sdram_bankmachine1_row_opened <= 1'd0;
+      main_sdram_bankmachine1_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine1_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine1_trccon_ready <= 1'd1;
+      main_sdram_bankmachine1_trccon_count <= 2'd0;
+      main_sdram_bankmachine1_trascon_ready <= 1'd1;
+      main_sdram_bankmachine1_trascon_count <= 2'd0;
+      main_sdram_bankmachine2_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine2_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine2_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine2_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine2_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine2_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine2_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine2_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine2_row <= 14'd0;
+      main_sdram_bankmachine2_row_opened <= 1'd0;
+      main_sdram_bankmachine2_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine2_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine2_trccon_ready <= 1'd1;
+      main_sdram_bankmachine2_trccon_count <= 2'd0;
+      main_sdram_bankmachine2_trascon_ready <= 1'd1;
+      main_sdram_bankmachine2_trascon_count <= 2'd0;
+      main_sdram_bankmachine3_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine3_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine3_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine3_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine3_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine3_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine3_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine3_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine3_row <= 14'd0;
+      main_sdram_bankmachine3_row_opened <= 1'd0;
+      main_sdram_bankmachine3_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine3_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine3_trccon_ready <= 1'd1;
+      main_sdram_bankmachine3_trccon_count <= 2'd0;
+      main_sdram_bankmachine3_trascon_ready <= 1'd1;
+      main_sdram_bankmachine3_trascon_count <= 2'd0;
+      main_sdram_bankmachine4_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine4_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine4_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine4_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine4_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine4_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine4_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine4_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine4_row <= 14'd0;
+      main_sdram_bankmachine4_row_opened <= 1'd0;
+      main_sdram_bankmachine4_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine4_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine4_trccon_ready <= 1'd1;
+      main_sdram_bankmachine4_trccon_count <= 2'd0;
+      main_sdram_bankmachine4_trascon_ready <= 1'd1;
+      main_sdram_bankmachine4_trascon_count <= 2'd0;
+      main_sdram_bankmachine5_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine5_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine5_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine5_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine5_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine5_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine5_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine5_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine5_row <= 14'd0;
+      main_sdram_bankmachine5_row_opened <= 1'd0;
+      main_sdram_bankmachine5_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine5_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine5_trccon_ready <= 1'd1;
+      main_sdram_bankmachine5_trccon_count <= 2'd0;
+      main_sdram_bankmachine5_trascon_ready <= 1'd1;
+      main_sdram_bankmachine5_trascon_count <= 2'd0;
+      main_sdram_bankmachine6_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine6_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine6_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine6_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine6_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine6_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine6_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine6_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine6_row <= 14'd0;
+      main_sdram_bankmachine6_row_opened <= 1'd0;
+      main_sdram_bankmachine6_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine6_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine6_trccon_ready <= 1'd1;
+      main_sdram_bankmachine6_trccon_count <= 2'd0;
+      main_sdram_bankmachine6_trascon_ready <= 1'd1;
+      main_sdram_bankmachine6_trascon_count <= 2'd0;
+      main_sdram_bankmachine7_cmd_buffer_lookahead_level <= 4'd0;
+      main_sdram_bankmachine7_cmd_buffer_lookahead_produce <= 3'd0;
+      main_sdram_bankmachine7_cmd_buffer_lookahead_consume <= 3'd0;
+      main_sdram_bankmachine7_cmd_buffer_source_valid <= 1'd0;
+      main_sdram_bankmachine7_cmd_buffer_source_first <= 1'd0;
+      main_sdram_bankmachine7_cmd_buffer_source_last <= 1'd0;
+      main_sdram_bankmachine7_cmd_buffer_source_payload_we <= 1'd0;
+      main_sdram_bankmachine7_cmd_buffer_source_payload_addr <= 21'd0;
+      main_sdram_bankmachine7_row <= 14'd0;
+      main_sdram_bankmachine7_row_opened <= 1'd0;
+      main_sdram_bankmachine7_twtpcon_ready <= 1'd1;
+      main_sdram_bankmachine7_twtpcon_count <= 3'd0;
+      main_sdram_bankmachine7_trccon_ready <= 1'd1;
+      main_sdram_bankmachine7_trccon_count <= 2'd0;
+      main_sdram_bankmachine7_trascon_ready <= 1'd1;
+      main_sdram_bankmachine7_trascon_count <= 2'd0;
+      main_sdram_choose_cmd_grant <= 3'd0;
+      main_sdram_choose_req_grant <= 3'd0;
+      main_sdram_trrdcon_ready <= 1'd1;
+      main_sdram_trrdcon_count <= 1'd0;
+      main_sdram_tfawcon_ready <= 1'd1;
+      main_sdram_tfawcon_window <= 4'd0;
+      main_sdram_tccdcon_ready <= 1'd1;
+      main_sdram_tccdcon_count <= 1'd0;
+      main_sdram_twtrcon_ready <= 1'd1;
+      main_sdram_twtrcon_count <= 3'd0;
+      main_sdram_time0 <= 5'd0;
+      main_sdram_time1 <= 4'd0;
+      main_adr_offset_r <= 2'd0;
+      main_count <= 1'd0;
+      builder_wb2csr_state <= 1'd0;
+      builder_refresher_state <= 2'd0;
+      builder_bankmachine0_state <= 3'd0;
+      builder_bankmachine1_state <= 3'd0;
+      builder_bankmachine2_state <= 3'd0;
+      builder_bankmachine3_state <= 3'd0;
+      builder_bankmachine4_state <= 3'd0;
+      builder_bankmachine5_state <= 3'd0;
+      builder_bankmachine6_state <= 3'd0;
+      builder_bankmachine7_state <= 3'd0;
+      builder_multiplexer_state <= 4'd0;
+      builder_rbank <= 3'd0;
+      builder_wbank <= 3'd0;
+      builder_new_master_wdata_ready0 <= 1'd0;
+      builder_new_master_wdata_ready1 <= 1'd0;
+      builder_new_master_wdata_ready2 <= 1'd0;
+      builder_new_master_rdata_valid0 <= 1'd0;
+      builder_new_master_rdata_valid1 <= 1'd0;
+      builder_new_master_rdata_valid2 <= 1'd0;
+      builder_new_master_rdata_valid3 <= 1'd0;
+      builder_new_master_rdata_valid4 <= 1'd0;
+      builder_new_master_rdata_valid5 <= 1'd0;
+      builder_new_master_rdata_valid6 <= 1'd0;
+      builder_new_master_rdata_valid7 <= 1'd0;
+      builder_new_master_rdata_valid8 <= 1'd0;
+      builder_new_master_rdata_valid9 <= 1'd0;
+      builder_fullmemorywe_state <= 2'd0;
+      builder_litedramwishbone2native_state <= 2'd0;
+      builder_minsoc_grant <= 1'd0;
+      builder_minsoc_slave_sel_r <= 4'd0;
+      builder_minsoc_count <= 20'd1000000;
+      builder_minsoc_interface0_bank_bus_dat_r <= 8'd0;
+      builder_minsoc_interface1_bank_bus_dat_r <= 8'd0;
+      builder_minsoc_interface2_bank_bus_dat_r <= 8'd0;
+      builder_minsoc_interface3_bank_bus_dat_r <= 8'd0;
+      builder_minsoc_interface4_bank_bus_dat_r <= 8'd0;
+      builder_minsoc_interface5_bank_bus_dat_r <= 8'd0;
+    end
+    builder_regs0 <= serial_rx;
+    builder_regs1 <= builder_regs0;
+  end
+
+  reg [31:0] mem[0:8191];
+  reg [31:0] memdat;
+  always @(posedge sys_clk) begin
+    memdat <= mem[main_minsoc_rom_adr];
+  end
+
+  assign main_minsoc_rom_dat_r = memdat;
+
+  initial begin
+    $readmemh("mem.init", mem);
+  end
+
+  reg [31:0] mem_1  [0:1023];
+  reg [ 9:0] memadr;
+  always @(posedge sys_clk) begin
+    if (main_minsoc_sram_we[0]) mem_1[main_minsoc_sram_adr][7:0] <= main_minsoc_sram_dat_w[7:0];
+    if (main_minsoc_sram_we[1]) mem_1[main_minsoc_sram_adr][15:8] <= main_minsoc_sram_dat_w[15:8];
+    if (main_minsoc_sram_we[2]) mem_1[main_minsoc_sram_adr][23:16] <= main_minsoc_sram_dat_w[23:16];
+    if (main_minsoc_sram_we[3]) mem_1[main_minsoc_sram_adr][31:24] <= main_minsoc_sram_dat_w[31:24];
+    memadr <= main_minsoc_sram_adr;
+  end
+
+  assign main_minsoc_sram_dat_r = mem_1[memadr];
+
+  initial begin
+    $readmemh("mem_1.init", mem_1);
+  end
+
+  reg [9:0] storage  [0:15];
+  reg [9:0] memdat_1;
+  reg [9:0] memdat_2;
+  always @(posedge sys_clk) begin
+    if (main_minsoc_uart_tx_fifo_wrport_we)
+      storage[main_minsoc_uart_tx_fifo_wrport_adr] <= main_minsoc_uart_tx_fifo_wrport_dat_w;
+    memdat_1 <= storage[main_minsoc_uart_tx_fifo_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+    if (main_minsoc_uart_tx_fifo_rdport_re)
+      memdat_2 <= storage[main_minsoc_uart_tx_fifo_rdport_adr];
+  end
+
+  assign main_minsoc_uart_tx_fifo_wrport_dat_r = memdat_1;
+  assign main_minsoc_uart_tx_fifo_rdport_dat_r = memdat_2;
+
+  reg [9:0] storage_1[0:15];
+  reg [9:0] memdat_3;
+  reg [9:0] memdat_4;
+  always @(posedge sys_clk) begin
+    if (main_minsoc_uart_rx_fifo_wrport_we)
+      storage_1[main_minsoc_uart_rx_fifo_wrport_adr] <= main_minsoc_uart_rx_fifo_wrport_dat_w;
+    memdat_3 <= storage_1[main_minsoc_uart_rx_fifo_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+    if (main_minsoc_uart_rx_fifo_rdport_re)
+      memdat_4 <= storage_1[main_minsoc_uart_rx_fifo_rdport_adr];
+  end
+
+  assign main_minsoc_uart_rx_fifo_wrport_dat_r = memdat_3;
+  assign main_minsoc_uart_rx_fifo_rdport_dat_r = memdat_4;
+
+  wire clk100_ibuf;
+  IBUF clkbuf (
+      .I(clk100),
+      .O(clk100_ibuf)
+  );
+
+  BUFG BUFG (
+      .I(clk100_ibuf),
+      .O(main_pll_clkin)
+  );
+
+  BUFG BUFG_1 (
+      .I(main_clkout0),
+      .O(sys_clk)
+  );
+
+  BUFG BUFG_2 (
+      .I(main_clkout1),
+      .O(sys4x_clk)
+  );
+
+  BUFG BUFG_3 (
+      .I(main_clkout2),
+      .O(sys4x_dqs_clk)
+  );
+
+  BUFG BUFG_4 (
+      .I(main_clkout3),
+      .O(clk200_clk)
+  );
+
+  (* LOC="IDELAYCTRL_X1Y0" *)
+  IDELAYCTRL IDELAYCTRL (
+      .REFCLK(clk200_clk),
+      .RST(main_ic_reset),
+      .RDY(idelayctl_rdy)
+  );
+
+  wire tq;
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(1'd0),
+      .D2(1'd1),
+      .D3(1'd0),
+      .D4(1'd1),
+      .D5(1'd0),
+      .D6(1'd1),
+      .D7(1'd0),
+      .D8(1'd1),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(main_a7ddrphy_sd_clk_se_nodelay),
+      .TQ(tq),
+      .TCE(1'b1),
+      .T1(1'b0)
+  );
+
+  OBUFTDS OBUFTDS_2 (
+      .I (main_a7ddrphy_sd_clk_se_nodelay),
+      .O (ddram_clk_p),
+      .OB(ddram_clk_n),
+      .T (tq)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_1 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[0]),
+      .D2(main_a7ddrphy_dfi_p0_address[0]),
+      .D3(main_a7ddrphy_dfi_p1_address[0]),
+      .D4(main_a7ddrphy_dfi_p1_address[0]),
+      .D5(main_a7ddrphy_dfi_p2_address[0]),
+      .D6(main_a7ddrphy_dfi_p2_address[0]),
+      .D7(main_a7ddrphy_dfi_p3_address[0]),
+      .D8(main_a7ddrphy_dfi_p3_address[0]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[0])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_2 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[1]),
+      .D2(main_a7ddrphy_dfi_p0_address[1]),
+      .D3(main_a7ddrphy_dfi_p1_address[1]),
+      .D4(main_a7ddrphy_dfi_p1_address[1]),
+      .D5(main_a7ddrphy_dfi_p2_address[1]),
+      .D6(main_a7ddrphy_dfi_p2_address[1]),
+      .D7(main_a7ddrphy_dfi_p3_address[1]),
+      .D8(main_a7ddrphy_dfi_p3_address[1]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[1])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_3 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[2]),
+      .D2(main_a7ddrphy_dfi_p0_address[2]),
+      .D3(main_a7ddrphy_dfi_p1_address[2]),
+      .D4(main_a7ddrphy_dfi_p1_address[2]),
+      .D5(main_a7ddrphy_dfi_p2_address[2]),
+      .D6(main_a7ddrphy_dfi_p2_address[2]),
+      .D7(main_a7ddrphy_dfi_p3_address[2]),
+      .D8(main_a7ddrphy_dfi_p3_address[2]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[2])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_4 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[3]),
+      .D2(main_a7ddrphy_dfi_p0_address[3]),
+      .D3(main_a7ddrphy_dfi_p1_address[3]),
+      .D4(main_a7ddrphy_dfi_p1_address[3]),
+      .D5(main_a7ddrphy_dfi_p2_address[3]),
+      .D6(main_a7ddrphy_dfi_p2_address[3]),
+      .D7(main_a7ddrphy_dfi_p3_address[3]),
+      .D8(main_a7ddrphy_dfi_p3_address[3]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[3])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_5 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[4]),
+      .D2(main_a7ddrphy_dfi_p0_address[4]),
+      .D3(main_a7ddrphy_dfi_p1_address[4]),
+      .D4(main_a7ddrphy_dfi_p1_address[4]),
+      .D5(main_a7ddrphy_dfi_p2_address[4]),
+      .D6(main_a7ddrphy_dfi_p2_address[4]),
+      .D7(main_a7ddrphy_dfi_p3_address[4]),
+      .D8(main_a7ddrphy_dfi_p3_address[4]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[4])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_6 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[5]),
+      .D2(main_a7ddrphy_dfi_p0_address[5]),
+      .D3(main_a7ddrphy_dfi_p1_address[5]),
+      .D4(main_a7ddrphy_dfi_p1_address[5]),
+      .D5(main_a7ddrphy_dfi_p2_address[5]),
+      .D6(main_a7ddrphy_dfi_p2_address[5]),
+      .D7(main_a7ddrphy_dfi_p3_address[5]),
+      .D8(main_a7ddrphy_dfi_p3_address[5]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[5])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_7 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[6]),
+      .D2(main_a7ddrphy_dfi_p0_address[6]),
+      .D3(main_a7ddrphy_dfi_p1_address[6]),
+      .D4(main_a7ddrphy_dfi_p1_address[6]),
+      .D5(main_a7ddrphy_dfi_p2_address[6]),
+      .D6(main_a7ddrphy_dfi_p2_address[6]),
+      .D7(main_a7ddrphy_dfi_p3_address[6]),
+      .D8(main_a7ddrphy_dfi_p3_address[6]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[6])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_8 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[7]),
+      .D2(main_a7ddrphy_dfi_p0_address[7]),
+      .D3(main_a7ddrphy_dfi_p1_address[7]),
+      .D4(main_a7ddrphy_dfi_p1_address[7]),
+      .D5(main_a7ddrphy_dfi_p2_address[7]),
+      .D6(main_a7ddrphy_dfi_p2_address[7]),
+      .D7(main_a7ddrphy_dfi_p3_address[7]),
+      .D8(main_a7ddrphy_dfi_p3_address[7]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[7])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_9 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[8]),
+      .D2(main_a7ddrphy_dfi_p0_address[8]),
+      .D3(main_a7ddrphy_dfi_p1_address[8]),
+      .D4(main_a7ddrphy_dfi_p1_address[8]),
+      .D5(main_a7ddrphy_dfi_p2_address[8]),
+      .D6(main_a7ddrphy_dfi_p2_address[8]),
+      .D7(main_a7ddrphy_dfi_p3_address[8]),
+      .D8(main_a7ddrphy_dfi_p3_address[8]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[8])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_10 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[9]),
+      .D2(main_a7ddrphy_dfi_p0_address[9]),
+      .D3(main_a7ddrphy_dfi_p1_address[9]),
+      .D4(main_a7ddrphy_dfi_p1_address[9]),
+      .D5(main_a7ddrphy_dfi_p2_address[9]),
+      .D6(main_a7ddrphy_dfi_p2_address[9]),
+      .D7(main_a7ddrphy_dfi_p3_address[9]),
+      .D8(main_a7ddrphy_dfi_p3_address[9]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[9])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_11 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[10]),
+      .D2(main_a7ddrphy_dfi_p0_address[10]),
+      .D3(main_a7ddrphy_dfi_p1_address[10]),
+      .D4(main_a7ddrphy_dfi_p1_address[10]),
+      .D5(main_a7ddrphy_dfi_p2_address[10]),
+      .D6(main_a7ddrphy_dfi_p2_address[10]),
+      .D7(main_a7ddrphy_dfi_p3_address[10]),
+      .D8(main_a7ddrphy_dfi_p3_address[10]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[10])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_12 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[11]),
+      .D2(main_a7ddrphy_dfi_p0_address[11]),
+      .D3(main_a7ddrphy_dfi_p1_address[11]),
+      .D4(main_a7ddrphy_dfi_p1_address[11]),
+      .D5(main_a7ddrphy_dfi_p2_address[11]),
+      .D6(main_a7ddrphy_dfi_p2_address[11]),
+      .D7(main_a7ddrphy_dfi_p3_address[11]),
+      .D8(main_a7ddrphy_dfi_p3_address[11]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[11])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_13 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[12]),
+      .D2(main_a7ddrphy_dfi_p0_address[12]),
+      .D3(main_a7ddrphy_dfi_p1_address[12]),
+      .D4(main_a7ddrphy_dfi_p1_address[12]),
+      .D5(main_a7ddrphy_dfi_p2_address[12]),
+      .D6(main_a7ddrphy_dfi_p2_address[12]),
+      .D7(main_a7ddrphy_dfi_p3_address[12]),
+      .D8(main_a7ddrphy_dfi_p3_address[12]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[12])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_14 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_address[13]),
+      .D2(main_a7ddrphy_dfi_p0_address[13]),
+      .D3(main_a7ddrphy_dfi_p1_address[13]),
+      .D4(main_a7ddrphy_dfi_p1_address[13]),
+      .D5(main_a7ddrphy_dfi_p2_address[13]),
+      .D6(main_a7ddrphy_dfi_p2_address[13]),
+      .D7(main_a7ddrphy_dfi_p3_address[13]),
+      .D8(main_a7ddrphy_dfi_p3_address[13]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_a_iob[13])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_15 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_bank[0]),
+      .D2(main_a7ddrphy_dfi_p0_bank[0]),
+      .D3(main_a7ddrphy_dfi_p1_bank[0]),
+      .D4(main_a7ddrphy_dfi_p1_bank[0]),
+      .D5(main_a7ddrphy_dfi_p2_bank[0]),
+      .D6(main_a7ddrphy_dfi_p2_bank[0]),
+      .D7(main_a7ddrphy_dfi_p3_bank[0]),
+      .D8(main_a7ddrphy_dfi_p3_bank[0]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_ba_iob[0])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_16 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_bank[1]),
+      .D2(main_a7ddrphy_dfi_p0_bank[1]),
+      .D3(main_a7ddrphy_dfi_p1_bank[1]),
+      .D4(main_a7ddrphy_dfi_p1_bank[1]),
+      .D5(main_a7ddrphy_dfi_p2_bank[1]),
+      .D6(main_a7ddrphy_dfi_p2_bank[1]),
+      .D7(main_a7ddrphy_dfi_p3_bank[1]),
+      .D8(main_a7ddrphy_dfi_p3_bank[1]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_ba_iob[1])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_17 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_bank[2]),
+      .D2(main_a7ddrphy_dfi_p0_bank[2]),
+      .D3(main_a7ddrphy_dfi_p1_bank[2]),
+      .D4(main_a7ddrphy_dfi_p1_bank[2]),
+      .D5(main_a7ddrphy_dfi_p2_bank[2]),
+      .D6(main_a7ddrphy_dfi_p2_bank[2]),
+      .D7(main_a7ddrphy_dfi_p3_bank[2]),
+      .D8(main_a7ddrphy_dfi_p3_bank[2]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_ba_iob[2])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_18 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_ras_n),
+      .D2(main_a7ddrphy_dfi_p0_ras_n),
+      .D3(main_a7ddrphy_dfi_p1_ras_n),
+      .D4(main_a7ddrphy_dfi_p1_ras_n),
+      .D5(main_a7ddrphy_dfi_p2_ras_n),
+      .D6(main_a7ddrphy_dfi_p2_ras_n),
+      .D7(main_a7ddrphy_dfi_p3_ras_n),
+      .D8(main_a7ddrphy_dfi_p3_ras_n),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_ras_n_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_19 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_cas_n),
+      .D2(main_a7ddrphy_dfi_p0_cas_n),
+      .D3(main_a7ddrphy_dfi_p1_cas_n),
+      .D4(main_a7ddrphy_dfi_p1_cas_n),
+      .D5(main_a7ddrphy_dfi_p2_cas_n),
+      .D6(main_a7ddrphy_dfi_p2_cas_n),
+      .D7(main_a7ddrphy_dfi_p3_cas_n),
+      .D8(main_a7ddrphy_dfi_p3_cas_n),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_cas_n_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_20 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_we_n),
+      .D2(main_a7ddrphy_dfi_p0_we_n),
+      .D3(main_a7ddrphy_dfi_p1_we_n),
+      .D4(main_a7ddrphy_dfi_p1_we_n),
+      .D5(main_a7ddrphy_dfi_p2_we_n),
+      .D6(main_a7ddrphy_dfi_p2_we_n),
+      .D7(main_a7ddrphy_dfi_p3_we_n),
+      .D8(main_a7ddrphy_dfi_p3_we_n),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_we_n_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_21 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_cke),
+      .D2(main_a7ddrphy_dfi_p0_cke),
+      .D3(main_a7ddrphy_dfi_p1_cke),
+      .D4(main_a7ddrphy_dfi_p1_cke),
+      .D5(main_a7ddrphy_dfi_p2_cke),
+      .D6(main_a7ddrphy_dfi_p2_cke),
+      .D7(main_a7ddrphy_dfi_p3_cke),
+      .D8(main_a7ddrphy_dfi_p3_cke),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_cke_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_22 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_odt),
+      .D2(main_a7ddrphy_dfi_p0_odt),
+      .D3(main_a7ddrphy_dfi_p1_odt),
+      .D4(main_a7ddrphy_dfi_p1_odt),
+      .D5(main_a7ddrphy_dfi_p2_odt),
+      .D6(main_a7ddrphy_dfi_p2_odt),
+      .D7(main_a7ddrphy_dfi_p3_odt),
+      .D8(main_a7ddrphy_dfi_p3_odt),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_odt_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_23 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_reset_n),
+      .D2(main_a7ddrphy_dfi_p0_reset_n),
+      .D3(main_a7ddrphy_dfi_p1_reset_n),
+      .D4(main_a7ddrphy_dfi_p1_reset_n),
+      .D5(main_a7ddrphy_dfi_p2_reset_n),
+      .D6(main_a7ddrphy_dfi_p2_reset_n),
+      .D7(main_a7ddrphy_dfi_p3_reset_n),
+      .D8(main_a7ddrphy_dfi_p3_reset_n),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_reset_n_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_24 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_cs_n),
+      .D2(main_a7ddrphy_dfi_p0_cs_n),
+      .D3(main_a7ddrphy_dfi_p1_cs_n),
+      .D4(main_a7ddrphy_dfi_p1_cs_n),
+      .D5(main_a7ddrphy_dfi_p2_cs_n),
+      .D6(main_a7ddrphy_dfi_p2_cs_n),
+      .D7(main_a7ddrphy_dfi_p3_cs_n),
+      .D8(main_a7ddrphy_dfi_p3_cs_n),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_cs_n_iob)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_25 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata_mask[0]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata_mask[2]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata_mask[0]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata_mask[2]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata_mask[0]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata_mask[2]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata_mask[0]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata_mask[2]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_dm_iob[0])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_26 (
+      .CLK(sys4x_dqs_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dqs_serdes_pattern[0]),
+      .D2(main_a7ddrphy_dqs_serdes_pattern[1]),
+      .D3(main_a7ddrphy_dqs_serdes_pattern[2]),
+      .D4(main_a7ddrphy_dqs_serdes_pattern[3]),
+      .D5(main_a7ddrphy_dqs_serdes_pattern[4]),
+      .D6(main_a7ddrphy_dqs_serdes_pattern[5]),
+      .D7(main_a7ddrphy_dqs_serdes_pattern[6]),
+      .D8(main_a7ddrphy_dqs_serdes_pattern[7]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dqs)),
+      .TCE(1'd1),
+      .OFB(main_a7ddrphy0),
+      .OQ(main_a7ddrphy_dqs_nodelay0),
+      .TQ(main_a7ddrphy_dqs_t0)
+  );
+
+  OBUFTDS OBUFTDS (
+      .I (main_a7ddrphy_dqs_nodelay0),
+      .T (main_a7ddrphy_dqs_t0),
+      .O (ddram_dqs_p[0]),
+      .OB(ddram_dqs_n[0])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_27 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata_mask[1]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata_mask[3]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata_mask[1]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata_mask[3]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata_mask[1]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata_mask[3]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata_mask[1]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata_mask[3]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .OQ(ddram_dm_iob[1])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_28 (
+      .CLK(sys4x_dqs_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dqs_serdes_pattern[0]),
+      .D2(main_a7ddrphy_dqs_serdes_pattern[1]),
+      .D3(main_a7ddrphy_dqs_serdes_pattern[2]),
+      .D4(main_a7ddrphy_dqs_serdes_pattern[3]),
+      .D5(main_a7ddrphy_dqs_serdes_pattern[4]),
+      .D6(main_a7ddrphy_dqs_serdes_pattern[5]),
+      .D7(main_a7ddrphy_dqs_serdes_pattern[6]),
+      .D8(main_a7ddrphy_dqs_serdes_pattern[7]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dqs)),
+      .TCE(1'd1),
+      .OFB(main_a7ddrphy1),
+      .OQ(main_a7ddrphy_dqs_nodelay1),
+      .TQ(main_a7ddrphy_dqs_t1)
+  );
+
+  OBUFTDS OBUFTDS_1 (
+      .I (main_a7ddrphy_dqs_nodelay1),
+      .T (main_a7ddrphy_dqs_t1),
+      .O (ddram_dqs_p[1]),
+      .OB(ddram_dqs_n[1])
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_29 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[0]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[16]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[0]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[16]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[0]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[16]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[0]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[16]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay0),
+      .TQ(main_a7ddrphy_dq_t0)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed0),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data0[7]),
+      .Q2(main_a7ddrphy_dq_i_data0[6]),
+      .Q3(main_a7ddrphy_dq_i_data0[5]),
+      .Q4(main_a7ddrphy_dq_i_data0[4]),
+      .Q5(main_a7ddrphy_dq_i_data0[3]),
+      .Q6(main_a7ddrphy_dq_i_data0[2]),
+      .Q7(main_a7ddrphy_dq_i_data0[1]),
+      .Q8(main_a7ddrphy_dq_i_data0[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay0),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed0)
+  );
+
+  IOBUF IOBUF (
+      .I (main_a7ddrphy_dq_o_nodelay0),
+      .T (main_a7ddrphy_dq_t0),
+      .IO(ddram_dq[0]),
+      .O (main_a7ddrphy_dq_i_nodelay0)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_30 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[1]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[17]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[1]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[17]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[1]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[17]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[1]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[17]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay1),
+      .TQ(main_a7ddrphy_dq_t1)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_1 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed1),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data1[7]),
+      .Q2(main_a7ddrphy_dq_i_data1[6]),
+      .Q3(main_a7ddrphy_dq_i_data1[5]),
+      .Q4(main_a7ddrphy_dq_i_data1[4]),
+      .Q5(main_a7ddrphy_dq_i_data1[3]),
+      .Q6(main_a7ddrphy_dq_i_data1[2]),
+      .Q7(main_a7ddrphy_dq_i_data1[1]),
+      .Q8(main_a7ddrphy_dq_i_data1[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_1 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay1),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed1)
+  );
+
+  IOBUF IOBUF_1 (
+      .I (main_a7ddrphy_dq_o_nodelay1),
+      .T (main_a7ddrphy_dq_t1),
+      .IO(ddram_dq[1]),
+      .O (main_a7ddrphy_dq_i_nodelay1)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_31 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[2]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[18]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[2]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[18]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[2]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[18]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[2]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[18]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay2),
+      .TQ(main_a7ddrphy_dq_t2)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_2 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed2),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data2[7]),
+      .Q2(main_a7ddrphy_dq_i_data2[6]),
+      .Q3(main_a7ddrphy_dq_i_data2[5]),
+      .Q4(main_a7ddrphy_dq_i_data2[4]),
+      .Q5(main_a7ddrphy_dq_i_data2[3]),
+      .Q6(main_a7ddrphy_dq_i_data2[2]),
+      .Q7(main_a7ddrphy_dq_i_data2[1]),
+      .Q8(main_a7ddrphy_dq_i_data2[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_2 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay2),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed2)
+  );
+
+  IOBUF IOBUF_2 (
+      .I (main_a7ddrphy_dq_o_nodelay2),
+      .T (main_a7ddrphy_dq_t2),
+      .IO(ddram_dq[2]),
+      .O (main_a7ddrphy_dq_i_nodelay2)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_32 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[3]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[19]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[3]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[19]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[3]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[19]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[3]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[19]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay3),
+      .TQ(main_a7ddrphy_dq_t3)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_3 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed3),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data3[7]),
+      .Q2(main_a7ddrphy_dq_i_data3[6]),
+      .Q3(main_a7ddrphy_dq_i_data3[5]),
+      .Q4(main_a7ddrphy_dq_i_data3[4]),
+      .Q5(main_a7ddrphy_dq_i_data3[3]),
+      .Q6(main_a7ddrphy_dq_i_data3[2]),
+      .Q7(main_a7ddrphy_dq_i_data3[1]),
+      .Q8(main_a7ddrphy_dq_i_data3[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_3 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay3),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed3)
+  );
+
+  IOBUF IOBUF_3 (
+      .I (main_a7ddrphy_dq_o_nodelay3),
+      .T (main_a7ddrphy_dq_t3),
+      .IO(ddram_dq[3]),
+      .O (main_a7ddrphy_dq_i_nodelay3)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_33 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[4]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[20]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[4]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[20]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[4]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[20]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[4]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[20]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay4),
+      .TQ(main_a7ddrphy_dq_t4)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_4 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed4),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data4[7]),
+      .Q2(main_a7ddrphy_dq_i_data4[6]),
+      .Q3(main_a7ddrphy_dq_i_data4[5]),
+      .Q4(main_a7ddrphy_dq_i_data4[4]),
+      .Q5(main_a7ddrphy_dq_i_data4[3]),
+      .Q6(main_a7ddrphy_dq_i_data4[2]),
+      .Q7(main_a7ddrphy_dq_i_data4[1]),
+      .Q8(main_a7ddrphy_dq_i_data4[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_4 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay4),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed4)
+  );
+
+  IOBUF IOBUF_4 (
+      .I (main_a7ddrphy_dq_o_nodelay4),
+      .T (main_a7ddrphy_dq_t4),
+      .IO(ddram_dq[4]),
+      .O (main_a7ddrphy_dq_i_nodelay4)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_34 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[5]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[21]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[5]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[21]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[5]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[21]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[5]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[21]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay5),
+      .TQ(main_a7ddrphy_dq_t5)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_5 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed5),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data5[7]),
+      .Q2(main_a7ddrphy_dq_i_data5[6]),
+      .Q3(main_a7ddrphy_dq_i_data5[5]),
+      .Q4(main_a7ddrphy_dq_i_data5[4]),
+      .Q5(main_a7ddrphy_dq_i_data5[3]),
+      .Q6(main_a7ddrphy_dq_i_data5[2]),
+      .Q7(main_a7ddrphy_dq_i_data5[1]),
+      .Q8(main_a7ddrphy_dq_i_data5[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_5 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay5),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed5)
+  );
+
+  IOBUF IOBUF_5 (
+      .I (main_a7ddrphy_dq_o_nodelay5),
+      .T (main_a7ddrphy_dq_t5),
+      .IO(ddram_dq[5]),
+      .O (main_a7ddrphy_dq_i_nodelay5)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_35 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[6]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[22]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[6]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[22]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[6]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[22]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[6]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[22]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay6),
+      .TQ(main_a7ddrphy_dq_t6)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_6 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed6),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data6[7]),
+      .Q2(main_a7ddrphy_dq_i_data6[6]),
+      .Q3(main_a7ddrphy_dq_i_data6[5]),
+      .Q4(main_a7ddrphy_dq_i_data6[4]),
+      .Q5(main_a7ddrphy_dq_i_data6[3]),
+      .Q6(main_a7ddrphy_dq_i_data6[2]),
+      .Q7(main_a7ddrphy_dq_i_data6[1]),
+      .Q8(main_a7ddrphy_dq_i_data6[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_6 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay6),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed6)
+  );
+
+  IOBUF IOBUF_6 (
+      .I (main_a7ddrphy_dq_o_nodelay6),
+      .T (main_a7ddrphy_dq_t6),
+      .IO(ddram_dq[6]),
+      .O (main_a7ddrphy_dq_i_nodelay6)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_36 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[7]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[23]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[7]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[23]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[7]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[23]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[7]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[23]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay7),
+      .TQ(main_a7ddrphy_dq_t7)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_7 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed7),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data7[7]),
+      .Q2(main_a7ddrphy_dq_i_data7[6]),
+      .Q3(main_a7ddrphy_dq_i_data7[5]),
+      .Q4(main_a7ddrphy_dq_i_data7[4]),
+      .Q5(main_a7ddrphy_dq_i_data7[3]),
+      .Q6(main_a7ddrphy_dq_i_data7[2]),
+      .Q7(main_a7ddrphy_dq_i_data7[1]),
+      .Q8(main_a7ddrphy_dq_i_data7[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_7 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay7),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[0] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed7)
+  );
+
+  IOBUF IOBUF_7 (
+      .I (main_a7ddrphy_dq_o_nodelay7),
+      .T (main_a7ddrphy_dq_t7),
+      .IO(ddram_dq[7]),
+      .O (main_a7ddrphy_dq_i_nodelay7)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_37 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[8]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[24]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[8]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[24]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[8]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[24]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[8]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[24]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay8),
+      .TQ(main_a7ddrphy_dq_t8)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_8 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed8),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data8[7]),
+      .Q2(main_a7ddrphy_dq_i_data8[6]),
+      .Q3(main_a7ddrphy_dq_i_data8[5]),
+      .Q4(main_a7ddrphy_dq_i_data8[4]),
+      .Q5(main_a7ddrphy_dq_i_data8[3]),
+      .Q6(main_a7ddrphy_dq_i_data8[2]),
+      .Q7(main_a7ddrphy_dq_i_data8[1]),
+      .Q8(main_a7ddrphy_dq_i_data8[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_8 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay8),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed8)
+  );
+
+  IOBUF IOBUF_8 (
+      .I (main_a7ddrphy_dq_o_nodelay8),
+      .T (main_a7ddrphy_dq_t8),
+      .IO(ddram_dq[8]),
+      .O (main_a7ddrphy_dq_i_nodelay8)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_38 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[9]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[25]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[9]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[25]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[9]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[25]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[9]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[25]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay9),
+      .TQ(main_a7ddrphy_dq_t9)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_9 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed9),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data9[7]),
+      .Q2(main_a7ddrphy_dq_i_data9[6]),
+      .Q3(main_a7ddrphy_dq_i_data9[5]),
+      .Q4(main_a7ddrphy_dq_i_data9[4]),
+      .Q5(main_a7ddrphy_dq_i_data9[3]),
+      .Q6(main_a7ddrphy_dq_i_data9[2]),
+      .Q7(main_a7ddrphy_dq_i_data9[1]),
+      .Q8(main_a7ddrphy_dq_i_data9[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_9 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay9),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed9)
+  );
+
+  IOBUF IOBUF_9 (
+      .I (main_a7ddrphy_dq_o_nodelay9),
+      .T (main_a7ddrphy_dq_t9),
+      .IO(ddram_dq[9]),
+      .O (main_a7ddrphy_dq_i_nodelay9)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_39 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[10]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[26]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[10]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[26]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[10]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[26]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[10]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[26]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay10),
+      .TQ(main_a7ddrphy_dq_t10)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_10 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed10),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data10[7]),
+      .Q2(main_a7ddrphy_dq_i_data10[6]),
+      .Q3(main_a7ddrphy_dq_i_data10[5]),
+      .Q4(main_a7ddrphy_dq_i_data10[4]),
+      .Q5(main_a7ddrphy_dq_i_data10[3]),
+      .Q6(main_a7ddrphy_dq_i_data10[2]),
+      .Q7(main_a7ddrphy_dq_i_data10[1]),
+      .Q8(main_a7ddrphy_dq_i_data10[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_10 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay10),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed10)
+  );
+
+  IOBUF IOBUF_10 (
+      .I (main_a7ddrphy_dq_o_nodelay10),
+      .T (main_a7ddrphy_dq_t10),
+      .IO(ddram_dq[10]),
+      .O (main_a7ddrphy_dq_i_nodelay10)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_40 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[11]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[27]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[11]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[27]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[11]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[27]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[11]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[27]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay11),
+      .TQ(main_a7ddrphy_dq_t11)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_11 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed11),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data11[7]),
+      .Q2(main_a7ddrphy_dq_i_data11[6]),
+      .Q3(main_a7ddrphy_dq_i_data11[5]),
+      .Q4(main_a7ddrphy_dq_i_data11[4]),
+      .Q5(main_a7ddrphy_dq_i_data11[3]),
+      .Q6(main_a7ddrphy_dq_i_data11[2]),
+      .Q7(main_a7ddrphy_dq_i_data11[1]),
+      .Q8(main_a7ddrphy_dq_i_data11[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_11 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay11),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed11)
+  );
+
+  IOBUF IOBUF_11 (
+      .I (main_a7ddrphy_dq_o_nodelay11),
+      .T (main_a7ddrphy_dq_t11),
+      .IO(ddram_dq[11]),
+      .O (main_a7ddrphy_dq_i_nodelay11)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_41 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[12]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[28]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[12]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[28]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[12]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[28]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[12]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[28]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay12),
+      .TQ(main_a7ddrphy_dq_t12)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_12 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed12),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data12[7]),
+      .Q2(main_a7ddrphy_dq_i_data12[6]),
+      .Q3(main_a7ddrphy_dq_i_data12[5]),
+      .Q4(main_a7ddrphy_dq_i_data12[4]),
+      .Q5(main_a7ddrphy_dq_i_data12[3]),
+      .Q6(main_a7ddrphy_dq_i_data12[2]),
+      .Q7(main_a7ddrphy_dq_i_data12[1]),
+      .Q8(main_a7ddrphy_dq_i_data12[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_12 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay12),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed12)
+  );
+
+  IOBUF IOBUF_12 (
+      .I (main_a7ddrphy_dq_o_nodelay12),
+      .T (main_a7ddrphy_dq_t12),
+      .IO(ddram_dq[12]),
+      .O (main_a7ddrphy_dq_i_nodelay12)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_42 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[13]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[29]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[13]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[29]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[13]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[29]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[13]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[29]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay13),
+      .TQ(main_a7ddrphy_dq_t13)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_13 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed13),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data13[7]),
+      .Q2(main_a7ddrphy_dq_i_data13[6]),
+      .Q3(main_a7ddrphy_dq_i_data13[5]),
+      .Q4(main_a7ddrphy_dq_i_data13[4]),
+      .Q5(main_a7ddrphy_dq_i_data13[3]),
+      .Q6(main_a7ddrphy_dq_i_data13[2]),
+      .Q7(main_a7ddrphy_dq_i_data13[1]),
+      .Q8(main_a7ddrphy_dq_i_data13[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_13 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay13),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed13)
+  );
+
+  IOBUF IOBUF_13 (
+      .I (main_a7ddrphy_dq_o_nodelay13),
+      .T (main_a7ddrphy_dq_t13),
+      .IO(ddram_dq[13]),
+      .O (main_a7ddrphy_dq_i_nodelay13)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_43 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[14]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[30]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[14]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[30]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[14]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[30]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[14]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[30]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay14),
+      .TQ(main_a7ddrphy_dq_t14)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_14 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed14),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data14[7]),
+      .Q2(main_a7ddrphy_dq_i_data14[6]),
+      .Q3(main_a7ddrphy_dq_i_data14[5]),
+      .Q4(main_a7ddrphy_dq_i_data14[4]),
+      .Q5(main_a7ddrphy_dq_i_data14[3]),
+      .Q6(main_a7ddrphy_dq_i_data14[2]),
+      .Q7(main_a7ddrphy_dq_i_data14[1]),
+      .Q8(main_a7ddrphy_dq_i_data14[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_14 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay14),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed14)
+  );
+
+  IOBUF IOBUF_14 (
+      .I (main_a7ddrphy_dq_o_nodelay14),
+      .T (main_a7ddrphy_dq_t14),
+      .IO(ddram_dq[14]),
+      .O (main_a7ddrphy_dq_i_nodelay14)
+  );
+
+  OSERDESE2 #(
+      .DATA_RATE_OQ("DDR"),
+      .DATA_RATE_TQ("BUF"),
+      .DATA_WIDTH(4'd8),
+      .SERDES_MODE("MASTER"),
+      .TRISTATE_WIDTH(1'd1)
+  ) OSERDESE2_44 (
+      .CLK(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .D1(main_a7ddrphy_dfi_p0_wrdata[15]),
+      .D2(main_a7ddrphy_dfi_p0_wrdata[31]),
+      .D3(main_a7ddrphy_dfi_p1_wrdata[15]),
+      .D4(main_a7ddrphy_dfi_p1_wrdata[31]),
+      .D5(main_a7ddrphy_dfi_p2_wrdata[15]),
+      .D6(main_a7ddrphy_dfi_p2_wrdata[31]),
+      .D7(main_a7ddrphy_dfi_p3_wrdata[15]),
+      .D8(main_a7ddrphy_dfi_p3_wrdata[31]),
+      .OCE(1'd1),
+      .RST(sys_rst),
+      .T1((~main_a7ddrphy_oe_dq)),
+      .TCE(1'd1),
+      .OQ(main_a7ddrphy_dq_o_nodelay15),
+      .TQ(main_a7ddrphy_dq_t15)
+  );
+
+  ISERDESE2 #(
+      .DATA_RATE("DDR"),
+      .DATA_WIDTH(4'd8),
+      .INTERFACE_TYPE("NETWORKING"),
+      .IOBDELAY("IFD"),
+      .NUM_CE(1'd1),
+      .SERDES_MODE("MASTER")
+  ) ISERDESE2_15 (
+      .BITSLIP(1'd0),
+      .CE1(1'd1),
+      .CLK(sys4x_clk),
+      .CLKB(sys4x_clk),
+      .CLKDIV(sys_clk),
+      .DDLY(main_a7ddrphy_dq_i_delayed15),
+      .RST(sys_rst),
+      .Q1(main_a7ddrphy_dq_i_data15[7]),
+      .Q2(main_a7ddrphy_dq_i_data15[6]),
+      .Q3(main_a7ddrphy_dq_i_data15[5]),
+      .Q4(main_a7ddrphy_dq_i_data15[4]),
+      .Q5(main_a7ddrphy_dq_i_data15[3]),
+      .Q6(main_a7ddrphy_dq_i_data15[2]),
+      .Q7(main_a7ddrphy_dq_i_data15[1]),
+      .Q8(main_a7ddrphy_dq_i_data15[0])
+  );
+
+  IDELAYE2 #(
+      .CINVCTRL_SEL("FALSE"),
+      .DELAY_SRC("IDATAIN"),
+      .HIGH_PERFORMANCE_MODE("TRUE"),
+      .IDELAY_TYPE("VARIABLE"),
+      .IDELAY_VALUE(1'd0),
+      .PIPE_SEL("FALSE"),
+      .REFCLK_FREQUENCY(200.0),
+      .SIGNAL_PATTERN("DATA")
+  ) IDELAYE2_15 (
+      .C(sys_clk),
+      .CE((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_inc_re)),
+      .IDATAIN(main_a7ddrphy_dq_i_nodelay15),
+      .INC(1'd1),
+      .LD((main_a7ddrphy_dly_sel_storage[1] & main_a7ddrphy_rdly_dq_rst_re)),
+      .LDPIPEEN(1'd0),
+      .DATAOUT(main_a7ddrphy_dq_i_delayed15)
+  );
+
+  IOBUF IOBUF_15 (
+      .I (main_a7ddrphy_dq_o_nodelay15),
+      .T (main_a7ddrphy_dq_t15),
+      .IO(ddram_dq[15]),
+      .O (main_a7ddrphy_dq_i_nodelay15)
+  );
+
+  reg [23:0] storage_2[0:7];
+  reg [23:0] memdat_5;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_we)
+      storage_2[main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_5 <= storage_2[main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_wrport_dat_r = memdat_5;
+  assign main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_dat_r = storage_2[main_sdram_bankmachine0_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_3[0:7];
+  reg [23:0] memdat_6;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_we)
+      storage_3[main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_6 <= storage_3[main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_wrport_dat_r = memdat_6;
+  assign main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_dat_r = storage_3[main_sdram_bankmachine1_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_4[0:7];
+  reg [23:0] memdat_7;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_we)
+      storage_4[main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_7 <= storage_4[main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_wrport_dat_r = memdat_7;
+  assign main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_dat_r = storage_4[main_sdram_bankmachine2_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_5[0:7];
+  reg [23:0] memdat_8;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_we)
+      storage_5[main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_8 <= storage_5[main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_wrport_dat_r = memdat_8;
+  assign main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_dat_r = storage_5[main_sdram_bankmachine3_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_6[0:7];
+  reg [23:0] memdat_9;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_we)
+      storage_6[main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_9 <= storage_6[main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_wrport_dat_r = memdat_9;
+  assign main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_dat_r = storage_6[main_sdram_bankmachine4_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_7 [0:7];
+  reg [23:0] memdat_10;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_we)
+      storage_7[main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_10 <= storage_7[main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_wrport_dat_r = memdat_10;
+  assign main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_dat_r = storage_7[main_sdram_bankmachine5_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_8 [0:7];
+  reg [23:0] memdat_11;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_we)
+      storage_8[main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_11 <= storage_8[main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_wrport_dat_r = memdat_11;
+  assign main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_dat_r = storage_8[main_sdram_bankmachine6_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] storage_9 [0:7];
+  reg [23:0] memdat_12;
+  always @(posedge sys_clk) begin
+    if (main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_we)
+      storage_9[main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr] <= main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_dat_w;
+    memdat_12 <= storage_9[main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_adr];
+  end
+
+  always @(posedge sys_clk) begin
+  end
+
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_wrport_dat_r = memdat_12;
+  assign main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_dat_r = storage_9[main_sdram_bankmachine7_cmd_buffer_lookahead_rdport_adr];
+
+  reg [23:0] tag_mem  [0:511];
+  reg [ 8:0] memadr_1;
+  always @(posedge sys_clk) begin
+    if (main_tag_port_we) tag_mem[main_tag_port_adr] <= main_tag_port_dat_w;
+    memadr_1 <= main_tag_port_adr;
+  end
+
+  assign main_tag_port_dat_r = tag_mem[memadr_1];
+
+  VexRiscv VexRiscv (
+      .clk(sys_clk),
+      .dBusWishbone_ACK(main_minsoc_cpu_dbus_ack),
+      .dBusWishbone_DAT_MISO(main_minsoc_cpu_dbus_dat_r),
+      .dBusWishbone_ERR(main_minsoc_cpu_dbus_err),
+      .externalInterruptArray(main_minsoc_cpu_interrupt),
+      .externalResetVector(main_minsoc_vexriscv),
+      .iBusWishbone_ACK(main_minsoc_cpu_ibus_ack),
+      .iBusWishbone_DAT_MISO(main_minsoc_cpu_ibus_dat_r),
+      .iBusWishbone_ERR(main_minsoc_cpu_ibus_err),
+      .reset((sys_rst | main_minsoc_cpu_reset)),
+      .softwareInterrupt(1'd0),
+      .timerInterrupt(1'd0),
+      .dBusWishbone_ADR(main_minsoc_cpu_dbus_adr),
+      .dBusWishbone_BTE(main_minsoc_cpu_dbus_bte),
+      .dBusWishbone_CTI(main_minsoc_cpu_dbus_cti),
+      .dBusWishbone_CYC(main_minsoc_cpu_dbus_cyc),
+      .dBusWishbone_DAT_MOSI(main_minsoc_cpu_dbus_dat_w),
+      .dBusWishbone_SEL(main_minsoc_cpu_dbus_sel),
+      .dBusWishbone_STB(main_minsoc_cpu_dbus_stb),
+      .dBusWishbone_WE(main_minsoc_cpu_dbus_we),
+      .iBusWishbone_ADR(main_minsoc_cpu_ibus_adr),
+      .iBusWishbone_BTE(main_minsoc_cpu_ibus_bte),
+      .iBusWishbone_CTI(main_minsoc_cpu_ibus_cti),
+      .iBusWishbone_CYC(main_minsoc_cpu_ibus_cyc),
+      .iBusWishbone_DAT_MOSI(main_minsoc_cpu_ibus_dat_w),
+      .iBusWishbone_SEL(main_minsoc_cpu_ibus_sel),
+      .iBusWishbone_STB(main_minsoc_cpu_ibus_stb),
+      .iBusWishbone_WE(main_minsoc_cpu_ibus_we)
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(5'd20),
+      .CLKOUT0_PHASE(1'd0),
+      .CLKOUT1_DIVIDE(3'd5),
+      .CLKOUT1_PHASE(1'd0),
+      .CLKOUT2_DIVIDE(3'd5),
+      .CLKOUT2_PHASE(90000),
+      .CLKOUT3_DIVIDE(3'd6),
+      .CLKOUT3_PHASE(1'd0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(main_pll_clkin),
+      .RST(main_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .CLKOUT2(main_clkout2),
+      .CLKOUT3(main_clkout3),
+      .LOCKED(main_locked)
+  );
+
+  reg [7:0] data_mem_grain0[0:511];
+  reg [8:0] memadr_2;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[0]) data_mem_grain0[main_data_port_adr] <= main_data_port_dat_w[7:0];
+    memadr_2 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[7:0] = data_mem_grain0[memadr_2];
+
+  reg [7:0] data_mem_grain1[0:511];
+  reg [8:0] memadr_3;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[1]) data_mem_grain1[main_data_port_adr] <= main_data_port_dat_w[15:8];
+    memadr_3 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[15:8] = data_mem_grain1[memadr_3];
+
+  reg [7:0] data_mem_grain2[0:511];
+  reg [8:0] memadr_4;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[2]) data_mem_grain2[main_data_port_adr] <= main_data_port_dat_w[23:16];
+    memadr_4 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[23:16] = data_mem_grain2[memadr_4];
+
+  reg [7:0] data_mem_grain3[0:511];
+  reg [8:0] memadr_5;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[3]) data_mem_grain3[main_data_port_adr] <= main_data_port_dat_w[31:24];
+    memadr_5 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[31:24] = data_mem_grain3[memadr_5];
+
+  reg [7:0] data_mem_grain4[0:511];
+  reg [8:0] memadr_6;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[4]) data_mem_grain4[main_data_port_adr] <= main_data_port_dat_w[39:32];
+    memadr_6 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[39:32] = data_mem_grain4[memadr_6];
+
+  reg [7:0] data_mem_grain5[0:511];
+  reg [8:0] memadr_7;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[5]) data_mem_grain5[main_data_port_adr] <= main_data_port_dat_w[47:40];
+    memadr_7 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[47:40] = data_mem_grain5[memadr_7];
+
+  reg [7:0] data_mem_grain6[0:511];
+  reg [8:0] memadr_8;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[6]) data_mem_grain6[main_data_port_adr] <= main_data_port_dat_w[55:48];
+    memadr_8 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[55:48] = data_mem_grain6[memadr_8];
+
+  reg [7:0] data_mem_grain7[0:511];
+  reg [8:0] memadr_9;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[7]) data_mem_grain7[main_data_port_adr] <= main_data_port_dat_w[63:56];
+    memadr_9 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[63:56] = data_mem_grain7[memadr_9];
+
+  reg [7:0] data_mem_grain8[0:511];
+  reg [8:0] memadr_10;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[8]) data_mem_grain8[main_data_port_adr] <= main_data_port_dat_w[71:64];
+    memadr_10 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[71:64] = data_mem_grain8[memadr_10];
+
+  reg [7:0] data_mem_grain9[0:511];
+  reg [8:0] memadr_11;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[9]) data_mem_grain9[main_data_port_adr] <= main_data_port_dat_w[79:72];
+    memadr_11 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[79:72] = data_mem_grain9[memadr_11];
+
+  reg [7:0] data_mem_grain10[0:511];
+  reg [8:0] memadr_12;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[10]) data_mem_grain10[main_data_port_adr] <= main_data_port_dat_w[87:80];
+    memadr_12 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[87:80] = data_mem_grain10[memadr_12];
+
+  reg [7:0] data_mem_grain11[0:511];
+  reg [8:0] memadr_13;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[11]) data_mem_grain11[main_data_port_adr] <= main_data_port_dat_w[95:88];
+    memadr_13 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[95:88] = data_mem_grain11[memadr_13];
+
+  reg [7:0] data_mem_grain12[0:511];
+  reg [8:0] memadr_14;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[12]) data_mem_grain12[main_data_port_adr] <= main_data_port_dat_w[103:96];
+    memadr_14 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[103:96] = data_mem_grain12[memadr_14];
+
+  reg [7:0] data_mem_grain13[0:511];
+  reg [8:0] memadr_15;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[13])
+      data_mem_grain13[main_data_port_adr] <= main_data_port_dat_w[111:104];
+    memadr_15 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[111:104] = data_mem_grain13[memadr_15];
+
+  reg [7:0] data_mem_grain14[0:511];
+  reg [8:0] memadr_16;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[14])
+      data_mem_grain14[main_data_port_adr] <= main_data_port_dat_w[119:112];
+    memadr_16 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[119:112] = data_mem_grain14[memadr_16];
+
+  reg [7:0] data_mem_grain15[0:511];
+  reg [8:0] memadr_17;
+  always @(posedge sys_clk) begin
+    if (main_data_port_we[15])
+      data_mem_grain15[main_data_port_adr] <= main_data_port_dat_w[127:120];
+    memadr_17 <= main_data_port_adr;
+  end
+
+  assign main_data_port_dat_r[127:120] = data_mem_grain15[memadr_17];
+
+  (* ars_ff1 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE (
+      .C  (sys_clk),
+      .CE (1'd1),
+      .D  (1'd0),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl0),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl0_rst_meta)
+  );
+
+  (* ars_ff2 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_1 (
+      .C  (sys_clk),
+      .CE (1'd1),
+      .D  (builder_xilinxasyncresetsynchronizerimpl0_rst_meta),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl0),
+      .Q  (sys_rst)
+  );
+
+  (* ars_ff1 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_2 (
+      .C  (sys4x_clk),
+      .CE (1'd1),
+      .D  (1'd0),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl1),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl1_rst_meta)
+  );
+
+  (* ars_ff2 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_3 (
+      .C  (sys4x_clk),
+      .CE (1'd1),
+      .D  (builder_xilinxasyncresetsynchronizerimpl1_rst_meta),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl1),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl1_expr)
+  );
+
+  (* ars_ff1 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_4 (
+      .C  (sys4x_dqs_clk),
+      .CE (1'd1),
+      .D  (1'd0),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl2),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl2_rst_meta)
+  );
+
+  (* ars_ff2 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_5 (
+      .C  (sys4x_dqs_clk),
+      .CE (1'd1),
+      .D  (builder_xilinxasyncresetsynchronizerimpl2_rst_meta),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl2),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl2_expr)
+  );
+
+  (* ars_ff1 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_6 (
+      .C  (clk200_clk),
+      .CE (1'd1),
+      .D  (1'd0),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl3),
+      .Q  (builder_xilinxasyncresetsynchronizerimpl3_rst_meta)
+  );
+
+  (* ars_ff2 = "true", async_reg = "true" *) FDPE #(
+      .INIT(1'd1)
+  ) FDPE_7 (
+      .C  (clk200_clk),
+      .CE (1'd1),
+      .D  (builder_xilinxasyncresetsynchronizerimpl3_rst_meta),
+      .PRE(builder_xilinxasyncresetsynchronizerimpl3),
+      .Q  (clk200_rst)
+  );
+
+endmodule
diff --git a/yosys-plugins/CODE_OF_CONDUCT.md b/yosys-plugins/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..c7d7eeb14
--- /dev/null
+++ b/yosys-plugins/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/yosys-plugins/CONTRIBUTING.md b/yosys-plugins/CONTRIBUTING.md
new file mode 100644
index 000000000..03d6c8361
--- /dev/null
+++ b/yosys-plugins/CONTRIBUTING.md
@@ -0,0 +1,79 @@
+# Contributing to Yosys F4PGA Plugins
+
+There are a couple of guidelines when contributing to Yosys F4PGA Plugins which are listed here.
+
+### Sending
+
+All contributions should be sent as [GitHub Pull requests](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).
+
+### License
+
+All software (code, associated documentation, support files, etc) in the Yosys F4PGA Plugins repository are licensed
+under the very permissive [Apache-2.0 Licence](LICENSE).
+A copy can be found in the [`LICENSE`](LICENSE) file.
+
+All new contributions must also be released under this license.
+
+### Code of Conduct
+
+By contributing you agree to the [code of conduct](CODE_OF_CONDUCT.md). We
+follow the open source best practice of using the [Contributor
+Covenant](https://www.contributor-covenant.org/) for our Code of Conduct.
+
+### Sign your work
+
+To improve tracking of who did what, we follow the Linux Kernel's
+["sign your work" system](https://github.com/wking/signed-off-by).
+This is also called a
+["DCO" or "Developer's Certificate of Origin"](https://developercertificate.org/).
+
+**All** commits are required to include this sign off and we use the
+[Probot DCO App](https://github.com/probot/dco) to check pull requests for
+this.
+
+The sign-off is a simple line at the end of the explanation for the
+patch, which certifies that you wrote it or otherwise have the right to
+pass it on as a open-source patch.  The rules are pretty simple: if you
+can certify the below:
+
+        Developer's Certificate of Origin 1.1
+
+        By making a contribution to this project, I certify that:
+
+        (a) The contribution was created in whole or in part by me and I
+            have the right to submit it under the open source license
+            indicated in the file; or
+
+        (b) The contribution is based upon previous work that, to the best
+            of my knowledge, is covered under an appropriate open source
+            license and I have the right under that license to submit that
+            work with modifications, whether created in whole or in part
+            by me, under the same open source license (unless I am
+            permitted to submit under a different license), as indicated
+            in the file; or
+
+        (c) The contribution was provided directly to me by some other
+            person who certified (a), (b) or (c) and I have not modified
+            it.
+
+	(d) I understand and agree that this project and the contribution
+	    are public and that a record of the contribution (including all
+	    personal information I submit with it, including my sign-off) is
+	    maintained indefinitely and may be redistributed consistent with
+	    this project or the open source license(s) involved.
+
+then you just add a line saying
+
+	Signed-off-by: Random J Developer <random@developer.example.org>
+
+using your real name (sorry, no pseudonyms or anonymous contributions.)
+
+You can add the signoff as part of your commit statement. For example:
+
+    git commit --signoff -a -m "Fixed some errors."
+
+*Hint:* If you've forgotten to add a signoff to one or more commits, you can use the
+following command to add signoffs to all commits between you and the upstream
+master:
+
+    git rebase --signoff upstream/master
diff --git a/yosys-plugins/Makefile b/yosys-plugins/Makefile
new file mode 100644
index 000000000..54e2fc178
--- /dev/null
+++ b/yosys-plugins/Makefile
@@ -0,0 +1,67 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+PLUGIN_LIST := fasm xdc params sdc ql-iob design_introspection integrateinv ql-qlf systemverilog uhdm dsp-ff
+PLUGINS := $(foreach plugin,$(PLUGIN_LIST),$(plugin).so)
+PLUGINS_INSTALL := $(foreach plugin,$(PLUGIN_LIST),install_$(plugin))
+PLUGINS_CLEAN := $(foreach plugin,$(PLUGIN_LIST),clean_$(plugin))
+PLUGINS_TEST := $(foreach plugin,$(PLUGIN_LIST),test_$(plugin))
+
+all: plugins
+
+TOP_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
+REQUIREMENTS_FILE = requirements.txt
+ENVIRONMENT_FILE ?= environment.yml
+
+-include ../third_party/make-env/conda.mk
+
+define install_plugin =
+$(1).so:
+	$$(MAKE) -C $(1) $$@
+
+install_$(1):
+	$$(MAKE) -C $(1) install
+
+clean_$(1):
+	$$(MAKE) -C $(1) clean
+
+test_$(1):
+	@$$(MAKE) --no-print-directory -C $(1) test
+endef
+
+$(foreach plugin,$(PLUGIN_LIST),$(eval $(call install_plugin,$(plugin))))
+
+pmgen.py:
+	wget -nc -O $@ https://raw.githubusercontent.com/YosysHQ/yosys/master/passes/pmgen/pmgen.py
+
+plugins: $(PLUGINS)
+
+install: $(PLUGINS_INSTALL)
+
+test: $(PLUGINS_TEST)
+
+plugins_clean: $(PLUGINS_CLEAN)
+
+clean:: plugins_clean
+	rm -rf pmgen.py
+
+CLANG_FORMAT ?= clang-format-8
+format:
+	find . \( -name "*.h" -o -name "*.cc" \) -and -not -path './third_party/*' -print0 | xargs -0 -P $$(nproc) ${CLANG_FORMAT} -style=file -i
+
+VERIBLE_FORMAT ?= verible-verilog-format
+format-verilog:
+	find */tests \( -name "*.v" -o -name "*.sv" \) -and -not -path './third_party/*' -print0 | xargs -0 $(VERIBLE_FORMAT) --inplace
diff --git a/yosys-plugins/Makefile_plugin.common b/yosys-plugins/Makefile_plugin.common
new file mode 100644
index 000000000..965399e98
--- /dev/null
+++ b/yosys-plugins/Makefile_plugin.common
@@ -0,0 +1,89 @@
+# -*- Makefile -*-
+# This Makefile template is supposed to be included in each plugin's Makefile.
+# Plugin Makefiles need to specify the plugin's name and source files.
+# The plugin name is how the final shared object will be named.
+# This shared object can be imported to Yosys with `plugin -i` command.
+#
+# Below is an example of a plugin Makefile that uses this template:
+# NAME = plugin_name
+# SOURCES = source1.cc source2.cc
+# include ../Makefile_plugin.common
+#
+# For the above example the final plugin shared object will be named plugin_name.so.
+# In order to test the plugin it has to be copied to Yosys's shared folder.
+# The install target in this Makefile copies the plugins into the shared folder
+# of the Yosys installation that is found in the PATH.
+# This is needed because the shared folder is where Yosys will look for the
+# plugin object when `plugin -i` is called in Yosys's synthesis script.
+#
+# To add tests for the plugin the Makefile_test.common Makefile should be used.
+# Refer to Makefile_test.common to learn more details.
+#
+# Below is a directory structure which shows how the plugin sources and tests
+# should be laid out
+#
+# |-- Makefile_plugin.common
+# |-- Makefile_test.common
+# |-- example
+# |   |-- Makefile
+# |   |-- source1.cc
+# |   |-- source2.cc
+# |   |-- tests
+# |       |-- Makefile
+# |       |-- test_case_1
+# |       |   |-- test_case_1.tcl
+# |       |   |-- test_case_1.v
+# |       |   |-- test_case_1.golden.ext
+# |       |   |-- ...
+# |-- example2
+# |-- ...
+
+SHELL := /usr/bin/env bash
+
+# Either find yosys in system and use its path or use the given path
+YOSYS_PATH ?= $(realpath $(dir $(shell command -v yosys))/..)
+
+# Find yosys-config, throw an error if not found
+YOSYS_CONFIG = $(YOSYS_PATH)/bin/yosys-config
+ifeq (,$(wildcard $(YOSYS_CONFIG)))
+  $(error "Didn't find 'yosys-config' under '$(YOSYS_PATH)'")
+endif
+
+CXX ?= $(shell $(YOSYS_CONFIG) --cxx)
+CXXFLAGS := $(shell $(YOSYS_CONFIG) --cxxflags) $(CXXFLAGS) #-DSDC_DEBUG
+LDFLAGS := $(shell $(YOSYS_CONFIG) --ldflags) $(LDFLAGS)
+LDLIBS := $(shell $(YOSYS_CONFIG) --ldlibs) $(LDLIBS)
+EXTRA_FLAGS ?=
+
+DATA_DIR = $(DESTDIR)$(shell $(YOSYS_CONFIG) --datdir)
+PLUGINS_DIR = $(DATA_DIR)/plugins
+
+OBJS := $(patsubst %.cc,%.o,$(SOURCES))
+DEPS ?=
+
+$(PLUGINS_DIR):
+	@mkdir -p $@
+
+all: $(NAME).so
+
+$(OBJS): %.o: %.cc $(DEPS)
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(EXTRA_FLAGS) -c -o $@ $(filter %.cc, $^)
+
+$(NAME).so: $(OBJS)
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS)
+
+../pmgen.py:
+	@$(MAKE) -C .. pmgen.py
+
+install_plugin: $(NAME).so | $(PLUGINS_DIR)
+	install -D $< $(PLUGINS_DIR)/$<
+
+test:
+	@$(MAKE) -C tests all
+
+.PHONY: install
+install: install_plugin
+
+clean:
+	rm -f *.d *.o *.so
+	$(MAKE) -C tests clean
diff --git a/yosys-plugins/Makefile_test.common b/yosys-plugins/Makefile_test.common
new file mode 100644
index 000000000..f09241dd4
--- /dev/null
+++ b/yosys-plugins/Makefile_test.common
@@ -0,0 +1,175 @@
+# -*- Makefile -*-
+# Each plugin shall have a directory named 'test' that contains test cases
+# directories and a Makefile which includes this Makefile template.
+# The test Makefile specifies which tests to execute and how to verify them.
+# The test to execute should be explicitly specified in the TESTS variable.
+# Each test needs a verification step define in the name_of_test_verify variable.
+# A simple diff verification template have been defined in the template Makefile
+# diff_test performs a simple diff and takes name of file and its extension
+# Example of a test Makefile is given below:
+#
+# include $(shell pwd)/../../Makefile_test.common
+# TESTS = test1 test2
+# test1_verify = $(call diff_test,test1,ext) && test $$(grep "PASS" test1/test1.txt | wc -l) -eq 2
+# test2_verify = $(call diff_test,test2,ext)
+#
+
+SHELL := /usr/bin/env bash
+
+# Either find yosys in system and use its path or use the given path
+YOSYS_PATH ?= $(realpath $(dir $(shell command -v yosys))/..)
+
+# Find yosys-config, throw an error if not found
+YOSYS_CONFIG = $(YOSYS_PATH)/bin/yosys-config
+ifeq (,$(wildcard $(YOSYS_CONFIG)))
+$(error "Didn't find 'yosys-config' under '$(YOSYS_PATH)'")
+endif
+
+GTEST_DIR ?= $(abspath ../../../third_party/googletest)
+CXX ?= $(shell $(YOSYS_CONFIG) --cxx)
+CXXFLAGS ?= $(shell $(YOSYS_CONFIG) --cxxflags) -I.. -I$(GTEST_DIR)/googletest/include
+LDLIBS ?= $(shell $(YOSYS_CONFIG) --ldlibs) -L$(GTEST_DIR)/build/lib -lgtest -lgtest_main -lpthread
+LDFLAGS ?= $(shell $(YOSYS_CONFIG) --ldflags)
+TEST_UTILS ?= $(abspath ../../test-utils.tcl)
+
+define test_tpl =
+$(1): $(1)/ok
+	@set +e; \
+	$$($$(subst /,-,$(1)_verify)); \
+	if [ $$$$? -eq 0 ]; then \
+		printf "Test %-20s \e[32mPASSED\e[0m @ %s\n" $(1) $(CURDIR); \
+		touch $$<; \
+		true; \
+	else \
+		printf "Test %-20s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+		false; \
+	fi
+
+$(1)/ok: $(1)/$$(notdir $(1).v)
+	@set +e; \
+	cd $(1); \
+	echo "source $(TEST_UTILS)" > run-$$(notdir $(1)).tcl ;\
+	echo "source $$(notdir $(1)).tcl" >> run-$$(notdir $(1)).tcl ;\
+	DESIGN_TOP=$$(notdir $(1)) TEST_OUTPUT_PREFIX=./ \
+	yosys -c "run-$$(notdir $(1)).tcl" -q -q -l $$(notdir $(1)).log; \
+	RETVAL=$$$$?; \
+	rm -f run-$$(notdir $(1)).tcl; \
+	if [ ! -z "$$($(1)_negative)" ] && [ $$($(1)_negative) -eq 1 ]; then \
+		if [ $$$$RETVAL -ne 0 ]; then \
+			printf "Negative test %-20s \e[32mPASSED\e[0m @ %s\n" $(1) $(CURDIR); \
+			true; \
+		else \
+			printf "Negative test %-20s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+			false; \
+		fi \
+	else \
+		if [ $$$$RETVAL -ne 0 ]; then \
+			echo "Unexpected runtime error"; \
+		    printf "Test %-20s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+			false; \
+		fi \
+	fi
+
+endef
+
+DEV = $(shell echo $(1) | cut -d "/" -f 1)
+SIM_LIBS = $(shell find ../$(DEV) -name "*.v" -not -name "*map.v" -not -name "cells_sim.v")
+define test_sim_tpl =
+$(1): $(1)/ok
+	@printf "Test %-18s \e[32mPASSED\e[0m @ %s\n" $(1) $(CURDIR);
+
+$(1)/$$(notdir $(1).vvp): $(1)/$$(notdir $(1).v)
+	@iverilog -vvvv -g2005 -o $$@ $$< $(SIM_LIBS) -I../ -DVCD_FILE=\"$(1)/$$(notdir $(1).vcd)\" >$(1)/$$(notdir $(1).vvp.log) 2>&1; \
+	if [ $$$$? -ne 0 ]; then \
+		printf "Test %-18s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+		false; \
+	fi
+
+$(1)/ok: $(1)/$$(notdir $(1).vvp) $(1)/$$(notdir $(1).v)
+	@vvp -vvvv $$< >$(1)/$$(notdir $(1).log) 2>&1; \
+	if [ $$$$? -ne 0 ]; then \
+		printf "Test %-18s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+		false; \
+	else \
+		touch $$@; \
+		true; \
+	fi
+
+endef
+
+define test_post_synth_sim_tpl =
+$(1): $(1)/ok
+	@printf "Test %-18s \e[32mPASSED\e[0m @ %s\n" $(1) $(CURDIR);
+
+$(1)/ok: $(1)/synth
+	@make -C $(1)/sim sim; \
+	if [ $$$$? -ne 0 ]; then \
+		printf "Test %-18s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+		false; \
+	else \
+		touch $$@; \
+		true; \
+	fi
+
+$(1)/synth: $(1)/$$(notdir $(1).v)
+	@set +e; \
+	cd $(1); \
+	echo "source $(TEST_UTILS)" > run-$$(notdir $(1)).tcl ;\
+	echo "source $$(notdir $(1)).tcl" >> run-$$(notdir $(1)).tcl ;\
+	DESIGN_TOP=$$(notdir $(1)) TEST_OUTPUT_PREFIX=./ \
+	yosys -c "run-$$(notdir $(1)).tcl" -q -q -l $$(notdir $(1)).log; \
+	RETVAL=$$$$?; \
+	rm -f run-$$(notdir $(1)).tcl; \
+	if [ ! -z "$$($(1)_negative)" ] && [ $$($(1)_negative) -eq 1 ]; then \
+		if [ $$$$RETVAL -ne 0 ]; then \
+			printf "Negative test %-20s \e[32mPASSED\e[0m @ %s\n" $(1) $(CURDIR); \
+			true; \
+		else \
+			printf "Negative test %-20s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+			false; \
+		fi \
+	else \
+		if [ $$$$RETVAL -ne 0 ]; then \
+			echo "Unexpected runtime error"; \
+		    printf "Test %-20s \e[31;1mFAILED\e[0m @ %s\n" $(1) $(CURDIR); \
+			false; \
+		fi \
+	fi
+
+endef
+
+define unit_test_tpl =
+$(1): $(1)/$(1).test
+	@$$<
+
+$(1)/$(1).test: $(1)/$(1).test.o $$(GTEST_DIR)/build/lib/libgtest.a
+	@$(CXX) $(LDFLAGS) -o $$@ $$< $(LDLIBS)
+
+$(1)/$(1).test.o: $(1)/$(1).test.cc
+	@$(CXX) $(CXXFLAGS) $(LDFLAGS) -c $$< -o $$@
+
+endef
+
+diff_test = diff $(1)/$(1).golden.$(2) $(1)/$(1).$(2)
+
+all: $(TESTS) $(SIM_TESTS) $(POST_SYNTH_SIM_TESTS) $(UNIT_TESTS)
+
+$(GTEST_DIR)/build/lib/libgtest.a $(GTEST_DIR)/build/lib/libgtest_main.a:
+	@mkdir -p $(GTEST_DIR)/build
+	@cd $(GTEST_DIR)/build; \
+	cmake ..; \
+	make
+
+.PHONY: all clean $(TESTS) $(SIM_TESTS) $(UNIT_TESTS)
+
+$(foreach test,$(TESTS),$(eval $(call test_tpl,$(test))))
+$(foreach test,$(SIM_TESTS),$(eval $(call test_sim_tpl,$(test))))
+$(foreach test,$(POST_SYNTH_SIM_TESTS),$(eval $(call test_post_synth_sim_tpl,$(test))))
+$(foreach test,$(UNIT_TESTS),$(eval $(call unit_test_tpl,$(test))))
+
+clean:
+	@rm -rf $(foreach test,$(TESTS),$(test)/$(test).sdc $(test)/$(test)_[0-9].sdc $(test)/$(test).txt $(test)/$(test).eblif $(test)/$(test).json)
+	@rm -rf $(foreach test,$(SIM_TESTS),$(test)/*.vvp $(test)/*.vcd)
+	@rm -rf $(foreach test,$(POST_SYNTH_SIM_TESTS),$(test)/sim/*.vvp $(test)/sim/*.vcd $(test)/sim/*post_synth.v)
+	@rm -rf $(foreach test,$(UNIT_TESTS),$(test)/$(test).test.o $(test)/$(test).test.d $(test)/$(test).test)
+	@find . -name "ok" -or -name "*.log" | xargs rm -rf
diff --git a/yosys-plugins/README.md b/yosys-plugins/README.md
new file mode 100644
index 000000000..04df3ff4e
--- /dev/null
+++ b/yosys-plugins/README.md
@@ -0,0 +1,109 @@
+# Yosys F4PGA Plugins
+
+This repository contains plugins for [Yosys](https://github.com/YosysHQ/yosys.git) developed as [part of the F4PGA project](https://f4pga.org).
+
+## Design introspection plugin
+
+Adds several commands that allow for collecting information about cells, nets, pins and ports in the design or a
+selection of objects.
+Additionally provides functions to convert selection on TCL lists.
+
+Following commands are added with the plugin:
+
+* get_cells
+* get_nets
+* get_pins
+* get_ports
+* get_count
+* selection_to_tcl_list
+
+## FASM plugin
+
+Writes out the design's [fasm features](https://fasm.readthedocs.io/en/latest/) based on the parameter annotations on a
+design cell.
+
+The plugin adds the following command:
+
+* write_fasm
+
+## Integrate inverters plugin
+
+Implements a pass that integrates inverters into cells that have ports with the 'invertible_pin' attribute set.
+
+The plugin adds the following command:
+
+* integrateinv
+
+## Parameters plugin
+
+Reads the specified parameter on a selected object.
+
+The plugin adds the following command:
+
+* getparam
+
+## QuickLogic IOB plugin
+
+[QuickLogic IOB plugin](./ql-iob/) annotates IO buffer cells with information from IO placement constraints.
+Used during synthesis for QuickLogic EOS-S3 architecture.
+
+The plugin adds the following command:
+
+* quicklogic_iob
+
+## QuickLogic QLF FPGAs plugin
+
+[QuickLogic QLF plugin](./ql-qlf/) extends Yosys with synthesis support for `qlf_k4n8` and `qlf_k6n10` architectures.
+
+The plugin adds the following command:
+
+* synth_quicklogic
+* ql_dsp
+
+Detailed help on the supported command(s) can be obtained by running `help <command_name>` in Yosys.
+
+## SDC plugin
+
+Reads Standard Delay Format (SDC) constraints, propagates these constraints across the design and writes out the
+complete SDC information.
+
+The plugin adds the following commands:
+
+* read_sdc
+* write_sdc
+* create_clock
+* get_clocks
+* propagate_clocks
+* set_false_path
+* set_max_delay
+* set_clock_groups
+
+## XDC plugin
+
+Reads Xilinx Design Constraints (XDC) files and annotates the specified cells parameters with properties such as:
+
+* INTERNAL_VREF
+* IOSTANDARD
+* SLEW
+* DRIVE
+* IN_TERM
+* LOC
+* PACKAGE_PIN
+
+The plugin adds the following commands:
+
+* read_xdc
+* get_iobanks
+* set_property
+* get_bank_tiles
+
+## SystemVerilog plugin
+
+Reads SystemVerilog and UHDM files and processes them into yosys AST.
+
+The plugin adds the following commands:
+
+* read_systemverilog
+* read_uhdm
+
+Detailed help on the supported command(s) can be obtained by running `help <command_name>` in Yosys.
diff --git a/yosys-plugins/bank_tiles.h b/yosys-plugins/bank_tiles.h
new file mode 100644
index 000000000..e15753bb4
--- /dev/null
+++ b/yosys-plugins/bank_tiles.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/log.h"
+#include "libs/json11/json11.hpp"
+
+USING_YOSYS_NAMESPACE
+// Coordinates of HCLK_IOI tiles associated with a specified bank
+using BankTilesMap = std::unordered_map<int, std::string>;
+
+// Find the part's JSON file with information including the IO Banks
+// and extract the bank tiles.
+inline BankTilesMap get_bank_tiles(const std::string json_file_name)
+{
+    BankTilesMap bank_tiles;
+    std::ifstream json_file(json_file_name);
+    if (!json_file.good()) {
+        log_cmd_error("Can't open JSON file %s", json_file_name.c_str());
+    }
+    std::string json_str((std::istreambuf_iterator<char>(json_file)), std::istreambuf_iterator<char>());
+    std::string error;
+    auto json = json11::Json::parse(json_str, error);
+    if (!error.empty()) {
+        log_cmd_error("%s\n", error.c_str());
+    }
+    auto json_objects = json.object_items();
+    auto iobanks = json_objects.find("iobanks");
+    if (iobanks == json_objects.end()) {
+        log_cmd_error("IO Bank information missing in the part's json: %s\n", json_file_name.c_str());
+    }
+
+    for (auto iobank : iobanks->second.object_items()) {
+        bank_tiles.emplace(std::atoi(iobank.first.c_str()), iobank.second.string_value());
+    }
+
+    return bank_tiles;
+}
diff --git a/yosys-plugins/design_introspection/Makefile b/yosys-plugins/design_introspection/Makefile
new file mode 100644
index 000000000..604254e80
--- /dev/null
+++ b/yosys-plugins/design_introspection/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = design_introspection
+SOURCES = design_introspection.cc \
+	  get_cmd.cc \
+	  get_nets.cc \
+	  get_ports.cc \
+	  get_cells.cc \
+	  get_pins.cc \
+	  get_count.cc \
+	  selection_to_tcl_list.cc
+
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/design_introspection/design_introspection.cc b/yosys-plugins/design_introspection/design_introspection.cc
new file mode 100644
index 000000000..b5193bf54
--- /dev/null
+++ b/yosys-plugins/design_introspection/design_introspection.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_cells.h"
+#include "get_count.h"
+#include "get_nets.h"
+#include "get_pins.h"
+#include "get_ports.h"
+#include "selection_to_tcl_list.h"
+
+USING_YOSYS_NAMESPACE
+
+PRIVATE_NAMESPACE_BEGIN
+
+struct DesignIntrospection {
+    DesignIntrospection() {}
+    GetNets get_nets_cmd;
+    GetPorts get_ports_cmd;
+    GetCells get_cells_cmd;
+    GetPins get_pins_cmd;
+    GetCount get_count_cmd;
+    SelectionToTclList selection_to_tcl_list_cmd;
+} DesignIntrospection;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/design_introspection/get_cells.cc b/yosys-plugins/design_introspection/get_cells.cc
new file mode 100644
index 000000000..ae4e82c95
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_cells.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_cells.h"
+
+USING_YOSYS_NAMESPACE
+
+std::string GetCells::TypeName() { return "cell"; }
+
+std::string GetCells::SelectionType() { return "c"; }
+
+GetCells::SelectionObjects GetCells::ExtractSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    SelectionObjects selected_objects;
+    for (auto module : design->selected_modules()) {
+        for (auto cell : module->selected_cells()) {
+            if (args.filters.size() > 0) {
+                Filter filter = args.filters.at(0);
+                std::string attr_value = cell->get_string_attribute(RTLIL::IdString(RTLIL::escape_id(filter.first)));
+                if (attr_value.compare(filter.second)) {
+                    continue;
+                }
+            }
+            std::string object_name(RTLIL::unescape_id(cell->name));
+            selected_objects.push_back(object_name);
+        }
+    }
+    if (selected_objects.size() == 0 and !args.is_quiet) {
+        log_warning("Couldn't find matching cell.\n");
+    }
+    return selected_objects;
+}
diff --git a/yosys-plugins/design_introspection/get_cells.h b/yosys-plugins/design_introspection/get_cells.h
new file mode 100644
index 000000000..c34da79e1
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_cells.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_CELLS_H_
+#define _GET_CELLS_H_
+
+#include "get_cmd.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetCells : public GetCmd {
+    GetCells() : GetCmd("get_cells", "Print matching cells") {}
+
+    std::string TypeName() override;
+    std::string SelectionType() override;
+    SelectionObjects ExtractSelection(RTLIL::Design *design, const CommandArgs &args) override;
+};
+
+#endif // GET_CELLS_H_
diff --git a/yosys-plugins/design_introspection/get_cmd.cc b/yosys-plugins/design_introspection/get_cmd.cc
new file mode 100644
index 000000000..66401a657
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_cmd.cc
@@ -0,0 +1,127 @@
+#include "get_cmd.h"
+
+USING_YOSYS_NAMESPACE
+
+void GetCmd::help()
+{
+    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+    log("\n");
+    log("   get_%ss [-quiet] [-filter filter_expression] "
+        "<%s_selection> \n",
+        TypeName().c_str(), TypeName().c_str());
+    log("\n");
+    log("Get matching %ss\n", TypeName().c_str());
+    log("\n");
+    log("Print the output to stdout too. This is useful when all Yosys "
+        "is "
+        "executed.\n");
+    log("\n");
+    log("    -filter\n");
+    log("        Name and value of attribute to be taken into "
+        "account.\n");
+    log("        e.g. -filter { attr == \"true\" }\n");
+    log("\n");
+    log("    -quiet\n");
+    log("        Don't print the result of the execution to stdout.\n");
+    log("\n");
+    log("    <selection_pattern>\n");
+    log("        Selection of %s names. Default are all %ss in the "
+        "design.\n",
+        TypeName().c_str(), TypeName().c_str());
+    log("\n");
+}
+
+void GetCmd::ExecuteSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    std::vector<std::string> selection_args;
+    // Add name of top module to selection string
+    std::transform(args.selection_objects.begin(), args.selection_objects.end(), std::back_inserter(selection_args),
+                   [&](const std::string &obj) { return RTLIL::unescape_id(design->top_module()->name) + "/" + SelectionType() + ":" + obj; });
+    extra_args(selection_args, 0, design);
+    if (design->selected_modules().empty()) {
+        if (!args.is_quiet) {
+            log_warning("Specified %s not found in design\n", TypeName().c_str());
+        }
+    }
+}
+
+void GetCmd::PackToTcl(const SelectionObjects &objects)
+{
+    Tcl_Obj *tcl_result;
+    if (objects.size() == 1) {
+        tcl_result = Tcl_NewStringObj(objects.at(0).c_str(), -1);
+    } else {
+        tcl_result = Tcl_NewListObj(0, NULL);
+        for (const auto &object : objects) {
+            Tcl_Obj *value_obj = Tcl_NewStringObj(object.c_str(), -1);
+            Tcl_ListObjAppendElement(yosys_get_tcl_interp(), tcl_result, value_obj);
+        }
+    }
+    Tcl_SetObjResult(yosys_get_tcl_interp(), tcl_result);
+}
+
+GetCmd::CommandArgs GetCmd::ParseCommand(const std::vector<std::string> &args)
+{
+    CommandArgs parsed_args{.filters = Filters(), .is_quiet = false, .selection_objects = SelectionObjects()};
+    size_t argidx(0);
+    for (argidx = 1; argidx < args.size(); argidx++) {
+        std::string arg = args[argidx];
+        if (arg == "-quiet") {
+            parsed_args.is_quiet = true;
+            continue;
+        }
+
+        if (arg == "-filter" and argidx + 1 < args.size()) {
+            std::string filter_arg = args[++argidx];
+
+            // Remove spaces
+            filter_arg.erase(std::remove_if(filter_arg.begin(), filter_arg.end(), isspace), filter_arg.end());
+
+            // Parse filters
+            // TODO Add support for multiple condition expression
+            // Currently only a single == is supported
+            std::regex filter_attr_regex("(\\w+\\s?==\\s?\\w+)([(||)(&&)]*)");
+            std::regex_token_iterator<std::string::iterator> regex_end;
+            std::regex_token_iterator<std::string::iterator> matches(filter_arg.begin(), filter_arg.end(), filter_attr_regex, 1);
+            if (matches == regex_end) {
+                log_warning("Currently -filter switch supports only a single "
+                            "'equal(==)' condition expression, the rest will be "
+                            "ignored\n");
+            }
+
+            while (matches != regex_end) {
+                std::string filter(*matches++);
+                auto separator = filter.find("==");
+                if (separator == std::string::npos) {
+                    log_cmd_error("Incorrect filter expression: %s\n", args[argidx].c_str());
+                }
+                parsed_args.filters.emplace_back(filter.substr(0, separator), filter.substr(separator + 2));
+            }
+            if (parsed_args.filters.size() > 1) {
+                log_warning("Currently -filter switch supports only a single "
+                            "'equal(==)' condition expression, the rest will be "
+                            "ignored\n");
+            }
+            continue;
+        }
+
+        if (arg.size() > 0 and arg[0] == '-') {
+            log_cmd_error("Unknown option %s.\n", arg.c_str());
+        }
+
+        break;
+    }
+    std::copy(args.begin() + argidx, args.end(), std::back_inserter(parsed_args.selection_objects));
+    return parsed_args;
+}
+
+void GetCmd::execute(std::vector<std::string> args, RTLIL::Design *design)
+{
+    if (design->top_module() == nullptr) {
+        log_cmd_error("No top module detected\n");
+    }
+
+    CommandArgs parsed_args(ParseCommand(args));
+    ExecuteSelection(design, parsed_args);
+    PackToTcl(ExtractSelection(design, parsed_args));
+}
diff --git a/yosys-plugins/design_introspection/get_cmd.h b/yosys-plugins/design_introspection/get_cmd.h
new file mode 100644
index 000000000..03a377171
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_cmd.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_CMD_H_
+#define _GET_CMD_H_
+
+#include "kernel/register.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetCmd : public Pass {
+    using Filter = std::pair<std::string, std::string>;
+    using Filters = std::vector<Filter>;
+    using SelectionObjects = std::vector<std::string>;
+    struct CommandArgs {
+        Filters filters;
+        bool is_quiet;
+        SelectionObjects selection_objects;
+    };
+
+    GetCmd(const std::string &name, const std::string &description) : Pass(name, description) {}
+
+    void help() override;
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override;
+
+  protected:
+    CommandArgs ParseCommand(const std::vector<std::string> &args);
+    void PackToTcl(const SelectionObjects &objects);
+
+  private:
+    virtual std::string TypeName() = 0;
+    virtual std::string SelectionType() = 0;
+    virtual SelectionObjects ExtractSelection(RTLIL::Design *design, const CommandArgs &args) = 0;
+    virtual void ExecuteSelection(RTLIL::Design *design, const CommandArgs &args);
+};
+
+#endif // GET_CMD_H_
diff --git a/yosys-plugins/design_introspection/get_count.cc b/yosys-plugins/design_introspection/get_count.cc
new file mode 100644
index 000000000..850d3f67a
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_count.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_count.h"
+
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+
+void GetCount::help()
+{
+    log("\n");
+    log("    get_count <options> [selection]");
+    log("\n");
+    log("When used from inside the TCL interpreter returns count of selected objects.\n");
+    log("The object type to count may be given as an argument. Only one at a time.\n");
+    log("If none is given then the total count of all selected objects is returned.\n");
+    log("\n");
+    log("    -modules\n");
+    log("        Returns the count of modules in selection\n");
+    log("\n");
+    log("    -cells\n");
+    log("        Returns the count of cells in selection\n");
+    log("\n");
+    log("    -wires\n");
+    log("        Returns the count of wires in selection\n");
+    log("\n");
+}
+
+void GetCount::execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design)
+{
+
+    // Parse args
+    ObjectType type = ObjectType::NONE;
+    if (a_Args.size() < 2) {
+        log_error("Invalid argument!\n");
+    }
+
+    if (a_Args[1] == "-modules") {
+        type = ObjectType::MODULE;
+    } else if (a_Args[1] == "-cells") {
+        type = ObjectType::CELL;
+    } else if (a_Args[1] == "-wires") {
+        type = ObjectType::WIRE;
+    } else if (a_Args[1][0] == '-') {
+        log_error("Invalid argument '%s'!\n", a_Args[1].c_str());
+    } else {
+        log_error("Object type not specified!\n");
+    }
+
+    extra_args(a_Args, 2, a_Design);
+
+    // Get the TCL interpreter
+    Tcl_Interp *tclInterp = yosys_get_tcl_interp();
+
+    // Count objects
+    size_t moduleCount = 0;
+    size_t cellCount = 0;
+    size_t wireCount = 0;
+
+    moduleCount += a_Design->selected_modules().size();
+    for (auto module : a_Design->selected_modules()) {
+        cellCount += module->selected_cells().size();
+        wireCount += module->selected_wires().size();
+    }
+
+    size_t count = 0;
+    switch (type) {
+    case ObjectType::MODULE:
+        count = moduleCount;
+        break;
+    case ObjectType::CELL:
+        count = cellCount;
+        break;
+    case ObjectType::WIRE:
+        count = wireCount;
+        break;
+    default:
+        log_assert(false);
+    }
+
+    // Return the value as string to the TCL interpreter
+    std::string value = std::to_string(count);
+
+    Tcl_Obj *tclStr = Tcl_NewStringObj(value.c_str(), value.size());
+    Tcl_SetObjResult(tclInterp, tclStr);
+}
diff --git a/yosys-plugins/design_introspection/get_count.h b/yosys-plugins/design_introspection/get_count.h
new file mode 100644
index 000000000..837fe6297
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_count.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_COUNT_H_
+#define _GET_COUNT_H_
+
+#include "kernel/register.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetCount : public Pass {
+
+    enum class ObjectType { NONE, MODULE, CELL, WIRE };
+
+    GetCount() : Pass("get_count", "Returns count of various selected object types to the TCL interpreter") {}
+
+    void help() override;
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override;
+};
+
+#endif // GET_COUNT_H_
diff --git a/yosys-plugins/design_introspection/get_nets.cc b/yosys-plugins/design_introspection/get_nets.cc
new file mode 100644
index 000000000..27e643add
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_nets.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_nets.h"
+
+USING_YOSYS_NAMESPACE
+
+std::string GetNets::TypeName() { return "net"; }
+
+std::string GetNets::SelectionType() { return "w"; }
+
+GetNets::SelectionObjects GetNets::ExtractSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    SelectionObjects selected_objects;
+    for (auto module : design->selected_modules()) {
+        for (auto wire : module->selected_wires()) {
+            if (args.filters.size() > 0) {
+                Filter filter = args.filters.at(0);
+                std::string attr_value = wire->get_string_attribute(RTLIL::IdString(RTLIL::escape_id(filter.first)));
+                if (attr_value.compare(filter.second)) {
+                    continue;
+                }
+            }
+            std::string object_name(RTLIL::unescape_id(wire->name));
+            selected_objects.push_back(object_name);
+        }
+    }
+    if (selected_objects.size() == 0 and !args.is_quiet) {
+        log_warning("Couldn't find matching net.\n");
+    }
+    return selected_objects;
+}
diff --git a/yosys-plugins/design_introspection/get_nets.h b/yosys-plugins/design_introspection/get_nets.h
new file mode 100644
index 000000000..b2c5dab70
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_nets.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_NETS_H_
+#define _GET_NETS_H_
+
+#include "get_cmd.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetNets : public GetCmd {
+    GetNets() : GetCmd("get_nets", "Print matching nets") {}
+
+    std::string TypeName() override;
+    std::string SelectionType() override;
+    SelectionObjects ExtractSelection(RTLIL::Design *design, const CommandArgs &args) override;
+};
+
+#endif // GET_NETS_H_
diff --git a/yosys-plugins/design_introspection/get_pins.cc b/yosys-plugins/design_introspection/get_pins.cc
new file mode 100644
index 000000000..6fa8b59ad
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_pins.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_pins.h"
+
+USING_YOSYS_NAMESPACE
+
+std::string GetPins::TypeName() { return "pin"; }
+
+std::string GetPins::SelectionType() { return "c"; }
+
+void GetPins::ExecuteSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    (void)design;
+    (void)args;
+}
+
+GetPins::SelectionObjects GetPins::ExtractSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    SelectionObjects selected_objects;
+    for (auto obj : args.selection_objects) {
+        size_t port_separator = obj.find_last_of('/');
+        std::string cell = obj.substr(0, port_separator);
+        std::string port = obj.substr(port_separator + 1);
+        SelectionObjects selection{RTLIL::unescape_id(design->top_module()->name) + "/" + SelectionType() + ":" + cell};
+        extra_args(selection, 0, design);
+        ExtractSingleSelection(selected_objects, design, port, args);
+    }
+    if (selected_objects.size() == 0 and !args.is_quiet) {
+        log_warning("Couldn't find matching pin.\n");
+    }
+    return selected_objects;
+}
+
+void GetPins::ExtractSingleSelection(SelectionObjects &objects, RTLIL::Design *design, const std::string &port_name, const CommandArgs &args)
+{
+    if (design->selected_modules().empty()) {
+        if (!args.is_quiet) {
+            log_warning("Specified %s not found in design\n", TypeName().c_str());
+        }
+    }
+    for (auto module : design->selected_modules()) {
+        for (auto cell : module->selected_cells()) {
+            if (!cell->hasPort(RTLIL::escape_id(port_name))) {
+                continue;
+            }
+            if (args.filters.size() > 0) {
+                Filter filter = args.filters.at(0);
+                std::string attr_value = cell->get_string_attribute(RTLIL::IdString(RTLIL::escape_id(filter.first)));
+                if (attr_value.compare(filter.second)) {
+                    continue;
+                }
+            }
+            std::string pin_name(RTLIL::unescape_id(cell->name) + "/" + port_name);
+            objects.push_back(pin_name);
+        }
+    }
+}
diff --git a/yosys-plugins/design_introspection/get_pins.h b/yosys-plugins/design_introspection/get_pins.h
new file mode 100644
index 000000000..8b66c525a
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_pins.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_PINS_H_
+#define _GET_PINS_H_
+
+#include "get_cmd.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetPins : public GetCmd {
+    GetPins() : GetCmd("get_pins", "Print matching pins") {}
+
+  private:
+    std::string TypeName() override;
+    std::string SelectionType() override;
+    SelectionObjects ExtractSelection(RTLIL::Design *design, const CommandArgs &args) override;
+    void ExecuteSelection(RTLIL::Design *design, const CommandArgs &args) override;
+    void ExtractSingleSelection(SelectionObjects &objects, RTLIL::Design *design, const std::string &port_name, const CommandArgs &args);
+};
+
+#endif // GET_PINS_H_
diff --git a/yosys-plugins/design_introspection/get_ports.cc b/yosys-plugins/design_introspection/get_ports.cc
new file mode 100644
index 000000000..51d11bf1e
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_ports.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "get_ports.h"
+#include "../utils.h"
+
+USING_YOSYS_NAMESPACE
+
+std::string GetPorts::TypeName() { return "port"; }
+
+std::string GetPorts::SelectionType() { return "x"; }
+
+void GetPorts::ExecuteSelection([[gnu::unused]] RTLIL::Design *design, [[gnu::unused]] const CommandArgs &args) {}
+
+GetPorts::SelectionObjects GetPorts::ExtractSelection(RTLIL::Design *design, const CommandArgs &args)
+{
+    std::string port_name = args.selection_objects.at(0);
+    trim(port_name);
+    std::string port_str(port_name.size(), '\0');
+    int bit(0);
+    if (!sscanf(port_name.c_str(), "%[^[][%d]", &port_str[0], &bit)) {
+        log_error("Couldn't find port %s\n", port_name.c_str());
+    }
+
+    port_str.resize(strlen(port_str.c_str()));
+    RTLIL::IdString port_id(RTLIL::escape_id(port_str));
+    SelectionObjects objects;
+    if (auto wire = design->top_module()->wire(port_id)) {
+        if (wire->port_input || wire->port_output) {
+            if (bit >= wire->start_offset && bit < wire->start_offset + wire->width) {
+                objects.push_back(port_name);
+            }
+        }
+    }
+    if (objects.size() == 0 and !args.is_quiet) {
+        log_warning("Couldn't find port matching %s\n", port_name.c_str());
+    }
+    return objects;
+}
diff --git a/yosys-plugins/design_introspection/get_ports.h b/yosys-plugins/design_introspection/get_ports.h
new file mode 100644
index 000000000..32662b98c
--- /dev/null
+++ b/yosys-plugins/design_introspection/get_ports.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef _GET_PORTS_H_
+#define _GET_PORTS_H_
+
+#include "get_cmd.h"
+
+USING_YOSYS_NAMESPACE
+
+struct GetPorts : public GetCmd {
+    GetPorts() : GetCmd("get_ports", "Print matching ports") {}
+
+  private:
+    std::string TypeName() override;
+    std::string SelectionType() override;
+    /* void execute(std::vector<std::string> args, RTLIL::Design* design) override; */
+    SelectionObjects ExtractSelection(RTLIL::Design *design, const CommandArgs &args) override;
+    void ExecuteSelection(RTLIL::Design *design, const CommandArgs &args) override;
+};
+
+#endif // GET_PORTS_H_
diff --git a/yosys-plugins/design_introspection/selection_to_tcl_list.cc b/yosys-plugins/design_introspection/selection_to_tcl_list.cc
new file mode 100644
index 000000000..fa1158a4a
--- /dev/null
+++ b/yosys-plugins/design_introspection/selection_to_tcl_list.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "selection_to_tcl_list.h"
+
+#include "kernel/log.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+
+void SelectionToTclList::help()
+{
+    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+    log("\n");
+    log("   selection_to_tcl_list selection\n");
+    log("\n");
+    log("Extract the current selection to a Tcl List with selection object names. \n");
+    log("\n");
+}
+
+void SelectionToTclList::execute(std::vector<std::string> args, RTLIL::Design *design)
+{
+    if (args.size() == 1) {
+        log_error("Incorrect number of arguments");
+    }
+    extra_args(args, 1, design);
+
+    Tcl_Interp *interp = yosys_get_tcl_interp();
+    Tcl_Obj *tcl_list = Tcl_NewListObj(0, NULL);
+
+    auto &selection = design->selection();
+    if (selection.empty()) {
+        log_warning("Selection is empty\n");
+    }
+
+    for (auto mod : design->modules()) {
+        if (selection.selected_module(mod->name)) {
+            for (auto wire : mod->wires()) {
+                if (selection.selected_member(mod->name, wire->name)) {
+                    AddObjectNameToTclList(mod->name, wire->name, tcl_list);
+                }
+            }
+            for (auto &it : mod->memories) {
+                if (selection.selected_member(mod->name, it.first)) {
+                    AddObjectNameToTclList(mod->name, it.first, tcl_list);
+                }
+            }
+            for (auto cell : mod->cells()) {
+                if (selection.selected_member(mod->name, cell->name)) {
+                    AddObjectNameToTclList(mod->name, cell->name, tcl_list);
+                }
+            }
+            for (auto &it : mod->processes) {
+                if (selection.selected_member(mod->name, it.first)) {
+                    AddObjectNameToTclList(mod->name, it.first, tcl_list);
+                }
+            }
+        }
+    }
+    Tcl_SetObjResult(interp, tcl_list);
+}
+
+void SelectionToTclList::AddObjectNameToTclList(RTLIL::IdString &module, RTLIL::IdString &object, Tcl_Obj *tcl_list)
+{
+    std::string name = RTLIL::unescape_id(module) + "/" + RTLIL::unescape_id(object);
+    Tcl_Obj *value_obj = Tcl_NewStringObj(name.c_str(), name.size());
+    Tcl_ListObjAppendElement(yosys_get_tcl_interp(), tcl_list, value_obj);
+}
diff --git a/yosys-plugins/design_introspection/selection_to_tcl_list.h b/yosys-plugins/design_introspection/selection_to_tcl_list.h
new file mode 100644
index 000000000..bbc4acbf0
--- /dev/null
+++ b/yosys-plugins/design_introspection/selection_to_tcl_list.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _SELECTION_TO_TCL_LIST_H_
+#define _SELECTION_TO_TCL_LIST_H_
+
+#include "kernel/register.h"
+
+USING_YOSYS_NAMESPACE
+
+struct SelectionToTclList : public Pass {
+    SelectionToTclList() : Pass("selection_to_tcl_list", "Extract selection to TCL list") {}
+
+    void help() override;
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override;
+
+  private:
+    void AddObjectNameToTclList(RTLIL::IdString &module, RTLIL::IdString &object, Tcl_Obj *tcl_list);
+};
+
+#endif // SELECTION_TO_TCL_LIST_H_
diff --git a/yosys-plugins/design_introspection/tests/Makefile b/yosys-plugins/design_introspection/tests/Makefile
new file mode 100644
index 000000000..4e6455f01
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/Makefile
@@ -0,0 +1,33 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = get_nets \
+	get_ports \
+	get_cells \
+	get_pins \
+	get_count \
+	selection_to_tcl_list
+
+UNIT_TESTS = trim_name
+
+include $(shell pwd)/../../Makefile_test.common
+
+get_nets_verify = true
+get_ports_verify = $(call diff_test,get_ports,txt)
+get_cells_verify = true
+get_pins_verify = $(call diff_test,get_pins,txt)
+get_count_verify = true
+selection_to_tcl_list_verify = $(call diff_test,selection_to_tcl_list,txt)
diff --git a/yosys-plugins/design_introspection/tests/get_cells/get_cells.golden.txt b/yosys-plugins/design_introspection/tests/get_cells/get_cells.golden.txt
new file mode 100644
index 000000000..b6ff53be0
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_cells/get_cells.golden.txt
@@ -0,0 +1,15 @@
+
+*inter* cells quiet
+bottom_intermediate_inst.OBUF_8
+
+*inter* cells
+bottom_intermediate_inst.OBUF_8
+
+*inter* cells with invalid filter expression
+bottom_intermediate_inst.OBUF_8
+
+Filtered cells
+OBUFTDS_2
+
+All cells
+{$abc$1984$lut$not$aiger1983$1} {$auto$alumacc.cc:485:replace_alu$1385.slice[0].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[1].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[2].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[3].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[4].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[5].carry4} {$auto$alumacc.cc:485:replace_alu$1385.slice[6].carry4} {$auto$simplemap.cc:420:simplemap_dff$1471} {$auto$simplemap.cc:420:simplemap_dff$1472} {$auto$simplemap.cc:420:simplemap_dff$1473} {$auto$simplemap.cc:420:simplemap_dff$1474} {$auto$simplemap.cc:420:simplemap_dff$1475} {$auto$simplemap.cc:420:simplemap_dff$1476} {$auto$simplemap.cc:420:simplemap_dff$1477} {$auto$simplemap.cc:420:simplemap_dff$1478} {$auto$simplemap.cc:420:simplemap_dff$1479} {$auto$simplemap.cc:420:simplemap_dff$1480} {$auto$simplemap.cc:420:simplemap_dff$1481} {$auto$simplemap.cc:420:simplemap_dff$1482} {$auto$simplemap.cc:420:simplemap_dff$1483} {$auto$simplemap.cc:420:simplemap_dff$1484} {$auto$simplemap.cc:420:simplemap_dff$1485} {$auto$simplemap.cc:420:simplemap_dff$1486} {$auto$simplemap.cc:420:simplemap_dff$1487} {$auto$simplemap.cc:420:simplemap_dff$1488} {$auto$simplemap.cc:420:simplemap_dff$1489} {$auto$simplemap.cc:420:simplemap_dff$1490} {$auto$simplemap.cc:420:simplemap_dff$1491} {$auto$simplemap.cc:420:simplemap_dff$1492} {$auto$simplemap.cc:420:simplemap_dff$1493} {$auto$simplemap.cc:420:simplemap_dff$1494} {$auto$simplemap.cc:420:simplemap_dff$1495} {$auto$simplemap.cc:420:simplemap_dff$1496} {$iopadmap$top.clk} OBUFTDS_2 OBUF_6 OBUF_7 OBUF_OUT bottom_inst.OBUF_10 bottom_inst.OBUF_11 bottom_inst.OBUF_9 bottom_intermediate_inst.OBUF_8
diff --git a/yosys-plugins/design_introspection/tests/get_cells/get_cells.tcl b/yosys-plugins/design_introspection/tests/get_cells/get_cells.tcl
new file mode 100644
index 000000000..d07792430
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_cells/get_cells.tcl
@@ -0,0 +1,32 @@
+yosys -import
+if { [info procs get_cells] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+
+set fp [open [test_output_path "get_cells.txt"] "w"]
+
+puts "\n*inter* cells quiet"
+puts $fp "\n*inter* cells quiet"
+puts $fp [get_cells -quiet *inter*]
+
+puts "\n*inter* cells"
+puts $fp "\n*inter* cells"
+puts $fp [get_cells *inter*]
+
+puts "\n*inter* cells with invalid filter expression"
+puts $fp "\n*inter* cells with invalid filter expression"
+puts $fp [get_cells -filter {mr_ff != true} *inter* ]
+
+puts "\nFiltered cells"
+puts $fp "\nFiltered cells"
+puts $fp [get_cells -filter {mr_ff == true || async_reg == true && dont_touch == true} ]
+
+puts "\nAll cells"
+puts $fp "\nAll cells"
+puts $fp [get_cells]
+
+close $fp
diff --git a/yosys-plugins/design_introspection/tests/get_cells/get_cells.v b/yosys-plugins/design_introspection/tests/get_cells/get_cells.v
new file mode 100644
index 000000000..c0a51ff1b
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_cells/get_cells.v
@@ -0,0 +1,121 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  (* async_reg = "true", mr_ff = "true", dont_touch = "true" *)
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  (* async_reg = "false", mr_ff = "false", dont_touch = "true" *)
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/design_introspection/tests/get_count/Makefile b/yosys-plugins/design_introspection/tests/get_count/Makefile
new file mode 100644
index 000000000..250eec32f
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_count/Makefile
@@ -0,0 +1,24 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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:
+	yosys -p "tcl script.tcl"
+	touch ok
+
+clean:
+	rm -rf ok
+
+.PHONY: test clean
diff --git a/yosys-plugins/design_introspection/tests/get_count/get_count.tcl b/yosys-plugins/design_introspection/tests/get_count/get_count.tcl
new file mode 100644
index 000000000..17689af72
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_count/get_count.tcl
@@ -0,0 +1,31 @@
+yosys -import
+if { [info procs get_count] == {} } { plugin -i design_introspection }
+yosys -import # ingest new plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -auto-top
+
+set n [get_count -modules my_gate]
+puts "Module count: $n"
+if {$n != "1"} {
+    error "Invalid count"
+}
+
+set n [get_count -cells t:\$_BUF_]
+puts "BUF count: $n"
+if {$n != "4"} {
+    error "Invalid count"
+}
+
+set n [get_count -cells t:\$_NOT_]
+puts "NOT count: $n"
+if {$n != "3"} {
+    error "Invalid count"
+}
+
+set n [get_count -wires w:*]
+puts "Wire count: $n"
+if {$n != "5"} {
+    error "Invalid count"
+}
+
diff --git a/yosys-plugins/design_introspection/tests/get_count/get_count.v b/yosys-plugins/design_introspection/tests/get_count/get_count.v
new file mode 100644
index 000000000..18aea441e
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_count/get_count.v
@@ -0,0 +1,39 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module my_gate (
+    input  wire A,
+    output wire Y
+);
+
+    assign Y = ~A;
+endmodule
+
+module top (
+    input  wire [7:0] di,
+    output wire [7:0] do
+);
+
+    my_gate c0 (.A(di[0]), .Y(do[0]));
+    \$_BUF_ c1 (.A(di[1]), .Y(do[1]));
+    \$_BUF_ c2 (.A(di[2]), .Y(do[2]));
+    \$_BUF_ c3 (.A(di[3]), .Y(do[3]));
+    \$_BUF_ c4 (.A(di[4]), .Y(do[4]));
+    \$_NOT_ c5 (.A(di[5]), .Y(do[5]));
+    \$_NOT_ c6 (.A(di[6]), .Y(do[6]));
+    \$_NOT_ c7 (.A(di[7]), .Y(do[7]));
+
+endmodule
diff --git a/yosys-plugins/design_introspection/tests/get_nets/get_nets.golden.txt b/yosys-plugins/design_introspection/tests/get_nets/get_nets.golden.txt
new file mode 100644
index 000000000..34eb615bb
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_nets/get_nets.golden.txt
@@ -0,0 +1,10 @@
+*inter* nets quiet
+bottom_intermediate_inst.I bottom_intermediate_inst.O bottom_intermediate_inst.bottom_intermediate_wire inter_wire inter_wire_2
+*inter* nets
+bottom_intermediate_inst.I bottom_intermediate_inst.O bottom_intermediate_inst.bottom_intermediate_wire inter_wire inter_wire_2
+*inter* nets with invalid filter expression
+bottom_intermediate_inst.I bottom_intermediate_inst.O bottom_intermediate_inst.bottom_intermediate_wire inter_wire inter_wire_2
+Filtered nets
+clk
+All nets
+{$abc$1984$aiger1983$38} {$abc$1984$aiger1983$42} {$abc$1984$aiger1983$43} {$abc$1984$aiger1983$44} {$abc$1984$aiger1983$45} {$abc$1984$aiger1983$50} {$abc$1984$aiger1983$51} {$abc$1984$aiger1983$52} {$abc$1984$aiger1983$53} {$abc$1984$aiger1983$58} {$abc$1984$aiger1983$59} {$abc$1984$aiger1983$60} {$abc$1984$aiger1983$61} {$abc$1984$aiger1983$66} {$abc$1984$aiger1983$67} {$abc$1984$aiger1983$68} {$abc$1984$aiger1983$69} {$abc$1984$aiger1983$74} {$abc$1984$aiger1983$75} {$abc$1984$aiger1983$76} {$abc$1984$aiger1983$77} {$abc$1984$aiger1983$82} {$abc$1984$aiger1983$83} {$abc$1984$aiger1983$84} {$abc$1984$aiger1983$85} {$abc$1984$aiger1983$88} {$abc$1984$aiger1983$89} {$abc$1984$aiger1983$90} {$abc$1984$aiger1983$91} {$abc$1984$aiger1983$92} {$abc$1984$aiger1983$93} {$abc$1984$iopadmap$clk} {$auto$alumacc.cc:485:replace_alu$1385.O} LD6 LD7 LD8 LD9 bottom_inst.I bottom_inst.O bottom_inst.OB bottom_intermediate_inst.I bottom_intermediate_inst.O bottom_intermediate_inst.bottom_intermediate_wire clk counter inter_wire inter_wire_2 led out_a out_b signal_n signal_p
diff --git a/yosys-plugins/design_introspection/tests/get_nets/get_nets.tcl b/yosys-plugins/design_introspection/tests/get_nets/get_nets.tcl
new file mode 100644
index 000000000..5dc7ae454
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_nets/get_nets.tcl
@@ -0,0 +1,32 @@
+yosys -import
+if { [info procs get_nets] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+
+set fp [open [test_output_path "get_nets.txt"] "w"]
+
+puts "\n*inter* nets quiet"
+puts $fp "*inter* nets quiet"
+puts $fp [get_nets -quiet *inter*]
+
+puts "\n*inter* nets"
+puts $fp "*inter* nets"
+puts $fp [get_nets *inter*]
+
+puts "\n*inter* nets with invalid filter expression"
+puts $fp "*inter* nets with invalid filter expression"
+puts $fp [get_nets -filter {mr_ff != true} *inter* ]
+
+puts "\nFiltered nets"
+puts $fp "Filtered nets"
+puts $fp [get_nets -filter {mr_ff == true || async_reg == true && dont_touch == true} ]
+
+puts "\nAll nets"
+puts $fp "All nets"
+puts $fp [get_nets]
+
+close $fp
diff --git a/yosys-plugins/design_introspection/tests/get_nets/get_nets.v b/yosys-plugins/design_introspection/tests/get_nets/get_nets.v
new file mode 100644
index 000000000..d8a6411db
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_nets/get_nets.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/design_introspection/tests/get_pins/get_pins.golden.txt b/yosys-plugins/design_introspection/tests/get_pins/get_pins.golden.txt
new file mode 100644
index 000000000..b92d21a97
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_pins/get_pins.golden.txt
@@ -0,0 +1,12 @@
+
+*inter* pins quiet
+OBUF_6/I
+
+*inter* pins
+OBUF_6/I
+
+*inter* pins with invalid filter expression
+bottom_intermediate_inst.OBUF_8/I
+
+Filtered pins
+OBUF_7/I OBUF_OUT/I
diff --git a/yosys-plugins/design_introspection/tests/get_pins/get_pins.tcl b/yosys-plugins/design_introspection/tests/get_pins/get_pins.tcl
new file mode 100644
index 000000000..43ab60ced
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_pins/get_pins.tcl
@@ -0,0 +1,28 @@
+yosys -import
+if { [info procs get_pins] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+
+set fp [open [test_output_path "get_pins.txt"] "w"]
+
+puts "\n*inter* pins quiet"
+puts $fp "\n*inter* pins quiet"
+puts $fp [get_pins -quiet OBUF_6/I]
+
+puts "\n*inter* pins"
+puts $fp "\n*inter* pins"
+puts $fp [get_pins OBUF_6/I]
+
+puts "\n*inter* pins with invalid filter expression"
+puts $fp "\n*inter* pins with invalid filter expression"
+puts $fp [get_pins -filter {mr_ff != true} *inter*/I ]
+
+puts "\nFiltered pins"
+puts $fp "\nFiltered pins"
+puts $fp [get_pins -filter {dont_touch == true || async_reg == true && mr_ff == true} *OBUF*/I ]
+
+close $fp
diff --git a/yosys-plugins/design_introspection/tests/get_pins/get_pins.v b/yosys-plugins/design_introspection/tests/get_pins/get_pins.v
new file mode 100644
index 000000000..d4d3b5069
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_pins/get_pins.v
@@ -0,0 +1,121 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      (* test_attr = "true" *)
+      .I(LD6),
+      .O(led[0])
+  );
+  (* dont_touch = "true" *) OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  (* dont_touch = "true" *) OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+(* async_reg = "true", mr_ff = "false", dont_touch = "true" *)
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/design_introspection/tests/get_ports/get_ports.golden.txt b/yosys-plugins/design_introspection/tests/get_ports/get_ports.golden.txt
new file mode 100644
index 000000000..d427ccd62
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_ports/get_ports.golden.txt
@@ -0,0 +1,8 @@
+signal_p port
+signal_p
+clk port
+clk
+led[0] port
+led[0]
+led[1] port
+led[1]
diff --git a/yosys-plugins/design_introspection/tests/get_ports/get_ports.tcl b/yosys-plugins/design_introspection/tests/get_ports/get_ports.tcl
new file mode 100644
index 000000000..7724e2867
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_ports/get_ports.tcl
@@ -0,0 +1,50 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+help get_ports
+
+set fp [open [test_output_path "get_ports.txt"] "w"]
+
+puts "\n signal_p port"
+puts $fp "signal_p port"
+puts $fp [get_ports signal_p]
+
+puts "\n clk port"
+puts $fp "clk port"
+puts $fp [get_ports clk]
+
+puts "\n"
+puts { led[0] port}
+puts $fp {led[0] port}
+puts $fp [get_ports {led[0]}]
+
+puts "\n"
+puts { led[1] port}
+puts $fp {led[1] port}
+puts $fp [get_ports { led[1] }]
+
+#puts "\nsignal_* ports quiet"
+#puts $fp "signal_* ports quiet"
+#puts $fp [get_ports -quiet signal_*]
+#
+#puts "\nsignal_* ports"
+#puts $fp "signal_* ports"
+#puts $fp [get_ports signal_*]
+#
+#puts "\nled ports with filter expression"
+#puts $fp "led ports with filter expression"
+#puts $fp [get_ports -filter {mr_ff != true} led]
+#
+#puts "\nFiltered ports"
+#puts $fp "Filtered ports"
+#puts $fp [get_ports -filter {mr_ff == true || async_reg == true && dont_touch == true} ]
+#
+#puts "\nAll ports"
+#puts $fp "All ports"
+#puts $fp [get_ports]
+
+close $fp
diff --git a/yosys-plugins/design_introspection/tests/get_ports/get_ports.v b/yosys-plugins/design_introspection/tests/get_ports/get_ports.v
new file mode 100644
index 000000000..d8a6411db
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/get_ports/get_ports.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.golden.txt b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.golden.txt
new file mode 100644
index 000000000..e071e398a
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.golden.txt
@@ -0,0 +1,3 @@
+{middle/$add$selection_to_tcl_list.v:54$5} top/middle_inst_4 top/middle_inst_3 top/middle_inst_2 top/middle_inst_1 {top/$add$selection_to_tcl_list.v:22$2} top/ibuf_inst top/ibuf_proxy
+{middle/$1\cnt[1:0]} {middle/$add$selection_to_tcl_list.v:54$5_Y} {middle/$0\cnt[1:0]} middle/clk_int middle/cnt middle/out middle/clk {top/$1\cnt[1:0]} {top/$add$selection_to_tcl_list.v:22$2_Y} {top/$0\cnt[1:0]} top/ibuf_out top/ibuf_proxy_out top/clk_int_2 top/clk_int_1 top/cnt top/out top/in top/clk2 top/clk
+{middle/$1\cnt[1:0]} {middle/$add$selection_to_tcl_list.v:54$5_Y} {middle/$0\cnt[1:0]} middle/clk_int middle/cnt middle/out middle/clk {middle/$add$selection_to_tcl_list.v:54$5} {middle/$proc$selection_to_tcl_list.v:50$6} {middle/$proc$selection_to_tcl_list.v:53$4} {top/$1\cnt[1:0]} {top/$add$selection_to_tcl_list.v:22$2_Y} {top/$0\cnt[1:0]} top/ibuf_out top/ibuf_proxy_out top/clk_int_2 top/clk_int_1 top/cnt top/out top/in top/clk2 top/clk top/middle_inst_4 top/middle_inst_3 top/middle_inst_2 top/middle_inst_1 {top/$add$selection_to_tcl_list.v:22$2} top/ibuf_inst top/ibuf_proxy {top/$proc$selection_to_tcl_list.v:8$3} {top/$proc$selection_to_tcl_list.v:21$1}
diff --git a/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.tcl b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.tcl
new file mode 100644
index 000000000..b58291723
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.tcl
@@ -0,0 +1,41 @@
+yosys -import
+if { [info procs selection_to_tcl_list] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+proc selection_to_tcl_list_through_file { selection } {
+    set file_name [test_output_path "[pid].txt"]
+    select $selection -write $file_name
+    set fh [open $file_name r]
+    set result [list]
+    while {[gets $fh line] >= 0} {
+	lappend result $line
+    }
+    close $fh
+    file delete $file_name
+    return $result
+}
+
+proc test_selection { rfh selection } {
+    if {[expr {[selection_to_tcl_list_through_file $selection] != [selection_to_tcl_list $selection]}]} {
+    	puts "List from file: [selection_to_tcl_list_through_file $selection]"
+    	puts "List in selection: [selection_to_tcl_list $selection]"
+	error "Test with selection: $selection failed"
+    } else {
+	puts $rfh [selection_to_tcl_list $selection]
+    }
+}
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Test the selection command and write results to file
+set rfh [open [test_output_path "selection_to_tcl_list.txt"] w]
+
+set selection_tests [list "t:*" "w:*" "*"]
+foreach test $selection_tests {
+    test_selection $rfh $test
+}
+
+close $rfh
diff --git a/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.v b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.v
new file mode 100644
index 000000000..88e9f9e1f
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/selection_to_tcl_list/selection_to_tcl_list.v
@@ -0,0 +1,58 @@
+module top (
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/design_introspection/tests/trim_name/trim_name.test.cc b/yosys-plugins/design_introspection/tests/trim_name/trim_name.test.cc
new file mode 100644
index 000000000..2ac3b3426
--- /dev/null
+++ b/yosys-plugins/design_introspection/tests/trim_name/trim_name.test.cc
@@ -0,0 +1,22 @@
+#include "../utils.h"
+
+#include <gtest/gtest.h>
+
+TEST(UtilitiesTest, TrimName)
+{
+    std::string original("  wire_name  ");
+    // trim wire_name from both sides
+    std::string name(original);
+    trim(name);
+    EXPECT_EQ(name, "wire_name");
+
+    // trim wire_name from left-hand side
+    name = original;
+    trim_left(name);
+    EXPECT_EQ(name, "wire_name  ");
+
+    // trim wire_name from right-hand side
+    name = original;
+    trim_right(name);
+    EXPECT_EQ(name, "  wire_name");
+}
diff --git a/yosys-plugins/dsp-ff/Makefile b/yosys-plugins/dsp-ff/Makefile
new file mode 100644
index 000000000..9cd980084
--- /dev/null
+++ b/yosys-plugins/dsp-ff/Makefile
@@ -0,0 +1,24 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = dsp-ff
+SOURCES = dsp_ff.cc 
+
+include ../Makefile_plugin.common
+
+install:
+	install -D nexus-dsp_rules.txt $(DATA_DIR)/nexus/dsp_rules.txt
+
diff --git a/yosys-plugins/dsp-ff/dsp_ff.cc b/yosys-plugins/dsp-ff/dsp_ff.cc
new file mode 100644
index 000000000..d0ecd8e23
--- /dev/null
+++ b/yosys-plugins/dsp-ff/dsp_ff.cc
@@ -0,0 +1,1373 @@
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+// ============================================================================
+
+struct DspFF : public Pass {
+
+    /// A structure identifying specific pin in a cell instance
+    struct CellPin {
+        RTLIL::Cell *cell;    /// Cell pointer (nullptr for top-level ports)
+        RTLIL::IdString port; /// Port name
+        int bit;              /// Bit index
+
+        CellPin(RTLIL::Cell *_cell, const RTLIL::IdString &_port, int _bit = 0) : cell(_cell), port(_port), bit(_bit) {}
+
+        CellPin(const CellPin &ref) = default;
+        CellPin(CellPin &&ref) = default;
+
+        unsigned int hash() const
+        {
+            unsigned int h = 0;
+            if (cell != nullptr) {
+                h = mkhash_add(h, cell->hash());
+            }
+            h = mkhash_add(h, port.hash());
+            h = mkhash_add(h, bit);
+            return h;
+        }
+
+        bool operator==(const CellPin &ref) const { return (cell == ref.cell) && (port == ref.port) && (bit == ref.bit); }
+
+        std::string as_string() const
+        {
+            if (cell != nullptr) {
+                return stringf("%s.%s[%d]", RTLIL::unescape_id(cell->name).c_str(), RTLIL::unescape_id(port).c_str(), bit);
+            } else {
+                return stringf("%s[%d]", RTLIL::unescape_id(port).c_str(), bit);
+            }
+        }
+    };
+
+    // ..........................................
+
+    /// Connection map
+    struct ConnMap {
+
+        /// Maps source SigBit to all sinks it drives CellPin.
+        dict<RTLIL::SigBit, std::vector<CellPin>> sinks;
+        /// Maps source SigBit to its driver CellPin
+        dict<RTLIL::SigBit, CellPin> drivers;
+
+        /// Builds the map
+        void build(RTLIL::Module *module, const SigMap &sigmap)
+        {
+            clear();
+
+            // Scan cell ports
+            for (auto *cell : module->cells()) {
+                for (const auto &it : cell->connections_) {
+                    const auto &port = it.first;
+                    const auto &sigbits = it.second.bits();
+                    for (size_t i = 0; i < sigbits.size(); ++i) {
+                        auto sigbit = sigmap(sigbits[i]);
+
+                        // This is an input port (sink))
+                        if (cell->input(port)) {
+                            auto &vec = sinks[sigbit];
+                            vec.push_back(CellPin(cell, port, i));
+                        }
+                        // This is a source
+                        if (cell->output(port)) {
+                            drivers.insert(std::make_pair(sigbit, CellPin(cell, port, i)));
+                        }
+                    }
+                }
+            }
+
+            // Scan top-level ports
+            for (auto &it : module->wires_) {
+                auto *wire = it.second;
+
+                if (!wire->port_input && !wire->port_output) {
+                    continue;
+                }
+
+                RTLIL::SigSpec sigspec(wire, wire->start_offset, wire->width);
+                const auto &sigbits = sigspec.bits();
+                for (size_t i = 0; i < sigbits.size(); ++i) {
+                    auto sigbit = sigbits[i];
+                    if (!sigbit.wire) {
+                        continue;
+                    }
+
+                    // Output port (sink)
+                    if (sigbit.wire->port_output) {
+                        auto &vec = sinks[sigmap(sigbit)];
+                        vec.push_back(CellPin(nullptr, sigbit.wire->name, i));
+                    }
+                    // Input port (source)
+                    if (sigbit.wire->port_input) {
+                        drivers.insert(std::make_pair(sigbit, CellPin(nullptr, sigbit.wire->name, i)));
+                    }
+                }
+            }
+        }
+
+        /// Clears the map
+        void clear()
+        {
+            sinks.clear();
+            drivers.clear();
+        };
+    };
+
+    // ..........................................
+
+    /// Describes a flip-flop type that can be integrated with a DSP cell
+    struct FlopType {
+        RTLIL::IdString name;
+
+        /// A dict of port names indexed by their functions (like "clk", "rst")
+        dict<RTLIL::IdString, RTLIL::IdString> ports;
+
+        struct {
+            /// A list of parameters that must match for all flip-flops
+            std::vector<RTLIL::IdString> matching;
+            /// A dict of parameter values that must match for a flip-flop
+            dict<RTLIL::IdString, RTLIL::Const> required;
+            /// A dict of parameters to be set in the DSP cell after integration
+            dict<RTLIL::IdString, RTLIL::Const> set;
+            /// A dict of parameters to be mapped to the DSP cell after integration
+            dict<RTLIL::IdString, RTLIL::IdString> map;
+        } params;
+    };
+
+    /// Describes a DSP cell port that has built-in register (flip-flops)
+    struct PortType {
+        RTLIL::IdString name;
+
+        /// Range of port pins that have FFs (low to high, inclusive)
+        std::pair<int, int> bits;
+        /// A dict of associated cell ports indexed by their function (like "clk, "rst")
+        /// along with the default value to connect when unused.
+        dict<RTLIL::IdString, std::pair<RTLIL::IdString, RTLIL::Const>> assoc;
+    };
+
+    /// Describes a DSP register
+    struct RegisterType {
+
+        /// Control parameters
+        struct {
+            /// A dict of parameters to be set in the cell after integration
+            dict<RTLIL::IdString, RTLIL::Const> set;
+            /// A dict of parameters to be mapped to the cell after integration
+            dict<RTLIL::IdString, RTLIL::IdString> map;
+        } params;
+
+        /// A list of ports to be connected to specific constants after flip-flop
+        /// integration.
+        dict<RTLIL::IdString, RTLIL::Const> connect;
+
+        unsigned int hash() const
+        {
+            unsigned int h = 0;
+            h = mkhash_add(h, params.set.hash());
+            h = mkhash_add(h, params.map.hash());
+            h = mkhash_add(h, connect.hash());
+            return h;
+        }
+
+        bool operator==(const RegisterType &ref) const
+        {
+            return (params.set == ref.params.set) && (params.map == ref.params.map) && (connect == ref.connect);
+        }
+    };
+
+    /// Describes a DSP cell type
+    struct DspType {
+        RTLIL::IdString name;
+        dict<RegisterType, std::vector<PortType>> registers;
+    };
+
+    /// Describes a changes made to a DSP cell
+    struct DspChanges {
+        pool<RTLIL::IdString> params; // Modified params
+        pool<RTLIL::IdString> conns;  // Altered connections (ports)
+    };
+
+    // ..........................................
+
+    /// Describes unique flip-flop configuration that is exclusive.
+    struct FlopData {
+        RTLIL::IdString type;
+        dict<RTLIL::IdString, RTLIL::SigBit> conns;
+        struct {
+            dict<RTLIL::IdString, RTLIL::Const> flop;
+            dict<RTLIL::IdString, RTLIL::Const> dsp;
+        } params;
+
+        FlopData(const RTLIL::IdString &_type) : type(_type){};
+
+        FlopData(const FlopData &ref) = default;
+        FlopData(FlopData &&ref) = default;
+
+        unsigned int hash() const
+        {
+            unsigned int h = 0;
+            h = mkhash_add(h, type.hash());
+            h = mkhash_add(h, conns.hash());
+            h = mkhash_add(h, params.flop.hash());
+            h = mkhash_add(h, params.dsp.hash());
+            return h;
+        }
+
+        bool operator==(const FlopData &ref) const
+        {
+            return (type == ref.type) && (conns == ref.conns) && (params.flop == ref.params.flop) && (params.dsp == ref.params.dsp);
+        }
+    };
+
+    // ..........................................
+
+    /// Loads FF and DSP integration rules from a file
+    void load_rules(const std::string &a_FileName)
+    {
+
+        // Parses a string and returns a vector of fields delimited by the
+        // given character.
+        auto getFields = [](const std::string &a_String, const char a_Delim = ' ', bool a_KeepEmpty = false) {
+            std::vector<std::string> fields;
+            std::stringstream ss(a_String);
+
+            while (ss.good()) {
+                std::string field;
+                std::getline(ss, field, a_Delim);
+                if (!field.empty() || a_KeepEmpty) {
+                    fields.push_back(field);
+                }
+            }
+
+            return fields;
+        };
+
+        // Parses a vector of strings like "<name>=<value>" starting from the
+        // second one on the list
+        auto parseNameValue = [&](const std::vector<std::string> &strs) {
+            const std::regex expr("(\\S+)=(\\S+)");
+            std::smatch match;
+
+            std::vector<std::pair<std::string, std::string>> vec;
+
+            for (size_t i = 1; i < strs.size(); ++i) {
+                if (std::regex_match(strs[i], match, expr)) {
+                    vec.push_back(std::make_pair(match[1], match[2]));
+                } else {
+                    log_error(" syntax error: '%s'\n", strs[i].c_str());
+                }
+            }
+
+            return vec;
+        };
+
+        // Parses port name as "<name>[<hi>:<lo>]" or just "<name>"
+        auto parsePortName = [&](const std::string &str) {
+            const std::regex expr("^(.*)\\[([0-9]+):([0-9]+)\\]");
+            std::smatch match;
+
+            std::tuple<std::string, int, int> data;
+            auto res = std::regex_match(str, match, expr);
+            if (res) {
+                data = std::make_tuple(std::string(match[1]), std::stoi(match[2]), std::stoi(match[3]));
+
+                if ((std::get<2>(data) > std::get<1>(data)) || std::get<2>(data) < 0 || std::get<1>(data) < 0) {
+                    log_error(" invalid port spec: '%s'\n", str.c_str());
+                }
+            } else {
+                data = std::make_tuple(str, -1, -1);
+            }
+
+            return data;
+        };
+
+        std::ifstream file(a_FileName);
+        std::string line;
+
+        log("Loading rules from '%s'...\n", a_FileName.c_str());
+        if (!file) {
+            log_error(" Error opening file '%s'!\n", a_FileName.c_str());
+        }
+
+        // Parse each port as if it was associated with its own DSP register.
+        // Group them each time a port definition is complete.
+        PortType portType;
+        RegisterType registerType;
+
+        std::vector<DspType> dspTypes;
+        std::vector<FlopType> flopTypes;
+
+        std::vector<RTLIL::IdString> dspAliases;
+        std::vector<std::string> portNames;
+
+        std::vector<std::string> tok;
+
+        // Parse the file
+        while (1) {
+
+            // Get line
+            std::getline(file, line);
+            if (!file) {
+                break;
+            }
+
+            // Strip comment if any, skip empty lines
+            size_t pos = line.find("#");
+            if (pos != std::string::npos) {
+                line = line.substr(0, pos);
+            }
+            if (line.find_first_not_of(" \r\n\t") == std::string::npos) {
+                continue;
+            }
+
+            // Split the line
+            const auto fields = getFields(line);
+            log_assert(fields.size() >= 1);
+
+            // DSP section
+            if (fields[0] == "dsp") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (!tok.empty()) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.push_back(fields[0]);
+
+                dspTypes.resize(dspTypes.size() + 1);
+                dspTypes.back().name = RTLIL::escape_id(fields[1]);
+
+                dspAliases.clear();
+                for (size_t i = 2; i < fields.size(); ++i) {
+                    dspAliases.push_back(RTLIL::escape_id(fields[i]));
+                }
+            } else if (fields[0] == "enddsp") {
+                if (fields.size() != 1) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() != 1 || tok.back() != "dsp") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.pop_back();
+
+                const auto dspType = dspTypes.back();
+
+                for (const auto &alias : dspAliases) {
+                    dspTypes.push_back(dspType);
+                    dspTypes.back().name = alias;
+                }
+            }
+
+            // DSP port section
+            else if (fields[0] == "port") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() != 1 || tok.back() != "dsp") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.push_back(fields[0]);
+
+                auto spec = parsePortName(fields[1]);
+
+                portType = PortType();
+                portType.name = RTLIL::escape_id(std::get<0>(spec));
+                portType.bits = std::make_pair(std::get<2>(spec), std::get<1>(spec));
+                portType.assoc.insert(std::make_pair(RTLIL::escape_id("clk"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
+                portType.assoc.insert(std::make_pair(RTLIL::escape_id("rst"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
+                portType.assoc.insert(std::make_pair(RTLIL::escape_id("ena"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
+
+                registerType = RegisterType();
+
+                portNames.clear();
+                for (size_t i = 2; i < fields.size(); ++i) {
+                    portNames.push_back(fields[i]);
+                }
+
+            } else if (fields[0] == "endport") {
+                if (fields.size() != 1) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() != 2 || tok.back() != "port") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.pop_back();
+
+                // Store the DSP port
+                auto &dspType = dspTypes.back();
+                dspType.registers[registerType].push_back(portType);
+
+                // Store any extra DSP ports belonging to the same register
+                for (const auto &name : portNames) {
+                    auto spec = parsePortName(name);
+
+                    PortType portTypeCopy = portType;
+                    portTypeCopy.name = RTLIL::escape_id(std::get<0>(spec));
+                    portTypeCopy.bits = std::make_pair(std::get<2>(spec), std::get<1>(spec));
+
+                    dspType.registers[registerType].push_back(portTypeCopy);
+                }
+            }
+
+            // Flip-flop type section
+            else if (fields[0] == "ff") {
+                if (fields.size() != 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (!tok.empty()) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.push_back(fields[0]);
+
+                flopTypes.resize(flopTypes.size() + 1);
+                flopTypes.back().name = RTLIL::escape_id(fields[1]);
+                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("clk"), RTLIL::IdString()));
+                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("rst"), RTLIL::IdString()));
+                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("ena"), RTLIL::IdString()));
+                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("d"), RTLIL::IdString()));
+                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("q"), RTLIL::IdString()));
+            } else if (fields[0] == "endff") {
+                if (fields.size() != 1) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() != 1 || tok.back() != "ff") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+                tok.pop_back();
+            }
+
+            // Signals
+            else if (fields[0] == "clk") {
+                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                // Associated clock
+                if (tok.back() == "port") {
+                    if (fields.size() != 3) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    portType.assoc[RTLIL::escape_id("clk")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
+                } else if (tok.back() == "ff") {
+                    if (fields.size() != 2) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    flopTypes.back().ports[RTLIL::escape_id("clk")] = RTLIL::escape_id(fields[1]);
+                }
+            } else if (fields[0] == "rst") {
+                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                // Associated reset
+                if (tok.back() == "port") {
+                    if (fields.size() != 3) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    portType.assoc[RTLIL::escape_id("rst")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
+                } else if (tok.back() == "ff") {
+                    if (fields.size() != 2) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    flopTypes.back().ports[RTLIL::escape_id("rst")] = RTLIL::escape_id(fields[1]);
+                }
+            } else if (fields[0] == "ena") {
+                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                // Associated enable
+                if (tok.back() == "port") {
+                    if (fields.size() != 3) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    portType.assoc[RTLIL::escape_id("ena")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
+                } else if (tok.back() == "ff") {
+                    if (fields.size() != 2) {
+                        log_error(" syntax error: '%s'\n", line.c_str());
+                    }
+                    flopTypes.back().ports[RTLIL::escape_id("ena")] = RTLIL::escape_id(fields[1]);
+                }
+            }
+
+            else if (fields[0] == "d") {
+                if (fields.size() != 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || tok.back() != "ff") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                flopTypes.back().ports[RTLIL::escape_id("d")] = RTLIL::escape_id(fields[1]);
+            } else if (fields[0] == "q") {
+                if (fields.size() != 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || tok.back() != "ff") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                flopTypes.back().ports[RTLIL::escape_id("q")] = RTLIL::escape_id(fields[1]);
+            }
+
+            // Parameters that must be set to certain values
+            else if (fields[0] == "require") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || tok.back() != "ff") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                const auto vec = parseNameValue(fields);
+                for (const auto &it : vec) {
+                    flopTypes.back().params.required.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
+                }
+            }
+            // Parameters that has to match for a flip-flop
+            else if (fields[0] == "match") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || tok.back() != "ff") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                for (size_t i = 1; i < fields.size(); ++i) {
+                    flopTypes.back().params.matching.push_back(RTLIL::escape_id(fields[i]));
+                }
+            }
+            // Parameters to set
+            else if (fields[0] == "set") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                const auto vec = parseNameValue(fields);
+                dict<RTLIL::IdString, RTLIL::Const> set;
+                for (const auto &it : vec) {
+                    set.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
+                }
+
+                if (tok.back() == "port") {
+                    registerType.params.set.swap(set);
+                } else if (tok.back() == "ff") {
+                    flopTypes.back().params.set.swap(set);
+                }
+            }
+            // Parameters to copy / map
+            else if (fields[0] == "map") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                const auto vec = parseNameValue(fields);
+                dict<RTLIL::IdString, RTLIL::IdString> map;
+                for (const auto &it : vec) {
+                    map.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::escape_id(it.second)));
+                }
+
+                if (tok.back() == "port") {
+                    registerType.params.map.swap(map);
+                } else if (tok.back() == "ff") {
+                    flopTypes.back().params.map.swap(map);
+                }
+            }
+            // Connections to make
+            else if (fields[0] == "con") {
+                if (fields.size() < 2) {
+                    log_error(" syntax error: '%s'\n", line.c_str());
+                }
+                if (tok.size() == 0 || tok.back() != "port") {
+                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+                }
+
+                const auto vec = parseNameValue(fields);
+                for (const auto &it : vec) {
+                    registerType.connect.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
+                }
+            }
+
+            else {
+                log_error(" unexpected keyword '%s'\n", fields[0].c_str());
+            }
+        }
+
+        // Convert lists to maps
+        for (const auto &it : dspTypes) {
+            if (m_DspTypes.count(it.name)) {
+                log_error(" duplicated rule for DSP '%s'\n", it.name.c_str());
+            }
+            m_DspTypes.insert(std::make_pair(it.name, it));
+        }
+        for (const auto &it : flopTypes) {
+            if (m_FlopTypes.count(it.name)) {
+                log_error(" duplicated rule for flip-flop '%s'\n", it.name.c_str());
+            }
+            m_FlopTypes.insert(std::make_pair(it.name, it));
+        }
+    }
+
+    void dump_rules()
+    {
+
+        // Dump DSP types
+        log("DSP types:\n");
+        for (const auto &it1 : m_DspTypes) {
+            const auto &dsp = it1.second;
+            log(" %s\n", dsp.name.c_str());
+
+            for (const auto &it2 : dsp.registers) {
+                const auto &reg = it2.first;
+                const auto &ports = it2.second;
+                log(" ports:\n");
+                for (const auto &port : ports) {
+
+                    std::string range;
+                    if (port.bits.first != -1 && port.bits.second != -1) {
+                        range = stringf("[%d:%d]", port.bits.second, port.bits.first);
+                    }
+
+                    log("  %s.%s%s\n", dsp.name.c_str(), port.name.c_str(), range.c_str());
+
+                    for (const auto &it : port.assoc) {
+                        log("   %.3s: %s\n", it.first.c_str(), !it.second.first.empty() ? it.second.first.c_str() : "<none>");
+                    }
+
+                    if (!reg.params.set.empty()) {
+                        log("   set params:\n");
+                        for (const auto &it : reg.params.set) {
+                            log("    %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
+                        }
+                    }
+                    if (!reg.params.map.empty()) {
+                        log("   map params:\n");
+                        for (const auto &it : reg.params.map) {
+                            log("    %s=%s\n", it.first.c_str(), it.second.c_str());
+                        }
+                    }
+                    if (!reg.connect.empty()) {
+                        log("   connect ports:\n");
+                        for (const auto &it : reg.connect) {
+                            log("    %s.%s=%s\n", dsp.name.c_str(), it.first.c_str(), it.second.as_string().c_str());
+                        }
+                    }
+                }
+            }
+        }
+
+        // Dump flop types
+        log("Flip-flop types:\n");
+        for (const auto &it : m_FlopTypes) {
+            const auto &ff = it.second;
+            log(" %s\n", ff.name.c_str());
+
+            for (const auto &it : ff.ports) {
+                log("  %.3s: %s\n", it.first.c_str(), !it.second.empty() ? it.second.c_str() : "<none>");
+            }
+
+            if (!ff.params.required.empty()) {
+                log("  required params:\n");
+                for (const auto &it : ff.params.required) {
+                    log("   %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
+                }
+            }
+            if (!ff.params.matching.empty()) {
+                log("  params that must match:\n");
+                for (const auto &it : ff.params.matching) {
+                    log("   %s\n", it.c_str());
+                }
+            }
+            if (!ff.params.set.empty()) {
+                log("  set params:\n");
+                for (const auto &it : ff.params.set) {
+                    log("   %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
+                }
+            }
+            if (!ff.params.map.empty()) {
+                log("  map params:\n");
+                for (const auto &it : ff.params.map) {
+                    log("   %s=%s\n", it.first.c_str(), it.second.c_str());
+                }
+            }
+        }
+    }
+
+    // ..........................................
+
+    /// Temporary SigBit to SigBit helper map.
+    SigMap m_SigMap;
+    /// Module connection map
+    ConnMap m_ConnMap;
+
+    /// Cells to be removed (per module!)
+    pool<RTLIL::Cell *> m_CellsToRemove;
+    /// DSP cells that got changed
+    dict<RTLIL::Cell *, DspChanges> m_DspChanges;
+
+    /// DSP types
+    dict<RTLIL::IdString, DspType> m_DspTypes;
+    /// Flip-flop types
+    dict<RTLIL::IdString, FlopType> m_FlopTypes;
+
+    // ..........................................
+
+    DspFF() : Pass("dsp_ff", "Integrates flip-flop into DSP blocks") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    dsp_ff -rules <rules.txt> [selection]\n");
+        log("\n");
+        log("Integrates flip-flops with DSP blocks and enables their internal registers.\n");
+        log("\n");
+        log("The pass loads a set of rules from the file given with the '-rules' parameter.\n");
+        log("The rules define what ports of a DSP module have internal registers and what\n");
+        log("has to be done to enable them. They also define compatible flip-flop cell\n");
+        log("types.\n");
+        log("\n");
+        log("The format of the rules file is the following:\n");
+        log("\n");
+        log("  # This is a comment\n");
+        log("\n");
+        log("  dsp <dsp_type> [<dsp_type> ...]\n");
+        log("    port <dsp_port> [<dsp_port> ...]\n");
+        log("      clk <associated clk> <default>\n");
+        log("     [rst <associated reset>] <default>\n");
+        log("     [ena <associated enable>] <default>\n");
+        log("\n");
+        log("     [set <param>=<value> [<param>=<value> ...]]\n");
+        log("     [map <dsp_param>=<ff_param> [<dsp_param>=<ff_param> ...]]\n");
+        log("     [con <port>=<const> [<port>=<const> ...]]\n");
+        log("    endport\n");
+        log("  enddsp\n");
+        log("\n");
+        log("  ff <ff_type>\n");
+        log("    clk <clock input>\n");
+        log("   [rst <reset input>]\n");
+        log("   [ena <enable input>]\n");
+        log("    d   <data input>\n");
+        log("    q   <data output>\n");
+        log("\n");
+        log("    require <param>=<value> [<param>=<value> ...]\n");
+        log("    match   <param> [<param> ...]\n");
+        log("\n");
+        log("    set <param>=<value> [<param>=<value> ...]\n");
+        log("    map <dsp_param>=<ff_param> [<dsp_param>=<ff_param> ...]\n");
+        log("  endff\n");
+        log("\n");
+        log("Each 'dsp' section defines a DSP cell type (can apply to multiple types).\n");
+        log("Within it each 'port' section defines a data port with internal register.\n");
+        log("There can be multiple port names given if they belong to the same control register.\n");
+        log("The port can be specified as a whole (eg. 'DATA') or as a subset of the whole\n");
+        log("(eg. 'DATA[7:0]').\n");
+        log("\n");
+        log("Statemenst 'clk', 'rst' and 'ena' define names of clock, reset and enable\n");
+        log("ports associated with the data port along with default constant values to\n");
+        log("connect them to when a given port has no counterpart in the flip-flop being\n");
+        log("integrated.\n");
+        log("\n");
+        log("The 'set' statement tells how to set control parameter(s) of the DSP that\n");
+        log("enable the input register on the port. The 'map' statement defines how to\n");
+        log("map parameter(s) of the flip-flip being integrated to the DSP. Finally the\n");
+        log("'con' statement informs how to connected control port(s) of the DSP to enable\n");
+        log("the register.\n");
+        log("\n");
+        log("Each 'ff' section defines a flip-flop type that can be integrated into a DSP\n");
+        log("cell. Inside this section 'clk', 'rst', 'ena', 'd' and 'q' define names of\n");
+        log("clock, reset, enable, data in and data out ports of the flip-flop respectively.\n");
+        log("\n");
+        log("The 'require' statement defines parameter(s) that must have specific value\n");
+        log("for a flip-flop to be considered for integration. The 'match' statement\n");
+        log("lists names of flip-flop parameters that must match on all flip-flops connected\n");
+        log("to a single DSP data port.\n");
+        log("\n");
+        log("The 'set' and 'map' statements serve the same function as in the DSP port\n");
+        log("section but here they may differ depending on the flip-flop type being\n");
+        log("integrated.\n");
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing DSP_FF pass.\n");
+
+        std::string rulesFile;
+
+        // Parse args
+        size_t argidx;
+        for (argidx = 1; argidx < a_Args.size(); argidx++) {
+            if (a_Args[argidx] == "-rules" && (argidx + 1) < a_Args.size()) {
+                rulesFile = a_Args[++argidx];
+                continue;
+            }
+
+            break;
+        }
+        extra_args(a_Args, argidx, a_Design);
+
+        // Check args
+        if (rulesFile.empty()) {
+            log_cmd_error("No rules file specified!");
+        }
+
+        // Reset state
+        m_CellsToRemove.clear();
+        m_DspChanges.clear();
+        m_DspTypes.clear();
+        m_FlopTypes.clear();
+
+        // Load rules
+        rewrite_filename(rulesFile);
+        load_rules(rulesFile);
+        if (log_force_debug) {
+            dump_rules();
+        }
+
+        // Process modules
+        for (auto module : a_Design->selected_modules()) {
+
+            // Setup the SigMap
+            m_SigMap.clear();
+            m_SigMap.set(module);
+
+            // Build the connection map
+            m_ConnMap.clear();
+            m_ConnMap.build(module, m_SigMap);
+
+            // Look for DSP cells
+            for (auto cell : module->cells()) {
+
+                // Not a DSP
+                if (!m_DspTypes.count(cell->type)) {
+                    continue;
+                }
+
+                // Process all registers
+                auto &dspType = m_DspTypes.at(cell->type);
+                for (auto &rule : dspType.registers) {
+                    processRegister(cell, rule.first, rule.second);
+                }
+            }
+
+            // Remove cells
+            for (const auto &cell : m_CellsToRemove) {
+                module->remove(cell);
+            }
+            m_CellsToRemove.clear();
+        }
+
+        // Clear maps
+        m_SigMap.clear();
+        m_ConnMap.clear();
+    }
+
+    // ..........................................
+
+    bool checkFlop(RTLIL::Cell *a_Cell)
+    {
+        const auto &flopType = m_FlopTypes.at(a_Cell->type);
+        bool isOk = true;
+
+        log_debug("checking connected flip-flop '%s' of type '%s'... ", a_Cell->name.c_str(), a_Cell->type.c_str());
+
+        // Must not have the "keep" attribute
+        if (a_Cell->has_keep_attr()) {
+            log_debug("\n   the 'keep' attribute is set");
+            isOk = false;
+        }
+
+        // Check if required parameters are set as they should be
+        for (const auto &it : flopType.params.required) {
+            const auto curr = a_Cell->getParam(it.first);
+            if (curr != it.second) {
+                log_debug("\n   param '%s' mismatch ('%s' instead of '%s')", it.first.c_str(), curr.decode_string().c_str(),
+                          it.second.decode_string().c_str());
+                isOk = false;
+            }
+        }
+
+        if (isOk) {
+            log_debug("Ok\n");
+        } else {
+            log_debug("\n");
+        }
+        return isOk;
+    }
+
+    bool checkFlopDataAgainstDspRegister(const FlopData &a_FlopData, RTLIL::Cell *a_Cell, const RegisterType &a_Register,
+                                         const std::vector<PortType> &a_Ports)
+    {
+        const auto &flopType = m_FlopTypes.at(a_FlopData.type);
+        const auto &changes = m_DspChanges[a_Cell];
+        bool isOk = true;
+
+        log_debug("  checking connected flip-flop settings against the DSP register... ");
+
+        // Check control signal connections
+        for (const auto &port : a_Ports) {
+            for (const auto &it : port.assoc) {
+                const auto &key = it.first;
+                const auto &port = it.second.first;
+
+                SigBit conn(RTLIL::Sx);
+                if (!port.empty() && a_Cell->hasPort(port)) {
+                    auto sigspec = a_Cell->getPort(port);
+                    auto sigbits = sigspec.bits();
+                    log_assert(sigbits.size() <= 1);
+                    if (!sigbits.empty()) {
+                        conn = m_SigMap(sigbits[0]);
+                    }
+                }
+
+                if (conn.is_wire() || (!conn.is_wire() && conn.data != RTLIL::Sx)) {
+                    if (conn != a_FlopData.conns.at(key)) {
+                        log_debug("\n   connection to port '%s' mismatch", port.c_str());
+                        isOk = false;
+                    }
+                }
+            }
+        }
+
+        auto checkParam = [&](const RTLIL::IdString &name, const RTLIL::Const &curr, const RTLIL::Const &next) {
+            if (curr != next && changes.params.count(name)) {
+                log_debug("\n   the param '%s' mismatch ('%s' instead of '%s')", name.c_str(), curr.decode_string().c_str(),
+                          next.decode_string().c_str());
+                isOk = false;
+                return false;
+            }
+            return true;
+        };
+
+        // Check parameters to be mapped (by the port rule)
+        for (const auto &it : a_Register.params.map) {
+            if (a_Cell->hasParam(it.first) && a_FlopData.params.dsp.count(it.second)) {
+                const auto curr = a_Cell->getParam(it.first);
+                const auto flop = a_FlopData.params.dsp.at(it.second);
+                checkParam(it.first, curr, flop);
+            }
+        }
+
+        // Check parameters to be set (by the port rule)
+        for (const auto &it : a_Register.params.set) {
+            if (a_Cell->hasParam(it.first)) {
+                const auto curr = a_Cell->getParam(it.first);
+                checkParam(it.first, curr, it.second);
+            }
+        }
+
+        // Check parameters to be mapped (by the flip-flop rule)
+        for (const auto &it : flopType.params.map) {
+            if (a_Cell->hasParam(it.first) && a_FlopData.params.dsp.count(it.second)) {
+                const auto curr = a_Cell->getParam(it.first);
+                const auto flop = a_FlopData.params.dsp.at(it.second);
+                checkParam(it.first, curr, flop);
+            }
+        }
+
+        // Check parameters to be set (by the flip-flop rule)
+        for (const auto &it : flopType.params.set) {
+            if (a_Cell->hasParam(it.first)) {
+                const auto curr = a_Cell->getParam(it.first);
+                checkParam(it.first, curr, it.second);
+            }
+        }
+
+        if (isOk) {
+            log_debug("Ok\n");
+        } else {
+            log_debug("\n");
+        }
+        return isOk;
+    }
+
+    /// Returns a string with either wire name or constant value for a SigBit
+    static std::string sigBitName(const RTLIL::SigBit &a_SigBit)
+    {
+        if (a_SigBit.is_wire()) {
+            RTLIL::Wire *w = a_SigBit.wire;
+            return RTLIL::unescape_id(w->name);
+        } else {
+            switch (a_SigBit.data) {
+            case RTLIL::State::S0:
+                return "1'b0";
+            case RTLIL::State::S1:
+                return "1'b1";
+            case RTLIL::State::Sx:
+                return "1'bx";
+            case RTLIL::State::Sz:
+                return "1'bz";
+            case RTLIL::State::Sa:
+                return "-";
+            case RTLIL::State::Sm:
+                return "m";
+            }
+            return "?";
+        }
+    }
+
+    // ..........................................
+
+    void processRegister(RTLIL::Cell *a_Cell, const RegisterType &a_Register, const std::vector<PortType> &a_Ports)
+    {
+
+        // The cell register control parameter(s) must not be set
+        for (const auto &it : a_Register.params.set) {
+            const auto curr = a_Cell->getParam(it.first);
+            if (curr == it.second) {
+                log_debug(" the param '%s' is already set to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
+                return;
+            }
+        }
+
+        pool<FlopData> groups;
+        dict<RTLIL::IdString, std::vector<RTLIL::Cell *>> flops;
+
+        // Process ports
+        bool flopsOk = true;
+        for (const auto &port : a_Ports) {
+            log_debug(" attempting flip-flop integration for %s.%s of %s\n", a_Cell->type.c_str(), port.name.c_str(), a_Cell->name.c_str());
+
+            if (!a_Cell->hasPort(port.name)) {
+                log_debug("  port unconnected.\n");
+                continue;
+            }
+            log_assert(a_Cell->output(port.name) || a_Cell->input(port.name));
+
+            // Get port connections
+            auto sigspec = a_Cell->getPort(port.name);
+            auto sigbits = sigspec.bits();
+
+            flops[port.name] = std::vector<RTLIL::Cell *>(sigbits.size(), nullptr);
+            for (size_t i = 0; i < sigbits.size(); ++i) {
+                auto sigbit = m_SigMap(sigbits[i]);
+
+                log_debug("  %2zu. ", i);
+
+                // Port connected to a const.
+                if (!sigbit.wire) {
+                    log_debug("constant\n");
+                    continue;
+                }
+
+                // Skip bits out of the specified range
+                if ((port.bits.first >= 0 && (int)i < port.bits.first) || (port.bits.second >= 0 && (int)i > port.bits.second)) {
+                    log_debug("(excluded)\n");
+                    continue;
+                }
+
+                pool<CellPin> others;
+
+                // Get sinks(s), discard the port completely if more than one sink
+                // is found.
+                if (a_Cell->output(port.name)) {
+                    if (m_ConnMap.sinks.count(sigbit)) {
+                        for (const auto &sink : m_ConnMap.sinks.at(sigbit)) {
+                            if (sink.cell != nullptr && m_CellsToRemove.count(sink.cell)) {
+                                continue;
+                            }
+                            others.insert(sink);
+                        }
+                    }
+
+                }
+                // Get driver. Discard if the driver drives something else too
+                else if (a_Cell->input(port.name)) {
+                    if (m_ConnMap.drivers.count(sigbit)) {
+                        auto driver = m_ConnMap.drivers.at(sigbit);
+
+                        if (m_ConnMap.sinks.count(sigbit)) {
+                            auto sinks = m_ConnMap.sinks.at(sigbit);
+                            if (sinks.size() > 1) {
+                                log_debug("multiple sinks (%zu)\n", others.size());
+                                flopsOk = false;
+                                continue;
+                            }
+                        }
+
+                        others.insert(driver);
+                    }
+                }
+
+                // No others - unconnected
+                if (others.empty()) {
+                    log_debug("unconnected\n");
+                    continue;
+                }
+
+                if (others.size() > 1) {
+                    log_debug("multiple sinks (%zu)\n", others.size());
+                    flopsOk = false;
+                    continue;
+                }
+
+                // Get the sink, check if this is a flip-flop
+                auto &other = *others.begin();
+                auto *flop = other.cell;
+
+                if (flop == nullptr) {
+                    if (!other.port.empty()) {
+                        log_debug("connection reaches module edge\n");
+                        flopsOk = false;
+                    }
+                    log_debug("unconnected\n");
+                    continue;
+                }
+
+                if (!m_FlopTypes.count(flop->type)) {
+                    log_debug("non-flip-flop connected\n");
+                    flopsOk = false;
+                    continue;
+                }
+
+                // Check if the connection goes to the data input/output port
+                const auto &flopType = m_FlopTypes.at(flop->type);
+                RTLIL::IdString flopPort;
+                if (a_Cell->output(port.name)) {
+                    flopPort = flopType.ports.at(RTLIL::escape_id("d"));
+                } else if (a_Cell->input(port.name)) {
+                    flopPort = flopType.ports.at(RTLIL::escape_id("q"));
+                }
+
+                if (flopPort != other.port) {
+                    log_debug("connection to non-data port of a flip-flip");
+                    flopsOk = false;
+                    continue;
+                }
+
+                // Check the flip-flop configuration
+                if (!checkFlop(flop)) {
+                    flopsOk = false;
+                    continue;
+                }
+
+                // Get parameters to be mapped to the DSP according to the port
+                // rule.
+                dict<RTLIL::IdString, RTLIL::Const> mappedParams;
+                for (const auto &it : a_Register.params.map) {
+                    if (flop->hasParam(it.second)) {
+                        const auto &value = flop->getParam(it.second);
+                        mappedParams.insert(std::make_pair(it.first, value));
+                    }
+                }
+
+                // Store the flop and its data
+                groups.insert(getFlopData(flop, mappedParams));
+                flops[port.name][i] = flop;
+            }
+        }
+
+        // Cannot integrate for various reasons
+        if (!flopsOk) {
+            log_debug(" cannot use the DSP register\n");
+            return;
+        }
+
+        // No matching flip-flop groups
+        if (groups.empty()) {
+            log_debug(" no matching flip-flops found\n");
+            return;
+        }
+
+        // Do not allow more than a single group
+        if (groups.size() != 1) {
+            log_debug(" %zu flip-flop groups, only a single one allowed\n", groups.size());
+            return;
+        }
+
+        // Validate the flip flop data agains the DSP cell
+        const auto &flopData = *groups.begin();
+        if (!checkFlopDataAgainstDspRegister(flopData, a_Cell, a_Register, a_Ports)) {
+            log_debug(" flip-flops vs. DSP check failed\n");
+            return;
+        }
+
+        // Log connections
+        for (const auto &port : a_Ports) {
+
+            if (!flops.count(port.name)) {
+                continue;
+            }
+
+            log(" %s %s.%s\n", a_Cell->type.c_str(), a_Cell->name.c_str(), port.name.c_str());
+
+            const auto &conns = flops.at(port.name);
+            for (size_t i = 0; i < conns.size(); ++i) {
+                if (conns[i] != nullptr) {
+                    log_debug("  %2zu. %s %s\n", i, conns[i]->type.c_str(), conns[i]->name.c_str());
+                } else if ((port.bits.first >= 0 && (int)i < port.bits.first) || (port.bits.second >= 0 && (int)i > port.bits.second)) {
+                    log_debug("  %2zu. (excluded)\n", i);
+                } else {
+                    log_debug("  %2zu. None\n", i);
+                }
+            }
+        }
+
+        // Reconnect data signals, mark the flip-flop for removal
+        const auto &flopType = m_FlopTypes.at(flopData.type);
+        for (const auto &port : a_Ports) {
+
+            if (!flops.count(port.name)) {
+                continue;
+            }
+
+            const auto &conns = flops.at(port.name);
+            auto sigspec = a_Cell->getPort(port.name);
+            auto sigbits = sigspec.bits();
+
+            for (size_t i = 0; i < conns.size(); ++i) {
+
+                auto *flop = conns[i];
+                if (flop == nullptr) {
+                    continue;
+                }
+
+                RTLIL::IdString flopPort;
+                if (a_Cell->output(port.name)) {
+                    flopPort = flopType.ports.at(RTLIL::escape_id("q"));
+                } else if (a_Cell->input(port.name)) {
+                    flopPort = flopType.ports.at(RTLIL::escape_id("d"));
+                }
+
+                if (!flop->hasPort(flopPort)) {
+                    log_error("cell '%s' does not have port '%s'!\n", flop->type.c_str(), flopPort.c_str());
+                }
+
+                sigbits[i] = SigBit(RTLIL::Sx);
+                auto sigspec = flop->getPort(flopPort);
+                log_assert(sigspec.bits().size() <= 1);
+                if (sigspec.bits().size() == 1) {
+                    sigbits[i] = sigspec.bits()[0];
+                }
+
+                m_CellsToRemove.insert(flop);
+            }
+
+            a_Cell->setPort(port.name, RTLIL::SigSpec(sigbits));
+        }
+
+        // Reconnect (map) control signals. Connect the default value if
+        // a particular signal is not present in the flip-flop.
+        for (const auto &port : a_Ports) {
+            for (const auto &it : port.assoc) {
+                const auto &key = it.first;
+                const auto &port = it.second.first;
+
+                auto conn = RTLIL::SigBit(RTLIL::SigChunk(it.second.second));
+                if (flopData.conns.count(key)) {
+                    conn = flopData.conns.at(key);
+                }
+
+                log_debug(" connecting %s.%s to %s\n", a_Cell->type.c_str(), port.c_str(), sigBitName(conn).c_str());
+                a_Cell->setPort(port, conn);
+                m_DspChanges[a_Cell].conns.insert(port);
+            }
+        }
+
+        // Connect control signals according to the register rule
+        for (const auto &it : a_Register.connect) {
+            log_debug(" connecting %s.%s to %s\n", a_Cell->type.c_str(), it.first.c_str(), it.second.as_string().c_str());
+            a_Cell->setPort(it.first, it.second);
+            m_DspChanges[a_Cell].conns.insert(it.first);
+        }
+
+        // Map parameters (register rule)
+        for (const auto &it : a_Register.params.map) {
+            if (flopData.params.dsp.count(it.second)) {
+                const auto &param = flopData.params.dsp.at(it.second);
+                log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), param.decode_string().c_str());
+                a_Cell->setParam(it.first, param);
+                m_DspChanges[a_Cell].params.insert(it.first);
+            }
+        }
+
+        // Map parameters (flip-flop rule)
+        for (const auto &it : flopType.params.map) {
+            if (flopData.params.dsp.count(it.second)) {
+                const auto &param = flopData.params.dsp.at(it.second);
+                log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), param.decode_string().c_str());
+                a_Cell->setParam(it.first, param);
+                m_DspChanges[a_Cell].params.insert(it.first);
+            }
+        }
+
+        // Set parameters (port rule)
+        for (const auto &it : a_Register.params.set) {
+            log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
+            a_Cell->setParam(it.first, it.second);
+            m_DspChanges[a_Cell].params.insert(it.first);
+        }
+
+        // Set parameters (flip-flop rule)
+        for (const auto &it : flopType.params.set) {
+            log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
+            a_Cell->setParam(it.first, it.second);
+            m_DspChanges[a_Cell].params.insert(it.first);
+        }
+    }
+
+    // ..........................................
+
+    /// Collects flip-flop connectivity data and parameters which defines the
+    /// group it belongs to.
+    FlopData getFlopData(RTLIL::Cell *a_Cell, const dict<RTLIL::IdString, RTLIL::Const> &a_ExtraParams)
+    {
+        FlopData data(a_Cell->type);
+
+        log_assert(m_FlopTypes.count(a_Cell->type) != 0);
+        const auto &flopType = m_FlopTypes.at(a_Cell->type);
+
+        // Gather connections to control ports
+        for (const auto &it : flopType.ports) {
+
+            // Skip "D" and "Q" as they connection will always differ.
+            if (it.first == RTLIL::escape_id("d") || it.first == RTLIL::escape_id("q")) {
+                continue;
+            }
+
+            if (!it.second.empty() && a_Cell->hasPort(it.second)) {
+                auto sigspec = a_Cell->getPort(it.second);
+                auto sigbits = sigspec.bits();
+                log_assert(sigbits.size() <= 1);
+                if (!sigbits.empty()) {
+                    data.conns[it.first] = m_SigMap(sigbits[0]);
+                }
+            }
+        }
+
+        // Gather flip-flop parameters that need to match
+        for (const auto &it : flopType.params.matching) {
+            log_assert(a_Cell->hasParam(it));
+            data.params.flop.insert(std::make_pair(it, a_Cell->getParam(it)));
+        }
+
+        // Gather flip-flop parameters to be mapped to the DSP as well
+        for (const auto &it : flopType.params.map) {
+            log_assert(a_Cell->hasParam(it.second));
+            data.params.flop.insert(std::make_pair(it.second, a_Cell->getParam(it.second)));
+        }
+
+        // Gather DSP parameters and their values to be set to too
+        for (const auto &it : flopType.params.set) {
+            data.params.dsp.insert(it);
+        }
+
+        // Append extra DSP parameters
+        for (const auto &it : a_ExtraParams) {
+            data.params.dsp.insert(it);
+        }
+
+        return data;
+    }
+
+} DspFF;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/dsp-ff/nexus-dsp_rules.txt b/yosys-plugins/dsp-ff/nexus-dsp_rules.txt
new file mode 100644
index 000000000..d21ea5d1b
--- /dev/null
+++ b/yosys-plugins/dsp-ff/nexus-dsp_rules.txt
@@ -0,0 +1,183 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+dsp MULT9X9 MULT18X18 MULT18X36 MULT36X36
+  port A SIGNEDA
+    clk CLK 0
+    rst RSTA 0
+    ena CEA 1
+
+    set REGINPUTA=REGISTER
+    map GSR=GSR
+  endport
+  port B SIGNEDB
+    clk CLK 0
+    rst RSTB 0
+    ena CEB 1
+
+    set REGINPUTB=REGISTER
+    map GSR=GSR
+  endport
+  port Z
+    clk CLK 0
+    rst RSTOUT 0
+    ena CEOUT 1
+
+    set REGOUTPUT=REGISTER
+    map GSR=GSR
+  endport
+enddsp
+
+dsp MULTPREADD9X9 MULTPREADD18X18 MULTADDSUB18X18 MULTADDSUB36X36
+  port A SIGNEDA
+    clk CLK 0
+    rst RSTA 0
+    ena CEA 1
+
+    set REGINPUTA=REGISTER
+    map GSR=GSR
+  endport
+  port B SIGNEDB
+    clk CLK 0
+    rst RSTB 0
+    ena CEB 1
+
+    set REGINPUTB=REGISTER
+    map GSR=GSR
+  endport
+  port C SIGNEDC
+    clk CLK 0
+    rst RSTC 0
+    ena CEC 1
+
+    set REGINPUTC=REGISTER
+    map GSR=GSR
+  endport
+  port Z
+    clk CLK 0
+    rst RSTOUT 0
+    ena CEOUT 1
+
+    set REGOUTPUT=REGISTER
+    map GSR=GSR
+  endport
+enddsp
+
+dsp MULTADDSUB9X9WIDE
+  port A0 SIGNED
+    clk CLK 0
+    rst RSTA0A1 0
+    ena CEA0A1 1
+
+    set REGINPUTAB0=REGISTER
+    map GSR=GSR
+  endport
+  port A1 SIGNED
+    clk CLK 0
+    rst RSTA0A1 0
+    ena CEA0A1 1
+
+    set REGINPUTAB1=REGISTER
+    map GSR=GSR
+  endport
+  port A2 SIGNED
+    clk CLK 0
+    rst RSTA2A3 0
+    ena CEA2A3 1
+
+    set REGINPUTAB2=REGISTER
+    map GSR=GSR
+  endport
+  port A3 SIGNED
+    clk CLK 0
+    rst RSTA2A3 0
+    ena CEA2A3 1
+
+    set REGINPUTAB3=REGISTER
+    map GSR=GSR
+  endport
+  port B0 SIGNED
+    clk CLK 0
+    rst RSTB0B1 0
+    ena CEB0B1 1
+
+    set REGINPUTAB0=REGISTER
+    map GSR=GSR
+  endport
+  port B1 SIGNED
+    clk CLK 0
+    rst RSTB0B1 0
+    ena CEB0B1 1
+
+    set REGINPUTAB1=REGISTER
+    map GSR=GSR
+  endport
+  port B2 SIGNED
+    clk CLK 0
+    rst RSTB2B3 0
+    ena CEB2B3 1
+
+    set REGINPUTAB2=REGISTER
+    map GSR=GSR
+  endport
+  port B3 SIGNED
+    clk CLK 0
+    rst RSTB2B3 0
+    ena CEB2B3 1
+
+    set REGINPUTAB3=REGISTER
+    map GSR=GSR
+  endport
+  port C SIGNED
+    clk CLK 0
+    rst RSTC 0
+    ena CEC 1
+
+    set REGINPUTC=REGISTER
+    map GSR=GSR
+  endport
+  port Z
+    clk CLK 0
+    rst RSTOUT 0
+    ena CEOUT 1
+
+    set REGOUTPUT=REGISTER
+    map GSR=GSR
+  endport
+enddsp
+
+ff FD1P3DX
+  clk CK
+  rst CD
+  ena SP
+  d   D
+  q   Q
+
+  match GSR
+  set RESETMODE=ASYNC
+endff
+
+ff FD1P3IX
+  clk CK
+  rst CD
+  ena SP
+  d   D
+  q   Q
+
+  match GSR
+  set RESETMODE=SYNC
+endff
+
diff --git a/yosys-plugins/dsp-ff/tests/Makefile b/yosys-plugins/dsp-ff/tests/Makefile
new file mode 100644
index 000000000..3a883f9ad
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/Makefile
@@ -0,0 +1,32 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = \
+    nexus_mult \
+    nexus_mult_wide \
+    nexus_fftypes \
+    nexus_conn_conflict \
+    nexus_conn_share \
+    nexus_param_conflict
+
+include $(shell pwd)/../../Makefile_test.common
+
+nexus_mult_verify = true
+nexus_mult_wide_verify = true
+nexus_fftypes_verify = true
+nexus_conn_conflict_verify = true
+nexus_conn_share_verify = true
+nexus_param_conflict_verify = true
diff --git a/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.tcl b/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.tcl
new file mode 100644
index 000000000..2bce1d432
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.tcl
@@ -0,0 +1,60 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "conflict_dsp_clk"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 9 t:FD1P3IX
+
+set TOP "conflict_ff_clk"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3IX
+
+set TOP "conflict_ff_rst"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3DX
+
+set TOP "conflict_ff_ena"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3IX
+
+set TOP "conflict_dsp_port"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 9 t:FD1P3IX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.v b/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.v
new file mode 100644
index 000000000..18fce91f2
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_conn_conflict/nexus_conn_conflict.v
@@ -0,0 +1,159 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module conflict_dsp_clk (
+    input  wire        CLK_A,
+    input  wire        CLK_B,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK_A)
+        ra <= A;
+
+    reg [8:0] rb;
+    always @(posedge CLK_B)
+        rb <= B;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (rb),
+        .Z (Z)
+    );
+
+endmodule
+
+module conflict_ff_clk (
+    input  wire        CLK1,
+    input  wire        CLK2,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [17:0] z;
+
+    always @(posedge CLK1)
+        Z[17:9] <= z[17:9];
+    always @(posedge CLK2)
+        Z[ 8:0] <= z[ 8:0];
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+endmodule
+
+module conflict_ff_rst (
+    input  wire        CLK,
+    input  wire        RST1,
+    input  wire        RST2,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [17:0] z;
+
+    always @(posedge CLK or posedge RST1)
+        if (RST1)
+            Z[17:9] <= 0;
+        else
+            Z[17:9] <= z[17:9];
+    always @(posedge CLK or posedge RST2)
+        if (RST2)
+            Z[ 8:0] <= 0;
+        else
+            Z[ 8:0] <= z[ 8:0];
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+endmodule
+
+module conflict_ff_ena (
+    input  wire        CLK,
+    input  wire        ENA1,
+    input  wire        ENA2,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [17:0] z;
+
+    always @(posedge CLK)
+        if (ENA1)
+            Z[17:9] <= z[17:9];
+    always @(posedge CLK)
+        if (ENA2)
+            Z[ 8:0] <= z[ 8:0];
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+endmodule
+
+module conflict_dsp_port (
+    input  wire        CLK_A,
+    input  wire [ 8:0] A,
+    input  wire        SA,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK_A)
+        ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A       (ra),
+        .SIGNEDA (SA),
+        .B       (B),
+        .Z       (Z)
+    );
+
+endmodule
diff --git a/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.tcl b/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.tcl
new file mode 100644
index 000000000..673131d52
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.tcl
@@ -0,0 +1,48 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "conflict_out_fanout"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3IX
+
+set TOP "conflict_out_fanout_to_top"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3IX
+
+set TOP "conflict_inp_fanout"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 9 t:FD1P3IX
+
+set TOP "conflict_inp_fanout_to_top"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 9 t:FD1P3IX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.v b/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.v
new file mode 100644
index 000000000..db020c326
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_conn_share/nexus_conn_share.v
@@ -0,0 +1,120 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module conflict_out_fanout (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z,
+    output wire [ 8:0] X,
+);
+
+    wire [17:0] z;
+    always @(posedge CLK)
+        Z <= z;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+    assign X = ~z[8:0];
+
+endmodule
+
+module conflict_out_fanout_to_top (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z,
+    output wire [ 8:0] X,
+);
+
+    wire [17:0] z;
+    always @(posedge CLK)
+        Z <= z;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+    assign X = z[8:0];
+
+endmodule
+
+module conflict_inp_fanout (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z,
+    output wire [ 3:0] X,
+);
+
+    wire [8:0] ra;
+    always @(posedge CLK)
+        ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+    assign X = ~ra[3:0];
+
+endmodule
+
+module conflict_inp_fanout_to_top (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z,
+    output wire [ 3:0] X,
+);
+
+    wire [8:0] ra;
+    always @(posedge CLK)
+        ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+    assign X = ra[3:0];
+
+endmodule
+
diff --git a/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.tcl b/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.tcl
new file mode 100644
index 000000000..d394e0431
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.tcl
@@ -0,0 +1,73 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "mult_ena"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+select -assert-count 0 t:FD1P3DX
+
+set TOP "mult_arst"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+select -assert-count 0 t:FD1P3DX
+
+set TOP "mult_arst_ena"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+select -assert-count 0 t:FD1P3DX
+
+set TOP "mult_srst"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+select -assert-count 0 t:FD1P3DX
+
+set TOP "mult_srst_ena"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+select -assert-count 0 t:FD1P3DX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.v b/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.v
new file mode 100644
index 000000000..b0eb3c8db
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_fftypes/nexus_fftypes.v
@@ -0,0 +1,142 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mult_ena (
+    input  wire        CLK,
+    input  wire        ENA,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK)
+        if (ENA) ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
+module mult_arst (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK or posedge RST)
+        if (RST) ra <= 0;
+        else     ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
+module mult_arst_ena (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire        ENA,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK or posedge RST)
+        if (RST)      ra <= 0;
+        else if (ENA) ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
+module mult_srst (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK)
+        if (RST) ra <= 0;
+        else     ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
+module mult_srst_ena (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire        ENA,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK)
+        if (RST)      ra <= 0;
+        else if (ENA) ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
diff --git a/yosys-plugins/dsp-ff/tests/nexus_mult/README.md b/yosys-plugins/dsp-ff/tests/nexus_mult/README.md
new file mode 100644
index 000000000..f72e27cb3
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_mult/README.md
@@ -0,0 +1 @@
+Simple DSP register inference
diff --git a/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.tcl b/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.tcl
new file mode 100644
index 000000000..3e52fbf39
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.tcl
@@ -0,0 +1,60 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "mult_ireg"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+
+set TOP "mult_oreg"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+
+set TOP "mult_all"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 0 t:FD1P3IX
+
+# The test cannot be run because the equivalence check fails at some internal
+# wires of the DSP simulation model which ends up dangling. So that's not a
+# real issue but makes the test fail.
+
+#set TOP "mult_ctrl"
+#design -load read
+#hierarchy -top ${TOP}
+#synth_nexus -flatten
+#techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+#equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+#design -load postopt
+#yosys cd ${TOP}
+#stat
+#select -assert-count 1 t:MULT9X9
+#select -assert-count 0 t:FD1P3IX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.v b/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.v
new file mode 100644
index 000000000..e6281d6c4
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_mult/nexus_mult.v
@@ -0,0 +1,122 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mult_ireg (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK)
+        ra <= A;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
+module mult_oreg (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z
+);
+
+    reg [17:0] z;
+    always @(posedge CLK)
+        Z <= z;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+endmodule
+
+module mult_all (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z
+);
+
+    reg [8:0] ra;
+    always @(posedge CLK)
+        ra <= A;
+
+    reg [8:0] rb;
+    always @(posedge CLK)
+        rb <= B;
+
+    reg [17:0] z;
+    always @(posedge CLK)
+        Z <= z;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (rb),
+        .Z (z)
+    );
+
+endmodule
+
+module mult_ctrl (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire        SA,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z
+);
+
+    reg [8:0] ra;
+    reg       rsa;
+
+    always @(posedge CLK) begin
+        ra  <= A;
+        rsa <= SA;
+    end
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A          (ra),
+        .SIGNEDA    (rsa),
+        .B          (B),
+        .Z          (Z)
+    );
+
+endmodule
+
diff --git a/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.tcl b/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.tcl
new file mode 100644
index 000000000..369717728
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "mult_wide"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULTADDSUB9X9WIDE
+select -assert-count 9 t:FD1P3IX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.v b/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.v
new file mode 100644
index 000000000..38161c6d8
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_mult_wide/nexus_mult_wide.v
@@ -0,0 +1,71 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mult_wide (
+    input  wire        CLK,
+    input  wire [ 8:0] A0,
+    input  wire [ 8:0] A1,
+    input  wire [ 8:0] A2,
+    input  wire [ 8:0] A3,
+    input  wire [ 8:0] B0,
+    input  wire [ 8:0] B1,
+    input  wire [ 8:0] B2,
+    input  wire [ 8:0] B3,
+    input  wire [53:0] C,
+    output wire [53:0] Z
+);
+
+    reg [8:0] ra0;
+    always @(posedge CLK)
+        ra0 <= A0;
+
+    reg [8:0] rb0;
+    always @(posedge CLK)
+        rb0 <= B0;
+
+    reg [8:0] rb2;
+    always @(posedge CLK)
+        rb2 <= B2;
+
+    MULTADDSUB9X9WIDE # (
+        .REGINPUTAB0("BYPASS"),
+        .REGINPUTAB1("BYPASS"),
+        .REGINPUTAB2("BYPASS"),
+        .REGINPUTAB3("BYPASS"),
+        .REGINPUTC("BYPASS"),
+        .REGADDSUB("BYPASS"),
+        .REGLOADC("BYPASS"),
+        .REGLOADC2("BYPASS"),
+        .REGPIPELINE("BYPASS"),
+        .REGOUTPUT("REGISTER")
+    ) mult (
+        .A0 (ra0),
+        .A1 (A1),
+        .A2 (A2),
+        .A3 (A3),
+        .B0 (rb0),
+        .B1 (B1),
+        .B2 (rb2),
+        .B3 (B3),
+        .C  (C),
+        .Z  (Z),
+
+        .LOADC      (1'b0),
+        .ADDSUB     (4'hF),
+        .SIGNED     (1'b1),
+    );
+
+endmodule
diff --git a/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.tcl b/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.tcl
new file mode 100644
index 000000000..27dff3a70
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.tcl
@@ -0,0 +1,41 @@
+yosys -import
+if { [info procs dsp_ff] == {} } { plugin -i dsp-ff }
+yosys -import  ;# ingest plugin commands
+
+set DSP_RULES [file dirname $::env(DESIGN_TOP)]/../../nexus-dsp_rules.txt
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+set TOP "conflict_dsp_ctrl_param"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 18 t:FD1P3IX
+
+set TOP "conflict_dsp_common_param"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+equiv_opt -assert -async2sync -map +/nexus/cells_sim.v debug dsp_ff -rules ${DSP_RULES}
+design -load postopt
+yosys cd ${TOP}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 9 t:FD1P3IX t:FD1P3DX %u
+
+set TOP "conflict_ff_param"
+design -load read
+hierarchy -top ${TOP}
+synth_nexus -flatten
+techmap -map +/nexus/cells_sim.v t:VLO t:VHI %u ;# Unmap VHI and VLO
+debug dsp_ff -rules ${DSP_RULES}
+stat
+select -assert-count 1 t:MULT9X9
+select -assert-count 4 t:FD1P3IX
+select -assert-count 5 t:FD1P3DX
diff --git a/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.v b/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.v
new file mode 100644
index 000000000..5269dea57
--- /dev/null
+++ b/yosys-plugins/dsp-ff/tests/nexus_param_conflict/nexus_param_conflict.v
@@ -0,0 +1,98 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module conflict_dsp_ctrl_param (
+    input  wire        CLK,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output reg  [17:0] Z,
+);
+
+    wire [17:0] z;
+    always @(posedge CLK)
+        Z <= z;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("REGISTER")
+    ) mult (
+        .A (A),
+        .B (B),
+        .Z (z)
+    );
+
+endmodule
+
+module conflict_dsp_common_param (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z,
+);
+
+    wire [8:0] ra;
+    always @(posedge CLK or posedge RST)
+        if (RST) ra <= 0;
+        else     ra <= A;
+
+    wire [8:0] rb;
+    always @(posedge CLK)
+        if (RST) rb <= 0;
+        else     rb <= B;
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (rb),
+        .Z (Z)
+    );
+
+endmodule
+
+module conflict_ff_param (
+    input  wire        CLK,
+    input  wire        RST,
+    input  wire [ 8:0] A,
+    input  wire [ 8:0] B,
+    output wire [17:0] Z,
+);
+
+    wire [8:0] ra;
+    always @(posedge CLK or posedge RST)
+        if (RST) ra[8:4] <= 0;
+        else     ra[8:4] <= A[8:4];
+
+    always @(posedge CLK)
+        if (RST) ra[3:0] <= 0;
+        else     ra[3:0] <= A[3:0];
+
+    MULT9X9 # (
+        .REGINPUTA("BYPASS"),
+        .REGINPUTB("BYPASS"),
+        .REGOUTPUT("BYPASS")
+    ) mult (
+        .A (ra),
+        .B (B),
+        .Z (Z)
+    );
+
+endmodule
+
diff --git a/yosys-plugins/environment.yml b/yosys-plugins/environment.yml
new file mode 100644
index 000000000..a4cf46c24
--- /dev/null
+++ b/yosys-plugins/environment.yml
@@ -0,0 +1,24 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+name: yosys-plugins
+channels:
+  - defaults
+  - litex-hub
+dependencies:
+  - litex-hub::yosys=0.17_7_g990c9b8e1=20220512_085338_py37
+  - litex-hub::surelog
+  - litex-hub::iverilog
diff --git a/yosys-plugins/fasm/Makefile b/yosys-plugins/fasm/Makefile
new file mode 100644
index 000000000..b149198a4
--- /dev/null
+++ b/yosys-plugins/fasm/Makefile
@@ -0,0 +1,20 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = fasm
+SOURCES = fasm.cc
+include ../Makefile_plugin.common
+
diff --git a/yosys-plugins/fasm/fasm.cc b/yosys-plugins/fasm/fasm.cc
new file mode 100644
index 000000000..c81d57f97
--- /dev/null
+++ b/yosys-plugins/fasm/fasm.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ *  ---
+ *
+ *   FASM backend
+ *
+ *   This plugin writes out the design's fasm features based on the parameter
+ *   annotations on the design cells.
+ */
+
+#include "../bank_tiles.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct WriteFasm : public Backend {
+    WriteFasm() : Backend("fasm", "Write out FASM features") {}
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    write_fasm -part_json <part_json_filename> <filename>\n");
+        log("\n");
+        log("Write out a file with vref FASM features.\n");
+        log("\n");
+    }
+
+    void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        size_t argidx = 1;
+        std::string part_json;
+        if (args[argidx] == "-part_json" && argidx + 1 < args.size()) {
+            part_json = args[++argidx];
+            argidx++;
+        }
+        extra_args(f, filename, args, argidx);
+        extract_fasm_features(f, design, part_json);
+    }
+
+    void extract_fasm_features(std::ostream *&f, RTLIL::Design *design, const std::string &part_json)
+    {
+        RTLIL::Module *top_module(design->top_module());
+        if (top_module == nullptr) {
+            log_cmd_error("%s: No top module detected.\n", pass_name.c_str());
+        }
+        auto bank_tiles = get_bank_tiles(part_json);
+        // Generate a fasm feature associated with the INTERNAL_VREF value per bank
+        // e.g. VREF value of 0.675 for bank 34 is associated with tile HCLK_IOI3_X113Y26
+        // hence we need to emit the following fasm feature: HCLK_IOI3_X113Y26.VREF.V_675_MV
+        for (auto cell : top_module->cells()) {
+            if (!cell->hasParam(ID(FASM_EXTRA)))
+                continue;
+            if (cell->getParam(ID(FASM_EXTRA)) == RTLIL::Const("INTERNAL_VREF")) {
+                if (bank_tiles.size() == 0) {
+                    log_cmd_error("%s: No bank tiles available on the target part.\n", pass_name.c_str());
+                }
+                int bank_number(cell->getParam(ID(NUMBER)).as_int());
+                if (bank_tiles.count(bank_number) == 0) {
+                    log_cmd_error("%s: No IO bank number %d on the target part.\n", pass_name.c_str(), bank_number);
+                }
+                int bank_vref(cell->getParam(ID(INTERNAL_VREF)).as_int());
+                *f << "HCLK_IOI3_" << bank_tiles[bank_number] << ".VREF.V_" << bank_vref << "_MV\n";
+            }
+        }
+    }
+} WriteFasm;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/fasm/tests/Makefile b/yosys-plugins/fasm/tests/Makefile
new file mode 100644
index 000000000..1c6f1d813
--- /dev/null
+++ b/yosys-plugins/fasm/tests/Makefile
@@ -0,0 +1,17 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 $(shell pwd)/../../Makefile_test.common
diff --git a/yosys-plugins/integrateinv/Makefile b/yosys-plugins/integrateinv/Makefile
new file mode 100644
index 000000000..f93225ab4
--- /dev/null
+++ b/yosys-plugins/integrateinv/Makefile
@@ -0,0 +1,19 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = integrateinv
+SOURCES = integrateinv.cc
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/integrateinv/integrateinv.cc b/yosys-plugins/integrateinv/integrateinv.cc
new file mode 100644
index 000000000..a47dcea01
--- /dev/null
+++ b/yosys-plugins/integrateinv/integrateinv.cc
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+/// A structure representing a pin
+struct Pin {
+    RTLIL::Cell *cell;    /// Cell pointer
+    RTLIL::IdString port; /// Cell port name
+    int bit;              /// Port bit index
+
+    Pin(RTLIL::Cell *_cell, const RTLIL::IdString &_port, int _bit = 0) : cell(_cell), port(_port), bit(_bit) {}
+
+    Pin(const Pin &ref) = default;
+
+    unsigned int hash() const
+    {
+        if (cell == nullptr) {
+            return mkhash_add(port.hash(), bit);
+        } else {
+            return mkhash_add(mkhash(cell->hash(), port.hash()), bit);
+        }
+    };
+};
+
+bool operator==(const Pin &lhs, const Pin &rhs) { return (lhs.cell == rhs.cell) && (lhs.port == rhs.port) && (lhs.bit == rhs.bit); }
+
+struct IntegrateInv : public Pass {
+
+    /// Temporary SigBit to SigBit helper map.
+    SigMap m_SigMap;
+    /// Map of SigBit objects to inverter cells.
+    dict<RTLIL::SigBit, RTLIL::Cell *> m_InvMap;
+    /// Map of inverter cells that can potentially be integrated and invertable
+    /// pins that they are connected to
+    dict<RTLIL::Cell *, pool<Pin>> m_Inverters;
+    /// Map of invertable pins and names of parameters controlling inversions
+    dict<Pin, RTLIL::IdString> m_InvParams;
+
+    IntegrateInv()
+        : Pass("integrateinv", "Integrates inverters ($_NOT_ cells) into ports "
+                               "with 'invertible_pin' attribute set")
+    {
+    }
+
+    void help() override
+    {
+        log("\n");
+        log("    integrateinv [selection]");
+        log("\n");
+        log("This pass integrates inverters into cells that have ports with the\n");
+        log("'invertible_pin' attribute set. The attribute should contain the name\n");
+        log("of a parameter controlling the inversion.\n");
+        log("\n");
+        log("This pass is essentially the opposite of the 'extractinv' pass.\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing INTEGRATEINV pass (integrating pin inverters).\n");
+
+        extra_args(a_Args, 1, a_Design);
+
+        // Process modules
+        for (auto module : a_Design->selected_modules()) {
+
+            // Setup the SigMap
+            m_SigMap.clear();
+            m_SigMap.set(module);
+
+            m_Inverters.clear();
+            m_InvParams.clear();
+
+            // Setup inverter map
+            buildInverterMap(module);
+
+            // Identify inverters that can be integrated and assign them with
+            // lists of cells and ports to integrate with
+            for (auto cell : module->selected_cells()) {
+                collectInverters(cell);
+            }
+
+            // Integrate inverters
+            integrateInverters();
+        }
+
+        // Clear maps
+        m_SigMap.clear();
+
+        m_InvMap.clear();
+        m_Inverters.clear();
+        m_InvParams.clear();
+    }
+
+    void buildInverterMap(RTLIL::Module *a_Module)
+    {
+        m_InvMap.clear();
+
+        for (auto cell : a_Module->cells()) {
+
+            // Skip non-inverters
+            if (cell->type != RTLIL::escape_id("$_NOT_")) {
+                continue;
+            }
+
+            // Get output connection
+            auto sigspec = cell->getPort(RTLIL::escape_id("Y"));
+            auto sigbit = m_SigMap(sigspec.bits().at(0));
+
+            // Store
+            log_assert(m_InvMap.count(sigbit) == 0);
+            m_InvMap[sigbit] = cell;
+        }
+    }
+
+    void collectInverters(RTLIL::Cell *a_Cell)
+    {
+        auto module = a_Cell->module;
+        auto design = module->design;
+
+        for (auto conn : a_Cell->connections()) {
+            auto port = conn.first;
+            auto sigspec = conn.second;
+
+            // Consider only inputs.
+            if (!a_Cell->input(port)) {
+                continue;
+            }
+
+            // Get the cell module
+            auto cellModule = design->module(a_Cell->type);
+            if (!cellModule) {
+                continue;
+            }
+
+            // Get wire.
+            auto wire = cellModule->wire(port);
+            if (!wire) {
+                continue;
+            }
+
+            // Check if the pin has an embedded inverter.
+            auto it = wire->attributes.find(ID::invertible_pin);
+            if (it == wire->attributes.end()) {
+                continue;
+            }
+
+            // Decode the parameter name.
+            RTLIL::IdString paramName = RTLIL::escape_id(it->second.decode_string());
+
+            // Look for connected inverters
+            auto sigbits = sigspec.bits();
+            for (size_t bit = 0; bit < sigbits.size(); ++bit) {
+
+                auto sigbit = sigbits[bit];
+                if (!sigbit.wire) {
+                    continue;
+                }
+
+                sigbit = m_SigMap(sigbit);
+
+                // Get the inverter if any
+                if (!m_InvMap.count(sigbit)) {
+                    continue;
+                }
+                auto inv = m_InvMap.at(sigbit);
+
+                // Save the inverter pin and the parameter name
+                auto pin = Pin(a_Cell, port, bit);
+
+                auto &list = m_Inverters[inv];
+                list.insert(pin);
+
+                log_assert(m_InvParams.count(pin) == 0);
+                m_InvParams[pin] = paramName;
+            }
+        }
+    }
+
+    void integrateInverters()
+    {
+
+        for (auto it : m_Inverters) {
+            auto inv = it.first;
+            auto pins = it.second;
+
+            // List all sinks of the inverter
+            auto sinks = getSinksForDriver(Pin(inv, RTLIL::escape_id("Y")));
+
+            // If the inverter drives only invertable pins then integrate it
+            if (sinks == pins) {
+                log("Integrating inverter %s into:\n", log_id(inv->name));
+
+                // Integrate into each pin
+                for (auto pin : pins) {
+                    log_assert(pin.cell != nullptr);
+                    log(" %s.%s[%d]\n", log_id(pin.cell->name), log_id(pin.port), pin.bit);
+
+                    // Change the connection
+                    auto sigspec = pin.cell->getPort(pin.port);
+                    auto sigbits = sigspec.bits();
+
+                    log_assert((size_t)pin.bit < sigbits.size());
+                    sigbits[pin.bit] = RTLIL::SigBit(inv->getPort(RTLIL::escape_id("A"))[0]);
+                    pin.cell->setPort(pin.port, RTLIL::SigSpec(sigbits));
+
+                    // Get the control parameter
+                    log_assert(m_InvParams.count(pin) != 0);
+                    auto paramName = m_InvParams[pin];
+
+                    RTLIL::Const invMask;
+                    auto param = pin.cell->parameters.find(paramName);
+                    if (param == pin.cell->parameters.end()) {
+                        invMask = RTLIL::Const(0, sigspec.size());
+                    } else {
+                        invMask = RTLIL::Const(param->second);
+                    }
+
+                    // Check width.
+                    if (invMask.size() != sigspec.size()) {
+                        log_error("The inversion parameter needs to be the same width as "
+                                  "the port (%s port %s parameter %s)",
+                                  log_id(pin.cell->name), log_id(pin.port), log_id(paramName));
+                    }
+
+                    // Toggle bit in the control parameter bitmask
+                    if (invMask[pin.bit] == RTLIL::State::S0) {
+                        invMask[pin.bit] = RTLIL::State::S1;
+                    } else if (invMask[pin.bit] == RTLIL::State::S1) {
+                        invMask[pin.bit] = RTLIL::State::S0;
+                    } else {
+                        log_error("The inversion parameter must contain only 0s and 1s (%s "
+                                  "parameter %s)\n",
+                                  log_id(pin.cell->name), log_id(paramName));
+                    }
+
+                    // Set the parameter back
+                    pin.cell->setParam(paramName, invMask);
+                }
+
+                // Remove the inverter
+                inv->module->remove(inv);
+            }
+        }
+    }
+
+    pool<Pin> getSinksForDriver(const Pin &a_Driver)
+    {
+        auto module = a_Driver.cell->module;
+        pool<Pin> sinks;
+
+        // The driver has to be an output pin
+        if (!a_Driver.cell->output(a_Driver.port)) {
+            return sinks;
+        }
+
+        // Get the driver sigbit
+        auto driverSigspec = a_Driver.cell->getPort(a_Driver.port);
+        auto driverSigbit = m_SigMap(driverSigspec.bits().at(a_Driver.bit));
+
+        // Look for connected sinks
+        for (auto cell : module->cells()) {
+            for (auto conn : cell->connections()) {
+                auto port = conn.first;
+                auto sigspec = conn.second;
+
+                // Consider only sinks (inputs)
+                if (!cell->input(port)) {
+                    continue;
+                }
+
+                // Check all sigbits
+                auto sigbits = sigspec.bits();
+                for (size_t bit = 0; bit < sigbits.size(); ++bit) {
+
+                    auto sigbit = sigbits[bit];
+                    if (!sigbit.wire) {
+                        continue;
+                    }
+
+                    // Got a sink pin of another cell
+                    sigbit = m_SigMap(sigbit);
+                    if (sigbit == driverSigbit) {
+                        sinks.insert(Pin(cell, port, bit));
+                    }
+                }
+            }
+        }
+
+        // Look for connected top-level output ports
+        for (auto conn : module->connections()) {
+            auto dst = conn.first;
+            auto src = conn.second;
+
+            auto sigbits = dst.bits();
+            for (size_t bit = 0; bit < sigbits.size(); ++bit) {
+
+                auto sigbit = sigbits[bit];
+                if (!sigbit.wire) {
+                    continue;
+                }
+
+                if (!sigbit.wire->port_output) {
+                    continue;
+                }
+
+                sigbit = m_SigMap(sigbit);
+                if (sigbit == driverSigbit) {
+                    sinks.insert(Pin(nullptr, sigbit.wire->name, bit));
+                }
+            }
+        }
+
+        return sinks;
+    }
+
+} IntegrateInv;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/integrateinv/tests/.gitignore b/yosys-plugins/integrateinv/tests/.gitignore
new file mode 100644
index 000000000..9766475a4
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/.gitignore
@@ -0,0 +1 @@
+ok
diff --git a/yosys-plugins/integrateinv/tests/Makefile b/yosys-plugins/integrateinv/tests/Makefile
new file mode 100644
index 000000000..fc6e87b0c
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/Makefile
@@ -0,0 +1,29 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = fanout \
+	hierarchy \
+	multi_bit \
+	single_bit \
+	toplevel
+
+include $(shell pwd)/../../Makefile_test.common
+
+fanout_verify = true
+hierarchy_verify = true
+multi_bit_verify = true
+single_bit_verify = true
+toplevel_verify = true
diff --git a/yosys-plugins/integrateinv/tests/fanout/fanout.tcl b/yosys-plugins/integrateinv/tests/fanout/fanout.tcl
new file mode 100644
index 000000000..100e1cc3a
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/fanout/fanout.tcl
@@ -0,0 +1,11 @@
+yosys -import
+if { [info procs integrateinv] == {} } { plugin -i integrateinv }
+yosys -import  ;# ingest plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -check -auto-top
+
+debug integrateinv
+
+select t:\$_NOT_ -assert-count 1
+select t:box r:INV_A=1'b1 %i -assert-count 3
diff --git a/yosys-plugins/integrateinv/tests/fanout/fanout.v b/yosys-plugins/integrateinv/tests/fanout/fanout.v
new file mode 100644
index 000000000..f30111866
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/fanout/fanout.v
@@ -0,0 +1,50 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module box(
+    (* invertible_pin="INV_A" *)
+    input  wire A,
+    input  wire B,
+
+    output wire Y
+);
+
+    parameter [0:0] INV_A = 1'b0;
+
+endmodule
+
+
+module top(
+    input  wire [1:0] di,
+    output wire [5:0] do
+);
+
+    wire [1:0] d;
+
+    \$_NOT_ n0 (.A(di[0]), .Y(d[0]));
+
+    box b00 (.A(d[0]), .B(    ), .Y(do[0]));
+    box b01 (.A(d[0]), .B(    ), .Y(do[1]));
+    box b02 (.A(    ), .B(d[0]), .Y(do[2]));
+
+    \$_NOT_ n1 (.A(di[1]), .Y(d[1]));
+
+    box b10 (.A(d[1]), .B(    ), .Y(do[3]));
+    box b11 (.A(d[1]), .B(    ), .Y(do[4]));
+    box b12 (.A(d[1]), .B(    ), .Y(do[5]));
+
+endmodule
diff --git a/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.tcl b/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.tcl
new file mode 100644
index 000000000..82a59fc4b
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.tcl
@@ -0,0 +1,17 @@
+yosys -import
+if { [info procs integrateinv] == {} } { plugin -i integrateinv }
+yosys -import  ;# ingest plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -check -auto-top
+
+debug integrateinv
+
+select -module top
+select t:\$_NOT_ -assert-count 1
+select t:box r:INV_A=1'b1 %i -assert-count 1
+select t:child -assert-count 1
+
+select -module child
+select t:\$_NOT_ -assert-count 0
+select t:box r:INV_A=1'b1 %i -assert-count 1
diff --git a/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.v b/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.v
new file mode 100644
index 000000000..32c451d4f
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/hierarchy/hierarchy.v
@@ -0,0 +1,58 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module box(
+    (* invertible_pin="INV_A" *)
+    input  wire A,
+    output wire Y
+);
+
+    parameter [0:0] INV_A = 1'b0;
+
+endmodule
+
+(* keep_hierarchy *)
+module child (
+    input  wire       I,
+    output wire [1:0] O
+);
+
+    wire d;
+
+    \$_NOT_ n (.A(I), .Y(d));
+
+    box b0 (.A(I), .Y(O[0]));
+    box b1 (.A(d), .Y(O[1]));
+
+endmodule
+
+
+module top(
+    input  wire       di,
+    output wire [4:0] do
+);
+
+    wire [1:0] d;
+
+    \$_NOT_ n0 (.A(di), .Y(d[0]));
+    \$_NOT_ n1 (.A(di), .Y(d[1]));
+
+    box   b0 (.A(d[0]), .Y(do[0]));
+    box   b1 (.A(d[1]), .Y(do[1]));
+    child c  (.I(d[1]), .O({do[3], do[2]}));
+
+endmodule
diff --git a/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.tcl b/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.tcl
new file mode 100644
index 000000000..4e6c1ba71
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.tcl
@@ -0,0 +1,11 @@
+yosys -import
+if { [info procs integrateinv] == {} } { plugin -i integrateinv }
+yosys -import  ;# ingest plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -check -auto-top
+
+debug integrateinv
+
+select t:\$_NOT_ -assert-count 2
+select t:box r:INV_A=2'b10 %i -assert-count 1
diff --git a/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.v b/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.v
new file mode 100644
index 000000000..1515b1783
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/multi_bit/multi_bit.v
@@ -0,0 +1,50 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module box(
+    (* invertible_pin="INV_A" *)
+    input  wire [1:0] A,
+    input  wire [1:0] B,
+
+    output wire Y
+);
+
+    parameter [1:0] INV_A = 2'b00;
+
+endmodule
+
+
+module top(
+    input  wire [3:0] di,
+    output wire       do
+);
+
+    wire [3:0] d;
+
+    \$_NOT_ n0 (.A(di[0]), .Y(d[0]));
+    \$_NOT_ n1 (.A(di[1]), .Y(d[1]));
+    \$_NOT_ n2 (.A(di[2]), .Y(d[2]));
+    \$_NOT_ n3 (.A(di[3]), .Y(d[3]));
+
+    box #(.INV_A(2'b01)) the_box (
+        .A ({d[1], d[0]}),
+        .B ({d[3], d[2]}),
+
+        .Y (do)
+    );
+
+endmodule
diff --git a/yosys-plugins/integrateinv/tests/single_bit/single_bit.tcl b/yosys-plugins/integrateinv/tests/single_bit/single_bit.tcl
new file mode 100644
index 000000000..7f1bdbb8a
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/single_bit/single_bit.tcl
@@ -0,0 +1,12 @@
+yosys -import
+if { [info procs integrateinv] == {} } { plugin -i integrateinv }
+yosys -import  ;# ingest plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -check -auto-top
+
+debug integrateinv
+
+select t:\$_NOT_ -assert-count 2
+select t:box r:INV_A=1'b0 %i -assert-count 1
+select t:box r:INV_C=1'b1 %i -assert-count 1
diff --git a/yosys-plugins/integrateinv/tests/single_bit/single_bit.v b/yosys-plugins/integrateinv/tests/single_bit/single_bit.v
new file mode 100644
index 000000000..2e0739e9f
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/single_bit/single_bit.v
@@ -0,0 +1,56 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module box(
+    (* invertible_pin="INV_A" *)
+    input  wire A,
+    input  wire B,
+    (* invertible_pin="INV_C" *)
+    input  wire C,
+    input  wire D,
+
+    output wire Y
+);
+
+    parameter [0:0] INV_A = 1'b0;
+    parameter [0:0] INV_C = 1'b0;
+
+endmodule
+
+
+module top(
+    input  wire [3:0] di,
+    output wire       do
+);
+
+    wire [3:0] d;
+
+    \$_NOT_ n0 (.A(di[0]), .Y(d[0]));
+    \$_NOT_ n1 (.A(di[1]), .Y(d[1]));
+    \$_NOT_ n2 (.A(di[2]), .Y(d[2]));
+    \$_NOT_ n3 (.A(di[3]), .Y(d[3]));
+
+    box #(.INV_A(1'b1)) the_box (
+        .A (d[0]),
+        .B (d[1]),
+        .C (d[2]),
+        .D (d[3]),
+
+        .Y (do)
+    );
+
+endmodule
diff --git a/yosys-plugins/integrateinv/tests/toplevel/toplevel.tcl b/yosys-plugins/integrateinv/tests/toplevel/toplevel.tcl
new file mode 100644
index 000000000..2595cb41e
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/toplevel/toplevel.tcl
@@ -0,0 +1,10 @@
+yosys -import
+if { [info procs integrateinv] == {} } { plugin -i integrateinv }
+yosys -import  ;# ingest plugin commands
+
+read_verilog -icells $::env(DESIGN_TOP).v
+hierarchy -check -auto-top
+
+debug integrateinv
+
+select t:\$_NOT_ -assert-count 1
diff --git a/yosys-plugins/integrateinv/tests/toplevel/toplevel.v b/yosys-plugins/integrateinv/tests/toplevel/toplevel.v
new file mode 100644
index 000000000..8c2173170
--- /dev/null
+++ b/yosys-plugins/integrateinv/tests/toplevel/toplevel.v
@@ -0,0 +1,43 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module box(
+    (* invertible_pin="INV_A" *)
+    input  wire A,
+    output wire Y
+);
+
+    parameter [0:0] INV_A = 1'b0;
+
+endmodule
+
+
+module top(
+    input  wire [1:0]  di,
+    output wire [2:0]  do
+);
+
+    wire [1:0] d;
+
+    \$_NOT_ n0 (.A(di[0]), .Y(d[0]));
+    \$_NOT_ n1 (.A(di[1]), .Y(d[1]));
+
+    box b0 (.A(d[0]), .Y(do[0]));
+    box b1 (.A(d[1]), .Y(do[1]));
+    assign do[0] = d[0];
+
+endmodule
diff --git a/yosys-plugins/params/Makefile b/yosys-plugins/params/Makefile
new file mode 100644
index 000000000..9740c7b26
--- /dev/null
+++ b/yosys-plugins/params/Makefile
@@ -0,0 +1,19 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = params
+SOURCES = params.cc
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/params/params.cc b/yosys-plugins/params/params.cc
new file mode 100644
index 000000000..e4c944dfa
--- /dev/null
+++ b/yosys-plugins/params/params.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+
+PRIVATE_NAMESPACE_BEGIN
+
+void register_in_tcl_interpreter(const std::string &command)
+{
+    Tcl_Interp *interp = yosys_get_tcl_interp();
+    std::string tcl_script = stringf("proc %s args { return [yosys %s {*}$args] }", command.c_str(), command.c_str());
+    Tcl_Eval(interp, tcl_script.c_str());
+}
+
+struct GetParam : public Pass {
+    GetParam() : Pass("getparam", "get parameter on object") { register_in_tcl_interpreter(pass_name); }
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("   getparam name selection\n");
+        log("\n");
+        log("Get the given parameter on the selected object. \n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        if (args.size() == 1) {
+            log_error("Incorrect number of arguments");
+        }
+        extra_args(args, 2, design);
+
+        auto param = RTLIL::IdString(RTLIL::escape_id(args.at(1)));
+        Tcl_Interp *interp = yosys_get_tcl_interp();
+        Tcl_Obj *tcl_list = Tcl_NewListObj(0, NULL);
+
+        for (auto module : design->selected_modules()) {
+            for (auto cell : module->selected_cells()) {
+                auto params = cell->parameters;
+                auto it = params.find(param);
+                if (it != params.end()) {
+                    std::string value;
+                    auto param_obj = it->second;
+                    if (param_obj.flags & RTLIL::CONST_FLAG_STRING) {
+                        value = param_obj.decode_string();
+                    } else {
+                        value = std::to_string(param_obj.as_int());
+                    }
+                    Tcl_Obj *value_obj = Tcl_NewStringObj(value.c_str(), value.size());
+                    Tcl_ListObjAppendElement(interp, tcl_list, value_obj);
+                }
+            }
+        }
+        Tcl_SetObjResult(interp, tcl_list);
+    }
+
+} GetParam;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/params/tests/Makefile b/yosys-plugins/params/tests/Makefile
new file mode 100644
index 000000000..610074d1b
--- /dev/null
+++ b/yosys-plugins/params/tests/Makefile
@@ -0,0 +1,28 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = pll
+include $(shell pwd)/../../Makefile_test.common
+
+json_test = python compare_output_json.py --json $(1)/$(1).json --golden $(1)/$(1).golden.json
+
+define json_update =
+$(1)_update_json:
+	python compare_output_json.py --json $(1)/$(1).json --golden $(1)/$(1).golden.json --update
+endef
+
+pll_verify = $(call json_test,pll) && test $$(grep "PASS" pll/pll.txt | wc -l) -eq 2
+
diff --git a/yosys-plugins/params/tests/compare_output_json.py b/yosys-plugins/params/tests/compare_output_json.py
new file mode 100644
index 000000000..d9c4e01be
--- /dev/null
+++ b/yosys-plugins/params/tests/compare_output_json.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 script extracts the top module cells and their corresponding parameters
+from json files produced by Yosys.
+The return code of this script is used to check if the output is equivalent.
+"""
+
+import sys
+import json
+import argparse
+
+parameters = ["CLKFBOUT_CLKOUT1_HIGH_TIME"]
+
+def read_cells(json_file):
+    with open(json_file) as f:
+        data = json.load(f)
+    f.close()
+    cells = data['modules']['top']['cells']
+    cells_parameters = dict()
+    for cell, opts in cells.items():
+        attributes = opts['parameters']
+        if len(attributes.keys()):
+            if any([x in parameters for x in attributes.keys()]):
+                cells_parameters[cell] = attributes
+    return cells_parameters
+
+
+def main(args):
+    cells = read_cells(args.json)
+    if args.update:
+        with open(args.golden, 'w') as f:
+            json.dump(cells, f, indent=2)
+    else:
+        with open(args.golden) as f:
+            cells_golden = json.load(f)
+            if cells == cells_golden:
+                exit(0)
+            else:
+                print(json.dumps(cells, indent=4))
+                json.dump(cells, open(args.json + ".fail", 'w'), indent=2)
+                print("VS")
+                print(json.dumps(cells_golden, indent=4))
+                exit(1)
+    f.close()
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--json', help = 'JSON to compare', required = True)
+    parser.add_argument('--golden', help = 'Golden JSON file', required = True)
+    parser.add_argument('--update', action = 'store_true', help = 'Update golden reference')
+    args = parser.parse_args()
+    main(args)
diff --git a/yosys-plugins/params/tests/pll/pll.golden.json b/yosys-plugins/params/tests/pll/pll.golden.json
new file mode 100644
index 000000000..bdc478eca
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/pll.golden.json
@@ -0,0 +1,128 @@
+{
+  "PLLE2_ADV": {
+    "CLKFBOUT_CLKOUT1_HIGH_TIME": "000110",
+    "CLKFBOUT_CLKOUT1_LOW_TIME": "000110",
+    "CLKFBOUT_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKFBOUT_CLKOUT1_PHASE_MUX": "000",
+    "CLKFBOUT_CLKOUT2_DELAY_TIME": "000000",
+    "CLKFBOUT_CLKOUT2_EDGE": "0",
+    "CLKFBOUT_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT0_CLKOUT1_HIGH_TIME": "001010",
+    "CLKOUT0_CLKOUT1_LOW_TIME": "001010",
+    "CLKOUT0_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKOUT0_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT0_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT0_CLKOUT2_EDGE": "0",
+    "CLKOUT0_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT1_CLKOUT1_HIGH_TIME": "000010",
+    "CLKOUT1_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT1_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKOUT1_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT1_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT1_CLKOUT2_EDGE": "1",
+    "CLKOUT1_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT2_CLKOUT1_HIGH_TIME": "000010",
+    "CLKOUT2_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT2_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT2_CLKOUT1_PHASE_MUX": "010",
+    "CLKOUT2_CLKOUT2_DELAY_TIME": "000001",
+    "CLKOUT2_CLKOUT2_EDGE": "1",
+    "CLKOUT2_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT3_CLKOUT1_HIGH_TIME": "000011",
+    "CLKOUT3_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT3_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT3_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT3_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT3_CLKOUT2_EDGE": "0",
+    "CLKOUT3_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT4_CLKOUT1_HIGH_TIME": "000001",
+    "CLKOUT4_CLKOUT1_LOW_TIME": "000001",
+    "CLKOUT4_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT4_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT4_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT4_CLKOUT2_EDGE": "0",
+    "CLKOUT4_CLKOUT2_NO_COUNT": "1",
+    "CLKOUT5_CLKOUT1_HIGH_TIME": "000001",
+    "CLKOUT5_CLKOUT1_LOW_TIME": "000001",
+    "CLKOUT5_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT5_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT5_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT5_CLKOUT2_EDGE": "0",
+    "CLKOUT5_CLKOUT2_NO_COUNT": "1",
+    "DIVCLK_DIVCLK_EDGE": "0",
+    "DIVCLK_DIVCLK_HIGH_TIME": "000001",
+    "DIVCLK_DIVCLK_LOW_TIME": "000001",
+    "DIVCLK_DIVCLK_NO_COUNT": "1",
+    "FILTREG1_RESERVED": "000000001000",
+    "INV_CLKINSEL": "0",
+    "LKTABLE": "1111111111110011100111111010010000000001",
+    "LOCKREG3_RESERVED": "1",
+    "STARTUP_WAIT": "0",
+    "TABLE": "1111110100",
+    "ZINV_PWRDWN": "1",
+    "ZINV_RST": "0"
+  },
+  "PLLE2_ADV_0": {
+    "CLKFBOUT_CLKOUT1_HIGH_TIME": "000110",
+    "CLKFBOUT_CLKOUT1_LOW_TIME": "000110",
+    "CLKFBOUT_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKFBOUT_CLKOUT1_PHASE_MUX": "000",
+    "CLKFBOUT_CLKOUT2_DELAY_TIME": "000000",
+    "CLKFBOUT_CLKOUT2_EDGE": "0",
+    "CLKFBOUT_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT0_CLKOUT1_HIGH_TIME": "001010",
+    "CLKOUT0_CLKOUT1_LOW_TIME": "001010",
+    "CLKOUT0_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKOUT0_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT0_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT0_CLKOUT2_EDGE": "0",
+    "CLKOUT0_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT1_CLKOUT1_HIGH_TIME": "000010",
+    "CLKOUT1_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT1_CLKOUT1_OUTPUT_ENABLE": "1",
+    "CLKOUT1_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT1_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT1_CLKOUT2_EDGE": "1",
+    "CLKOUT1_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT2_CLKOUT1_HIGH_TIME": "000010",
+    "CLKOUT2_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT2_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT2_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT2_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT2_CLKOUT2_EDGE": "1",
+    "CLKOUT2_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT3_CLKOUT1_HIGH_TIME": "000011",
+    "CLKOUT3_CLKOUT1_LOW_TIME": "000011",
+    "CLKOUT3_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT3_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT3_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT3_CLKOUT2_EDGE": "0",
+    "CLKOUT3_CLKOUT2_NO_COUNT": "0",
+    "CLKOUT4_CLKOUT1_HIGH_TIME": "000001",
+    "CLKOUT4_CLKOUT1_LOW_TIME": "000001",
+    "CLKOUT4_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT4_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT4_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT4_CLKOUT2_EDGE": "0",
+    "CLKOUT4_CLKOUT2_NO_COUNT": "1",
+    "CLKOUT5_CLKOUT1_HIGH_TIME": "000001",
+    "CLKOUT5_CLKOUT1_LOW_TIME": "000001",
+    "CLKOUT5_CLKOUT1_OUTPUT_ENABLE": "0",
+    "CLKOUT5_CLKOUT1_PHASE_MUX": "000",
+    "CLKOUT5_CLKOUT2_DELAY_TIME": "000000",
+    "CLKOUT5_CLKOUT2_EDGE": "0",
+    "CLKOUT5_CLKOUT2_NO_COUNT": "1",
+    "DIVCLK_DIVCLK_EDGE": "0",
+    "DIVCLK_DIVCLK_HIGH_TIME": "000001",
+    "DIVCLK_DIVCLK_LOW_TIME": "000001",
+    "DIVCLK_DIVCLK_NO_COUNT": "1",
+    "FILTREG1_RESERVED": "000000001000",
+    "INV_CLKINSEL": "0",
+    "LKTABLE": "1111111111110011100111111010010000000001",
+    "LOCKREG3_RESERVED": "1",
+    "STARTUP_WAIT": "0",
+    "TABLE": "1111110100",
+    "ZINV_PWRDWN": "1",
+    "ZINV_RST": "0"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/params/tests/pll/pll.tcl b/yosys-plugins/params/tests/pll/pll.tcl
new file mode 100644
index 000000000..796fdaed5
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/pll.tcl
@@ -0,0 +1,58 @@
+yosys -import
+if { [info procs getparam] == {} } { plugin -i params }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Check phase parameter values on bith PLLE2_ADV instances
+set reference_phase [list 90 70]
+set phase [getparam CLKOUT2_PHASE top/PLLE2_ADV_0 top/PLLE2_ADV]
+if {[llength $phase] != 2} {
+	error "Getparam should return a list with 2 elements"
+}
+set fp [open [test_output_path "pll.txt"] "w"]
+puts -nonewline $fp "Phase before: "
+if {$phase == $reference_phase} {
+	puts $fp "PASS"
+} else {
+	puts $fp "FAIL: $phase != $reference_phase"
+}
+
+# Modify the phase parameter value on one of the PLLE2_ADV instances
+setparam -set CLKOUT2_PHASE [expr [lindex $phase 0] * 1000] top/PLLE2_ADV
+
+# Verify that the parameter has been correctly updated on the chosen instance
+set reference_phase [list 90000 70]
+set phase [getparam CLKOUT2_PHASE top/PLLE2_ADV_0 top/PLLE2_ADV]
+puts -nonewline $fp "Phase after: "
+if {$phase == $reference_phase} {
+	puts $fp "PASS"
+} else {
+	puts $fp "FAIL: $phase != $reference_phase"
+}
+close $fp
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp -iopad -run prepare:check
+
+# Map Xilinx tech library to 7-series VPR tech library.
+read_verilog -lib [file dirname $::env(DESIGN_TOP)]/techmaps/cells_sim.v
+techmap -map  [file dirname $::env(DESIGN_TOP)]/techmaps/cells_map.v
+
+# opt_expr -undriven makes sure all nets are driven, if only by the $undef
+# net.
+opt_expr -undriven
+opt_clean
+
+setundef -zero -params
+stat
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "pll.json"]
+write_blif -attr -param -cname -conn [test_output_path "pll.eblif"]
diff --git a/yosys-plugins/params/tests/pll/pll.v b/yosys-plugins/params/tests/pll/pll.v
new file mode 100644
index 000000000..fbdc77ea3
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/pll.v
@@ -0,0 +1,77 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* dont_touch = "true" *) input clk100,
+    input cpu_reset,
+    output [2:0] led
+);
+
+  wire [2:0] led;
+  wire builder_pll_fb;
+
+  assign led[0] = main_locked;
+  assign led[1] = main_clkout0;
+  assign led[2] = main_clkout1;
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(5'd20),
+      .CLKOUT0_PHASE(1'd0),
+      .CLKOUT1_DIVIDE(3'd5),
+      .CLKOUT1_PHASE(1'd0),
+      .CLKOUT2_DIVIDE(3'd5),
+      .CLKOUT2_PHASE(7'd70),
+      .CLKOUT3_DIVIDE(3'd6),
+      .CLKOUT3_PHASE(1'd0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV_0 (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk100),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .LOCKED(main_locked)
+  );
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(5'd20),
+      .CLKOUT0_PHASE(1'd0),
+      .CLKOUT1_DIVIDE(3'd5),
+      .CLKOUT1_PHASE(1'd0),
+      .CLKOUT2_DIVIDE(3'd5),
+      .CLKOUT2_PHASE(7'd90),
+      .CLKOUT3_DIVIDE(3'd6),
+      .CLKOUT3_PHASE(1'd0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk100),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .LOCKED(main_locked)
+  );
+
+endmodule
diff --git a/yosys-plugins/params/tests/pll/pll.xdc b/yosys-plugins/params/tests/pll/pll.xdc
new file mode 100644
index 000000000..2f4eba35d
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/pll.xdc
@@ -0,0 +1,9 @@
+# ## clk100:0
+set_property LOC E3 [get_ports clk100]
+set_property IOSTANDARD LVCMOS33 [get_ports clk100]
+# ## cpu_reset:0
+set_property LOC C2 [get_ports cpu_reset]
+set_property IOSTANDARD LVCMOS33 [get_ports cpu_reset]
+set_property LOC H5 [get_ports {led[0]}]
+set_property LOC J5 [get_ports {led[1]}]
+set_property LOC T9 [get_ports {led[2]}]
diff --git a/yosys-plugins/params/tests/pll/techmaps/cells_map.v b/yosys-plugins/params/tests/pll/techmaps/cells_map.v
new file mode 100644
index 000000000..19b67dddc
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/techmaps/cells_map.v
@@ -0,0 +1,860 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+// ============================================================================
+// CMT
+
+`define PLL_FRAC_PRECISION 10
+`define PLL_FIXED_WIDTH 32
+
+// Rounds a fixed point number to a given precision
+function [`PLL_FIXED_WIDTH:1] pll_round_frac(input [`PLL_FIXED_WIDTH:1] decimal,
+                                             input [`PLL_FIXED_WIDTH:1] precision);
+
+  if (decimal[(`PLL_FRAC_PRECISION-precision)] == 1'b1) begin
+    pll_round_frac = decimal + (1'b1 << (`PLL_FRAC_PRECISION - precision));
+  end else begin
+    pll_round_frac = decimal;
+  end
+
+endfunction
+
+// Computes content of the PLLs divider registers
+function [13:0] pll_divider_regs(input [7:0] divide,  // Max divide is 128
+                                 input [31:0] duty_cycle   // Duty cycle is multiplied by 100,000
+);
+
+  reg [`PLL_FIXED_WIDTH:1] duty_cycle_fix;
+  reg [`PLL_FIXED_WIDTH:1] duty_cycle_min;
+  reg [`PLL_FIXED_WIDTH:1] duty_cycle_max;
+
+  reg [               6:0] high_time;
+  reg [               6:0] low_time;
+  reg                      w_edge;
+  reg                      no_count;
+
+  reg [`PLL_FIXED_WIDTH:1] temp;
+
+  if (divide >= 64) begin
+    duty_cycle_min = ((divide - 64) * 100_000) / divide;
+    duty_cycle_max = (645 / divide) * 100_00;
+    if (duty_cycle > duty_cycle_max) duty_cycle = duty_cycle_max;
+    if (duty_cycle < duty_cycle_min) duty_cycle = duty_cycle_min;
+  end
+
+  duty_cycle_fix = (duty_cycle << `PLL_FRAC_PRECISION) / 100_000;
+
+  if (divide == 7'h01) begin
+    high_time = 7'h01;
+    w_edge    = 1'b0;
+    low_time  = 7'h01;
+    no_count  = 1'b1;
+
+  end else begin
+    temp = pll_round_frac(duty_cycle_fix*divide, 1);
+
+    high_time = temp[`PLL_FRAC_PRECISION+7:`PLL_FRAC_PRECISION+1];
+    w_edge    = temp[`PLL_FRAC_PRECISION];
+
+    if (high_time == 7'h00) begin
+      high_time = 7'h01;
+      w_edge    = 1'b0;
+    end
+
+    if (high_time == divide) begin
+      high_time = divide - 1;
+      w_edge    = 1'b1;
+    end
+
+    low_time = divide - high_time;
+    no_count = 1'b0;
+  end
+
+  pll_divider_regs = {w_edge, no_count, high_time[5:0], low_time[5:0]};
+endfunction
+
+// Computes the PLLs phase shift registers
+function [10:0] pll_phase_regs(input [7:0] divide, input signed [31:0] phase);
+
+  reg [`PLL_FIXED_WIDTH:1] phase_in_cycles;
+  reg [`PLL_FIXED_WIDTH:1] phase_fixed;
+  reg [1:0] mx;
+  reg [5:0] delay_time;
+  reg [2:0] phase_mux;
+
+  reg [`PLL_FIXED_WIDTH:1] temp;
+
+  if (phase < 0) begin
+    phase_fixed = ((phase + 360000) << `PLL_FRAC_PRECISION) / 1000;
+  end else begin
+    phase_fixed = (phase << `PLL_FRAC_PRECISION) / 1000;
+  end
+
+  phase_in_cycles = (phase_fixed * divide) / 360;
+  temp            = pll_round_frac(phase_in_cycles, 3);
+
+  mx              = 2'b00;
+  phase_mux       = temp[`PLL_FRAC_PRECISION:`PLL_FRAC_PRECISION-2];
+  delay_time      = temp[`PLL_FRAC_PRECISION+6:`PLL_FRAC_PRECISION+1];
+
+  pll_phase_regs  = {mx, phase_mux, delay_time};
+endfunction
+
+
+// Given PLL/MMCM divide, duty_cycle and phase calculates content of the
+// CLKREG1 and CLKREG2.
+function [37:0] pll_clkregs(input [7:0] divide,  // Max divide is 128
+                            input [31:0] duty_cycle,  // Multiplied by 100,000
+                            input signed [31:0] phase       // Phase is given in degrees (-360,000 to 360,000)
+);
+
+  reg [13:0] pll_div;  // EDGE, NO_COUNT, HIGH_TIME[5:0], LOW_TIME[5:0]
+  reg [10:0] pll_phase;  // MX, PHASE_MUX[2:0], DELAY_TIME[5:0]
+
+  pll_div = pll_divider_regs(divide, duty_cycle);
+  pll_phase = pll_phase_regs(divide, phase);
+
+  pll_clkregs = {
+    // CLKREG2: RESERVED[6:0], MX[1:0], EDGE, NO_COUNT, DELAY_TIME[5:0]
+    6'h00,
+    pll_phase[10:9],
+    pll_div[13:12],
+    pll_phase[5:0],
+    // CLKREG1: PHASE_MUX[3:0], RESERVED, HIGH_TIME[5:0], LOW_TIME[5:0]
+    pll_phase[8:6],
+    1'b0,
+    pll_div[11:0]
+  };
+
+endfunction
+
+// This function takes the divide value and outputs the necessary lock values
+function [39:0] pll_lktable_lookup(input [6:0] divide // Max divide is 64
+);
+
+  reg [2559:0] lookup;
+
+  lookup = {
+    // This table is composed of:
+    // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
+    40'b00110_00110_1111101000_1111101001_0000000001,
+    40'b00110_00110_1111101000_1111101001_0000000001,
+    40'b01000_01000_1111101000_1111101001_0000000001,
+    40'b01011_01011_1111101000_1111101001_0000000001,
+    40'b01110_01110_1111101000_1111101001_0000000001,
+    40'b10001_10001_1111101000_1111101001_0000000001,
+    40'b10011_10011_1111101000_1111101001_0000000001,
+    40'b10110_10110_1111101000_1111101001_0000000001,
+    40'b11001_11001_1111101000_1111101001_0000000001,
+    40'b11100_11100_1111101000_1111101001_0000000001,
+    40'b11111_11111_1110000100_1111101001_0000000001,
+    40'b11111_11111_1100111001_1111101001_0000000001,
+    40'b11111_11111_1011101110_1111101001_0000000001,
+    40'b11111_11111_1010111100_1111101001_0000000001,
+    40'b11111_11111_1010001010_1111101001_0000000001,
+    40'b11111_11111_1001110001_1111101001_0000000001,
+    40'b11111_11111_1000111111_1111101001_0000000001,
+    40'b11111_11111_1000100110_1111101001_0000000001,
+    40'b11111_11111_1000001101_1111101001_0000000001,
+    40'b11111_11111_0111110100_1111101001_0000000001,
+    40'b11111_11111_0111011011_1111101001_0000000001,
+    40'b11111_11111_0111000010_1111101001_0000000001,
+    40'b11111_11111_0110101001_1111101001_0000000001,
+    40'b11111_11111_0110010000_1111101001_0000000001,
+    40'b11111_11111_0110010000_1111101001_0000000001,
+    40'b11111_11111_0101110111_1111101001_0000000001,
+    40'b11111_11111_0101011110_1111101001_0000000001,
+    40'b11111_11111_0101011110_1111101001_0000000001,
+    40'b11111_11111_0101000101_1111101001_0000000001,
+    40'b11111_11111_0101000101_1111101001_0000000001,
+    40'b11111_11111_0100101100_1111101001_0000000001,
+    40'b11111_11111_0100101100_1111101001_0000000001,
+    40'b11111_11111_0100101100_1111101001_0000000001,
+    40'b11111_11111_0100010011_1111101001_0000000001,
+    40'b11111_11111_0100010011_1111101001_0000000001,
+    40'b11111_11111_0100010011_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001,
+    40'b11111_11111_0011111010_1111101001_0000000001
+  };
+
+  pll_lktable_lookup = lookup[((64-divide)*40)+:40];
+endfunction
+
+// This function takes the divide value and the bandwidth setting of the PLL
+// and outputs the digital filter settings necessary.
+function [9:0] pll_table_lookup(input [6:0] divide,  // Max divide is 64
+                                input [8*9:0] BANDWIDTH);
+
+  reg [639:0] lookup_low;
+  reg [639:0] lookup_high;
+  reg [639:0] lookup_optimized;
+
+  reg [  9:0] lookup_entry;
+
+  lookup_low = {
+    // CP_RES_LFHF
+    10'b0010_1111_00,
+    10'b0010_1111_00,
+    10'b0010_0111_00,
+    10'b0010_1101_00,
+    10'b0010_0101_00,
+    10'b0010_0101_00,
+    10'b0010_1001_00,
+    10'b0010_1110_00,
+    10'b0010_1110_00,
+    10'b0010_0001_00,
+    10'b0010_0001_00,
+    10'b0010_0110_00,
+    10'b0010_0110_00,
+    10'b0010_0110_00,
+    10'b0010_0110_00,
+    10'b0010_1010_00,
+    10'b0010_1010_00,
+    10'b0010_1010_00,
+    10'b0010_1010_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_1100_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0010_0010_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0011_1100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00
+  };
+
+  lookup_high = {
+    // CP_RES_LFHF
+    10'b0011_0111_00,
+    10'b0011_0111_00,
+    10'b0101_1111_00,
+    10'b0111_1111_00,
+    10'b0111_1011_00,
+    10'b1101_0111_00,
+    10'b1110_1011_00,
+    10'b1110_1101_00,
+    10'b1111_1101_00,
+    10'b1111_0111_00,
+    10'b1111_1011_00,
+    10'b1111_1101_00,
+    10'b1111_0011_00,
+    10'b1110_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0101_1100_00,
+    10'b0101_1100_00,
+    10'b0101_1100_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b0100_0010_00,
+    10'b0100_0010_00,
+    10'b0100_0010_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0011_0100_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00
+  };
+
+  lookup_optimized = {
+    // CP_RES_LFHF
+    10'b0011_0111_00,
+    10'b0011_0111_00,
+    10'b0101_1111_00,
+    10'b0111_1111_00,
+    10'b0111_1011_00,
+    10'b1101_0111_00,
+    10'b1110_1011_00,
+    10'b1110_1101_00,
+    10'b1111_1101_00,
+    10'b1111_0111_00,
+    10'b1111_1011_00,
+    10'b1111_1101_00,
+    10'b1111_0011_00,
+    10'b1110_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b1111_0101_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0111_0110_00,
+    10'b0101_1100_00,
+    10'b0101_1100_00,
+    10'b0101_1100_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b1100_0001_00,
+    10'b0100_0010_00,
+    10'b0100_0010_00,
+    10'b0100_0010_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0011_0100_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0010_1000_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0100_1100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00,
+    10'b0010_0100_00
+  };
+
+  if (BANDWIDTH == "LOW") begin
+    pll_table_lookup = lookup_low[((64-divide)*10)+:10];
+  end else if (BANDWIDTH == "HIGH") begin
+    pll_table_lookup = lookup_high[((64-divide)*10)+:10];
+  end else if (BANDWIDTH == "OPTIMIZED") begin
+    pll_table_lookup = lookup_optimized[((64-divide)*10)+:10];
+  end
+
+endfunction
+
+// ............................................................................
+// IMPORTANT NOTE: Due to lack of support for real type parameters in Yosys
+// the PLL parameters that define duty cycles and phase shifts have to be
+// provided as integers! The DUTY_CYCLE is expressed as % of high time times
+// 1000 whereas the PHASE is expressed in degrees times 1000.
+
+// PLLE2_ADV
+module PLLE2_ADV (
+    input CLKFBIN,
+    input CLKIN1,
+    input CLKIN2,
+    input CLKINSEL,
+
+    output CLKFBOUT,
+    output CLKOUT0,
+    output CLKOUT1,
+    output CLKOUT2,
+    output CLKOUT3,
+    output CLKOUT4,
+    output CLKOUT5,
+
+    input  PWRDWN,
+    input  RST,
+    output LOCKED,
+
+    input         DCLK,
+    input         DEN,
+    input         DWE,
+    output        DRDY,
+    input  [ 6:0] DADDR,
+    input  [15:0] DI,
+    output [15:0] DO
+);
+
+  parameter _TECHMAP_CONSTMSK_CLKINSEL_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKINSEL_ = 0;
+
+  parameter _TECHMAP_CONSTMSK_RST_ = 0;
+  parameter _TECHMAP_CONSTVAL_RST_ = 0;
+  parameter _TECHMAP_CONSTMSK_PWRDWN_ = 0;
+  parameter _TECHMAP_CONSTVAL_PWRDWN_ = 0;
+
+  parameter _TECHMAP_CONSTMSK_CLKFBOUT_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKFBOUT_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT0_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT0_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT1_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT1_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT2_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT2_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT3_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT3_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT4_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT4_ = 0;
+  parameter _TECHMAP_CONSTMSK_CLKOUT5_ = 0;
+  parameter _TECHMAP_CONSTVAL_CLKOUT5_ = 0;
+
+  parameter _TECHMAP_CONSTMSK_DCLK_ = 0;
+  parameter _TECHMAP_CONSTVAL_DCLK_ = 0;
+  parameter _TECHMAP_CONSTMSK_DEN_ = 0;
+  parameter _TECHMAP_CONSTVAL_DEN_ = 0;
+  parameter _TECHMAP_CONSTMSK_DWE_ = 0;
+  parameter _TECHMAP_CONSTVAL_DWE_ = 0;
+
+  parameter IS_CLKINSEL_INVERTED = 1'b0;
+  parameter IS_RST_INVERTED = 1'b0;
+  parameter IS_PWRDWN_INVERTED = 1'b0;
+
+  parameter BANDWIDTH = "OPTIMIZED";
+  parameter STARTUP_WAIT = "FALSE";
+  parameter COMPENSATION = "ZHOLD";
+
+  parameter CLKIN1_PERIOD = 0.0;
+  parameter REF_JITTER1 = 0.01;
+  parameter CLKIN2_PERIOD = 0.0;
+  parameter REF_JITTER2 = 0.01;
+
+  parameter [5:0] DIVCLK_DIVIDE = 1;
+
+  parameter [5:0] CLKFBOUT_MULT = 1;
+  parameter CLKFBOUT_PHASE = 0;
+
+  parameter [6:0] CLKOUT0_DIVIDE = 1;
+  parameter CLKOUT0_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT0_PHASE = 0;
+
+  parameter [6:0] CLKOUT1_DIVIDE = 1;
+  parameter CLKOUT1_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT1_PHASE = 0;
+
+  parameter [6:0] CLKOUT2_DIVIDE = 1;
+  parameter CLKOUT2_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT2_PHASE = 0;
+
+  parameter [6:0] CLKOUT3_DIVIDE = 1;
+  parameter CLKOUT3_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT3_PHASE = 0;
+
+  parameter [6:0] CLKOUT4_DIVIDE = 1;
+  parameter CLKOUT4_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT4_PHASE = 0;
+
+  parameter [6:0] CLKOUT5_DIVIDE = 1;
+  parameter CLKOUT5_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT5_PHASE = 0;
+
+  // Compute PLL's registers content
+  localparam CLKFBOUT_REGS = pll_clkregs(CLKFBOUT_MULT, 50000, CLKFBOUT_PHASE);
+  localparam DIVCLK_REGS = pll_clkregs(DIVCLK_DIVIDE, 50000, 0);
+
+  localparam CLKOUT0_REGS = pll_clkregs(CLKOUT0_DIVIDE, CLKOUT0_DUTY_CYCLE, CLKOUT0_PHASE);
+  localparam CLKOUT1_REGS = pll_clkregs(CLKOUT1_DIVIDE, CLKOUT1_DUTY_CYCLE, CLKOUT1_PHASE);
+  localparam CLKOUT2_REGS = pll_clkregs(CLKOUT2_DIVIDE, CLKOUT2_DUTY_CYCLE, CLKOUT2_PHASE);
+  localparam CLKOUT3_REGS = pll_clkregs(CLKOUT3_DIVIDE, CLKOUT3_DUTY_CYCLE, CLKOUT3_PHASE);
+  localparam CLKOUT4_REGS = pll_clkregs(CLKOUT4_DIVIDE, CLKOUT4_DUTY_CYCLE, CLKOUT4_PHASE);
+  localparam CLKOUT5_REGS = pll_clkregs(CLKOUT5_DIVIDE, CLKOUT5_DUTY_CYCLE, CLKOUT5_PHASE);
+
+  // Handle inputs that should have certain logic levels when left unconnected
+  localparam INV_CLKINSEL = (_TECHMAP_CONSTMSK_CLKINSEL_ == 1) ? !_TECHMAP_CONSTVAL_CLKINSEL_ :
+			     (_TECHMAP_CONSTVAL_CLKINSEL_ == 0) ? IS_CLKINSEL_INVERTED :
+			     IS_CLKINSEL_INVERTED;
+  generate
+    if (_TECHMAP_CONSTMSK_CLKINSEL_ == 1) begin
+      wire clkinsel = 1'b1;
+    end else if (_TECHMAP_CONSTVAL_CLKINSEL_ == 0) begin
+      wire clkinsel = 1'b1;
+    end else begin
+      wire clkinsel = CLKINSEL;
+    end
+  endgenerate
+
+  localparam INV_PWRDWN = (_TECHMAP_CONSTMSK_PWRDWN_ == 1) ? !_TECHMAP_CONSTVAL_PWRDWN_ :
+			  (_TECHMAP_CONSTVAL_PWRDWN_ == 0) ? ~IS_PWRDWN_INVERTED :
+			  IS_PWRDWN_INVERTED;
+  generate
+    if (_TECHMAP_CONSTMSK_PWRDWN_ == 1) begin
+      wire pwrdwn = 1'b1;
+    end else if (_TECHMAP_CONSTVAL_PWRDWN_ == 0) begin
+      wire pwrdwn = 1'b1;
+    end else begin
+      wire pwrdwn = PWRDWN;
+    end
+  endgenerate
+
+  localparam INV_RST = (_TECHMAP_CONSTMSK_RST_ == 1) ? !_TECHMAP_CONSTVAL_PWRDWN_ :
+		       (_TECHMAP_CONSTVAL_RST_ == 0) ? ~IS_RST_INVERTED : IS_RST_INVERTED;
+  generate
+    if (_TECHMAP_CONSTMSK_RST_ == 1) begin
+      wire rst = 1'b1;
+    end else if (_TECHMAP_CONSTVAL_RST_ == 0) begin
+      wire rst = 1'b1;
+    end else begin
+      wire rst = RST;
+    end
+  endgenerate
+
+  generate
+    if (_TECHMAP_CONSTMSK_DCLK_ == 1) wire dclk = _TECHMAP_CONSTVAL_DCLK_;
+    else if (_TECHMAP_CONSTVAL_DCLK_ == 0) wire dclk = 1'b0;
+    else wire dclk = DCLK;
+  endgenerate
+
+  generate
+    if (_TECHMAP_CONSTMSK_DEN_ == 1) wire den = _TECHMAP_CONSTVAL_DEN_;
+    else if (_TECHMAP_CONSTVAL_DEN_ == 0) wire den = 1'b0;
+    else wire den = DEN;
+  endgenerate
+
+  generate
+    if (_TECHMAP_CONSTMSK_DWE_ == 1) wire dwe = _TECHMAP_CONSTVAL_DWE_;
+    else if (_TECHMAP_CONSTVAL_DWE_ == 0) wire dwe = 1'b0;
+    else wire dwe = DWE;
+  endgenerate
+
+  // The substituted cell
+  PLLE2_ADV_VPR #(
+      // Inverters
+      .INV_CLKINSEL(INV_CLKINSEL),
+      .ZINV_PWRDWN (INV_PWRDWN),
+      .ZINV_RST    (INV_RST),
+
+      // Straight mapped parameters
+      .STARTUP_WAIT(STARTUP_WAIT == "TRUE"),
+
+      // Lookup tables
+      .LKTABLE(pll_lktable_lookup(CLKFBOUT_MULT)),
+      .TABLE  (pll_table_lookup(CLKFBOUT_MULT, BANDWIDTH)),
+
+      // FIXME: How to compute values the two below ?
+      .FILTREG1_RESERVED(12'b0000_00001000),
+      .LOCKREG3_RESERVED(1'b1),
+
+      // Clock feedback settings
+      .CLKFBOUT_CLKOUT1_HIGH_TIME (CLKFBOUT_REGS[11:6]),
+      .CLKFBOUT_CLKOUT1_LOW_TIME  (CLKFBOUT_REGS[5:0]),
+      .CLKFBOUT_CLKOUT1_PHASE_MUX (CLKFBOUT_REGS[15:13]),
+      .CLKFBOUT_CLKOUT2_DELAY_TIME(CLKFBOUT_REGS[21:16]),
+      .CLKFBOUT_CLKOUT2_EDGE      (CLKFBOUT_REGS[23]),
+      .CLKFBOUT_CLKOUT2_NO_COUNT  (CLKFBOUT_REGS[22]),
+
+      // Internal VCO divider settings
+      .DIVCLK_DIVCLK_HIGH_TIME(DIVCLK_REGS[11:6]),
+      .DIVCLK_DIVCLK_LOW_TIME (DIVCLK_REGS[5:0]),
+      .DIVCLK_DIVCLK_NO_COUNT (DIVCLK_REGS[22]),
+      .DIVCLK_DIVCLK_EDGE     (DIVCLK_REGS[23]),
+
+      // CLKOUT0
+      .CLKOUT0_CLKOUT1_HIGH_TIME (CLKOUT0_REGS[11:6]),
+      .CLKOUT0_CLKOUT1_LOW_TIME  (CLKOUT0_REGS[5:0]),
+      .CLKOUT0_CLKOUT1_PHASE_MUX (CLKOUT0_REGS[15:13]),
+      .CLKOUT0_CLKOUT2_DELAY_TIME(CLKOUT0_REGS[21:16]),
+      .CLKOUT0_CLKOUT2_EDGE      (CLKOUT0_REGS[23]),
+      .CLKOUT0_CLKOUT2_NO_COUNT  (CLKOUT0_REGS[22]),
+
+      // CLKOUT1
+      .CLKOUT1_CLKOUT1_HIGH_TIME (CLKOUT1_REGS[11:6]),
+      .CLKOUT1_CLKOUT1_LOW_TIME  (CLKOUT1_REGS[5:0]),
+      .CLKOUT1_CLKOUT1_PHASE_MUX (CLKOUT1_REGS[15:13]),
+      .CLKOUT1_CLKOUT2_DELAY_TIME(CLKOUT1_REGS[21:16]),
+      .CLKOUT1_CLKOUT2_EDGE      (CLKOUT1_REGS[23]),
+      .CLKOUT1_CLKOUT2_NO_COUNT  (CLKOUT1_REGS[22]),
+
+      // CLKOUT2
+      .CLKOUT2_CLKOUT1_HIGH_TIME (CLKOUT2_REGS[11:6]),
+      .CLKOUT2_CLKOUT1_LOW_TIME  (CLKOUT2_REGS[5:0]),
+      .CLKOUT2_CLKOUT1_PHASE_MUX (CLKOUT2_REGS[15:13]),
+      .CLKOUT2_CLKOUT2_DELAY_TIME(CLKOUT2_REGS[21:16]),
+      .CLKOUT2_CLKOUT2_EDGE      (CLKOUT2_REGS[23]),
+      .CLKOUT2_CLKOUT2_NO_COUNT  (CLKOUT2_REGS[22]),
+
+      // CLKOUT3
+      .CLKOUT3_CLKOUT1_HIGH_TIME (CLKOUT3_REGS[11:6]),
+      .CLKOUT3_CLKOUT1_LOW_TIME  (CLKOUT3_REGS[5:0]),
+      .CLKOUT3_CLKOUT1_PHASE_MUX (CLKOUT3_REGS[15:13]),
+      .CLKOUT3_CLKOUT2_DELAY_TIME(CLKOUT3_REGS[21:16]),
+      .CLKOUT3_CLKOUT2_EDGE      (CLKOUT3_REGS[23]),
+      .CLKOUT3_CLKOUT2_NO_COUNT  (CLKOUT3_REGS[22]),
+
+      // CLKOUT4
+      .CLKOUT4_CLKOUT1_HIGH_TIME (CLKOUT4_REGS[11:6]),
+      .CLKOUT4_CLKOUT1_LOW_TIME  (CLKOUT4_REGS[5:0]),
+      .CLKOUT4_CLKOUT1_PHASE_MUX (CLKOUT4_REGS[15:13]),
+      .CLKOUT4_CLKOUT2_DELAY_TIME(CLKOUT4_REGS[21:16]),
+      .CLKOUT4_CLKOUT2_EDGE      (CLKOUT4_REGS[23]),
+      .CLKOUT4_CLKOUT2_NO_COUNT  (CLKOUT4_REGS[22]),
+
+      // CLKOUT5
+      .CLKOUT5_CLKOUT1_HIGH_TIME (CLKOUT5_REGS[11:6]),
+      .CLKOUT5_CLKOUT1_LOW_TIME  (CLKOUT5_REGS[5:0]),
+      .CLKOUT5_CLKOUT1_PHASE_MUX (CLKOUT5_REGS[15:13]),
+      .CLKOUT5_CLKOUT2_DELAY_TIME(CLKOUT5_REGS[21:16]),
+      .CLKOUT5_CLKOUT2_EDGE      (CLKOUT5_REGS[23]),
+      .CLKOUT5_CLKOUT2_NO_COUNT  (CLKOUT5_REGS[22]),
+
+      // Clock output enable controls
+      .CLKFBOUT_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKFBOUT_ === 1'bX),
+
+      .CLKOUT0_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT0_ === 1'bX),
+      .CLKOUT1_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT1_ === 1'bX),
+      .CLKOUT2_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT2_ === 1'bX),
+      .CLKOUT3_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT3_ === 1'bX),
+      .CLKOUT4_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT4_ === 1'bX),
+      .CLKOUT5_CLKOUT1_OUTPUT_ENABLE(_TECHMAP_CONSTVAL_CLKOUT5_ === 1'bX)
+  ) _TECHMAP_REPLACE_ (
+      .CLKFBIN (CLKFBIN),
+      .CLKIN1  (CLKIN1),
+      .CLKIN2  (CLKIN2),
+      .CLKFBOUT(CLKFBOUT),
+      .CLKOUT0 (CLKOUT0),
+      .CLKOUT1 (CLKOUT1),
+      .CLKOUT2 (CLKOUT2),
+      .CLKOUT3 (CLKOUT3),
+      .CLKOUT4 (CLKOUT4),
+      .CLKOUT5 (CLKOUT5),
+
+      .CLKINSEL(clkinsel),
+
+      .PWRDWN(pwrdwn),
+      .RST   (rst),
+      .LOCKED(LOCKED),
+
+      .DCLK (dclk),
+      .DEN  (den),
+      .DWE  (dwe),
+      .DRDY (DRDY),
+      .DADDR(DADDR),
+      .DI   (DI),
+      .DO   (DO)
+  );
+
+endmodule
+
+// PLLE2_BASE
+module PLLE2_BASE (
+    input CLKFBIN,
+    input CLKIN,
+
+    output CLKFBOUT,
+    output CLKOUT0,
+    output CLKOUT1,
+    output CLKOUT2,
+    output CLKOUT3,
+    output CLKOUT4,
+    output CLKOUT5,
+
+    input  RST,
+    output LOCKED
+);
+
+  parameter IS_CLKINSEL_INVERTED = 1'b0;
+  parameter IS_RST_INVERTED = 1'b0;
+
+  parameter BANDWIDTH = "OPTIMIZED";
+  parameter STARTUP_WAIT = "FALSE";
+
+  parameter CLKIN1_PERIOD = 0.0;
+  parameter REF_JITTER1 = 0.1;
+
+  parameter [5:0] DIVCLK_DIVIDE = 1;
+
+  parameter [5:0] CLKFBOUT_MULT = 1;
+  parameter signed CLKFBOUT_PHASE = 0;
+
+  parameter [6:0] CLKOUT0_DIVIDE = 1;
+  parameter CLKOUT0_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT0_PHASE = 0;
+
+  parameter [6:0] CLKOUT1_DIVIDE = 1;
+  parameter CLKOUT1_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT1_PHASE = 0;
+
+  parameter [6:0] CLKOUT2_DIVIDE = 1;
+  parameter CLKOUT2_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT2_PHASE = 0;
+
+  parameter [6:0] CLKOUT3_DIVIDE = 1;
+  parameter CLKOUT3_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT3_PHASE = 0;
+
+  parameter [6:0] CLKOUT4_DIVIDE = 1;
+  parameter CLKOUT4_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT4_PHASE = 0;
+
+  parameter [6:0] CLKOUT5_DIVIDE = 1;
+  parameter CLKOUT5_DUTY_CYCLE = 50000;
+  parameter signed CLKOUT5_PHASE = 0;
+
+  // The substituted cell
+  PLLE2_ADV #(
+      .IS_CLKINSEL_INVERTED(IS_CLKINSEL_INVERTED),
+      .IS_RST_INVERTED(IS_RST_INVERTED),
+      .IS_PWRDWN_INVERTED(1'b0),
+
+      .BANDWIDTH(BANDWIDTH),
+      .STARTUP_WAIT(STARTUP_WAIT),
+
+      .CLKIN1_PERIOD(CLKIN1_PERIOD),
+      .REF_JITTER1  (REF_JITTER1),
+
+      .DIVCLK_DIVIDE(DIVCLK_DIVIDE),
+
+      .CLKFBOUT_MULT (CLKFBOUT_MULT),
+      .CLKFBOUT_PHASE(CLKFBOUT_PHASE),
+
+      .CLKOUT0_DIVIDE(CLKOUT0_DIVIDE),
+      .CLKOUT0_DUTY_CYCLE(CLKOUT0_DUTY_CYCLE),
+      .CLKOUT0_PHASE(CLKOUT0_PHASE),
+
+      .CLKOUT1_DIVIDE(CLKOUT1_DIVIDE),
+      .CLKOUT1_DUTY_CYCLE(CLKOUT1_DUTY_CYCLE),
+      .CLKOUT1_PHASE(CLKOUT1_PHASE),
+
+      .CLKOUT2_DIVIDE(CLKOUT2_DIVIDE),
+      .CLKOUT2_DUTY_CYCLE(CLKOUT2_DUTY_CYCLE),
+      .CLKOUT2_PHASE(CLKOUT2_PHASE),
+
+      .CLKOUT3_DIVIDE(CLKOUT3_DIVIDE),
+      .CLKOUT3_DUTY_CYCLE(CLKOUT3_DUTY_CYCLE),
+      .CLKOUT3_PHASE(CLKOUT3_PHASE),
+
+      .CLKOUT4_DIVIDE(CLKOUT4_DIVIDE),
+      .CLKOUT4_DUTY_CYCLE(CLKOUT4_DUTY_CYCLE),
+      .CLKOUT4_PHASE(CLKOUT4_PHASE),
+
+      .CLKOUT5_DIVIDE(CLKOUT5_DIVIDE),
+      .CLKOUT5_DUTY_CYCLE(CLKOUT5_DUTY_CYCLE),
+      .CLKOUT5_PHASE(CLKOUT5_PHASE)
+  ) _TECHMAP_REPLACE_ (
+      .CLKFBIN (CLKFBIN),
+      .CLKIN1  (CLKIN),
+      .CLKINSEL(1'b1),
+
+      .CLKFBOUT(CLKFBOUT),
+      .CLKOUT0 (CLKOUT0),
+      .CLKOUT1 (CLKOUT1),
+      .CLKOUT2 (CLKOUT2),
+      .CLKOUT3 (CLKOUT3),
+      .CLKOUT4 (CLKOUT4),
+      .CLKOUT5 (CLKOUT5),
+
+      .PWRDWN(1'b0),
+      .RST(RST),
+      .LOCKED(LOCKED),
+
+      .DCLK(1'b0),
+      .DEN(1'b0),
+      .DWE(1'b0),
+      .DRDY(),
+      .DADDR(7'd0),
+      .DI(16'd0),
+      .DO()
+  );
+
+endmodule
diff --git a/yosys-plugins/params/tests/pll/techmaps/cells_sim.v b/yosys-plugins/params/tests/pll/techmaps/cells_sim.v
new file mode 100644
index 000000000..aa842f101
--- /dev/null
+++ b/yosys-plugins/params/tests/pll/techmaps/cells_sim.v
@@ -0,0 +1,160 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+// ============================================================================
+// CMT
+
+// PLLE2_ADV_VPR
+(* blackbox *)
+module PLLE2_ADV_VPR (
+    input CLKFBIN,
+    input CLKIN1,
+    input CLKIN2,
+    input CLKINSEL,
+
+    output CLKFBOUT,
+    output CLKOUT0,
+    output CLKOUT1,
+    output CLKOUT2,
+    output CLKOUT3,
+    output CLKOUT4,
+    output CLKOUT5,
+
+    input  PWRDWN,
+    input  RST,
+    output LOCKED,
+
+    input         DCLK,
+    input         DEN,
+    input         DWE,
+    output        DRDY,
+    input  [ 6:0] DADDR,
+    input  [15:0] DI,
+    output [15:0] DO
+);
+
+  parameter [0:0] INV_CLKINSEL = 1'd0;
+  parameter [0:0] ZINV_PWRDWN = 1'd0;
+  parameter [0:0] ZINV_RST = 1'd1;
+
+  parameter [0:0] STARTUP_WAIT = 1'd0;
+
+  // Tables
+  parameter [9:0] TABLE = 10'd0;
+  parameter [39:0] LKTABLE = 40'd0;
+  parameter [15:0] POWER_REG = 16'd0;
+  parameter [11:0] FILTREG1_RESERVED = 12'd0;
+  parameter [9:0] FILTREG2_RESERVED = 10'd0;
+  parameter [5:0] LOCKREG1_RESERVED = 6'd0;
+  parameter [0:0] LOCKREG2_RESERVED = 1'b0;
+  parameter [0:0] LOCKREG3_RESERVED = 1'b0;
+
+  // DIVCLK
+  parameter [5:0] DIVCLK_DIVCLK_HIGH_TIME = 6'd0;
+  parameter [5:0] DIVCLK_DIVCLK_LOW_TIME = 6'd0;
+  parameter [0:0] DIVCLK_DIVCLK_NO_COUNT = 1'b1;
+  parameter [0:0] DIVCLK_DIVCLK_EDGE = 1'b0;
+
+  // CLKFBOUT
+  parameter [5:0] CLKFBOUT_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKFBOUT_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKFBOUT_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKFBOUT_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKFBOUT_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKFBOUT_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKFBOUT_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKFBOUT_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKFBOUT_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKFBOUT_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT0
+  parameter [5:0] CLKOUT0_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT0_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT0_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT0_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT0_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT0_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT0_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT0_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT0_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT0_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT1
+  parameter [5:0] CLKOUT1_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT1_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT1_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT1_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT1_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT1_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT1_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT1_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT1_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT1_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT2
+  parameter [5:0] CLKOUT2_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT2_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT2_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT2_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT2_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT2_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT2_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT2_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT2_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT2_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT3
+  parameter [5:0] CLKOUT3_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT3_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT3_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT3_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT3_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT3_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT3_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT3_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT3_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT3_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT4
+  parameter [5:0] CLKOUT4_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT4_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT4_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT4_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT4_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT4_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT4_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT4_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT4_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT4_CLKOUT2_NO_COUNT = 1'b1;
+
+  // CLKOUT5
+  parameter [5:0] CLKOUT5_CLKOUT1_HIGH_TIME = 6'd0;
+  parameter [5:0] CLKOUT5_CLKOUT1_LOW_TIME = 6'd0;
+  parameter [0:0] CLKOUT5_CLKOUT1_OUTPUT_ENABLE = 1'b0;
+  parameter [2:0] CLKOUT5_CLKOUT1_PHASE_MUX = 3'd0;
+  parameter [5:0] CLKOUT5_CLKOUT2_DELAY_TIME = 6'd0;
+  parameter [0:0] CLKOUT5_CLKOUT2_EDGE = 1'b0;
+  parameter [2:0] CLKOUT5_CLKOUT2_FRAC = 3'd0;
+  parameter [0:0] CLKOUT5_CLKOUT2_FRAC_EN = 1'b0;
+  parameter [0:0] CLKOUT5_CLKOUT2_FRAC_WF_R = 1'b0;
+  parameter [0:0] CLKOUT5_CLKOUT2_NO_COUNT = 1'b1;
+
+
+  // TODO: Compensation parameters
+
+  // TODO: How to simulate a PLL in verilog (i.e. the VCO) ???
+
+endmodule
diff --git a/yosys-plugins/ql-iob/Makefile b/yosys-plugins/ql-iob/Makefile
new file mode 100644
index 000000000..dc8975705
--- /dev/null
+++ b/yosys-plugins/ql-iob/Makefile
@@ -0,0 +1,19 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = ql-iob
+SOURCES = ql-iob.cc pcf_parser.cc pinmap_parser.cc
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/ql-iob/README.md b/yosys-plugins/ql-iob/README.md
new file mode 100644
index 000000000..8e3e85a82
--- /dev/null
+++ b/yosys-plugins/ql-iob/README.md
@@ -0,0 +1,11 @@
+# QuickLogic IO buffer plugin
+
+This plugin allows to annotate IO buffer cells with information from IO placement constraints. This is required to determine at the netlist level what types of IO buffers have to be used where.
+
+The plugin reads IO constraints from a PCF file and a board pinmap from a pinmap CSV file. The pinmap file should contain the followin columns: `name`, `x`, `y` and `type` (optional). Basing on this information each IO cell has the following parameters set:
+
+- IO_PAD - Name of the IO pad,
+- IO_LOC - Location of the IO pad (eg. "X10Y20"),
+- IO_TYPE - Type of the IO buffer (to be used inside techmap).
+
+See the plugin's help for more details.
diff --git a/yosys-plugins/ql-iob/pcf_parser.cc b/yosys-plugins/ql-iob/pcf_parser.cc
new file mode 100644
index 000000000..dfcad9e54
--- /dev/null
+++ b/yosys-plugins/ql-iob/pcf_parser.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "pcf_parser.hh"
+
+#include <regex>
+
+// ============================================================================
+
+bool PcfParser::parse(const std::string &a_FileName)
+{
+
+    // Open the file
+    std::ifstream file(a_FileName.c_str());
+
+    // Parse it
+    return parse(file);
+}
+
+const std::vector<PcfParser::Constraint> PcfParser::getConstraints() const { return m_Constraints; }
+
+// ============================================================================
+
+bool PcfParser::parse(std::ifstream &a_Stream)
+{
+
+    if (!a_Stream.good()) {
+        return false;
+    }
+
+    // Clear constraints
+    m_Constraints.clear();
+
+    // Parse PCF lines
+    std::regex re("^\\s*set_io\\s+([^#\\s]+)\\s+([^#\\s]+)(?:\\s+#(.*))?");
+
+    while (a_Stream.good()) {
+        std::string line;
+        std::getline(a_Stream, line);
+
+        // Match against regex
+        std::cmatch cm;
+        if (std::regex_match(line.c_str(), cm, re)) {
+            m_Constraints.push_back(Constraint(cm[1].str(), cm[2].str(), cm[3].str()));
+        }
+    }
+
+    return true;
+}
diff --git a/yosys-plugins/ql-iob/pcf_parser.hh b/yosys-plugins/ql-iob/pcf_parser.hh
new file mode 100644
index 000000000..7324ee369
--- /dev/null
+++ b/yosys-plugins/ql-iob/pcf_parser.hh
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef PCF_PARSER_HH
+#define PCF_PARSER_HH
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+// ============================================================================
+
+class PcfParser {
+public:
+
+    /// A constraint
+    struct Constraint {
+
+        const std::string netName;
+        const std::string padName;
+        const std::string comment;
+
+        Constraint () = default;
+
+        Constraint (
+            const std::string& a_NetName,
+            const std::string& a_PadName,
+            const std::string& a_Comment = std::string()
+        ) : netName(a_NetName), padName(a_PadName), comment(a_Comment) {}
+    };
+
+    /// Constructor
+    PcfParser () = default;
+
+    /// Parses a PCF file and stores constraint within the class instance.
+    /// Returns false in case of error
+    bool parse (const std::string& a_FileName);
+    bool parse (std::ifstream& a_Stream);
+
+    /// Returns the constraint list
+    const std::vector<Constraint> getConstraints () const;
+
+private:
+
+    /// A list of constraints
+    std::vector<Constraint> m_Constraints;
+};
+
+#endif // PCF_PARSER_HH
diff --git a/yosys-plugins/ql-iob/pinmap_parser.cc b/yosys-plugins/ql-iob/pinmap_parser.cc
new file mode 100644
index 000000000..8f228ffdd
--- /dev/null
+++ b/yosys-plugins/ql-iob/pinmap_parser.cc
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "pinmap_parser.hh"
+
+#include <sstream>
+
+// ============================================================================
+
+bool PinmapParser::parse(const std::string &a_FileName)
+{
+
+    // Open the file
+    std::ifstream file(a_FileName.c_str());
+
+    // Parse it
+    return parse(file);
+}
+
+const std::vector<PinmapParser::Entry> PinmapParser::getEntries() const { return m_Entries; }
+
+// ============================================================================
+
+std::vector<std::string> PinmapParser::getFields(const std::string &a_String)
+{
+
+    std::vector<std::string> fields;
+    std::stringstream ss(a_String);
+
+    while (ss.good()) {
+        std::string field;
+        std::getline(ss, field, ',');
+
+        fields.push_back(field);
+    }
+
+    return fields;
+}
+
+bool PinmapParser::parseHeader(std::ifstream &a_Stream)
+{
+
+    // Get the header line
+    std::string header;
+    std::getline(a_Stream, header);
+
+    // Parse fields
+    m_Fields = getFields(header);
+    if (m_Fields.empty()) {
+        return false;
+    }
+
+    return true;
+}
+
+bool PinmapParser::parseData(std::ifstream &a_Stream)
+{
+
+    // Parse lines as they come
+    while (a_Stream.good()) {
+        std::string line;
+        std::getline(a_Stream, line);
+
+        if (line.empty()) {
+            continue;
+        }
+
+        // Parse datafields
+        auto data = getFields(line);
+
+        // Assign data fields to columns
+        Entry entry;
+        for (size_t i = 0; i < data.size(); ++i) {
+
+            if (i >= m_Fields.size()) {
+                return false;
+            }
+
+            entry[m_Fields[i]] = data[i];
+        }
+
+        m_Entries.push_back(entry);
+    }
+
+    return true;
+}
+
+bool PinmapParser::parse(std::ifstream &a_Stream)
+{
+
+    if (!a_Stream.good()) {
+        return false;
+    }
+
+    // Clear pinmap entries
+    m_Entries.clear();
+
+    // Parse header
+    if (!parseHeader(a_Stream)) {
+        return false;
+    }
+    // Parse data fields
+    if (!parseData(a_Stream)) {
+        return false;
+    }
+
+    return true;
+}
diff --git a/yosys-plugins/ql-iob/pinmap_parser.hh b/yosys-plugins/ql-iob/pinmap_parser.hh
new file mode 100644
index 000000000..781ca834b
--- /dev/null
+++ b/yosys-plugins/ql-iob/pinmap_parser.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#ifndef PINMAP_PARSER_HH
+#define PINMAP_PARSER_HH
+
+#include <fstream>
+#include <string>
+#include <vector>
+#include <map>
+
+// ============================================================================
+
+class PinmapParser {
+public:
+
+    /// A pinmap entry type
+    typedef std::map<std::string, std::string> Entry;
+
+    /// Constructor
+    PinmapParser () = default;
+
+    /// Parses a pinmap CSV file
+    bool parse (const std::string& a_FileName);
+    bool parse (std::ifstream& a_Stream);
+
+    /// Returns a vector of entries
+    const std::vector<Entry> getEntries() const;
+
+private:
+
+    /// Splits the input string into a vector of fields. Fields are comma
+    /// separated.
+    static std::vector<std::string> getFields (const std::string& a_String);
+
+    /// Parses the header
+    bool parseHeader (std::ifstream& a_Stream);
+    /// Parses the data
+    bool parseData   (std::ifstream& a_Stream);
+
+    /// Header fields
+    std::vector<std::string> m_Fields;
+    /// A list of entries
+    std::vector<Entry> m_Entries;
+};
+
+#endif // PINMAP_PARSER_HH
diff --git a/yosys-plugins/ql-iob/ql-iob.cc b/yosys-plugins/ql-iob/ql-iob.cc
new file mode 100644
index 000000000..cc36304fc
--- /dev/null
+++ b/yosys-plugins/ql-iob/ql-iob.cc
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "pcf_parser.hh"
+#include "pinmap_parser.hh"
+
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+#include <regex>
+#include <sstream>
+
+#ifndef YS_OVERRIDE
+#define YS_OVERRIDE override
+#endif
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct QuicklogicIob : public Pass {
+
+    struct IoCellType {
+        std::string type;                        // Cell type
+        std::string port;                        // Name of the port that goes to a pad
+        std::vector<std::string> preferredTypes; // A list of preferred IO cell types
+
+        IoCellType(const std::string &_type, const std::string &_port, const std::vector<std::string> _preferredTypes = std::vector<std::string>())
+            : type(_type), port(_port), preferredTypes(_preferredTypes)
+        {
+        }
+    };
+
+    QuicklogicIob() : Pass("quicklogic_iob", "Map IO buffers to cells that correspond to their assigned locations") {}
+
+    void help() YS_OVERRIDE
+    {
+        log("\n");
+        log("    quicklogic_iob <PCF file> <pinmap file> [<io cell specs>]");
+        log("\n");
+        log("This command assigns certain parameters of the specified IO cell types\n");
+        log("basing on the placement constraints and the pin map of the target device\n");
+        log("\n");
+        log("Each affected IO cell is assigned the followin parameters:\n");
+        log(" - IO_PAD  = \"<IO pad name>\"\n");
+        log(" - IO_LOC  = \"<IO cell location>\"\n");
+        log(" - IO_CELL = \"<IO cell type>\"\n");
+        log("\n");
+        log("Parameters:\n");
+        log("\n");
+        log("    - <PCF file>\n");
+        log("        Path to a PCF file with IO constraints for the design\n");
+        log("\n");
+        log("    - <pinmap file>\n");
+        log("        Path to a pinmap CSV file with package pin map\n");
+        log("\n");
+        log("    - <io cell specs> (optional)\n");
+        log("        A space-separated list of <io cell type>:<port> or of\n");
+        log("        <io cell type>:<port>:<preferred type 1>,<preferred type 2>...\n");
+        log("        Each entry defines a type of IO cell to be affected an its port\n");
+        log("        name that should connect to the top-level port of the design.\n");
+        log("\n");
+        log("        The third argument is a comma-separated list of preferred IO cell\n");
+        log("        types in order of preference.\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) YS_OVERRIDE
+    {
+        if (a_Args.size() < 3) {
+            log_cmd_error("    Usage: quicklogic_iob <PCF file> <pinmap file> [<io cell specs>]");
+        }
+
+        // A map of IO cell types and their port names that should go to a pad
+        std::unordered_map<std::string, IoCellType> ioCellTypes;
+
+        // Parse io cell specification
+        if (a_Args.size() > 3) {
+
+            // FIXME: Are these characters set the only ones that can be in
+            // cell / port name ?
+            std::regex re1("^([\\w$]+):([\\w$]+)$");
+            std::regex re2("^([\\w$]+):([\\w$]+):([\\w,$]+)$");
+
+            for (size_t i = 3; i < a_Args.size(); ++i) {
+                std::cmatch cm;
+
+                // No preffered IO cell types
+                if (std::regex_match(a_Args[i].c_str(), cm, re1)) {
+                    ioCellTypes.emplace(cm[1].str(), IoCellType(cm[1], cm[2]));
+                }
+
+                // With preferred IO cell types
+                else if (std::regex_match(a_Args[i].c_str(), cm, re2)) {
+                    std::vector<std::string> preferredTypes;
+                    std::stringstream ss(cm[3]);
+
+                    while (ss.good()) {
+                        std::string field;
+                        std::getline(ss, field, ',');
+
+                        preferredTypes.push_back(field);
+                    }
+
+                    ioCellTypes.emplace(cm[1].str(), IoCellType(cm[1], cm[2], preferredTypes));
+                }
+
+                // Invalid
+                else {
+                    log_cmd_error("Invalid IO cell+port spec: '%s'\n", a_Args[i].c_str());
+                }
+            }
+        }
+
+        // Use the default IO cells for QuickLogic FPGAs
+        else {
+            ioCellTypes.emplace("inpad", IoCellType("inpad", "P", {"BIDIR", "SDIOMUX"}));
+            ioCellTypes.emplace("outpad", IoCellType("outpad", "P", {"BIDIR", "SDIOMUX"}));
+            ioCellTypes.emplace("bipad", IoCellType("bipad", "P", {"BIDIR", "SDIOMUX"}));
+            ioCellTypes.emplace("ckpad", IoCellType("ckpad", "P", {"CLOCK", "BIDIR", "SDIOMUX"}));
+        }
+
+        // Get the top module of the design
+        RTLIL::Module *topModule = a_Design->top_module();
+        if (topModule == nullptr) {
+            log_cmd_error("No top module detected!\n");
+        }
+
+        // Read and parse the PCF file
+        log("Loading PCF from '%s'...\n", a_Args[1].c_str());
+        auto pcfParser = PcfParser();
+        if (!pcfParser.parse(a_Args[1])) {
+            log_cmd_error("Failed to parse the PCF file!\n");
+        }
+
+        // Build a map of net names to constraints
+        std::unordered_map<std::string, const PcfParser::Constraint> constraintMap;
+        for (auto &constraint : pcfParser.getConstraints()) {
+            if (constraintMap.count(constraint.netName) != 0) {
+                log_cmd_error("The net '%s' is constrained twice!", constraint.netName.c_str());
+            }
+            constraintMap.emplace(constraint.netName, constraint);
+        }
+
+        // Read and parse pinmap CSV file
+        log("Loading pinmap CSV from '%s'...\n", a_Args[2].c_str());
+        auto pinmapParser = PinmapParser();
+        if (!pinmapParser.parse(a_Args[2])) {
+            log_cmd_error("Failed to parse the pinmap CSV file!\n");
+        }
+
+        // Build a map of pad names to entries
+        std::unordered_map<std::string, std::vector<PinmapParser::Entry>> pinmapMap;
+        for (auto &entry : pinmapParser.getEntries()) {
+            if (entry.count("name") != 0) {
+                auto &name = entry.at("name");
+
+                if (pinmapMap.count(name) == 0) {
+                    pinmapMap[name] = std::vector<PinmapParser::Entry>();
+                }
+
+                pinmapMap[name].push_back(entry);
+            }
+        }
+
+        // Check all IO cells
+        log("Processing cells...");
+        log("\n");
+        log("  type       | net        | pad        | loc      | type     | instance\n");
+        log(" ------------+------------+------------+----------+----------+-----------\n");
+        for (auto cell : topModule->cells()) {
+            auto ysCellType = RTLIL::unescape_id(cell->type);
+
+            // Not an IO cell
+            if (ioCellTypes.count(ysCellType) == 0) {
+                continue;
+            }
+
+            log("  %-10s ", ysCellType.c_str());
+
+            std::string netName;
+            std::string padName;
+            std::string locName;
+            std::string cellType;
+
+            // Get connections to the specified port
+            const auto &ioCellType = ioCellTypes.at(ysCellType);
+            const std::string port = RTLIL::escape_id(ioCellType.port);
+            if (cell->connections().count(port)) {
+
+                // Get the sigspec of the connection
+                auto sigspec = cell->connections().at(port);
+
+                // Get the connected wire
+                for (auto sigbit : sigspec.bits()) {
+                    if (sigbit.wire != nullptr) {
+                        auto wire = sigbit.wire;
+
+                        // Has to be top level wire
+                        if (wire->port_input || wire->port_output) {
+
+                            // Check if the wire is constrained. Get pad name.
+                            std::string baseName = RTLIL::unescape_id(wire->name);
+                            std::string netNames[] = {
+                              baseName,
+                              stringf("%s[%d]", baseName.c_str(), sigbit.offset),
+                              stringf("%s(%d)", baseName.c_str(), sigbit.offset),
+                            };
+
+                            padName = "";
+                            netName = "";
+
+                            for (auto &name : netNames) {
+                                if (constraintMap.count(name)) {
+                                    auto constraint = constraintMap.at(name);
+                                    padName = constraint.padName;
+                                    netName = name;
+                                    break;
+                                }
+                            }
+
+                            // Check if there is an entry in the pinmap for this pad name
+                            if (pinmapMap.count(padName)) {
+
+                                // Choose a correct entry for the cell
+                                auto entry = choosePinmapEntry(pinmapMap.at(padName), ioCellType);
+
+                                // Location string
+                                if (entry.count("x") && entry.count("y")) {
+                                    locName = stringf("X%sY%s", entry.at("x").c_str(), entry.at("y").c_str());
+                                }
+
+                                // Cell type
+                                if (entry.count("type")) {
+                                    cellType = entry.at("type");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            log("| %-10s | %-10s | %-8s | %-8s | %s\n", netName.c_str(), padName.c_str(), locName.c_str(), cellType.c_str(), cell->name.c_str());
+
+            // Annotate the cell by setting its parameters
+            cell->setParam(RTLIL::escape_id("IO_PAD"), padName);
+            cell->setParam(RTLIL::escape_id("IO_LOC"), locName);
+            cell->setParam(RTLIL::escape_id("IO_TYPE"), cellType);
+        }
+    }
+
+    PinmapParser::Entry choosePinmapEntry(const std::vector<PinmapParser::Entry> &a_Entries, const IoCellType &a_IoCellType)
+    {
+        // No preferred types, pick the first one
+        if (a_IoCellType.preferredTypes.empty()) {
+            return a_Entries[0];
+        }
+
+        // Loop over preferred types
+        for (auto &type : a_IoCellType.preferredTypes) {
+
+            // Find an entry for that type. If found then return it.
+            for (auto &entry : a_Entries) {
+                if (type == entry.at("type")) {
+                    return entry;
+                }
+            }
+        }
+
+        // No preferred type was found, pick the first one.
+        return a_Entries[0];
+    }
+
+} QuicklogicIob;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-iob/tests/.gitignore b/yosys-plugins/ql-iob/tests/.gitignore
new file mode 100644
index 000000000..744eec9c3
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/.gitignore
@@ -0,0 +1,2 @@
+*.eblif
+ok
diff --git a/yosys-plugins/ql-iob/tests/Makefile b/yosys-plugins/ql-iob/tests/Makefile
new file mode 100644
index 000000000..5e6bc92aa
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/Makefile
@@ -0,0 +1,29 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = sdiomux ckpad
+
+all: clean $(addsuffix /ok,$(TESTS))
+
+clean:
+	@find . -name "ok" | xargs rm -rf
+
+sdiomux/ok:
+	@$(MAKE) -C sdiomux test
+ckpad/ok:
+	@$(MAKE) -C ckpad test
+
+.PHONY: all clean
diff --git a/yosys-plugins/ql-iob/tests/ckpad/Makefile b/yosys-plugins/ql-iob/tests/ckpad/Makefile
new file mode 100644
index 000000000..9a2e2d3c3
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/ckpad/Makefile
@@ -0,0 +1,21 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# TODO: Integrate this in the Makefile_test.command environment ?
+test:
+	@yosys -s script.ys -q -q -l $@.log
+	@printf "Test %-18s \e[32mPASSED\e[0m @ %s\n" $@ $(CURDIR);
+	@touch ok
diff --git a/yosys-plugins/ql-iob/tests/ckpad/design.pcf b/yosys-plugins/ql-iob/tests/ckpad/design.pcf
new file mode 100644
index 000000000..00563c565
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/ckpad/design.pcf
@@ -0,0 +1,14 @@
+set_io clk0 B3 # to a BIDIR
+set_io clk1 A3 # to a BIDIR/CLOCK 
+set_io clk2 B4 # to a BIDIR
+set_io clk3 C4 # to a BIDIR/CLOCK
+
+set_io d(0) C1
+set_io d(1) A1
+set_io d(2) A2
+set_io d(3) B2
+
+set_io q(0) B5
+set_io q(1) D6
+set_io q(2) A5
+set_io q(3) C6
diff --git a/yosys-plugins/ql-iob/tests/ckpad/design.v b/yosys-plugins/ql-iob/tests/ckpad/design.v
new file mode 100644
index 000000000..e717ac928
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/ckpad/design.v
@@ -0,0 +1,34 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input wire clk0,
+    input wire clk1,
+    (* clkbuf_inhibit *)
+    input wire clk2,
+    (* clkbuf_inhibit *)
+    input wire clk3,
+
+    input  wire [3:0] d,
+    output reg  [3:0] q
+);
+
+  always @(posedge clk0) q[0] <= d[0];
+  always @(posedge clk1) q[1] <= d[1];
+  always @(posedge clk2) q[2] <= d[2];
+  always @(posedge clk3) q[3] <= d[3];
+
+endmodule
diff --git a/yosys-plugins/ql-iob/tests/ckpad/script.ys b/yosys-plugins/ql-iob/tests/ckpad/script.ys
new file mode 100644
index 000000000..b5b87139d
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/ckpad/script.ys
@@ -0,0 +1,25 @@
+plugin -i ql-iob
+read_verilog design.v
+
+# Generic synthesis
+synth -lut 4 -flatten -auto-top
+
+# Techmap
+read_verilog -lib ../common/pp3_cells_sim.v
+techmap -map ../common/pp3_cells_map.v
+
+# Insert QuickLogic specific IOBs and clock buffers
+clkbufmap -buf $_BUF_ Y:A -inpad ckpad Q:P
+iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top
+opt_clean
+
+stat
+
+quicklogic_iob design.pcf ../pinmap.csv
+
+select r:IO_TYPE=BIDIR   -assert-count 11
+select r:IO_TYPE=CLOCK   -assert-count 1
+select r:IO_TYPE=SDIOMUX -assert-count 0
+select r:IO_TYPE=        -assert-count 0
+
+write_blif -attr -param -cname design.eblif
diff --git a/yosys-plugins/ql-iob/tests/common/pp3_cells_map.v b/yosys-plugins/ql-iob/tests/common/pp3_cells_map.v
new file mode 100644
index 000000000..2b9592e08
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/common/pp3_cells_map.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$_DFF_P_ (
+    D,
+    Q,
+    C
+);
+  input D;
+  input C;
+  output Q;
+  dff _TECHMAP_REPLACE_ (
+      .Q  (Q),
+      .D  (D),
+      .CLK(C)
+  );
+endmodule
+
diff --git a/yosys-plugins/ql-iob/tests/common/pp3_cells_sim.v b/yosys-plugins/ql-iob/tests/common/pp3_cells_sim.v
new file mode 100644
index 000000000..8167f4705
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/common/pp3_cells_sim.v
@@ -0,0 +1,63 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module inpad (
+    output Q,
+    (* iopad_external_pin *)
+    input  P
+);
+  assign Q = P;
+endmodule
+
+module outpad (
+    (* iopad_external_pin *)
+    output P,
+    input  A
+);
+  assign P = A;
+endmodule
+
+module ckpad (
+    output Q,
+    (* iopad_external_pin *)
+    input  P
+);
+  assign Q = P;
+endmodule
+
+module bipad (
+    input  A,
+    input  EN,
+    output Q,
+    (* iopad_external_pin *)
+    inout  P
+);
+  assign Q = P;
+  assign P = EN ? A : 1'bz;
+endmodule
+
+
+module dff (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+  always @(posedge CLK) Q <= D;
+endmodule
+
diff --git a/yosys-plugins/ql-iob/tests/pinmap.csv b/yosys-plugins/ql-iob/tests/pinmap.csv
new file mode 100644
index 000000000..c7edb1723
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/pinmap.csv
@@ -0,0 +1,52 @@
+name,x,y,z,type
+B1,4,3,0,BIDIR
+C1,6,3,0,BIDIR
+A1,8,3,0,BIDIR
+A2,10,3,0,BIDIR
+B2,12,3,0,BIDIR
+C3,14,3,0,BIDIR
+B3,16,3,0,BIDIR
+A3,18,2,0,CLOCK
+A3,18,3,0,BIDIR
+C4,20,2,0,CLOCK
+C4,20,3,0,BIDIR
+B4,22,3,0,BIDIR
+A4,24,3,0,BIDIR
+C5,26,3,0,BIDIR
+B5,28,3,0,BIDIR
+D6,30,3,0,BIDIR
+A5,32,3,0,BIDIR
+C6,34,3,0,BIDIR
+E7,34,32,0,BIDIR
+D7,32,32,0,BIDIR
+E8,30,32,0,BIDIR
+H8,28,32,0,BIDIR
+G8,26,32,0,BIDIR
+H7,24,32,0,BIDIR
+G7,22,33,0,CLOCK
+G7,22,32,0,BIDIR
+H6,20,32,0,BIDIR
+H6,20,33,0,CLOCK
+G6,18,32,0,BIDIR
+G6,18,33,0,CLOCK
+F7,16,32,0,BIDIR
+F6,14,32,0,BIDIR
+H5,12,32,0,BIDIR
+G5,10,32,0,BIDIR
+F5,8,32,0,BIDIR
+F4,6,32,0,BIDIR
+G4,4,32,0,BIDIR
+H4,3,31,0,SDIOMUX
+E3,2,31,0,SDIOMUX
+F3,1,31,0,SDIOMUX
+F2,3,30,0,SDIOMUX
+H3,2,30,0,SDIOMUX
+G2,1,30,0,SDIOMUX
+E2,3,29,0,SDIOMUX
+H2,2,29,0,SDIOMUX
+D2,1,29,0,SDIOMUX
+F1,3,28,0,SDIOMUX
+H1,2,28,0,SDIOMUX
+D1,1,28,0,SDIOMUX
+E1,3,27,0,SDIOMUX
+G1,2,27,0,SDIOMUX
diff --git a/yosys-plugins/ql-iob/tests/sdiomux/Makefile b/yosys-plugins/ql-iob/tests/sdiomux/Makefile
new file mode 100644
index 000000000..9a2e2d3c3
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/sdiomux/Makefile
@@ -0,0 +1,21 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# TODO: Integrate this in the Makefile_test.command environment ?
+test:
+	@yosys -s script.ys -q -q -l $@.log
+	@printf "Test %-18s \e[32mPASSED\e[0m @ %s\n" $@ $(CURDIR);
+	@touch ok
diff --git a/yosys-plugins/ql-iob/tests/sdiomux/design.pcf b/yosys-plugins/ql-iob/tests/sdiomux/design.pcf
new file mode 100644
index 000000000..9aa05514b
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/sdiomux/design.pcf
@@ -0,0 +1,5 @@
+set_io clk    B1
+set_io led(0) C1
+set_io led(1) A1
+set_io led(2) H3
+set_io led(3) E3
diff --git a/yosys-plugins/ql-iob/tests/sdiomux/design.v b/yosys-plugins/ql-iob/tests/sdiomux/design.v
new file mode 100644
index 000000000..e7e49769e
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/sdiomux/design.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input  wire       clk,
+    output wire [3:0] led,
+    inout  wire       io
+);
+
+  reg [3:0] r;
+  initial r <= 0;
+
+  always @(posedge clk) r <= r + io;
+
+  assign led = {r[0], r[1], r[2], r[3]};
+  assign io  = r[0] ? 1 : 1'bz;
+
+endmodule
diff --git a/yosys-plugins/ql-iob/tests/sdiomux/script.ys b/yosys-plugins/ql-iob/tests/sdiomux/script.ys
new file mode 100644
index 000000000..0af0a0e8e
--- /dev/null
+++ b/yosys-plugins/ql-iob/tests/sdiomux/script.ys
@@ -0,0 +1,24 @@
+plugin -i ql-iob
+read_verilog design.v
+
+# Generic synthesis
+synth -lut 4 -flatten -auto-top
+
+# Techmap
+read_verilog -lib ../common/pp3_cells_sim.v
+techmap -map ../common/pp3_cells_map.v
+
+# Insert QuickLogic specific IOBs and clock buffers
+clkbufmap -buf $_BUF_ Y:A -inpad ckpad Q:P
+iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top
+opt_clean
+
+stat
+
+quicklogic_iob design.pcf ../pinmap.csv
+
+select r:IO_TYPE=BIDIR   -assert-count 3
+select r:IO_TYPE=SDIOMUX -assert-count 2
+select r:IO_TYPE=        -assert-count 1
+
+write_blif -attr -param -cname design.eblif
diff --git a/yosys-plugins/ql-qlf/Makefile b/yosys-plugins/ql-qlf/Makefile
new file mode 100644
index 000000000..b0411b847
--- /dev/null
+++ b/yosys-plugins/ql-qlf/Makefile
@@ -0,0 +1,104 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = ql-qlf
+SOURCES = synth_quicklogic.cc \
+          ql-dsp.cc \
+          pp3_braminit.cc \
+          quicklogic_eqn.cc \
+          ql-edif.cc \
+          ql-dsp-simd.cc \
+          ql-dsp-macc.cc \
+          ql-bram-split.cc \
+          ql-dsp-io-regs.cc \
+          ql-bram-asymmetric.cc
+
+DEPS = pmgen/ql-dsp-pm.h \
+       pmgen/ql-dsp-macc.h \
+       pmgen/ql-bram-asymmetric-wider-write.h \
+       pmgen/ql-bram-asymmetric-wider-read.h
+
+include ../Makefile_plugin.common
+
+COMMON          = common
+QLF_K4N8_DIR    = qlf_k4n8
+QLF_K6N10_DIR   = qlf_k6n10
+QLF_K6N10F_DIR  = qlf_k6n10f
+PP3_DIR         = pp3
+VERILOG_MODULES = $(COMMON)/cells_sim.v         \
+                  $(QLF_K4N8_DIR)/arith_map.v   \
+                  $(QLF_K4N8_DIR)/cells_sim.v   \
+                  $(QLF_K4N8_DIR)/ffs_map.v     \
+                  $(QLF_K6N10_DIR)/arith_map.v \
+                  $(QLF_K6N10_DIR)/brams_map.v \
+                  $(QLF_K6N10_DIR)/brams.txt   \
+                  $(QLF_K6N10_DIR)/cells_sim.v \
+                  $(QLF_K6N10_DIR)/ffs_map.v   \
+                  $(QLF_K6N10_DIR)/dsp_map.v   \
+                  $(QLF_K6N10_DIR)/lut_map.v   \
+                  $(QLF_K6N10F_DIR)/arith_map.v \
+                  $(QLF_K6N10F_DIR)/brams_map.v \
+                  $(QLF_K6N10F_DIR)/brams_final_map.v \
+                  $(QLF_K6N10F_DIR)/brams.txt   \
+                  $(QLF_K6N10F_DIR)/cells_sim.v \
+                  $(QLF_K6N10F_DIR)/dsp_sim.v \
+                  $(QLF_K6N10F_DIR)/sram1024x18.v \
+                  $(QLF_K6N10F_DIR)/TDP18K_FIFO.v \
+                  $(QLF_K6N10F_DIR)/ufifo_ctl.v \
+                  $(QLF_K6N10F_DIR)/ffs_map.v   \
+                  $(QLF_K6N10F_DIR)/dsp_map.v   \
+                  $(QLF_K6N10F_DIR)/dsp_final_map.v \
+                  $(PP3_DIR)/abc9_map.v    \
+                  $(PP3_DIR)/abc9_model.v  \
+                  $(PP3_DIR)/abc9_unmap.v  \
+                  $(PP3_DIR)/cells_map.v   \
+                  $(PP3_DIR)/cells_sim.v   \
+                  $(PP3_DIR)/ffs_map.v     \
+                  $(PP3_DIR)/latches_map.v \
+                  $(PP3_DIR)/lut_map.v     \
+                  $(PP3_DIR)/lutdefs.txt   \
+                  $(PP3_DIR)/brams_sim.v   \
+                  $(PP3_DIR)/brams_map.v   \
+                  $(PP3_DIR)/brams.txt     \
+                  $(PP3_DIR)/bram_init_8_16.vh \
+                  $(PP3_DIR)/bram_init_32.vh   \
+                  $(PP3_DIR)/qlal4s3b_sim.v    \
+                  $(PP3_DIR)/mult_sim.v        \
+                  $(PP3_DIR)/qlal3_sim.v       \
+
+pmgen:
+	mkdir -p pmgen
+
+pmgen/ql-dsp-pm.h: ../pmgen.py ql_dsp.pmg | pmgen
+	python3 ../pmgen.py -o $@ -p ql_dsp ql_dsp.pmg
+
+pmgen/ql-dsp-macc.h: ../pmgen.py ql-dsp-macc.pmg | pmgen
+	python3 ../pmgen.py -o $@ -p ql_dsp_macc ql-dsp-macc.pmg
+
+pmgen/ql-bram-asymmetric-wider-write.h: ../pmgen.py ql-bram-asymmetric-wider-write.pmg | pmgen
+	python3 ../pmgen.py -o $@ -p ql_bram_asymmetric_wider_write ql-bram-asymmetric-wider-write.pmg
+
+pmgen/ql-bram-asymmetric-wider-read.h: ../pmgen.py ql-bram-asymmetric-wider-read.pmg | pmgen
+	python3 ../pmgen.py -o $@ -p ql_bram_asymmetric_wider_read ql-bram-asymmetric-wider-read.pmg
+
+install_modules: $(VERILOG_MODULES)
+	$(foreach f,$^,install -D $(f) $(DATA_DIR)/quicklogic/$(f);)
+
+install: install_modules
+
+clean:
+	$(MAKE) -f ../Makefile_plugin.common $@
+	rm -rf pmgen
diff --git a/yosys-plugins/ql-qlf/common/cells_sim.v b/yosys-plugins/ql-qlf/common/cells_sim.v
new file mode 100644
index 000000000..95bc86be4
--- /dev/null
+++ b/yosys-plugins/ql-qlf/common/cells_sim.v
@@ -0,0 +1,53 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+
+module inv (
+    output Q,
+    input  A
+);
+  assign Q = A ? 0 : 1;
+endmodule
+
+module buff (
+    output Q,
+    input  A
+);
+  assign Q = A;
+endmodule
+
+module logic_0 (
+    output a
+);
+  assign a = 0;
+endmodule
+
+module logic_1 (
+    output a
+);
+  assign a = 1;
+endmodule
+
+(* blackbox *)
+module gclkbuff (
+    input  A,
+    output Z
+);
+
+  assign Z = A;
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/pp3/abc9_map.v b/yosys-plugins/ql-qlf/pp3/abc9_map.v
new file mode 100644
index 000000000..8b342f64b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/abc9_map.v
@@ -0,0 +1,42 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 file exists to map purely-synchronous flops to ABC9 flops, while 
+// mapping flops with asynchronous-set/clear as boxes, this is because ABC9 
+// doesn't support asynchronous-set/clear flops in sequential synthesis.
+
+module dffepc (
+  output Q,
+  input D,
+  input CLK,
+  input EN,
+  input CLR,
+  input PRE
+);
+
+parameter INIT = 1'b0;
+
+parameter _TECHMAP_CONSTMSK_CLR_ = 1'b0;
+parameter _TECHMAP_CONSTMSK_PRE_ = 1'b0;
+parameter _TECHMAP_CONSTVAL_CLR_ = 1'b0;
+parameter _TECHMAP_CONSTVAL_PRE_ = 1'b0;
+
+if (_TECHMAP_CONSTMSK_CLR_ != 1'b0 && _TECHMAP_CONSTMSK_PRE_ != 1'b0 && _TECHMAP_CONSTVAL_CLR_ == 1'b0 && _TECHMAP_CONSTVAL_PRE_ == 1'b0)
+    $__PP3_DFFEPC_SYNCONLY _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN));
+else
+    wire _TECHMAP_FAIL_ = 1;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/abc9_model.v b/yosys-plugins/ql-qlf/pp3/abc9_model.v
new file mode 100644
index 000000000..a8b03e736
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/abc9_model.v
@@ -0,0 +1,27 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* abc9_flop, lib_whitebox *)
+module $__PP3_DFFEPC_SYNCONLY (
+  output Q,
+  input D,
+  input CLK,
+  input EN,
+);
+
+  dffepc ff (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0));
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/abc9_unmap.v b/yosys-plugins/ql-qlf/pp3/abc9_unmap.v
new file mode 100644
index 000000000..29a1adf0e
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/abc9_unmap.v
@@ -0,0 +1,29 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module $__PP3_DFFEPC_SYNCONLY (
+  output Q,
+  input D,
+  input CLK,
+  input EN,
+);
+
+// For some reason ABC9 adds init attributes to wires even though they were removed before mapping.
+// As a workaround, remove any init attributes that get reintroduced.
+wire _TECHMAP_REMOVEINIT_Q_ = 1;
+
+dffepc _TECHMAP_REPLACE_ (.Q(Q), .D(D), .CLK(CLK), .EN(EN), .PRE(1'b0), .CLR(1'b0));
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/bram_init_32.vh b/yosys-plugins/ql-qlf/pp3/bram_init_32.vh
new file mode 100644
index 000000000..dafaf2555
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/bram_init_32.vh
@@ -0,0 +1,512 @@
+.INIT({1'b0, INIT[2047*8 +: 8], 1'b0, INIT[2046*8 +: 8], 1'b0, INIT[2043*8 +: 8], 1'b0, INIT[2042*8 +: 8], 
+          1'b0, INIT[2039*8 +: 8], 1'b0, INIT[2038*8 +: 8], 1'b0, INIT[2035*8 +: 8], 1'b0, INIT[2034*8 +: 8], 
+          1'b0, INIT[2031*8 +: 8], 1'b0, INIT[2030*8 +: 8], 1'b0, INIT[2027*8 +: 8], 1'b0, INIT[2026*8 +: 8], 
+          1'b0, INIT[2023*8 +: 8], 1'b0, INIT[2022*8 +: 8], 1'b0, INIT[2019*8 +: 8], 1'b0, INIT[2018*8 +: 8], 
+          1'b0, INIT[2015*8 +: 8], 1'b0, INIT[2014*8 +: 8], 1'b0, INIT[2011*8 +: 8], 1'b0, INIT[2010*8 +: 8], 
+          1'b0, INIT[2007*8 +: 8], 1'b0, INIT[2006*8 +: 8], 1'b0, INIT[2003*8 +: 8], 1'b0, INIT[2002*8 +: 8], 
+          1'b0, INIT[1999*8 +: 8], 1'b0, INIT[1998*8 +: 8], 1'b0, INIT[1995*8 +: 8], 1'b0, INIT[1994*8 +: 8], 
+          1'b0, INIT[1991*8 +: 8], 1'b0, INIT[1990*8 +: 8], 1'b0, INIT[1987*8 +: 8], 1'b0, INIT[1986*8 +: 8], 
+          1'b0, INIT[1983*8 +: 8], 1'b0, INIT[1982*8 +: 8], 1'b0, INIT[1979*8 +: 8], 1'b0, INIT[1978*8 +: 8], 
+          1'b0, INIT[1975*8 +: 8], 1'b0, INIT[1974*8 +: 8], 1'b0, INIT[1971*8 +: 8], 1'b0, INIT[1970*8 +: 8], 
+          1'b0, INIT[1967*8 +: 8], 1'b0, INIT[1966*8 +: 8], 1'b0, INIT[1963*8 +: 8], 1'b0, INIT[1962*8 +: 8], 
+          1'b0, INIT[1959*8 +: 8], 1'b0, INIT[1958*8 +: 8], 1'b0, INIT[1955*8 +: 8], 1'b0, INIT[1954*8 +: 8], 
+          1'b0, INIT[1951*8 +: 8], 1'b0, INIT[1950*8 +: 8], 1'b0, INIT[1947*8 +: 8], 1'b0, INIT[1946*8 +: 8], 
+          1'b0, INIT[1943*8 +: 8], 1'b0, INIT[1942*8 +: 8], 1'b0, INIT[1939*8 +: 8], 1'b0, INIT[1938*8 +: 8], 
+          1'b0, INIT[1935*8 +: 8], 1'b0, INIT[1934*8 +: 8], 1'b0, INIT[1931*8 +: 8], 1'b0, INIT[1930*8 +: 8], 
+          1'b0, INIT[1927*8 +: 8], 1'b0, INIT[1926*8 +: 8], 1'b0, INIT[1923*8 +: 8], 1'b0, INIT[1922*8 +: 8], 
+          1'b0, INIT[1919*8 +: 8], 1'b0, INIT[1918*8 +: 8], 1'b0, INIT[1915*8 +: 8], 1'b0, INIT[1914*8 +: 8], 
+          1'b0, INIT[1911*8 +: 8], 1'b0, INIT[1910*8 +: 8], 1'b0, INIT[1907*8 +: 8], 1'b0, INIT[1906*8 +: 8], 
+          1'b0, INIT[1903*8 +: 8], 1'b0, INIT[1902*8 +: 8], 1'b0, INIT[1899*8 +: 8], 1'b0, INIT[1898*8 +: 8], 
+          1'b0, INIT[1895*8 +: 8], 1'b0, INIT[1894*8 +: 8], 1'b0, INIT[1891*8 +: 8], 1'b0, INIT[1890*8 +: 8], 
+          1'b0, INIT[1887*8 +: 8], 1'b0, INIT[1886*8 +: 8], 1'b0, INIT[1883*8 +: 8], 1'b0, INIT[1882*8 +: 8], 
+          1'b0, INIT[1879*8 +: 8], 1'b0, INIT[1878*8 +: 8], 1'b0, INIT[1875*8 +: 8], 1'b0, INIT[1874*8 +: 8], 
+          1'b0, INIT[1871*8 +: 8], 1'b0, INIT[1870*8 +: 8], 1'b0, INIT[1867*8 +: 8], 1'b0, INIT[1866*8 +: 8], 
+          1'b0, INIT[1863*8 +: 8], 1'b0, INIT[1862*8 +: 8], 1'b0, INIT[1859*8 +: 8], 1'b0, INIT[1858*8 +: 8], 
+          1'b0, INIT[1855*8 +: 8], 1'b0, INIT[1854*8 +: 8], 1'b0, INIT[1851*8 +: 8], 1'b0, INIT[1850*8 +: 8], 
+          1'b0, INIT[1847*8 +: 8], 1'b0, INIT[1846*8 +: 8], 1'b0, INIT[1843*8 +: 8], 1'b0, INIT[1842*8 +: 8], 
+          1'b0, INIT[1839*8 +: 8], 1'b0, INIT[1838*8 +: 8], 1'b0, INIT[1835*8 +: 8], 1'b0, INIT[1834*8 +: 8], 
+          1'b0, INIT[1831*8 +: 8], 1'b0, INIT[1830*8 +: 8], 1'b0, INIT[1827*8 +: 8], 1'b0, INIT[1826*8 +: 8], 
+          1'b0, INIT[1823*8 +: 8], 1'b0, INIT[1822*8 +: 8], 1'b0, INIT[1819*8 +: 8], 1'b0, INIT[1818*8 +: 8], 
+          1'b0, INIT[1815*8 +: 8], 1'b0, INIT[1814*8 +: 8], 1'b0, INIT[1811*8 +: 8], 1'b0, INIT[1810*8 +: 8], 
+          1'b0, INIT[1807*8 +: 8], 1'b0, INIT[1806*8 +: 8], 1'b0, INIT[1803*8 +: 8], 1'b0, INIT[1802*8 +: 8], 
+          1'b0, INIT[1799*8 +: 8], 1'b0, INIT[1798*8 +: 8], 1'b0, INIT[1795*8 +: 8], 1'b0, INIT[1794*8 +: 8], 
+          1'b0, INIT[1791*8 +: 8], 1'b0, INIT[1790*8 +: 8], 1'b0, INIT[1787*8 +: 8], 1'b0, INIT[1786*8 +: 8], 
+          1'b0, INIT[1783*8 +: 8], 1'b0, INIT[1782*8 +: 8], 1'b0, INIT[1779*8 +: 8], 1'b0, INIT[1778*8 +: 8], 
+          1'b0, INIT[1775*8 +: 8], 1'b0, INIT[1774*8 +: 8], 1'b0, INIT[1771*8 +: 8], 1'b0, INIT[1770*8 +: 8], 
+          1'b0, INIT[1767*8 +: 8], 1'b0, INIT[1766*8 +: 8], 1'b0, INIT[1763*8 +: 8], 1'b0, INIT[1762*8 +: 8], 
+          1'b0, INIT[1759*8 +: 8], 1'b0, INIT[1758*8 +: 8], 1'b0, INIT[1755*8 +: 8], 1'b0, INIT[1754*8 +: 8], 
+          1'b0, INIT[1751*8 +: 8], 1'b0, INIT[1750*8 +: 8], 1'b0, INIT[1747*8 +: 8], 1'b0, INIT[1746*8 +: 8], 
+          1'b0, INIT[1743*8 +: 8], 1'b0, INIT[1742*8 +: 8], 1'b0, INIT[1739*8 +: 8], 1'b0, INIT[1738*8 +: 8], 
+          1'b0, INIT[1735*8 +: 8], 1'b0, INIT[1734*8 +: 8], 1'b0, INIT[1731*8 +: 8], 1'b0, INIT[1730*8 +: 8], 
+          1'b0, INIT[1727*8 +: 8], 1'b0, INIT[1726*8 +: 8], 1'b0, INIT[1723*8 +: 8], 1'b0, INIT[1722*8 +: 8], 
+          1'b0, INIT[1719*8 +: 8], 1'b0, INIT[1718*8 +: 8], 1'b0, INIT[1715*8 +: 8], 1'b0, INIT[1714*8 +: 8], 
+          1'b0, INIT[1711*8 +: 8], 1'b0, INIT[1710*8 +: 8], 1'b0, INIT[1707*8 +: 8], 1'b0, INIT[1706*8 +: 8], 
+          1'b0, INIT[1703*8 +: 8], 1'b0, INIT[1702*8 +: 8], 1'b0, INIT[1699*8 +: 8], 1'b0, INIT[1698*8 +: 8], 
+          1'b0, INIT[1695*8 +: 8], 1'b0, INIT[1694*8 +: 8], 1'b0, INIT[1691*8 +: 8], 1'b0, INIT[1690*8 +: 8], 
+          1'b0, INIT[1687*8 +: 8], 1'b0, INIT[1686*8 +: 8], 1'b0, INIT[1683*8 +: 8], 1'b0, INIT[1682*8 +: 8], 
+          1'b0, INIT[1679*8 +: 8], 1'b0, INIT[1678*8 +: 8], 1'b0, INIT[1675*8 +: 8], 1'b0, INIT[1674*8 +: 8], 
+          1'b0, INIT[1671*8 +: 8], 1'b0, INIT[1670*8 +: 8], 1'b0, INIT[1667*8 +: 8], 1'b0, INIT[1666*8 +: 8], 
+          1'b0, INIT[1663*8 +: 8], 1'b0, INIT[1662*8 +: 8], 1'b0, INIT[1659*8 +: 8], 1'b0, INIT[1658*8 +: 8], 
+          1'b0, INIT[1655*8 +: 8], 1'b0, INIT[1654*8 +: 8], 1'b0, INIT[1651*8 +: 8], 1'b0, INIT[1650*8 +: 8], 
+          1'b0, INIT[1647*8 +: 8], 1'b0, INIT[1646*8 +: 8], 1'b0, INIT[1643*8 +: 8], 1'b0, INIT[1642*8 +: 8], 
+          1'b0, INIT[1639*8 +: 8], 1'b0, INIT[1638*8 +: 8], 1'b0, INIT[1635*8 +: 8], 1'b0, INIT[1634*8 +: 8], 
+          1'b0, INIT[1631*8 +: 8], 1'b0, INIT[1630*8 +: 8], 1'b0, INIT[1627*8 +: 8], 1'b0, INIT[1626*8 +: 8], 
+          1'b0, INIT[1623*8 +: 8], 1'b0, INIT[1622*8 +: 8], 1'b0, INIT[1619*8 +: 8], 1'b0, INIT[1618*8 +: 8], 
+          1'b0, INIT[1615*8 +: 8], 1'b0, INIT[1614*8 +: 8], 1'b0, INIT[1611*8 +: 8], 1'b0, INIT[1610*8 +: 8], 
+          1'b0, INIT[1607*8 +: 8], 1'b0, INIT[1606*8 +: 8], 1'b0, INIT[1603*8 +: 8], 1'b0, INIT[1602*8 +: 8], 
+          1'b0, INIT[1599*8 +: 8], 1'b0, INIT[1598*8 +: 8], 1'b0, INIT[1595*8 +: 8], 1'b0, INIT[1594*8 +: 8], 
+          1'b0, INIT[1591*8 +: 8], 1'b0, INIT[1590*8 +: 8], 1'b0, INIT[1587*8 +: 8], 1'b0, INIT[1586*8 +: 8], 
+          1'b0, INIT[1583*8 +: 8], 1'b0, INIT[1582*8 +: 8], 1'b0, INIT[1579*8 +: 8], 1'b0, INIT[1578*8 +: 8], 
+          1'b0, INIT[1575*8 +: 8], 1'b0, INIT[1574*8 +: 8], 1'b0, INIT[1571*8 +: 8], 1'b0, INIT[1570*8 +: 8], 
+          1'b0, INIT[1567*8 +: 8], 1'b0, INIT[1566*8 +: 8], 1'b0, INIT[1563*8 +: 8], 1'b0, INIT[1562*8 +: 8], 
+          1'b0, INIT[1559*8 +: 8], 1'b0, INIT[1558*8 +: 8], 1'b0, INIT[1555*8 +: 8], 1'b0, INIT[1554*8 +: 8], 
+          1'b0, INIT[1551*8 +: 8], 1'b0, INIT[1550*8 +: 8], 1'b0, INIT[1547*8 +: 8], 1'b0, INIT[1546*8 +: 8], 
+          1'b0, INIT[1543*8 +: 8], 1'b0, INIT[1542*8 +: 8], 1'b0, INIT[1539*8 +: 8], 1'b0, INIT[1538*8 +: 8], 
+          1'b0, INIT[1535*8 +: 8], 1'b0, INIT[1534*8 +: 8], 1'b0, INIT[1531*8 +: 8], 1'b0, INIT[1530*8 +: 8], 
+          1'b0, INIT[1527*8 +: 8], 1'b0, INIT[1526*8 +: 8], 1'b0, INIT[1523*8 +: 8], 1'b0, INIT[1522*8 +: 8], 
+          1'b0, INIT[1519*8 +: 8], 1'b0, INIT[1518*8 +: 8], 1'b0, INIT[1515*8 +: 8], 1'b0, INIT[1514*8 +: 8], 
+          1'b0, INIT[1511*8 +: 8], 1'b0, INIT[1510*8 +: 8], 1'b0, INIT[1507*8 +: 8], 1'b0, INIT[1506*8 +: 8], 
+          1'b0, INIT[1503*8 +: 8], 1'b0, INIT[1502*8 +: 8], 1'b0, INIT[1499*8 +: 8], 1'b0, INIT[1498*8 +: 8], 
+          1'b0, INIT[1495*8 +: 8], 1'b0, INIT[1494*8 +: 8], 1'b0, INIT[1491*8 +: 8], 1'b0, INIT[1490*8 +: 8], 
+          1'b0, INIT[1487*8 +: 8], 1'b0, INIT[1486*8 +: 8], 1'b0, INIT[1483*8 +: 8], 1'b0, INIT[1482*8 +: 8], 
+          1'b0, INIT[1479*8 +: 8], 1'b0, INIT[1478*8 +: 8], 1'b0, INIT[1475*8 +: 8], 1'b0, INIT[1474*8 +: 8], 
+          1'b0, INIT[1471*8 +: 8], 1'b0, INIT[1470*8 +: 8], 1'b0, INIT[1467*8 +: 8], 1'b0, INIT[1466*8 +: 8], 
+          1'b0, INIT[1463*8 +: 8], 1'b0, INIT[1462*8 +: 8], 1'b0, INIT[1459*8 +: 8], 1'b0, INIT[1458*8 +: 8], 
+          1'b0, INIT[1455*8 +: 8], 1'b0, INIT[1454*8 +: 8], 1'b0, INIT[1451*8 +: 8], 1'b0, INIT[1450*8 +: 8], 
+          1'b0, INIT[1447*8 +: 8], 1'b0, INIT[1446*8 +: 8], 1'b0, INIT[1443*8 +: 8], 1'b0, INIT[1442*8 +: 8], 
+          1'b0, INIT[1439*8 +: 8], 1'b0, INIT[1438*8 +: 8], 1'b0, INIT[1435*8 +: 8], 1'b0, INIT[1434*8 +: 8], 
+          1'b0, INIT[1431*8 +: 8], 1'b0, INIT[1430*8 +: 8], 1'b0, INIT[1427*8 +: 8], 1'b0, INIT[1426*8 +: 8], 
+          1'b0, INIT[1423*8 +: 8], 1'b0, INIT[1422*8 +: 8], 1'b0, INIT[1419*8 +: 8], 1'b0, INIT[1418*8 +: 8], 
+          1'b0, INIT[1415*8 +: 8], 1'b0, INIT[1414*8 +: 8], 1'b0, INIT[1411*8 +: 8], 1'b0, INIT[1410*8 +: 8], 
+          1'b0, INIT[1407*8 +: 8], 1'b0, INIT[1406*8 +: 8], 1'b0, INIT[1403*8 +: 8], 1'b0, INIT[1402*8 +: 8], 
+          1'b0, INIT[1399*8 +: 8], 1'b0, INIT[1398*8 +: 8], 1'b0, INIT[1395*8 +: 8], 1'b0, INIT[1394*8 +: 8], 
+          1'b0, INIT[1391*8 +: 8], 1'b0, INIT[1390*8 +: 8], 1'b0, INIT[1387*8 +: 8], 1'b0, INIT[1386*8 +: 8], 
+          1'b0, INIT[1383*8 +: 8], 1'b0, INIT[1382*8 +: 8], 1'b0, INIT[1379*8 +: 8], 1'b0, INIT[1378*8 +: 8], 
+          1'b0, INIT[1375*8 +: 8], 1'b0, INIT[1374*8 +: 8], 1'b0, INIT[1371*8 +: 8], 1'b0, INIT[1370*8 +: 8], 
+          1'b0, INIT[1367*8 +: 8], 1'b0, INIT[1366*8 +: 8], 1'b0, INIT[1363*8 +: 8], 1'b0, INIT[1362*8 +: 8], 
+          1'b0, INIT[1359*8 +: 8], 1'b0, INIT[1358*8 +: 8], 1'b0, INIT[1355*8 +: 8], 1'b0, INIT[1354*8 +: 8], 
+          1'b0, INIT[1351*8 +: 8], 1'b0, INIT[1350*8 +: 8], 1'b0, INIT[1347*8 +: 8], 1'b0, INIT[1346*8 +: 8], 
+          1'b0, INIT[1343*8 +: 8], 1'b0, INIT[1342*8 +: 8], 1'b0, INIT[1339*8 +: 8], 1'b0, INIT[1338*8 +: 8], 
+          1'b0, INIT[1335*8 +: 8], 1'b0, INIT[1334*8 +: 8], 1'b0, INIT[1331*8 +: 8], 1'b0, INIT[1330*8 +: 8], 
+          1'b0, INIT[1327*8 +: 8], 1'b0, INIT[1326*8 +: 8], 1'b0, INIT[1323*8 +: 8], 1'b0, INIT[1322*8 +: 8], 
+          1'b0, INIT[1319*8 +: 8], 1'b0, INIT[1318*8 +: 8], 1'b0, INIT[1315*8 +: 8], 1'b0, INIT[1314*8 +: 8], 
+          1'b0, INIT[1311*8 +: 8], 1'b0, INIT[1310*8 +: 8], 1'b0, INIT[1307*8 +: 8], 1'b0, INIT[1306*8 +: 8], 
+          1'b0, INIT[1303*8 +: 8], 1'b0, INIT[1302*8 +: 8], 1'b0, INIT[1299*8 +: 8], 1'b0, INIT[1298*8 +: 8], 
+          1'b0, INIT[1295*8 +: 8], 1'b0, INIT[1294*8 +: 8], 1'b0, INIT[1291*8 +: 8], 1'b0, INIT[1290*8 +: 8], 
+          1'b0, INIT[1287*8 +: 8], 1'b0, INIT[1286*8 +: 8], 1'b0, INIT[1283*8 +: 8], 1'b0, INIT[1282*8 +: 8], 
+          1'b0, INIT[1279*8 +: 8], 1'b0, INIT[1278*8 +: 8], 1'b0, INIT[1275*8 +: 8], 1'b0, INIT[1274*8 +: 8], 
+          1'b0, INIT[1271*8 +: 8], 1'b0, INIT[1270*8 +: 8], 1'b0, INIT[1267*8 +: 8], 1'b0, INIT[1266*8 +: 8], 
+          1'b0, INIT[1263*8 +: 8], 1'b0, INIT[1262*8 +: 8], 1'b0, INIT[1259*8 +: 8], 1'b0, INIT[1258*8 +: 8], 
+          1'b0, INIT[1255*8 +: 8], 1'b0, INIT[1254*8 +: 8], 1'b0, INIT[1251*8 +: 8], 1'b0, INIT[1250*8 +: 8], 
+          1'b0, INIT[1247*8 +: 8], 1'b0, INIT[1246*8 +: 8], 1'b0, INIT[1243*8 +: 8], 1'b0, INIT[1242*8 +: 8], 
+          1'b0, INIT[1239*8 +: 8], 1'b0, INIT[1238*8 +: 8], 1'b0, INIT[1235*8 +: 8], 1'b0, INIT[1234*8 +: 8], 
+          1'b0, INIT[1231*8 +: 8], 1'b0, INIT[1230*8 +: 8], 1'b0, INIT[1227*8 +: 8], 1'b0, INIT[1226*8 +: 8], 
+          1'b0, INIT[1223*8 +: 8], 1'b0, INIT[1222*8 +: 8], 1'b0, INIT[1219*8 +: 8], 1'b0, INIT[1218*8 +: 8], 
+          1'b0, INIT[1215*8 +: 8], 1'b0, INIT[1214*8 +: 8], 1'b0, INIT[1211*8 +: 8], 1'b0, INIT[1210*8 +: 8], 
+          1'b0, INIT[1207*8 +: 8], 1'b0, INIT[1206*8 +: 8], 1'b0, INIT[1203*8 +: 8], 1'b0, INIT[1202*8 +: 8], 
+          1'b0, INIT[1199*8 +: 8], 1'b0, INIT[1198*8 +: 8], 1'b0, INIT[1195*8 +: 8], 1'b0, INIT[1194*8 +: 8], 
+          1'b0, INIT[1191*8 +: 8], 1'b0, INIT[1190*8 +: 8], 1'b0, INIT[1187*8 +: 8], 1'b0, INIT[1186*8 +: 8], 
+          1'b0, INIT[1183*8 +: 8], 1'b0, INIT[1182*8 +: 8], 1'b0, INIT[1179*8 +: 8], 1'b0, INIT[1178*8 +: 8], 
+          1'b0, INIT[1175*8 +: 8], 1'b0, INIT[1174*8 +: 8], 1'b0, INIT[1171*8 +: 8], 1'b0, INIT[1170*8 +: 8], 
+          1'b0, INIT[1167*8 +: 8], 1'b0, INIT[1166*8 +: 8], 1'b0, INIT[1163*8 +: 8], 1'b0, INIT[1162*8 +: 8], 
+          1'b0, INIT[1159*8 +: 8], 1'b0, INIT[1158*8 +: 8], 1'b0, INIT[1155*8 +: 8], 1'b0, INIT[1154*8 +: 8], 
+          1'b0, INIT[1151*8 +: 8], 1'b0, INIT[1150*8 +: 8], 1'b0, INIT[1147*8 +: 8], 1'b0, INIT[1146*8 +: 8], 
+          1'b0, INIT[1143*8 +: 8], 1'b0, INIT[1142*8 +: 8], 1'b0, INIT[1139*8 +: 8], 1'b0, INIT[1138*8 +: 8], 
+          1'b0, INIT[1135*8 +: 8], 1'b0, INIT[1134*8 +: 8], 1'b0, INIT[1131*8 +: 8], 1'b0, INIT[1130*8 +: 8], 
+          1'b0, INIT[1127*8 +: 8], 1'b0, INIT[1126*8 +: 8], 1'b0, INIT[1123*8 +: 8], 1'b0, INIT[1122*8 +: 8], 
+          1'b0, INIT[1119*8 +: 8], 1'b0, INIT[1118*8 +: 8], 1'b0, INIT[1115*8 +: 8], 1'b0, INIT[1114*8 +: 8], 
+          1'b0, INIT[1111*8 +: 8], 1'b0, INIT[1110*8 +: 8], 1'b0, INIT[1107*8 +: 8], 1'b0, INIT[1106*8 +: 8], 
+          1'b0, INIT[1103*8 +: 8], 1'b0, INIT[1102*8 +: 8], 1'b0, INIT[1099*8 +: 8], 1'b0, INIT[1098*8 +: 8], 
+          1'b0, INIT[1095*8 +: 8], 1'b0, INIT[1094*8 +: 8], 1'b0, INIT[1091*8 +: 8], 1'b0, INIT[1090*8 +: 8], 
+          1'b0, INIT[1087*8 +: 8], 1'b0, INIT[1086*8 +: 8], 1'b0, INIT[1083*8 +: 8], 1'b0, INIT[1082*8 +: 8], 
+          1'b0, INIT[1079*8 +: 8], 1'b0, INIT[1078*8 +: 8], 1'b0, INIT[1075*8 +: 8], 1'b0, INIT[1074*8 +: 8], 
+          1'b0, INIT[1071*8 +: 8], 1'b0, INIT[1070*8 +: 8], 1'b0, INIT[1067*8 +: 8], 1'b0, INIT[1066*8 +: 8], 
+          1'b0, INIT[1063*8 +: 8], 1'b0, INIT[1062*8 +: 8], 1'b0, INIT[1059*8 +: 8], 1'b0, INIT[1058*8 +: 8], 
+          1'b0, INIT[1055*8 +: 8], 1'b0, INIT[1054*8 +: 8], 1'b0, INIT[1051*8 +: 8], 1'b0, INIT[1050*8 +: 8], 
+          1'b0, INIT[1047*8 +: 8], 1'b0, INIT[1046*8 +: 8], 1'b0, INIT[1043*8 +: 8], 1'b0, INIT[1042*8 +: 8], 
+          1'b0, INIT[1039*8 +: 8], 1'b0, INIT[1038*8 +: 8], 1'b0, INIT[1035*8 +: 8], 1'b0, INIT[1034*8 +: 8], 
+          1'b0, INIT[1031*8 +: 8], 1'b0, INIT[1030*8 +: 8], 1'b0, INIT[1027*8 +: 8], 1'b0, INIT[1026*8 +: 8], 
+          1'b0, INIT[1023*8 +: 8], 1'b0, INIT[1022*8 +: 8], 1'b0, INIT[1019*8 +: 8], 1'b0, INIT[1018*8 +: 8], 
+          1'b0, INIT[1015*8 +: 8], 1'b0, INIT[1014*8 +: 8], 1'b0, INIT[1011*8 +: 8], 1'b0, INIT[1010*8 +: 8], 
+          1'b0, INIT[1007*8 +: 8], 1'b0, INIT[1006*8 +: 8], 1'b0, INIT[1003*8 +: 8], 1'b0, INIT[1002*8 +: 8], 
+          1'b0, INIT[ 999*8 +: 8], 1'b0, INIT[ 998*8 +: 8], 1'b0, INIT[ 995*8 +: 8], 1'b0, INIT[ 994*8 +: 8], 
+          1'b0, INIT[ 991*8 +: 8], 1'b0, INIT[ 990*8 +: 8], 1'b0, INIT[ 987*8 +: 8], 1'b0, INIT[ 986*8 +: 8], 
+          1'b0, INIT[ 983*8 +: 8], 1'b0, INIT[ 982*8 +: 8], 1'b0, INIT[ 979*8 +: 8], 1'b0, INIT[ 978*8 +: 8], 
+          1'b0, INIT[ 975*8 +: 8], 1'b0, INIT[ 974*8 +: 8], 1'b0, INIT[ 971*8 +: 8], 1'b0, INIT[ 970*8 +: 8], 
+          1'b0, INIT[ 967*8 +: 8], 1'b0, INIT[ 966*8 +: 8], 1'b0, INIT[ 963*8 +: 8], 1'b0, INIT[ 962*8 +: 8], 
+          1'b0, INIT[ 959*8 +: 8], 1'b0, INIT[ 958*8 +: 8], 1'b0, INIT[ 955*8 +: 8], 1'b0, INIT[ 954*8 +: 8], 
+          1'b0, INIT[ 951*8 +: 8], 1'b0, INIT[ 950*8 +: 8], 1'b0, INIT[ 947*8 +: 8], 1'b0, INIT[ 946*8 +: 8], 
+          1'b0, INIT[ 943*8 +: 8], 1'b0, INIT[ 942*8 +: 8], 1'b0, INIT[ 939*8 +: 8], 1'b0, INIT[ 938*8 +: 8], 
+          1'b0, INIT[ 935*8 +: 8], 1'b0, INIT[ 934*8 +: 8], 1'b0, INIT[ 931*8 +: 8], 1'b0, INIT[ 930*8 +: 8], 
+          1'b0, INIT[ 927*8 +: 8], 1'b0, INIT[ 926*8 +: 8], 1'b0, INIT[ 923*8 +: 8], 1'b0, INIT[ 922*8 +: 8], 
+          1'b0, INIT[ 919*8 +: 8], 1'b0, INIT[ 918*8 +: 8], 1'b0, INIT[ 915*8 +: 8], 1'b0, INIT[ 914*8 +: 8], 
+          1'b0, INIT[ 911*8 +: 8], 1'b0, INIT[ 910*8 +: 8], 1'b0, INIT[ 907*8 +: 8], 1'b0, INIT[ 906*8 +: 8], 
+          1'b0, INIT[ 903*8 +: 8], 1'b0, INIT[ 902*8 +: 8], 1'b0, INIT[ 899*8 +: 8], 1'b0, INIT[ 898*8 +: 8], 
+          1'b0, INIT[ 895*8 +: 8], 1'b0, INIT[ 894*8 +: 8], 1'b0, INIT[ 891*8 +: 8], 1'b0, INIT[ 890*8 +: 8], 
+          1'b0, INIT[ 887*8 +: 8], 1'b0, INIT[ 886*8 +: 8], 1'b0, INIT[ 883*8 +: 8], 1'b0, INIT[ 882*8 +: 8], 
+          1'b0, INIT[ 879*8 +: 8], 1'b0, INIT[ 878*8 +: 8], 1'b0, INIT[ 875*8 +: 8], 1'b0, INIT[ 874*8 +: 8], 
+          1'b0, INIT[ 871*8 +: 8], 1'b0, INIT[ 870*8 +: 8], 1'b0, INIT[ 867*8 +: 8], 1'b0, INIT[ 866*8 +: 8], 
+          1'b0, INIT[ 863*8 +: 8], 1'b0, INIT[ 862*8 +: 8], 1'b0, INIT[ 859*8 +: 8], 1'b0, INIT[ 858*8 +: 8], 
+          1'b0, INIT[ 855*8 +: 8], 1'b0, INIT[ 854*8 +: 8], 1'b0, INIT[ 851*8 +: 8], 1'b0, INIT[ 850*8 +: 8], 
+          1'b0, INIT[ 847*8 +: 8], 1'b0, INIT[ 846*8 +: 8], 1'b0, INIT[ 843*8 +: 8], 1'b0, INIT[ 842*8 +: 8], 
+          1'b0, INIT[ 839*8 +: 8], 1'b0, INIT[ 838*8 +: 8], 1'b0, INIT[ 835*8 +: 8], 1'b0, INIT[ 834*8 +: 8], 
+          1'b0, INIT[ 831*8 +: 8], 1'b0, INIT[ 830*8 +: 8], 1'b0, INIT[ 827*8 +: 8], 1'b0, INIT[ 826*8 +: 8], 
+          1'b0, INIT[ 823*8 +: 8], 1'b0, INIT[ 822*8 +: 8], 1'b0, INIT[ 819*8 +: 8], 1'b0, INIT[ 818*8 +: 8], 
+          1'b0, INIT[ 815*8 +: 8], 1'b0, INIT[ 814*8 +: 8], 1'b0, INIT[ 811*8 +: 8], 1'b0, INIT[ 810*8 +: 8], 
+          1'b0, INIT[ 807*8 +: 8], 1'b0, INIT[ 806*8 +: 8], 1'b0, INIT[ 803*8 +: 8], 1'b0, INIT[ 802*8 +: 8], 
+          1'b0, INIT[ 799*8 +: 8], 1'b0, INIT[ 798*8 +: 8], 1'b0, INIT[ 795*8 +: 8], 1'b0, INIT[ 794*8 +: 8], 
+          1'b0, INIT[ 791*8 +: 8], 1'b0, INIT[ 790*8 +: 8], 1'b0, INIT[ 787*8 +: 8], 1'b0, INIT[ 786*8 +: 8], 
+          1'b0, INIT[ 783*8 +: 8], 1'b0, INIT[ 782*8 +: 8], 1'b0, INIT[ 779*8 +: 8], 1'b0, INIT[ 778*8 +: 8], 
+          1'b0, INIT[ 775*8 +: 8], 1'b0, INIT[ 774*8 +: 8], 1'b0, INIT[ 771*8 +: 8], 1'b0, INIT[ 770*8 +: 8], 
+          1'b0, INIT[ 767*8 +: 8], 1'b0, INIT[ 766*8 +: 8], 1'b0, INIT[ 763*8 +: 8], 1'b0, INIT[ 762*8 +: 8], 
+          1'b0, INIT[ 759*8 +: 8], 1'b0, INIT[ 758*8 +: 8], 1'b0, INIT[ 755*8 +: 8], 1'b0, INIT[ 754*8 +: 8], 
+          1'b0, INIT[ 751*8 +: 8], 1'b0, INIT[ 750*8 +: 8], 1'b0, INIT[ 747*8 +: 8], 1'b0, INIT[ 746*8 +: 8], 
+          1'b0, INIT[ 743*8 +: 8], 1'b0, INIT[ 742*8 +: 8], 1'b0, INIT[ 739*8 +: 8], 1'b0, INIT[ 738*8 +: 8], 
+          1'b0, INIT[ 735*8 +: 8], 1'b0, INIT[ 734*8 +: 8], 1'b0, INIT[ 731*8 +: 8], 1'b0, INIT[ 730*8 +: 8], 
+          1'b0, INIT[ 727*8 +: 8], 1'b0, INIT[ 726*8 +: 8], 1'b0, INIT[ 723*8 +: 8], 1'b0, INIT[ 722*8 +: 8], 
+          1'b0, INIT[ 719*8 +: 8], 1'b0, INIT[ 718*8 +: 8], 1'b0, INIT[ 715*8 +: 8], 1'b0, INIT[ 714*8 +: 8], 
+          1'b0, INIT[ 711*8 +: 8], 1'b0, INIT[ 710*8 +: 8], 1'b0, INIT[ 707*8 +: 8], 1'b0, INIT[ 706*8 +: 8], 
+          1'b0, INIT[ 703*8 +: 8], 1'b0, INIT[ 702*8 +: 8], 1'b0, INIT[ 699*8 +: 8], 1'b0, INIT[ 698*8 +: 8], 
+          1'b0, INIT[ 695*8 +: 8], 1'b0, INIT[ 694*8 +: 8], 1'b0, INIT[ 691*8 +: 8], 1'b0, INIT[ 690*8 +: 8], 
+          1'b0, INIT[ 687*8 +: 8], 1'b0, INIT[ 686*8 +: 8], 1'b0, INIT[ 683*8 +: 8], 1'b0, INIT[ 682*8 +: 8], 
+          1'b0, INIT[ 679*8 +: 8], 1'b0, INIT[ 678*8 +: 8], 1'b0, INIT[ 675*8 +: 8], 1'b0, INIT[ 674*8 +: 8], 
+          1'b0, INIT[ 671*8 +: 8], 1'b0, INIT[ 670*8 +: 8], 1'b0, INIT[ 667*8 +: 8], 1'b0, INIT[ 666*8 +: 8], 
+          1'b0, INIT[ 663*8 +: 8], 1'b0, INIT[ 662*8 +: 8], 1'b0, INIT[ 659*8 +: 8], 1'b0, INIT[ 658*8 +: 8], 
+          1'b0, INIT[ 655*8 +: 8], 1'b0, INIT[ 654*8 +: 8], 1'b0, INIT[ 651*8 +: 8], 1'b0, INIT[ 650*8 +: 8], 
+          1'b0, INIT[ 647*8 +: 8], 1'b0, INIT[ 646*8 +: 8], 1'b0, INIT[ 643*8 +: 8], 1'b0, INIT[ 642*8 +: 8], 
+          1'b0, INIT[ 639*8 +: 8], 1'b0, INIT[ 638*8 +: 8], 1'b0, INIT[ 635*8 +: 8], 1'b0, INIT[ 634*8 +: 8], 
+          1'b0, INIT[ 631*8 +: 8], 1'b0, INIT[ 630*8 +: 8], 1'b0, INIT[ 627*8 +: 8], 1'b0, INIT[ 626*8 +: 8], 
+          1'b0, INIT[ 623*8 +: 8], 1'b0, INIT[ 622*8 +: 8], 1'b0, INIT[ 619*8 +: 8], 1'b0, INIT[ 618*8 +: 8], 
+          1'b0, INIT[ 615*8 +: 8], 1'b0, INIT[ 614*8 +: 8], 1'b0, INIT[ 611*8 +: 8], 1'b0, INIT[ 610*8 +: 8], 
+          1'b0, INIT[ 607*8 +: 8], 1'b0, INIT[ 606*8 +: 8], 1'b0, INIT[ 603*8 +: 8], 1'b0, INIT[ 602*8 +: 8], 
+          1'b0, INIT[ 599*8 +: 8], 1'b0, INIT[ 598*8 +: 8], 1'b0, INIT[ 595*8 +: 8], 1'b0, INIT[ 594*8 +: 8], 
+          1'b0, INIT[ 591*8 +: 8], 1'b0, INIT[ 590*8 +: 8], 1'b0, INIT[ 587*8 +: 8], 1'b0, INIT[ 586*8 +: 8], 
+          1'b0, INIT[ 583*8 +: 8], 1'b0, INIT[ 582*8 +: 8], 1'b0, INIT[ 579*8 +: 8], 1'b0, INIT[ 578*8 +: 8], 
+          1'b0, INIT[ 575*8 +: 8], 1'b0, INIT[ 574*8 +: 8], 1'b0, INIT[ 571*8 +: 8], 1'b0, INIT[ 570*8 +: 8], 
+          1'b0, INIT[ 567*8 +: 8], 1'b0, INIT[ 566*8 +: 8], 1'b0, INIT[ 563*8 +: 8], 1'b0, INIT[ 562*8 +: 8], 
+          1'b0, INIT[ 559*8 +: 8], 1'b0, INIT[ 558*8 +: 8], 1'b0, INIT[ 555*8 +: 8], 1'b0, INIT[ 554*8 +: 8], 
+          1'b0, INIT[ 551*8 +: 8], 1'b0, INIT[ 550*8 +: 8], 1'b0, INIT[ 547*8 +: 8], 1'b0, INIT[ 546*8 +: 8], 
+          1'b0, INIT[ 543*8 +: 8], 1'b0, INIT[ 542*8 +: 8], 1'b0, INIT[ 539*8 +: 8], 1'b0, INIT[ 538*8 +: 8], 
+          1'b0, INIT[ 535*8 +: 8], 1'b0, INIT[ 534*8 +: 8], 1'b0, INIT[ 531*8 +: 8], 1'b0, INIT[ 530*8 +: 8], 
+          1'b0, INIT[ 527*8 +: 8], 1'b0, INIT[ 526*8 +: 8], 1'b0, INIT[ 523*8 +: 8], 1'b0, INIT[ 522*8 +: 8], 
+          1'b0, INIT[ 519*8 +: 8], 1'b0, INIT[ 518*8 +: 8], 1'b0, INIT[ 515*8 +: 8], 1'b0, INIT[ 514*8 +: 8], 
+          1'b0, INIT[ 511*8 +: 8], 1'b0, INIT[ 510*8 +: 8], 1'b0, INIT[ 507*8 +: 8], 1'b0, INIT[ 506*8 +: 8], 
+          1'b0, INIT[ 503*8 +: 8], 1'b0, INIT[ 502*8 +: 8], 1'b0, INIT[ 499*8 +: 8], 1'b0, INIT[ 498*8 +: 8], 
+          1'b0, INIT[ 495*8 +: 8], 1'b0, INIT[ 494*8 +: 8], 1'b0, INIT[ 491*8 +: 8], 1'b0, INIT[ 490*8 +: 8], 
+          1'b0, INIT[ 487*8 +: 8], 1'b0, INIT[ 486*8 +: 8], 1'b0, INIT[ 483*8 +: 8], 1'b0, INIT[ 482*8 +: 8], 
+          1'b0, INIT[ 479*8 +: 8], 1'b0, INIT[ 478*8 +: 8], 1'b0, INIT[ 475*8 +: 8], 1'b0, INIT[ 474*8 +: 8], 
+          1'b0, INIT[ 471*8 +: 8], 1'b0, INIT[ 470*8 +: 8], 1'b0, INIT[ 467*8 +: 8], 1'b0, INIT[ 466*8 +: 8], 
+          1'b0, INIT[ 463*8 +: 8], 1'b0, INIT[ 462*8 +: 8], 1'b0, INIT[ 459*8 +: 8], 1'b0, INIT[ 458*8 +: 8], 
+          1'b0, INIT[ 455*8 +: 8], 1'b0, INIT[ 454*8 +: 8], 1'b0, INIT[ 451*8 +: 8], 1'b0, INIT[ 450*8 +: 8], 
+          1'b0, INIT[ 447*8 +: 8], 1'b0, INIT[ 446*8 +: 8], 1'b0, INIT[ 443*8 +: 8], 1'b0, INIT[ 442*8 +: 8], 
+          1'b0, INIT[ 439*8 +: 8], 1'b0, INIT[ 438*8 +: 8], 1'b0, INIT[ 435*8 +: 8], 1'b0, INIT[ 434*8 +: 8], 
+          1'b0, INIT[ 431*8 +: 8], 1'b0, INIT[ 430*8 +: 8], 1'b0, INIT[ 427*8 +: 8], 1'b0, INIT[ 426*8 +: 8], 
+          1'b0, INIT[ 423*8 +: 8], 1'b0, INIT[ 422*8 +: 8], 1'b0, INIT[ 419*8 +: 8], 1'b0, INIT[ 418*8 +: 8], 
+          1'b0, INIT[ 415*8 +: 8], 1'b0, INIT[ 414*8 +: 8], 1'b0, INIT[ 411*8 +: 8], 1'b0, INIT[ 410*8 +: 8], 
+          1'b0, INIT[ 407*8 +: 8], 1'b0, INIT[ 406*8 +: 8], 1'b0, INIT[ 403*8 +: 8], 1'b0, INIT[ 402*8 +: 8], 
+          1'b0, INIT[ 399*8 +: 8], 1'b0, INIT[ 398*8 +: 8], 1'b0, INIT[ 395*8 +: 8], 1'b0, INIT[ 394*8 +: 8], 
+          1'b0, INIT[ 391*8 +: 8], 1'b0, INIT[ 390*8 +: 8], 1'b0, INIT[ 387*8 +: 8], 1'b0, INIT[ 386*8 +: 8], 
+          1'b0, INIT[ 383*8 +: 8], 1'b0, INIT[ 382*8 +: 8], 1'b0, INIT[ 379*8 +: 8], 1'b0, INIT[ 378*8 +: 8], 
+          1'b0, INIT[ 375*8 +: 8], 1'b0, INIT[ 374*8 +: 8], 1'b0, INIT[ 371*8 +: 8], 1'b0, INIT[ 370*8 +: 8], 
+          1'b0, INIT[ 367*8 +: 8], 1'b0, INIT[ 366*8 +: 8], 1'b0, INIT[ 363*8 +: 8], 1'b0, INIT[ 362*8 +: 8], 
+          1'b0, INIT[ 359*8 +: 8], 1'b0, INIT[ 358*8 +: 8], 1'b0, INIT[ 355*8 +: 8], 1'b0, INIT[ 354*8 +: 8], 
+          1'b0, INIT[ 351*8 +: 8], 1'b0, INIT[ 350*8 +: 8], 1'b0, INIT[ 347*8 +: 8], 1'b0, INIT[ 346*8 +: 8], 
+          1'b0, INIT[ 343*8 +: 8], 1'b0, INIT[ 342*8 +: 8], 1'b0, INIT[ 339*8 +: 8], 1'b0, INIT[ 338*8 +: 8], 
+          1'b0, INIT[ 335*8 +: 8], 1'b0, INIT[ 334*8 +: 8], 1'b0, INIT[ 331*8 +: 8], 1'b0, INIT[ 330*8 +: 8], 
+          1'b0, INIT[ 327*8 +: 8], 1'b0, INIT[ 326*8 +: 8], 1'b0, INIT[ 323*8 +: 8], 1'b0, INIT[ 322*8 +: 8], 
+          1'b0, INIT[ 319*8 +: 8], 1'b0, INIT[ 318*8 +: 8], 1'b0, INIT[ 315*8 +: 8], 1'b0, INIT[ 314*8 +: 8], 
+          1'b0, INIT[ 311*8 +: 8], 1'b0, INIT[ 310*8 +: 8], 1'b0, INIT[ 307*8 +: 8], 1'b0, INIT[ 306*8 +: 8], 
+          1'b0, INIT[ 303*8 +: 8], 1'b0, INIT[ 302*8 +: 8], 1'b0, INIT[ 299*8 +: 8], 1'b0, INIT[ 298*8 +: 8], 
+          1'b0, INIT[ 295*8 +: 8], 1'b0, INIT[ 294*8 +: 8], 1'b0, INIT[ 291*8 +: 8], 1'b0, INIT[ 290*8 +: 8], 
+          1'b0, INIT[ 287*8 +: 8], 1'b0, INIT[ 286*8 +: 8], 1'b0, INIT[ 283*8 +: 8], 1'b0, INIT[ 282*8 +: 8], 
+          1'b0, INIT[ 279*8 +: 8], 1'b0, INIT[ 278*8 +: 8], 1'b0, INIT[ 275*8 +: 8], 1'b0, INIT[ 274*8 +: 8], 
+          1'b0, INIT[ 271*8 +: 8], 1'b0, INIT[ 270*8 +: 8], 1'b0, INIT[ 267*8 +: 8], 1'b0, INIT[ 266*8 +: 8], 
+          1'b0, INIT[ 263*8 +: 8], 1'b0, INIT[ 262*8 +: 8], 1'b0, INIT[ 259*8 +: 8], 1'b0, INIT[ 258*8 +: 8], 
+          1'b0, INIT[ 255*8 +: 8], 1'b0, INIT[ 254*8 +: 8], 1'b0, INIT[ 251*8 +: 8], 1'b0, INIT[ 250*8 +: 8], 
+          1'b0, INIT[ 247*8 +: 8], 1'b0, INIT[ 246*8 +: 8], 1'b0, INIT[ 243*8 +: 8], 1'b0, INIT[ 242*8 +: 8], 
+          1'b0, INIT[ 239*8 +: 8], 1'b0, INIT[ 238*8 +: 8], 1'b0, INIT[ 235*8 +: 8], 1'b0, INIT[ 234*8 +: 8], 
+          1'b0, INIT[ 231*8 +: 8], 1'b0, INIT[ 230*8 +: 8], 1'b0, INIT[ 227*8 +: 8], 1'b0, INIT[ 226*8 +: 8], 
+          1'b0, INIT[ 223*8 +: 8], 1'b0, INIT[ 222*8 +: 8], 1'b0, INIT[ 219*8 +: 8], 1'b0, INIT[ 218*8 +: 8], 
+          1'b0, INIT[ 215*8 +: 8], 1'b0, INIT[ 214*8 +: 8], 1'b0, INIT[ 211*8 +: 8], 1'b0, INIT[ 210*8 +: 8], 
+          1'b0, INIT[ 207*8 +: 8], 1'b0, INIT[ 206*8 +: 8], 1'b0, INIT[ 203*8 +: 8], 1'b0, INIT[ 202*8 +: 8], 
+          1'b0, INIT[ 199*8 +: 8], 1'b0, INIT[ 198*8 +: 8], 1'b0, INIT[ 195*8 +: 8], 1'b0, INIT[ 194*8 +: 8], 
+          1'b0, INIT[ 191*8 +: 8], 1'b0, INIT[ 190*8 +: 8], 1'b0, INIT[ 187*8 +: 8], 1'b0, INIT[ 186*8 +: 8], 
+          1'b0, INIT[ 183*8 +: 8], 1'b0, INIT[ 182*8 +: 8], 1'b0, INIT[ 179*8 +: 8], 1'b0, INIT[ 178*8 +: 8], 
+          1'b0, INIT[ 175*8 +: 8], 1'b0, INIT[ 174*8 +: 8], 1'b0, INIT[ 171*8 +: 8], 1'b0, INIT[ 170*8 +: 8], 
+          1'b0, INIT[ 167*8 +: 8], 1'b0, INIT[ 166*8 +: 8], 1'b0, INIT[ 163*8 +: 8], 1'b0, INIT[ 162*8 +: 8], 
+          1'b0, INIT[ 159*8 +: 8], 1'b0, INIT[ 158*8 +: 8], 1'b0, INIT[ 155*8 +: 8], 1'b0, INIT[ 154*8 +: 8], 
+          1'b0, INIT[ 151*8 +: 8], 1'b0, INIT[ 150*8 +: 8], 1'b0, INIT[ 147*8 +: 8], 1'b0, INIT[ 146*8 +: 8], 
+          1'b0, INIT[ 143*8 +: 8], 1'b0, INIT[ 142*8 +: 8], 1'b0, INIT[ 139*8 +: 8], 1'b0, INIT[ 138*8 +: 8], 
+          1'b0, INIT[ 135*8 +: 8], 1'b0, INIT[ 134*8 +: 8], 1'b0, INIT[ 131*8 +: 8], 1'b0, INIT[ 130*8 +: 8], 
+          1'b0, INIT[ 127*8 +: 8], 1'b0, INIT[ 126*8 +: 8], 1'b0, INIT[ 123*8 +: 8], 1'b0, INIT[ 122*8 +: 8], 
+          1'b0, INIT[ 119*8 +: 8], 1'b0, INIT[ 118*8 +: 8], 1'b0, INIT[ 115*8 +: 8], 1'b0, INIT[ 114*8 +: 8], 
+          1'b0, INIT[ 111*8 +: 8], 1'b0, INIT[ 110*8 +: 8], 1'b0, INIT[ 107*8 +: 8], 1'b0, INIT[ 106*8 +: 8], 
+          1'b0, INIT[ 103*8 +: 8], 1'b0, INIT[ 102*8 +: 8], 1'b0, INIT[  99*8 +: 8], 1'b0, INIT[  98*8 +: 8], 
+          1'b0, INIT[  95*8 +: 8], 1'b0, INIT[  94*8 +: 8], 1'b0, INIT[  91*8 +: 8], 1'b0, INIT[  90*8 +: 8], 
+          1'b0, INIT[  87*8 +: 8], 1'b0, INIT[  86*8 +: 8], 1'b0, INIT[  83*8 +: 8], 1'b0, INIT[  82*8 +: 8], 
+          1'b0, INIT[  79*8 +: 8], 1'b0, INIT[  78*8 +: 8], 1'b0, INIT[  75*8 +: 8], 1'b0, INIT[  74*8 +: 8], 
+          1'b0, INIT[  71*8 +: 8], 1'b0, INIT[  70*8 +: 8], 1'b0, INIT[  67*8 +: 8], 1'b0, INIT[  66*8 +: 8], 
+          1'b0, INIT[  63*8 +: 8], 1'b0, INIT[  62*8 +: 8], 1'b0, INIT[  59*8 +: 8], 1'b0, INIT[  58*8 +: 8], 
+          1'b0, INIT[  55*8 +: 8], 1'b0, INIT[  54*8 +: 8], 1'b0, INIT[  51*8 +: 8], 1'b0, INIT[  50*8 +: 8], 
+          1'b0, INIT[  47*8 +: 8], 1'b0, INIT[  46*8 +: 8], 1'b0, INIT[  43*8 +: 8], 1'b0, INIT[  42*8 +: 8], 
+          1'b0, INIT[  39*8 +: 8], 1'b0, INIT[  38*8 +: 8], 1'b0, INIT[  35*8 +: 8], 1'b0, INIT[  34*8 +: 8], 
+          1'b0, INIT[  31*8 +: 8], 1'b0, INIT[  30*8 +: 8], 1'b0, INIT[  27*8 +: 8], 1'b0, INIT[  26*8 +: 8], 
+          1'b0, INIT[  23*8 +: 8], 1'b0, INIT[  22*8 +: 8], 1'b0, INIT[  19*8 +: 8], 1'b0, INIT[  18*8 +: 8], 
+          1'b0, INIT[  15*8 +: 8], 1'b0, INIT[  14*8 +: 8], 1'b0, INIT[  11*8 +: 8], 1'b0, INIT[  10*8 +: 8], 
+          1'b0, INIT[   7*8 +: 8], 1'b0, INIT[   6*8 +: 8], 1'b0, INIT[   3*8 +: 8], 1'b0, INIT[   2*8 +: 8], 
+          1'b0, INIT[2045*8 +: 8], 1'b0, INIT[2044*8 +: 8], 1'b0, INIT[2041*8 +: 8], 1'b0, INIT[2040*8 +: 8], 
+          1'b0, INIT[2037*8 +: 8], 1'b0, INIT[2036*8 +: 8], 1'b0, INIT[2033*8 +: 8], 1'b0, INIT[2032*8 +: 8], 
+          1'b0, INIT[2029*8 +: 8], 1'b0, INIT[2028*8 +: 8], 1'b0, INIT[2025*8 +: 8], 1'b0, INIT[2024*8 +: 8], 
+          1'b0, INIT[2021*8 +: 8], 1'b0, INIT[2020*8 +: 8], 1'b0, INIT[2017*8 +: 8], 1'b0, INIT[2016*8 +: 8], 
+          1'b0, INIT[2013*8 +: 8], 1'b0, INIT[2012*8 +: 8], 1'b0, INIT[2009*8 +: 8], 1'b0, INIT[2008*8 +: 8], 
+          1'b0, INIT[2005*8 +: 8], 1'b0, INIT[2004*8 +: 8], 1'b0, INIT[2001*8 +: 8], 1'b0, INIT[2000*8 +: 8], 
+          1'b0, INIT[1997*8 +: 8], 1'b0, INIT[1996*8 +: 8], 1'b0, INIT[1993*8 +: 8], 1'b0, INIT[1992*8 +: 8], 
+          1'b0, INIT[1989*8 +: 8], 1'b0, INIT[1988*8 +: 8], 1'b0, INIT[1985*8 +: 8], 1'b0, INIT[1984*8 +: 8], 
+          1'b0, INIT[1981*8 +: 8], 1'b0, INIT[1980*8 +: 8], 1'b0, INIT[1977*8 +: 8], 1'b0, INIT[1976*8 +: 8], 
+          1'b0, INIT[1973*8 +: 8], 1'b0, INIT[1972*8 +: 8], 1'b0, INIT[1969*8 +: 8], 1'b0, INIT[1968*8 +: 8], 
+          1'b0, INIT[1965*8 +: 8], 1'b0, INIT[1964*8 +: 8], 1'b0, INIT[1961*8 +: 8], 1'b0, INIT[1960*8 +: 8], 
+          1'b0, INIT[1957*8 +: 8], 1'b0, INIT[1956*8 +: 8], 1'b0, INIT[1953*8 +: 8], 1'b0, INIT[1952*8 +: 8], 
+          1'b0, INIT[1949*8 +: 8], 1'b0, INIT[1948*8 +: 8], 1'b0, INIT[1945*8 +: 8], 1'b0, INIT[1944*8 +: 8], 
+          1'b0, INIT[1941*8 +: 8], 1'b0, INIT[1940*8 +: 8], 1'b0, INIT[1937*8 +: 8], 1'b0, INIT[1936*8 +: 8], 
+          1'b0, INIT[1933*8 +: 8], 1'b0, INIT[1932*8 +: 8], 1'b0, INIT[1929*8 +: 8], 1'b0, INIT[1928*8 +: 8], 
+          1'b0, INIT[1925*8 +: 8], 1'b0, INIT[1924*8 +: 8], 1'b0, INIT[1921*8 +: 8], 1'b0, INIT[1920*8 +: 8], 
+          1'b0, INIT[1917*8 +: 8], 1'b0, INIT[1916*8 +: 8], 1'b0, INIT[1913*8 +: 8], 1'b0, INIT[1912*8 +: 8], 
+          1'b0, INIT[1909*8 +: 8], 1'b0, INIT[1908*8 +: 8], 1'b0, INIT[1905*8 +: 8], 1'b0, INIT[1904*8 +: 8], 
+          1'b0, INIT[1901*8 +: 8], 1'b0, INIT[1900*8 +: 8], 1'b0, INIT[1897*8 +: 8], 1'b0, INIT[1896*8 +: 8], 
+          1'b0, INIT[1893*8 +: 8], 1'b0, INIT[1892*8 +: 8], 1'b0, INIT[1889*8 +: 8], 1'b0, INIT[1888*8 +: 8], 
+          1'b0, INIT[1885*8 +: 8], 1'b0, INIT[1884*8 +: 8], 1'b0, INIT[1881*8 +: 8], 1'b0, INIT[1880*8 +: 8], 
+          1'b0, INIT[1877*8 +: 8], 1'b0, INIT[1876*8 +: 8], 1'b0, INIT[1873*8 +: 8], 1'b0, INIT[1872*8 +: 8], 
+          1'b0, INIT[1869*8 +: 8], 1'b0, INIT[1868*8 +: 8], 1'b0, INIT[1865*8 +: 8], 1'b0, INIT[1864*8 +: 8], 
+          1'b0, INIT[1861*8 +: 8], 1'b0, INIT[1860*8 +: 8], 1'b0, INIT[1857*8 +: 8], 1'b0, INIT[1856*8 +: 8], 
+          1'b0, INIT[1853*8 +: 8], 1'b0, INIT[1852*8 +: 8], 1'b0, INIT[1849*8 +: 8], 1'b0, INIT[1848*8 +: 8], 
+          1'b0, INIT[1845*8 +: 8], 1'b0, INIT[1844*8 +: 8], 1'b0, INIT[1841*8 +: 8], 1'b0, INIT[1840*8 +: 8], 
+          1'b0, INIT[1837*8 +: 8], 1'b0, INIT[1836*8 +: 8], 1'b0, INIT[1833*8 +: 8], 1'b0, INIT[1832*8 +: 8], 
+          1'b0, INIT[1829*8 +: 8], 1'b0, INIT[1828*8 +: 8], 1'b0, INIT[1825*8 +: 8], 1'b0, INIT[1824*8 +: 8], 
+          1'b0, INIT[1821*8 +: 8], 1'b0, INIT[1820*8 +: 8], 1'b0, INIT[1817*8 +: 8], 1'b0, INIT[1816*8 +: 8], 
+          1'b0, INIT[1813*8 +: 8], 1'b0, INIT[1812*8 +: 8], 1'b0, INIT[1809*8 +: 8], 1'b0, INIT[1808*8 +: 8], 
+          1'b0, INIT[1805*8 +: 8], 1'b0, INIT[1804*8 +: 8], 1'b0, INIT[1801*8 +: 8], 1'b0, INIT[1800*8 +: 8], 
+          1'b0, INIT[1797*8 +: 8], 1'b0, INIT[1796*8 +: 8], 1'b0, INIT[1793*8 +: 8], 1'b0, INIT[1792*8 +: 8], 
+          1'b0, INIT[1789*8 +: 8], 1'b0, INIT[1788*8 +: 8], 1'b0, INIT[1785*8 +: 8], 1'b0, INIT[1784*8 +: 8], 
+          1'b0, INIT[1781*8 +: 8], 1'b0, INIT[1780*8 +: 8], 1'b0, INIT[1777*8 +: 8], 1'b0, INIT[1776*8 +: 8], 
+          1'b0, INIT[1773*8 +: 8], 1'b0, INIT[1772*8 +: 8], 1'b0, INIT[1769*8 +: 8], 1'b0, INIT[1768*8 +: 8], 
+          1'b0, INIT[1765*8 +: 8], 1'b0, INIT[1764*8 +: 8], 1'b0, INIT[1761*8 +: 8], 1'b0, INIT[1760*8 +: 8], 
+          1'b0, INIT[1757*8 +: 8], 1'b0, INIT[1756*8 +: 8], 1'b0, INIT[1753*8 +: 8], 1'b0, INIT[1752*8 +: 8], 
+          1'b0, INIT[1749*8 +: 8], 1'b0, INIT[1748*8 +: 8], 1'b0, INIT[1745*8 +: 8], 1'b0, INIT[1744*8 +: 8], 
+          1'b0, INIT[1741*8 +: 8], 1'b0, INIT[1740*8 +: 8], 1'b0, INIT[1737*8 +: 8], 1'b0, INIT[1736*8 +: 8], 
+          1'b0, INIT[1733*8 +: 8], 1'b0, INIT[1732*8 +: 8], 1'b0, INIT[1729*8 +: 8], 1'b0, INIT[1728*8 +: 8], 
+          1'b0, INIT[1725*8 +: 8], 1'b0, INIT[1724*8 +: 8], 1'b0, INIT[1721*8 +: 8], 1'b0, INIT[1720*8 +: 8], 
+          1'b0, INIT[1717*8 +: 8], 1'b0, INIT[1716*8 +: 8], 1'b0, INIT[1713*8 +: 8], 1'b0, INIT[1712*8 +: 8], 
+          1'b0, INIT[1709*8 +: 8], 1'b0, INIT[1708*8 +: 8], 1'b0, INIT[1705*8 +: 8], 1'b0, INIT[1704*8 +: 8], 
+          1'b0, INIT[1701*8 +: 8], 1'b0, INIT[1700*8 +: 8], 1'b0, INIT[1697*8 +: 8], 1'b0, INIT[1696*8 +: 8], 
+          1'b0, INIT[1693*8 +: 8], 1'b0, INIT[1692*8 +: 8], 1'b0, INIT[1689*8 +: 8], 1'b0, INIT[1688*8 +: 8], 
+          1'b0, INIT[1685*8 +: 8], 1'b0, INIT[1684*8 +: 8], 1'b0, INIT[1681*8 +: 8], 1'b0, INIT[1680*8 +: 8], 
+          1'b0, INIT[1677*8 +: 8], 1'b0, INIT[1676*8 +: 8], 1'b0, INIT[1673*8 +: 8], 1'b0, INIT[1672*8 +: 8], 
+          1'b0, INIT[1669*8 +: 8], 1'b0, INIT[1668*8 +: 8], 1'b0, INIT[1665*8 +: 8], 1'b0, INIT[1664*8 +: 8], 
+          1'b0, INIT[1661*8 +: 8], 1'b0, INIT[1660*8 +: 8], 1'b0, INIT[1657*8 +: 8], 1'b0, INIT[1656*8 +: 8], 
+          1'b0, INIT[1653*8 +: 8], 1'b0, INIT[1652*8 +: 8], 1'b0, INIT[1649*8 +: 8], 1'b0, INIT[1648*8 +: 8], 
+          1'b0, INIT[1645*8 +: 8], 1'b0, INIT[1644*8 +: 8], 1'b0, INIT[1641*8 +: 8], 1'b0, INIT[1640*8 +: 8], 
+          1'b0, INIT[1637*8 +: 8], 1'b0, INIT[1636*8 +: 8], 1'b0, INIT[1633*8 +: 8], 1'b0, INIT[1632*8 +: 8], 
+          1'b0, INIT[1629*8 +: 8], 1'b0, INIT[1628*8 +: 8], 1'b0, INIT[1625*8 +: 8], 1'b0, INIT[1624*8 +: 8], 
+          1'b0, INIT[1621*8 +: 8], 1'b0, INIT[1620*8 +: 8], 1'b0, INIT[1617*8 +: 8], 1'b0, INIT[1616*8 +: 8], 
+          1'b0, INIT[1613*8 +: 8], 1'b0, INIT[1612*8 +: 8], 1'b0, INIT[1609*8 +: 8], 1'b0, INIT[1608*8 +: 8], 
+          1'b0, INIT[1605*8 +: 8], 1'b0, INIT[1604*8 +: 8], 1'b0, INIT[1601*8 +: 8], 1'b0, INIT[1600*8 +: 8], 
+          1'b0, INIT[1597*8 +: 8], 1'b0, INIT[1596*8 +: 8], 1'b0, INIT[1593*8 +: 8], 1'b0, INIT[1592*8 +: 8], 
+          1'b0, INIT[1589*8 +: 8], 1'b0, INIT[1588*8 +: 8], 1'b0, INIT[1585*8 +: 8], 1'b0, INIT[1584*8 +: 8], 
+          1'b0, INIT[1581*8 +: 8], 1'b0, INIT[1580*8 +: 8], 1'b0, INIT[1577*8 +: 8], 1'b0, INIT[1576*8 +: 8], 
+          1'b0, INIT[1573*8 +: 8], 1'b0, INIT[1572*8 +: 8], 1'b0, INIT[1569*8 +: 8], 1'b0, INIT[1568*8 +: 8], 
+          1'b0, INIT[1565*8 +: 8], 1'b0, INIT[1564*8 +: 8], 1'b0, INIT[1561*8 +: 8], 1'b0, INIT[1560*8 +: 8], 
+          1'b0, INIT[1557*8 +: 8], 1'b0, INIT[1556*8 +: 8], 1'b0, INIT[1553*8 +: 8], 1'b0, INIT[1552*8 +: 8], 
+          1'b0, INIT[1549*8 +: 8], 1'b0, INIT[1548*8 +: 8], 1'b0, INIT[1545*8 +: 8], 1'b0, INIT[1544*8 +: 8], 
+          1'b0, INIT[1541*8 +: 8], 1'b0, INIT[1540*8 +: 8], 1'b0, INIT[1537*8 +: 8], 1'b0, INIT[1536*8 +: 8], 
+          1'b0, INIT[1533*8 +: 8], 1'b0, INIT[1532*8 +: 8], 1'b0, INIT[1529*8 +: 8], 1'b0, INIT[1528*8 +: 8], 
+          1'b0, INIT[1525*8 +: 8], 1'b0, INIT[1524*8 +: 8], 1'b0, INIT[1521*8 +: 8], 1'b0, INIT[1520*8 +: 8], 
+          1'b0, INIT[1517*8 +: 8], 1'b0, INIT[1516*8 +: 8], 1'b0, INIT[1513*8 +: 8], 1'b0, INIT[1512*8 +: 8], 
+          1'b0, INIT[1509*8 +: 8], 1'b0, INIT[1508*8 +: 8], 1'b0, INIT[1505*8 +: 8], 1'b0, INIT[1504*8 +: 8], 
+          1'b0, INIT[1501*8 +: 8], 1'b0, INIT[1500*8 +: 8], 1'b0, INIT[1497*8 +: 8], 1'b0, INIT[1496*8 +: 8], 
+          1'b0, INIT[1493*8 +: 8], 1'b0, INIT[1492*8 +: 8], 1'b0, INIT[1489*8 +: 8], 1'b0, INIT[1488*8 +: 8], 
+          1'b0, INIT[1485*8 +: 8], 1'b0, INIT[1484*8 +: 8], 1'b0, INIT[1481*8 +: 8], 1'b0, INIT[1480*8 +: 8], 
+          1'b0, INIT[1477*8 +: 8], 1'b0, INIT[1476*8 +: 8], 1'b0, INIT[1473*8 +: 8], 1'b0, INIT[1472*8 +: 8], 
+          1'b0, INIT[1469*8 +: 8], 1'b0, INIT[1468*8 +: 8], 1'b0, INIT[1465*8 +: 8], 1'b0, INIT[1464*8 +: 8], 
+          1'b0, INIT[1461*8 +: 8], 1'b0, INIT[1460*8 +: 8], 1'b0, INIT[1457*8 +: 8], 1'b0, INIT[1456*8 +: 8], 
+          1'b0, INIT[1453*8 +: 8], 1'b0, INIT[1452*8 +: 8], 1'b0, INIT[1449*8 +: 8], 1'b0, INIT[1448*8 +: 8], 
+          1'b0, INIT[1445*8 +: 8], 1'b0, INIT[1444*8 +: 8], 1'b0, INIT[1441*8 +: 8], 1'b0, INIT[1440*8 +: 8], 
+          1'b0, INIT[1437*8 +: 8], 1'b0, INIT[1436*8 +: 8], 1'b0, INIT[1433*8 +: 8], 1'b0, INIT[1432*8 +: 8], 
+          1'b0, INIT[1429*8 +: 8], 1'b0, INIT[1428*8 +: 8], 1'b0, INIT[1425*8 +: 8], 1'b0, INIT[1424*8 +: 8], 
+          1'b0, INIT[1421*8 +: 8], 1'b0, INIT[1420*8 +: 8], 1'b0, INIT[1417*8 +: 8], 1'b0, INIT[1416*8 +: 8], 
+          1'b0, INIT[1413*8 +: 8], 1'b0, INIT[1412*8 +: 8], 1'b0, INIT[1409*8 +: 8], 1'b0, INIT[1408*8 +: 8], 
+          1'b0, INIT[1405*8 +: 8], 1'b0, INIT[1404*8 +: 8], 1'b0, INIT[1401*8 +: 8], 1'b0, INIT[1400*8 +: 8], 
+          1'b0, INIT[1397*8 +: 8], 1'b0, INIT[1396*8 +: 8], 1'b0, INIT[1393*8 +: 8], 1'b0, INIT[1392*8 +: 8], 
+          1'b0, INIT[1389*8 +: 8], 1'b0, INIT[1388*8 +: 8], 1'b0, INIT[1385*8 +: 8], 1'b0, INIT[1384*8 +: 8], 
+          1'b0, INIT[1381*8 +: 8], 1'b0, INIT[1380*8 +: 8], 1'b0, INIT[1377*8 +: 8], 1'b0, INIT[1376*8 +: 8], 
+          1'b0, INIT[1373*8 +: 8], 1'b0, INIT[1372*8 +: 8], 1'b0, INIT[1369*8 +: 8], 1'b0, INIT[1368*8 +: 8], 
+          1'b0, INIT[1365*8 +: 8], 1'b0, INIT[1364*8 +: 8], 1'b0, INIT[1361*8 +: 8], 1'b0, INIT[1360*8 +: 8], 
+          1'b0, INIT[1357*8 +: 8], 1'b0, INIT[1356*8 +: 8], 1'b0, INIT[1353*8 +: 8], 1'b0, INIT[1352*8 +: 8], 
+          1'b0, INIT[1349*8 +: 8], 1'b0, INIT[1348*8 +: 8], 1'b0, INIT[1345*8 +: 8], 1'b0, INIT[1344*8 +: 8], 
+          1'b0, INIT[1341*8 +: 8], 1'b0, INIT[1340*8 +: 8], 1'b0, INIT[1337*8 +: 8], 1'b0, INIT[1336*8 +: 8], 
+          1'b0, INIT[1333*8 +: 8], 1'b0, INIT[1332*8 +: 8], 1'b0, INIT[1329*8 +: 8], 1'b0, INIT[1328*8 +: 8], 
+          1'b0, INIT[1325*8 +: 8], 1'b0, INIT[1324*8 +: 8], 1'b0, INIT[1321*8 +: 8], 1'b0, INIT[1320*8 +: 8], 
+          1'b0, INIT[1317*8 +: 8], 1'b0, INIT[1316*8 +: 8], 1'b0, INIT[1313*8 +: 8], 1'b0, INIT[1312*8 +: 8], 
+          1'b0, INIT[1309*8 +: 8], 1'b0, INIT[1308*8 +: 8], 1'b0, INIT[1305*8 +: 8], 1'b0, INIT[1304*8 +: 8], 
+          1'b0, INIT[1301*8 +: 8], 1'b0, INIT[1300*8 +: 8], 1'b0, INIT[1297*8 +: 8], 1'b0, INIT[1296*8 +: 8], 
+          1'b0, INIT[1293*8 +: 8], 1'b0, INIT[1292*8 +: 8], 1'b0, INIT[1289*8 +: 8], 1'b0, INIT[1288*8 +: 8], 
+          1'b0, INIT[1285*8 +: 8], 1'b0, INIT[1284*8 +: 8], 1'b0, INIT[1281*8 +: 8], 1'b0, INIT[1280*8 +: 8], 
+          1'b0, INIT[1277*8 +: 8], 1'b0, INIT[1276*8 +: 8], 1'b0, INIT[1273*8 +: 8], 1'b0, INIT[1272*8 +: 8], 
+          1'b0, INIT[1269*8 +: 8], 1'b0, INIT[1268*8 +: 8], 1'b0, INIT[1265*8 +: 8], 1'b0, INIT[1264*8 +: 8], 
+          1'b0, INIT[1261*8 +: 8], 1'b0, INIT[1260*8 +: 8], 1'b0, INIT[1257*8 +: 8], 1'b0, INIT[1256*8 +: 8], 
+          1'b0, INIT[1253*8 +: 8], 1'b0, INIT[1252*8 +: 8], 1'b0, INIT[1249*8 +: 8], 1'b0, INIT[1248*8 +: 8], 
+          1'b0, INIT[1245*8 +: 8], 1'b0, INIT[1244*8 +: 8], 1'b0, INIT[1241*8 +: 8], 1'b0, INIT[1240*8 +: 8], 
+          1'b0, INIT[1237*8 +: 8], 1'b0, INIT[1236*8 +: 8], 1'b0, INIT[1233*8 +: 8], 1'b0, INIT[1232*8 +: 8], 
+          1'b0, INIT[1229*8 +: 8], 1'b0, INIT[1228*8 +: 8], 1'b0, INIT[1225*8 +: 8], 1'b0, INIT[1224*8 +: 8], 
+          1'b0, INIT[1221*8 +: 8], 1'b0, INIT[1220*8 +: 8], 1'b0, INIT[1217*8 +: 8], 1'b0, INIT[1216*8 +: 8], 
+          1'b0, INIT[1213*8 +: 8], 1'b0, INIT[1212*8 +: 8], 1'b0, INIT[1209*8 +: 8], 1'b0, INIT[1208*8 +: 8], 
+          1'b0, INIT[1205*8 +: 8], 1'b0, INIT[1204*8 +: 8], 1'b0, INIT[1201*8 +: 8], 1'b0, INIT[1200*8 +: 8], 
+          1'b0, INIT[1197*8 +: 8], 1'b0, INIT[1196*8 +: 8], 1'b0, INIT[1193*8 +: 8], 1'b0, INIT[1192*8 +: 8], 
+          1'b0, INIT[1189*8 +: 8], 1'b0, INIT[1188*8 +: 8], 1'b0, INIT[1185*8 +: 8], 1'b0, INIT[1184*8 +: 8], 
+          1'b0, INIT[1181*8 +: 8], 1'b0, INIT[1180*8 +: 8], 1'b0, INIT[1177*8 +: 8], 1'b0, INIT[1176*8 +: 8], 
+          1'b0, INIT[1173*8 +: 8], 1'b0, INIT[1172*8 +: 8], 1'b0, INIT[1169*8 +: 8], 1'b0, INIT[1168*8 +: 8], 
+          1'b0, INIT[1165*8 +: 8], 1'b0, INIT[1164*8 +: 8], 1'b0, INIT[1161*8 +: 8], 1'b0, INIT[1160*8 +: 8], 
+          1'b0, INIT[1157*8 +: 8], 1'b0, INIT[1156*8 +: 8], 1'b0, INIT[1153*8 +: 8], 1'b0, INIT[1152*8 +: 8], 
+          1'b0, INIT[1149*8 +: 8], 1'b0, INIT[1148*8 +: 8], 1'b0, INIT[1145*8 +: 8], 1'b0, INIT[1144*8 +: 8], 
+          1'b0, INIT[1141*8 +: 8], 1'b0, INIT[1140*8 +: 8], 1'b0, INIT[1137*8 +: 8], 1'b0, INIT[1136*8 +: 8], 
+          1'b0, INIT[1133*8 +: 8], 1'b0, INIT[1132*8 +: 8], 1'b0, INIT[1129*8 +: 8], 1'b0, INIT[1128*8 +: 8], 
+          1'b0, INIT[1125*8 +: 8], 1'b0, INIT[1124*8 +: 8], 1'b0, INIT[1121*8 +: 8], 1'b0, INIT[1120*8 +: 8], 
+          1'b0, INIT[1117*8 +: 8], 1'b0, INIT[1116*8 +: 8], 1'b0, INIT[1113*8 +: 8], 1'b0, INIT[1112*8 +: 8], 
+          1'b0, INIT[1109*8 +: 8], 1'b0, INIT[1108*8 +: 8], 1'b0, INIT[1105*8 +: 8], 1'b0, INIT[1104*8 +: 8], 
+          1'b0, INIT[1101*8 +: 8], 1'b0, INIT[1100*8 +: 8], 1'b0, INIT[1097*8 +: 8], 1'b0, INIT[1096*8 +: 8], 
+          1'b0, INIT[1093*8 +: 8], 1'b0, INIT[1092*8 +: 8], 1'b0, INIT[1089*8 +: 8], 1'b0, INIT[1088*8 +: 8], 
+          1'b0, INIT[1085*8 +: 8], 1'b0, INIT[1084*8 +: 8], 1'b0, INIT[1081*8 +: 8], 1'b0, INIT[1080*8 +: 8], 
+          1'b0, INIT[1077*8 +: 8], 1'b0, INIT[1076*8 +: 8], 1'b0, INIT[1073*8 +: 8], 1'b0, INIT[1072*8 +: 8], 
+          1'b0, INIT[1069*8 +: 8], 1'b0, INIT[1068*8 +: 8], 1'b0, INIT[1065*8 +: 8], 1'b0, INIT[1064*8 +: 8], 
+          1'b0, INIT[1061*8 +: 8], 1'b0, INIT[1060*8 +: 8], 1'b0, INIT[1057*8 +: 8], 1'b0, INIT[1056*8 +: 8], 
+          1'b0, INIT[1053*8 +: 8], 1'b0, INIT[1052*8 +: 8], 1'b0, INIT[1049*8 +: 8], 1'b0, INIT[1048*8 +: 8], 
+          1'b0, INIT[1045*8 +: 8], 1'b0, INIT[1044*8 +: 8], 1'b0, INIT[1041*8 +: 8], 1'b0, INIT[1040*8 +: 8], 
+          1'b0, INIT[1037*8 +: 8], 1'b0, INIT[1036*8 +: 8], 1'b0, INIT[1033*8 +: 8], 1'b0, INIT[1032*8 +: 8], 
+          1'b0, INIT[1029*8 +: 8], 1'b0, INIT[1028*8 +: 8], 1'b0, INIT[1025*8 +: 8], 1'b0, INIT[1024*8 +: 8], 
+          1'b0, INIT[1021*8 +: 8], 1'b0, INIT[1020*8 +: 8], 1'b0, INIT[1017*8 +: 8], 1'b0, INIT[1016*8 +: 8], 
+          1'b0, INIT[1013*8 +: 8], 1'b0, INIT[1012*8 +: 8], 1'b0, INIT[1009*8 +: 8], 1'b0, INIT[1008*8 +: 8], 
+          1'b0, INIT[1005*8 +: 8], 1'b0, INIT[1004*8 +: 8], 1'b0, INIT[1001*8 +: 8], 1'b0, INIT[1000*8 +: 8], 
+          1'b0, INIT[ 997*8 +: 8], 1'b0, INIT[ 996*8 +: 8], 1'b0, INIT[ 993*8 +: 8], 1'b0, INIT[ 992*8 +: 8], 
+          1'b0, INIT[ 989*8 +: 8], 1'b0, INIT[ 988*8 +: 8], 1'b0, INIT[ 985*8 +: 8], 1'b0, INIT[ 984*8 +: 8], 
+          1'b0, INIT[ 981*8 +: 8], 1'b0, INIT[ 980*8 +: 8], 1'b0, INIT[ 977*8 +: 8], 1'b0, INIT[ 976*8 +: 8], 
+          1'b0, INIT[ 973*8 +: 8], 1'b0, INIT[ 972*8 +: 8], 1'b0, INIT[ 969*8 +: 8], 1'b0, INIT[ 968*8 +: 8], 
+          1'b0, INIT[ 965*8 +: 8], 1'b0, INIT[ 964*8 +: 8], 1'b0, INIT[ 961*8 +: 8], 1'b0, INIT[ 960*8 +: 8], 
+          1'b0, INIT[ 957*8 +: 8], 1'b0, INIT[ 956*8 +: 8], 1'b0, INIT[ 953*8 +: 8], 1'b0, INIT[ 952*8 +: 8], 
+          1'b0, INIT[ 949*8 +: 8], 1'b0, INIT[ 948*8 +: 8], 1'b0, INIT[ 945*8 +: 8], 1'b0, INIT[ 944*8 +: 8], 
+          1'b0, INIT[ 941*8 +: 8], 1'b0, INIT[ 940*8 +: 8], 1'b0, INIT[ 937*8 +: 8], 1'b0, INIT[ 936*8 +: 8], 
+          1'b0, INIT[ 933*8 +: 8], 1'b0, INIT[ 932*8 +: 8], 1'b0, INIT[ 929*8 +: 8], 1'b0, INIT[ 928*8 +: 8], 
+          1'b0, INIT[ 925*8 +: 8], 1'b0, INIT[ 924*8 +: 8], 1'b0, INIT[ 921*8 +: 8], 1'b0, INIT[ 920*8 +: 8], 
+          1'b0, INIT[ 917*8 +: 8], 1'b0, INIT[ 916*8 +: 8], 1'b0, INIT[ 913*8 +: 8], 1'b0, INIT[ 912*8 +: 8], 
+          1'b0, INIT[ 909*8 +: 8], 1'b0, INIT[ 908*8 +: 8], 1'b0, INIT[ 905*8 +: 8], 1'b0, INIT[ 904*8 +: 8], 
+          1'b0, INIT[ 901*8 +: 8], 1'b0, INIT[ 900*8 +: 8], 1'b0, INIT[ 897*8 +: 8], 1'b0, INIT[ 896*8 +: 8], 
+          1'b0, INIT[ 893*8 +: 8], 1'b0, INIT[ 892*8 +: 8], 1'b0, INIT[ 889*8 +: 8], 1'b0, INIT[ 888*8 +: 8], 
+          1'b0, INIT[ 885*8 +: 8], 1'b0, INIT[ 884*8 +: 8], 1'b0, INIT[ 881*8 +: 8], 1'b0, INIT[ 880*8 +: 8], 
+          1'b0, INIT[ 877*8 +: 8], 1'b0, INIT[ 876*8 +: 8], 1'b0, INIT[ 873*8 +: 8], 1'b0, INIT[ 872*8 +: 8], 
+          1'b0, INIT[ 869*8 +: 8], 1'b0, INIT[ 868*8 +: 8], 1'b0, INIT[ 865*8 +: 8], 1'b0, INIT[ 864*8 +: 8], 
+          1'b0, INIT[ 861*8 +: 8], 1'b0, INIT[ 860*8 +: 8], 1'b0, INIT[ 857*8 +: 8], 1'b0, INIT[ 856*8 +: 8], 
+          1'b0, INIT[ 853*8 +: 8], 1'b0, INIT[ 852*8 +: 8], 1'b0, INIT[ 849*8 +: 8], 1'b0, INIT[ 848*8 +: 8], 
+          1'b0, INIT[ 845*8 +: 8], 1'b0, INIT[ 844*8 +: 8], 1'b0, INIT[ 841*8 +: 8], 1'b0, INIT[ 840*8 +: 8], 
+          1'b0, INIT[ 837*8 +: 8], 1'b0, INIT[ 836*8 +: 8], 1'b0, INIT[ 833*8 +: 8], 1'b0, INIT[ 832*8 +: 8], 
+          1'b0, INIT[ 829*8 +: 8], 1'b0, INIT[ 828*8 +: 8], 1'b0, INIT[ 825*8 +: 8], 1'b0, INIT[ 824*8 +: 8], 
+          1'b0, INIT[ 821*8 +: 8], 1'b0, INIT[ 820*8 +: 8], 1'b0, INIT[ 817*8 +: 8], 1'b0, INIT[ 816*8 +: 8], 
+          1'b0, INIT[ 813*8 +: 8], 1'b0, INIT[ 812*8 +: 8], 1'b0, INIT[ 809*8 +: 8], 1'b0, INIT[ 808*8 +: 8], 
+          1'b0, INIT[ 805*8 +: 8], 1'b0, INIT[ 804*8 +: 8], 1'b0, INIT[ 801*8 +: 8], 1'b0, INIT[ 800*8 +: 8], 
+          1'b0, INIT[ 797*8 +: 8], 1'b0, INIT[ 796*8 +: 8], 1'b0, INIT[ 793*8 +: 8], 1'b0, INIT[ 792*8 +: 8], 
+          1'b0, INIT[ 789*8 +: 8], 1'b0, INIT[ 788*8 +: 8], 1'b0, INIT[ 785*8 +: 8], 1'b0, INIT[ 784*8 +: 8], 
+          1'b0, INIT[ 781*8 +: 8], 1'b0, INIT[ 780*8 +: 8], 1'b0, INIT[ 777*8 +: 8], 1'b0, INIT[ 776*8 +: 8], 
+          1'b0, INIT[ 773*8 +: 8], 1'b0, INIT[ 772*8 +: 8], 1'b0, INIT[ 769*8 +: 8], 1'b0, INIT[ 768*8 +: 8], 
+          1'b0, INIT[ 765*8 +: 8], 1'b0, INIT[ 764*8 +: 8], 1'b0, INIT[ 761*8 +: 8], 1'b0, INIT[ 760*8 +: 8], 
+          1'b0, INIT[ 757*8 +: 8], 1'b0, INIT[ 756*8 +: 8], 1'b0, INIT[ 753*8 +: 8], 1'b0, INIT[ 752*8 +: 8], 
+          1'b0, INIT[ 749*8 +: 8], 1'b0, INIT[ 748*8 +: 8], 1'b0, INIT[ 745*8 +: 8], 1'b0, INIT[ 744*8 +: 8], 
+          1'b0, INIT[ 741*8 +: 8], 1'b0, INIT[ 740*8 +: 8], 1'b0, INIT[ 737*8 +: 8], 1'b0, INIT[ 736*8 +: 8], 
+          1'b0, INIT[ 733*8 +: 8], 1'b0, INIT[ 732*8 +: 8], 1'b0, INIT[ 729*8 +: 8], 1'b0, INIT[ 728*8 +: 8], 
+          1'b0, INIT[ 725*8 +: 8], 1'b0, INIT[ 724*8 +: 8], 1'b0, INIT[ 721*8 +: 8], 1'b0, INIT[ 720*8 +: 8], 
+          1'b0, INIT[ 717*8 +: 8], 1'b0, INIT[ 716*8 +: 8], 1'b0, INIT[ 713*8 +: 8], 1'b0, INIT[ 712*8 +: 8], 
+          1'b0, INIT[ 709*8 +: 8], 1'b0, INIT[ 708*8 +: 8], 1'b0, INIT[ 705*8 +: 8], 1'b0, INIT[ 704*8 +: 8], 
+          1'b0, INIT[ 701*8 +: 8], 1'b0, INIT[ 700*8 +: 8], 1'b0, INIT[ 697*8 +: 8], 1'b0, INIT[ 696*8 +: 8], 
+          1'b0, INIT[ 693*8 +: 8], 1'b0, INIT[ 692*8 +: 8], 1'b0, INIT[ 689*8 +: 8], 1'b0, INIT[ 688*8 +: 8], 
+          1'b0, INIT[ 685*8 +: 8], 1'b0, INIT[ 684*8 +: 8], 1'b0, INIT[ 681*8 +: 8], 1'b0, INIT[ 680*8 +: 8], 
+          1'b0, INIT[ 677*8 +: 8], 1'b0, INIT[ 676*8 +: 8], 1'b0, INIT[ 673*8 +: 8], 1'b0, INIT[ 672*8 +: 8], 
+          1'b0, INIT[ 669*8 +: 8], 1'b0, INIT[ 668*8 +: 8], 1'b0, INIT[ 665*8 +: 8], 1'b0, INIT[ 664*8 +: 8], 
+          1'b0, INIT[ 661*8 +: 8], 1'b0, INIT[ 660*8 +: 8], 1'b0, INIT[ 657*8 +: 8], 1'b0, INIT[ 656*8 +: 8], 
+          1'b0, INIT[ 653*8 +: 8], 1'b0, INIT[ 652*8 +: 8], 1'b0, INIT[ 649*8 +: 8], 1'b0, INIT[ 648*8 +: 8], 
+          1'b0, INIT[ 645*8 +: 8], 1'b0, INIT[ 644*8 +: 8], 1'b0, INIT[ 641*8 +: 8], 1'b0, INIT[ 640*8 +: 8], 
+          1'b0, INIT[ 637*8 +: 8], 1'b0, INIT[ 636*8 +: 8], 1'b0, INIT[ 633*8 +: 8], 1'b0, INIT[ 632*8 +: 8], 
+          1'b0, INIT[ 629*8 +: 8], 1'b0, INIT[ 628*8 +: 8], 1'b0, INIT[ 625*8 +: 8], 1'b0, INIT[ 624*8 +: 8], 
+          1'b0, INIT[ 621*8 +: 8], 1'b0, INIT[ 620*8 +: 8], 1'b0, INIT[ 617*8 +: 8], 1'b0, INIT[ 616*8 +: 8], 
+          1'b0, INIT[ 613*8 +: 8], 1'b0, INIT[ 612*8 +: 8], 1'b0, INIT[ 609*8 +: 8], 1'b0, INIT[ 608*8 +: 8], 
+          1'b0, INIT[ 605*8 +: 8], 1'b0, INIT[ 604*8 +: 8], 1'b0, INIT[ 601*8 +: 8], 1'b0, INIT[ 600*8 +: 8], 
+          1'b0, INIT[ 597*8 +: 8], 1'b0, INIT[ 596*8 +: 8], 1'b0, INIT[ 593*8 +: 8], 1'b0, INIT[ 592*8 +: 8], 
+          1'b0, INIT[ 589*8 +: 8], 1'b0, INIT[ 588*8 +: 8], 1'b0, INIT[ 585*8 +: 8], 1'b0, INIT[ 584*8 +: 8], 
+          1'b0, INIT[ 581*8 +: 8], 1'b0, INIT[ 580*8 +: 8], 1'b0, INIT[ 577*8 +: 8], 1'b0, INIT[ 576*8 +: 8], 
+          1'b0, INIT[ 573*8 +: 8], 1'b0, INIT[ 572*8 +: 8], 1'b0, INIT[ 569*8 +: 8], 1'b0, INIT[ 568*8 +: 8], 
+          1'b0, INIT[ 565*8 +: 8], 1'b0, INIT[ 564*8 +: 8], 1'b0, INIT[ 561*8 +: 8], 1'b0, INIT[ 560*8 +: 8], 
+          1'b0, INIT[ 557*8 +: 8], 1'b0, INIT[ 556*8 +: 8], 1'b0, INIT[ 553*8 +: 8], 1'b0, INIT[ 552*8 +: 8], 
+          1'b0, INIT[ 549*8 +: 8], 1'b0, INIT[ 548*8 +: 8], 1'b0, INIT[ 545*8 +: 8], 1'b0, INIT[ 544*8 +: 8], 
+          1'b0, INIT[ 541*8 +: 8], 1'b0, INIT[ 540*8 +: 8], 1'b0, INIT[ 537*8 +: 8], 1'b0, INIT[ 536*8 +: 8], 
+          1'b0, INIT[ 533*8 +: 8], 1'b0, INIT[ 532*8 +: 8], 1'b0, INIT[ 529*8 +: 8], 1'b0, INIT[ 528*8 +: 8], 
+          1'b0, INIT[ 525*8 +: 8], 1'b0, INIT[ 524*8 +: 8], 1'b0, INIT[ 521*8 +: 8], 1'b0, INIT[ 520*8 +: 8], 
+          1'b0, INIT[ 517*8 +: 8], 1'b0, INIT[ 516*8 +: 8], 1'b0, INIT[ 513*8 +: 8], 1'b0, INIT[ 512*8 +: 8], 
+          1'b0, INIT[ 509*8 +: 8], 1'b0, INIT[ 508*8 +: 8], 1'b0, INIT[ 505*8 +: 8], 1'b0, INIT[ 504*8 +: 8], 
+          1'b0, INIT[ 501*8 +: 8], 1'b0, INIT[ 500*8 +: 8], 1'b0, INIT[ 497*8 +: 8], 1'b0, INIT[ 496*8 +: 8], 
+          1'b0, INIT[ 493*8 +: 8], 1'b0, INIT[ 492*8 +: 8], 1'b0, INIT[ 489*8 +: 8], 1'b0, INIT[ 488*8 +: 8], 
+          1'b0, INIT[ 485*8 +: 8], 1'b0, INIT[ 484*8 +: 8], 1'b0, INIT[ 481*8 +: 8], 1'b0, INIT[ 480*8 +: 8], 
+          1'b0, INIT[ 477*8 +: 8], 1'b0, INIT[ 476*8 +: 8], 1'b0, INIT[ 473*8 +: 8], 1'b0, INIT[ 472*8 +: 8], 
+          1'b0, INIT[ 469*8 +: 8], 1'b0, INIT[ 468*8 +: 8], 1'b0, INIT[ 465*8 +: 8], 1'b0, INIT[ 464*8 +: 8], 
+          1'b0, INIT[ 461*8 +: 8], 1'b0, INIT[ 460*8 +: 8], 1'b0, INIT[ 457*8 +: 8], 1'b0, INIT[ 456*8 +: 8], 
+          1'b0, INIT[ 453*8 +: 8], 1'b0, INIT[ 452*8 +: 8], 1'b0, INIT[ 449*8 +: 8], 1'b0, INIT[ 448*8 +: 8], 
+          1'b0, INIT[ 445*8 +: 8], 1'b0, INIT[ 444*8 +: 8], 1'b0, INIT[ 441*8 +: 8], 1'b0, INIT[ 440*8 +: 8], 
+          1'b0, INIT[ 437*8 +: 8], 1'b0, INIT[ 436*8 +: 8], 1'b0, INIT[ 433*8 +: 8], 1'b0, INIT[ 432*8 +: 8], 
+          1'b0, INIT[ 429*8 +: 8], 1'b0, INIT[ 428*8 +: 8], 1'b0, INIT[ 425*8 +: 8], 1'b0, INIT[ 424*8 +: 8], 
+          1'b0, INIT[ 421*8 +: 8], 1'b0, INIT[ 420*8 +: 8], 1'b0, INIT[ 417*8 +: 8], 1'b0, INIT[ 416*8 +: 8], 
+          1'b0, INIT[ 413*8 +: 8], 1'b0, INIT[ 412*8 +: 8], 1'b0, INIT[ 409*8 +: 8], 1'b0, INIT[ 408*8 +: 8], 
+          1'b0, INIT[ 405*8 +: 8], 1'b0, INIT[ 404*8 +: 8], 1'b0, INIT[ 401*8 +: 8], 1'b0, INIT[ 400*8 +: 8], 
+          1'b0, INIT[ 397*8 +: 8], 1'b0, INIT[ 396*8 +: 8], 1'b0, INIT[ 393*8 +: 8], 1'b0, INIT[ 392*8 +: 8], 
+          1'b0, INIT[ 389*8 +: 8], 1'b0, INIT[ 388*8 +: 8], 1'b0, INIT[ 385*8 +: 8], 1'b0, INIT[ 384*8 +: 8], 
+          1'b0, INIT[ 381*8 +: 8], 1'b0, INIT[ 380*8 +: 8], 1'b0, INIT[ 377*8 +: 8], 1'b0, INIT[ 376*8 +: 8], 
+          1'b0, INIT[ 373*8 +: 8], 1'b0, INIT[ 372*8 +: 8], 1'b0, INIT[ 369*8 +: 8], 1'b0, INIT[ 368*8 +: 8], 
+          1'b0, INIT[ 365*8 +: 8], 1'b0, INIT[ 364*8 +: 8], 1'b0, INIT[ 361*8 +: 8], 1'b0, INIT[ 360*8 +: 8], 
+          1'b0, INIT[ 357*8 +: 8], 1'b0, INIT[ 356*8 +: 8], 1'b0, INIT[ 353*8 +: 8], 1'b0, INIT[ 352*8 +: 8], 
+          1'b0, INIT[ 349*8 +: 8], 1'b0, INIT[ 348*8 +: 8], 1'b0, INIT[ 345*8 +: 8], 1'b0, INIT[ 344*8 +: 8], 
+          1'b0, INIT[ 341*8 +: 8], 1'b0, INIT[ 340*8 +: 8], 1'b0, INIT[ 337*8 +: 8], 1'b0, INIT[ 336*8 +: 8], 
+          1'b0, INIT[ 333*8 +: 8], 1'b0, INIT[ 332*8 +: 8], 1'b0, INIT[ 329*8 +: 8], 1'b0, INIT[ 328*8 +: 8], 
+          1'b0, INIT[ 325*8 +: 8], 1'b0, INIT[ 324*8 +: 8], 1'b0, INIT[ 321*8 +: 8], 1'b0, INIT[ 320*8 +: 8], 
+          1'b0, INIT[ 317*8 +: 8], 1'b0, INIT[ 316*8 +: 8], 1'b0, INIT[ 313*8 +: 8], 1'b0, INIT[ 312*8 +: 8], 
+          1'b0, INIT[ 309*8 +: 8], 1'b0, INIT[ 308*8 +: 8], 1'b0, INIT[ 305*8 +: 8], 1'b0, INIT[ 304*8 +: 8], 
+          1'b0, INIT[ 301*8 +: 8], 1'b0, INIT[ 300*8 +: 8], 1'b0, INIT[ 297*8 +: 8], 1'b0, INIT[ 296*8 +: 8], 
+          1'b0, INIT[ 293*8 +: 8], 1'b0, INIT[ 292*8 +: 8], 1'b0, INIT[ 289*8 +: 8], 1'b0, INIT[ 288*8 +: 8], 
+          1'b0, INIT[ 285*8 +: 8], 1'b0, INIT[ 284*8 +: 8], 1'b0, INIT[ 281*8 +: 8], 1'b0, INIT[ 280*8 +: 8], 
+          1'b0, INIT[ 277*8 +: 8], 1'b0, INIT[ 276*8 +: 8], 1'b0, INIT[ 273*8 +: 8], 1'b0, INIT[ 272*8 +: 8], 
+          1'b0, INIT[ 269*8 +: 8], 1'b0, INIT[ 268*8 +: 8], 1'b0, INIT[ 265*8 +: 8], 1'b0, INIT[ 264*8 +: 8], 
+          1'b0, INIT[ 261*8 +: 8], 1'b0, INIT[ 260*8 +: 8], 1'b0, INIT[ 257*8 +: 8], 1'b0, INIT[ 256*8 +: 8], 
+          1'b0, INIT[ 253*8 +: 8], 1'b0, INIT[ 252*8 +: 8], 1'b0, INIT[ 249*8 +: 8], 1'b0, INIT[ 248*8 +: 8], 
+          1'b0, INIT[ 245*8 +: 8], 1'b0, INIT[ 244*8 +: 8], 1'b0, INIT[ 241*8 +: 8], 1'b0, INIT[ 240*8 +: 8], 
+          1'b0, INIT[ 237*8 +: 8], 1'b0, INIT[ 236*8 +: 8], 1'b0, INIT[ 233*8 +: 8], 1'b0, INIT[ 232*8 +: 8], 
+          1'b0, INIT[ 229*8 +: 8], 1'b0, INIT[ 228*8 +: 8], 1'b0, INIT[ 225*8 +: 8], 1'b0, INIT[ 224*8 +: 8], 
+          1'b0, INIT[ 221*8 +: 8], 1'b0, INIT[ 220*8 +: 8], 1'b0, INIT[ 217*8 +: 8], 1'b0, INIT[ 216*8 +: 8], 
+          1'b0, INIT[ 213*8 +: 8], 1'b0, INIT[ 212*8 +: 8], 1'b0, INIT[ 209*8 +: 8], 1'b0, INIT[ 208*8 +: 8], 
+          1'b0, INIT[ 205*8 +: 8], 1'b0, INIT[ 204*8 +: 8], 1'b0, INIT[ 201*8 +: 8], 1'b0, INIT[ 200*8 +: 8], 
+          1'b0, INIT[ 197*8 +: 8], 1'b0, INIT[ 196*8 +: 8], 1'b0, INIT[ 193*8 +: 8], 1'b0, INIT[ 192*8 +: 8], 
+          1'b0, INIT[ 189*8 +: 8], 1'b0, INIT[ 188*8 +: 8], 1'b0, INIT[ 185*8 +: 8], 1'b0, INIT[ 184*8 +: 8], 
+          1'b0, INIT[ 181*8 +: 8], 1'b0, INIT[ 180*8 +: 8], 1'b0, INIT[ 177*8 +: 8], 1'b0, INIT[ 176*8 +: 8], 
+          1'b0, INIT[ 173*8 +: 8], 1'b0, INIT[ 172*8 +: 8], 1'b0, INIT[ 169*8 +: 8], 1'b0, INIT[ 168*8 +: 8], 
+          1'b0, INIT[ 165*8 +: 8], 1'b0, INIT[ 164*8 +: 8], 1'b0, INIT[ 161*8 +: 8], 1'b0, INIT[ 160*8 +: 8], 
+          1'b0, INIT[ 157*8 +: 8], 1'b0, INIT[ 156*8 +: 8], 1'b0, INIT[ 153*8 +: 8], 1'b0, INIT[ 152*8 +: 8], 
+          1'b0, INIT[ 149*8 +: 8], 1'b0, INIT[ 148*8 +: 8], 1'b0, INIT[ 145*8 +: 8], 1'b0, INIT[ 144*8 +: 8], 
+          1'b0, INIT[ 141*8 +: 8], 1'b0, INIT[ 140*8 +: 8], 1'b0, INIT[ 137*8 +: 8], 1'b0, INIT[ 136*8 +: 8], 
+          1'b0, INIT[ 133*8 +: 8], 1'b0, INIT[ 132*8 +: 8], 1'b0, INIT[ 129*8 +: 8], 1'b0, INIT[ 128*8 +: 8], 
+          1'b0, INIT[ 125*8 +: 8], 1'b0, INIT[ 124*8 +: 8], 1'b0, INIT[ 121*8 +: 8], 1'b0, INIT[ 120*8 +: 8], 
+          1'b0, INIT[ 117*8 +: 8], 1'b0, INIT[ 116*8 +: 8], 1'b0, INIT[ 113*8 +: 8], 1'b0, INIT[ 112*8 +: 8], 
+          1'b0, INIT[ 109*8 +: 8], 1'b0, INIT[ 108*8 +: 8], 1'b0, INIT[ 105*8 +: 8], 1'b0, INIT[ 104*8 +: 8], 
+          1'b0, INIT[ 101*8 +: 8], 1'b0, INIT[ 100*8 +: 8], 1'b0, INIT[  97*8 +: 8], 1'b0, INIT[  96*8 +: 8], 
+          1'b0, INIT[  93*8 +: 8], 1'b0, INIT[  92*8 +: 8], 1'b0, INIT[  89*8 +: 8], 1'b0, INIT[  88*8 +: 8], 
+          1'b0, INIT[  85*8 +: 8], 1'b0, INIT[  84*8 +: 8], 1'b0, INIT[  81*8 +: 8], 1'b0, INIT[  80*8 +: 8], 
+          1'b0, INIT[  77*8 +: 8], 1'b0, INIT[  76*8 +: 8], 1'b0, INIT[  73*8 +: 8], 1'b0, INIT[  72*8 +: 8], 
+          1'b0, INIT[  69*8 +: 8], 1'b0, INIT[  68*8 +: 8], 1'b0, INIT[  65*8 +: 8], 1'b0, INIT[  64*8 +: 8], 
+          1'b0, INIT[  61*8 +: 8], 1'b0, INIT[  60*8 +: 8], 1'b0, INIT[  57*8 +: 8], 1'b0, INIT[  56*8 +: 8], 
+          1'b0, INIT[  53*8 +: 8], 1'b0, INIT[  52*8 +: 8], 1'b0, INIT[  49*8 +: 8], 1'b0, INIT[  48*8 +: 8], 
+          1'b0, INIT[  45*8 +: 8], 1'b0, INIT[  44*8 +: 8], 1'b0, INIT[  41*8 +: 8], 1'b0, INIT[  40*8 +: 8], 
+          1'b0, INIT[  37*8 +: 8], 1'b0, INIT[  36*8 +: 8], 1'b0, INIT[  33*8 +: 8], 1'b0, INIT[  32*8 +: 8], 
+          1'b0, INIT[  29*8 +: 8], 1'b0, INIT[  28*8 +: 8], 1'b0, INIT[  25*8 +: 8], 1'b0, INIT[  24*8 +: 8], 
+          1'b0, INIT[  21*8 +: 8], 1'b0, INIT[  20*8 +: 8], 1'b0, INIT[  17*8 +: 8], 1'b0, INIT[  16*8 +: 8], 
+          1'b0, INIT[  13*8 +: 8], 1'b0, INIT[  12*8 +: 8], 1'b0, INIT[   9*8 +: 8], 1'b0, INIT[   8*8 +: 8], 
+          1'b0, INIT[   5*8 +: 8], 1'b0, INIT[   4*8 +: 8], 1'b0, INIT[   1*8 +: 8], 1'b0, INIT[   0*8 +: 8]}),
diff --git a/yosys-plugins/ql-qlf/pp3/bram_init_8_16.vh b/yosys-plugins/ql-qlf/pp3/bram_init_8_16.vh
new file mode 100644
index 000000000..2de9f8b65
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/bram_init_8_16.vh
@@ -0,0 +1,512 @@
+.INIT({1'b0, INIT[2047*8 +: 8], 1'b0, INIT[2046*8 +: 8], 1'b0, INIT[2045*8 +: 8], 1'b0, INIT[2044*8 +: 8], 
+          1'b0, INIT[2043*8 +: 8], 1'b0, INIT[2042*8 +: 8], 1'b0, INIT[2041*8 +: 8], 1'b0, INIT[2040*8 +: 8], 
+          1'b0, INIT[2039*8 +: 8], 1'b0, INIT[2038*8 +: 8], 1'b0, INIT[2037*8 +: 8], 1'b0, INIT[2036*8 +: 8], 
+          1'b0, INIT[2035*8 +: 8], 1'b0, INIT[2034*8 +: 8], 1'b0, INIT[2033*8 +: 8], 1'b0, INIT[2032*8 +: 8], 
+          1'b0, INIT[2031*8 +: 8], 1'b0, INIT[2030*8 +: 8], 1'b0, INIT[2029*8 +: 8], 1'b0, INIT[2028*8 +: 8], 
+          1'b0, INIT[2027*8 +: 8], 1'b0, INIT[2026*8 +: 8], 1'b0, INIT[2025*8 +: 8], 1'b0, INIT[2024*8 +: 8], 
+          1'b0, INIT[2023*8 +: 8], 1'b0, INIT[2022*8 +: 8], 1'b0, INIT[2021*8 +: 8], 1'b0, INIT[2020*8 +: 8], 
+          1'b0, INIT[2019*8 +: 8], 1'b0, INIT[2018*8 +: 8], 1'b0, INIT[2017*8 +: 8], 1'b0, INIT[2016*8 +: 8], 
+          1'b0, INIT[2015*8 +: 8], 1'b0, INIT[2014*8 +: 8], 1'b0, INIT[2013*8 +: 8], 1'b0, INIT[2012*8 +: 8], 
+          1'b0, INIT[2011*8 +: 8], 1'b0, INIT[2010*8 +: 8], 1'b0, INIT[2009*8 +: 8], 1'b0, INIT[2008*8 +: 8], 
+          1'b0, INIT[2007*8 +: 8], 1'b0, INIT[2006*8 +: 8], 1'b0, INIT[2005*8 +: 8], 1'b0, INIT[2004*8 +: 8], 
+          1'b0, INIT[2003*8 +: 8], 1'b0, INIT[2002*8 +: 8], 1'b0, INIT[2001*8 +: 8], 1'b0, INIT[2000*8 +: 8], 
+          1'b0, INIT[1999*8 +: 8], 1'b0, INIT[1998*8 +: 8], 1'b0, INIT[1997*8 +: 8], 1'b0, INIT[1996*8 +: 8], 
+          1'b0, INIT[1995*8 +: 8], 1'b0, INIT[1994*8 +: 8], 1'b0, INIT[1993*8 +: 8], 1'b0, INIT[1992*8 +: 8], 
+          1'b0, INIT[1991*8 +: 8], 1'b0, INIT[1990*8 +: 8], 1'b0, INIT[1989*8 +: 8], 1'b0, INIT[1988*8 +: 8], 
+          1'b0, INIT[1987*8 +: 8], 1'b0, INIT[1986*8 +: 8], 1'b0, INIT[1985*8 +: 8], 1'b0, INIT[1984*8 +: 8], 
+          1'b0, INIT[1983*8 +: 8], 1'b0, INIT[1982*8 +: 8], 1'b0, INIT[1981*8 +: 8], 1'b0, INIT[1980*8 +: 8], 
+          1'b0, INIT[1979*8 +: 8], 1'b0, INIT[1978*8 +: 8], 1'b0, INIT[1977*8 +: 8], 1'b0, INIT[1976*8 +: 8], 
+          1'b0, INIT[1975*8 +: 8], 1'b0, INIT[1974*8 +: 8], 1'b0, INIT[1973*8 +: 8], 1'b0, INIT[1972*8 +: 8], 
+          1'b0, INIT[1971*8 +: 8], 1'b0, INIT[1970*8 +: 8], 1'b0, INIT[1969*8 +: 8], 1'b0, INIT[1968*8 +: 8], 
+          1'b0, INIT[1967*8 +: 8], 1'b0, INIT[1966*8 +: 8], 1'b0, INIT[1965*8 +: 8], 1'b0, INIT[1964*8 +: 8], 
+          1'b0, INIT[1963*8 +: 8], 1'b0, INIT[1962*8 +: 8], 1'b0, INIT[1961*8 +: 8], 1'b0, INIT[1960*8 +: 8], 
+          1'b0, INIT[1959*8 +: 8], 1'b0, INIT[1958*8 +: 8], 1'b0, INIT[1957*8 +: 8], 1'b0, INIT[1956*8 +: 8], 
+          1'b0, INIT[1955*8 +: 8], 1'b0, INIT[1954*8 +: 8], 1'b0, INIT[1953*8 +: 8], 1'b0, INIT[1952*8 +: 8], 
+          1'b0, INIT[1951*8 +: 8], 1'b0, INIT[1950*8 +: 8], 1'b0, INIT[1949*8 +: 8], 1'b0, INIT[1948*8 +: 8], 
+          1'b0, INIT[1947*8 +: 8], 1'b0, INIT[1946*8 +: 8], 1'b0, INIT[1945*8 +: 8], 1'b0, INIT[1944*8 +: 8], 
+          1'b0, INIT[1943*8 +: 8], 1'b0, INIT[1942*8 +: 8], 1'b0, INIT[1941*8 +: 8], 1'b0, INIT[1940*8 +: 8], 
+          1'b0, INIT[1939*8 +: 8], 1'b0, INIT[1938*8 +: 8], 1'b0, INIT[1937*8 +: 8], 1'b0, INIT[1936*8 +: 8], 
+          1'b0, INIT[1935*8 +: 8], 1'b0, INIT[1934*8 +: 8], 1'b0, INIT[1933*8 +: 8], 1'b0, INIT[1932*8 +: 8], 
+          1'b0, INIT[1931*8 +: 8], 1'b0, INIT[1930*8 +: 8], 1'b0, INIT[1929*8 +: 8], 1'b0, INIT[1928*8 +: 8], 
+          1'b0, INIT[1927*8 +: 8], 1'b0, INIT[1926*8 +: 8], 1'b0, INIT[1925*8 +: 8], 1'b0, INIT[1924*8 +: 8], 
+          1'b0, INIT[1923*8 +: 8], 1'b0, INIT[1922*8 +: 8], 1'b0, INIT[1921*8 +: 8], 1'b0, INIT[1920*8 +: 8], 
+          1'b0, INIT[1919*8 +: 8], 1'b0, INIT[1918*8 +: 8], 1'b0, INIT[1917*8 +: 8], 1'b0, INIT[1916*8 +: 8], 
+          1'b0, INIT[1915*8 +: 8], 1'b0, INIT[1914*8 +: 8], 1'b0, INIT[1913*8 +: 8], 1'b0, INIT[1912*8 +: 8], 
+          1'b0, INIT[1911*8 +: 8], 1'b0, INIT[1910*8 +: 8], 1'b0, INIT[1909*8 +: 8], 1'b0, INIT[1908*8 +: 8], 
+          1'b0, INIT[1907*8 +: 8], 1'b0, INIT[1906*8 +: 8], 1'b0, INIT[1905*8 +: 8], 1'b0, INIT[1904*8 +: 8], 
+          1'b0, INIT[1903*8 +: 8], 1'b0, INIT[1902*8 +: 8], 1'b0, INIT[1901*8 +: 8], 1'b0, INIT[1900*8 +: 8], 
+          1'b0, INIT[1899*8 +: 8], 1'b0, INIT[1898*8 +: 8], 1'b0, INIT[1897*8 +: 8], 1'b0, INIT[1896*8 +: 8], 
+          1'b0, INIT[1895*8 +: 8], 1'b0, INIT[1894*8 +: 8], 1'b0, INIT[1893*8 +: 8], 1'b0, INIT[1892*8 +: 8], 
+          1'b0, INIT[1891*8 +: 8], 1'b0, INIT[1890*8 +: 8], 1'b0, INIT[1889*8 +: 8], 1'b0, INIT[1888*8 +: 8], 
+          1'b0, INIT[1887*8 +: 8], 1'b0, INIT[1886*8 +: 8], 1'b0, INIT[1885*8 +: 8], 1'b0, INIT[1884*8 +: 8], 
+          1'b0, INIT[1883*8 +: 8], 1'b0, INIT[1882*8 +: 8], 1'b0, INIT[1881*8 +: 8], 1'b0, INIT[1880*8 +: 8], 
+          1'b0, INIT[1879*8 +: 8], 1'b0, INIT[1878*8 +: 8], 1'b0, INIT[1877*8 +: 8], 1'b0, INIT[1876*8 +: 8], 
+          1'b0, INIT[1875*8 +: 8], 1'b0, INIT[1874*8 +: 8], 1'b0, INIT[1873*8 +: 8], 1'b0, INIT[1872*8 +: 8], 
+          1'b0, INIT[1871*8 +: 8], 1'b0, INIT[1870*8 +: 8], 1'b0, INIT[1869*8 +: 8], 1'b0, INIT[1868*8 +: 8], 
+          1'b0, INIT[1867*8 +: 8], 1'b0, INIT[1866*8 +: 8], 1'b0, INIT[1865*8 +: 8], 1'b0, INIT[1864*8 +: 8], 
+          1'b0, INIT[1863*8 +: 8], 1'b0, INIT[1862*8 +: 8], 1'b0, INIT[1861*8 +: 8], 1'b0, INIT[1860*8 +: 8], 
+          1'b0, INIT[1859*8 +: 8], 1'b0, INIT[1858*8 +: 8], 1'b0, INIT[1857*8 +: 8], 1'b0, INIT[1856*8 +: 8], 
+          1'b0, INIT[1855*8 +: 8], 1'b0, INIT[1854*8 +: 8], 1'b0, INIT[1853*8 +: 8], 1'b0, INIT[1852*8 +: 8], 
+          1'b0, INIT[1851*8 +: 8], 1'b0, INIT[1850*8 +: 8], 1'b0, INIT[1849*8 +: 8], 1'b0, INIT[1848*8 +: 8], 
+          1'b0, INIT[1847*8 +: 8], 1'b0, INIT[1846*8 +: 8], 1'b0, INIT[1845*8 +: 8], 1'b0, INIT[1844*8 +: 8], 
+          1'b0, INIT[1843*8 +: 8], 1'b0, INIT[1842*8 +: 8], 1'b0, INIT[1841*8 +: 8], 1'b0, INIT[1840*8 +: 8], 
+          1'b0, INIT[1839*8 +: 8], 1'b0, INIT[1838*8 +: 8], 1'b0, INIT[1837*8 +: 8], 1'b0, INIT[1836*8 +: 8], 
+          1'b0, INIT[1835*8 +: 8], 1'b0, INIT[1834*8 +: 8], 1'b0, INIT[1833*8 +: 8], 1'b0, INIT[1832*8 +: 8], 
+          1'b0, INIT[1831*8 +: 8], 1'b0, INIT[1830*8 +: 8], 1'b0, INIT[1829*8 +: 8], 1'b0, INIT[1828*8 +: 8], 
+          1'b0, INIT[1827*8 +: 8], 1'b0, INIT[1826*8 +: 8], 1'b0, INIT[1825*8 +: 8], 1'b0, INIT[1824*8 +: 8], 
+          1'b0, INIT[1823*8 +: 8], 1'b0, INIT[1822*8 +: 8], 1'b0, INIT[1821*8 +: 8], 1'b0, INIT[1820*8 +: 8], 
+          1'b0, INIT[1819*8 +: 8], 1'b0, INIT[1818*8 +: 8], 1'b0, INIT[1817*8 +: 8], 1'b0, INIT[1816*8 +: 8], 
+          1'b0, INIT[1815*8 +: 8], 1'b0, INIT[1814*8 +: 8], 1'b0, INIT[1813*8 +: 8], 1'b0, INIT[1812*8 +: 8], 
+          1'b0, INIT[1811*8 +: 8], 1'b0, INIT[1810*8 +: 8], 1'b0, INIT[1809*8 +: 8], 1'b0, INIT[1808*8 +: 8], 
+          1'b0, INIT[1807*8 +: 8], 1'b0, INIT[1806*8 +: 8], 1'b0, INIT[1805*8 +: 8], 1'b0, INIT[1804*8 +: 8], 
+          1'b0, INIT[1803*8 +: 8], 1'b0, INIT[1802*8 +: 8], 1'b0, INIT[1801*8 +: 8], 1'b0, INIT[1800*8 +: 8], 
+          1'b0, INIT[1799*8 +: 8], 1'b0, INIT[1798*8 +: 8], 1'b0, INIT[1797*8 +: 8], 1'b0, INIT[1796*8 +: 8], 
+          1'b0, INIT[1795*8 +: 8], 1'b0, INIT[1794*8 +: 8], 1'b0, INIT[1793*8 +: 8], 1'b0, INIT[1792*8 +: 8], 
+          1'b0, INIT[1791*8 +: 8], 1'b0, INIT[1790*8 +: 8], 1'b0, INIT[1789*8 +: 8], 1'b0, INIT[1788*8 +: 8], 
+          1'b0, INIT[1787*8 +: 8], 1'b0, INIT[1786*8 +: 8], 1'b0, INIT[1785*8 +: 8], 1'b0, INIT[1784*8 +: 8], 
+          1'b0, INIT[1783*8 +: 8], 1'b0, INIT[1782*8 +: 8], 1'b0, INIT[1781*8 +: 8], 1'b0, INIT[1780*8 +: 8], 
+          1'b0, INIT[1779*8 +: 8], 1'b0, INIT[1778*8 +: 8], 1'b0, INIT[1777*8 +: 8], 1'b0, INIT[1776*8 +: 8], 
+          1'b0, INIT[1775*8 +: 8], 1'b0, INIT[1774*8 +: 8], 1'b0, INIT[1773*8 +: 8], 1'b0, INIT[1772*8 +: 8], 
+          1'b0, INIT[1771*8 +: 8], 1'b0, INIT[1770*8 +: 8], 1'b0, INIT[1769*8 +: 8], 1'b0, INIT[1768*8 +: 8], 
+          1'b0, INIT[1767*8 +: 8], 1'b0, INIT[1766*8 +: 8], 1'b0, INIT[1765*8 +: 8], 1'b0, INIT[1764*8 +: 8], 
+          1'b0, INIT[1763*8 +: 8], 1'b0, INIT[1762*8 +: 8], 1'b0, INIT[1761*8 +: 8], 1'b0, INIT[1760*8 +: 8], 
+          1'b0, INIT[1759*8 +: 8], 1'b0, INIT[1758*8 +: 8], 1'b0, INIT[1757*8 +: 8], 1'b0, INIT[1756*8 +: 8], 
+          1'b0, INIT[1755*8 +: 8], 1'b0, INIT[1754*8 +: 8], 1'b0, INIT[1753*8 +: 8], 1'b0, INIT[1752*8 +: 8], 
+          1'b0, INIT[1751*8 +: 8], 1'b0, INIT[1750*8 +: 8], 1'b0, INIT[1749*8 +: 8], 1'b0, INIT[1748*8 +: 8], 
+          1'b0, INIT[1747*8 +: 8], 1'b0, INIT[1746*8 +: 8], 1'b0, INIT[1745*8 +: 8], 1'b0, INIT[1744*8 +: 8], 
+          1'b0, INIT[1743*8 +: 8], 1'b0, INIT[1742*8 +: 8], 1'b0, INIT[1741*8 +: 8], 1'b0, INIT[1740*8 +: 8], 
+          1'b0, INIT[1739*8 +: 8], 1'b0, INIT[1738*8 +: 8], 1'b0, INIT[1737*8 +: 8], 1'b0, INIT[1736*8 +: 8], 
+          1'b0, INIT[1735*8 +: 8], 1'b0, INIT[1734*8 +: 8], 1'b0, INIT[1733*8 +: 8], 1'b0, INIT[1732*8 +: 8], 
+          1'b0, INIT[1731*8 +: 8], 1'b0, INIT[1730*8 +: 8], 1'b0, INIT[1729*8 +: 8], 1'b0, INIT[1728*8 +: 8], 
+          1'b0, INIT[1727*8 +: 8], 1'b0, INIT[1726*8 +: 8], 1'b0, INIT[1725*8 +: 8], 1'b0, INIT[1724*8 +: 8], 
+          1'b0, INIT[1723*8 +: 8], 1'b0, INIT[1722*8 +: 8], 1'b0, INIT[1721*8 +: 8], 1'b0, INIT[1720*8 +: 8], 
+          1'b0, INIT[1719*8 +: 8], 1'b0, INIT[1718*8 +: 8], 1'b0, INIT[1717*8 +: 8], 1'b0, INIT[1716*8 +: 8], 
+          1'b0, INIT[1715*8 +: 8], 1'b0, INIT[1714*8 +: 8], 1'b0, INIT[1713*8 +: 8], 1'b0, INIT[1712*8 +: 8], 
+          1'b0, INIT[1711*8 +: 8], 1'b0, INIT[1710*8 +: 8], 1'b0, INIT[1709*8 +: 8], 1'b0, INIT[1708*8 +: 8], 
+          1'b0, INIT[1707*8 +: 8], 1'b0, INIT[1706*8 +: 8], 1'b0, INIT[1705*8 +: 8], 1'b0, INIT[1704*8 +: 8], 
+          1'b0, INIT[1703*8 +: 8], 1'b0, INIT[1702*8 +: 8], 1'b0, INIT[1701*8 +: 8], 1'b0, INIT[1700*8 +: 8], 
+          1'b0, INIT[1699*8 +: 8], 1'b0, INIT[1698*8 +: 8], 1'b0, INIT[1697*8 +: 8], 1'b0, INIT[1696*8 +: 8], 
+          1'b0, INIT[1695*8 +: 8], 1'b0, INIT[1694*8 +: 8], 1'b0, INIT[1693*8 +: 8], 1'b0, INIT[1692*8 +: 8], 
+          1'b0, INIT[1691*8 +: 8], 1'b0, INIT[1690*8 +: 8], 1'b0, INIT[1689*8 +: 8], 1'b0, INIT[1688*8 +: 8], 
+          1'b0, INIT[1687*8 +: 8], 1'b0, INIT[1686*8 +: 8], 1'b0, INIT[1685*8 +: 8], 1'b0, INIT[1684*8 +: 8], 
+          1'b0, INIT[1683*8 +: 8], 1'b0, INIT[1682*8 +: 8], 1'b0, INIT[1681*8 +: 8], 1'b0, INIT[1680*8 +: 8], 
+          1'b0, INIT[1679*8 +: 8], 1'b0, INIT[1678*8 +: 8], 1'b0, INIT[1677*8 +: 8], 1'b0, INIT[1676*8 +: 8], 
+          1'b0, INIT[1675*8 +: 8], 1'b0, INIT[1674*8 +: 8], 1'b0, INIT[1673*8 +: 8], 1'b0, INIT[1672*8 +: 8], 
+          1'b0, INIT[1671*8 +: 8], 1'b0, INIT[1670*8 +: 8], 1'b0, INIT[1669*8 +: 8], 1'b0, INIT[1668*8 +: 8], 
+          1'b0, INIT[1667*8 +: 8], 1'b0, INIT[1666*8 +: 8], 1'b0, INIT[1665*8 +: 8], 1'b0, INIT[1664*8 +: 8], 
+          1'b0, INIT[1663*8 +: 8], 1'b0, INIT[1662*8 +: 8], 1'b0, INIT[1661*8 +: 8], 1'b0, INIT[1660*8 +: 8], 
+          1'b0, INIT[1659*8 +: 8], 1'b0, INIT[1658*8 +: 8], 1'b0, INIT[1657*8 +: 8], 1'b0, INIT[1656*8 +: 8], 
+          1'b0, INIT[1655*8 +: 8], 1'b0, INIT[1654*8 +: 8], 1'b0, INIT[1653*8 +: 8], 1'b0, INIT[1652*8 +: 8], 
+          1'b0, INIT[1651*8 +: 8], 1'b0, INIT[1650*8 +: 8], 1'b0, INIT[1649*8 +: 8], 1'b0, INIT[1648*8 +: 8], 
+          1'b0, INIT[1647*8 +: 8], 1'b0, INIT[1646*8 +: 8], 1'b0, INIT[1645*8 +: 8], 1'b0, INIT[1644*8 +: 8], 
+          1'b0, INIT[1643*8 +: 8], 1'b0, INIT[1642*8 +: 8], 1'b0, INIT[1641*8 +: 8], 1'b0, INIT[1640*8 +: 8], 
+          1'b0, INIT[1639*8 +: 8], 1'b0, INIT[1638*8 +: 8], 1'b0, INIT[1637*8 +: 8], 1'b0, INIT[1636*8 +: 8], 
+          1'b0, INIT[1635*8 +: 8], 1'b0, INIT[1634*8 +: 8], 1'b0, INIT[1633*8 +: 8], 1'b0, INIT[1632*8 +: 8], 
+          1'b0, INIT[1631*8 +: 8], 1'b0, INIT[1630*8 +: 8], 1'b0, INIT[1629*8 +: 8], 1'b0, INIT[1628*8 +: 8], 
+          1'b0, INIT[1627*8 +: 8], 1'b0, INIT[1626*8 +: 8], 1'b0, INIT[1625*8 +: 8], 1'b0, INIT[1624*8 +: 8], 
+          1'b0, INIT[1623*8 +: 8], 1'b0, INIT[1622*8 +: 8], 1'b0, INIT[1621*8 +: 8], 1'b0, INIT[1620*8 +: 8], 
+          1'b0, INIT[1619*8 +: 8], 1'b0, INIT[1618*8 +: 8], 1'b0, INIT[1617*8 +: 8], 1'b0, INIT[1616*8 +: 8], 
+          1'b0, INIT[1615*8 +: 8], 1'b0, INIT[1614*8 +: 8], 1'b0, INIT[1613*8 +: 8], 1'b0, INIT[1612*8 +: 8], 
+          1'b0, INIT[1611*8 +: 8], 1'b0, INIT[1610*8 +: 8], 1'b0, INIT[1609*8 +: 8], 1'b0, INIT[1608*8 +: 8], 
+          1'b0, INIT[1607*8 +: 8], 1'b0, INIT[1606*8 +: 8], 1'b0, INIT[1605*8 +: 8], 1'b0, INIT[1604*8 +: 8], 
+          1'b0, INIT[1603*8 +: 8], 1'b0, INIT[1602*8 +: 8], 1'b0, INIT[1601*8 +: 8], 1'b0, INIT[1600*8 +: 8], 
+          1'b0, INIT[1599*8 +: 8], 1'b0, INIT[1598*8 +: 8], 1'b0, INIT[1597*8 +: 8], 1'b0, INIT[1596*8 +: 8], 
+          1'b0, INIT[1595*8 +: 8], 1'b0, INIT[1594*8 +: 8], 1'b0, INIT[1593*8 +: 8], 1'b0, INIT[1592*8 +: 8], 
+          1'b0, INIT[1591*8 +: 8], 1'b0, INIT[1590*8 +: 8], 1'b0, INIT[1589*8 +: 8], 1'b0, INIT[1588*8 +: 8], 
+          1'b0, INIT[1587*8 +: 8], 1'b0, INIT[1586*8 +: 8], 1'b0, INIT[1585*8 +: 8], 1'b0, INIT[1584*8 +: 8], 
+          1'b0, INIT[1583*8 +: 8], 1'b0, INIT[1582*8 +: 8], 1'b0, INIT[1581*8 +: 8], 1'b0, INIT[1580*8 +: 8], 
+          1'b0, INIT[1579*8 +: 8], 1'b0, INIT[1578*8 +: 8], 1'b0, INIT[1577*8 +: 8], 1'b0, INIT[1576*8 +: 8], 
+          1'b0, INIT[1575*8 +: 8], 1'b0, INIT[1574*8 +: 8], 1'b0, INIT[1573*8 +: 8], 1'b0, INIT[1572*8 +: 8], 
+          1'b0, INIT[1571*8 +: 8], 1'b0, INIT[1570*8 +: 8], 1'b0, INIT[1569*8 +: 8], 1'b0, INIT[1568*8 +: 8], 
+          1'b0, INIT[1567*8 +: 8], 1'b0, INIT[1566*8 +: 8], 1'b0, INIT[1565*8 +: 8], 1'b0, INIT[1564*8 +: 8], 
+          1'b0, INIT[1563*8 +: 8], 1'b0, INIT[1562*8 +: 8], 1'b0, INIT[1561*8 +: 8], 1'b0, INIT[1560*8 +: 8], 
+          1'b0, INIT[1559*8 +: 8], 1'b0, INIT[1558*8 +: 8], 1'b0, INIT[1557*8 +: 8], 1'b0, INIT[1556*8 +: 8], 
+          1'b0, INIT[1555*8 +: 8], 1'b0, INIT[1554*8 +: 8], 1'b0, INIT[1553*8 +: 8], 1'b0, INIT[1552*8 +: 8], 
+          1'b0, INIT[1551*8 +: 8], 1'b0, INIT[1550*8 +: 8], 1'b0, INIT[1549*8 +: 8], 1'b0, INIT[1548*8 +: 8], 
+          1'b0, INIT[1547*8 +: 8], 1'b0, INIT[1546*8 +: 8], 1'b0, INIT[1545*8 +: 8], 1'b0, INIT[1544*8 +: 8], 
+          1'b0, INIT[1543*8 +: 8], 1'b0, INIT[1542*8 +: 8], 1'b0, INIT[1541*8 +: 8], 1'b0, INIT[1540*8 +: 8], 
+          1'b0, INIT[1539*8 +: 8], 1'b0, INIT[1538*8 +: 8], 1'b0, INIT[1537*8 +: 8], 1'b0, INIT[1536*8 +: 8], 
+          1'b0, INIT[1535*8 +: 8], 1'b0, INIT[1534*8 +: 8], 1'b0, INIT[1533*8 +: 8], 1'b0, INIT[1532*8 +: 8], 
+          1'b0, INIT[1531*8 +: 8], 1'b0, INIT[1530*8 +: 8], 1'b0, INIT[1529*8 +: 8], 1'b0, INIT[1528*8 +: 8], 
+          1'b0, INIT[1527*8 +: 8], 1'b0, INIT[1526*8 +: 8], 1'b0, INIT[1525*8 +: 8], 1'b0, INIT[1524*8 +: 8], 
+          1'b0, INIT[1523*8 +: 8], 1'b0, INIT[1522*8 +: 8], 1'b0, INIT[1521*8 +: 8], 1'b0, INIT[1520*8 +: 8], 
+          1'b0, INIT[1519*8 +: 8], 1'b0, INIT[1518*8 +: 8], 1'b0, INIT[1517*8 +: 8], 1'b0, INIT[1516*8 +: 8], 
+          1'b0, INIT[1515*8 +: 8], 1'b0, INIT[1514*8 +: 8], 1'b0, INIT[1513*8 +: 8], 1'b0, INIT[1512*8 +: 8], 
+          1'b0, INIT[1511*8 +: 8], 1'b0, INIT[1510*8 +: 8], 1'b0, INIT[1509*8 +: 8], 1'b0, INIT[1508*8 +: 8], 
+          1'b0, INIT[1507*8 +: 8], 1'b0, INIT[1506*8 +: 8], 1'b0, INIT[1505*8 +: 8], 1'b0, INIT[1504*8 +: 8], 
+          1'b0, INIT[1503*8 +: 8], 1'b0, INIT[1502*8 +: 8], 1'b0, INIT[1501*8 +: 8], 1'b0, INIT[1500*8 +: 8], 
+          1'b0, INIT[1499*8 +: 8], 1'b0, INIT[1498*8 +: 8], 1'b0, INIT[1497*8 +: 8], 1'b0, INIT[1496*8 +: 8], 
+          1'b0, INIT[1495*8 +: 8], 1'b0, INIT[1494*8 +: 8], 1'b0, INIT[1493*8 +: 8], 1'b0, INIT[1492*8 +: 8], 
+          1'b0, INIT[1491*8 +: 8], 1'b0, INIT[1490*8 +: 8], 1'b0, INIT[1489*8 +: 8], 1'b0, INIT[1488*8 +: 8], 
+          1'b0, INIT[1487*8 +: 8], 1'b0, INIT[1486*8 +: 8], 1'b0, INIT[1485*8 +: 8], 1'b0, INIT[1484*8 +: 8], 
+          1'b0, INIT[1483*8 +: 8], 1'b0, INIT[1482*8 +: 8], 1'b0, INIT[1481*8 +: 8], 1'b0, INIT[1480*8 +: 8], 
+          1'b0, INIT[1479*8 +: 8], 1'b0, INIT[1478*8 +: 8], 1'b0, INIT[1477*8 +: 8], 1'b0, INIT[1476*8 +: 8], 
+          1'b0, INIT[1475*8 +: 8], 1'b0, INIT[1474*8 +: 8], 1'b0, INIT[1473*8 +: 8], 1'b0, INIT[1472*8 +: 8], 
+          1'b0, INIT[1471*8 +: 8], 1'b0, INIT[1470*8 +: 8], 1'b0, INIT[1469*8 +: 8], 1'b0, INIT[1468*8 +: 8], 
+          1'b0, INIT[1467*8 +: 8], 1'b0, INIT[1466*8 +: 8], 1'b0, INIT[1465*8 +: 8], 1'b0, INIT[1464*8 +: 8], 
+          1'b0, INIT[1463*8 +: 8], 1'b0, INIT[1462*8 +: 8], 1'b0, INIT[1461*8 +: 8], 1'b0, INIT[1460*8 +: 8], 
+          1'b0, INIT[1459*8 +: 8], 1'b0, INIT[1458*8 +: 8], 1'b0, INIT[1457*8 +: 8], 1'b0, INIT[1456*8 +: 8], 
+          1'b0, INIT[1455*8 +: 8], 1'b0, INIT[1454*8 +: 8], 1'b0, INIT[1453*8 +: 8], 1'b0, INIT[1452*8 +: 8], 
+          1'b0, INIT[1451*8 +: 8], 1'b0, INIT[1450*8 +: 8], 1'b0, INIT[1449*8 +: 8], 1'b0, INIT[1448*8 +: 8], 
+          1'b0, INIT[1447*8 +: 8], 1'b0, INIT[1446*8 +: 8], 1'b0, INIT[1445*8 +: 8], 1'b0, INIT[1444*8 +: 8], 
+          1'b0, INIT[1443*8 +: 8], 1'b0, INIT[1442*8 +: 8], 1'b0, INIT[1441*8 +: 8], 1'b0, INIT[1440*8 +: 8], 
+          1'b0, INIT[1439*8 +: 8], 1'b0, INIT[1438*8 +: 8], 1'b0, INIT[1437*8 +: 8], 1'b0, INIT[1436*8 +: 8], 
+          1'b0, INIT[1435*8 +: 8], 1'b0, INIT[1434*8 +: 8], 1'b0, INIT[1433*8 +: 8], 1'b0, INIT[1432*8 +: 8], 
+          1'b0, INIT[1431*8 +: 8], 1'b0, INIT[1430*8 +: 8], 1'b0, INIT[1429*8 +: 8], 1'b0, INIT[1428*8 +: 8], 
+          1'b0, INIT[1427*8 +: 8], 1'b0, INIT[1426*8 +: 8], 1'b0, INIT[1425*8 +: 8], 1'b0, INIT[1424*8 +: 8], 
+          1'b0, INIT[1423*8 +: 8], 1'b0, INIT[1422*8 +: 8], 1'b0, INIT[1421*8 +: 8], 1'b0, INIT[1420*8 +: 8], 
+          1'b0, INIT[1419*8 +: 8], 1'b0, INIT[1418*8 +: 8], 1'b0, INIT[1417*8 +: 8], 1'b0, INIT[1416*8 +: 8], 
+          1'b0, INIT[1415*8 +: 8], 1'b0, INIT[1414*8 +: 8], 1'b0, INIT[1413*8 +: 8], 1'b0, INIT[1412*8 +: 8], 
+          1'b0, INIT[1411*8 +: 8], 1'b0, INIT[1410*8 +: 8], 1'b0, INIT[1409*8 +: 8], 1'b0, INIT[1408*8 +: 8], 
+          1'b0, INIT[1407*8 +: 8], 1'b0, INIT[1406*8 +: 8], 1'b0, INIT[1405*8 +: 8], 1'b0, INIT[1404*8 +: 8], 
+          1'b0, INIT[1403*8 +: 8], 1'b0, INIT[1402*8 +: 8], 1'b0, INIT[1401*8 +: 8], 1'b0, INIT[1400*8 +: 8], 
+          1'b0, INIT[1399*8 +: 8], 1'b0, INIT[1398*8 +: 8], 1'b0, INIT[1397*8 +: 8], 1'b0, INIT[1396*8 +: 8], 
+          1'b0, INIT[1395*8 +: 8], 1'b0, INIT[1394*8 +: 8], 1'b0, INIT[1393*8 +: 8], 1'b0, INIT[1392*8 +: 8], 
+          1'b0, INIT[1391*8 +: 8], 1'b0, INIT[1390*8 +: 8], 1'b0, INIT[1389*8 +: 8], 1'b0, INIT[1388*8 +: 8], 
+          1'b0, INIT[1387*8 +: 8], 1'b0, INIT[1386*8 +: 8], 1'b0, INIT[1385*8 +: 8], 1'b0, INIT[1384*8 +: 8], 
+          1'b0, INIT[1383*8 +: 8], 1'b0, INIT[1382*8 +: 8], 1'b0, INIT[1381*8 +: 8], 1'b0, INIT[1380*8 +: 8], 
+          1'b0, INIT[1379*8 +: 8], 1'b0, INIT[1378*8 +: 8], 1'b0, INIT[1377*8 +: 8], 1'b0, INIT[1376*8 +: 8], 
+          1'b0, INIT[1375*8 +: 8], 1'b0, INIT[1374*8 +: 8], 1'b0, INIT[1373*8 +: 8], 1'b0, INIT[1372*8 +: 8], 
+          1'b0, INIT[1371*8 +: 8], 1'b0, INIT[1370*8 +: 8], 1'b0, INIT[1369*8 +: 8], 1'b0, INIT[1368*8 +: 8], 
+          1'b0, INIT[1367*8 +: 8], 1'b0, INIT[1366*8 +: 8], 1'b0, INIT[1365*8 +: 8], 1'b0, INIT[1364*8 +: 8], 
+          1'b0, INIT[1363*8 +: 8], 1'b0, INIT[1362*8 +: 8], 1'b0, INIT[1361*8 +: 8], 1'b0, INIT[1360*8 +: 8], 
+          1'b0, INIT[1359*8 +: 8], 1'b0, INIT[1358*8 +: 8], 1'b0, INIT[1357*8 +: 8], 1'b0, INIT[1356*8 +: 8], 
+          1'b0, INIT[1355*8 +: 8], 1'b0, INIT[1354*8 +: 8], 1'b0, INIT[1353*8 +: 8], 1'b0, INIT[1352*8 +: 8], 
+          1'b0, INIT[1351*8 +: 8], 1'b0, INIT[1350*8 +: 8], 1'b0, INIT[1349*8 +: 8], 1'b0, INIT[1348*8 +: 8], 
+          1'b0, INIT[1347*8 +: 8], 1'b0, INIT[1346*8 +: 8], 1'b0, INIT[1345*8 +: 8], 1'b0, INIT[1344*8 +: 8], 
+          1'b0, INIT[1343*8 +: 8], 1'b0, INIT[1342*8 +: 8], 1'b0, INIT[1341*8 +: 8], 1'b0, INIT[1340*8 +: 8], 
+          1'b0, INIT[1339*8 +: 8], 1'b0, INIT[1338*8 +: 8], 1'b0, INIT[1337*8 +: 8], 1'b0, INIT[1336*8 +: 8], 
+          1'b0, INIT[1335*8 +: 8], 1'b0, INIT[1334*8 +: 8], 1'b0, INIT[1333*8 +: 8], 1'b0, INIT[1332*8 +: 8], 
+          1'b0, INIT[1331*8 +: 8], 1'b0, INIT[1330*8 +: 8], 1'b0, INIT[1329*8 +: 8], 1'b0, INIT[1328*8 +: 8], 
+          1'b0, INIT[1327*8 +: 8], 1'b0, INIT[1326*8 +: 8], 1'b0, INIT[1325*8 +: 8], 1'b0, INIT[1324*8 +: 8], 
+          1'b0, INIT[1323*8 +: 8], 1'b0, INIT[1322*8 +: 8], 1'b0, INIT[1321*8 +: 8], 1'b0, INIT[1320*8 +: 8], 
+          1'b0, INIT[1319*8 +: 8], 1'b0, INIT[1318*8 +: 8], 1'b0, INIT[1317*8 +: 8], 1'b0, INIT[1316*8 +: 8], 
+          1'b0, INIT[1315*8 +: 8], 1'b0, INIT[1314*8 +: 8], 1'b0, INIT[1313*8 +: 8], 1'b0, INIT[1312*8 +: 8], 
+          1'b0, INIT[1311*8 +: 8], 1'b0, INIT[1310*8 +: 8], 1'b0, INIT[1309*8 +: 8], 1'b0, INIT[1308*8 +: 8], 
+          1'b0, INIT[1307*8 +: 8], 1'b0, INIT[1306*8 +: 8], 1'b0, INIT[1305*8 +: 8], 1'b0, INIT[1304*8 +: 8], 
+          1'b0, INIT[1303*8 +: 8], 1'b0, INIT[1302*8 +: 8], 1'b0, INIT[1301*8 +: 8], 1'b0, INIT[1300*8 +: 8], 
+          1'b0, INIT[1299*8 +: 8], 1'b0, INIT[1298*8 +: 8], 1'b0, INIT[1297*8 +: 8], 1'b0, INIT[1296*8 +: 8], 
+          1'b0, INIT[1295*8 +: 8], 1'b0, INIT[1294*8 +: 8], 1'b0, INIT[1293*8 +: 8], 1'b0, INIT[1292*8 +: 8], 
+          1'b0, INIT[1291*8 +: 8], 1'b0, INIT[1290*8 +: 8], 1'b0, INIT[1289*8 +: 8], 1'b0, INIT[1288*8 +: 8], 
+          1'b0, INIT[1287*8 +: 8], 1'b0, INIT[1286*8 +: 8], 1'b0, INIT[1285*8 +: 8], 1'b0, INIT[1284*8 +: 8], 
+          1'b0, INIT[1283*8 +: 8], 1'b0, INIT[1282*8 +: 8], 1'b0, INIT[1281*8 +: 8], 1'b0, INIT[1280*8 +: 8], 
+          1'b0, INIT[1279*8 +: 8], 1'b0, INIT[1278*8 +: 8], 1'b0, INIT[1277*8 +: 8], 1'b0, INIT[1276*8 +: 8], 
+          1'b0, INIT[1275*8 +: 8], 1'b0, INIT[1274*8 +: 8], 1'b0, INIT[1273*8 +: 8], 1'b0, INIT[1272*8 +: 8], 
+          1'b0, INIT[1271*8 +: 8], 1'b0, INIT[1270*8 +: 8], 1'b0, INIT[1269*8 +: 8], 1'b0, INIT[1268*8 +: 8], 
+          1'b0, INIT[1267*8 +: 8], 1'b0, INIT[1266*8 +: 8], 1'b0, INIT[1265*8 +: 8], 1'b0, INIT[1264*8 +: 8], 
+          1'b0, INIT[1263*8 +: 8], 1'b0, INIT[1262*8 +: 8], 1'b0, INIT[1261*8 +: 8], 1'b0, INIT[1260*8 +: 8], 
+          1'b0, INIT[1259*8 +: 8], 1'b0, INIT[1258*8 +: 8], 1'b0, INIT[1257*8 +: 8], 1'b0, INIT[1256*8 +: 8], 
+          1'b0, INIT[1255*8 +: 8], 1'b0, INIT[1254*8 +: 8], 1'b0, INIT[1253*8 +: 8], 1'b0, INIT[1252*8 +: 8], 
+          1'b0, INIT[1251*8 +: 8], 1'b0, INIT[1250*8 +: 8], 1'b0, INIT[1249*8 +: 8], 1'b0, INIT[1248*8 +: 8], 
+          1'b0, INIT[1247*8 +: 8], 1'b0, INIT[1246*8 +: 8], 1'b0, INIT[1245*8 +: 8], 1'b0, INIT[1244*8 +: 8], 
+          1'b0, INIT[1243*8 +: 8], 1'b0, INIT[1242*8 +: 8], 1'b0, INIT[1241*8 +: 8], 1'b0, INIT[1240*8 +: 8], 
+          1'b0, INIT[1239*8 +: 8], 1'b0, INIT[1238*8 +: 8], 1'b0, INIT[1237*8 +: 8], 1'b0, INIT[1236*8 +: 8], 
+          1'b0, INIT[1235*8 +: 8], 1'b0, INIT[1234*8 +: 8], 1'b0, INIT[1233*8 +: 8], 1'b0, INIT[1232*8 +: 8], 
+          1'b0, INIT[1231*8 +: 8], 1'b0, INIT[1230*8 +: 8], 1'b0, INIT[1229*8 +: 8], 1'b0, INIT[1228*8 +: 8], 
+          1'b0, INIT[1227*8 +: 8], 1'b0, INIT[1226*8 +: 8], 1'b0, INIT[1225*8 +: 8], 1'b0, INIT[1224*8 +: 8], 
+          1'b0, INIT[1223*8 +: 8], 1'b0, INIT[1222*8 +: 8], 1'b0, INIT[1221*8 +: 8], 1'b0, INIT[1220*8 +: 8], 
+          1'b0, INIT[1219*8 +: 8], 1'b0, INIT[1218*8 +: 8], 1'b0, INIT[1217*8 +: 8], 1'b0, INIT[1216*8 +: 8], 
+          1'b0, INIT[1215*8 +: 8], 1'b0, INIT[1214*8 +: 8], 1'b0, INIT[1213*8 +: 8], 1'b0, INIT[1212*8 +: 8], 
+          1'b0, INIT[1211*8 +: 8], 1'b0, INIT[1210*8 +: 8], 1'b0, INIT[1209*8 +: 8], 1'b0, INIT[1208*8 +: 8], 
+          1'b0, INIT[1207*8 +: 8], 1'b0, INIT[1206*8 +: 8], 1'b0, INIT[1205*8 +: 8], 1'b0, INIT[1204*8 +: 8], 
+          1'b0, INIT[1203*8 +: 8], 1'b0, INIT[1202*8 +: 8], 1'b0, INIT[1201*8 +: 8], 1'b0, INIT[1200*8 +: 8], 
+          1'b0, INIT[1199*8 +: 8], 1'b0, INIT[1198*8 +: 8], 1'b0, INIT[1197*8 +: 8], 1'b0, INIT[1196*8 +: 8], 
+          1'b0, INIT[1195*8 +: 8], 1'b0, INIT[1194*8 +: 8], 1'b0, INIT[1193*8 +: 8], 1'b0, INIT[1192*8 +: 8], 
+          1'b0, INIT[1191*8 +: 8], 1'b0, INIT[1190*8 +: 8], 1'b0, INIT[1189*8 +: 8], 1'b0, INIT[1188*8 +: 8], 
+          1'b0, INIT[1187*8 +: 8], 1'b0, INIT[1186*8 +: 8], 1'b0, INIT[1185*8 +: 8], 1'b0, INIT[1184*8 +: 8], 
+          1'b0, INIT[1183*8 +: 8], 1'b0, INIT[1182*8 +: 8], 1'b0, INIT[1181*8 +: 8], 1'b0, INIT[1180*8 +: 8], 
+          1'b0, INIT[1179*8 +: 8], 1'b0, INIT[1178*8 +: 8], 1'b0, INIT[1177*8 +: 8], 1'b0, INIT[1176*8 +: 8], 
+          1'b0, INIT[1175*8 +: 8], 1'b0, INIT[1174*8 +: 8], 1'b0, INIT[1173*8 +: 8], 1'b0, INIT[1172*8 +: 8], 
+          1'b0, INIT[1171*8 +: 8], 1'b0, INIT[1170*8 +: 8], 1'b0, INIT[1169*8 +: 8], 1'b0, INIT[1168*8 +: 8], 
+          1'b0, INIT[1167*8 +: 8], 1'b0, INIT[1166*8 +: 8], 1'b0, INIT[1165*8 +: 8], 1'b0, INIT[1164*8 +: 8], 
+          1'b0, INIT[1163*8 +: 8], 1'b0, INIT[1162*8 +: 8], 1'b0, INIT[1161*8 +: 8], 1'b0, INIT[1160*8 +: 8], 
+          1'b0, INIT[1159*8 +: 8], 1'b0, INIT[1158*8 +: 8], 1'b0, INIT[1157*8 +: 8], 1'b0, INIT[1156*8 +: 8], 
+          1'b0, INIT[1155*8 +: 8], 1'b0, INIT[1154*8 +: 8], 1'b0, INIT[1153*8 +: 8], 1'b0, INIT[1152*8 +: 8], 
+          1'b0, INIT[1151*8 +: 8], 1'b0, INIT[1150*8 +: 8], 1'b0, INIT[1149*8 +: 8], 1'b0, INIT[1148*8 +: 8], 
+          1'b0, INIT[1147*8 +: 8], 1'b0, INIT[1146*8 +: 8], 1'b0, INIT[1145*8 +: 8], 1'b0, INIT[1144*8 +: 8], 
+          1'b0, INIT[1143*8 +: 8], 1'b0, INIT[1142*8 +: 8], 1'b0, INIT[1141*8 +: 8], 1'b0, INIT[1140*8 +: 8], 
+          1'b0, INIT[1139*8 +: 8], 1'b0, INIT[1138*8 +: 8], 1'b0, INIT[1137*8 +: 8], 1'b0, INIT[1136*8 +: 8], 
+          1'b0, INIT[1135*8 +: 8], 1'b0, INIT[1134*8 +: 8], 1'b0, INIT[1133*8 +: 8], 1'b0, INIT[1132*8 +: 8], 
+          1'b0, INIT[1131*8 +: 8], 1'b0, INIT[1130*8 +: 8], 1'b0, INIT[1129*8 +: 8], 1'b0, INIT[1128*8 +: 8], 
+          1'b0, INIT[1127*8 +: 8], 1'b0, INIT[1126*8 +: 8], 1'b0, INIT[1125*8 +: 8], 1'b0, INIT[1124*8 +: 8], 
+          1'b0, INIT[1123*8 +: 8], 1'b0, INIT[1122*8 +: 8], 1'b0, INIT[1121*8 +: 8], 1'b0, INIT[1120*8 +: 8], 
+          1'b0, INIT[1119*8 +: 8], 1'b0, INIT[1118*8 +: 8], 1'b0, INIT[1117*8 +: 8], 1'b0, INIT[1116*8 +: 8], 
+          1'b0, INIT[1115*8 +: 8], 1'b0, INIT[1114*8 +: 8], 1'b0, INIT[1113*8 +: 8], 1'b0, INIT[1112*8 +: 8], 
+          1'b0, INIT[1111*8 +: 8], 1'b0, INIT[1110*8 +: 8], 1'b0, INIT[1109*8 +: 8], 1'b0, INIT[1108*8 +: 8], 
+          1'b0, INIT[1107*8 +: 8], 1'b0, INIT[1106*8 +: 8], 1'b0, INIT[1105*8 +: 8], 1'b0, INIT[1104*8 +: 8], 
+          1'b0, INIT[1103*8 +: 8], 1'b0, INIT[1102*8 +: 8], 1'b0, INIT[1101*8 +: 8], 1'b0, INIT[1100*8 +: 8], 
+          1'b0, INIT[1099*8 +: 8], 1'b0, INIT[1098*8 +: 8], 1'b0, INIT[1097*8 +: 8], 1'b0, INIT[1096*8 +: 8], 
+          1'b0, INIT[1095*8 +: 8], 1'b0, INIT[1094*8 +: 8], 1'b0, INIT[1093*8 +: 8], 1'b0, INIT[1092*8 +: 8], 
+          1'b0, INIT[1091*8 +: 8], 1'b0, INIT[1090*8 +: 8], 1'b0, INIT[1089*8 +: 8], 1'b0, INIT[1088*8 +: 8], 
+          1'b0, INIT[1087*8 +: 8], 1'b0, INIT[1086*8 +: 8], 1'b0, INIT[1085*8 +: 8], 1'b0, INIT[1084*8 +: 8], 
+          1'b0, INIT[1083*8 +: 8], 1'b0, INIT[1082*8 +: 8], 1'b0, INIT[1081*8 +: 8], 1'b0, INIT[1080*8 +: 8], 
+          1'b0, INIT[1079*8 +: 8], 1'b0, INIT[1078*8 +: 8], 1'b0, INIT[1077*8 +: 8], 1'b0, INIT[1076*8 +: 8], 
+          1'b0, INIT[1075*8 +: 8], 1'b0, INIT[1074*8 +: 8], 1'b0, INIT[1073*8 +: 8], 1'b0, INIT[1072*8 +: 8], 
+          1'b0, INIT[1071*8 +: 8], 1'b0, INIT[1070*8 +: 8], 1'b0, INIT[1069*8 +: 8], 1'b0, INIT[1068*8 +: 8], 
+          1'b0, INIT[1067*8 +: 8], 1'b0, INIT[1066*8 +: 8], 1'b0, INIT[1065*8 +: 8], 1'b0, INIT[1064*8 +: 8], 
+          1'b0, INIT[1063*8 +: 8], 1'b0, INIT[1062*8 +: 8], 1'b0, INIT[1061*8 +: 8], 1'b0, INIT[1060*8 +: 8], 
+          1'b0, INIT[1059*8 +: 8], 1'b0, INIT[1058*8 +: 8], 1'b0, INIT[1057*8 +: 8], 1'b0, INIT[1056*8 +: 8], 
+          1'b0, INIT[1055*8 +: 8], 1'b0, INIT[1054*8 +: 8], 1'b0, INIT[1053*8 +: 8], 1'b0, INIT[1052*8 +: 8], 
+          1'b0, INIT[1051*8 +: 8], 1'b0, INIT[1050*8 +: 8], 1'b0, INIT[1049*8 +: 8], 1'b0, INIT[1048*8 +: 8], 
+          1'b0, INIT[1047*8 +: 8], 1'b0, INIT[1046*8 +: 8], 1'b0, INIT[1045*8 +: 8], 1'b0, INIT[1044*8 +: 8], 
+          1'b0, INIT[1043*8 +: 8], 1'b0, INIT[1042*8 +: 8], 1'b0, INIT[1041*8 +: 8], 1'b0, INIT[1040*8 +: 8], 
+          1'b0, INIT[1039*8 +: 8], 1'b0, INIT[1038*8 +: 8], 1'b0, INIT[1037*8 +: 8], 1'b0, INIT[1036*8 +: 8], 
+          1'b0, INIT[1035*8 +: 8], 1'b0, INIT[1034*8 +: 8], 1'b0, INIT[1033*8 +: 8], 1'b0, INIT[1032*8 +: 8], 
+          1'b0, INIT[1031*8 +: 8], 1'b0, INIT[1030*8 +: 8], 1'b0, INIT[1029*8 +: 8], 1'b0, INIT[1028*8 +: 8], 
+          1'b0, INIT[1027*8 +: 8], 1'b0, INIT[1026*8 +: 8], 1'b0, INIT[1025*8 +: 8], 1'b0, INIT[1024*8 +: 8], 
+          1'b0, INIT[1023*8 +: 8], 1'b0, INIT[1022*8 +: 8], 1'b0, INIT[1021*8 +: 8], 1'b0, INIT[1020*8 +: 8], 
+          1'b0, INIT[1019*8 +: 8], 1'b0, INIT[1018*8 +: 8], 1'b0, INIT[1017*8 +: 8], 1'b0, INIT[1016*8 +: 8], 
+          1'b0, INIT[1015*8 +: 8], 1'b0, INIT[1014*8 +: 8], 1'b0, INIT[1013*8 +: 8], 1'b0, INIT[1012*8 +: 8], 
+          1'b0, INIT[1011*8 +: 8], 1'b0, INIT[1010*8 +: 8], 1'b0, INIT[1009*8 +: 8], 1'b0, INIT[1008*8 +: 8], 
+          1'b0, INIT[1007*8 +: 8], 1'b0, INIT[1006*8 +: 8], 1'b0, INIT[1005*8 +: 8], 1'b0, INIT[1004*8 +: 8], 
+          1'b0, INIT[1003*8 +: 8], 1'b0, INIT[1002*8 +: 8], 1'b0, INIT[1001*8 +: 8], 1'b0, INIT[1000*8 +: 8], 
+          1'b0, INIT[ 999*8 +: 8], 1'b0, INIT[ 998*8 +: 8], 1'b0, INIT[ 997*8 +: 8], 1'b0, INIT[ 996*8 +: 8], 
+          1'b0, INIT[ 995*8 +: 8], 1'b0, INIT[ 994*8 +: 8], 1'b0, INIT[ 993*8 +: 8], 1'b0, INIT[ 992*8 +: 8], 
+          1'b0, INIT[ 991*8 +: 8], 1'b0, INIT[ 990*8 +: 8], 1'b0, INIT[ 989*8 +: 8], 1'b0, INIT[ 988*8 +: 8], 
+          1'b0, INIT[ 987*8 +: 8], 1'b0, INIT[ 986*8 +: 8], 1'b0, INIT[ 985*8 +: 8], 1'b0, INIT[ 984*8 +: 8], 
+          1'b0, INIT[ 983*8 +: 8], 1'b0, INIT[ 982*8 +: 8], 1'b0, INIT[ 981*8 +: 8], 1'b0, INIT[ 980*8 +: 8], 
+          1'b0, INIT[ 979*8 +: 8], 1'b0, INIT[ 978*8 +: 8], 1'b0, INIT[ 977*8 +: 8], 1'b0, INIT[ 976*8 +: 8], 
+          1'b0, INIT[ 975*8 +: 8], 1'b0, INIT[ 974*8 +: 8], 1'b0, INIT[ 973*8 +: 8], 1'b0, INIT[ 972*8 +: 8], 
+          1'b0, INIT[ 971*8 +: 8], 1'b0, INIT[ 970*8 +: 8], 1'b0, INIT[ 969*8 +: 8], 1'b0, INIT[ 968*8 +: 8], 
+          1'b0, INIT[ 967*8 +: 8], 1'b0, INIT[ 966*8 +: 8], 1'b0, INIT[ 965*8 +: 8], 1'b0, INIT[ 964*8 +: 8], 
+          1'b0, INIT[ 963*8 +: 8], 1'b0, INIT[ 962*8 +: 8], 1'b0, INIT[ 961*8 +: 8], 1'b0, INIT[ 960*8 +: 8], 
+          1'b0, INIT[ 959*8 +: 8], 1'b0, INIT[ 958*8 +: 8], 1'b0, INIT[ 957*8 +: 8], 1'b0, INIT[ 956*8 +: 8], 
+          1'b0, INIT[ 955*8 +: 8], 1'b0, INIT[ 954*8 +: 8], 1'b0, INIT[ 953*8 +: 8], 1'b0, INIT[ 952*8 +: 8], 
+          1'b0, INIT[ 951*8 +: 8], 1'b0, INIT[ 950*8 +: 8], 1'b0, INIT[ 949*8 +: 8], 1'b0, INIT[ 948*8 +: 8], 
+          1'b0, INIT[ 947*8 +: 8], 1'b0, INIT[ 946*8 +: 8], 1'b0, INIT[ 945*8 +: 8], 1'b0, INIT[ 944*8 +: 8], 
+          1'b0, INIT[ 943*8 +: 8], 1'b0, INIT[ 942*8 +: 8], 1'b0, INIT[ 941*8 +: 8], 1'b0, INIT[ 940*8 +: 8], 
+          1'b0, INIT[ 939*8 +: 8], 1'b0, INIT[ 938*8 +: 8], 1'b0, INIT[ 937*8 +: 8], 1'b0, INIT[ 936*8 +: 8], 
+          1'b0, INIT[ 935*8 +: 8], 1'b0, INIT[ 934*8 +: 8], 1'b0, INIT[ 933*8 +: 8], 1'b0, INIT[ 932*8 +: 8], 
+          1'b0, INIT[ 931*8 +: 8], 1'b0, INIT[ 930*8 +: 8], 1'b0, INIT[ 929*8 +: 8], 1'b0, INIT[ 928*8 +: 8], 
+          1'b0, INIT[ 927*8 +: 8], 1'b0, INIT[ 926*8 +: 8], 1'b0, INIT[ 925*8 +: 8], 1'b0, INIT[ 924*8 +: 8], 
+          1'b0, INIT[ 923*8 +: 8], 1'b0, INIT[ 922*8 +: 8], 1'b0, INIT[ 921*8 +: 8], 1'b0, INIT[ 920*8 +: 8], 
+          1'b0, INIT[ 919*8 +: 8], 1'b0, INIT[ 918*8 +: 8], 1'b0, INIT[ 917*8 +: 8], 1'b0, INIT[ 916*8 +: 8], 
+          1'b0, INIT[ 915*8 +: 8], 1'b0, INIT[ 914*8 +: 8], 1'b0, INIT[ 913*8 +: 8], 1'b0, INIT[ 912*8 +: 8], 
+          1'b0, INIT[ 911*8 +: 8], 1'b0, INIT[ 910*8 +: 8], 1'b0, INIT[ 909*8 +: 8], 1'b0, INIT[ 908*8 +: 8], 
+          1'b0, INIT[ 907*8 +: 8], 1'b0, INIT[ 906*8 +: 8], 1'b0, INIT[ 905*8 +: 8], 1'b0, INIT[ 904*8 +: 8], 
+          1'b0, INIT[ 903*8 +: 8], 1'b0, INIT[ 902*8 +: 8], 1'b0, INIT[ 901*8 +: 8], 1'b0, INIT[ 900*8 +: 8], 
+          1'b0, INIT[ 899*8 +: 8], 1'b0, INIT[ 898*8 +: 8], 1'b0, INIT[ 897*8 +: 8], 1'b0, INIT[ 896*8 +: 8], 
+          1'b0, INIT[ 895*8 +: 8], 1'b0, INIT[ 894*8 +: 8], 1'b0, INIT[ 893*8 +: 8], 1'b0, INIT[ 892*8 +: 8], 
+          1'b0, INIT[ 891*8 +: 8], 1'b0, INIT[ 890*8 +: 8], 1'b0, INIT[ 889*8 +: 8], 1'b0, INIT[ 888*8 +: 8], 
+          1'b0, INIT[ 887*8 +: 8], 1'b0, INIT[ 886*8 +: 8], 1'b0, INIT[ 885*8 +: 8], 1'b0, INIT[ 884*8 +: 8], 
+          1'b0, INIT[ 883*8 +: 8], 1'b0, INIT[ 882*8 +: 8], 1'b0, INIT[ 881*8 +: 8], 1'b0, INIT[ 880*8 +: 8], 
+          1'b0, INIT[ 879*8 +: 8], 1'b0, INIT[ 878*8 +: 8], 1'b0, INIT[ 877*8 +: 8], 1'b0, INIT[ 876*8 +: 8], 
+          1'b0, INIT[ 875*8 +: 8], 1'b0, INIT[ 874*8 +: 8], 1'b0, INIT[ 873*8 +: 8], 1'b0, INIT[ 872*8 +: 8], 
+          1'b0, INIT[ 871*8 +: 8], 1'b0, INIT[ 870*8 +: 8], 1'b0, INIT[ 869*8 +: 8], 1'b0, INIT[ 868*8 +: 8], 
+          1'b0, INIT[ 867*8 +: 8], 1'b0, INIT[ 866*8 +: 8], 1'b0, INIT[ 865*8 +: 8], 1'b0, INIT[ 864*8 +: 8], 
+          1'b0, INIT[ 863*8 +: 8], 1'b0, INIT[ 862*8 +: 8], 1'b0, INIT[ 861*8 +: 8], 1'b0, INIT[ 860*8 +: 8], 
+          1'b0, INIT[ 859*8 +: 8], 1'b0, INIT[ 858*8 +: 8], 1'b0, INIT[ 857*8 +: 8], 1'b0, INIT[ 856*8 +: 8], 
+          1'b0, INIT[ 855*8 +: 8], 1'b0, INIT[ 854*8 +: 8], 1'b0, INIT[ 853*8 +: 8], 1'b0, INIT[ 852*8 +: 8], 
+          1'b0, INIT[ 851*8 +: 8], 1'b0, INIT[ 850*8 +: 8], 1'b0, INIT[ 849*8 +: 8], 1'b0, INIT[ 848*8 +: 8], 
+          1'b0, INIT[ 847*8 +: 8], 1'b0, INIT[ 846*8 +: 8], 1'b0, INIT[ 845*8 +: 8], 1'b0, INIT[ 844*8 +: 8], 
+          1'b0, INIT[ 843*8 +: 8], 1'b0, INIT[ 842*8 +: 8], 1'b0, INIT[ 841*8 +: 8], 1'b0, INIT[ 840*8 +: 8], 
+          1'b0, INIT[ 839*8 +: 8], 1'b0, INIT[ 838*8 +: 8], 1'b0, INIT[ 837*8 +: 8], 1'b0, INIT[ 836*8 +: 8], 
+          1'b0, INIT[ 835*8 +: 8], 1'b0, INIT[ 834*8 +: 8], 1'b0, INIT[ 833*8 +: 8], 1'b0, INIT[ 832*8 +: 8], 
+          1'b0, INIT[ 831*8 +: 8], 1'b0, INIT[ 830*8 +: 8], 1'b0, INIT[ 829*8 +: 8], 1'b0, INIT[ 828*8 +: 8], 
+          1'b0, INIT[ 827*8 +: 8], 1'b0, INIT[ 826*8 +: 8], 1'b0, INIT[ 825*8 +: 8], 1'b0, INIT[ 824*8 +: 8], 
+          1'b0, INIT[ 823*8 +: 8], 1'b0, INIT[ 822*8 +: 8], 1'b0, INIT[ 821*8 +: 8], 1'b0, INIT[ 820*8 +: 8], 
+          1'b0, INIT[ 819*8 +: 8], 1'b0, INIT[ 818*8 +: 8], 1'b0, INIT[ 817*8 +: 8], 1'b0, INIT[ 816*8 +: 8], 
+          1'b0, INIT[ 815*8 +: 8], 1'b0, INIT[ 814*8 +: 8], 1'b0, INIT[ 813*8 +: 8], 1'b0, INIT[ 812*8 +: 8], 
+          1'b0, INIT[ 811*8 +: 8], 1'b0, INIT[ 810*8 +: 8], 1'b0, INIT[ 809*8 +: 8], 1'b0, INIT[ 808*8 +: 8], 
+          1'b0, INIT[ 807*8 +: 8], 1'b0, INIT[ 806*8 +: 8], 1'b0, INIT[ 805*8 +: 8], 1'b0, INIT[ 804*8 +: 8], 
+          1'b0, INIT[ 803*8 +: 8], 1'b0, INIT[ 802*8 +: 8], 1'b0, INIT[ 801*8 +: 8], 1'b0, INIT[ 800*8 +: 8], 
+          1'b0, INIT[ 799*8 +: 8], 1'b0, INIT[ 798*8 +: 8], 1'b0, INIT[ 797*8 +: 8], 1'b0, INIT[ 796*8 +: 8], 
+          1'b0, INIT[ 795*8 +: 8], 1'b0, INIT[ 794*8 +: 8], 1'b0, INIT[ 793*8 +: 8], 1'b0, INIT[ 792*8 +: 8], 
+          1'b0, INIT[ 791*8 +: 8], 1'b0, INIT[ 790*8 +: 8], 1'b0, INIT[ 789*8 +: 8], 1'b0, INIT[ 788*8 +: 8], 
+          1'b0, INIT[ 787*8 +: 8], 1'b0, INIT[ 786*8 +: 8], 1'b0, INIT[ 785*8 +: 8], 1'b0, INIT[ 784*8 +: 8], 
+          1'b0, INIT[ 783*8 +: 8], 1'b0, INIT[ 782*8 +: 8], 1'b0, INIT[ 781*8 +: 8], 1'b0, INIT[ 780*8 +: 8], 
+          1'b0, INIT[ 779*8 +: 8], 1'b0, INIT[ 778*8 +: 8], 1'b0, INIT[ 777*8 +: 8], 1'b0, INIT[ 776*8 +: 8], 
+          1'b0, INIT[ 775*8 +: 8], 1'b0, INIT[ 774*8 +: 8], 1'b0, INIT[ 773*8 +: 8], 1'b0, INIT[ 772*8 +: 8], 
+          1'b0, INIT[ 771*8 +: 8], 1'b0, INIT[ 770*8 +: 8], 1'b0, INIT[ 769*8 +: 8], 1'b0, INIT[ 768*8 +: 8], 
+          1'b0, INIT[ 767*8 +: 8], 1'b0, INIT[ 766*8 +: 8], 1'b0, INIT[ 765*8 +: 8], 1'b0, INIT[ 764*8 +: 8], 
+          1'b0, INIT[ 763*8 +: 8], 1'b0, INIT[ 762*8 +: 8], 1'b0, INIT[ 761*8 +: 8], 1'b0, INIT[ 760*8 +: 8], 
+          1'b0, INIT[ 759*8 +: 8], 1'b0, INIT[ 758*8 +: 8], 1'b0, INIT[ 757*8 +: 8], 1'b0, INIT[ 756*8 +: 8], 
+          1'b0, INIT[ 755*8 +: 8], 1'b0, INIT[ 754*8 +: 8], 1'b0, INIT[ 753*8 +: 8], 1'b0, INIT[ 752*8 +: 8], 
+          1'b0, INIT[ 751*8 +: 8], 1'b0, INIT[ 750*8 +: 8], 1'b0, INIT[ 749*8 +: 8], 1'b0, INIT[ 748*8 +: 8], 
+          1'b0, INIT[ 747*8 +: 8], 1'b0, INIT[ 746*8 +: 8], 1'b0, INIT[ 745*8 +: 8], 1'b0, INIT[ 744*8 +: 8], 
+          1'b0, INIT[ 743*8 +: 8], 1'b0, INIT[ 742*8 +: 8], 1'b0, INIT[ 741*8 +: 8], 1'b0, INIT[ 740*8 +: 8], 
+          1'b0, INIT[ 739*8 +: 8], 1'b0, INIT[ 738*8 +: 8], 1'b0, INIT[ 737*8 +: 8], 1'b0, INIT[ 736*8 +: 8], 
+          1'b0, INIT[ 735*8 +: 8], 1'b0, INIT[ 734*8 +: 8], 1'b0, INIT[ 733*8 +: 8], 1'b0, INIT[ 732*8 +: 8], 
+          1'b0, INIT[ 731*8 +: 8], 1'b0, INIT[ 730*8 +: 8], 1'b0, INIT[ 729*8 +: 8], 1'b0, INIT[ 728*8 +: 8], 
+          1'b0, INIT[ 727*8 +: 8], 1'b0, INIT[ 726*8 +: 8], 1'b0, INIT[ 725*8 +: 8], 1'b0, INIT[ 724*8 +: 8], 
+          1'b0, INIT[ 723*8 +: 8], 1'b0, INIT[ 722*8 +: 8], 1'b0, INIT[ 721*8 +: 8], 1'b0, INIT[ 720*8 +: 8], 
+          1'b0, INIT[ 719*8 +: 8], 1'b0, INIT[ 718*8 +: 8], 1'b0, INIT[ 717*8 +: 8], 1'b0, INIT[ 716*8 +: 8], 
+          1'b0, INIT[ 715*8 +: 8], 1'b0, INIT[ 714*8 +: 8], 1'b0, INIT[ 713*8 +: 8], 1'b0, INIT[ 712*8 +: 8], 
+          1'b0, INIT[ 711*8 +: 8], 1'b0, INIT[ 710*8 +: 8], 1'b0, INIT[ 709*8 +: 8], 1'b0, INIT[ 708*8 +: 8], 
+          1'b0, INIT[ 707*8 +: 8], 1'b0, INIT[ 706*8 +: 8], 1'b0, INIT[ 705*8 +: 8], 1'b0, INIT[ 704*8 +: 8], 
+          1'b0, INIT[ 703*8 +: 8], 1'b0, INIT[ 702*8 +: 8], 1'b0, INIT[ 701*8 +: 8], 1'b0, INIT[ 700*8 +: 8], 
+          1'b0, INIT[ 699*8 +: 8], 1'b0, INIT[ 698*8 +: 8], 1'b0, INIT[ 697*8 +: 8], 1'b0, INIT[ 696*8 +: 8], 
+          1'b0, INIT[ 695*8 +: 8], 1'b0, INIT[ 694*8 +: 8], 1'b0, INIT[ 693*8 +: 8], 1'b0, INIT[ 692*8 +: 8], 
+          1'b0, INIT[ 691*8 +: 8], 1'b0, INIT[ 690*8 +: 8], 1'b0, INIT[ 689*8 +: 8], 1'b0, INIT[ 688*8 +: 8], 
+          1'b0, INIT[ 687*8 +: 8], 1'b0, INIT[ 686*8 +: 8], 1'b0, INIT[ 685*8 +: 8], 1'b0, INIT[ 684*8 +: 8], 
+          1'b0, INIT[ 683*8 +: 8], 1'b0, INIT[ 682*8 +: 8], 1'b0, INIT[ 681*8 +: 8], 1'b0, INIT[ 680*8 +: 8], 
+          1'b0, INIT[ 679*8 +: 8], 1'b0, INIT[ 678*8 +: 8], 1'b0, INIT[ 677*8 +: 8], 1'b0, INIT[ 676*8 +: 8], 
+          1'b0, INIT[ 675*8 +: 8], 1'b0, INIT[ 674*8 +: 8], 1'b0, INIT[ 673*8 +: 8], 1'b0, INIT[ 672*8 +: 8], 
+          1'b0, INIT[ 671*8 +: 8], 1'b0, INIT[ 670*8 +: 8], 1'b0, INIT[ 669*8 +: 8], 1'b0, INIT[ 668*8 +: 8], 
+          1'b0, INIT[ 667*8 +: 8], 1'b0, INIT[ 666*8 +: 8], 1'b0, INIT[ 665*8 +: 8], 1'b0, INIT[ 664*8 +: 8], 
+          1'b0, INIT[ 663*8 +: 8], 1'b0, INIT[ 662*8 +: 8], 1'b0, INIT[ 661*8 +: 8], 1'b0, INIT[ 660*8 +: 8], 
+          1'b0, INIT[ 659*8 +: 8], 1'b0, INIT[ 658*8 +: 8], 1'b0, INIT[ 657*8 +: 8], 1'b0, INIT[ 656*8 +: 8], 
+          1'b0, INIT[ 655*8 +: 8], 1'b0, INIT[ 654*8 +: 8], 1'b0, INIT[ 653*8 +: 8], 1'b0, INIT[ 652*8 +: 8], 
+          1'b0, INIT[ 651*8 +: 8], 1'b0, INIT[ 650*8 +: 8], 1'b0, INIT[ 649*8 +: 8], 1'b0, INIT[ 648*8 +: 8], 
+          1'b0, INIT[ 647*8 +: 8], 1'b0, INIT[ 646*8 +: 8], 1'b0, INIT[ 645*8 +: 8], 1'b0, INIT[ 644*8 +: 8], 
+          1'b0, INIT[ 643*8 +: 8], 1'b0, INIT[ 642*8 +: 8], 1'b0, INIT[ 641*8 +: 8], 1'b0, INIT[ 640*8 +: 8], 
+          1'b0, INIT[ 639*8 +: 8], 1'b0, INIT[ 638*8 +: 8], 1'b0, INIT[ 637*8 +: 8], 1'b0, INIT[ 636*8 +: 8], 
+          1'b0, INIT[ 635*8 +: 8], 1'b0, INIT[ 634*8 +: 8], 1'b0, INIT[ 633*8 +: 8], 1'b0, INIT[ 632*8 +: 8], 
+          1'b0, INIT[ 631*8 +: 8], 1'b0, INIT[ 630*8 +: 8], 1'b0, INIT[ 629*8 +: 8], 1'b0, INIT[ 628*8 +: 8], 
+          1'b0, INIT[ 627*8 +: 8], 1'b0, INIT[ 626*8 +: 8], 1'b0, INIT[ 625*8 +: 8], 1'b0, INIT[ 624*8 +: 8], 
+          1'b0, INIT[ 623*8 +: 8], 1'b0, INIT[ 622*8 +: 8], 1'b0, INIT[ 621*8 +: 8], 1'b0, INIT[ 620*8 +: 8], 
+          1'b0, INIT[ 619*8 +: 8], 1'b0, INIT[ 618*8 +: 8], 1'b0, INIT[ 617*8 +: 8], 1'b0, INIT[ 616*8 +: 8], 
+          1'b0, INIT[ 615*8 +: 8], 1'b0, INIT[ 614*8 +: 8], 1'b0, INIT[ 613*8 +: 8], 1'b0, INIT[ 612*8 +: 8], 
+          1'b0, INIT[ 611*8 +: 8], 1'b0, INIT[ 610*8 +: 8], 1'b0, INIT[ 609*8 +: 8], 1'b0, INIT[ 608*8 +: 8], 
+          1'b0, INIT[ 607*8 +: 8], 1'b0, INIT[ 606*8 +: 8], 1'b0, INIT[ 605*8 +: 8], 1'b0, INIT[ 604*8 +: 8], 
+          1'b0, INIT[ 603*8 +: 8], 1'b0, INIT[ 602*8 +: 8], 1'b0, INIT[ 601*8 +: 8], 1'b0, INIT[ 600*8 +: 8], 
+          1'b0, INIT[ 599*8 +: 8], 1'b0, INIT[ 598*8 +: 8], 1'b0, INIT[ 597*8 +: 8], 1'b0, INIT[ 596*8 +: 8], 
+          1'b0, INIT[ 595*8 +: 8], 1'b0, INIT[ 594*8 +: 8], 1'b0, INIT[ 593*8 +: 8], 1'b0, INIT[ 592*8 +: 8], 
+          1'b0, INIT[ 591*8 +: 8], 1'b0, INIT[ 590*8 +: 8], 1'b0, INIT[ 589*8 +: 8], 1'b0, INIT[ 588*8 +: 8], 
+          1'b0, INIT[ 587*8 +: 8], 1'b0, INIT[ 586*8 +: 8], 1'b0, INIT[ 585*8 +: 8], 1'b0, INIT[ 584*8 +: 8], 
+          1'b0, INIT[ 583*8 +: 8], 1'b0, INIT[ 582*8 +: 8], 1'b0, INIT[ 581*8 +: 8], 1'b0, INIT[ 580*8 +: 8], 
+          1'b0, INIT[ 579*8 +: 8], 1'b0, INIT[ 578*8 +: 8], 1'b0, INIT[ 577*8 +: 8], 1'b0, INIT[ 576*8 +: 8], 
+          1'b0, INIT[ 575*8 +: 8], 1'b0, INIT[ 574*8 +: 8], 1'b0, INIT[ 573*8 +: 8], 1'b0, INIT[ 572*8 +: 8], 
+          1'b0, INIT[ 571*8 +: 8], 1'b0, INIT[ 570*8 +: 8], 1'b0, INIT[ 569*8 +: 8], 1'b0, INIT[ 568*8 +: 8], 
+          1'b0, INIT[ 567*8 +: 8], 1'b0, INIT[ 566*8 +: 8], 1'b0, INIT[ 565*8 +: 8], 1'b0, INIT[ 564*8 +: 8], 
+          1'b0, INIT[ 563*8 +: 8], 1'b0, INIT[ 562*8 +: 8], 1'b0, INIT[ 561*8 +: 8], 1'b0, INIT[ 560*8 +: 8], 
+          1'b0, INIT[ 559*8 +: 8], 1'b0, INIT[ 558*8 +: 8], 1'b0, INIT[ 557*8 +: 8], 1'b0, INIT[ 556*8 +: 8], 
+          1'b0, INIT[ 555*8 +: 8], 1'b0, INIT[ 554*8 +: 8], 1'b0, INIT[ 553*8 +: 8], 1'b0, INIT[ 552*8 +: 8], 
+          1'b0, INIT[ 551*8 +: 8], 1'b0, INIT[ 550*8 +: 8], 1'b0, INIT[ 549*8 +: 8], 1'b0, INIT[ 548*8 +: 8], 
+          1'b0, INIT[ 547*8 +: 8], 1'b0, INIT[ 546*8 +: 8], 1'b0, INIT[ 545*8 +: 8], 1'b0, INIT[ 544*8 +: 8], 
+          1'b0, INIT[ 543*8 +: 8], 1'b0, INIT[ 542*8 +: 8], 1'b0, INIT[ 541*8 +: 8], 1'b0, INIT[ 540*8 +: 8], 
+          1'b0, INIT[ 539*8 +: 8], 1'b0, INIT[ 538*8 +: 8], 1'b0, INIT[ 537*8 +: 8], 1'b0, INIT[ 536*8 +: 8], 
+          1'b0, INIT[ 535*8 +: 8], 1'b0, INIT[ 534*8 +: 8], 1'b0, INIT[ 533*8 +: 8], 1'b0, INIT[ 532*8 +: 8], 
+          1'b0, INIT[ 531*8 +: 8], 1'b0, INIT[ 530*8 +: 8], 1'b0, INIT[ 529*8 +: 8], 1'b0, INIT[ 528*8 +: 8], 
+          1'b0, INIT[ 527*8 +: 8], 1'b0, INIT[ 526*8 +: 8], 1'b0, INIT[ 525*8 +: 8], 1'b0, INIT[ 524*8 +: 8], 
+          1'b0, INIT[ 523*8 +: 8], 1'b0, INIT[ 522*8 +: 8], 1'b0, INIT[ 521*8 +: 8], 1'b0, INIT[ 520*8 +: 8], 
+          1'b0, INIT[ 519*8 +: 8], 1'b0, INIT[ 518*8 +: 8], 1'b0, INIT[ 517*8 +: 8], 1'b0, INIT[ 516*8 +: 8], 
+          1'b0, INIT[ 515*8 +: 8], 1'b0, INIT[ 514*8 +: 8], 1'b0, INIT[ 513*8 +: 8], 1'b0, INIT[ 512*8 +: 8], 
+          1'b0, INIT[ 511*8 +: 8], 1'b0, INIT[ 510*8 +: 8], 1'b0, INIT[ 509*8 +: 8], 1'b0, INIT[ 508*8 +: 8], 
+          1'b0, INIT[ 507*8 +: 8], 1'b0, INIT[ 506*8 +: 8], 1'b0, INIT[ 505*8 +: 8], 1'b0, INIT[ 504*8 +: 8], 
+          1'b0, INIT[ 503*8 +: 8], 1'b0, INIT[ 502*8 +: 8], 1'b0, INIT[ 501*8 +: 8], 1'b0, INIT[ 500*8 +: 8], 
+          1'b0, INIT[ 499*8 +: 8], 1'b0, INIT[ 498*8 +: 8], 1'b0, INIT[ 497*8 +: 8], 1'b0, INIT[ 496*8 +: 8], 
+          1'b0, INIT[ 495*8 +: 8], 1'b0, INIT[ 494*8 +: 8], 1'b0, INIT[ 493*8 +: 8], 1'b0, INIT[ 492*8 +: 8], 
+          1'b0, INIT[ 491*8 +: 8], 1'b0, INIT[ 490*8 +: 8], 1'b0, INIT[ 489*8 +: 8], 1'b0, INIT[ 488*8 +: 8], 
+          1'b0, INIT[ 487*8 +: 8], 1'b0, INIT[ 486*8 +: 8], 1'b0, INIT[ 485*8 +: 8], 1'b0, INIT[ 484*8 +: 8], 
+          1'b0, INIT[ 483*8 +: 8], 1'b0, INIT[ 482*8 +: 8], 1'b0, INIT[ 481*8 +: 8], 1'b0, INIT[ 480*8 +: 8], 
+          1'b0, INIT[ 479*8 +: 8], 1'b0, INIT[ 478*8 +: 8], 1'b0, INIT[ 477*8 +: 8], 1'b0, INIT[ 476*8 +: 8], 
+          1'b0, INIT[ 475*8 +: 8], 1'b0, INIT[ 474*8 +: 8], 1'b0, INIT[ 473*8 +: 8], 1'b0, INIT[ 472*8 +: 8], 
+          1'b0, INIT[ 471*8 +: 8], 1'b0, INIT[ 470*8 +: 8], 1'b0, INIT[ 469*8 +: 8], 1'b0, INIT[ 468*8 +: 8], 
+          1'b0, INIT[ 467*8 +: 8], 1'b0, INIT[ 466*8 +: 8], 1'b0, INIT[ 465*8 +: 8], 1'b0, INIT[ 464*8 +: 8], 
+          1'b0, INIT[ 463*8 +: 8], 1'b0, INIT[ 462*8 +: 8], 1'b0, INIT[ 461*8 +: 8], 1'b0, INIT[ 460*8 +: 8], 
+          1'b0, INIT[ 459*8 +: 8], 1'b0, INIT[ 458*8 +: 8], 1'b0, INIT[ 457*8 +: 8], 1'b0, INIT[ 456*8 +: 8], 
+          1'b0, INIT[ 455*8 +: 8], 1'b0, INIT[ 454*8 +: 8], 1'b0, INIT[ 453*8 +: 8], 1'b0, INIT[ 452*8 +: 8], 
+          1'b0, INIT[ 451*8 +: 8], 1'b0, INIT[ 450*8 +: 8], 1'b0, INIT[ 449*8 +: 8], 1'b0, INIT[ 448*8 +: 8], 
+          1'b0, INIT[ 447*8 +: 8], 1'b0, INIT[ 446*8 +: 8], 1'b0, INIT[ 445*8 +: 8], 1'b0, INIT[ 444*8 +: 8], 
+          1'b0, INIT[ 443*8 +: 8], 1'b0, INIT[ 442*8 +: 8], 1'b0, INIT[ 441*8 +: 8], 1'b0, INIT[ 440*8 +: 8], 
+          1'b0, INIT[ 439*8 +: 8], 1'b0, INIT[ 438*8 +: 8], 1'b0, INIT[ 437*8 +: 8], 1'b0, INIT[ 436*8 +: 8], 
+          1'b0, INIT[ 435*8 +: 8], 1'b0, INIT[ 434*8 +: 8], 1'b0, INIT[ 433*8 +: 8], 1'b0, INIT[ 432*8 +: 8], 
+          1'b0, INIT[ 431*8 +: 8], 1'b0, INIT[ 430*8 +: 8], 1'b0, INIT[ 429*8 +: 8], 1'b0, INIT[ 428*8 +: 8], 
+          1'b0, INIT[ 427*8 +: 8], 1'b0, INIT[ 426*8 +: 8], 1'b0, INIT[ 425*8 +: 8], 1'b0, INIT[ 424*8 +: 8], 
+          1'b0, INIT[ 423*8 +: 8], 1'b0, INIT[ 422*8 +: 8], 1'b0, INIT[ 421*8 +: 8], 1'b0, INIT[ 420*8 +: 8], 
+          1'b0, INIT[ 419*8 +: 8], 1'b0, INIT[ 418*8 +: 8], 1'b0, INIT[ 417*8 +: 8], 1'b0, INIT[ 416*8 +: 8], 
+          1'b0, INIT[ 415*8 +: 8], 1'b0, INIT[ 414*8 +: 8], 1'b0, INIT[ 413*8 +: 8], 1'b0, INIT[ 412*8 +: 8], 
+          1'b0, INIT[ 411*8 +: 8], 1'b0, INIT[ 410*8 +: 8], 1'b0, INIT[ 409*8 +: 8], 1'b0, INIT[ 408*8 +: 8], 
+          1'b0, INIT[ 407*8 +: 8], 1'b0, INIT[ 406*8 +: 8], 1'b0, INIT[ 405*8 +: 8], 1'b0, INIT[ 404*8 +: 8], 
+          1'b0, INIT[ 403*8 +: 8], 1'b0, INIT[ 402*8 +: 8], 1'b0, INIT[ 401*8 +: 8], 1'b0, INIT[ 400*8 +: 8], 
+          1'b0, INIT[ 399*8 +: 8], 1'b0, INIT[ 398*8 +: 8], 1'b0, INIT[ 397*8 +: 8], 1'b0, INIT[ 396*8 +: 8], 
+          1'b0, INIT[ 395*8 +: 8], 1'b0, INIT[ 394*8 +: 8], 1'b0, INIT[ 393*8 +: 8], 1'b0, INIT[ 392*8 +: 8], 
+          1'b0, INIT[ 391*8 +: 8], 1'b0, INIT[ 390*8 +: 8], 1'b0, INIT[ 389*8 +: 8], 1'b0, INIT[ 388*8 +: 8], 
+          1'b0, INIT[ 387*8 +: 8], 1'b0, INIT[ 386*8 +: 8], 1'b0, INIT[ 385*8 +: 8], 1'b0, INIT[ 384*8 +: 8], 
+          1'b0, INIT[ 383*8 +: 8], 1'b0, INIT[ 382*8 +: 8], 1'b0, INIT[ 381*8 +: 8], 1'b0, INIT[ 380*8 +: 8], 
+          1'b0, INIT[ 379*8 +: 8], 1'b0, INIT[ 378*8 +: 8], 1'b0, INIT[ 377*8 +: 8], 1'b0, INIT[ 376*8 +: 8], 
+          1'b0, INIT[ 375*8 +: 8], 1'b0, INIT[ 374*8 +: 8], 1'b0, INIT[ 373*8 +: 8], 1'b0, INIT[ 372*8 +: 8], 
+          1'b0, INIT[ 371*8 +: 8], 1'b0, INIT[ 370*8 +: 8], 1'b0, INIT[ 369*8 +: 8], 1'b0, INIT[ 368*8 +: 8], 
+          1'b0, INIT[ 367*8 +: 8], 1'b0, INIT[ 366*8 +: 8], 1'b0, INIT[ 365*8 +: 8], 1'b0, INIT[ 364*8 +: 8], 
+          1'b0, INIT[ 363*8 +: 8], 1'b0, INIT[ 362*8 +: 8], 1'b0, INIT[ 361*8 +: 8], 1'b0, INIT[ 360*8 +: 8], 
+          1'b0, INIT[ 359*8 +: 8], 1'b0, INIT[ 358*8 +: 8], 1'b0, INIT[ 357*8 +: 8], 1'b0, INIT[ 356*8 +: 8], 
+          1'b0, INIT[ 355*8 +: 8], 1'b0, INIT[ 354*8 +: 8], 1'b0, INIT[ 353*8 +: 8], 1'b0, INIT[ 352*8 +: 8], 
+          1'b0, INIT[ 351*8 +: 8], 1'b0, INIT[ 350*8 +: 8], 1'b0, INIT[ 349*8 +: 8], 1'b0, INIT[ 348*8 +: 8], 
+          1'b0, INIT[ 347*8 +: 8], 1'b0, INIT[ 346*8 +: 8], 1'b0, INIT[ 345*8 +: 8], 1'b0, INIT[ 344*8 +: 8], 
+          1'b0, INIT[ 343*8 +: 8], 1'b0, INIT[ 342*8 +: 8], 1'b0, INIT[ 341*8 +: 8], 1'b0, INIT[ 340*8 +: 8], 
+          1'b0, INIT[ 339*8 +: 8], 1'b0, INIT[ 338*8 +: 8], 1'b0, INIT[ 337*8 +: 8], 1'b0, INIT[ 336*8 +: 8], 
+          1'b0, INIT[ 335*8 +: 8], 1'b0, INIT[ 334*8 +: 8], 1'b0, INIT[ 333*8 +: 8], 1'b0, INIT[ 332*8 +: 8], 
+          1'b0, INIT[ 331*8 +: 8], 1'b0, INIT[ 330*8 +: 8], 1'b0, INIT[ 329*8 +: 8], 1'b0, INIT[ 328*8 +: 8], 
+          1'b0, INIT[ 327*8 +: 8], 1'b0, INIT[ 326*8 +: 8], 1'b0, INIT[ 325*8 +: 8], 1'b0, INIT[ 324*8 +: 8], 
+          1'b0, INIT[ 323*8 +: 8], 1'b0, INIT[ 322*8 +: 8], 1'b0, INIT[ 321*8 +: 8], 1'b0, INIT[ 320*8 +: 8], 
+          1'b0, INIT[ 319*8 +: 8], 1'b0, INIT[ 318*8 +: 8], 1'b0, INIT[ 317*8 +: 8], 1'b0, INIT[ 316*8 +: 8], 
+          1'b0, INIT[ 315*8 +: 8], 1'b0, INIT[ 314*8 +: 8], 1'b0, INIT[ 313*8 +: 8], 1'b0, INIT[ 312*8 +: 8], 
+          1'b0, INIT[ 311*8 +: 8], 1'b0, INIT[ 310*8 +: 8], 1'b0, INIT[ 309*8 +: 8], 1'b0, INIT[ 308*8 +: 8], 
+          1'b0, INIT[ 307*8 +: 8], 1'b0, INIT[ 306*8 +: 8], 1'b0, INIT[ 305*8 +: 8], 1'b0, INIT[ 304*8 +: 8], 
+          1'b0, INIT[ 303*8 +: 8], 1'b0, INIT[ 302*8 +: 8], 1'b0, INIT[ 301*8 +: 8], 1'b0, INIT[ 300*8 +: 8], 
+          1'b0, INIT[ 299*8 +: 8], 1'b0, INIT[ 298*8 +: 8], 1'b0, INIT[ 297*8 +: 8], 1'b0, INIT[ 296*8 +: 8], 
+          1'b0, INIT[ 295*8 +: 8], 1'b0, INIT[ 294*8 +: 8], 1'b0, INIT[ 293*8 +: 8], 1'b0, INIT[ 292*8 +: 8], 
+          1'b0, INIT[ 291*8 +: 8], 1'b0, INIT[ 290*8 +: 8], 1'b0, INIT[ 289*8 +: 8], 1'b0, INIT[ 288*8 +: 8], 
+          1'b0, INIT[ 287*8 +: 8], 1'b0, INIT[ 286*8 +: 8], 1'b0, INIT[ 285*8 +: 8], 1'b0, INIT[ 284*8 +: 8], 
+          1'b0, INIT[ 283*8 +: 8], 1'b0, INIT[ 282*8 +: 8], 1'b0, INIT[ 281*8 +: 8], 1'b0, INIT[ 280*8 +: 8], 
+          1'b0, INIT[ 279*8 +: 8], 1'b0, INIT[ 278*8 +: 8], 1'b0, INIT[ 277*8 +: 8], 1'b0, INIT[ 276*8 +: 8], 
+          1'b0, INIT[ 275*8 +: 8], 1'b0, INIT[ 274*8 +: 8], 1'b0, INIT[ 273*8 +: 8], 1'b0, INIT[ 272*8 +: 8], 
+          1'b0, INIT[ 271*8 +: 8], 1'b0, INIT[ 270*8 +: 8], 1'b0, INIT[ 269*8 +: 8], 1'b0, INIT[ 268*8 +: 8], 
+          1'b0, INIT[ 267*8 +: 8], 1'b0, INIT[ 266*8 +: 8], 1'b0, INIT[ 265*8 +: 8], 1'b0, INIT[ 264*8 +: 8], 
+          1'b0, INIT[ 263*8 +: 8], 1'b0, INIT[ 262*8 +: 8], 1'b0, INIT[ 261*8 +: 8], 1'b0, INIT[ 260*8 +: 8], 
+          1'b0, INIT[ 259*8 +: 8], 1'b0, INIT[ 258*8 +: 8], 1'b0, INIT[ 257*8 +: 8], 1'b0, INIT[ 256*8 +: 8], 
+          1'b0, INIT[ 255*8 +: 8], 1'b0, INIT[ 254*8 +: 8], 1'b0, INIT[ 253*8 +: 8], 1'b0, INIT[ 252*8 +: 8], 
+          1'b0, INIT[ 251*8 +: 8], 1'b0, INIT[ 250*8 +: 8], 1'b0, INIT[ 249*8 +: 8], 1'b0, INIT[ 248*8 +: 8], 
+          1'b0, INIT[ 247*8 +: 8], 1'b0, INIT[ 246*8 +: 8], 1'b0, INIT[ 245*8 +: 8], 1'b0, INIT[ 244*8 +: 8], 
+          1'b0, INIT[ 243*8 +: 8], 1'b0, INIT[ 242*8 +: 8], 1'b0, INIT[ 241*8 +: 8], 1'b0, INIT[ 240*8 +: 8], 
+          1'b0, INIT[ 239*8 +: 8], 1'b0, INIT[ 238*8 +: 8], 1'b0, INIT[ 237*8 +: 8], 1'b0, INIT[ 236*8 +: 8], 
+          1'b0, INIT[ 235*8 +: 8], 1'b0, INIT[ 234*8 +: 8], 1'b0, INIT[ 233*8 +: 8], 1'b0, INIT[ 232*8 +: 8], 
+          1'b0, INIT[ 231*8 +: 8], 1'b0, INIT[ 230*8 +: 8], 1'b0, INIT[ 229*8 +: 8], 1'b0, INIT[ 228*8 +: 8], 
+          1'b0, INIT[ 227*8 +: 8], 1'b0, INIT[ 226*8 +: 8], 1'b0, INIT[ 225*8 +: 8], 1'b0, INIT[ 224*8 +: 8], 
+          1'b0, INIT[ 223*8 +: 8], 1'b0, INIT[ 222*8 +: 8], 1'b0, INIT[ 221*8 +: 8], 1'b0, INIT[ 220*8 +: 8], 
+          1'b0, INIT[ 219*8 +: 8], 1'b0, INIT[ 218*8 +: 8], 1'b0, INIT[ 217*8 +: 8], 1'b0, INIT[ 216*8 +: 8], 
+          1'b0, INIT[ 215*8 +: 8], 1'b0, INIT[ 214*8 +: 8], 1'b0, INIT[ 213*8 +: 8], 1'b0, INIT[ 212*8 +: 8], 
+          1'b0, INIT[ 211*8 +: 8], 1'b0, INIT[ 210*8 +: 8], 1'b0, INIT[ 209*8 +: 8], 1'b0, INIT[ 208*8 +: 8], 
+          1'b0, INIT[ 207*8 +: 8], 1'b0, INIT[ 206*8 +: 8], 1'b0, INIT[ 205*8 +: 8], 1'b0, INIT[ 204*8 +: 8], 
+          1'b0, INIT[ 203*8 +: 8], 1'b0, INIT[ 202*8 +: 8], 1'b0, INIT[ 201*8 +: 8], 1'b0, INIT[ 200*8 +: 8], 
+          1'b0, INIT[ 199*8 +: 8], 1'b0, INIT[ 198*8 +: 8], 1'b0, INIT[ 197*8 +: 8], 1'b0, INIT[ 196*8 +: 8], 
+          1'b0, INIT[ 195*8 +: 8], 1'b0, INIT[ 194*8 +: 8], 1'b0, INIT[ 193*8 +: 8], 1'b0, INIT[ 192*8 +: 8], 
+          1'b0, INIT[ 191*8 +: 8], 1'b0, INIT[ 190*8 +: 8], 1'b0, INIT[ 189*8 +: 8], 1'b0, INIT[ 188*8 +: 8], 
+          1'b0, INIT[ 187*8 +: 8], 1'b0, INIT[ 186*8 +: 8], 1'b0, INIT[ 185*8 +: 8], 1'b0, INIT[ 184*8 +: 8], 
+          1'b0, INIT[ 183*8 +: 8], 1'b0, INIT[ 182*8 +: 8], 1'b0, INIT[ 181*8 +: 8], 1'b0, INIT[ 180*8 +: 8], 
+          1'b0, INIT[ 179*8 +: 8], 1'b0, INIT[ 178*8 +: 8], 1'b0, INIT[ 177*8 +: 8], 1'b0, INIT[ 176*8 +: 8], 
+          1'b0, INIT[ 175*8 +: 8], 1'b0, INIT[ 174*8 +: 8], 1'b0, INIT[ 173*8 +: 8], 1'b0, INIT[ 172*8 +: 8], 
+          1'b0, INIT[ 171*8 +: 8], 1'b0, INIT[ 170*8 +: 8], 1'b0, INIT[ 169*8 +: 8], 1'b0, INIT[ 168*8 +: 8], 
+          1'b0, INIT[ 167*8 +: 8], 1'b0, INIT[ 166*8 +: 8], 1'b0, INIT[ 165*8 +: 8], 1'b0, INIT[ 164*8 +: 8], 
+          1'b0, INIT[ 163*8 +: 8], 1'b0, INIT[ 162*8 +: 8], 1'b0, INIT[ 161*8 +: 8], 1'b0, INIT[ 160*8 +: 8], 
+          1'b0, INIT[ 159*8 +: 8], 1'b0, INIT[ 158*8 +: 8], 1'b0, INIT[ 157*8 +: 8], 1'b0, INIT[ 156*8 +: 8], 
+          1'b0, INIT[ 155*8 +: 8], 1'b0, INIT[ 154*8 +: 8], 1'b0, INIT[ 153*8 +: 8], 1'b0, INIT[ 152*8 +: 8], 
+          1'b0, INIT[ 151*8 +: 8], 1'b0, INIT[ 150*8 +: 8], 1'b0, INIT[ 149*8 +: 8], 1'b0, INIT[ 148*8 +: 8], 
+          1'b0, INIT[ 147*8 +: 8], 1'b0, INIT[ 146*8 +: 8], 1'b0, INIT[ 145*8 +: 8], 1'b0, INIT[ 144*8 +: 8], 
+          1'b0, INIT[ 143*8 +: 8], 1'b0, INIT[ 142*8 +: 8], 1'b0, INIT[ 141*8 +: 8], 1'b0, INIT[ 140*8 +: 8], 
+          1'b0, INIT[ 139*8 +: 8], 1'b0, INIT[ 138*8 +: 8], 1'b0, INIT[ 137*8 +: 8], 1'b0, INIT[ 136*8 +: 8], 
+          1'b0, INIT[ 135*8 +: 8], 1'b0, INIT[ 134*8 +: 8], 1'b0, INIT[ 133*8 +: 8], 1'b0, INIT[ 132*8 +: 8], 
+          1'b0, INIT[ 131*8 +: 8], 1'b0, INIT[ 130*8 +: 8], 1'b0, INIT[ 129*8 +: 8], 1'b0, INIT[ 128*8 +: 8], 
+          1'b0, INIT[ 127*8 +: 8], 1'b0, INIT[ 126*8 +: 8], 1'b0, INIT[ 125*8 +: 8], 1'b0, INIT[ 124*8 +: 8], 
+          1'b0, INIT[ 123*8 +: 8], 1'b0, INIT[ 122*8 +: 8], 1'b0, INIT[ 121*8 +: 8], 1'b0, INIT[ 120*8 +: 8], 
+          1'b0, INIT[ 119*8 +: 8], 1'b0, INIT[ 118*8 +: 8], 1'b0, INIT[ 117*8 +: 8], 1'b0, INIT[ 116*8 +: 8], 
+          1'b0, INIT[ 115*8 +: 8], 1'b0, INIT[ 114*8 +: 8], 1'b0, INIT[ 113*8 +: 8], 1'b0, INIT[ 112*8 +: 8], 
+          1'b0, INIT[ 111*8 +: 8], 1'b0, INIT[ 110*8 +: 8], 1'b0, INIT[ 109*8 +: 8], 1'b0, INIT[ 108*8 +: 8], 
+          1'b0, INIT[ 107*8 +: 8], 1'b0, INIT[ 106*8 +: 8], 1'b0, INIT[ 105*8 +: 8], 1'b0, INIT[ 104*8 +: 8], 
+          1'b0, INIT[ 103*8 +: 8], 1'b0, INIT[ 102*8 +: 8], 1'b0, INIT[ 101*8 +: 8], 1'b0, INIT[ 100*8 +: 8], 
+          1'b0, INIT[  99*8 +: 8], 1'b0, INIT[  98*8 +: 8], 1'b0, INIT[  97*8 +: 8], 1'b0, INIT[  96*8 +: 8], 
+          1'b0, INIT[  95*8 +: 8], 1'b0, INIT[  94*8 +: 8], 1'b0, INIT[  93*8 +: 8], 1'b0, INIT[  92*8 +: 8], 
+          1'b0, INIT[  91*8 +: 8], 1'b0, INIT[  90*8 +: 8], 1'b0, INIT[  89*8 +: 8], 1'b0, INIT[  88*8 +: 8], 
+          1'b0, INIT[  87*8 +: 8], 1'b0, INIT[  86*8 +: 8], 1'b0, INIT[  85*8 +: 8], 1'b0, INIT[  84*8 +: 8], 
+          1'b0, INIT[  83*8 +: 8], 1'b0, INIT[  82*8 +: 8], 1'b0, INIT[  81*8 +: 8], 1'b0, INIT[  80*8 +: 8], 
+          1'b0, INIT[  79*8 +: 8], 1'b0, INIT[  78*8 +: 8], 1'b0, INIT[  77*8 +: 8], 1'b0, INIT[  76*8 +: 8], 
+          1'b0, INIT[  75*8 +: 8], 1'b0, INIT[  74*8 +: 8], 1'b0, INIT[  73*8 +: 8], 1'b0, INIT[  72*8 +: 8], 
+          1'b0, INIT[  71*8 +: 8], 1'b0, INIT[  70*8 +: 8], 1'b0, INIT[  69*8 +: 8], 1'b0, INIT[  68*8 +: 8], 
+          1'b0, INIT[  67*8 +: 8], 1'b0, INIT[  66*8 +: 8], 1'b0, INIT[  65*8 +: 8], 1'b0, INIT[  64*8 +: 8], 
+          1'b0, INIT[  63*8 +: 8], 1'b0, INIT[  62*8 +: 8], 1'b0, INIT[  61*8 +: 8], 1'b0, INIT[  60*8 +: 8], 
+          1'b0, INIT[  59*8 +: 8], 1'b0, INIT[  58*8 +: 8], 1'b0, INIT[  57*8 +: 8], 1'b0, INIT[  56*8 +: 8], 
+          1'b0, INIT[  55*8 +: 8], 1'b0, INIT[  54*8 +: 8], 1'b0, INIT[  53*8 +: 8], 1'b0, INIT[  52*8 +: 8], 
+          1'b0, INIT[  51*8 +: 8], 1'b0, INIT[  50*8 +: 8], 1'b0, INIT[  49*8 +: 8], 1'b0, INIT[  48*8 +: 8], 
+          1'b0, INIT[  47*8 +: 8], 1'b0, INIT[  46*8 +: 8], 1'b0, INIT[  45*8 +: 8], 1'b0, INIT[  44*8 +: 8], 
+          1'b0, INIT[  43*8 +: 8], 1'b0, INIT[  42*8 +: 8], 1'b0, INIT[  41*8 +: 8], 1'b0, INIT[  40*8 +: 8], 
+          1'b0, INIT[  39*8 +: 8], 1'b0, INIT[  38*8 +: 8], 1'b0, INIT[  37*8 +: 8], 1'b0, INIT[  36*8 +: 8], 
+          1'b0, INIT[  35*8 +: 8], 1'b0, INIT[  34*8 +: 8], 1'b0, INIT[  33*8 +: 8], 1'b0, INIT[  32*8 +: 8], 
+          1'b0, INIT[  31*8 +: 8], 1'b0, INIT[  30*8 +: 8], 1'b0, INIT[  29*8 +: 8], 1'b0, INIT[  28*8 +: 8], 
+          1'b0, INIT[  27*8 +: 8], 1'b0, INIT[  26*8 +: 8], 1'b0, INIT[  25*8 +: 8], 1'b0, INIT[  24*8 +: 8], 
+          1'b0, INIT[  23*8 +: 8], 1'b0, INIT[  22*8 +: 8], 1'b0, INIT[  21*8 +: 8], 1'b0, INIT[  20*8 +: 8], 
+          1'b0, INIT[  19*8 +: 8], 1'b0, INIT[  18*8 +: 8], 1'b0, INIT[  17*8 +: 8], 1'b0, INIT[  16*8 +: 8], 
+          1'b0, INIT[  15*8 +: 8], 1'b0, INIT[  14*8 +: 8], 1'b0, INIT[  13*8 +: 8], 1'b0, INIT[  12*8 +: 8], 
+          1'b0, INIT[  11*8 +: 8], 1'b0, INIT[  10*8 +: 8], 1'b0, INIT[   9*8 +: 8], 1'b0, INIT[   8*8 +: 8], 
+          1'b0, INIT[   7*8 +: 8], 1'b0, INIT[   6*8 +: 8], 1'b0, INIT[   5*8 +: 8], 1'b0, INIT[   4*8 +: 8], 
+          1'b0, INIT[   3*8 +: 8], 1'b0, INIT[   2*8 +: 8], 1'b0, INIT[   1*8 +: 8], 1'b0, INIT[   0*8 +: 8]}),
diff --git a/yosys-plugins/ql-qlf/pp3/brams.txt b/yosys-plugins/ql-qlf/pp3/brams.txt
new file mode 100644
index 000000000..3917bf6af
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/brams.txt
@@ -0,0 +1,54 @@
+# PP3 block RAM rules.
+
+bram $__QUICKLOGIC_RAMB16K
+  init 1
+  abits  9     @a9d32
+  dbits 32     @a9d32
+  abits 10     @a10d16
+  dbits 16     @a10d16
+  abits 11     @a11d8
+  dbits  8     @a11d8
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 4   @a9d32
+  enable 1 2   @a10d16
+  enable 1 1   @a11d8
+  transp 0 0
+  clocks 2 3
+  clkpol 2 3
+endbram
+
+bram $__QUICKLOGIC_RAMB8K
+  init 1
+  abits  9     @a9d16
+  dbits 16     @a9d16
+  abits 10     @a10d8
+  dbits  8     @a10d8
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 2   @a9d16
+  enable 1 1   @a10d8
+  transp 0 0
+  clocks 2 3
+  clkpol 2 3
+endbram
+
+match $__QUICKLOGIC_RAMB16K
+#  attribute ram_style=block ram_block
+  min bits 128
+  min efficiency 2
+#  shuffle_enable B
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QUICKLOGIC_RAMB8K
+#  attribute ram_style=block ram_block
+  min bits 128
+  min efficiency 2
+#  shuffle_enable B
+  make_transp
+endmatch
+
diff --git a/yosys-plugins/ql-qlf/pp3/brams_map.v b/yosys-plugins/ql-qlf/pp3/brams_map.v
new file mode 100644
index 000000000..c0ebb3924
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/brams_map.v
@@ -0,0 +1,1268 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$__QUICKLOGIC_RAMB16K (
+    CLK2,
+    CLK3,
+    A1ADDR,
+    A1DATA,
+    A1EN,
+    B1ADDR,
+    B1DATA,
+    B1EN
+);
+  parameter CFG_ABITS = 9;
+  parameter CFG_DBITS = 36;
+  parameter CFG_ENABLE_B = 4;
+
+  parameter CLKPOL2 = 1;
+  parameter CLKPOL3 = 1;
+  parameter [16383:0] INIT = 16384'bx;
+
+  input CLK2;
+  input CLK3;
+
+  input [CFG_ABITS-1:0] A1ADDR;
+  output [CFG_DBITS-1:0] A1DATA;
+  input A1EN;
+
+  input [CFG_ABITS-1:0] B1ADDR;
+  input [CFG_DBITS-1:0] B1DATA;
+  input [CFG_ENABLE_B-1:0] B1EN;
+
+  wire VCC = 1'b1;
+  wire GND = 1'b0;
+
+  wire [3:0] DIP, DOP;
+  wire [31:0] DI, DO;
+
+  wire [31:0] DOB;
+  wire [ 3:0] DOPB;
+
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS1_1;
+  wire [ 1:0] WS2_0;
+  wire [ 1:0] WS2_1;
+
+  wire [ 4:0] wen_reg;
+
+  assign wen_reg[4:CFG_ENABLE_B] = 0;
+  assign wen_reg[CFG_ENABLE_B-1:0] = B1EN;
+
+  assign A1DATA = DO;
+  assign DI = B1DATA;
+
+  if (CFG_DBITS <= 8) begin
+    assign WS1_0 = 2'b00;
+    assign WS2_0 = 2'b00;
+  end else if (CFG_DBITS > 8 && CFG_DBITS <= 16) begin
+    assign WS1_0 = 2'b01;
+    assign WS2_0 = 2'b01;
+  end else if (CFG_DBITS > 16) begin
+    assign WS1_0 = 2'b10;
+    assign WS2_0 = 2'b10;
+  end
+
+  generate
+    if (CFG_DBITS <= 16) begin
+      ram8k_2x1_cell_macro #(
+          `include "bram_init_32.vh"
+      ) _TECHMAP_REPLACE_ (
+          .A1_0(B1ADDR),
+          .A1_1(GND),
+          .A2_0(A1ADDR),
+          .A2_1(GND),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(CLK2),
+          .CLK1_1(CLK2),
+          .CLK1S_0(!CLKPOL2),
+          .CLK1S_1(!CLKPOL2),
+          .CLK1EN_0(VCC),
+          .CLK1EN_1(VCC),
+          .CLK2_0(CLK3),
+          .CLK2_1(CLK3),
+          .CLK2S_0(!CLKPOL3),
+          .CLK2S_1(!CLKPOL3),
+          .CLK2EN_0(A1EN),
+          .CLK2EN_1(A1EN),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(VCC),
+          .CS1_1(GND),
+          .CS2_0(VCC),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(GND),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1(GND),
+          .WD_0({GND, DI[15:8], GND, DI[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(GND),
+          .WEN1_0(wen_reg[1:0]),
+          .WEN1_1(wen_reg[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({DOP[1], DO[15:8], DOP[0], DO[7:0]}),
+          .RD_1(),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end else if (CFG_DBITS <= 32) begin
+      ram8k_2x1_cell_macro #(
+          `include "bram_init_32.vh"
+      ) _TECHMAP_REPLACE_ (
+          .A1_0(B1ADDR),
+          .A1_1(GND),
+          .A2_0(A1ADDR),
+          .A2_1(GND),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(CLK2),
+          .CLK1_1(CLK2),
+          .CLK1S_0(!CLKPOL2),
+          .CLK1S_1(!CLKPOL2),
+          .CLK1EN_0(VCC),
+          .CLK1EN_1(VCC),
+          .CLK2_0(CLK3),
+          .CLK2_1(CLK3),
+          .CLK2S_0(!CLKPOL3),
+          .CLK2S_1(!CLKPOL3),
+          .CLK2EN_0(A1EN),
+          .CLK2EN_1(A1EN),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(VCC),
+          .CS1_1(GND),
+          .CS2_0(VCC),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(GND),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1({GND, DI[31:24], GND, DI[23:16]}),
+          .WD_0({GND, DI[15:8], GND, DI[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(GND),
+          .WEN1_0(wen_reg[1:0]),
+          .WEN1_1(wen_reg[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({DOP[1], DO[15:8], DOP[0], DO[7:0]}),
+          .RD_1({DOP[3], DO[31:24], DOP[2], DO[23:16]}),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end else begin
+      wire TECHMAP_FAIL = 1'b1;
+    end
+  endgenerate
+endmodule
+
+// ------------------------------------------------------------------------
+
+module \$__QUICKLOGIC_RAMB8K (
+    CLK2,
+    CLK3,
+    A1ADDR,
+    A1DATA,
+    A1EN,
+    B1ADDR,
+    B1DATA,
+    B1EN
+);
+  parameter CFG_ABITS = 9;
+  parameter CFG_DBITS = 18;
+  parameter CFG_ENABLE_B = 2;
+
+  parameter CLKPOL2 = 1;
+  parameter CLKPOL3 = 1;
+  parameter [8191:0] INIT = 8192'bx;
+
+  input CLK2;
+  input CLK3;
+
+  input [CFG_ABITS-1:0] A1ADDR;
+  output [CFG_DBITS-1:0] A1DATA;
+  input A1EN;
+
+  input [CFG_ABITS-1:0] B1ADDR;
+  input [CFG_DBITS-1:0] B1DATA;
+  input [CFG_ENABLE_B-1:0] B1EN;
+
+  wire [10:0] A1ADDR_11;
+  wire [10:0] B1ADDR_11;
+
+  wire [1:0] DIP, DOP;
+  wire [15:0] DI, DO;
+
+  wire [15:0] DOBDO;
+  wire [ 1:0] DOPBDOP;
+
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS1_1;
+  wire [ 1:0] WS2_0;
+  wire [ 1:0] WS2_1;
+
+  wire [ 2:0] wen_reg;
+
+  assign wen_reg[2:CFG_ENABLE_B] = 0;
+  assign wen_reg[CFG_ENABLE_B-1:0] = B1EN;
+
+  wire GND = 1'b0;
+  wire VCC = 1'b1;
+
+  assign A1DATA = DO;
+  assign DI = B1DATA;
+
+  if (CFG_ABITS == 11) begin
+    assign A1ADDR_11[CFG_ABITS-1:0] = A1ADDR;
+    assign B1ADDR_11[CFG_ABITS-1:0] = B1ADDR;
+  end else begin
+    assign A1ADDR_11[10:CFG_ABITS]  = 0;
+    assign A1ADDR_11[CFG_ABITS-1:0] = A1ADDR;
+    assign B1ADDR_11[10:CFG_ABITS]  = 0;
+    assign B1ADDR_11[CFG_ABITS-1:0] = B1ADDR;
+  end
+
+  if (CFG_DBITS <= 9) begin
+    assign WS1_0 = 2'b00;
+    assign WS2_0 = 2'b00;
+  end else if (CFG_DBITS > 9 && CFG_DBITS <= 18) begin
+    assign WS1_0 = 2'b01;
+    assign WS2_0 = 2'b01;
+  end else if (CFG_DBITS > 18) begin
+    assign WS1_0 = 2'b10;
+    assign WS2_0 = 2'b10;
+  end
+
+  ram8k_2x1_cell_macro #(
+      `include "bram_init_8_16.vh"
+  ) _TECHMAP_REPLACE_ (
+      .A1_0(B1ADDR_11),
+      .A1_1(GND),
+      .A2_0(A1ADDR_11),
+      .A2_1(GND),
+      .ASYNC_FLUSH_0(GND),
+      .ASYNC_FLUSH_1(GND),
+      .ASYNC_FLUSH_S0(GND),
+      .ASYNC_FLUSH_S1(GND),
+      .CLK1_0(CLK2),
+      .CLK1_1(GND),
+      .CLK1S_0(!CLKPOL2),
+      .CLK1S_1(GND),
+      .CLK1EN_0(VCC),
+      .CLK1EN_1(VCC),
+      .CLK2_0(CLK3),
+      .CLK2_1(GND),
+      .CLK2S_0(!CLKPOL3),
+      .CLK2S_1(GND),
+      .CLK2EN_0(A1EN),
+      .CLK2EN_1(GND),
+      .CONCAT_EN_0(GND),
+      .CONCAT_EN_1(GND),
+      .CS1_0(VCC),
+      .CS1_1(GND),
+      .CS2_0(VCC),
+      .CS2_1(GND),
+      .DIR_0(GND),
+      .DIR_1(GND),
+      .FIFO_EN_0(GND),
+      .FIFO_EN_1(GND),
+      .P1_0(GND),
+      .P1_1(GND),
+      .P2_0(GND),
+      .P2_1(GND),
+      .PIPELINE_RD_0(GND),
+      .PIPELINE_RD_1(GND),
+      .SYNC_FIFO_0(GND),
+      .SYNC_FIFO_1(GND),
+      .WD_1(GND),
+      .WD_0({GND, DI[15:8], GND, DI[7:0]}),
+      .WIDTH_SELECT1_0(WS1_0),
+      .WIDTH_SELECT1_1(GND),
+      .WIDTH_SELECT2_0(WS2_0),
+      .WIDTH_SELECT2_1(GND),
+      .WEN1_0(wen_reg[1:0]),
+      .WEN1_1(GND),
+      .Almost_Empty_0(),
+      .Almost_Empty_1(),
+      .Almost_Full_0(),
+      .Almost_Full_1(),
+      .POP_FLAG_0(),
+      .POP_FLAG_1(),
+      .PUSH_FLAG_0(),
+      .PUSH_FLAG_1(),
+      .RD_0({DOP[1], DO[15:8], DOP[0], DO[7:0]}),
+      .RD_1(),
+      .TEST1A(GND),
+      .TEST1B(GND),
+      .RMA(4'd0),
+      .RMB(4'd0),
+      .RMEA(GND),
+      .RMEB(GND)
+  );
+endmodule
+
+module RAM_8K_BLK (
+    WA,
+    RA,
+    WD,
+    WClk,
+    RClk,
+    WClk_En,
+    RClk_En,
+    WEN,
+    RD
+);
+
+  parameter addr_int 	= 9,
+          data_depth_int = 512,
+          data_width_int = 18,
+          wr_enable_int 	= 2,
+          reg_rd_int 	= 0;
+
+  parameter [8191:0] INIT = 8192'bx;
+  parameter INIT_FILE = "init.mem";
+
+  input [addr_int-1:0] WA;
+  input [addr_int-1:0] RA;
+  input WClk, RClk;
+  input WClk_En, RClk_En;
+  input [wr_enable_int-1:0] WEN;
+  input [data_width_int-1:0] WD;
+  output [data_width_int-1:0] RD;
+
+  wire VCC, GND;
+  wire WClk0_Sel, RClk0_Sel;
+  wire WClk1_Sel, RClk1_Sel;
+
+  wire reg_rd0;
+  wire reg_rd1;
+  wire [10:0] addr_wr0, addr_rd0, addr_wr1, addr_rd1;
+
+  wire [17:0] in_reg0;
+
+  wire [ 2:0] wen_reg0;
+
+  wire [15:0] out_reg0;
+
+  wire [ 1:0] out_par0;
+
+  wire [1:0] WS1_0, WS2_0;
+  wire [1:0] WS_GND;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+
+  wire WD0_SEL, RD0_SEL;
+  wire WD1_SEL, RD1_SEL;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign WD0_SEL = 1'b1;
+  assign RD0_SEL = 1'b1;
+  assign WD1_SEL = 1'b0;
+  assign RD1_SEL = 1'b0;
+
+  assign WClk0_Sel = 1'b0;
+  assign RClk0_Sel = 1'b0;
+
+  assign WClk1_Sel = 1'b0;
+  assign RClk1_Sel = 1'b0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign WS_GND = 2'b00;
+
+  assign reg_rd1 = 1'b0;
+
+  assign wen_reg0[2:wr_enable_int] = 0;
+  assign wen_reg0[wr_enable_int-1:0] = WEN;
+
+  assign addr_wr1 = 11'b0000000000;
+  assign addr_rd1 = 11'b0000000000;
+
+  generate
+
+    if (addr_int == 11) begin
+      assign addr_wr0[10:0] = WA;
+      assign addr_rd0[10:0] = RA;
+    end else begin
+      assign addr_wr0[10:addr_int]  = 0;
+      assign addr_wr0[addr_int-1:0] = WA;
+      assign addr_rd0[10:addr_int]  = 0;
+      assign addr_rd0[addr_int-1:0] = RA;
+    end
+
+    if (data_width_int == 16) begin
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 16) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+  endgenerate
+
+  ram8k_2x1_cell_macro #(
+      .INIT(INIT)
+  ) _TECHMAP_REPLACE_ (
+      .A1_0(addr_wr0),
+      .A1_1(addr_wr1),
+      .A2_0(addr_rd0),
+      .A2_1(addr_rd1),
+      .ASYNC_FLUSH_0(GND),
+      .ASYNC_FLUSH_1(GND),
+      .ASYNC_FLUSH_S0(GND),
+      .ASYNC_FLUSH_S1(GND),
+      .CLK1_0(WClk),
+      .CLK1_1(GND),
+      .CLK1S_0(WClk0_Sel),
+      .CLK1S_1(WClk1_Sel),
+      .CLK1EN_0(WClk_En),
+      .CLK1EN_1(GND),
+      .CLK2_0(RClk),
+      .CLK2_1(GND),
+      .CLK2S_0(RClk0_Sel),
+      .CLK2S_1(RClk1_Sel),
+      .CLK2EN_0(RClk_En),
+      .CLK2EN_1(GND),
+      .CONCAT_EN_0(GND),
+      .CONCAT_EN_1(GND),
+      .CS1_0(WD0_SEL),
+      .CS1_1(WD1_SEL),
+      .CS2_0(RD0_SEL),
+      .CS2_1(RD1_SEL),
+      .DIR_0(GND),
+      .DIR_1(GND),
+      .FIFO_EN_0(GND),
+      .FIFO_EN_1(GND),
+      .P1_0(GND),
+      .P1_1(GND),
+      .P2_0(GND),
+      .P2_1(GND),
+      .PIPELINE_RD_0(reg_rd0),
+      .PIPELINE_RD_1(reg_rd1),
+      .SYNC_FIFO_0(GND),
+      .SYNC_FIFO_1(GND),
+      .WD_1({18{GND}}),
+      .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+      .WIDTH_SELECT1_0(WS1_0),
+      .WIDTH_SELECT1_1(WS_GND),
+      .WIDTH_SELECT2_0(WS2_0),
+      .WIDTH_SELECT2_1(WS_GND),
+      .WEN1_0(wen_reg0[1:0]),
+      .WEN1_1({2{GND}}),
+      .Almost_Empty_0(),
+      .Almost_Empty_1(),
+      .Almost_Full_0(),
+      .Almost_Full_1(),
+      .POP_FLAG_0(),
+      .POP_FLAG_1(),
+      .PUSH_FLAG_0(),
+      .PUSH_FLAG_1(),
+      .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+      .RD_1(),
+      .SD(SD),
+      .SD_RB1(SD_RB1),
+      .LS(LS),
+      .LS_RB1(LS_RB1),
+      .DS(DS),
+      .DS_RB1(DS_RB1),
+      .TEST1A(GND),
+      .TEST1B(GND),
+      .RMA(4'd0),
+      .RMB(4'd0),
+      .RMEA(GND),
+      .RMEB(GND)
+  );
+
+  assign RD[data_width_int-1 : 0] = {out_par0, out_reg0};
+
+endmodule
+
+
+module RAM_16K_BLK (
+    WA,
+    RA,
+    WD,
+    WClk,
+    RClk,
+    WClk_En,
+    RClk_En,
+    WEN,
+    RD
+);
+
+  parameter addr_int       = 9,
+          data_depth_int = 512,
+	  data_width_int = 36,
+          wr_enable_int  = 4,
+	  reg_rd_int 	 = 0;
+
+  parameter [16383:0] INIT = 16384'bx;
+  parameter INIT_FILE = "init.mem";
+
+  input [addr_int-1:0] WA;
+  input [addr_int-1:0] RA;
+  input WClk, RClk;
+  input WClk_En, RClk_En;
+  input [wr_enable_int-1:0] WEN;
+  input [data_width_int-1:0] WD;
+  output [data_width_int-1:0] RD;
+
+  wire VCC, GND;
+
+  wire WClk0_Sel, RClk0_Sel;
+  wire WClk1_Sel, RClk1_Sel;
+
+  wire reg_rd0;
+  wire reg_rd1;
+  wire [10:0] addr_wr0, addr_rd0, addr_wr1, addr_rd1;
+
+  wire [31:0] in_reg0;
+
+  wire [ 4:0] wen_reg0;
+
+  wire [31:0] out_reg0;
+
+  wire [ 3:0] out_par0;
+
+  wire [1:0] WS1_0, WS2_0;
+  wire [1:0] WS_GND;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+
+  wire WD0_SEL, RD0_SEL;
+  wire WD1_SEL, RD1_SEL;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign WD0_SEL = 1'b1;
+  assign RD0_SEL = 1'b1;
+  assign WD1_SEL = 1'b1;
+  assign RD1_SEL = 1'b1;
+
+  assign WClk0_Sel = 1'b0;
+  assign RClk0_Sel = 1'b0;
+
+  assign WClk1_Sel = 1'b0;
+  assign RClk1_Sel = 1'b0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign WS_GND = 2'b00;
+
+  assign reg_rd1 = 1'b0;
+
+  assign wen_reg0[4:wr_enable_int] = 0;
+  assign wen_reg0[wr_enable_int-1:0] = WEN;
+
+  assign addr_wr1 = 11'b0000000000;
+  assign addr_rd1 = 11'b0000000000;
+
+  generate
+
+    if (addr_int == 11) begin
+      assign addr_wr0[10:0] = WA;
+      assign addr_rd0[10:0] = RA;
+    end else begin
+      assign addr_wr0[10:addr_int]  = 0;
+      assign addr_wr0[addr_int-1:0] = WA;
+      assign addr_rd0[10:addr_int]  = 0;
+      assign addr_rd0[addr_int-1:0] = RA;
+    end
+
+    if (data_width_int == 32) begin
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 32) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+    if (data_width_int <= 16) begin
+
+      ram8k_2x1_cell_macro #(
+          .INIT(INIT)
+      ) _TECHMAP_REPLACE_ (
+          .A1_0(addr_wr0),
+          .A1_1(addr_wr1),
+          .A2_0(addr_rd0),
+          .A2_1(addr_rd1),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(WClk),
+          .CLK1_1(WClk),
+          .CLK1S_0(WClk0_Sel),
+          .CLK1S_1(WClk0_Sel),
+          .CLK1EN_0(WClk_En),
+          .CLK1EN_1(WClk_En),
+          .CLK2_0(RClk),
+          .CLK2_1(RClk),
+          .CLK2S_0(RClk0_Sel),
+          .CLK2S_1(RClk0_Sel),
+          .CLK2EN_0(RClk_En),
+          .CLK2EN_1(RClk_En),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(WD0_SEL),
+          .CS1_1(GND),
+          .CS2_0(RD0_SEL),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1({18{GND}}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(WS_GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(WS_GND),
+          .WEN1_0(wen_reg0[1:0]),
+          .WEN1_1(wen_reg0[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1(),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end else if (data_width_int > 16) begin
+
+      ram8k_2x1_cell_macro #(
+          .INIT(INIT)
+      ) _TECHMAP_REPLACE_ (
+          .A1_0(addr_wr0),
+          .A1_1(addr_wr1),
+          .A2_0(addr_rd0),
+          .A2_1(addr_rd1),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(WClk),
+          .CLK1_1(WClk),
+          .CLK1S_0(WClk0_Sel),
+          .CLK1S_1(WClk0_Sel),
+          .CLK1EN_0(WClk_En),
+          .CLK1EN_1(WClk_En),
+          .CLK2_0(RClk),
+          .CLK2_1(RClk),
+          .CLK2S_0(RClk0_Sel),
+          .CLK2S_1(RClk0_Sel),
+          .CLK2EN_0(RClk_En),
+          .CLK2EN_1(RClk_En),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(WD0_SEL),
+          .CS1_1(GND),
+          .CS2_0(RD0_SEL),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1({1'b0, in_reg0[31:24], 1'b0, in_reg0[23:16]}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(WS_GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(WS_GND),
+          .WEN1_0(wen_reg0[1:0]),
+          .WEN1_1(wen_reg0[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1({out_par0[3], out_reg0[31:24], out_par0[2], out_reg0[23:16]}),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end else begin
+      wire TECHMAP_FAIL = 1'b1;
+    end
+
+  endgenerate
+
+  assign RD[data_width_int-1 : 0] = {out_par0, out_reg0};
+
+endmodule
+
+
+module FIFO_8K_BLK (
+    DIN,
+    Fifo_Push_Flush,
+    Fifo_Pop_Flush,
+    PUSH,
+    POP,
+    Push_Clk,
+    Pop_Clk,
+    Push_Clk_En,
+    Pop_Clk_En,
+    Fifo_Dir,
+    Async_Flush,
+    Almost_Full,
+    Almost_Empty,
+    PUSH_FLAG,
+    POP_FLAG,
+    DOUT
+);
+
+  parameter data_depth_int = 512, data_width_int = 18, reg_rd_int = 0, sync_fifo_int = 0;
+
+  input Fifo_Push_Flush, Fifo_Pop_Flush;
+  input Push_Clk, Pop_Clk;
+  input PUSH, POP;
+  input [data_width_int-1:0] DIN;
+  input Push_Clk_En, Pop_Clk_En, Fifo_Dir, Async_Flush;
+  output [data_width_int-1:0] DOUT;
+  output [3:0] PUSH_FLAG, POP_FLAG;
+  output Almost_Full, Almost_Empty;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+  wire VCC, GND;
+
+  wire [10:0] addr_wr, addr_rd;
+  wire clk1_sig0, clk2_sig0, clk1_sig_en0, clk2_sig_en0, fifo_clk1_flush_sig0, fifo_clk2_flush_sig0, p1_sig0, p2_sig0,clk1_sig_sel0,clk2_sig_sel0;
+  wire reg_rd0, sync_fifo0;
+  wire [15:0] in_reg0;
+  wire [15:0] out_reg0;
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS2_0;
+  wire Push_Clk0_Sel, Pop_Clk0_Sel;
+  wire Async_Flush_Sel0;
+
+  wire [1:0] out_par0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign Push_Clk0_Sel  	= 1'b0;
+  assign Pop_Clk0_Sel   	= 1'b0;
+  assign Async_Flush_Sel0 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign sync_fifo0 = sync_fifo_int;
+
+  assign addr_wr=11'b00000000000;
+  assign addr_rd=11'b00000000000;
+
+  assign clk1_sig0 = Fifo_Dir ? Pop_Clk : Push_Clk;
+  assign clk2_sig0 = Fifo_Dir ? Push_Clk : Pop_Clk ;
+  assign clk1_sig_en0 = Fifo_Dir ? Pop_Clk_En : Push_Clk_En;
+  assign clk2_sig_en0 = Fifo_Dir ? Push_Clk_En : Pop_Clk_En ;
+  assign clk1_sig_sel0 =  Push_Clk0_Sel;
+  assign clk2_sig_sel0 =  Pop_Clk0_Sel ;
+  assign fifo_clk1_flush_sig0 = Fifo_Dir ? Fifo_Pop_Flush : Fifo_Push_Flush;
+  assign fifo_clk2_flush_sig0 = Fifo_Dir ? Fifo_Push_Flush : Fifo_Pop_Flush ;
+  assign p1_sig0 = Fifo_Dir ? POP : PUSH;
+  assign p2_sig0 = Fifo_Dir ? PUSH : POP ;
+
+  generate
+
+    if (data_width_int == 16) begin
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 16) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+  endgenerate
+
+  ram8k_2x1_cell_macro _TECHMAP_REPLACE_ (
+      .A1_0(addr_wr),
+      .A1_1(addr_wr),
+      .A2_0(addr_rd),
+      .A2_1(addr_rd),
+      .ASYNC_FLUSH_0(Async_Flush),
+      .ASYNC_FLUSH_1(GND),
+      .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+      .ASYNC_FLUSH_S1(GND),
+      .CLK1_0(clk1_sig0),
+      .CLK1_1(GND),
+      .CLK1EN_0(clk1_sig_en0),
+      .CLK1EN_1(GND),
+      .CLK2_0(clk2_sig0),
+      .CLK2_1(GND),
+      .CLK1S_0(clk1_sig_sel0),
+      .CLK1S_1(GND),
+      .CLK2S_0(clk2_sig_sel0),
+      .CLK2S_1(GND),
+      .CLK2EN_0(clk2_sig_en0),
+      .CLK2EN_1(GND),
+      .CONCAT_EN_0(GND),
+      .CONCAT_EN_1(GND),
+      .CS1_0(fifo_clk1_flush_sig0),
+      .CS1_1(GND),
+      .CS2_0(fifo_clk2_flush_sig0),
+      .CS2_1(GND),
+      .DIR_0(Fifo_Dir),
+      .DIR_1(GND),
+      .FIFO_EN_0(VCC),
+      .FIFO_EN_1(GND),
+      .P1_0(p1_sig0),
+      .P1_1(GND),
+      .P2_0(p2_sig0),
+      .P2_1(GND),
+      .PIPELINE_RD_0(reg_rd0),
+      .PIPELINE_RD_1(GND),
+      .SYNC_FIFO_0(sync_fifo0),
+      .SYNC_FIFO_1(GND),
+      .WD_1({18{GND}}),
+      .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+      .WIDTH_SELECT1_0(WS1_0),
+      .WIDTH_SELECT1_1({GND, GND}),
+      .WIDTH_SELECT2_0(WS2_0),
+      .WIDTH_SELECT2_1({GND, GND}),
+      .WEN1_0({GND, GND}),
+      .WEN1_1({GND, GND}),
+      .Almost_Empty_0(Almost_Empty),
+      .Almost_Empty_1(),
+      .Almost_Full_0(Almost_Full),
+      .Almost_Full_1(),
+      .POP_FLAG_0(POP_FLAG),
+      .POP_FLAG_1(),
+      .PUSH_FLAG_0(PUSH_FLAG),
+      .PUSH_FLAG_1(),
+      .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+      .RD_1(),
+      .SD(SD),
+      .SD_RB1(SD_RB1),
+      .LS(LS),
+      .LS_RB1(LS_RB1),
+      .DS(DS),
+      .DS_RB1(DS_RB1),
+      .TEST1A(GND),
+      .TEST1B(GND),
+      .RMA(4'd0),
+      .RMB(4'd0),
+      .RMEA(GND),
+      .RMEB(GND)
+  );
+
+  assign DOUT[data_width_int-1 : 0] = {out_par0, out_reg0};
+
+endmodule
+
+
+module FIFO_16K_BLK (
+    DIN,
+    Fifo_Push_Flush,
+    Fifo_Pop_Flush,
+    PUSH,
+    POP,
+    Push_Clk,
+    Pop_Clk,
+    Push_Clk_En,
+    Pop_Clk_En,
+    Fifo_Dir,
+    Async_Flush,
+    Almost_Full,
+    Almost_Empty,
+    PUSH_FLAG,
+    POP_FLAG,
+    DOUT
+);
+
+  parameter data_depth_int = 512, data_width_int = 36, reg_rd_int = 0, sync_fifo_int = 0;
+
+  input Fifo_Push_Flush, Fifo_Pop_Flush;
+  input Push_Clk, Pop_Clk;
+  input PUSH, POP;
+  input [data_width_int-1:0] DIN;
+  input Push_Clk_En, Pop_Clk_En, Fifo_Dir, Async_Flush;
+  output [data_width_int-1:0] DOUT;
+  output [3:0] PUSH_FLAG, POP_FLAG;
+  output Almost_Full, Almost_Empty;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+  wire VCC, GND;
+
+  wire [10:0] addr_wr, addr_rd;
+  wire clk1_sig0, clk2_sig0, clk1_sig_en0, clk2_sig_en0, fifo_clk1_flush_sig0, fifo_clk2_flush_sig0, p1_sig0, p2_sig0,clk1_sig_sel0,clk2_sig_sel0;
+  wire reg_rd0, sync_fifo0;
+  wire [31:0] in_reg0;
+  wire [31:0] out_reg0;
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS2_0;
+  wire Push_Clk0_Sel, Pop_Clk0_Sel;
+  wire Async_Flush_Sel0;
+
+  wire [3:0] out_par0;
+  wire [1:0] out_par1;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign Push_Clk0_Sel  	= 1'b0;
+  assign Pop_Clk0_Sel   	= 1'b0;
+  assign Async_Flush_Sel0 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign sync_fifo0 = sync_fifo_int;
+
+  assign addr_wr=11'b00000000000;
+  assign addr_rd=11'b00000000000;
+
+  assign clk1_sig0 = Fifo_Dir ? Pop_Clk : Push_Clk;
+  assign clk2_sig0 = Fifo_Dir ? Push_Clk : Pop_Clk ;
+  assign clk1_sig_en0 = Fifo_Dir ? Pop_Clk_En : Push_Clk_En;
+  assign clk2_sig_en0 = Fifo_Dir ? Push_Clk_En : Pop_Clk_En ;
+  assign clk1_sig_sel0 =  Push_Clk0_Sel;
+  assign clk2_sig_sel0 =  Pop_Clk0_Sel ;
+  assign fifo_clk1_flush_sig0 = Fifo_Dir ? Fifo_Pop_Flush : Fifo_Push_Flush;
+  assign fifo_clk2_flush_sig0 = Fifo_Dir ? Fifo_Push_Flush : Fifo_Pop_Flush ;
+  assign p1_sig0 = Fifo_Dir ? POP : PUSH;
+  assign p2_sig0 = Fifo_Dir ? PUSH : POP ;
+
+  generate
+    if (data_width_int == 32) begin
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 32) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+    if (data_width_int <= 16) begin
+
+      ram8k_2x1_cell_macro _TECHMAP_REPLACE_ (
+          .A1_0(addr_wr),
+          .A1_1(addr_wr),
+          .A2_0(addr_rd),
+          .A2_1(addr_rd),
+          .ASYNC_FLUSH_0(Async_Flush),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+          .ASYNC_FLUSH_S1(Async_Flush_Sel0),
+          .CLK1_0(clk1_sig0),
+          .CLK1_1(clk1_sig0),
+          .CLK1EN_0(clk1_sig_en0),
+          .CLK1EN_1(clk1_sig_en0),
+          .CLK2_0(clk2_sig0),
+          .CLK2_1(clk2_sig0),
+          .CLK1S_0(clk1_sig_sel0),
+          .CLK1S_1(clk1_sig_sel0),
+          .CLK2S_0(clk2_sig_sel0),
+          .CLK2S_1(clk2_sig_sel0),
+          .CLK2EN_0(clk2_sig_en0),
+          .CLK2EN_1(clk2_sig_en0),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(fifo_clk1_flush_sig0),
+          .CS1_1(GND),
+          .CS2_0(fifo_clk2_flush_sig0),
+          .CS2_1(GND),
+          .DIR_0(Fifo_Dir),
+          .DIR_1(GND),
+          .FIFO_EN_0(VCC),
+          .FIFO_EN_1(GND),
+          .P1_0(p1_sig0),
+          .P1_1(GND),
+          .P2_0(p2_sig0),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(sync_fifo0),
+          .SYNC_FIFO_1(GND),
+          .WD_1({18{GND}}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1({GND, GND}),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1({GND, GND}),
+          .WEN1_0({GND, GND}),
+          .WEN1_1({GND, GND}),
+          .Almost_Empty_0(Almost_Empty),
+          .Almost_Empty_1(),
+          .Almost_Full_0(Almost_Full),
+          .Almost_Full_1(),
+          .POP_FLAG_0(POP_FLAG),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(PUSH_FLAG),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1(),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+
+    end else if (data_width_int > 16) begin
+
+      ram8k_2x1_cell_macro _TECHMAP_REPLACE_ (
+          .A1_0(addr_wr),
+          .A1_1(addr_wr),
+          .A2_0(addr_rd),
+          .A2_1(addr_rd),
+          .ASYNC_FLUSH_0(Async_Flush),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+          .ASYNC_FLUSH_S1(Async_Flush_Sel0),
+          .CLK1_0(clk1_sig0),
+          .CLK1_1(clk1_sig0),
+          .CLK1EN_0(clk1_sig_en0),
+          .CLK1EN_1(clk1_sig_en0),
+          .CLK2_0(clk2_sig0),
+          .CLK2_1(clk2_sig0),
+          .CLK1S_0(clk1_sig_sel0),
+          .CLK1S_1(clk1_sig_sel0),
+          .CLK2S_0(clk2_sig_sel0),
+          .CLK2S_1(clk2_sig_sel0),
+          .CLK2EN_0(clk2_sig_en0),
+          .CLK2EN_1(clk2_sig_en0),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(fifo_clk1_flush_sig0),
+          .CS1_1(GND),
+          .CS2_0(fifo_clk2_flush_sig0),
+          .CS2_1(GND),
+          .DIR_0(Fifo_Dir),
+          .DIR_1(GND),
+          .FIFO_EN_0(VCC),
+          .FIFO_EN_1(GND),
+          .P1_0(p1_sig0),
+          .P1_1(GND),
+          .P2_0(p2_sig0),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(sync_fifo0),
+          .SYNC_FIFO_1(GND),
+          .WD_1({1'b0, in_reg0[31:24], 1'b0, in_reg0[23:16]}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1({GND, GND}),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1({GND, GND}),
+          .WEN1_0({GND, GND}),
+          .WEN1_1({GND, GND}),
+          .Almost_Empty_0(Almost_Empty),
+          .Almost_Empty_1(),
+          .Almost_Full_0(Almost_Full),
+          .Almost_Full_1(),
+          .POP_FLAG_0(POP_FLAG),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(PUSH_FLAG),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1({out_par0[3], out_reg0[31:24], out_par0[2], out_reg0[23:16]}),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end
+
+  endgenerate
+
+  assign DOUT[data_width_int-1 : 0] = {out_par0, out_reg0};
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/brams_sim.v b/yosys-plugins/ql-qlf/pp3/brams_sim.v
new file mode 100644
index 000000000..1b1525683
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/brams_sim.v
@@ -0,0 +1,2940 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns / 10ps
+module fifo_controller_model (
+    Rst_n,
+    Push_Clk,
+    Pop_Clk,
+
+    Fifo_Push,
+    Fifo_Push_Flush,
+    Fifo_Full,
+    Fifo_Full_Usr,
+
+    Fifo_Pop,
+    Fifo_Pop_Flush,
+    Fifo_Empty,
+    Fifo_Empty_Usr,
+
+    Write_Addr,
+
+    Read_Addr,
+
+    //	 Static Control Signals
+    Fifo_Ram_Mode,
+    Fifo_Sync_Mode,
+    Fifo_Push_Width,
+    Fifo_Pop_Width
+);
+
+
+
+  //************* PPII 4K Parameters **************************//
+
+  parameter MAX_PTR_WIDTH = 12;
+
+  parameter DEPTH1 = (1 << (MAX_PTR_WIDTH - 3));
+  parameter DEPTH2 = (1 << (MAX_PTR_WIDTH - 2));
+  parameter DEPTH3 = (1 << (MAX_PTR_WIDTH - 1));
+
+  parameter D1_QTR_A = MAX_PTR_WIDTH - 5;
+  parameter D2_QTR_A = MAX_PTR_WIDTH - 4;
+  parameter D3_QTR_A = MAX_PTR_WIDTH - 3;
+
+  input Rst_n;
+  input Push_Clk;
+  input Pop_Clk;
+
+  input Fifo_Push;
+  input Fifo_Push_Flush;
+  output Fifo_Full;
+  output [3:0] Fifo_Full_Usr;
+
+  input Fifo_Pop;
+  input Fifo_Pop_Flush;
+  output Fifo_Empty;
+  output [3:0] Fifo_Empty_Usr;
+
+  output [MAX_PTR_WIDTH-2:0] Write_Addr;
+
+  output [MAX_PTR_WIDTH-2:0] Read_Addr;
+
+  input Fifo_Ram_Mode;
+  input Fifo_Sync_Mode;
+  input [1:0] Fifo_Push_Width;
+  input [1:0] Fifo_Pop_Width;
+
+  reg    flush_pop_clk_tf;
+  reg    flush_pop2push_clk1;
+  reg    flush_push_clk_tf;
+  reg    flush_push2pop_clk1;
+  reg    pop_local_flush_mask;
+  reg    push_flush_tf_pop_clk;
+  reg    pop2push_ack1;
+  reg    pop2push_ack2;
+  reg    push_local_flush_mask;
+  reg    pop_flush_tf_push_clk;
+  reg    push2pop_ack1;
+  reg    push2pop_ack2;
+
+  reg    fifo_full_flag_f;
+  reg    [3:0]  Fifo_Full_Usr;
+
+  reg    fifo_empty_flag_f;
+  reg    [3:0]  Fifo_Empty_Usr;
+
+  reg    [MAX_PTR_WIDTH-1:0]  push_ptr_push_clk;
+  reg    [MAX_PTR_WIDTH-1:0]  pop_ptr_push_clk;
+  reg    [MAX_PTR_WIDTH-1:0]  pop_ptr_async;
+  reg    [MAX_PTR_WIDTH-1:0]  pop_ptr_pop_clk ;
+  reg    [MAX_PTR_WIDTH-1:0]  push_ptr_pop_clk;
+  reg    [MAX_PTR_WIDTH-1:0]  push_ptr_async;
+
+  reg    [1:0]  push_ptr_push_clk_mask;
+  reg    [1:0]  pop_ptr_pop_clk_mask;
+
+  reg    [MAX_PTR_WIDTH-1:0]  pop_ptr_push_clk_mux;
+  reg    [MAX_PTR_WIDTH-1:0]  push_ptr_pop_clk_mux;
+
+  reg    match_room4none;
+  reg    match_room4one;
+  reg    match_room4half;
+  reg    match_room4quart;
+
+  reg    match_all_left;
+  reg    match_half_left;
+  reg    match_quart_left;
+
+  reg   [MAX_PTR_WIDTH-1:0]   depth1_reg;
+  reg   [MAX_PTR_WIDTH-1:0]   depth2_reg;
+  reg   [MAX_PTR_WIDTH-1:0]   depth3_reg;
+
+
+  wire	push_clk_rst;
+  wire	push_clk_rst_mux;
+  wire	push_flush_done;
+  wire	pop_clk_rst;
+  wire	pop_clk_rst_mux;
+  wire	pop_flush_done;
+
+  wire	push_flush_gated;
+  wire	pop_flush_gated;
+
+  wire	[MAX_PTR_WIDTH-2:0] Write_Addr;
+  wire	[MAX_PTR_WIDTH-2:0] Read_Addr;
+
+  wire	[MAX_PTR_WIDTH-1:0] push_ptr_push_clk_plus1;
+  wire	[MAX_PTR_WIDTH-1:0] next_push_ptr_push_clk;
+  wire	[MAX_PTR_WIDTH-1:0] pop_ptr_pop_clk_plus1;
+  wire	[MAX_PTR_WIDTH-1:0] next_pop_ptr_pop_clk;
+  wire	[MAX_PTR_WIDTH-1:0] next_push_ptr_push_clk_mask;
+  wire	[MAX_PTR_WIDTH-1:0] next_pop_ptr_pop_clk_mask;
+
+  wire	[MAX_PTR_WIDTH-1:0] pop_ptr_push_clk_l_shift1;
+  wire	[MAX_PTR_WIDTH-1:0] pop_ptr_push_clk_l_shift2;
+  wire	[MAX_PTR_WIDTH-1:0] pop_ptr_push_clk_r_shift1;
+  wire	[MAX_PTR_WIDTH-1:0] pop_ptr_push_clk_r_shift2;
+
+  wire	[MAX_PTR_WIDTH-1:0] push_ptr_pop_clk_l_shift1;
+  wire	[MAX_PTR_WIDTH-1:0] push_ptr_pop_clk_l_shift2;
+  wire	[MAX_PTR_WIDTH-1:0] push_ptr_pop_clk_r_shift1;
+  wire	[MAX_PTR_WIDTH-1:0] push_ptr_pop_clk_r_shift2;
+
+  wire	[MAX_PTR_WIDTH-1:0] push_diff;
+  wire	[MAX_PTR_WIDTH-1:0] push_diff_plus_1;
+  wire	[MAX_PTR_WIDTH-1:0] pop_diff;
+
+  wire	match_room4all;
+  wire	match_room4eight;
+
+  wire	match_one_left;
+  wire	match_one2eight_left;
+
+  integer	depth_sel_push;
+  integer depth_sel_pop;
+
+  initial begin
+    depth1_reg = DEPTH1;
+    depth2_reg = DEPTH2;
+    depth3_reg = DEPTH3;
+  end
+
+  initial begin
+    flush_pop_clk_tf      <= 1'b0;
+    push2pop_ack1         <= 1'b0;
+    push2pop_ack2         <= 1'b0;
+    pop_local_flush_mask  <= 1'b0;
+    flush_push2pop_clk1   <= 1'b0;
+    push_flush_tf_pop_clk <= 1'b0;
+    flush_push_clk_tf     <= 1'b0;
+    pop2push_ack1         <= 1'b0;
+    pop2push_ack2         <= 1'b0;
+    push_local_flush_mask <= 1'b0;
+    flush_pop2push_clk1   <= 1'b0;
+    pop_flush_tf_push_clk <= 1'b0;
+    push_ptr_push_clk     <= 0;
+    pop_ptr_push_clk      <= 0;
+    pop_ptr_async         <= 0;
+    fifo_full_flag_f      <= 0;
+    pop_ptr_pop_clk       <= 0;
+    push_ptr_pop_clk      <= 0;
+    push_ptr_async        <= 0;
+    fifo_empty_flag_f     <= 1;
+    Fifo_Full_Usr         <= 4'b0001;
+    Fifo_Empty_Usr        <= 4'b0000;
+  end
+
+  assign Fifo_Full = fifo_full_flag_f;
+  assign Fifo_Empty = fifo_empty_flag_f;
+
+  assign Write_Addr = push_ptr_push_clk[MAX_PTR_WIDTH-2:0];
+  assign Read_Addr = next_pop_ptr_pop_clk[MAX_PTR_WIDTH-2:0];
+
+  assign push_ptr_push_clk_plus1 = push_ptr_push_clk + 1;
+  assign next_push_ptr_push_clk = (Fifo_Push) ? push_ptr_push_clk_plus1 : push_ptr_push_clk;
+  assign next_push_ptr_push_clk_mask = {
+    (push_ptr_push_clk_mask & next_push_ptr_push_clk[MAX_PTR_WIDTH-1:MAX_PTR_WIDTH-2]),
+    next_push_ptr_push_clk[MAX_PTR_WIDTH-3:0]
+  };
+
+  assign pop_ptr_pop_clk_plus1 = pop_ptr_pop_clk + 1;
+  assign next_pop_ptr_pop_clk = (Fifo_Pop) ? pop_ptr_pop_clk_plus1 : pop_ptr_pop_clk;
+  assign next_pop_ptr_pop_clk_mask = {
+    (pop_ptr_pop_clk_mask & next_pop_ptr_pop_clk[MAX_PTR_WIDTH-1:MAX_PTR_WIDTH-2]),
+    next_pop_ptr_pop_clk[MAX_PTR_WIDTH-3:0]
+  };
+
+  assign pop_ptr_push_clk_l_shift1 = {pop_ptr_push_clk[MAX_PTR_WIDTH-2:0], 1'b0};
+  assign pop_ptr_push_clk_l_shift2 = {pop_ptr_push_clk[MAX_PTR_WIDTH-3:0], 2'b0};
+  assign pop_ptr_push_clk_r_shift1 = {1'b0, pop_ptr_push_clk[MAX_PTR_WIDTH-1:1]};
+  assign pop_ptr_push_clk_r_shift2 = {2'b0, pop_ptr_push_clk[MAX_PTR_WIDTH-1:2]};
+
+  assign push_ptr_pop_clk_l_shift1 = {push_ptr_pop_clk[MAX_PTR_WIDTH-2:0], 1'b0};
+  assign push_ptr_pop_clk_l_shift2 = {push_ptr_pop_clk[MAX_PTR_WIDTH-3:0], 2'b0};
+  assign push_ptr_pop_clk_r_shift1 = {1'b0, push_ptr_pop_clk[MAX_PTR_WIDTH-1:1]};
+  assign push_ptr_pop_clk_r_shift2 = {2'b0, push_ptr_pop_clk[MAX_PTR_WIDTH-1:2]};
+
+  assign push_diff = next_push_ptr_push_clk_mask - pop_ptr_push_clk_mux;
+  assign push_diff_plus_1 = push_diff + 1;
+  assign pop_diff = push_ptr_pop_clk_mux - next_pop_ptr_pop_clk_mask;
+
+  assign match_room4all = ~|push_diff;
+  assign	match_room4eight	= ( depth_sel_push == 3 ) ? ( push_diff >= DEPTH3-8 ) : ( depth_sel_push == 2 ) ? ( push_diff >= DEPTH2-8 ) : ( push_diff >= DEPTH1-8 );
+
+  assign match_one_left = (pop_diff == 1);
+  assign match_one2eight_left = (pop_diff < 8);
+
+  assign push_flush_gated = Fifo_Push_Flush & ~push_local_flush_mask;
+  assign pop_flush_gated = Fifo_Pop_Flush & ~pop_local_flush_mask;
+
+  assign push_clk_rst = flush_pop2push_clk1 ^ pop_flush_tf_push_clk;
+  assign pop_clk_rst = flush_push2pop_clk1 ^ push_flush_tf_pop_clk;
+
+  assign pop_flush_done = push2pop_ack1 ^ push2pop_ack2;
+  assign push_flush_done = pop2push_ack1 ^ pop2push_ack2;
+
+  assign	push_clk_rst_mux	= ( Fifo_Sync_Mode ) ? ( Fifo_Push_Flush | Fifo_Pop_Flush ) : ( push_flush_gated | push_clk_rst );
+  assign	pop_clk_rst_mux		= ( Fifo_Sync_Mode ) ? ( Fifo_Push_Flush | Fifo_Pop_Flush ) : ( pop_flush_gated | ( pop_local_flush_mask & ~pop_flush_done ) | pop_clk_rst );
+
+
+  reg match_room_at_most63, match_at_most63_left;
+
+  always@( push_diff or push_diff_plus_1 or depth_sel_push or match_room4none or match_room4one )
+	begin
+    if (depth_sel_push == 1) begin
+      match_room4none		<= ( push_diff[D1_QTR_A+2:0] == depth1_reg[D1_QTR_A+2:0] );
+      // syao 2/12/2013
+      match_room4one		<= ( push_diff_plus_1[D1_QTR_A+2:0] == depth1_reg ) | match_room4none;
+
+      match_room4half		<= ( push_diff[D1_QTR_A+1] == 1'b1 );
+      match_room4quart	<= ( push_diff[D1_QTR_A] == 1'b1 );
+
+      match_room_at_most63    <=  push_diff[6];
+    end else if (depth_sel_push == 2) begin
+      match_room4none		<= ( push_diff[D2_QTR_A+2:0] == depth2_reg[D2_QTR_A+2:0] );
+      // syao 2/12/2013
+      match_room4one		<= ( push_diff_plus_1[D2_QTR_A+2:0] == depth2_reg ) | match_room4none;
+
+      match_room4half		<= ( push_diff[D2_QTR_A+1] == 1'b1 );
+      match_room4quart	<= ( push_diff[D2_QTR_A] == 1'b1 );
+
+      // syao 2/12/2013
+      //			match_room_at_most63    <=  push_diff[6];
+      match_room_at_most63    <=  &push_diff[7:6];
+    end else begin
+      match_room4none <= (push_diff == depth3_reg);
+      match_room4one <= (push_diff_plus_1 == depth3_reg) | match_room4none;
+
+      match_room4half <= (push_diff[D3_QTR_A+1] == 1'b1);
+      match_room4quart <= (push_diff[D3_QTR_A] == 1'b1);
+
+      // syao 2/12/2013
+      //			match_room_at_most63	<= &push_diff[7:6];
+      match_room_at_most63 <= &push_diff[8:6];
+    end
+  end
+
+
+
+  assign room4_32s = ~push_diff[5];
+  assign room4_16s = ~push_diff[4];
+  assign room4_8s  = ~push_diff[3];
+  assign room4_4s  = ~push_diff[2];
+  assign room4_2s  = ~push_diff[1];
+  assign room4_1s  = &push_diff[1:0];
+
+  always @(depth_sel_pop or pop_diff) begin
+    if (depth_sel_pop == 1) begin
+      match_all_left <= (pop_diff[D1_QTR_A+2:0] == depth1_reg[D1_QTR_A+2:0]);
+
+      match_half_left <= (pop_diff[D1_QTR_A+1] == 1'b1);
+      match_quart_left <= (pop_diff[D1_QTR_A] == 1'b1);
+
+      match_at_most63_left <= ~pop_diff[6];
+    end else if (depth_sel_pop == 2) begin
+      match_all_left <= (pop_diff[D2_QTR_A+2:0] == depth2_reg[D2_QTR_A+2:0]);
+
+      match_half_left <= (pop_diff[D2_QTR_A+1] == 1'b1);
+      match_quart_left <= (pop_diff[D2_QTR_A] == 1'b1);
+
+      // syao 2/12/2013
+      //			match_at_most63_left	<= ~pop_diff[6];			
+      match_at_most63_left <= ~|pop_diff[7:6];
+    end else begin
+      match_all_left <= (pop_diff == depth3_reg);
+
+      match_half_left <= (pop_diff[D3_QTR_A+1] == 1'b1);
+      match_quart_left <= (pop_diff[D3_QTR_A] == 1'b1);
+
+      // syao 2/12/2013
+      //			match_at_most63_left	<= ~|pop_diff[7:6];			
+      match_at_most63_left <= ~|pop_diff[8:6];
+    end
+  end
+
+
+
+  assign at_least_32 = pop_diff[5];
+  assign at_least_16 = pop_diff[4];
+  assign at_least_8 = pop_diff[3];
+  assign at_least_4 = pop_diff[2];
+  assign at_least_2 = pop_diff[1];
+  assign one_left = pop_diff[0];
+
+
+  always @(posedge Pop_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+      push2pop_ack1 <= 1'b0;
+      push2pop_ack2 <= 1'b0;
+      flush_pop_clk_tf <= 1'b0;
+      pop_local_flush_mask <= 1'b0;
+      flush_push2pop_clk1 <= 1'b0;
+      push_flush_tf_pop_clk <= 1'b0;
+    end else begin
+      push2pop_ack1 <= pop_flush_tf_push_clk;
+      push2pop_ack2 <= push2pop_ack1;
+      flush_push2pop_clk1 <= flush_push_clk_tf;
+      if (pop_flush_gated) begin
+        flush_pop_clk_tf <= ~flush_pop_clk_tf;
+      end
+
+      if (pop_flush_gated & ~Fifo_Sync_Mode) begin
+        pop_local_flush_mask <= 1'b1;
+      end else if (pop_flush_done) begin
+        pop_local_flush_mask <= 1'b0;
+      end
+
+      if (pop_clk_rst) begin
+        push_flush_tf_pop_clk <= ~push_flush_tf_pop_clk;
+      end
+    end
+  end
+
+  always @(posedge Push_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+      pop2push_ack1 <= 1'b0;
+      pop2push_ack2 <= 1'b0;
+      flush_push_clk_tf <= 1'b0;
+      push_local_flush_mask <= 1'b0;
+      flush_pop2push_clk1 <= 1'b0;
+      pop_flush_tf_push_clk <= 1'b0;
+    end else begin
+      pop2push_ack1				<= push_flush_tf_pop_clk;
+      pop2push_ack2				<= pop2push_ack1;
+      flush_pop2push_clk1	<= flush_pop_clk_tf;
+      if (push_flush_gated) begin
+        flush_push_clk_tf <= ~flush_push_clk_tf;
+      end
+
+      if (push_flush_gated & ~Fifo_Sync_Mode) begin
+        push_local_flush_mask <= 1'b1;
+      end else if (push_flush_done) begin
+        push_local_flush_mask <= 1'b0;
+      end
+
+      if (push_clk_rst) begin
+        pop_flush_tf_push_clk <= ~pop_flush_tf_push_clk;
+      end
+    end
+  end
+
+  always@( Fifo_Push_Width or Fifo_Pop_Width or pop_ptr_push_clk_l_shift1 or pop_ptr_push_clk_l_shift2 or pop_ptr_push_clk_r_shift1 or
+						pop_ptr_push_clk_r_shift2 or push_ptr_pop_clk_l_shift1 or push_ptr_pop_clk_l_shift2 or push_ptr_pop_clk_r_shift1 or push_ptr_pop_clk_r_shift2 or
+						pop_ptr_push_clk or push_ptr_pop_clk )
+	begin
+    case ({
+      Fifo_Push_Width, Fifo_Pop_Width
+    })
+      4'b0001:	//	byte push halfword pop
+      begin
+        push_ptr_push_clk_mask <= 2'b11;
+        pop_ptr_pop_clk_mask   <= 2'b01;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_l_shift1;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_r_shift1;
+      end
+      4'b0010:	//	byte push word pop
+      begin
+        push_ptr_push_clk_mask <= 2'b11;
+        pop_ptr_pop_clk_mask   <= 2'b00;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_l_shift2;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_r_shift2;
+      end
+      4'b0100:	//	halfword push byte pop
+      begin
+        push_ptr_push_clk_mask <= 2'b01;
+        pop_ptr_pop_clk_mask   <= 2'b11;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_r_shift1;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_l_shift1;
+      end
+      4'b0110:	//	halfword push word pop
+      begin
+        push_ptr_push_clk_mask <= 2'b11;
+        pop_ptr_pop_clk_mask   <= 2'b01;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_l_shift1;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_r_shift1;
+      end
+      4'b1000:	//	word push byte pop
+      begin
+        push_ptr_push_clk_mask <= 2'b00;
+        pop_ptr_pop_clk_mask   <= 2'b11;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_r_shift2;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_l_shift2;
+      end
+      4'b1001:	//	word push halfword pop
+      begin
+        push_ptr_push_clk_mask <= 2'b01;
+        pop_ptr_pop_clk_mask   <= 2'b11;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk_r_shift1;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk_l_shift1;
+      end
+      default:	//	no conversion
+      begin
+        push_ptr_push_clk_mask <= 2'b11;
+        pop_ptr_pop_clk_mask   <= 2'b11;
+        pop_ptr_push_clk_mux   <= pop_ptr_push_clk;
+        push_ptr_pop_clk_mux   <= push_ptr_pop_clk;
+      end
+    endcase
+  end
+
+  always @(Fifo_Ram_Mode or Fifo_Push_Width) begin
+    if (Fifo_Ram_Mode == Fifo_Push_Width[0]) begin
+      depth_sel_push <= 2;
+    end else if (Fifo_Ram_Mode == Fifo_Push_Width[1]) begin
+      depth_sel_push <= 1;
+    end else begin
+      depth_sel_push <= 3;
+    end
+  end
+
+  always @(Fifo_Ram_Mode or Fifo_Pop_Width) begin
+    if (Fifo_Ram_Mode == Fifo_Pop_Width[0]) begin
+      depth_sel_pop <= 2;
+    end else if (Fifo_Ram_Mode == Fifo_Pop_Width[1]) begin
+      depth_sel_pop <= 1;
+    end else begin
+      depth_sel_pop <= 3;
+    end
+  end
+
+  always @(posedge Push_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+      push_ptr_push_clk <= 0;
+      pop_ptr_push_clk <= 0;
+      pop_ptr_async <= 0;
+      fifo_full_flag_f <= 0;
+    end else begin
+      if (push_clk_rst_mux) begin
+        push_ptr_push_clk <= 0;
+        pop_ptr_push_clk <= 0;
+        pop_ptr_async <= 0;
+        fifo_full_flag_f <= 0;
+      end else begin
+        push_ptr_push_clk <= next_push_ptr_push_clk;
+        pop_ptr_push_clk <= (Fifo_Sync_Mode) ? next_pop_ptr_pop_clk : pop_ptr_async;
+        pop_ptr_async <= pop_ptr_pop_clk;
+        fifo_full_flag_f <= match_room4one | match_room4none;
+      end
+    end
+  end
+
+  always @(posedge Pop_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+      pop_ptr_pop_clk <= 0;
+      push_ptr_pop_clk <= 0;
+      push_ptr_async <= 0;
+      fifo_empty_flag_f <= 1;
+    end else begin
+      if (pop_clk_rst_mux) begin
+        pop_ptr_pop_clk <= 0;
+        push_ptr_pop_clk <= 0;
+        push_ptr_async <= 0;
+        fifo_empty_flag_f <= 1;
+      end else begin
+        pop_ptr_pop_clk <= next_pop_ptr_pop_clk;
+        push_ptr_pop_clk <= (Fifo_Sync_Mode) ? next_push_ptr_push_clk : push_ptr_async;
+        push_ptr_async <= push_ptr_push_clk;
+        fifo_empty_flag_f <= (pop_diff == 1) | (pop_diff == 0);
+      end
+    end
+  end
+
+  always @(posedge Push_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+
+      //based on rtl, this should be full after reset		
+      //			Fifo_Full_Usr	<= 4'b1000;
+      Fifo_Full_Usr <= 4'b0001;
+    end else begin
+      if (match_room4none) begin
+        Fifo_Full_Usr <= 4'b0000;
+      end else if (match_room4all) begin
+        Fifo_Full_Usr <= 4'b0001;
+      end else if (~match_room4half) begin
+        Fifo_Full_Usr <= 4'b0010;
+      end else if (~match_room4quart) begin
+        Fifo_Full_Usr <= 4'b0011;
+      end else begin
+        if (match_room_at_most63) begin
+          if (room4_32s) Fifo_Full_Usr <= 4'b1010;
+          else if (room4_16s) Fifo_Full_Usr <= 4'b1011;
+          else if (room4_8s) Fifo_Full_Usr <= 4'b1100;
+          else if (room4_4s) Fifo_Full_Usr <= 4'b1101;
+          else if (room4_2s) Fifo_Full_Usr <= 4'b1110;
+          else if (room4_1s) Fifo_Full_Usr <= 4'b1111;
+          else Fifo_Full_Usr <= 4'b1110;
+        end else Fifo_Full_Usr <= 4'b0100;
+      end
+    end
+  end
+
+  always @(posedge Pop_Clk or negedge Rst_n) begin
+    if (~Rst_n) begin
+      Fifo_Empty_Usr <= 4'b0000;
+    end else begin
+      if (Fifo_Pop_Flush | (pop_local_flush_mask & ~pop_flush_done) | pop_clk_rst) begin
+        Fifo_Empty_Usr <= 4'b0000;
+      end else if (match_all_left) begin
+        Fifo_Empty_Usr <= 4'b1111;
+      end else if (match_half_left) begin
+        Fifo_Empty_Usr <= 4'b1110;
+      end else if (match_quart_left) begin
+        Fifo_Empty_Usr <= 4'b1101;
+      end else begin
+        if (match_at_most63_left) begin
+          if (at_least_32) Fifo_Empty_Usr <= 4'b0110;
+          else if (at_least_16) Fifo_Empty_Usr <= 4'b0101;
+          else if (at_least_8) Fifo_Empty_Usr <= 4'b0100;
+          else if (at_least_4) Fifo_Empty_Usr <= 4'b0011;
+          else if (at_least_2) Fifo_Empty_Usr <= 4'b0010;
+          else if (one_left) Fifo_Empty_Usr <= 4'b0001;
+          else Fifo_Empty_Usr <= 4'b0000;
+        end else Fifo_Empty_Usr <= 4'b1000;
+      end
+    end
+  end
+endmodule
+
+`timescale 10 ps / 1 ps
+
+//`define ADDRWID 8
+`define DATAWID 18 
+`define WEWID 2
+//`define DEPTH 256
+
+module ram (
+    AA,
+    AB,
+    CLKA,
+    CLKB,
+    WENA,
+    WENB,
+    CENA,
+    CENB,
+    WENBA,
+    WENBB,
+    DA,
+    QA,
+    DB,
+    QB
+);
+
+
+  parameter ADDRWID = 8;
+  parameter DEPTH = (1 << ADDRWID);
+
+  parameter [9215:0] INIT = 9216'bx;
+  parameter INIT_FILE = "init.mem";
+  parameter init_ad = 0;
+
+  parameter data_width_int = 16;
+  parameter data_depth_int = 1024;
+
+  output [`DATAWID-1:0] QA;
+  input CLKA;
+  input CENA;
+  input WENA;
+  input [`WEWID-1:0] WENBA;
+  input [ADDRWID-1:0] AA;
+  input [`DATAWID-1:0] DA;
+  output [`DATAWID-1:0] QB;
+
+  input CLKB;
+  input CENB;
+  input WENB;
+  input [`WEWID-1:0] WENBB;
+  input [ADDRWID-1:0] AB;
+  input [`DATAWID-1:0] DB;
+
+  integer i, j, k, l, m, n, o;
+
+  wire                CEN1;
+  wire                OEN1;
+  wire                WEN1;
+  wire [  `WEWID-1:0] WENB1;
+  wire [ ADDRWID-1:0] A1;
+
+  reg  [ ADDRWID-1:0] AddrOut1;
+  wire [`DATAWID-1:0] I1;
+
+  wire                CEN2;
+  wire                OEN2;
+  wire                WEN2;
+  wire [  `WEWID-1:0] WENB2;
+  wire [ ADDRWID-1:0] A2;
+
+  reg  [ ADDRWID-1:0] AddrOut2;
+  wire [`DATAWID-1:0] I2;
+
+  reg [`DATAWID-1:0] O1, QAreg;
+  reg [`DATAWID-1:0] O2, QBreg;
+
+  reg                 WEN1_f;
+  reg                 WEN2_f;
+  reg  [ ADDRWID-1:0] A2_f;
+  reg  [ ADDRWID-1:0] A1_f;
+
+  wire                CEN1_SEL;
+  wire                WEN1_SEL;
+  wire [ ADDRWID-1:0] A1_SEL;
+  wire [`DATAWID-1:0] I1_SEL;
+  wire [  `WEWID-1:0] WENB1_SEL;
+
+  wire                CEN2_SEL;
+  wire                WEN2_SEL;
+  wire [ ADDRWID-1:0] A2_SEL;
+  wire [`DATAWID-1:0] I2_SEL;
+  wire [  `WEWID-1:0] WENB2_SEL;
+  wire                overlap;
+
+  wire CLKA_d, CLKB_d, CEN1_d, CEN2_d;
+
+  assign	A1_SEL    = AA;
+  assign	I1_SEL    = DA;
+  assign	CEN1_SEL  = CENA;
+  assign	WEN1_SEL  = WENA;
+  assign	WENB1_SEL = WENBA;
+
+  assign	A2_SEL    = AB;
+  assign	I2_SEL    = DB;
+  assign	CEN2_SEL  = CENB;
+  assign	WEN2_SEL  = WENB;
+  assign	WENB2_SEL = WENBB;
+
+  assign	CEN1	= CEN1_SEL;
+  assign	OEN1	= 1'b0;
+  assign	WEN1	= WEN1_SEL;
+  assign	WENB1	= WENB1_SEL;
+  assign	A1		= A1_SEL;
+  assign	I1		= I1_SEL;
+
+  assign	CEN2	= CEN2_SEL;
+  assign	OEN2	= 1'b0;
+  assign	WEN2	= WEN2_SEL;
+  assign	WENB2	= WENB2_SEL;
+  assign	A2		= A2_SEL;
+  assign	I2		= I2_SEL;
+
+  //assign	QA	= O1;
+  //assign	QB	= O2;
+
+  reg [`DATAWID-1:0] ram[DEPTH-1:0];
+  reg [data_width_int-1 : 0] ram_dum[data_depth_int-1:0];
+  reg [`DATAWID-1:0] wrData1;
+  reg [`DATAWID-1:0] wrData2;
+  wire [`DATAWID-1:0] tmpData1;
+  wire [`DATAWID-1:0] tmpData2;
+
+  reg CENreg1, CENreg2;
+
+  assign #1 CLKA_d = CLKA;
+  assign #1 CLKB_d = CLKB;
+  // updated by sya 20130523
+  assign #2 CEN1_d = CEN1;
+  assign #2 CEN2_d = CEN2;
+
+  assign QA = QAreg | O1;
+  assign QB = QBreg | O2;
+
+  assign tmpData1 = ram[A1];
+  assign tmpData2 = ram[A2];
+
+  assign overlap = (A1_f == A2_f) & WEN1_f & WEN2_f;
+
+  initial begin
+`ifndef YOSYS
+    $readmemh(INIT_FILE, ram_dum);
+`endif
+    #10 n = 0;
+    o = 0;
+    for (i = 0; i < DEPTH; i = i + 1) begin
+      if (data_width_int > 16)
+        ram[i] <= {
+          1'b0,
+          ram_dum[i][((16*init_ad)+16)-1:((16*init_ad)+8)],
+          1'b0,
+          ram_dum[i][((16*init_ad)+8)-1:(16*init_ad)]
+        };
+      else if (data_width_int <= 8 && data_depth_int <= 1024)
+        ram[i] <= {
+          1'b0, ram_dum[i+n+1+(1024*init_ad)][7:0], 1'b0, ram_dum[i+n+(1024*init_ad)][7:0]
+        };
+      else if (data_width_int <= 8 && data_depth_int > 1024)
+        ram[i] <= {1'b0, ram_dum[i+o+init_ad+1][7:0], 1'b0, ram_dum[i+o+init_ad][7:0]};
+      else if (data_width_int > 8 && data_width_int <= 16 && data_depth_int > 512)
+        ram[i] <= {1'b0, ram_dum[i+n+init_ad][15:8], 1'b0, ram_dum[i+n+init_ad][7:0]};
+      else ram[i] <= {1'b0, ram_dum[i+(512*init_ad)][15:8], 1'b0, ram_dum[i+(512*init_ad)][7:0]};
+
+      n = n + 1;
+      o = o + 3;
+    end
+  end
+
+  always @(WENB1 or I1 or tmpData1) begin
+    for (j = 0; j < 9; j = j + 1) begin
+      wrData1[j] <= (WENB1[0]) ? tmpData1[j] : I1[j];
+    end
+    for (l = 9; l < 19; l = l + 1) begin
+      wrData1[l] <= (WENB1[1]) ? tmpData1[l] : I1[l];
+    end
+  end
+
+  always @(posedge CLKA) begin
+    if (~WEN1 & ~CEN1) begin
+      ram[A1] <= wrData1[`DATAWID-1:0];
+    end
+  end
+
+  //pre-charging to 1 every clock cycle
+  always @(posedge CLKA_d)
+    if (~CEN1_d) begin
+      O1 = 18'h3ffff;
+      #100;
+      O1 = 18'h00000;
+    end
+
+
+  always @(posedge CLKA)
+    if (~CEN1) begin
+      AddrOut1 <= A1;
+    end
+
+  always @(posedge CLKA_d)
+    if (~CEN1_d) begin
+      QAreg <= ram[AddrOut1];
+    end
+
+
+  always @(posedge CLKA) begin
+    WEN1_f <= ~WEN1 & ~CEN1;
+    A1_f   <= A1;
+
+  end
+
+  always @(WENB2 or I2 or tmpData2) begin
+    for (k = 0; k < 9; k = k + 1) begin
+      wrData2[k] <= (WENB2[0]) ? tmpData2[k] : I2[k];
+    end
+    for (m = 9; m < 19; m = m + 1) begin
+      wrData2[m] <= (WENB2[1]) ? tmpData2[m] : I2[m];
+    end
+  end
+
+  always @(posedge CLKB) begin
+    if (~WEN2 & ~CEN2) begin
+      ram[A2] <= wrData2[`DATAWID-1:0];
+    end
+  end
+
+  //pre-charging to 1 every clock cycle
+  always @(posedge CLKB_d)
+    if (~CEN2_d) begin
+      O2 = 18'h3ffff;
+      #100;
+      O2 = 18'h00000;
+    end
+
+  always @(posedge CLKB)
+    if (~CEN2) begin
+      AddrOut2 <= A2;
+    end
+
+  always @(posedge CLKB_d)
+    if (~CEN2_d) begin
+      QBreg <= ram[AddrOut2];
+    end
+
+  always @(posedge CLKB) begin
+    WEN2_f <= ~WEN2 & ~CEN2;
+    A2_f   <= A2;
+
+  end
+
+  always @(A1_f or A2_f or overlap) begin
+    if (overlap) begin
+      ram[A1_f] <= 18'bxxxxxxxxxxxxxxxxxx;
+    end
+  end
+
+endmodule
+
+`timescale 1 ns / 10 ps
+//`define ADDRWID 10
+`define DATAWID 18
+`define WEWID 2
+
+module x2_model (
+    Concat_En,
+
+    ram0_WIDTH_SELA,
+    ram0_WIDTH_SELB,
+    ram0_PLRD,
+
+    ram0_CEA,
+    ram0_CEB,
+    ram0_I,
+    ram0_O,
+    ram0_AA,
+    ram0_AB,
+    ram0_CSBA,
+    ram0_CSBB,
+    ram0_WENBA,
+
+    ram1_WIDTH_SELA,
+    ram1_WIDTH_SELB,
+    ram1_PLRD,
+
+    ram1_CEA,
+    ram1_CEB,
+    ram1_I,
+    ram1_O,
+    ram1_AA,
+    ram1_AB,
+    ram1_CSBA,
+    ram1_CSBB,
+    ram1_WENBA
+);
+
+  parameter ADDRWID = 10;
+  parameter [18431:0] INIT = 18432'bx;
+  parameter INIT_FILE = "init.mem";
+  parameter data_width_int = 16;
+  parameter data_depth_int = 1024;
+  parameter init_ad1 = 0;
+  parameter init_ad2 = (data_depth_int > 1024) ? 2 : 1;
+
+
+  input Concat_En;
+
+  input [1:0] ram0_WIDTH_SELA;
+  input [1:0] ram0_WIDTH_SELB;
+  input ram0_PLRD;
+  input ram0_CEA;
+  input ram0_CEB;
+  input [`DATAWID-1:0] ram0_I;
+  output [`DATAWID-1:0] ram0_O;
+  input [ADDRWID-1:0] ram0_AA;
+  input [ADDRWID-1:0] ram0_AB;
+  input ram0_CSBA;
+  input ram0_CSBB;
+  input [`WEWID-1:0] ram0_WENBA;
+
+  input [1:0] ram1_WIDTH_SELA;
+  input [1:0] ram1_WIDTH_SELB;
+  input ram1_PLRD;
+  input ram1_CEA;
+  input ram1_CEB;
+  input [`DATAWID-1:0] ram1_I;
+  output [`DATAWID-1:0] ram1_O;
+  input [ADDRWID-1:0] ram1_AA;
+  input [ADDRWID-1:0] ram1_AB;
+  input ram1_CSBA;
+  input ram1_CSBB;
+  input [`WEWID-1:0] ram1_WENBA;
+
+  reg                 ram0_PLRDA_SEL;
+  reg                 ram0_PLRDB_SEL;
+  reg                 ram1_PLRDA_SEL;
+  reg                 ram1_PLRDB_SEL;
+  reg                 ram_AA_ram_SEL;
+  reg                 ram_AB_ram_SEL;
+
+  reg  [  `WEWID-1:0] ram0_WENBA_SEL;
+  reg  [  `WEWID-1:0] ram0_WENBB_SEL;
+  reg  [  `WEWID-1:0] ram1_WENBA_SEL;
+  reg  [  `WEWID-1:0] ram1_WENBB_SEL;
+
+  reg                 ram0_A_x9_SEL;
+  reg                 ram0_B_x9_SEL;
+  reg                 ram1_A_x9_SEL;
+  reg                 ram1_B_x9_SEL;
+
+  reg  [ ADDRWID-3:0] ram0_AA_SEL;
+  reg  [ ADDRWID-3:0] ram0_AB_SEL;
+  reg  [ ADDRWID-3:0] ram1_AA_SEL;
+  reg  [ ADDRWID-3:0] ram1_AB_SEL;
+
+  reg                 ram0_AA_byte_SEL;
+  reg                 ram0_AB_byte_SEL;
+  reg                 ram1_AA_byte_SEL;
+  reg                 ram1_AB_byte_SEL;
+
+  reg                 ram0_AA_byte_SEL_Q;
+  reg                 ram0_AB_byte_SEL_Q;
+  reg                 ram1_AA_byte_SEL_Q;
+  reg                 ram1_AB_byte_SEL_Q;
+  reg                 ram0_A_mux_ctl_Q;
+  reg                 ram0_B_mux_ctl_Q;
+  reg                 ram1_A_mux_ctl_Q;
+  reg                 ram1_B_mux_ctl_Q;
+
+  reg                 ram0_O_mux_ctrl_Q;
+  reg                 ram1_O_mux_ctrl_Q;
+
+  reg                 ram_AA_ram_SEL_Q;
+  reg                 ram_AB_ram_SEL_Q;
+
+  wire [`DATAWID-1:0] QA_1_SEL3;
+  wire [`DATAWID-1:0] QB_0_SEL2;
+  wire [`DATAWID-1:0] QB_1_SEL2;
+
+  reg  [`DATAWID-1:0] QA_0_Q;
+  reg  [`DATAWID-1:0] QB_0_Q;
+  reg  [`DATAWID-1:0] QA_1_Q;
+  reg  [`DATAWID-1:0] QB_1_Q;
+
+  wire [`DATAWID-1:0] QA_0;
+  wire [`DATAWID-1:0] QB_0;
+  wire [`DATAWID-1:0] QA_1;
+  wire [`DATAWID-1:0] QB_1;
+
+  wire                ram0_CSBA_SEL;
+  wire                ram0_CSBB_SEL;
+  wire                ram1_CSBA_SEL;
+  wire                ram1_CSBB_SEL;
+
+  wire [`DATAWID-1:0] ram0_I_SEL1;
+  wire [`DATAWID-1:0] ram1_I_SEL1;
+
+  wire                dual_port;
+
+  wire                ram0_WEBA_SEL;
+  wire                ram0_WEBB_SEL;
+  wire                ram1_WEBA_SEL;
+  wire                ram1_WEBB_SEL;
+
+  wire [`DATAWID-1:0] ram1_I_SEL2;
+
+  wire [`DATAWID-1:0] QA_1_SEL2;
+  wire [`DATAWID-1:0] QA_0_SEL1;
+  wire [`DATAWID-1:0] QB_0_SEL1;
+  wire [`DATAWID-1:0] QA_1_SEL1;
+  wire [`DATAWID-1:0] QB_1_SEL1;
+
+  wire [`DATAWID-1:0] QB_0_SEL3;
+  wire [`DATAWID-1:0] QA_0_SEL2;
+
+  initial begin
+    QA_0_Q             <= 0;
+    QB_0_Q             <= 0;
+    QA_1_Q             <= 0;
+    QB_1_Q             <= 0;
+    ram0_AA_byte_SEL_Q <= 0;
+    ram0_A_mux_ctl_Q   <= 0;
+    ram0_AB_byte_SEL_Q <= 0;
+    ram0_B_mux_ctl_Q   <= 0;
+    ram1_AA_byte_SEL_Q <= 0;
+    ram1_A_mux_ctl_Q   <= 0;
+    ram1_AB_byte_SEL_Q <= 0;
+    ram1_B_mux_ctl_Q   <= 0;
+    ram_AA_ram_SEL_Q   <= 0;
+    ram1_O_mux_ctrl_Q  <= 0;
+    ram_AB_ram_SEL_Q   <= 0;
+    ram0_O_mux_ctrl_Q  <= 0;
+  end
+
+  assign dual_port = Concat_En & ~(ram0_WIDTH_SELA[1] | ram0_WIDTH_SELB[1]);
+
+  assign ram0_CSBA_SEL = ram0_CSBA;
+  assign ram0_CSBB_SEL = ram0_CSBB;
+  assign ram1_CSBA_SEL = Concat_En ? ram0_CSBA : ram1_CSBA;
+  assign ram1_CSBB_SEL = Concat_En ? ram0_CSBB : ram1_CSBB;
+
+  assign ram0_O = QB_0_SEL3;
+  assign ram1_O = dual_port ? QA_1_SEL3 : QB_1_SEL2;
+
+  assign ram0_I_SEL1[8:0] = ram0_I[8:0];
+  assign ram1_I_SEL1[8:0] = ram1_I[8:0];
+  assign ram0_I_SEL1[17:9] = ram0_AA_byte_SEL ? ram0_I[8:0] : ram0_I[17:9];
+  assign ram1_I_SEL1[17:9]	= ( ( ~Concat_En & ram1_AA_byte_SEL ) | ( dual_port & ram0_AB_byte_SEL ) ) ? ram1_I[8:0] : ram1_I[17:9];
+
+  assign ram1_I_SEL2 = (Concat_En & ~ram0_WIDTH_SELA[1]) ? ram0_I_SEL1 : ram1_I_SEL1;
+
+  assign ram0_WEBA_SEL = &ram0_WENBA_SEL;
+  assign ram0_WEBB_SEL = &ram0_WENBB_SEL;
+  assign ram1_WEBA_SEL = &ram1_WENBA_SEL;
+  assign ram1_WEBB_SEL = &ram1_WENBB_SEL;
+
+  assign QA_0_SEL1 = (ram0_PLRDA_SEL) ? QA_0_Q : QA_0;
+  assign QB_0_SEL1 = (ram0_PLRDB_SEL) ? QB_0_Q : QB_0;
+  assign QA_1_SEL1 = (ram1_PLRDA_SEL) ? QA_1_Q : QA_1;
+  assign QB_1_SEL1 = (ram1_PLRDB_SEL) ? QB_1_Q : QB_1;
+
+  assign QA_1_SEL3 = ram1_O_mux_ctrl_Q ? QA_1_SEL2 : QA_0_SEL2;
+
+  assign QA_0_SEL2[8:0] = ram0_A_mux_ctl_Q ? QA_0_SEL1[17:9] : QA_0_SEL1[8:0];
+  assign QB_0_SEL2[8:0] = ram0_B_mux_ctl_Q ? QB_0_SEL1[17:9] : QB_0_SEL1[8:0];
+  assign QA_1_SEL2[8:0] = ram1_A_mux_ctl_Q ? QA_1_SEL1[17:9] : QA_1_SEL1[8:0];
+  assign QB_1_SEL2[8:0] = ram1_B_mux_ctl_Q ? QB_1_SEL1[17:9] : QB_1_SEL1[8:0];
+
+  assign QA_0_SEL2[17:9] = QA_0_SEL1[17:9];
+  assign QB_0_SEL2[17:9] = QB_0_SEL1[17:9];
+  assign QA_1_SEL2[17:9] = QA_1_SEL1[17:9];
+  assign QB_1_SEL2[17:9] = QB_1_SEL1[17:9];
+
+  assign QB_0_SEL3 = ram0_O_mux_ctrl_Q ? QB_1_SEL2 : QB_0_SEL2;
+
+  always @(posedge ram0_CEA) begin
+    QA_0_Q <= QA_0;
+  end
+  always @(posedge ram0_CEB) begin
+    QB_0_Q <= QB_0;
+  end
+  always @(posedge ram1_CEA) begin
+    QA_1_Q <= QA_1;
+  end
+  always @(posedge ram1_CEB) begin
+    QB_1_Q <= QB_1;
+  end
+
+  always @(posedge ram0_CEA) begin
+    if (ram0_CSBA_SEL == 0) ram0_AA_byte_SEL_Q <= ram0_AA_byte_SEL;
+    if (ram0_PLRDA_SEL || (ram0_CSBA_SEL == 0))
+      ram0_A_mux_ctl_Q <= ram0_A_x9_SEL & (ram0_PLRDA_SEL ? ram0_AA_byte_SEL_Q : ram0_AA_byte_SEL);
+  end
+
+  always @(posedge ram0_CEB) begin
+    if (ram0_CSBB_SEL == 0) ram0_AB_byte_SEL_Q <= ram0_AB_byte_SEL;
+    if (ram0_PLRDB_SEL || (ram0_CSBB_SEL == 0))
+      ram0_B_mux_ctl_Q <= ram0_B_x9_SEL & (ram0_PLRDB_SEL ? ram0_AB_byte_SEL_Q : ram0_AB_byte_SEL);
+  end
+
+  always @(posedge ram1_CEA) begin
+    if (ram1_CSBA_SEL == 0) ram1_AA_byte_SEL_Q <= ram1_AA_byte_SEL;
+    if (ram1_PLRDA_SEL || (ram1_CSBA_SEL == 0))
+      ram1_A_mux_ctl_Q <= ram1_A_x9_SEL & (ram1_PLRDA_SEL ? ram1_AA_byte_SEL_Q : ram1_AA_byte_SEL);
+  end
+
+  always @(posedge ram1_CEB) begin
+    if (ram1_CSBB_SEL == 0) ram1_AB_byte_SEL_Q <= ram1_AB_byte_SEL;
+    if (ram1_PLRDB_SEL || (ram1_CSBB_SEL == 0))
+      ram1_B_mux_ctl_Q <= ram1_B_x9_SEL & (ram1_PLRDB_SEL ? ram1_AB_byte_SEL_Q : ram1_AB_byte_SEL);
+  end
+
+  always @(posedge ram0_CEA) begin
+    ram_AA_ram_SEL_Q  <= ram_AA_ram_SEL;
+    ram1_O_mux_ctrl_Q <= (ram0_PLRDA_SEL ? ram_AA_ram_SEL_Q : ram_AA_ram_SEL);
+  end
+
+  always @(posedge ram0_CEB) begin
+    ram_AB_ram_SEL_Q  <= ram_AB_ram_SEL;
+    ram0_O_mux_ctrl_Q <= (ram0_PLRDB_SEL ? ram_AB_ram_SEL_Q : ram_AB_ram_SEL);
+  end
+
+  always@( Concat_En or ram0_WIDTH_SELA or ram0_WIDTH_SELB or ram0_AA or ram0_AB or ram0_WENBA or 
+	         ram1_AA or ram1_AB or ram1_WENBA or ram0_PLRD or ram1_PLRD or ram1_WIDTH_SELA or ram1_WIDTH_SELB ) 
+	begin
+    ram0_A_x9_SEL <= (~|ram0_WIDTH_SELA);
+    ram1_A_x9_SEL <= (~|ram0_WIDTH_SELA);
+    ram0_B_x9_SEL <= (~|ram0_WIDTH_SELB);
+    ram0_AA_byte_SEL <= ram0_AA[0] & (~|ram0_WIDTH_SELA);
+    ram0_AB_byte_SEL <= ram0_AB[0] & (~|ram0_WIDTH_SELB);
+    if (~Concat_En) begin
+      ram_AA_ram_SEL	<= 1'b0;
+      ram_AB_ram_SEL	<= 1'b0;
+      ram1_B_x9_SEL		<= ( ~|ram1_WIDTH_SELB );
+
+      ram0_PLRDA_SEL	<= ram0_PLRD;
+      ram0_PLRDB_SEL	<= ram0_PLRD;
+      ram1_PLRDA_SEL	<= ram1_PLRD;
+      ram1_PLRDB_SEL	<= ram1_PLRD;
+      ram0_WENBB_SEL	<= {`WEWID{1'b1}};
+      ram1_WENBB_SEL	<= {`WEWID{1'b1}};
+
+      ram0_AA_SEL				<= ram0_AA >> ( ~|ram0_WIDTH_SELA );
+      ram0_WENBA_SEL[0]	<= ( ram0_AA[0] & ( ~|ram0_WIDTH_SELA ) ) | ram0_WENBA[0];
+      ram0_WENBA_SEL[1]	<= ( ~ram0_AA[0] & ( ~|ram0_WIDTH_SELA ) ) | ram0_WENBA[( |ram0_WIDTH_SELA )];
+      ram0_AB_SEL				<= ram0_AB >> ( ~|ram0_WIDTH_SELB );
+
+      ram1_AA_SEL				<= ram1_AA >> ( ~|ram1_WIDTH_SELA );
+      ram1_AA_byte_SEL	<= ram1_AA[0] & ( ~|ram1_WIDTH_SELA );
+      ram1_WENBA_SEL[0]	<= ( ram1_AA[0] & ( ~|ram1_WIDTH_SELA ) ) | ram1_WENBA[0];
+      ram1_WENBA_SEL[1]	<= ( ~ram1_AA[0] & ( ~|ram1_WIDTH_SELA ) ) | ram1_WENBA[( |ram1_WIDTH_SELA )];
+      ram1_AB_SEL				<= ram1_AB >> ( ~|ram1_WIDTH_SELB );
+      ram1_AB_byte_SEL	<= ram1_AB[0] & ( ~|ram1_WIDTH_SELB );
+    end else begin
+      ram_AA_ram_SEL <= ~ram0_WIDTH_SELA[1] & ram0_AA[~ram0_WIDTH_SELA[0]];
+      ram_AB_ram_SEL <= ~ram0_WIDTH_SELB[1] & ram0_AB[~ram0_WIDTH_SELB[0]];
+      ram1_B_x9_SEL <= (~|ram0_WIDTH_SELB);
+
+      ram0_PLRDA_SEL <= ram1_PLRD;
+      ram1_PLRDA_SEL <= ram1_PLRD;
+      ram0_PLRDB_SEL <= ram0_PLRD;
+      ram1_PLRDB_SEL <= ram0_PLRD;
+
+      ram0_AA_SEL <= ram0_AA >> {
+        ~ram0_WIDTH_SELA[1] & ~(ram0_WIDTH_SELA[1] ^ ram0_WIDTH_SELA[0]),
+        ~ram0_WIDTH_SELA[1] & ram0_WIDTH_SELA[0]
+      };
+      ram1_AA_SEL <= ram0_AA >> {
+        ~ram0_WIDTH_SELA[1] & ~(ram0_WIDTH_SELA[1] ^ ram0_WIDTH_SELA[0]),
+        ~ram0_WIDTH_SELA[1] & ram0_WIDTH_SELA[0]
+      };
+      ram1_AA_byte_SEL <= ram0_AA[0] & (~|ram0_WIDTH_SELA);
+      ram0_WENBA_SEL[0]	<= ram0_WENBA[0] | ( ~ram0_WIDTH_SELA[1] & ( ram0_AA[0] | ( ~ram0_WIDTH_SELA[0] & ram0_AA[1] ) ) );
+      ram0_WENBA_SEL[1]	<= ( ( ~|ram0_WIDTH_SELA & ram0_WENBA[0] ) | ( |ram0_WIDTH_SELA & ram0_WENBA[1] ) ) | ( ~ram0_WIDTH_SELA[1] & ( ( ram0_WIDTH_SELA[0] & ram0_AA[0] ) | ( ~ram0_WIDTH_SELA[0] & ~ram0_AA[0] ) | ( ~ram0_WIDTH_SELA[0] & ram0_AA[1] ) ) );
+
+      ram1_WENBA_SEL[0]	<= ( ( ~ram0_WIDTH_SELA[1] & ram0_WENBA[0] ) | ( ram0_WIDTH_SELA[1] & ram1_WENBA[0] ) ) | ( ~ram0_WIDTH_SELA[1] & ( ( ram0_WIDTH_SELA[0] & ~ram0_AA[0] ) | ( ~ram0_WIDTH_SELA[0] & ram0_AA[0] ) | ( ~ram0_WIDTH_SELA[0] & ~ram0_AA[1] ) ) );
+      ram1_WENBA_SEL[1]	<= ( ( ( ram0_WIDTH_SELA == 2'b00 ) & ram0_WENBA[0] ) | ( ( ram0_WIDTH_SELA[1] == 1'b1 ) & ram1_WENBA[1] ) | ( ( ram0_WIDTH_SELA == 2'b01 ) & ram0_WENBA[1] ) ) | ( ~ram0_WIDTH_SELA[1] & ( ~ram0_AA[0] | ( ~ram0_WIDTH_SELA[0] & ~ram0_AA[1] ) ) );
+
+      ram0_AB_SEL <= ram0_AB >> {
+        ~ram0_WIDTH_SELB[1] & ~(ram0_WIDTH_SELB[1] ^ ram0_WIDTH_SELB[0]),
+        ~ram0_WIDTH_SELB[1] & ram0_WIDTH_SELB[0]
+      };
+      ram1_AB_SEL <= ram0_AB >> {
+        ~ram0_WIDTH_SELB[1] & ~(ram0_WIDTH_SELB[1] ^ ram0_WIDTH_SELB[0]),
+        ~ram0_WIDTH_SELB[1] & ram0_WIDTH_SELB[0]
+      };
+      ram1_AB_byte_SEL <= ram0_AB[0] & (~|ram0_WIDTH_SELB);
+      ram0_WENBB_SEL[0]	<= ram0_WIDTH_SELB[1] | ( ram0_WIDTH_SELA[1] | ram1_WENBA[0] | ( ram0_AB[0] | ( ~ram0_WIDTH_SELB[0] & ram0_AB[1] ) ) );
+      ram0_WENBB_SEL[1]	<= ram0_WIDTH_SELB[1] | ( ram0_WIDTH_SELA[1] | ( ( ~|ram0_WIDTH_SELB & ram1_WENBA[0] ) | ( |ram0_WIDTH_SELB & ram1_WENBA[1] ) ) | ( ( ram0_WIDTH_SELB[0] & ram0_AB[0] ) | ( ~ram0_WIDTH_SELB[0] & ~ram0_AB[0] ) | ( ~ram0_WIDTH_SELB[0] & ram0_AB[1] ) ) );
+      ram1_WENBB_SEL[0]	<= ram0_WIDTH_SELB[1] | ( ram0_WIDTH_SELA[1] | ram1_WENBA[0] | ( ( ram0_WIDTH_SELB[0] & ~ram0_AB[0] ) | ( ~ram0_WIDTH_SELB[0] & ram0_AB[0] ) | ( ~ram0_WIDTH_SELB[0] & ~ram0_AB[1] ) ) );
+      ram1_WENBB_SEL[1]	<= ram0_WIDTH_SELB[1] | ( ram0_WIDTH_SELA[1] | ( ( ~|ram0_WIDTH_SELB & ram1_WENBA[0] ) | ( |ram0_WIDTH_SELB & ram1_WENBA[1] ) ) | ( ~ram0_AB[0] | ( ~ram0_WIDTH_SELB[0] & ~ram0_AB[1] ) ) );
+    end
+  end
+
+  ram #(
+      .ADDRWID(ADDRWID - 2),
+      .INIT(INIT[0*9216+:9216]),
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int),
+      .init_ad(init_ad1)
+  ) ram0_inst (
+      .AA(ram0_AA_SEL),
+      .AB(ram0_AB_SEL),
+      .CLKA(ram0_CEA),
+      .CLKB(ram0_CEB),
+      .WENA(ram0_WEBA_SEL),
+      .WENB(ram0_WEBB_SEL),
+      .CENA(ram0_CSBA_SEL),
+      .CENB(ram0_CSBB_SEL),
+      .WENBA(ram0_WENBA_SEL),
+      .WENBB(ram0_WENBB_SEL),
+      .DA(ram0_I_SEL1),
+      .QA(QA_0),
+      .DB(ram1_I_SEL1),
+      .QB(QB_0)
+  );
+
+  ram #(
+      .ADDRWID(ADDRWID - 2),
+      .INIT(INIT[1*9216+:9216]),
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int),
+      .init_ad(init_ad2)
+  ) ram1_inst (
+      .AA(ram1_AA_SEL),
+      .AB(ram1_AB_SEL),
+      .CLKA(ram1_CEA),
+      .CLKB(ram1_CEB),
+      .WENA(ram1_WEBA_SEL),
+      .WENB(ram1_WEBB_SEL),
+      .CENA(ram1_CSBA_SEL),
+      .CENB(ram1_CSBB_SEL),
+      .WENBA(ram1_WENBA_SEL),
+      .WENBB(ram1_WENBB_SEL),
+      .DA(ram1_I_SEL2),
+      .QA(QA_1),
+      .DB(ram1_I_SEL1),
+      .QB(QB_1)
+  );
+
+endmodule
+
+`timescale 1 ns / 10 ps
+`define ADDRWID 11
+`define DATAWID 18
+`define WEWID 2
+
+module ram_block_8K (
+    CLK1_0,
+    CLK2_0,
+    WD_0,
+    RD_0,
+    A1_0,
+    A2_0,
+    CS1_0,
+    CS2_0,
+    WEN1_0,
+    POP_0,
+    Almost_Full_0,
+    Almost_Empty_0,
+    PUSH_FLAG_0,
+    POP_FLAG_0,
+
+    FIFO_EN_0,
+    SYNC_FIFO_0,
+    PIPELINE_RD_0,
+    WIDTH_SELECT1_0,
+    WIDTH_SELECT2_0,
+
+    CLK1_1,
+    CLK2_1,
+    WD_1,
+    RD_1,
+    A1_1,
+    A2_1,
+    CS1_1,
+    CS2_1,
+    WEN1_1,
+    POP_1,
+    Almost_Empty_1,
+    Almost_Full_1,
+    PUSH_FLAG_1,
+    POP_FLAG_1,
+
+    FIFO_EN_1,
+    SYNC_FIFO_1,
+    PIPELINE_RD_1,
+    WIDTH_SELECT1_1,
+    WIDTH_SELECT2_1,
+
+    CONCAT_EN_0,
+    CONCAT_EN_1,
+
+    PUSH_0,
+    PUSH_1,
+    aFlushN_0,
+    aFlushN_1
+);
+
+  parameter [18431:0] INIT = 18432'bx;
+  parameter INIT_FILE = "init.mem";
+  parameter data_width_int = 16;
+  parameter data_depth_int = 1024;
+
+  input CLK1_0;
+  input CLK2_0;
+  input [`DATAWID-1:0] WD_0;
+  output [`DATAWID-1:0] RD_0;
+  input [`ADDRWID-1:0] A1_0;  //chnge
+  input [`ADDRWID-1:0] A2_0;  //chnge
+  input CS1_0;
+  input CS2_0;
+  input [`WEWID-1:0] WEN1_0;
+  input POP_0;
+  output Almost_Full_0;
+  output Almost_Empty_0;
+  output [3:0] PUSH_FLAG_0;
+  output [3:0] POP_FLAG_0;
+  input FIFO_EN_0;
+  input SYNC_FIFO_0;
+  input PIPELINE_RD_0;
+  input [1:0] WIDTH_SELECT1_0;
+  input [1:0] WIDTH_SELECT2_0;
+
+  input CLK1_1;
+  input CLK2_1;
+  input [`DATAWID-1:0] WD_1;
+  output [`DATAWID-1:0] RD_1;
+  input [`ADDRWID-1:0] A1_1;  //chnge
+  input [`ADDRWID-1:0] A2_1;  //chnge
+  input CS1_1;
+  input CS2_1;
+  input [`WEWID-1:0] WEN1_1;
+  input POP_1;
+  output Almost_Full_1;
+  output Almost_Empty_1;
+  output [3:0] PUSH_FLAG_1;
+  output [3:0] POP_FLAG_1;
+  input FIFO_EN_1;
+  input SYNC_FIFO_1;
+  input PIPELINE_RD_1;
+  input [1:0] WIDTH_SELECT1_1;
+  input [1:0] WIDTH_SELECT2_1;
+
+  input CONCAT_EN_0;
+  input CONCAT_EN_1;
+
+
+  input PUSH_0;
+  input PUSH_1;
+  input aFlushN_0;
+  input aFlushN_1;
+
+  reg                 rstn;
+
+  wire [  `WEWID-1:0] RAM0_WENb1_SEL;
+  wire [  `WEWID-1:0] RAM1_WENb1_SEL;
+
+  wire                RAM0_CS1_SEL;
+  wire                RAM0_CS2_SEL;
+  wire                RAM1_CS1_SEL;
+  wire                RAM1_CS2_SEL;
+
+  wire [`ADDRWID-1:0] Fifo0_Write_Addr;
+  wire [`ADDRWID-1:0] Fifo0_Read_Addr;
+
+  wire [`ADDRWID-1:0] Fifo1_Write_Addr;
+  wire [`ADDRWID-1:0] Fifo1_Read_Addr;
+
+  wire [`ADDRWID-1:0] RAM0_AA_SEL;
+  wire [`ADDRWID-1:0] RAM0_AB_SEL;
+  wire [`ADDRWID-1:0] RAM1_AA_SEL;
+  wire [`ADDRWID-1:0] RAM1_AB_SEL;
+
+  wire                Concat_En_SEL;
+
+  //  To simulate POR
+  initial begin
+    rstn = 1'b0;
+    #30 rstn = 1'b1;
+  end
+
+  assign fifo0_rstn = rstn & aFlushN_0;
+  assign fifo1_rstn = rstn & aFlushN_1;
+
+  assign Concat_En_SEL = (CONCAT_EN_0 | WIDTH_SELECT1_0[1] | WIDTH_SELECT2_0[1]) ? 1'b1 : 1'b0;
+
+  assign RAM0_AA_SEL = FIFO_EN_0 ? Fifo0_Write_Addr : A1_0[`ADDRWID-1:0];
+  assign RAM0_AB_SEL = FIFO_EN_0 ? Fifo0_Read_Addr : A2_0[`ADDRWID-1:0];
+  assign RAM1_AA_SEL = FIFO_EN_1 ? Fifo1_Write_Addr : A1_1[`ADDRWID-1:0];
+  assign RAM1_AB_SEL = FIFO_EN_1 ? Fifo1_Read_Addr : A2_1[`ADDRWID-1:0];
+
+  assign RAM0_WENb1_SEL = FIFO_EN_0 ? {`WEWID{~PUSH_0}} : ~WEN1_0;
+  assign RAM1_WENb1_SEL = ( FIFO_EN_1 & ~Concat_En_SEL ) ? { `WEWID{ ~PUSH_1 } } :
+                          ( ( FIFO_EN_0 &  Concat_En_SEL ) ? ( WIDTH_SELECT1_0[1] ? { `WEWID{ ~PUSH_0 } } : { `WEWID{ 1'b1 } } ) : ~WEN1_1 );
+
+  assign RAM0_CS1_SEL = (FIFO_EN_0 ? CS1_0 : ~CS1_0);
+  assign RAM0_CS2_SEL = (FIFO_EN_0 ? CS2_0 : ~CS2_0);
+  assign RAM1_CS1_SEL = (FIFO_EN_1 ? CS1_1 : ~CS1_1);
+  assign RAM1_CS2_SEL = (FIFO_EN_1 ? CS2_1 : ~CS2_1);
+
+  x2_model #(
+      .ADDRWID(`ADDRWID),
+      .INIT(INIT),
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int)
+  ) x2_8K_model_inst (
+      .Concat_En(Concat_En_SEL),
+
+      .ram0_WIDTH_SELA(WIDTH_SELECT1_0),
+      .ram0_WIDTH_SELB(WIDTH_SELECT2_0),
+      .ram0_PLRD(PIPELINE_RD_0),
+
+      .ram0_CEA(CLK1_0),
+      .ram0_CEB(CLK2_0),
+      .ram0_I(WD_0),
+      .ram0_O(RD_0),
+      .ram0_AA(RAM0_AA_SEL),
+      .ram0_AB(RAM0_AB_SEL),
+      .ram0_CSBA(RAM0_CS1_SEL),
+      .ram0_CSBB(RAM0_CS2_SEL),
+      .ram0_WENBA(RAM0_WENb1_SEL),
+
+      .ram1_WIDTH_SELA(WIDTH_SELECT1_1),
+      .ram1_WIDTH_SELB(WIDTH_SELECT2_1),
+      .ram1_PLRD(PIPELINE_RD_1),
+
+      .ram1_CEA(CLK1_1),
+      .ram1_CEB(CLK2_1),
+      .ram1_I(WD_1),
+      .ram1_O(RD_1),
+      .ram1_AA(RAM1_AA_SEL),
+      .ram1_AB(RAM1_AB_SEL),
+      .ram1_CSBA(RAM1_CS1_SEL),
+      .ram1_CSBB(RAM1_CS2_SEL),
+      .ram1_WENBA(RAM1_WENb1_SEL)
+  );
+
+  fifo_controller_model #(
+      .MAX_PTR_WIDTH(`ADDRWID + 1)
+  ) fifo_controller0_inst (
+      .Push_Clk(CLK1_0),
+      .Pop_Clk (CLK2_0),
+
+      .Fifo_Push(PUSH_0),
+      .Fifo_Push_Flush(CS1_0),
+      .Fifo_Full(Almost_Full_0),
+      .Fifo_Full_Usr(PUSH_FLAG_0),
+
+      .Fifo_Pop(POP_0),
+      .Fifo_Pop_Flush(CS2_0),
+      .Fifo_Empty(Almost_Empty_0),
+      .Fifo_Empty_Usr(POP_FLAG_0),
+
+      .Write_Addr(Fifo0_Write_Addr),
+
+      .Read_Addr(Fifo0_Read_Addr),
+
+      .Fifo_Ram_Mode(Concat_En_SEL),
+      .Fifo_Sync_Mode(SYNC_FIFO_0),
+      .Fifo_Push_Width(WIDTH_SELECT1_0),
+      .Fifo_Pop_Width(WIDTH_SELECT2_0),
+      .Rst_n(fifo0_rstn)
+  );
+
+  fifo_controller_model #(
+      .MAX_PTR_WIDTH(`ADDRWID + 1)
+  ) fifo_controller1_inst (
+      .Push_Clk(CLK1_1),
+      .Pop_Clk (CLK2_1),
+
+      .Fifo_Push(PUSH_1),
+      .Fifo_Push_Flush(CS1_1),
+      .Fifo_Full(Almost_Full_1),
+      .Fifo_Full_Usr(PUSH_FLAG_1),
+
+      .Fifo_Pop(POP_1),
+      .Fifo_Pop_Flush(CS2_1),
+      .Fifo_Empty(Almost_Empty_1),
+      .Fifo_Empty_Usr(POP_FLAG_1),
+
+      .Write_Addr(Fifo1_Write_Addr),
+
+      .Read_Addr(Fifo1_Read_Addr),
+
+      .Fifo_Ram_Mode(1'b0),
+      .Fifo_Sync_Mode(SYNC_FIFO_1),
+      .Fifo_Push_Width({1'b0, WIDTH_SELECT1_1[0]}),
+      .Fifo_Pop_Width({1'b0, WIDTH_SELECT2_1[0]}),
+      .Rst_n(fifo1_rstn)
+  );
+
+endmodule
+
+module sw_mux (
+    port_out,
+    default_port,
+    alt_port,
+    switch
+);
+
+  output port_out;
+  input default_port;
+  input alt_port;
+  input switch;
+
+  assign port_out = switch ? alt_port : default_port;
+
+endmodule
+
+
+`define ADDRWID_8k2 11
+`define DATAWID 18
+`define WEWID 2
+
+module ram8k_2x1_cell (
+    CLK1_0,
+    CLK2_0,
+    CLK1S_0,
+    CLK2S_0,
+    WD_0,
+    RD_0,
+    A1_0,
+    A2_0,
+    CS1_0,
+    CS2_0,
+    WEN1_0,
+    CLK1EN_0,
+    CLK2EN_0,
+    P1_0,
+    P2_0,
+    Almost_Full_0,
+    Almost_Empty_0,
+    PUSH_FLAG_0,
+    POP_FLAG_0,
+
+    FIFO_EN_0,
+    SYNC_FIFO_0,
+    PIPELINE_RD_0,
+    WIDTH_SELECT1_0,
+    WIDTH_SELECT2_0,
+    DIR_0,
+    ASYNC_FLUSH_0,
+    ASYNC_FLUSH_S0,
+
+    CLK1_1,
+    CLK2_1,
+    CLK1S_1,
+    CLK2S_1,
+    WD_1,
+    RD_1,
+    A1_1,
+    A2_1,
+    CS1_1,
+    CS2_1,
+    WEN1_1,
+    CLK1EN_1,
+    CLK2EN_1,
+    P1_1,
+    P2_1,
+    Almost_Empty_1,
+    Almost_Full_1,
+    PUSH_FLAG_1,
+    POP_FLAG_1,
+
+    FIFO_EN_1,
+    SYNC_FIFO_1,
+    PIPELINE_RD_1,
+    WIDTH_SELECT1_1,
+    WIDTH_SELECT2_1,
+    DIR_1,
+    ASYNC_FLUSH_1,
+    ASYNC_FLUSH_S1,
+
+    CONCAT_EN_0,
+    CONCAT_EN_1
+);
+
+  parameter [18431:0] INIT = 18432'bx;
+  parameter INIT_FILE = "init.mem";
+  parameter data_width_int = 16;
+  parameter data_depth_int = 1024;
+
+  input CLK1_0;
+  input CLK2_0;
+  input CLK1S_0;
+  input CLK2S_0;
+  input [`DATAWID-1:0] WD_0;
+  output [`DATAWID-1:0] RD_0;
+  input [`ADDRWID_8k2-1:0] A1_0;
+  input [`ADDRWID_8k2-1:0] A2_0;
+  input CS1_0;
+  input CS2_0;
+  input [`WEWID-1:0] WEN1_0;
+  input CLK1EN_0;
+  input CLK2EN_0;
+  input P1_0;
+  input P2_0;
+  output Almost_Full_0;
+  output Almost_Empty_0;
+  output [3:0] PUSH_FLAG_0;
+  output [3:0] POP_FLAG_0;
+  input FIFO_EN_0;
+  input SYNC_FIFO_0;
+  input DIR_0;
+  input ASYNC_FLUSH_0;
+  input ASYNC_FLUSH_S0;
+  input PIPELINE_RD_0;
+  input [1:0] WIDTH_SELECT1_0;
+  input [1:0] WIDTH_SELECT2_0;
+
+  input CLK1_1;
+  input CLK2_1;
+  input CLK1S_1;
+  input CLK2S_1;
+  input [`DATAWID-1:0] WD_1;
+  output [`DATAWID-1:0] RD_1;
+  input [`ADDRWID_8k2-1:0] A1_1;
+  input [`ADDRWID_8k2-1:0] A2_1;
+  input CS1_1;
+  input CS2_1;
+  input [`WEWID-1:0] WEN1_1;
+  input CLK1EN_1;
+  input CLK2EN_1;
+  input P1_1;
+  input P2_1;
+  output Almost_Full_1;
+  output Almost_Empty_1;
+  output [3:0] PUSH_FLAG_1;
+  output [3:0] POP_FLAG_1;
+  input FIFO_EN_1;
+  input SYNC_FIFO_1;
+  input DIR_1;
+  input ASYNC_FLUSH_1;
+  input ASYNC_FLUSH_S1;
+  input PIPELINE_RD_1;
+  input [1:0] WIDTH_SELECT1_1;
+  input [1:0] WIDTH_SELECT2_1;
+
+  input CONCAT_EN_0;
+  input CONCAT_EN_1;
+
+  //CODE here
+  reg RAM0_domain_sw;
+  reg RAM1_domain_sw;
+
+  wire CLK1P_0, CLK1P_1, CLK2P_0, CLK2P_1, ASYNC_FLUSHP_1, ASYNC_FLUSHP_0;
+
+  assign WidSel1_1 = WIDTH_SELECT1_0[1];
+  assign WidSel2_1 = WIDTH_SELECT2_0[1];
+
+  assign CLK1P_0 = CLK1S_0 ? ~CLK1_0 : CLK1_0;
+  assign CLK1P_1 = CLK1S_1 ? ~CLK1_1 : CLK1_1;
+  assign CLK2P_0 = CLK2S_0 ? ~CLK2_0 : CLK2_0;
+  assign CLK2P_1 = CLK2S_1 ? ~CLK2_1 : CLK2_1;
+  assign ASYNC_FLUSHP_0 = ASYNC_FLUSH_S0 ? ~ASYNC_FLUSH_0 : ASYNC_FLUSH_0;
+  assign ASYNC_FLUSHP_1 = ASYNC_FLUSH_S1 ? ~ASYNC_FLUSH_1 : ASYNC_FLUSH_1;
+
+
+  /* FIFO mode-only switching */
+  always @(CONCAT_EN_0 or FIFO_EN_0 or FIFO_EN_1 or WidSel1_1 or WidSel2_1 or DIR_0 or DIR_1) begin
+    if (CONCAT_EN_0)                                               //CONCAT enabled, only RAM0 ports are checked
+		begin
+      if (~FIFO_EN_0)                                              //RAM MODE (no switching)
+			begin
+        RAM0_domain_sw = 1'b0;  //Both Switches are on default during RAM mode
+        RAM1_domain_sw = 1'b0;
+      end
+		else                                                               //FIFO Mode
+			begin
+        RAM0_domain_sw = DIR_0;  //Both Switches will get DIR_0 (primary port) during concat
+        RAM1_domain_sw = DIR_0;
+      end
+    end
+	else                                                                 //CONCAT disabled, RAM0 and RAM1 ports are be checked
+		begin
+      if (WidSel1_1 || WidSel2_1)        //AUTO-CONCAT FIFO/RAM Mode Horizontal Concatenation
+				begin
+        if (~FIFO_EN_0)                                          //RAM MODE (no switching)
+					begin
+          RAM0_domain_sw = 1'b0;  //Both Switches are on default during RAM mode
+          RAM1_domain_sw = 1'b0;
+        end
+				else                                                           //FIFO Mode
+					begin
+          RAM0_domain_sw = DIR_0;  //Both Switches will get DIR_0 (primary port) during concat
+          RAM1_domain_sw = DIR_0;
+        end
+      end
+			else                                                             //FIFO/RAM Individual Mode
+				begin
+        if (~FIFO_EN_0)  //RAM0 Mode
+          RAM0_domain_sw = 1'b0;
+        else  //FIFO0 Mode
+          RAM0_domain_sw = DIR_0;
+        if (~FIFO_EN_1)  //RAM1 Mode
+          RAM1_domain_sw = 1'b0;
+        else  //FIFO1 Mode
+          RAM1_domain_sw = DIR_1;
+      end
+    end
+  end
+
+  assign RAM0_Clk1_gated = CLK1EN_0 & CLK1P_0;
+  assign RAM0_Clk2_gated = CLK2EN_0 & CLK2P_0;
+  assign RAM1_Clk1_gated = CLK1EN_1 & CLK1P_1;
+  assign RAM1_Clk2_gated = CLK2EN_1 & CLK2P_1;
+
+  //PORT1 of RAMs is designated to PUSH circuitry, while PORT2 gets POP circuitry
+  sw_mux RAM0_clk_sw_port1 (
+      .port_out(RAM0_clk_port1),
+      .default_port(RAM0_Clk1_gated),
+      .alt_port(RAM0_Clk2_gated),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_P_sw_port1 (
+      .port_out(RAM0_push_port1),
+      .default_port(P1_0),
+      .alt_port(P2_0),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_Flush_sw_port1 (
+      .port_out(RAM0CS_Sync_Flush_port1),
+      .default_port(CS1_0),
+      .alt_port(CS2_0),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_WidSel0_port1 (
+      .port_out(RAM0_Wid_Sel0_port1),
+      .default_port(WIDTH_SELECT1_0[0]),
+      .alt_port(WIDTH_SELECT2_0[0]),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_WidSel1_port1 (
+      .port_out(RAM0_Wid_Sel1_port1),
+      .default_port(WIDTH_SELECT1_0[1]),
+      .alt_port(WIDTH_SELECT2_0[1]),
+      .switch(RAM0_domain_sw)
+  );
+
+  sw_mux RAM0_clk_sw_port2 (
+      .port_out(RAM0_clk_port2),
+      .default_port(RAM0_Clk2_gated),
+      .alt_port(RAM0_Clk1_gated),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_P_sw_port2 (
+      .port_out(RAM0_pop_port2),
+      .default_port(P2_0),
+      .alt_port(P1_0),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_Flush_sw_port2 (
+      .port_out(RAM0CS_Sync_Flush_port2),
+      .default_port(CS2_0),
+      .alt_port(CS1_0),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_WidSel0_port2 (
+      .port_out(RAM0_Wid_Sel0_port2),
+      .default_port(WIDTH_SELECT2_0[0]),
+      .alt_port(WIDTH_SELECT1_0[0]),
+      .switch(RAM0_domain_sw)
+  );
+  sw_mux RAM0_WidSel1_port2 (
+      .port_out(RAM0_Wid_Sel1_port2),
+      .default_port(WIDTH_SELECT2_0[1]),
+      .alt_port(WIDTH_SELECT1_0[1]),
+      .switch(RAM0_domain_sw)
+  );
+
+  sw_mux RAM1_clk_sw_port1 (
+      .port_out(RAM1_clk_port1),
+      .default_port(RAM1_Clk1_gated),
+      .alt_port(RAM1_Clk2_gated),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_P_sw_port1 (
+      .port_out(RAM1_push_port1),
+      .default_port(P1_1),
+      .alt_port(P2_1),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_Flush_sw_port1 (
+      .port_out(RAM1CS_Sync_Flush_port1),
+      .default_port(CS1_1),
+      .alt_port(CS2_1),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_WidSel0_port1 (
+      .port_out(RAM1_Wid_Sel0_port1),
+      .default_port(WIDTH_SELECT1_1[0]),
+      .alt_port(WIDTH_SELECT2_1[0]),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_WidSel1_port1 (
+      .port_out(RAM1_Wid_Sel1_port1),
+      .default_port(WIDTH_SELECT1_1[1]),
+      .alt_port(WIDTH_SELECT2_1[1]),
+      .switch(RAM1_domain_sw)
+  );
+
+
+  sw_mux RAM1_clk_sw_port2 (
+      .port_out(RAM1_clk_port2),
+      .default_port(RAM1_Clk2_gated),
+      .alt_port(RAM1_Clk1_gated),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_P_sw_port2 (
+      .port_out(RAM1_pop_port2),
+      .default_port(P2_1),
+      .alt_port(P1_1),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_Flush_sw_port2 (
+      .port_out(RAM1CS_Sync_Flush_port2),
+      .default_port(CS2_1),
+      .alt_port(CS1_1),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_WidSel0_port2 (
+      .port_out(RAM1_Wid_Sel0_port2),
+      .default_port(WIDTH_SELECT2_1[0]),
+      .alt_port(WIDTH_SELECT1_1[0]),
+      .switch(RAM1_domain_sw)
+  );
+  sw_mux RAM1_WidSel1_port2 (
+      .port_out(RAM1_Wid_Sel1_port2),
+      .default_port(WIDTH_SELECT2_1[1]),
+      .alt_port(WIDTH_SELECT1_1[1]),
+      .switch(RAM1_domain_sw)
+  );
+
+  ram_block_8K #(
+      .INIT(INIT),
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int)
+  ) ram_block_8K_inst (
+      .CLK1_0(RAM0_clk_port1),
+      .CLK2_0(RAM0_clk_port2),
+      .WD_0(WD_0),
+      .RD_0(RD_0),
+      .A1_0(A1_0),
+      .A2_0(A2_0),
+      .CS1_0(RAM0CS_Sync_Flush_port1),
+      .CS2_0(RAM0CS_Sync_Flush_port2),
+      .WEN1_0(WEN1_0),
+      .POP_0(RAM0_pop_port2),
+      .Almost_Full_0(Almost_Full_0),
+      .Almost_Empty_0(Almost_Empty_0),
+      .PUSH_FLAG_0(PUSH_FLAG_0),
+      .POP_FLAG_0(POP_FLAG_0),
+
+      .FIFO_EN_0(FIFO_EN_0),
+      .SYNC_FIFO_0(SYNC_FIFO_0),
+      .PIPELINE_RD_0(PIPELINE_RD_0),
+      .WIDTH_SELECT1_0({RAM0_Wid_Sel1_port1, RAM0_Wid_Sel0_port1}),
+      .WIDTH_SELECT2_0({RAM0_Wid_Sel1_port2, RAM0_Wid_Sel0_port2}),
+
+      .CLK1_1(RAM1_clk_port1),
+      .CLK2_1(RAM1_clk_port2),
+      .WD_1(WD_1),
+      .RD_1(RD_1),
+      .A1_1(A1_1),
+      .A2_1(A2_1),
+      .CS1_1(RAM1CS_Sync_Flush_port1),
+      .CS2_1(RAM1CS_Sync_Flush_port2),
+      .WEN1_1(WEN1_1),
+      .POP_1(RAM1_pop_port2),
+      .Almost_Empty_1(Almost_Empty_1),
+      .Almost_Full_1(Almost_Full_1),
+      .PUSH_FLAG_1(PUSH_FLAG_1),
+      .POP_FLAG_1(POP_FLAG_1),
+
+      .FIFO_EN_1(FIFO_EN_1),
+      .SYNC_FIFO_1(SYNC_FIFO_1),
+      .PIPELINE_RD_1(PIPELINE_RD_1),
+      .WIDTH_SELECT1_1({RAM1_Wid_Sel1_port1, RAM1_Wid_Sel0_port1}),
+      .WIDTH_SELECT2_1({RAM1_Wid_Sel1_port2, RAM1_Wid_Sel0_port2}),
+
+      .CONCAT_EN_0(CONCAT_EN_0),
+      .CONCAT_EN_1(CONCAT_EN_1),
+
+      .PUSH_0(RAM0_push_port1),
+      .PUSH_1(RAM1_push_port1),
+      .aFlushN_0(~ASYNC_FLUSHP_0),
+      .aFlushN_1(~ASYNC_FLUSHP_1)
+  );
+
+endmodule
+
+module ram8k_2x1_cell_macro #(
+    parameter [18431:0] INIT = 18432'bx,
+    parameter INIT_FILE = "init.mem",
+    parameter data_width_int = 16,
+    parameter data_depth_int = 1024
+) (
+    input [10:0] A1_0,
+    input [10:0] A1_1,
+    input [10:0] A2_0,
+    input [10:0] A2_1,
+    (* clkbuf_sink *)
+    input CLK1_0,
+    (* clkbuf_sink *)
+    input CLK1_1,
+    (* clkbuf_sink *)
+    input CLK2_0,
+    (* clkbuf_sink *)
+    input CLK2_1,
+    output Almost_Empty_0,
+    Almost_Empty_1,
+    Almost_Full_0,
+    Almost_Full_1,
+    input ASYNC_FLUSH_0,
+    ASYNC_FLUSH_1,
+    ASYNC_FLUSH_S0,
+    ASYNC_FLUSH_S1,
+    CLK1EN_0,
+    CLK1EN_1,
+    CLK1S_0,
+    CLK1S_1,
+    CLK2EN_0,
+    CLK2EN_1,
+    CLK2S_0,
+    CLK2S_1,
+    CONCAT_EN_0,
+    CONCAT_EN_1,
+    CS1_0,
+    CS1_1,
+    CS2_0,
+    CS2_1,
+    DIR_0,
+    DIR_1,
+    FIFO_EN_0,
+    FIFO_EN_1,
+    P1_0,
+    P1_1,
+    P2_0,
+    P2_1,
+    PIPELINE_RD_0,
+    PIPELINE_RD_1,
+    output [3:0] POP_FLAG_0,
+    output [3:0] POP_FLAG_1,
+    output [3:0] PUSH_FLAG_0,
+    output [3:0] PUSH_FLAG_1,
+    output [17:0] RD_0,
+    output [17:0] RD_1,
+    input SYNC_FIFO_0,
+    SYNC_FIFO_1,
+    input [17:0] WD_0,
+    input [17:0] WD_1,
+    input [1:0] WEN1_0,
+    input [1:0] WEN1_1,
+    input [1:0] WIDTH_SELECT1_0,
+    input [1:0] WIDTH_SELECT1_1,
+    input [1:0] WIDTH_SELECT2_0,
+    input [1:0] WIDTH_SELECT2_1,
+    input SD,
+    DS,
+    LS,
+    SD_RB1,
+    LS_RB1,
+    DS_RB1,
+    RMEA,
+    RMEB,
+    TEST1A,
+    TEST1B,
+    input [3:0] RMA,
+    input [3:0] RMB
+);
+
+
+  ram8k_2x1_cell #(
+      .INIT(INIT),
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int)
+  ) I1 (
+      .A1_0({A1_0[10:0]}),
+      .A1_1({A1_1[10:0]}),
+      .A2_0({A2_0[10:0]}),
+      .A2_1({A2_1[10:0]}),
+      .Almost_Empty_0(Almost_Empty_0),
+      .Almost_Empty_1(Almost_Empty_1),
+      .Almost_Full_0(Almost_Full_0),
+      .Almost_Full_1(Almost_Full_1),
+      .ASYNC_FLUSH_0(ASYNC_FLUSH_0),
+      .ASYNC_FLUSH_1(ASYNC_FLUSH_1),
+      .ASYNC_FLUSH_S0(ASYNC_FLUSH_S0),
+      .ASYNC_FLUSH_S1(ASYNC_FLUSH_S1),
+      .CLK1_0(CLK1_0),
+      .CLK1_1(CLK1_1),
+      .CLK1EN_0(CLK1EN_0),
+      .CLK1EN_1(CLK1EN_1),
+      .CLK1S_0(CLK1S_0),
+      .CLK1S_1(CLK1S_1),
+      .CLK2_0(CLK2_0),
+      .CLK2_1(CLK2_1),
+      .CLK2EN_0(CLK2EN_0),
+      .CLK2EN_1(CLK2EN_1),
+      .CLK2S_0(CLK2S_0),
+      .CLK2S_1(CLK2S_1),
+      .CONCAT_EN_0(CONCAT_EN_0),
+      .CONCAT_EN_1(CONCAT_EN_1),
+      .CS1_0(CS1_0),
+      .CS1_1(CS1_1),
+      .CS2_0(CS2_0),
+      .CS2_1(CS2_1),
+      .DIR_0(DIR_0),
+      .DIR_1(DIR_1),
+      .FIFO_EN_0(FIFO_EN_0),
+      .FIFO_EN_1(FIFO_EN_1),
+      .P1_0(P1_0),
+      .P1_1(P1_1),
+      .P2_0(P2_0),
+      .P2_1(P2_1),
+      .PIPELINE_RD_0(PIPELINE_RD_0),
+      .PIPELINE_RD_1(PIPELINE_RD_1),
+      .POP_FLAG_0({POP_FLAG_0[3:0]}),
+      .POP_FLAG_1({POP_FLAG_1[3:0]}),
+      .PUSH_FLAG_0({PUSH_FLAG_0[3:0]}),
+      .PUSH_FLAG_1({PUSH_FLAG_1[3:0]}),
+      .RD_0({RD_0[17:0]}),
+      .RD_1({RD_1[17:0]}),
+      .SYNC_FIFO_0(SYNC_FIFO_0),
+      .SYNC_FIFO_1(SYNC_FIFO_1),
+      .WD_0({WD_0[17:0]}),
+      .WD_1({WD_1[17:0]}),
+      .WEN1_0({WEN1_0[1:0]}),
+      .WEN1_1({WEN1_1[1:0]}),
+      .WIDTH_SELECT1_0({WIDTH_SELECT1_0[1:0]}),
+      .WIDTH_SELECT1_1({WIDTH_SELECT1_1[1:0]}),
+      .WIDTH_SELECT2_0({WIDTH_SELECT2_0[1:0]}),
+      .WIDTH_SELECT2_1({WIDTH_SELECT2_1[1:0]})
+  );
+
+endmodule  /* ram8k_2x1_cell_macro */
+
+module RAM_8K_BLK (
+    WA,
+    RA,
+    WD,
+    WClk,
+    RClk,
+    WClk_En,
+    RClk_En,
+    WEN,
+    RD
+);
+
+  parameter addr_int 	= 9,
+          data_depth_int = 512,
+          data_width_int = 18,
+          wr_enable_int 	= 2,
+          reg_rd_int 	= 0;
+
+  parameter [8191:0] INIT = 8192'bx;
+  parameter INIT_FILE = "init.mem";
+
+  input [addr_int-1:0] WA;
+  input [addr_int-1:0] RA;
+  input WClk, RClk;
+  input WClk_En, RClk_En;
+  input [wr_enable_int-1:0] WEN;
+  input [data_width_int-1:0] WD;
+  output [data_width_int-1:0] RD;
+
+  wire VCC, GND;
+  wire WClk0_Sel, RClk0_Sel;
+  wire WClk1_Sel, RClk1_Sel;
+
+  wire reg_rd0;
+  wire reg_rd1;
+  wire [10:0] addr_wr0, addr_rd0, addr_wr1, addr_rd1;
+
+  wire [17:0] in_reg0;
+
+  wire [ 2:0] wen_reg0;
+
+  wire [15:0] out_reg0;
+
+  wire [ 1:0] out_par0;
+
+  wire [1:0] WS1_0, WS2_0;
+  wire [1:0] WS_GND;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+
+  wire WD0_SEL, RD0_SEL;
+  wire WD1_SEL, RD1_SEL;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign WD0_SEL = 1'b1;
+  assign RD0_SEL = 1'b1;
+  assign WD1_SEL = 1'b0;
+  assign RD1_SEL = 1'b0;
+
+  assign WClk0_Sel = 1'b0;
+  assign RClk0_Sel = 1'b0;
+
+  assign WClk1_Sel = 1'b0;
+  assign RClk1_Sel = 1'b0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign WS_GND = 2'b00;
+
+  assign reg_rd1 = 1'b0;
+
+  assign wen_reg0[2:wr_enable_int] = 0;
+  assign wen_reg0[wr_enable_int-1:0] = WEN;
+
+  assign addr_wr1 = 11'b0000000000;
+  assign addr_rd1 = 11'b0000000000;
+
+  generate
+
+    if (addr_int == 11) begin
+      assign addr_wr0[10:0] = WA;
+      assign addr_rd0[10:0] = RA;
+    end else begin
+      assign addr_wr0[10:addr_int]  = 0;
+      assign addr_wr0[addr_int-1:0] = WA;
+      assign addr_rd0[10:addr_int]  = 0;
+      assign addr_rd0[addr_int-1:0] = RA;
+    end
+
+    if (data_width_int == 16) begin
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 16) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+  endgenerate
+
+  ram8k_2x1_cell_macro #(
+      `include "bram_init_8_16.vh"
+      .INIT_FILE(INIT_FILE),
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int)
+  ) U1 (
+      .A1_0(addr_wr0),
+      .A1_1(addr_wr1),
+      .A2_0(addr_rd0),
+      .A2_1(addr_rd1),
+      .ASYNC_FLUSH_0(GND),  //chk
+      .ASYNC_FLUSH_1(GND),  //chk
+      .ASYNC_FLUSH_S0(GND),
+      .ASYNC_FLUSH_S1(GND),
+      .CLK1_0(WClk),
+      .CLK1_1(GND),
+      .CLK1S_0(WClk0_Sel),
+      .CLK1S_1(WClk1_Sel),
+      .CLK1EN_0(WClk_En),
+      .CLK1EN_1(GND),
+      .CLK2_0(RClk),
+      .CLK2_1(GND),
+      .CLK2S_0(RClk0_Sel),
+      .CLK2S_1(RClk1_Sel),
+      .CLK2EN_0(RClk_En),
+      .CLK2EN_1(GND),
+      .CONCAT_EN_0(GND),
+      .CONCAT_EN_1(GND),
+      .CS1_0(WD0_SEL),
+      .CS1_1(WD1_SEL),
+      .CS2_0(RD0_SEL),
+      .CS2_1(RD1_SEL),
+      .DIR_0(GND),
+      .DIR_1(GND),
+      .FIFO_EN_0(GND),
+      .FIFO_EN_1(GND),
+      .P1_0(GND),  //P1_0
+      .P1_1(GND),  //P1_1
+      .P2_0(GND),  //
+      .P2_1(GND),  //
+      .PIPELINE_RD_0(reg_rd0),
+      .PIPELINE_RD_1(reg_rd1),
+      .SYNC_FIFO_0(GND),
+      .SYNC_FIFO_1(GND),
+      .WD_1({18{GND}}),
+      .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+      .WIDTH_SELECT1_0(WS1_0),
+      .WIDTH_SELECT1_1(WS_GND),
+      .WIDTH_SELECT2_0(WS2_0),
+      .WIDTH_SELECT2_1(WS_GND),
+      .WEN1_0(wen_reg0[1:0]),
+      .WEN1_1({2{GND}}),
+      .Almost_Empty_0(),
+      .Almost_Empty_1(),
+      .Almost_Full_0(),
+      .Almost_Full_1(),
+      .POP_FLAG_0(),
+      .POP_FLAG_1(),
+      .PUSH_FLAG_0(),
+      .PUSH_FLAG_1(),
+      .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+      .RD_1(),
+      .SD(SD),
+      .SD_RB1(SD_RB1),
+      .LS(LS),
+      .LS_RB1(LS_RB1),
+      .DS(DS),
+      .DS_RB1(DS_RB1),
+      .TEST1A(GND),
+      .TEST1B(GND),
+      .RMA(4'd0),
+      .RMB(4'd0),
+      .RMEA(GND),
+      .RMEB(GND)
+  );
+
+  assign RD[data_width_int-1 : 0] = out_reg0[data_width_int-1 : 0];
+
+
+endmodule
+
+
+module RAM_16K_BLK (
+    WA,
+    RA,
+    WD,
+    WClk,
+    RClk,
+    WClk_En,
+    RClk_En,
+    WEN,
+    RD
+);
+
+  parameter addr_int 	= 9,
+          data_depth_int = 512,
+	  		  data_width_int = 36,
+          wr_enable_int 	= 4,
+	  		  reg_rd_int 	= 0;
+
+  parameter [16383:0] INIT = 16384'bx;
+  parameter INIT_FILE = "init.mem";
+
+  input [addr_int-1:0] WA;
+  input [addr_int-1:0] RA;
+  input WClk, RClk;
+  input WClk_En, RClk_En;
+  input [wr_enable_int-1:0] WEN;
+  input [data_width_int-1:0] WD;
+  output [data_width_int-1:0] RD;
+
+  wire VCC, GND;
+
+  wire WClk0_Sel, RClk0_Sel;
+  wire WClk1_Sel, RClk1_Sel;
+
+  wire reg_rd0;
+  wire reg_rd1;
+  wire [10:0] addr_wr0, addr_rd0, addr_wr1, addr_rd1;
+
+  wire [31:0] in_reg0;
+
+  wire [ 4:0] wen_reg0;
+
+  wire [31:0] out_reg0;
+
+  wire [ 3:0] out_par0;
+
+  wire [1:0] WS1_0, WS2_0;
+  wire [1:0] WS_GND;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+
+  wire WD0_SEL, RD0_SEL;
+  wire WD1_SEL, RD1_SEL;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign WD0_SEL = 1'b1;
+  assign RD0_SEL = 1'b1;
+  assign WD1_SEL = 1'b1;
+  assign RD1_SEL = 1'b1;
+
+  assign WClk0_Sel = 1'b0;
+  assign RClk0_Sel = 1'b0;
+
+  assign WClk1_Sel = 1'b0;
+  assign RClk1_Sel = 1'b0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign WS_GND = 2'b00;
+
+  assign reg_rd1 = 1'b0;
+
+  assign wen_reg0[4:wr_enable_int] = 0;
+  assign wen_reg0[wr_enable_int-1:0] = WEN;
+
+  assign addr_wr1 = 11'b0000000000;
+  assign addr_rd1 = 11'b0000000000;
+
+  generate
+
+    if (addr_int == 11) begin
+      assign addr_wr0[10:0] = WA;
+      assign addr_rd0[10:0] = RA;
+    end else begin
+      assign addr_wr0[10:addr_int]  = 0;
+      assign addr_wr0[addr_int-1:0] = WA;
+      assign addr_rd0[10:addr_int]  = 0;
+      assign addr_rd0[addr_int-1:0] = RA;
+    end
+
+    if (data_width_int == 32) begin
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 32) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = WD[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+    if (data_width_int <= 16) begin
+
+      ram8k_2x1_cell_macro #(
+          `include "bram_init_8_16.vh"
+          .INIT_FILE(INIT_FILE),
+          .data_width_int(data_width_int),
+          .data_depth_int(data_depth_int)
+      ) U1 (
+          .A1_0(addr_wr0),
+          .A1_1(addr_wr1),
+          .A2_0(addr_rd0),
+          .A2_1(addr_rd1),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(WClk),
+          .CLK1_1(WClk),
+          .CLK1S_0(WClk0_Sel),
+          .CLK1S_1(WClk0_Sel),
+          .CLK1EN_0(WClk_En),
+          .CLK1EN_1(WClk_En),
+          .CLK2_0(RClk),
+          .CLK2_1(RClk),
+          .CLK2S_0(RClk0_Sel),
+          .CLK2S_1(RClk0_Sel),
+          .CLK2EN_0(RClk_En),
+          .CLK2EN_1(RClk_En),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(WD0_SEL),
+          .CS1_1(GND),
+          .CS2_0(RD0_SEL),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1({18{GND}}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(WS_GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(WS_GND),
+          .WEN1_0(wen_reg0[1:0]),
+          .WEN1_1(wen_reg0[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1(),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end else if (data_width_int > 16) begin
+
+      ram8k_2x1_cell_macro #(
+          `include "bram_init_32.vh"
+          .INIT_FILE(INIT_FILE),
+          .data_width_int(data_width_int),
+          .data_depth_int(data_depth_int)
+      ) U2 (
+          .A1_0(addr_wr0),
+          .A1_1(addr_wr1),
+          .A2_0(addr_rd0),
+          .A2_1(addr_rd1),
+          .ASYNC_FLUSH_0(GND),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(GND),
+          .ASYNC_FLUSH_S1(GND),
+          .CLK1_0(WClk),
+          .CLK1_1(WClk),
+          .CLK1S_0(WClk0_Sel),
+          .CLK1S_1(WClk0_Sel),
+          .CLK1EN_0(WClk_En),
+          .CLK1EN_1(WClk_En),
+          .CLK2_0(RClk),
+          .CLK2_1(RClk),
+          .CLK2S_0(RClk0_Sel),
+          .CLK2S_1(RClk0_Sel),
+          .CLK2EN_0(RClk_En),
+          .CLK2EN_1(RClk_En),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(WD0_SEL),
+          .CS1_1(GND),
+          .CS2_0(RD0_SEL),
+          .CS2_1(GND),
+          .DIR_0(GND),
+          .DIR_1(GND),
+          .FIFO_EN_0(GND),
+          .FIFO_EN_1(GND),
+          .P1_0(GND),
+          .P1_1(GND),
+          .P2_0(GND),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(GND),
+          .SYNC_FIFO_1(GND),
+          .WD_1({1'b0, in_reg0[31:24], 1'b0, in_reg0[23:16]}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1(WS_GND),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1(WS_GND),
+          .WEN1_0(wen_reg0[1:0]),
+          .WEN1_1(wen_reg0[3:2]),
+          .Almost_Empty_0(),
+          .Almost_Empty_1(),
+          .Almost_Full_0(),
+          .Almost_Full_1(),
+          .POP_FLAG_0(),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1({out_par0[3], out_reg0[31:24], out_par0[2], out_reg0[23:16]}),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end
+
+  endgenerate
+
+  assign RD[data_width_int-1 : 0] = out_reg0[data_width_int-1 : 0];
+
+endmodule
+
+
+module FIFO_8K_BLK (
+    DIN,
+    Fifo_Push_Flush,
+    Fifo_Pop_Flush,
+    PUSH,
+    POP,
+    Push_Clk,
+    Pop_Clk,
+    Push_Clk_En,
+    Pop_Clk_En,
+    Fifo_Dir,
+    Async_Flush,
+    Almost_Full,
+    Almost_Empty,
+    PUSH_FLAG,
+    POP_FLAG,
+    DOUT
+);
+
+  parameter data_depth_int = 512, data_width_int = 36, reg_rd_int = 0, sync_fifo_int = 0;
+
+  input Fifo_Push_Flush, Fifo_Pop_Flush;
+  input Push_Clk, Pop_Clk;
+  input PUSH, POP;
+  input [data_width_int-1:0] DIN;
+  input Push_Clk_En, Pop_Clk_En, Fifo_Dir, Async_Flush;
+  output [data_width_int-1:0] DOUT;
+  output [3:0] PUSH_FLAG, POP_FLAG;
+  output Almost_Full, Almost_Empty;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+  wire VCC, GND;
+
+  wire [10:0] addr_wr, addr_rd;
+  wire clk1_sig0, clk2_sig0, clk1_sig_en0, clk2_sig_en0, fifo_clk1_flush_sig0, fifo_clk2_flush_sig0, p1_sig0, p2_sig0,clk1_sig_sel0,clk2_sig_sel0;
+  wire reg_rd0, sync_fifo0;
+  wire [15:0] in_reg0;
+  wire [15:0] out_reg0;
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS2_0;
+  wire Push_Clk0_Sel, Pop_Clk0_Sel;
+  wire Async_Flush_Sel0;
+
+  wire [1:0] out_par0;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign Push_Clk0_Sel  	= 1'b0;
+  assign Pop_Clk0_Sel   	= 1'b0;
+  assign Async_Flush_Sel0 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign sync_fifo0 = sync_fifo_int;
+
+  assign addr_wr=11'b00000000000;
+  assign addr_rd=11'b00000000000;
+
+  assign clk1_sig0 = Fifo_Dir ? Pop_Clk : Push_Clk;
+  assign clk2_sig0 = Fifo_Dir ? Push_Clk : Pop_Clk ;
+  assign clk1_sig_en0 = Fifo_Dir ? Pop_Clk_En : Push_Clk_En;
+  assign clk2_sig_en0 = Fifo_Dir ? Push_Clk_En : Pop_Clk_En ;
+  assign clk1_sig_sel0 =  Push_Clk0_Sel;
+  assign clk2_sig_sel0 =  Pop_Clk0_Sel ;
+  assign fifo_clk1_flush_sig0 = Fifo_Dir ? Fifo_Pop_Flush : Fifo_Push_Flush;
+  assign fifo_clk2_flush_sig0 = Fifo_Dir ? Fifo_Push_Flush : Fifo_Pop_Flush ;
+  assign p1_sig0 = Fifo_Dir ? POP : PUSH;
+  assign p2_sig0 = Fifo_Dir ? PUSH : POP ;
+
+  generate
+
+    if (data_width_int == 16) begin
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 16) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[15:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+  endgenerate
+
+  ram8k_2x1_cell_macro #(
+      .data_width_int(data_width_int),
+      .data_depth_int(data_depth_int)
+  ) U1 (
+      .A1_0(addr_wr),
+      .A1_1(addr_wr),
+      .A2_0(addr_rd),
+      .A2_1(addr_rd),
+      .ASYNC_FLUSH_0(Async_Flush),
+      .ASYNC_FLUSH_1(GND),
+      .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+      .ASYNC_FLUSH_S1(GND),
+      .CLK1_0(clk1_sig0),
+      .CLK1_1(GND),
+      .CLK1EN_0(clk1_sig_en0),
+      .CLK1EN_1(GND),
+      .CLK2_0(clk2_sig0),
+      .CLK2_1(GND),
+      .CLK1S_0(clk1_sig_sel0),
+      .CLK1S_1(GND),
+      .CLK2S_0(clk2_sig_sel0),
+      .CLK2S_1(GND),
+      .CLK2EN_0(clk2_sig_en0),
+      .CLK2EN_1(GND),
+      .CONCAT_EN_0(GND),
+      .CONCAT_EN_1(GND),
+      .CS1_0(fifo_clk1_flush_sig0),
+      .CS1_1(GND),
+      .CS2_0(fifo_clk2_flush_sig0),
+      .CS2_1(GND),
+      .DIR_0(Fifo_Dir),
+      .DIR_1(GND),
+      .FIFO_EN_0(VCC),
+      .FIFO_EN_1(GND),
+      .P1_0(p1_sig0),
+      .P1_1(GND),
+      .P2_0(p2_sig0),
+      .P2_1(GND),
+      .PIPELINE_RD_0(reg_rd0),
+      .PIPELINE_RD_1(GND),
+      .SYNC_FIFO_0(sync_fifo0),
+      .SYNC_FIFO_1(GND),
+      .WD_1({18{GND}}),
+      .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+      .WIDTH_SELECT1_0(WS1_0),
+      .WIDTH_SELECT1_1({GND, GND}),
+      .WIDTH_SELECT2_0(WS2_0),
+      .WIDTH_SELECT2_1({GND, GND}),
+      .WEN1_0({GND, GND}),
+      .WEN1_1({GND, GND}),
+      .Almost_Empty_0(Almost_Empty),
+      .Almost_Empty_1(),
+      .Almost_Full_0(Almost_Full),
+      .Almost_Full_1(),
+      .POP_FLAG_0(POP_FLAG),
+      .POP_FLAG_1(),
+      .PUSH_FLAG_0(PUSH_FLAG),
+      .PUSH_FLAG_1(),
+      .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+      .RD_1(),
+      .SD(SD),
+      .SD_RB1(SD_RB1),
+      .LS(LS),
+      .LS_RB1(LS_RB1),
+      .DS(DS),
+      .DS_RB1(DS_RB1),
+      .TEST1A(GND),
+      .TEST1B(GND),
+      .RMA(4'd0),
+      .RMB(4'd0),
+      .RMEA(GND),
+      .RMEB(GND)
+  );
+
+  assign DOUT[data_width_int-1 : 0] = out_reg0[data_width_int-1 : 0];
+
+endmodule
+
+
+module FIFO_16K_BLK (
+    DIN,
+    Fifo_Push_Flush,
+    Fifo_Pop_Flush,
+    PUSH,
+    POP,
+    Push_Clk,
+    Pop_Clk,
+    Push_Clk_En,
+    Pop_Clk_En,
+    Fifo_Dir,
+    Async_Flush,
+    Almost_Full,
+    Almost_Empty,
+    PUSH_FLAG,
+    POP_FLAG,
+    DOUT
+);
+
+  parameter data_depth_int = 512, data_width_int = 36, reg_rd_int = 0, sync_fifo_int = 0;
+
+  input Fifo_Push_Flush, Fifo_Pop_Flush;
+  input Push_Clk, Pop_Clk;
+  input PUSH, POP;
+  input [data_width_int-1:0] DIN;
+  input Push_Clk_En, Pop_Clk_En, Fifo_Dir, Async_Flush;
+  output [data_width_int-1:0] DOUT;
+  output [3:0] PUSH_FLAG, POP_FLAG;
+  output Almost_Full, Almost_Empty;
+
+  wire LS, DS, SD, LS_RB1, DS_RB1, SD_RB1;
+  wire VCC, GND;
+
+  wire [10:0] addr_wr, addr_rd;
+  wire clk1_sig0, clk2_sig0, clk1_sig_en0, clk2_sig_en0, fifo_clk1_flush_sig0, fifo_clk2_flush_sig0, p1_sig0, p2_sig0,clk1_sig_sel0,clk2_sig_sel0;
+  wire reg_rd0, sync_fifo0;
+  wire [31:0] in_reg0;
+  wire [31:0] out_reg0;
+  wire [ 1:0] WS1_0;
+  wire [ 1:0] WS2_0;
+  wire Push_Clk0_Sel, Pop_Clk0_Sel;
+  wire Async_Flush_Sel0;
+
+  wire [3:0] out_par0;
+  wire [1:0] out_par1;
+
+  assign LS = 1'b0;
+  assign DS = 1'b0;
+  assign SD = 1'b0;
+  assign LS_RB1 = 1'b0;
+  assign DS_RB1 = 1'b0;
+  assign SD_RB1 = 1'b0;
+
+  assign VCC = 1'b1;
+  assign GND = 1'b0;
+
+  assign Push_Clk0_Sel  	= 1'b0;
+  assign Pop_Clk0_Sel   	= 1'b0;
+  assign Async_Flush_Sel0 = 1'b0;
+
+  assign reg_rd0 = reg_rd_int;
+  assign sync_fifo0 = sync_fifo_int;
+
+  assign addr_wr=11'b00000000000;
+  assign addr_rd=11'b00000000000;
+
+  assign clk1_sig0 = Fifo_Dir ? Pop_Clk : Push_Clk;
+  assign clk2_sig0 = Fifo_Dir ? Push_Clk : Pop_Clk ;
+  assign clk1_sig_en0 = Fifo_Dir ? Pop_Clk_En : Push_Clk_En;
+  assign clk2_sig_en0 = Fifo_Dir ? Push_Clk_En : Pop_Clk_En ;
+  assign clk1_sig_sel0 =  Push_Clk0_Sel;
+  assign clk2_sig_sel0 =  Pop_Clk0_Sel ;
+  assign fifo_clk1_flush_sig0 = Fifo_Dir ? Fifo_Pop_Flush : Fifo_Push_Flush;
+  assign fifo_clk2_flush_sig0 = Fifo_Dir ? Fifo_Push_Flush : Fifo_Pop_Flush ;
+  assign p1_sig0 = Fifo_Dir ? POP : PUSH;
+  assign p2_sig0 = Fifo_Dir ? PUSH : POP ;
+
+  generate
+    if (data_width_int == 32) begin
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int > 8 && data_width_int < 32) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end else if (data_width_int <= 8) begin
+      assign in_reg0[31:data_width_int]  = 0;
+      assign in_reg0[data_width_int-1:0] = DIN[data_width_int-1:0];
+    end
+
+    if (data_width_int <= 8) begin
+      assign WS1_0 = 2'b00;
+      assign WS2_0 = 2'b00;
+    end else if (data_width_int > 8 && data_width_int <= 16) begin
+      assign WS1_0 = 2'b01;
+      assign WS2_0 = 2'b01;
+    end else if (data_width_int > 16) begin
+      assign WS1_0 = 2'b10;
+      assign WS2_0 = 2'b10;
+    end
+
+    if (data_width_int <= 16) begin
+
+      ram8k_2x1_cell_macro #(
+          .data_width_int(data_width_int),
+          .data_depth_int(data_depth_int)
+      ) U1 (
+          .A1_0(addr_wr),
+          .A1_1(addr_wr),
+          .A2_0(addr_rd),
+          .A2_1(addr_rd),
+          .ASYNC_FLUSH_0(Async_Flush),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+          .ASYNC_FLUSH_S1(Async_Flush_Sel0),
+          .CLK1_0(clk1_sig0),
+          .CLK1_1(clk1_sig0),
+          .CLK1EN_0(clk1_sig_en0),
+          .CLK1EN_1(clk1_sig_en0),
+          .CLK2_0(clk2_sig0),
+          .CLK2_1(clk2_sig0),
+          .CLK1S_0(clk1_sig_sel0),
+          .CLK1S_1(clk1_sig_sel0),
+          .CLK2S_0(clk2_sig_sel0),
+          .CLK2S_1(clk2_sig_sel0),
+          .CLK2EN_0(clk2_sig_en0),
+          .CLK2EN_1(clk2_sig_en0),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(fifo_clk1_flush_sig0),
+          .CS1_1(GND),
+          .CS2_0(fifo_clk2_flush_sig0),
+          .CS2_1(GND),
+          .DIR_0(Fifo_Dir),
+          .DIR_1(GND),
+          .FIFO_EN_0(VCC),
+          .FIFO_EN_1(GND),
+          .P1_0(p1_sig0),
+          .P1_1(GND),
+          .P2_0(p2_sig0),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(sync_fifo0),
+          .SYNC_FIFO_1(GND),
+          .WD_1({18{GND}}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1({GND, GND}),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1({GND, GND}),
+          .WEN1_0({GND, GND}),
+          .WEN1_1({GND, GND}),
+          .Almost_Empty_0(Almost_Empty),
+          .Almost_Empty_1(),
+          .Almost_Full_0(Almost_Full),
+          .Almost_Full_1(),
+          .POP_FLAG_0(POP_FLAG),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(PUSH_FLAG),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1(),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+
+    end else if (data_width_int > 16) begin
+
+      ram8k_2x1_cell_macro #(
+          .data_width_int(data_width_int),
+          .data_depth_int(data_depth_int)
+      ) U2 (
+          .A1_0(addr_wr),
+          .A1_1(addr_wr),
+          .A2_0(addr_rd),
+          .A2_1(addr_rd),
+          .ASYNC_FLUSH_0(Async_Flush),
+          .ASYNC_FLUSH_1(GND),
+          .ASYNC_FLUSH_S0(Async_Flush_Sel0),
+          .ASYNC_FLUSH_S1(Async_Flush_Sel0),
+          .CLK1_0(clk1_sig0),
+          .CLK1_1(clk1_sig0),
+          .CLK1EN_0(clk1_sig_en0),
+          .CLK1EN_1(clk1_sig_en0),
+          .CLK2_0(clk2_sig0),
+          .CLK2_1(clk2_sig0),
+          .CLK1S_0(clk1_sig_sel0),
+          .CLK1S_1(clk1_sig_sel0),
+          .CLK2S_0(clk2_sig_sel0),
+          .CLK2S_1(clk2_sig_sel0),
+          .CLK2EN_0(clk2_sig_en0),
+          .CLK2EN_1(clk2_sig_en0),
+          .CONCAT_EN_0(VCC),
+          .CONCAT_EN_1(GND),
+          .CS1_0(fifo_clk1_flush_sig0),
+          .CS1_1(GND),
+          .CS2_0(fifo_clk2_flush_sig0),
+          .CS2_1(GND),
+          .DIR_0(Fifo_Dir),
+          .DIR_1(GND),
+          .FIFO_EN_0(VCC),
+          .FIFO_EN_1(GND),
+          .P1_0(p1_sig0),
+          .P1_1(GND),
+          .P2_0(p2_sig0),
+          .P2_1(GND),
+          .PIPELINE_RD_0(reg_rd0),
+          .PIPELINE_RD_1(GND),
+          .SYNC_FIFO_0(sync_fifo0),
+          .SYNC_FIFO_1(GND),
+          .WD_1({1'b0, in_reg0[31:24], 1'b0, in_reg0[23:16]}),
+          .WD_0({1'b0, in_reg0[15:8], 1'b0, in_reg0[7:0]}),
+          .WIDTH_SELECT1_0(WS1_0),
+          .WIDTH_SELECT1_1({GND, GND}),
+          .WIDTH_SELECT2_0(WS2_0),
+          .WIDTH_SELECT2_1({GND, GND}),
+          .WEN1_0({GND, GND}),
+          .WEN1_1({GND, GND}),
+          .Almost_Empty_0(Almost_Empty),
+          .Almost_Empty_1(),
+          .Almost_Full_0(Almost_Full),
+          .Almost_Full_1(),
+          .POP_FLAG_0(POP_FLAG),
+          .POP_FLAG_1(),
+          .PUSH_FLAG_0(PUSH_FLAG),
+          .PUSH_FLAG_1(),
+          .RD_0({out_par0[1], out_reg0[15:8], out_par0[0], out_reg0[7:0]}),
+          .RD_1({out_par0[3], out_reg0[31:24], out_par0[2], out_reg0[23:16]}),
+          .SD(SD),
+          .SD_RB1(SD_RB1),
+          .LS(LS),
+          .LS_RB1(LS_RB1),
+          .DS(DS),
+          .DS_RB1(DS_RB1),
+          .TEST1A(GND),
+          .TEST1B(GND),
+          .RMA(4'd0),
+          .RMB(4'd0),
+          .RMEA(GND),
+          .RMEB(GND)
+      );
+    end
+
+  endgenerate
+
+  assign DOUT[data_width_int-1 : 0] = out_reg0[data_width_int-1 : 0];
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/pp3/cells_map.v b/yosys-plugins/ql-qlf/pp3/cells_map.v
new file mode 100644
index 000000000..bd3d36e3b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/cells_map.v
@@ -0,0 +1,70 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$_MUX8_ (
+    A,
+    B,
+    C,
+    D,
+    E,
+    F,
+    G,
+    H,
+    S,
+    T,
+    U,
+    Y
+);
+  input A, B, C, D, E, F, G, H, S, T, U;
+  output Y;
+  mux8x0 _TECHMAP_REPLACE_ (
+      .A (A),
+      .B (B),
+      .C (C),
+      .D (D),
+      .E (E),
+      .F (F),
+      .G (G),
+      .H (H),
+      .S0(S),
+      .S1(T),
+      .S2(U),
+      .Q (Y)
+  );
+endmodule
+
+module \$_MUX4_ (
+    A,
+    B,
+    C,
+    D,
+    S,
+    T,
+    U,
+    Y
+);
+  input A, B, C, D, S, T, U;
+  output Y;
+  mux4x0 _TECHMAP_REPLACE_ (
+      .A (A),
+      .B (B),
+      .C (C),
+      .D (D),
+      .S0(S),
+      .S1(T),
+      .Q (Y)
+  );
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/cells_sim.v b/yosys-plugins/ql-qlf/pp3/cells_sim.v
new file mode 100644
index 000000000..a04403c78
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/cells_sim.v
@@ -0,0 +1,499 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module inv (
+    output Q,
+    input  A
+);
+  assign Q = A ? 0 : 1;
+endmodule
+
+module buff (
+    output Q,
+    input  A
+);
+  assign Q = A;
+endmodule
+
+module logic_0 (
+    output a
+);
+  assign a = 0;
+endmodule
+
+module logic_1 (
+    output a
+);
+  assign a = 1;
+endmodule
+
+module gclkbuff (
+    input  A,
+    output Z
+);
+  specify
+    (A => Z) = 0;
+  endspecify
+
+  assign Z = A;
+endmodule
+
+module inpad (
+    output Q,
+    (* iopad_external_pin *)
+    input  P
+);
+  specify
+    (P => Q) = 0;
+  endspecify
+  assign Q = P;
+endmodule
+
+module outpad (
+    (* iopad_external_pin *)
+    output P,
+    input  A
+);
+  specify
+    (A => P) = 0;
+  endspecify
+  assign P = A;
+endmodule
+
+module ckpad (
+    output Q,
+    (* iopad_external_pin *)
+    input  P
+);
+  specify
+    (P => Q) = 0;
+  endspecify
+  assign Q = P;
+endmodule
+
+module bipad (
+    input  A,
+    input  EN,
+    output Q,
+    (* iopad_external_pin *)
+    inout  P
+);
+  assign Q = P;
+  assign P = EN ? A : 1'bz;
+endmodule
+
+module dff (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+  always @(posedge CLK) Q <= D;
+endmodule
+
+module dffc (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    (* clkbuf_sink *)
+    input CLR
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR)
+    if (CLR) Q <= 1'b0;
+    else Q <= D;
+endmodule
+
+module dffp (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    (* clkbuf_sink *)
+    input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge PRE)
+    if (PRE) Q <= 1'b1;
+    else Q <= D;
+endmodule
+
+module dffpc (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    (* clkbuf_sink *)
+    input CLR,
+    (* clkbuf_sink *)
+    input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR or posedge PRE)
+    if (CLR) Q <= 1'b0;
+    else if (PRE) Q <= 1'b1;
+    else Q <= D;
+endmodule
+
+module dffe (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    input EN
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+  always @(posedge CLK) if (EN) Q <= D;
+endmodule
+
+module dffec (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    input EN,
+    (* clkbuf_sink *)
+    input CLR
+);
+  parameter [0:0] INIT = 1'b0;
+  initial Q = INIT;
+
+  always @(posedge CLK or posedge CLR)
+    if (CLR) Q <= 1'b0;
+    else if (EN) Q <= D;
+endmodule
+
+(* lib_whitebox *)
+module dffepc (
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input CLK,
+    input EN,
+    (* clkbuf_sink *)
+    input CLR,
+    (* clkbuf_sink *)
+    input PRE
+);
+  parameter [0:0] INIT = 1'b0;
+
+  specify
+    if (EN) (posedge CLK => (Q : D)) = 1701;  // QCK -> QZ
+    if (CLR) (CLR => Q) = 967;  // QRT -> QZ
+    if (PRE) (PRE => Q) = 1252;  // QST -> QZ
+    $setup(D, posedge CLK, 216);  // QCK -> QDS
+    $setup(EN, posedge CLK, 590);  // QCK -> QEN
+  endspecify
+
+  initial Q = INIT;
+  always @(posedge CLK or posedge CLR or posedge PRE)
+    if (CLR) Q <= 1'b0;
+    else if (PRE) Q <= 1'b1;
+    else if (EN) Q <= D;
+endmodule
+
+//                  FZ       FS F2 (F1 TO 0)
+(* abc9_box, lib_whitebox *)
+module AND2I0 (
+    output Q,
+    input  A,
+    B
+);
+  specify
+    (A => Q) = 698;  // FS -> FZ
+    (B => Q) = 639;  // F2 -> FZ
+  endspecify
+
+  assign Q = A ? B : 0;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux2x0 (
+    output Q,
+    input  S,
+    A,
+    B
+);
+  specify
+    (S => Q) = 698;  // FS -> FZ
+    (A => Q) = 639;  // F1 -> FZ
+    (B => Q) = 639;  // F2 -> FZ
+  endspecify
+
+  assign Q = S ? B : A;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux2x1 (
+    output Q,
+    input  S,
+    A,
+    B
+);
+  specify
+    (S => Q) = 698;  // FS -> FZ
+    (A => Q) = 639;  // F1 -> FZ
+    (B => Q) = 639;  // F2 -> FZ
+  endspecify
+
+  assign Q = S ? B : A;
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module mux4x0 (
+    output Q,
+    input  S0,
+    S1,
+    A,
+    B,
+    C,
+    D
+);
+  specify
+    (S0 => Q) = 1251;  // TAB -> TZ
+    (S1 => Q) = 1406;  // TSL -> TZ
+    (A => Q) = 1699;  // TA1 -> TZ
+    (B => Q) = 1687;  // TA2 -> TZ
+    (C => Q) = 1669;  // TB1 -> TZ
+    (D => Q) = 1679;  // TB2 -> TZ
+  endspecify
+
+  assign Q = S1 ? (S0 ? D : C) : (S0 ? B : A);
+endmodule
+
+// S0 BSL TSL
+// S1 BAB TAB
+// S2 TBS
+// A TA1
+// B TA2
+// C TB1
+// D TB2
+// E BA1
+// F BA2
+// G BB1
+// H BB2
+// Q CZ
+(* abc9_box, lib_whitebox *)
+module mux8x0 (
+    output Q,
+    input  S0,
+    S1,
+    S2,
+    A,
+    B,
+    C,
+    D,
+    E,
+    F,
+    G,
+    H
+);
+  specify
+    (S0 => Q) = 1593;  // ('TSL', 'BSL') -> CZ
+    (S1 => Q) = 1437;  // ('TAB', 'BAB') -> CZ
+    (S2 => Q) = 995;  // TBS -> CZ
+    (A => Q) = 1887;  // TA1 -> CZ
+    (B => Q) = 1873;  // TA2 -> CZ
+    (C => Q) = 1856;  // TB1 -> CZ
+    (D => Q) = 1860;  // TB2 -> CZ
+    (E => Q) = 1714;  // BA1 -> CZ
+    (F => Q) = 1773;  // BA2 -> CZ
+    (G => Q) = 1749;  // BB1 -> CZ
+    (H => Q) = 1723;  // BB2 -> CZ
+  endspecify
+
+  assign Q = S2 ? (S1 ? (S0 ? H : G) : (S0 ? F : E)) : (S1 ? (S0 ? D : C) : (S0 ? B : A));
+endmodule
+
+(* abc9_lut=1, lib_whitebox *)
+module LUT1 (
+    output O,
+    input  I0
+);
+  parameter [1:0] INIT = 0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 698;  // FS -> FZ
+  endspecify
+
+  assign O = I0 ? INIT[1] : INIT[0];
+endmodule
+
+//               TZ        TSL TAB
+(* abc9_lut=2, lib_whitebox *)
+module LUT2 (
+    output O,
+    input  I0,
+    I1
+);
+  parameter [3:0] INIT = 4'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 1251;  // TAB -> TZ
+    (I1 => O) = 1406;  // TSL -> TZ
+  endspecify
+
+  wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
+
+(* abc9_lut=2, lib_whitebox *)
+module LUT3 (
+    output O,
+    input  I0,
+    I1,
+    I2
+);
+  parameter [7:0] INIT = 8'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 1251;  // TAB -> TZ
+    (I1 => O) = 1406;  // TSL -> TZ
+    (I2 => O) = 1699;  // ('TA1', 'TA2', 'TB1', 'TB2') -> TZ
+  endspecify
+
+  wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0];
+  wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
+
+(* abc9_lut=4, lib_whitebox *)
+module LUT4 (
+    output O,
+    input  I0,
+    I1,
+    I2,
+    I3
+);
+  parameter [15:0] INIT = 16'h0;
+  parameter EQN = "(I0)";
+
+  // These timings are for PolarPro 3E; other families will need updating.
+  specify
+    (I0 => O) = 995;  // TBS -> CZ
+    (I1 => O) = 1437;  // ('TAB', 'BAB') -> CZ
+    (I2 => O) = 1593;  // ('TSL', 'BSL') -> CZ
+    (I3 => O) = 1887;  // ('TA1', 'TA2', 'TB1', 'TB2', 'BA1', 'BA2', 'BB1', 'BB2') -> CZ
+  endspecify
+
+  wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0];
+  wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0];
+  wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+  assign O = I0 ? s1[1] : s1[0];
+endmodule
+
+module logic_cell_macro (
+    input  BA1,
+    input  BA2,
+    input  BAB,
+    input  BAS1,
+    input  BAS2,
+    input  BB1,
+    input  BB2,
+    input  BBS1,
+    input  BBS2,
+    input  BSL,
+    input  F1,
+    input  F2,
+    input  FS,
+    input  QCK,
+    input  QCKS,
+    input  QDI,
+    input  QDS,
+    input  QEN,
+    input  QRT,
+    input  QST,
+    input  TA1,
+    input  TA2,
+    input  TAB,
+    input  TAS1,
+    input  TAS2,
+    input  TB1,
+    input  TB2,
+    input  TBS,
+    input  TBS1,
+    input  TBS2,
+    input  TSL,
+    output CZ,
+    output FZ,
+    output QZ,
+    output TZ
+);
+
+  wire TAP1, TAP2, TBP1, TBP2, BAP1, BAP2, BBP1, BBP2, QCKP, TAI, TBI, BAI, BBI, TZI, BZI, CZI, QZI;
+  reg QZ_r;
+
+  assign QZ   = QZ_r;
+  assign TAP1 = TAS1 ? ~TA1 : TA1;
+  assign TAP2 = TAS2 ? ~TA2 : TA2;
+  assign TBP1 = TBS1 ? ~TB1 : TB1;
+  assign TBP2 = TBS2 ? ~TB2 : TB2;
+  assign BAP1 = BAS1 ? ~BA1 : BA1;
+  assign BAP2 = BAS2 ? ~BA2 : BA2;
+  assign BBP1 = BBS1 ? ~BB1 : BB1;
+  assign BBP2 = BBS2 ? ~BB2 : BB2;
+
+  assign TAI  = TSL ? TAP2 : TAP1;
+  assign TBI  = TSL ? TBP2 : TBP1;
+  assign BAI  = BSL ? BAP2 : BAP1;
+  assign BBI  = BSL ? BBP2 : BBP1;
+  assign TZI  = TAB ? TBI : TAI;
+  assign BZI  = BAB ? BBI : BAI;
+  assign CZI  = TBS ? BZI : TZI;
+  assign QZI  = QDS ? QDI : CZI;
+  assign FZ   = FS ? F2 : F1;
+  assign TZ   = TZI;
+  assign CZ   = CZI;
+  assign QCKP = QCKS ? QCK : ~QCK;
+
+  initial QZ_r <= 1'b0;
+
+  always @(posedge QCKP or posedge QRT or posedge QST) begin
+    if (QRT)
+        QZ_r <= 1'b0;
+    else if (QST)
+        QZ_r <= 1'b1;
+    else if (QEN)
+        QZ_r <= QZI;
+  end
+
+endmodule
+
+// Include simulation models of QLAL4S3B eFPGA interface
+`include "qlal4s3b_sim.v"
+// Include simulation models for QLAL3 hard blocks
+`include "qlal3_sim.v"
+// Include BRAM and FIFO simulation models
+`include "brams_sim.v"
+// Include MULT simulation models
+`include "mult_sim.v"
+
diff --git a/yosys-plugins/ql-qlf/pp3/ffs_map.v b/yosys-plugins/ql-qlf/pp3/ffs_map.v
new file mode 100644
index 000000000..b26e6a64b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/ffs_map.v
@@ -0,0 +1,34 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$_DFFSRE_PPPP_ (
+    input  C,
+    S,
+    R,
+    E,
+    D,
+    output Q
+);
+  wire _TECHMAP_REMOVEINIT_Q_ = 1;
+  dffepc _TECHMAP_REPLACE_ (
+      .CLK(C),
+      .PRE(S),
+      .CLR(R),
+      .EN (E),
+      .D  (D),
+      .Q  (Q)
+  );
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/latches_map.v b/yosys-plugins/ql-qlf/pp3/latches_map.v
new file mode 100644
index 000000000..514d9cdcd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/latches_map.v
@@ -0,0 +1,27 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$_DLATCH_P_ (E, D, Q);
+  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
+  input E, D;
+  output Q = E ? D : Q;
+endmodule
+
+module \$_DLATCH_N_ (E, D, Q);
+  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
+  input E, D;
+  output Q = !E ? D : Q;
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/lut_map.v b/yosys-plugins/ql-qlf/pp3/lut_map.v
new file mode 100644
index 000000000..a7b2a7cff
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/lut_map.v
@@ -0,0 +1,70 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$lut (
+    A,
+    Y
+);
+  parameter WIDTH = 0;
+  parameter LUT = 0;
+
+  input [WIDTH-1:0] A;
+  output Y;
+
+  generate
+    if (WIDTH == 1) begin
+      LUT1 #(
+          .EQN (""),
+          .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+          .O (Y),
+          .I0(A[0])
+      );
+    end else if (WIDTH == 2) begin
+      LUT2 #(
+          .EQN (""),
+          .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+          .O (Y),
+          .I0(A[0]),
+          .I1(A[1])
+      );
+    end else if (WIDTH == 3) begin
+      LUT3 #(
+          .EQN (""),
+          .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+          .O (Y),
+          .I0(A[0]),
+          .I1(A[1]),
+          .I2(A[2])
+      );
+    end else if (WIDTH == 4) begin
+      LUT4 #(
+          .EQN (""),
+          .INIT(LUT)
+      ) _TECHMAP_REPLACE_ (
+          .O (Y),
+          .I0(A[0]),
+          .I1(A[1]),
+          .I2(A[2]),
+          .I3(A[3])
+      );
+    end else begin
+      wire _TECHMAP_FAIL_ = 1;
+    end
+  endgenerate
+endmodule
diff --git a/yosys-plugins/ql-qlf/pp3/lutdefs.txt b/yosys-plugins/ql-qlf/pp3/lutdefs.txt
new file mode 100644
index 000000000..747f2a755
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/lutdefs.txt
@@ -0,0 +1,4 @@
+1 1.00 1.00
+2 2.00 1.00
+3 2.00 1.00
+4 8.00 1.00
diff --git a/yosys-plugins/ql-qlf/pp3/mult_sim.v b/yosys-plugins/ql-qlf/pp3/mult_sim.v
new file mode 100644
index 000000000..d46ddc025
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/mult_sim.v
@@ -0,0 +1,140 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+module qlal4s3_mult_32x32_cell (
+    input  [31:0] Amult,
+    input  [31:0] Bmult,
+    input  [ 1:0] Valid_mult,
+    output [63:0] Cmult
+);
+
+endmodule  /* qlal4s3_32x32_mult_cell */
+
+(* blackbox *)
+module qlal4s3_mult_16x16_cell (
+    input  [15:0] Amult,
+    input  [15:0] Bmult,
+    input         Valid_mult,
+    output [31:0] Cmult
+);
+
+endmodule  /* qlal4s3_16x16_mult_cell */
+
+
+/* Verilog model of QLAL4S3 Multiplier */
+/*qlal4s3_mult_cell*/
+module signed_mult (
+    A,
+    B,
+    Valid,
+    C
+);
+
+  parameter WIDTH = 32;
+  parameter CWIDTH = 2 * WIDTH;
+
+  input [WIDTH-1:0] A, B;
+  input Valid;
+  output [CWIDTH-1:0] C;
+
+  reg signed [WIDTH-1:0] A_q, B_q;
+  wire signed [CWIDTH-1:0] C_int;
+
+  assign C_int = A_q * B_q;
+  assign valid_int = Valid;
+  assign C = C_int;
+
+  always @(*) if (valid_int == 1'b1) A_q <= A;
+
+  always @(*) if (valid_int == 1'b1) B_q <= B;
+
+endmodule
+
+
+module qlal4s3_mult_cell_macro (
+    Amult,
+    Bmult,
+    Valid_mult,
+    sel_mul_32x32,
+    Cmult
+);
+
+  input [31:0] Amult;
+  input [31:0] Bmult;
+  input [1:0] Valid_mult;
+  input sel_mul_32x32;
+  output [63:0] Cmult;
+
+  wire [15:0] A_mult_16_0;
+  wire [15:0] B_mult_16_0;
+  wire [31:0] C_mult_16_0;
+  wire [15:0] A_mult_16_1;
+  wire [15:0] B_mult_16_1;
+  wire [31:0] C_mult_16_1;
+  wire [31:0] A_mult_32;
+  wire [31:0] B_mult_32;
+  wire [63:0] C_mult_32;
+  wire        Valid_mult_16_0;
+  wire        Valid_mult_16_1;
+  wire        Valid_mult_32;
+
+
+  assign Cmult           = sel_mul_32x32 ? C_mult_32 : {C_mult_16_1, C_mult_16_0};
+
+  assign A_mult_16_0     = sel_mul_32x32 ? 16'h0 : Amult[15:0];
+  assign B_mult_16_0     = sel_mul_32x32 ? 16'h0 : Bmult[15:0];
+  assign A_mult_16_1     = sel_mul_32x32 ? 16'h0 : Amult[31:16];
+  assign B_mult_16_1     = sel_mul_32x32 ? 16'h0 : Bmult[31:16];
+
+  assign A_mult_32       = sel_mul_32x32 ? Amult : 32'h0;
+  assign B_mult_32       = sel_mul_32x32 ? Bmult : 32'h0;
+
+  assign Valid_mult_16_0 = sel_mul_32x32 ? 1'b0 : Valid_mult[0];
+  assign Valid_mult_16_1 = sel_mul_32x32 ? 1'b0 : Valid_mult[1];
+  assign Valid_mult_32   = sel_mul_32x32 ? Valid_mult[0] : 1'b0;
+
+  signed_mult #(
+      .WIDTH(16)
+  ) u_signed_mult_16_0 (
+      .A    (A_mult_16_0),  //I: 16 bits
+      .B    (B_mult_16_0),  //I: 16 bits
+      .Valid(Valid_mult_16_0),  //I
+      .C    (C_mult_16_0)  //O: 32 bits
+  );
+
+  signed_mult #(
+      .WIDTH(16)
+  ) u_signed_mult_16_1 (
+      .A    (A_mult_16_1),  //I: 16 bits
+      .B    (B_mult_16_1),  //I: 16 bits
+      .Valid(Valid_mult_16_1),  //I
+      .C    (C_mult_16_1)  //O: 32 bits
+  );
+
+  signed_mult #(
+      .WIDTH(32)
+  ) u_signed_mult_32 (
+      .A    (A_mult_32),  //I: 32 bits
+      .B    (B_mult_32),  //I: 32 bits
+      .Valid(Valid_mult_32),  //I
+      .C    (C_mult_32)  //O: 64 bits
+  );
+
+endmodule
+/*qlal4s3_mult_cell*/
+
+
diff --git a/yosys-plugins/ql-qlf/pp3/qlal3_sim.v b/yosys-plugins/ql-qlf/pp3/qlal3_sim.v
new file mode 100644
index 000000000..c1380e5d6
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/qlal3_sim.v
@@ -0,0 +1,397 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* blackbox *)
+(* keep *)
+module qlal3_left_assp_macro (
+  input         A2F_ACK,
+  output [ 7:0] A2F_ADDR,
+  output [ 7:0] A2F_Control,
+  input  [ 7:0] A2F_GP_IN,
+  output [ 7:0] A2F_GP_OUT,
+  input  [ 7:0] A2F_RD_DATA,
+  output        A2F_REQ,
+  output        A2F_RWn,
+  input  [ 6:0] A2F_Status,
+  output [ 7:0] A2F_WR_DATA,
+  input  [31:0] Amult0,
+  input  [31:0] Bmult0,
+  output [63:0] Cmult0,
+  input  [ 8:0] RAM0_ADDR,
+  input         RAM0_CLK,
+  input         RAM0_CLKS,
+  output [35:0] RAM0_RD_DATA,
+  input         RAM0_RD_EN,
+  input         RAM0_RME_af,
+  input  [ 3:0] RAM0_RM_af,
+  input         RAM0_TEST1_af,
+  input  [ 3:0] RAM0_WR_BE,
+  input  [35:0] RAM0_WR_DATA,
+  input         RAM0_WR_EN,
+  input  [11:0] RAM8K_P0_ADDR,
+  input         RAM8K_P0_CLK,
+  input         RAM8K_P0_CLKS,
+  input  [ 1:0] RAM8K_P0_WR_BE,
+  input  [16:0] RAM8K_P0_WR_DATA,
+  input         RAM8K_P0_WR_EN,
+  input  [11:0] RAM8K_P1_ADDR,
+  input         RAM8K_P1_CLK,
+  input         RAM8K_P1_CLKS,
+  output [16:0] RAM8K_P1_RD_DATA,
+  input         RAM8K_P1_RD_EN,
+  input         RAM8K_P1_mux,
+  input         RAM8K_RME_af,
+  input  [ 3:0] RAM8K_RM_af,
+  input         RAM8K_TEST1_af,
+  output        RAM8K_fifo_almost_empty,
+  output        RAM8K_fifo_almost_full,
+  output [ 3:0] RAM8K_fifo_empty_flag,
+  input         RAM8K_fifo_en,
+  output [ 3:0] RAM8K_fifo_full_flag,
+  input         RESET_n,
+  input         RESET_nS,
+  input         SEL_18_bottom,
+  input         SEL_18_left,
+  input         SEL_18_right,
+  input         SEL_18_top,
+  input         SPI_CLK,
+  input         SPI_CLKS,
+  output        SPI_MISO,
+  output        SPI_MISOe,
+  input         SPI_MOSI,
+  input         SPI_SSn,
+  output        SYSCLK,
+  output        SYSCLK_x2,
+  input         Valid_mult0,
+  input  [ 3:0] af_burnin_mode,
+  input  [31:0] af_dev_id,
+  input         af_fpga_int_en,
+  input         af_opt_0,
+  input         af_opt_1,
+  input         \af_plat_id[0] ,
+  input         \af_plat_id[1] ,
+  input         \af_plat_id[2] ,
+  input         \af_plat_id[3] ,
+  input         \af_plat_id[4] ,
+  input         \af_plat_id[5] ,
+  input         \af_plat_id[6] ,
+  input         \af_plat_id[7] ,
+  input         af_spi_cpha,
+  input         af_spi_cpol,
+  input         af_spi_lsbf,
+  input         default_SPI_IO_mux,
+  input         drive_io_en_0,
+  input         drive_io_en_1,
+  input         drive_io_en_2,
+  input         drive_io_en_3,
+  input         drive_io_en_4,
+  input         drive_io_en_5,
+  output        fast_clk_out,
+  input  [ 7:0] int_i,
+  output        int_o,
+  input         osc_en,
+  input         osc_fsel,
+  input  [ 2:0] osc_sel,
+  input  [ 1:0] reg_addr_int,
+  input         reg_clk_int,
+  input         reg_clk_intS,
+  output [ 7:0] reg_rd_data_int,
+  input         reg_rd_en_int,
+  input  [ 7:0] reg_wr_data_int,
+  input         reg_wr_en_int
+);
+endmodule
+
+(* blackbox *)
+(* keep *)
+module qlal3_right_assp_macro (
+  input  [31:0] Amult1,
+  input  [31:0] Bmult1,
+  output [63:0] Cmult1,
+  output        DrivingI2cBusOut,
+  input  [ 8:0] RAM1_ADDR,
+  input         RAM1_CLK,
+  input         RAM1_CLKS,
+  output [35:0] RAM1_RD_DATA,
+  input         RAM1_RD_EN,
+  input         RAM1_RME_af,
+  input  [ 3:0] RAM1_RM_af,
+  input         RAM1_TEST1_af,
+  input  [ 3:0] RAM1_WR_BE,
+  input  [35:0] RAM1_WR_DATA,
+  input         RAM1_WR_EN,
+  input  [ 8:0] RAM2_P0_ADDR,
+  input         RAM2_P0_CLK,
+  input         RAM2_P0_CLKS,
+  input  [ 3:0] RAM2_P0_WR_BE,
+  input  [31:0] RAM2_P0_WR_DATA,
+  input         RAM2_P0_WR_EN,
+  input  [ 8:0] RAM2_P1_ADDR,
+  input         RAM2_P1_CLK,
+  input         RAM2_P1_CLKS,
+  output [31:0] RAM2_P1_RD_DATA,
+  input         RAM2_P1_RD_EN,
+  input         RAM2_RME_af,
+  input  [ 3:0] RAM2_RM_af,
+  input         RAM2_TEST1_af,
+  input  [ 8:0] RAM3_P0_ADDR,
+  input         RAM3_P0_CLK,
+  input         RAM3_P0_CLKS,
+  input  [31:0] RAM3_P0_WR_DATA,
+  input  [ 3:0] RAM3_P0_WR_EN,
+  input  [ 8:0] RAM3_P1_ADDR,
+  input         RAM3_P1_CLK,
+  input         RAM3_P1_CLKS,
+  output [31:0] RAM3_P1_RD_DATA,
+  input         RAM3_P1_RD_EN,
+  input         RAM3_RME_af,
+  input  [ 3:0] RAM3_RM_af,
+  input         RAM3_TEST1_af,
+  input         SCL_i,
+  output        SCL_o,
+  output        SCL_oen,
+  input         SDA_i,
+  output        SDA_o,
+  output        SDA_oen,
+  input         Valid_mult1,
+  input         al_clr_i,
+  output        al_o,
+  input         al_stick_en_i,
+  input         arst,
+  input         arstS,
+  output        i2c_busy_o,
+  input         rxack_clr_i,
+  output        rxack_o,
+  input         rxack_stick_en_i,
+  output        tip_o,
+  output        wb_ack,
+  input  [ 2:0] wb_adr,
+  input         wb_clk,
+  input         wb_clkS,
+  input         wb_cyc,
+  input  [ 7:0] wb_dat_i,
+  output [ 7:0] wb_dat_o,
+  output        wb_inta,
+  input         wb_rst,
+  input         wb_rstS,
+  input         wb_stb,
+  input         wb_we
+);
+endmodule
+
+// ============================================================================
+// Cells common to ASSPL and ASSPR
+
+(* blackbox *)
+module qlal3_mult_32x32_cell (
+  input  [31:0] Amult,
+  input  [31:0] Bmult,
+  input         Valid_mult,
+  output [63:0] Cmult
+);
+endmodule
+
+(* blackbox *)
+module qlal3_ram_512x36_cell (
+  input  [ 8:0] RAM_ADDR,
+  input         RAM_CLK,
+  input         RAM_CLKS,
+  output [35:0] RAM_RD_DATA,
+  input         RAM_RD_EN,
+  input         RAM_RME_af,
+  input  [ 3:0] RAM_RM_af,
+  input         RAM_TEST1_af,
+  input  [ 3:0] RAM_WR_BE,
+  input  [35:0] RAM_WR_DATA,
+  input         RAM_WR_EN
+);
+endmodule
+
+(* blackbox *)
+module qlal3_ram_512x32_cell (
+  input  [ 8:0] RAM_P0_ADDR,
+  input         RAM_P0_CLK,
+  input         RAM_P0_CLKS,
+  input  [ 3:0] RAM_P0_WR_BE,
+  input  [31:0] RAM_P0_WR_DATA,
+  input         RAM_P0_WR_EN,
+  input  [ 8:0] RAM_P1_ADDR,
+  input         RAM_P1_CLK,
+  input         RAM_P1_CLKS,
+  output [31:0] RAM_P1_RD_DATA,
+  input         RAM_P1_RD_EN,
+  input         RAM_RME_af,
+  input  [ 3:0] RAM_RM_af,
+  input         RAM_TEST1_af,
+);
+endmodule
+
+(* blackbox *)
+module qlal3_ram_4096x17_cell (
+  input  [11:0] RAM_P0_ADDR,
+  input         RAM_P0_CLK,
+  input         RAM_P0_CLKS,
+  input  [ 1:0] RAM_P0_WR_BE,
+  input  [16:0] RAM_P0_WR_DATA,
+  input         RAM_P0_WR_EN,
+  input  [11:0] RAM_P1_ADDR,
+  input         RAM_P1_CLK,
+  input         RAM_P1_CLKS,
+  output [16:0] RAM_P1_RD_DATA,
+  input         RAM_P1_RD_EN,
+  input         RAM_P1_mux,
+  input         RAM_RME_af,
+  input  [ 3:0] RAM_RM_af,
+  input         RAM_TEST1_af,
+  output        RAM_fifo_almost_empty,
+  output        RAM_fifo_almost_full,
+  output [ 3:0] RAM_fifo_empty_flag,
+  input         RAM_fifo_en,
+  output [ 3:0] RAM_fifo_full_flag
+);
+endmodule
+
+// ============================================================================
+// Cells specific to ASSPL
+
+(* blackbox *)
+module qlal3_spi_cell (
+  input         A2F_ACK,
+  output [ 7:0] A2F_ADDR,
+  output [ 7:0] A2F_Control,
+  input  [ 7:0] A2F_GP_IN,
+  output [ 7:0] A2F_GP_OUT,
+  input  [ 7:0] A2F_RD_DATA,
+  output        A2F_REQ,
+  output        A2F_RWn,
+  input  [ 6:0] A2F_Status,
+  output [ 7:0] A2F_WR_DATA,
+
+  input         af_spi_cpha,
+  input         af_spi_cpol,
+  input         af_spi_lsbf,
+
+  input         SPI_CLK,
+  input         SPI_CLKS,
+  output        SPI_MISO,
+  output        SPI_MISOe,
+  input         SPI_MOSI,
+  input         SPI_SSn
+);
+endmodule
+
+(* blackbox *)
+module qlal3_interrupt_controller_cell (
+  input         af_fpga_int_en,
+  input  [ 7:0] int_i,
+  output        int_o,
+
+  input  [ 1:0] reg_addr_int,
+  input         reg_clk_int,
+  input         reg_clk_intS,
+  output [ 7:0] reg_rd_data_int,
+  input         reg_rd_en_int,
+  input  [ 7:0] reg_wr_data_int,
+  input         reg_wr_en_int
+);
+endmodule
+
+(* blackbox *)
+module qlal3_oscillator_cell (
+  input         osc_en,
+  input         osc_fsel,
+  input  [ 2:0] osc_sel,
+  output        fast_clk_out
+);
+endmodule
+
+(* blackbox *)
+module qlal3_io_control_cell (
+  input         default_SPI_IO_mux,
+  input         drive_io_en_0,
+  input         drive_io_en_1,
+  input         drive_io_en_2,
+  input         drive_io_en_3,
+  input         drive_io_en_4,
+  input         drive_io_en_5
+);
+endmodule
+
+(* blackbox *)
+module qlal3_system_cell (
+  input         RESET_n,
+  input         RESET_nS,
+  input         SEL_18_bottom,
+  input         SEL_18_left,
+  input         SEL_18_right,
+  input         SEL_18_top,
+  output        SYSCLK,
+  output        SYSCLK_x2,
+  input  [ 3:0] af_burnin_mode,
+  input  [31:0] af_dev_id,
+  input         af_opt_0,
+  input         af_opt_1,
+  input         \af_plat_id[0] ,
+  input         \af_plat_id[1] ,
+  input         \af_plat_id[2] ,
+  input         \af_plat_id[3] ,
+  input         \af_plat_id[4] ,
+  input         \af_plat_id[5] ,
+  input         \af_plat_id[6] ,
+  input         \af_plat_id[7]
+);
+endmodule
+
+// ============================================================================
+// Cells specific to ASSPR
+
+(* blackbox *)
+module qlal3_i2c_cell (
+  input         arst,
+  input         arstS,
+
+  output        wb_ack,
+  input  [ 2:0] wb_adr,
+  input         wb_clk,
+  input         wb_clkS,
+  input         wb_cyc,
+  input  [ 7:0] wb_dat_i,
+  output [ 7:0] wb_dat_o,
+  output        wb_inta,
+  input         wb_rst,
+  input         wb_rstS,
+  input         wb_stb,
+  input         wb_we,
+
+  input         al_clr_i,
+  output        al_o,
+  input         al_stick_en_i,
+  output        i2c_busy_o,
+  input         rxack_clr_i,
+  output        rxack_o,
+  input         rxack_stick_en_i,
+  output        tip_o,
+  output        DrivingI2cBusOut,
+
+  input         SCL_i,
+  output        SCL_o,
+  output        SCL_oen,
+  input         SDA_i,
+  output        SDA_o,
+  output        SDA_oen
+);
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/pp3/qlal4s3b_sim.v b/yosys-plugins/ql-qlf/pp3/qlal4s3b_sim.v
new file mode 100644
index 000000000..39184a89d
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3/qlal4s3b_sim.v
@@ -0,0 +1,2493 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns / 10ps
+module ahb_gen_bfm (
+
+    // AHB Slave Interface to AHB Bus Matrix
+    //
+    A2F_HCLK,
+    A2F_HRESET,
+
+    A2F_HADDRS,
+    A2F_HSEL,
+    A2F_HTRANSS,
+    A2F_HSIZES,
+    A2F_HWRITES,
+    A2F_HREADYS,
+    A2F_HWDATAS,
+
+    A2F_HREADYOUTS,
+    A2F_HRESPS,
+    A2F_HRDATAS
+
+);
+
+  //------Port Parameters----------------
+  //
+
+  parameter ADDRWIDTH = 32;
+  parameter DATAWIDTH = 32;
+
+  //
+  // Define the default address between transfers
+  //
+  parameter DEFAULT_AHB_ADDRESS = {(ADDRWIDTH) {1'b1}};
+
+  //
+  // Define the standard delay from clock
+  //
+  parameter STD_CLK_DLY = 2;
+
+  //
+  // Define Debug Message Controls
+  //
+  parameter ENABLE_AHB_REG_WR_DEBUG_MSG = 1'b1;
+  parameter ENABLE_AHB_REG_RD_DEBUG_MSG = 1'b1;
+
+  //
+  // Define the size of the message arrays
+  //
+  parameter TEST_MSG_ARRAY_SIZE = (64 * 8);
+
+
+  //------Port Signals-------------------
+  //
+
+  // AHB connection to master
+  //
+  input A2F_HCLK;
+  input A2F_HRESET;
+
+  output [ADDRWIDTH-1:0] A2F_HADDRS;
+  output A2F_HSEL;
+  output [1:0] A2F_HTRANSS;
+  output [2:0] A2F_HSIZES;
+  output A2F_HWRITES;
+  output A2F_HREADYS;
+  output [DATAWIDTH-1:0] A2F_HWDATAS;
+
+  input A2F_HREADYOUTS;
+  input A2F_HRESPS;
+  input [DATAWIDTH-1:0] A2F_HRDATAS;
+
+
+  wire                           A2F_HCLK;
+  wire                           A2F_HRESET;
+
+  reg  [          ADDRWIDTH-1:0] A2F_HADDRS;
+  reg                            A2F_HSEL;
+  reg  [                    1:0] A2F_HTRANSS;
+  reg  [                    2:0] A2F_HSIZES;
+  reg                            A2F_HWRITES;
+  reg                            A2F_HREADYS;
+  reg  [          DATAWIDTH-1:0] A2F_HWDATAS;
+
+  wire                           A2F_HREADYOUTS;
+  wire                           A2F_HRESPS;
+  wire [          DATAWIDTH-1:0] A2F_HRDATAS;
+
+
+  //------Define Parameters--------------
+  //
+
+  //
+  // None at this time
+  //
+
+  //------Internal Signals---------------
+  //
+
+  //	Define internal signals
+  //
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg1;  // Bus used for depositing test messages in ASCI
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg2;  // Bus used for depositing test messages in ASCI
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg3;  // Bus used for depositing test messages in ASCI
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg4;  // Bus used for depositing test messages in ASCI
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg5;  // Bus used for depositing test messages in ASCI
+  reg  [TEST_MSG_ARRAY_SIZE-1:0] ahb_bfm_msg6;  // Bus used for depositing test messages in ASCI
+
+
+  //------Logic Operations---------------
+  //
+
+  // Define the intial state of key signals
+  //
+  initial begin
+
+    A2F_HADDRS   <= DEFAULT_AHB_ADDRESS;  // Default Address
+    A2F_HSEL     <= 1'b0;  // Bridge not selected
+    A2F_HTRANSS  <= 2'h0;  // "IDLE" State
+    A2F_HSIZES   <= 3'h0;  // "Byte" Transfer Size
+    A2F_HWRITES  <= 1'b0;  // "Read" operation
+    A2F_HREADYS  <= 1'b0;  // Slave is not ready
+    A2F_HWDATAS  <= {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+    ahb_bfm_msg1 <= "NO ACTIVITY";  // Bus used for depositing test messages in ASCI
+    ahb_bfm_msg2 <= "NO ACTIVITY";  // Bus used for depositing test messages in ASCI
+    ahb_bfm_msg3 <= "NO ACTIVITY";  // Bus used for depositing test messages in ASCI
+    ahb_bfm_msg4 <= "NO ACTIVITY";  // Bus used for depositing test messages in ASCI
+    ahb_bfm_msg5 <= "NO ACTIVITY";  // Bus used for depositiog test messages in ASCI
+    ahb_bfm_msg6 <= "NO ACTIVITY";  // Bus used for depositiog test messages in ASCI
+  end
+
+
+  //------Instantiate Modules------------
+  //
+
+  //
+  // None at this time
+  //
+
+
+  //------BFM Routines-------------------
+  //
+`ifndef YOSYS
+  task ahb_read_al4s3b_fabric;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    input [2:0] TARGET_XFR_SIZE;  //        Transfer Size for AHB bus
+    output [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Read";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      A2F_HADDRS   = TARGET_ADDRESS;  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL     = 1'b1;  // Bridge   selected
+      A2F_HREADYS  = 1'b1;  // Slave is ready
+      A2F_HTRANSS  = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES   = TARGET_XFR_SIZE;  // Transfer Size
+
+      A2F_HWRITES  = 1'b0;  // "Read"  operation
+      A2F_HWDATAS  = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+    end
+  endtask
+
+
+  task ahb_write_al4s3b_fabric;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    input [2:0] TARGET_XFR_SIZE;  //        Transfer Size for AHB bus
+    input [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Write";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      A2F_HADDRS   = TARGET_ADDRESS;  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL     = 1'b1;  // Bridge   selected
+      A2F_HREADYS  = 1'b1;  // Slave is ready
+      A2F_HTRANSS  = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES   = TARGET_XFR_SIZE;  // Transfer Size
+
+      A2F_HWRITES  = 1'b1;  // "Write"  operation
+      A2F_HWDATAS  = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+      A2F_HWDATAS  = TARGET_DATA;  // Write From test routine
+      A2F_HWRITES  = 1'b0;  // "Read"  operation
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+    end
+  endtask
+
+  task ahb_read_word_al4s3b_fabric;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    output [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+
+      wait(A2F_HRESET == 0);
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Read";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      A2F_HADDRS   = TARGET_ADDRESS;  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL     = 1'b1;  // Bridge   selected
+      A2F_HREADYS  = 1'b1;  // Slave is ready
+      A2F_HTRANSS  = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES   = 3'b010;  // Transfer Size
+
+      A2F_HWRITES  = 1'b0;  // "Read"  operation
+      A2F_HWDATAS  = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+    end
+  endtask
+
+
+  task ahb_write_word_al4s3b_fabric;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    input [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+      wait(A2F_HRESET == 0);
+
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Write";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      A2F_HADDRS   = TARGET_ADDRESS;  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL     = 1'b1;  // Bridge   selected
+      A2F_HREADYS  = 1'b1;  // Slave is ready
+      A2F_HTRANSS  = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES   = 3'b010;  // Transfer Size
+
+      A2F_HWRITES  = 1'b1;  // "Write"  operation
+      A2F_HWDATAS  = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+      A2F_HWDATAS  = TARGET_DATA;  // Write From test routine
+      A2F_HWRITES  = 1'b0;  // "Read"  operation
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+      //$stop();
+
+    end
+  endtask
+
+  task ahb_write_al4s3b_fabric_mod;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    input [2:0] TARGET_XFR_SIZE;  //        Transfer Size for AHB bus
+    input [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Write";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      //A2F_HADDRS    =  TARGET_ADDRESS;       // Transfer Address
+      A2F_HADDRS = {
+        TARGET_ADDRESS[ADDRWIDTH-1:11], (TARGET_ADDRESS[10:0] << 2)
+      };  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL = 1'b1;  // Bridge   selected
+      A2F_HREADYS = 1'b1;  // Slave is ready
+      A2F_HTRANSS = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES = TARGET_XFR_SIZE;  // Transfer Size
+
+      A2F_HWRITES = 1'b1;  // "Write"  operation
+      A2F_HWDATAS = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+      A2F_HWDATAS  = TARGET_DATA;  // Write From test routine
+      A2F_HWRITES  = 1'b0;  // "Read"  operation
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+    end
+  endtask
+
+
+  task ahb_read_al4s3b_fabric_mod;
+    input [ADDRWIDTH-1:0] TARGET_ADDRESS;  //        Address to be written on the SPI bus
+    input [2:0] TARGET_XFR_SIZE;  //        Transfer Size for AHB bus
+    output [DATAWIDTH-1:0] TARGET_DATA;  //        Data    to be written on the SPI bus
+
+    reg [DATAWIDTH-1:0] read_data;
+
+    integer i, j, k;
+
+    begin
+      // Read Command Bit
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      // Issue Diagnostic Messages
+      //
+      ahb_bfm_msg1 = "AHB Single Read";
+      ahb_bfm_msg2 = "Address Phase";
+      ahb_bfm_msg3 = "SEQ";
+
+      //A2F_HADDRS    =  TARGET_ADDRESS;       // Transfer Address
+      A2F_HADDRS = {
+        TARGET_ADDRESS[ADDRWIDTH-1:11], (TARGET_ADDRESS[10:0] << 2)
+      };  // Transfer Address
+
+      // Define the Transfer Request
+      //
+      // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+      //                     -------------  -------------  ------------------------------------
+      //                          0             0            IDLE               (No Transfer)
+      //                          0             1            BUSY               (No Transfer)
+      //                          1             0            NONSEQ             (Do Transfer)
+      //                          1             1            SEQ                (Do Transfer)
+      //
+      // Transfer decode of: A2F_HREADYS                   Description
+      //                     -----------                   ------------------------------------
+      //                          0                          Slave is not ready (No Transfer)
+      //                          1                          Slave is     ready (Do Transfer)
+      //
+      A2F_HSEL = 1'b1;  // Bridge   selected
+      A2F_HREADYS = 1'b1;  // Slave is ready
+      A2F_HTRANSS = 2'h2;  // "NONSEQ" State
+
+      //
+      // Define "Transfer Size Encoding" is based on the following:
+      //
+      //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+      //       --------  --------  --------  ----  -----------
+      //          0         0         0         8  Byte
+      //          0         0         1        16  Halfword
+      //          0         1         0        32  Word
+      //          0         1         1        64  Doublword
+      //          1         0         0       128  4-word line
+      //          1         0         1       256  8-word line
+      //          1         1         0       512  -
+      //          1         1         1      1024  -
+      //
+      //       The fabric design only supports up to 32 bits at a time.
+      //
+      A2F_HSIZES = TARGET_XFR_SIZE;  // Transfer Size
+
+      A2F_HWRITES = 1'b0;  // "Read"  operation
+      A2F_HWDATAS = {(DATAWIDTH) {1'b0}};  // Write Data Value of "0"
+
+      //
+      // Wait for next clock to sampe the slave's response
+      //
+      @(posedge A2F_HCLK) #STD_CLK_DLY;
+
+      ahb_bfm_msg2 = "Data Phase";
+      ahb_bfm_msg3 = "IDLE";
+      ahb_bfm_msg4 = "Waiting for Slave";
+
+      // Set the next transfer cycle to "IDLE"
+      A2F_HADDRS   = DEFAULT_AHB_ADDRESS;  // Default Address
+      A2F_HSEL     = 1'b0;  // Bridge not selected
+      A2F_HTRANSS  = 2'h0;  // "IDLE" State
+      A2F_HSIZES   = 3'h0;  // "Byte" Transfer Size
+
+      //
+      // Check if the slave has returend data
+      //
+      while (A2F_HREADYOUTS == 1'b0) begin
+        @(posedge A2F_HCLK) #STD_CLK_DLY;
+      end
+
+      A2F_HREADYS = 1'b0;  // Slave is not ready
+      TARGET_DATA = A2F_HRDATAS;  // Read slave data value
+
+      // Clear Diagnostic Messages
+      //
+      ahb_bfm_msg1 <= "NO ACTIVITY";
+      ahb_bfm_msg2 <= "NO ACTIVITY";
+      ahb_bfm_msg3 <= "NO ACTIVITY";
+      ahb_bfm_msg4 <= "NO ACTIVITY";
+      ahb_bfm_msg5 <= "NO ACTIVITY";
+      ahb_bfm_msg6 <= "NO ACTIVITY";
+
+    end
+  endtask
+`endif
+
+endmodule
+
+`timescale 1ns / 10ps
+
+module oscillator_s1 (
+
+    OSC_CLK_EN,
+    OSC_CLK
+
+);
+
+  //	Define the oscillator's frequency
+  //
+  //	Note:	The parameter above assumes that values are calculated in units of nS.
+  //
+  parameter T_CYCLE_CLK = (1000.0 / 19.2);
+
+  input OSC_CLK_EN;
+  output OSC_CLK;
+
+  wire OSC_CLK_EN;
+  wire OSC_CLK;
+
+  reg  osc_int_clk;
+
+  //	Define the output enable
+  //
+  assign OSC_CLK = OSC_CLK_EN ? osc_int_clk : 1'bZ;
+
+  // Define the clock oscillator section
+  //
+  initial begin
+    osc_int_clk = 0;  // Intialize the clock at time 0ns.
+`ifndef YOSYS
+    forever				// Generate a clock with an expected frequency.
+	begin
+      #(T_CYCLE_CLK / 2) osc_int_clk = 1;
+      #(T_CYCLE_CLK / 2) osc_int_clk = 0;
+    end
+`endif
+  end
+
+endmodule
+
+`timescale 1ns / 10ps
+
+module sdma_bfm (
+
+    // SDMA Interface Signals
+    //
+    sdma_req_i,
+    sdma_sreq_i,
+    sdma_done_o,
+    sdma_active_o
+
+);
+
+  input [3:0] sdma_req_i;
+  input [3:0] sdma_sreq_i;
+  output [3:0] sdma_done_o;
+  output [3:0] sdma_active_o;
+
+  reg [3:0] sdma_done_sig;
+  reg [3:0] sdma_active_sig;
+
+  assign sdma_done_o   = sdma_done_sig;
+  assign sdma_active_o = sdma_active_sig;
+
+  initial begin
+    sdma_done_sig   <= 4'h0;
+    sdma_active_sig <= 4'h0;
+
+  end
+
+`ifndef YOSYS
+  task drive_dma_active;
+    input [3:0] dma_active_i;
+    begin
+      sdma_active_sig <= dma_active_i;
+      #100;
+      //sdma_active_sig <= 4'h0;
+
+    end
+  endtask
+`endif
+endmodule
+
+`timescale 1ns / 10ps
+module ahb2fb_asynbrig_if (
+
+    A2F_HCLK,  // clock
+    A2F_HRESET,  // reset
+
+    // AHB connection to master
+    //
+    A2F_HSEL,
+    A2F_HADDRS,
+    A2F_HTRANSS,
+    A2F_HSIZES,
+    A2F_HWRITES,
+    A2F_HREADYS,
+
+    A2F_HREADYOUTS,
+    A2F_HRESPS,
+
+    // Fabric Interface
+    //
+    AHB_ASYNC_ADDR_O,
+    AHB_ASYNC_READ_EN_O,
+    AHB_ASYNC_WRITE_EN_O,
+    AHB_ASYNC_BYTE_STROBE_O,
+
+    AHB_ASYNC_STB_TOGGLE_O,
+
+    FABRIC_ASYNC_ACK_TOGGLE_I
+
+);
+
+
+  //-----Port Parameters-----------------
+  //
+
+  parameter DATAWIDTH = 32;
+  parameter APERWIDTH = 17;
+
+  parameter STATE_WIDTH = 1;
+
+  parameter AHB_ASYNC_IDLE = 0;
+  parameter AHB_ASYNC_WAIT = 1;
+
+
+  //-----Port Signals--------------------
+  //
+
+
+  //------------------------------------------
+  // AHB connection to master
+  //
+  input A2F_HCLK;  // clock
+  input A2F_HRESET;  // reset
+
+  input [APERWIDTH-1:0] A2F_HADDRS;
+  input A2F_HSEL;
+  input [1:0] A2F_HTRANSS;
+  input [2:0] A2F_HSIZES;
+  input A2F_HWRITES;
+  input A2F_HREADYS;
+
+  output A2F_HREADYOUTS;
+  output A2F_HRESPS;
+
+
+  //------------------------------------------
+  // Fabric Interface
+  //
+  output [APERWIDTH-1:0] AHB_ASYNC_ADDR_O;
+  output AHB_ASYNC_READ_EN_O;
+  output AHB_ASYNC_WRITE_EN_O;
+  output [3:0] AHB_ASYNC_BYTE_STROBE_O;
+
+  output AHB_ASYNC_STB_TOGGLE_O;
+
+  input FABRIC_ASYNC_ACK_TOGGLE_I;
+
+
+  //------------------------------------------
+  // AHB connection to master
+  //
+  wire                   A2F_HCLK;  // clock
+  wire                   A2F_HRESET;  // reset
+
+  wire [  APERWIDTH-1:0] A2F_HADDRS;
+  wire                   A2F_HSEL;
+  wire [            1:0] A2F_HTRANSS;
+  wire [            2:0] A2F_HSIZES;
+  wire                   A2F_HWRITES;
+  wire                   A2F_HREADYS;
+
+  reg                    A2F_HREADYOUTS;
+  reg                    A2F_HREADYOUTS_nxt;
+
+  wire                   A2F_HRESPS;
+
+
+  //------------------------------------------
+  // Fabric Interface
+  //
+  reg  [  APERWIDTH-1:0] AHB_ASYNC_ADDR_O;
+  reg                    AHB_ASYNC_READ_EN_O;
+  reg                    AHB_ASYNC_WRITE_EN_O;
+
+  reg  [            3:0] AHB_ASYNC_BYTE_STROBE_O;
+  reg  [            3:0] AHB_ASYNC_BYTE_STROBE_O_nxt;
+
+
+
+  reg                    AHB_ASYNC_STB_TOGGLE_O;
+  reg                    AHB_ASYNC_STB_TOGGLE_O_nxt;
+
+  wire                   FABRIC_ASYNC_ACK_TOGGLE_I;
+
+
+  //------Define Parameters---------
+  //
+
+  //
+  // None at this time
+  //
+
+
+  //-----Internal Signals--------------------
+  //
+
+  wire                   trans_req;  // transfer request 
+
+  reg  [STATE_WIDTH-1:0] ahb_to_fabric_state;
+  reg  [STATE_WIDTH-1:0] ahb_to_fabric_state_nxt;
+
+  reg                    fabric_async_ack_toggle_i_1ff;
+  reg                    fabric_async_ack_toggle_i_2ff;
+  reg                    fabric_async_ack_toggle_i_3ff;
+
+  wire                   fabric_async_ack;
+
+  //------Logic Operations----------
+  //
+
+
+  // Define the Transfer Request
+  //
+  // Transfer decode of: A2F_HTRANS[1]  A2F_HTRANS[0]  Description
+  //                     -------------  -------------  ------------------------------------
+  //                          0             0            IDLE               (No Transfer)
+  //                          0             1            BUSY               (No Transfer)
+  //                          1             0            NONSEQ             (Do Transfer)
+  //                          1             1            SEQ                (Do Transfer)
+  //
+  // Transfer decode of: A2F_HREADYS                   Description
+  //                     -----------                   ------------------------------------
+  //                          0                          Slave is not ready (No Transfer)
+  //                          1                          Slave is     ready (Do Transfer)
+  //
+  assign trans_req        =   A2F_HSEL
+	                        &   A2F_HREADYS 
+						    &   A2F_HTRANSS[1]; // transfer request issued only in SEQ and NONSEQ status and slave is
+  // selected and last transfer finish
+
+
+  // Check for acknowldge from the fabric
+  //
+  // Note: The fabric is on a different and potentially asynchronous clock.
+  //       Therefore, acknowledge is passed as a toggle signal.
+  //
+  assign fabric_async_ack = fabric_async_ack_toggle_i_2ff ^ fabric_async_ack_toggle_i_3ff;
+
+
+  // Issue transfer status
+  //
+  // Note: All transfers are considered to have completed successfully.
+  //
+  assign A2F_HRESPS = 1'b0;  // OKAY response from slave
+
+
+  // Address signal registering, to make the address and data active at the same cycle
+  //
+  always @(posedge A2F_HCLK or posedge A2F_HRESET) begin
+    if (A2F_HRESET) begin
+      ahb_to_fabric_state           <= AHB_ASYNC_IDLE;
+
+      AHB_ASYNC_ADDR_O              <= {(APERWIDTH) {1'b0}};  //default address 0 is selected
+      AHB_ASYNC_READ_EN_O           <= 1'b0;
+      AHB_ASYNC_WRITE_EN_O          <= 1'b0;
+      AHB_ASYNC_BYTE_STROBE_O       <= 4'b0;
+
+      AHB_ASYNC_STB_TOGGLE_O        <= 1'b0;
+
+      fabric_async_ack_toggle_i_1ff <= 1'b0;
+      fabric_async_ack_toggle_i_2ff <= 1'b0;
+      fabric_async_ack_toggle_i_3ff <= 1'b0;
+
+      A2F_HREADYOUTS                <= 1'b0;
+    end else begin
+      ahb_to_fabric_state <= ahb_to_fabric_state_nxt;
+
+      if (trans_req) begin
+        AHB_ASYNC_ADDR_O        <= A2F_HADDRS[APERWIDTH-1:0];
+        AHB_ASYNC_READ_EN_O     <= ~A2F_HWRITES;
+        AHB_ASYNC_WRITE_EN_O    <= A2F_HWRITES;
+        AHB_ASYNC_BYTE_STROBE_O <= AHB_ASYNC_BYTE_STROBE_O_nxt;
+      end
+
+      AHB_ASYNC_STB_TOGGLE_O        <= AHB_ASYNC_STB_TOGGLE_O_nxt;
+
+      fabric_async_ack_toggle_i_1ff <= FABRIC_ASYNC_ACK_TOGGLE_I;
+      fabric_async_ack_toggle_i_2ff <= fabric_async_ack_toggle_i_1ff;
+      fabric_async_ack_toggle_i_3ff <= fabric_async_ack_toggle_i_2ff;
+
+      A2F_HREADYOUTS                <= A2F_HREADYOUTS_nxt;
+    end
+  end
+
+
+  // Byte Strobe Signal Decode
+  //
+  // Note: The "Transfer Size Encoding" is defined as follows:
+  //
+  //       HSIZE[2]  HSIZE[1]  HSIZE[0]  Bits  Description
+  //       --------  --------  --------  ----  -----------
+  //          0         0         0         8  Byte
+  //          0         0         1        16  Halfword
+  //          0         1         0        32  Word
+  //          0         1         1        64  Doublword
+  //          1         0         0       128  4-word line
+  //          1         0         1       256  8-word line
+  //          1         1         0       512  -
+  //          1         1         1      1024  -
+  //
+  //       The fabric design only supports up to 32 bits at a time.
+  //
+  always @(A2F_HSIZES or A2F_HADDRS) begin
+    case (A2F_HSIZES)
+      3'b000:                                  //byte
+        begin
+        case (A2F_HADDRS[1:0])
+          2'b00:   AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0001;
+          2'b01:   AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0010;
+          2'b10:   AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0100;
+          2'b11:   AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b1000;
+          default: AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0000;
+        endcase
+      end
+      3'b001:                                  //half word
+        begin
+        case (A2F_HADDRS[1])
+          1'b0:    AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0011;
+          1'b1:    AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b1100;
+          default: AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b0000;
+        endcase
+      end
+      default: AHB_ASYNC_BYTE_STROBE_O_nxt <= 4'b1111;  // default 32 bits, word
+    endcase
+  end
+
+
+  // Define the AHB Interface Statemachine
+  //
+  always @(trans_req or fabric_async_ack or AHB_ASYNC_STB_TOGGLE_O or ahb_to_fabric_state) begin
+    case (ahb_to_fabric_state)
+      AHB_ASYNC_IDLE: begin
+        case (trans_req)
+          1'b0:  // Wait for an AHB Transfer
+            begin
+            ahb_to_fabric_state_nxt    <= AHB_ASYNC_IDLE;
+            A2F_HREADYOUTS_nxt         <= 1'b1;
+            AHB_ASYNC_STB_TOGGLE_O_nxt <= AHB_ASYNC_STB_TOGGLE_O;
+          end
+          1'b1:  // AHB Transfer Detected
+            begin
+            ahb_to_fabric_state_nxt    <= AHB_ASYNC_WAIT;
+            A2F_HREADYOUTS_nxt         <= 1'b0;
+            AHB_ASYNC_STB_TOGGLE_O_nxt <= ~AHB_ASYNC_STB_TOGGLE_O;
+          end
+        endcase
+      end
+      AHB_ASYNC_WAIT: begin
+        AHB_ASYNC_STB_TOGGLE_O_nxt <= AHB_ASYNC_STB_TOGGLE_O;
+
+        case (fabric_async_ack)
+          1'b0:  // Wait for Acknowledge from Fabric Interface
+            begin
+            ahb_to_fabric_state_nxt <= AHB_ASYNC_WAIT;
+            A2F_HREADYOUTS_nxt      <= 1'b0;
+          end
+          1'b1:  // Received Acknowledge from Fabric Interface
+            begin
+            ahb_to_fabric_state_nxt <= AHB_ASYNC_IDLE;
+            A2F_HREADYOUTS_nxt      <= 1'b1;
+          end
+        endcase
+      end
+      default: begin
+        ahb_to_fabric_state_nxt    <= AHB_ASYNC_IDLE;
+        A2F_HREADYOUTS_nxt         <= 1'b0;
+        AHB_ASYNC_STB_TOGGLE_O_nxt <= AHB_ASYNC_STB_TOGGLE_O;
+      end
+    endcase
+  end
+
+endmodule
+
+`timescale 1ns / 10ps
+
+module fb2ahb_asynbrig_if (
+
+    A2F_HRDATAS,
+
+    // AHB Interface
+    //
+    AHB_ASYNC_READ_EN_I,
+    AHB_ASYNC_WRITE_EN_I,
+    AHB_ASYNC_BYTE_STROBE_I,
+
+    AHB_ASYNC_STB_TOGGLE_I,
+
+    // Fabric Interface
+    //
+    WB_CLK_I,
+    WB_RST_I,
+    WB_ACK_I,
+    WB_DAT_I,
+
+    WB_CYC_O,
+    WB_BYTE_STB_O,
+    WB_WE_O,
+    WB_RD_O,
+    WB_STB_O,
+
+    FABRIC_ASYNC_ACK_TOGGLE_O
+
+);
+
+
+  //-----Port Parameters-----------------
+  //
+
+  parameter DATAWIDTH = 32;
+
+  parameter STATE_WIDTH = 1;
+
+  parameter FAB_ASYNC_IDLE = 0;
+  parameter FAB_ASYNC_WAIT = 1;
+
+
+  //-----Port Signals--------------------
+  //
+
+
+  //------------------------------------------
+  // AHB connection to master
+  //
+  output [DATAWIDTH-1:0] A2F_HRDATAS;
+
+
+  //------------------------------------------
+  // Fabric Interface
+  //
+  input AHB_ASYNC_READ_EN_I;
+  input AHB_ASYNC_WRITE_EN_I;
+  input [3:0] AHB_ASYNC_BYTE_STROBE_I;
+
+  input AHB_ASYNC_STB_TOGGLE_I;
+
+
+  input WB_CLK_I;
+  input WB_RST_I;
+  input WB_ACK_I;
+  input [DATAWIDTH-1:0] WB_DAT_I;
+
+  output WB_CYC_O;
+  output [3:0] WB_BYTE_STB_O;
+  output WB_WE_O;
+  output WB_RD_O;
+  output WB_STB_O;
+
+  output FABRIC_ASYNC_ACK_TOGGLE_O;
+
+
+  //------------------------------------------
+  // AHB connection to master
+  //
+
+  reg  [  DATAWIDTH-1:0] A2F_HRDATAS;
+  reg  [  DATAWIDTH-1:0] A2F_HRDATAS_nxt;
+
+
+  //------------------------------------------
+  // Fabric Interface
+  //
+  wire                   AHB_ASYNC_READ_EN_I;
+  wire                   AHB_ASYNC_WRITE_EN_I;
+
+  wire [            3:0] AHB_ASYNC_BYTE_STROBE_I;
+
+  wire                   AHB_ASYNC_STB_TOGGLE_I;
+
+
+  wire                   WB_CLK_I;
+  wire                   WB_RST_I;
+  wire                   WB_ACK_I;
+
+  reg                    WB_CYC_O;
+  reg                    WB_CYC_O_nxt;
+
+  reg  [            3:0] WB_BYTE_STB_O;
+  reg  [            3:0] WB_BYTE_STB_O_nxt;
+
+  reg                    WB_WE_O;
+  reg                    WB_WE_O_nxt;
+
+  reg                    WB_RD_O;
+  reg                    WB_RD_O_nxt;
+
+  reg                    WB_STB_O;
+  reg                    WB_STB_O_nxt;
+
+  reg                    FABRIC_ASYNC_ACK_TOGGLE_O;
+  reg                    FABRIC_ASYNC_ACK_TOGGLE_O_nxt;
+
+
+  //------Define Parameters---------
+  //
+
+  //
+  // None at this time
+  //
+
+
+  //-----Internal Signals--------------------
+  //
+
+  reg  [STATE_WIDTH-1:0] fabric_to_ahb_state;
+  reg  [STATE_WIDTH-1:0] fabric_to_ahb_state_nxt;
+
+  reg                    ahb_async_stb_toggle_i_1ff;
+  reg                    ahb_async_stb_toggle_i_2ff;
+  reg                    ahb_async_stb_toggle_i_3ff;
+
+  wire                   ahb_async_stb;
+
+
+  //------Logic Operations----------
+  //
+
+
+  // Check for transfer from the AHB
+  //
+  // Note: The AHB is on a different and potentially asynchronous clock.
+  //       Therefore, strobe is passed as a toggle signal.
+  //
+  assign ahb_async_stb = ahb_async_stb_toggle_i_2ff ^ ahb_async_stb_toggle_i_3ff;
+
+
+  // Address signal registering, to make the address and data active at the same cycle
+  //
+  always @(posedge WB_CLK_I or posedge WB_RST_I) begin
+    if (WB_RST_I) begin
+      fabric_to_ahb_state        <= FAB_ASYNC_IDLE;
+
+      A2F_HRDATAS                <= {(DATAWIDTH) {1'b0}};
+
+      WB_CYC_O                   <= 1'b0;
+      WB_BYTE_STB_O              <= 4'b0;
+      WB_WE_O                    <= 1'b0;
+      WB_RD_O                    <= 1'b0;
+      WB_STB_O                   <= 1'b0;
+
+      FABRIC_ASYNC_ACK_TOGGLE_O  <= 1'b0;
+
+      ahb_async_stb_toggle_i_1ff <= 1'b0;
+      ahb_async_stb_toggle_i_2ff <= 1'b0;
+      ahb_async_stb_toggle_i_3ff <= 1'b0;
+
+    end else begin
+
+      fabric_to_ahb_state        <= fabric_to_ahb_state_nxt;
+
+      A2F_HRDATAS                <= A2F_HRDATAS_nxt;
+
+      WB_CYC_O                   <= WB_CYC_O_nxt;
+      WB_BYTE_STB_O              <= WB_BYTE_STB_O_nxt;
+      WB_WE_O                    <= WB_WE_O_nxt;
+      WB_RD_O                    <= WB_RD_O_nxt;
+      WB_STB_O                   <= WB_STB_O_nxt;
+
+      FABRIC_ASYNC_ACK_TOGGLE_O  <= FABRIC_ASYNC_ACK_TOGGLE_O_nxt;
+
+      ahb_async_stb_toggle_i_1ff <= AHB_ASYNC_STB_TOGGLE_I;
+      ahb_async_stb_toggle_i_2ff <= ahb_async_stb_toggle_i_1ff;
+      ahb_async_stb_toggle_i_3ff <= ahb_async_stb_toggle_i_2ff;
+
+    end
+  end
+
+
+  // Define the Fabric Interface Statemachine
+  //
+  always @(
+            ahb_async_stb             or
+            AHB_ASYNC_READ_EN_I       or
+            AHB_ASYNC_WRITE_EN_I      or
+            AHB_ASYNC_BYTE_STROBE_I   or
+            A2F_HRDATAS               or
+            WB_ACK_I                  or
+            WB_DAT_I                  or
+            WB_CYC_O                  or
+            WB_BYTE_STB_O             or
+            WB_WE_O                   or
+            WB_RD_O                   or
+            WB_STB_O                  or
+            FABRIC_ASYNC_ACK_TOGGLE_O or
+            fabric_to_ahb_state
+    )
+    begin
+    case (fabric_to_ahb_state)
+      FAB_ASYNC_IDLE: begin
+        FABRIC_ASYNC_ACK_TOGGLE_O_nxt <= FABRIC_ASYNC_ACK_TOGGLE_O;
+        A2F_HRDATAS_nxt               <= A2F_HRDATAS;
+
+        case (ahb_async_stb)
+          1'b0:  // Wait for an AHB Transfer
+            begin
+            fabric_to_ahb_state_nxt <= FAB_ASYNC_IDLE;
+
+            WB_CYC_O_nxt            <= 1'b0;
+            WB_BYTE_STB_O_nxt       <= 4'b0;
+            WB_WE_O_nxt             <= 1'b0;
+            WB_RD_O_nxt             <= 1'b0;
+            WB_STB_O_nxt            <= 1'b0;
+
+          end
+          1'b1:  // AHB Transfer Detected
+            begin
+            fabric_to_ahb_state_nxt <= FAB_ASYNC_WAIT;
+
+            WB_CYC_O_nxt            <= 1'b1;
+            WB_BYTE_STB_O_nxt       <= AHB_ASYNC_BYTE_STROBE_I;
+            WB_WE_O_nxt             <= AHB_ASYNC_WRITE_EN_I;
+            WB_RD_O_nxt             <= AHB_ASYNC_READ_EN_I;
+            WB_STB_O_nxt            <= 1'b1;
+
+          end
+        endcase
+      end
+      FAB_ASYNC_WAIT: begin
+
+        case (WB_ACK_I)
+          1'b0:  // Wait for Acknowledge from Fabric Interface
+            begin
+            fabric_to_ahb_state_nxt       <= FAB_ASYNC_WAIT;
+
+            A2F_HRDATAS_nxt               <= A2F_HRDATAS;
+
+            WB_CYC_O_nxt                  <= WB_CYC_O;
+            WB_BYTE_STB_O_nxt             <= WB_BYTE_STB_O;
+            WB_WE_O_nxt                   <= WB_WE_O;
+            WB_RD_O_nxt                   <= WB_RD_O;
+            WB_STB_O_nxt                  <= WB_STB_O;
+
+            FABRIC_ASYNC_ACK_TOGGLE_O_nxt <= FABRIC_ASYNC_ACK_TOGGLE_O;
+          end
+          1'b1:  // Received Acknowledge from Fabric Interface
+            begin
+            fabric_to_ahb_state_nxt       <= FAB_ASYNC_IDLE;
+
+            A2F_HRDATAS_nxt               <= WB_DAT_I;
+
+            WB_CYC_O_nxt                  <= 1'b0;
+            WB_BYTE_STB_O_nxt             <= 4'b0;
+            WB_WE_O_nxt                   <= 1'b0;
+            WB_RD_O_nxt                   <= 1'b0;
+            WB_STB_O_nxt                  <= 1'b0;
+
+            FABRIC_ASYNC_ACK_TOGGLE_O_nxt <= ~FABRIC_ASYNC_ACK_TOGGLE_O;
+          end
+        endcase
+      end
+      default: begin
+        fabric_to_ahb_state_nxt       <= FAB_ASYNC_IDLE;
+
+        A2F_HRDATAS_nxt               <= A2F_HRDATAS;
+
+        WB_CYC_O_nxt                  <= 1'b0;
+        WB_BYTE_STB_O_nxt             <= 4'b0;
+        WB_WE_O_nxt                   <= 1'b0;
+        WB_RD_O_nxt                   <= 1'b0;
+        WB_STB_O_nxt                  <= 1'b0;
+
+        FABRIC_ASYNC_ACK_TOGGLE_O_nxt <= FABRIC_ASYNC_ACK_TOGGLE_O;
+      end
+    endcase
+  end
+
+endmodule
+
+`timescale 1ns / 10ps
+
+module ahb2fb_asynbrig (
+
+    // AHB Slave Interface to AHB Bus Matrix
+    //
+    A2F_HCLK,
+    A2F_HRESET,
+
+    A2F_HADDRS,
+    A2F_HSEL,
+    A2F_HTRANSS,
+    A2F_HSIZES,
+    A2F_HWRITES,
+    A2F_HREADYS,
+    A2F_HWDATAS,
+
+    A2F_HREADYOUTS,
+    A2F_HRESPS,
+    A2F_HRDATAS,
+
+    // Fabric Wishbone Bus
+    //
+    WB_CLK_I,
+    WB_RST_I,
+    WB_DAT_I,
+    WB_ACK_I,
+
+    WB_ADR_O,
+    WB_CYC_O,
+    WB_BYTE_STB_O,
+    WB_WE_O,
+    WB_RD_O,
+    WB_STB_O,
+    WB_DAT_O
+
+);
+
+
+  //-----Port Parameters-----------------
+  //
+
+  parameter ADDRWIDTH = 32;
+  parameter DATAWIDTH = 32;
+  parameter APERWIDTH = 17;
+
+
+  //-----Port Signals--------------------
+  //
+
+  input A2F_HCLK;  // Clock
+  input A2F_HRESET;  // Reset
+
+  // AHB connection to master
+  //
+  input [ADDRWIDTH-1:0] A2F_HADDRS;
+  input A2F_HSEL;
+  input [1:0] A2F_HTRANSS;
+  input [2:0] A2F_HSIZES;
+  input A2F_HWRITES;
+  input A2F_HREADYS;
+  input [DATAWIDTH-1:0] A2F_HWDATAS;
+
+  output A2F_HREADYOUTS;
+  output A2F_HRESPS;
+  output [DATAWIDTH-1:0] A2F_HRDATAS;
+
+  // Wishbone connection to Fabric IP
+  //
+  input WB_CLK_I;  // Fabric Clock Input         from Fabric
+  input WB_RST_I;  // Fabric Reset Input         from Fabric
+  input [DATAWIDTH-1:0] WB_DAT_I;  // Read Data Bus              from Fabric
+  input WB_ACK_I;  // Transfer Cycle Acknowledge from Fabric
+
+  output [APERWIDTH-1:0] WB_ADR_O;  // Address Bus                to   Fabric
+  output WB_CYC_O;  // Cycle Chip Select          to   Fabric
+  output [3:0] WB_BYTE_STB_O;  // Byte Select                to   Fabric
+  output WB_WE_O;  // Write Enable               to   Fabric
+  output WB_RD_O;  // Read  Enable               to   Fabric
+  output WB_STB_O;  // Strobe Signal              to   Fabric
+  output [DATAWIDTH-1:0] WB_DAT_O;  // Write Data Bus             to   Fabric
+
+
+  wire                 A2F_HCLK;  // Clock
+  wire                 A2F_HRESET;  // Reset
+
+  // AHB connection to master
+  //
+  wire [ADDRWIDTH-1:0] A2F_HADDRS;
+  wire                 A2F_HSEL;
+  wire [          1:0] A2F_HTRANSS;
+  wire [          2:0] A2F_HSIZES;
+  wire                 A2F_HWRITES;
+  wire                 A2F_HREADYS;
+  wire [DATAWIDTH-1:0] A2F_HWDATAS;
+
+  wire                 A2F_HREADYOUTS;
+  wire                 A2F_HRESPS;
+  wire [DATAWIDTH-1:0] A2F_HRDATAS;
+
+
+  // Wishbone connection to Fabric IP
+  //
+  wire                 WB_CLK_I;  // Fabric Clock Input         from Fabric
+  wire                 WB_RST_I;  // Fabric Reset Input         from Fabric
+  wire [DATAWIDTH-1:0] WB_DAT_I;  // Read Data Bus              from Fabric
+  wire                 WB_ACK_I;  // Transfer Cycle Acknowledge from Fabric
+
+  wire [APERWIDTH-1:0] WB_ADR_O;  // Address Bus (128KB)        to   Fabric
+  wire                 WB_CYC_O;  // Cycle Chip Select          to   Fabric
+  wire [          3:0] WB_BYTE_STB_O;  // Byte Select                to   Fabric
+  wire                 WB_WE_O;  // Write Enable               to   Fabric
+  wire                 WB_RD_O;  // Read  Enable               to   Fabric
+  wire                 WB_STB_O;  // Strobe Signal              to   Fabric
+  wire [DATAWIDTH-1:0] WB_DAT_O;  // Write Data Bus             to   Fabric
+
+
+
+  //------Define Parameters---------
+  //
+
+  //
+  // None at this time
+  //
+
+
+  //-----Internal Signals--------------------
+  //
+
+  // Register module interface signals
+  wire [APERWIDTH-1:0] ahb_async_addr;
+  wire                 ahb_async_read_en;
+  wire                 ahb_async_write_en;
+  wire [          3:0] ahb_async_byte_strobe;
+
+  wire                 ahb_async_stb_toggle;
+
+  wire                 fabric_async_ack_toggle;
+
+
+  //------Logic Operations----------
+  //
+
+  // Define the data input from the AHB and output to the fabric
+  //
+  // Note: Due to the nature of the bus timing, there is no need to register
+  //       this value locally.
+  //
+  assign WB_DAT_O = A2F_HWDATAS;
+
+  // Define the Address bus output from the AHB and output to the fabric
+  //
+  // Note: Due to the nature of the bus timing, there is no need to register
+  //       this value locally.
+  //
+  assign WB_ADR_O = ahb_async_addr;
+
+
+  //------Instantiate Modules----------------
+  //
+
+  // Interface block to convert AHB transfers to simple read/write
+  // controls.
+  ahb2fb_asynbrig_if #(
+
+      .DATAWIDTH(DATAWIDTH),
+      .APERWIDTH(APERWIDTH)
+
+  ) u_FFE_ahb_to_fabric_async_bridge_interface (
+      .A2F_HCLK  (A2F_HCLK),
+      .A2F_HRESET(A2F_HRESET),
+
+      // Input slave port: 32 bit data bus interface
+      .A2F_HSEL   (A2F_HSEL),
+      .A2F_HADDRS (A2F_HADDRS[APERWIDTH-1:0]),
+      .A2F_HTRANSS(A2F_HTRANSS),
+      .A2F_HSIZES (A2F_HSIZES),
+      .A2F_HWRITES(A2F_HWRITES),
+      .A2F_HREADYS(A2F_HREADYS),
+
+      .A2F_HREADYOUTS(A2F_HREADYOUTS),
+      .A2F_HRESPS    (A2F_HRESPS),
+
+      // Register interface
+      .AHB_ASYNC_ADDR_O       (ahb_async_addr),
+      .AHB_ASYNC_READ_EN_O    (ahb_async_read_en),
+      .AHB_ASYNC_WRITE_EN_O   (ahb_async_write_en),
+      .AHB_ASYNC_BYTE_STROBE_O(ahb_async_byte_strobe),
+      .AHB_ASYNC_STB_TOGGLE_O (ahb_async_stb_toggle),
+
+      .FABRIC_ASYNC_ACK_TOGGLE_I(fabric_async_ack_toggle)
+
+  );
+
+
+  fb2ahb_asynbrig_if  //                                     #(
+  //                                      )
+
+  u_FFE_fabric_to_ahb_async_bridge_interface (
+      .A2F_HRDATAS(A2F_HRDATAS),
+
+      .AHB_ASYNC_READ_EN_I    (ahb_async_read_en),
+      .AHB_ASYNC_WRITE_EN_I   (ahb_async_write_en),
+      .AHB_ASYNC_BYTE_STROBE_I(ahb_async_byte_strobe),
+      .AHB_ASYNC_STB_TOGGLE_I (ahb_async_stb_toggle),
+
+      .WB_CLK_I(WB_CLK_I),  // Fabric Clock Input         from Fabric
+      .WB_RST_I(WB_RST_I),  // Fabric Reset Input         from Fabric
+      .WB_ACK_I(WB_ACK_I),  // Transfer Cycle Acknowledge from Fabric
+      .WB_DAT_I(WB_DAT_I),  // Data Bus Input             from Fabric
+
+      .WB_CYC_O     (WB_CYC_O),  // Cycle Chip Select          to   Fabric
+      .WB_BYTE_STB_O(WB_BYTE_STB_O),  // Byte Select                to   Fabric
+      .WB_WE_O      (WB_WE_O),  // Write Enable               to   Fabric
+      .WB_RD_O      (WB_RD_O),  // Read  Enable               to   Fabric
+      .WB_STB_O     (WB_STB_O),  // Strobe Signal              to   Fabric
+
+      .FABRIC_ASYNC_ACK_TOGGLE_O(fabric_async_ack_toggle)
+
+  );
+endmodule
+
+
+`timescale 1ns / 10ps
+module qlal4s3b_cell_macro_bfm (
+
+    // AHB-To-Fabric Bridge
+    //
+    WBs_ADR,
+    WBs_CYC,
+    WBs_BYTE_STB,
+    WBs_WE,
+    WBs_RD,
+    WBs_STB,
+    WBs_WR_DAT,
+    WB_CLK,
+    WB_RST,
+    WBs_RD_DAT,
+    WBs_ACK,
+    //
+    // SDMA Signals
+    //
+    SDMA_Req,
+    SDMA_Sreq,
+    SDMA_Done,
+    SDMA_Active,
+    //
+    // FB Interrupts
+    //
+    FB_msg_out,
+    FB_Int_Clr,
+    FB_Start,
+    FB_Busy,
+    //
+    // FB Clocks
+    //
+    Sys_Clk0,
+    Sys_Clk0_Rst,
+    Sys_Clk1,
+    Sys_Clk1_Rst,
+    //
+    // Packet FIFO
+    //
+    Sys_PKfb_Clk,
+    Sys_PKfb_Rst,
+    FB_PKfbData,
+    FB_PKfbPush,
+    FB_PKfbSOF,
+    FB_PKfbEOF,
+    FB_PKfbOverflow,
+    //
+    // Sensor Interface
+    //
+    Sensor_Int,
+    TimeStamp,
+    //
+    // SPI Master APB Bus
+    //
+    Sys_Pclk,
+    Sys_Pclk_Rst,
+    Sys_PSel,
+    SPIm_Paddr,
+    SPIm_PEnable,
+    SPIm_PWrite,
+    SPIm_PWdata,
+    SPIm_Prdata,
+    SPIm_PReady,
+    SPIm_PSlvErr,
+    //
+    // Misc
+    //
+    Device_ID,
+    //
+    // FBIO Signals
+    //
+    FBIO_In,
+    FBIO_In_En,
+    FBIO_Out,
+    FBIO_Out_En,
+    //
+    // ???
+    //
+    SFBIO,
+    Device_ID_6S,
+    Device_ID_4S,
+    SPIm_PWdata_26S,
+    SPIm_PWdata_24S,
+    SPIm_PWdata_14S,
+    SPIm_PWdata_11S,
+    SPIm_PWdata_0S,
+    SPIm_Paddr_8S,
+    SPIm_Paddr_6S,
+    FB_PKfbPush_1S,
+    FB_PKfbData_31S,
+    FB_PKfbData_21S,
+    FB_PKfbData_19S,
+    FB_PKfbData_9S,
+    FB_PKfbData_6S,
+    Sys_PKfb_ClkS,
+    FB_BusyS,
+    WB_CLKS
+);
+  //------Port Parameters----------------
+  //
+
+  //
+  // None at this time
+  //
+
+  //------Port Signals-------------------
+  //
+
+  //
+  // AHB-To-Fabric Bridge
+  //
+  output [16:0] WBs_ADR;
+  output WBs_CYC;
+  output [3:0] WBs_BYTE_STB;
+  output WBs_WE;
+  output WBs_RD;
+  output WBs_STB;
+  output [31:0] WBs_WR_DAT;
+  input WB_CLK;
+  output WB_RST;
+  input [31:0] WBs_RD_DAT;
+  input WBs_ACK;
+  //
+  // SDMA Signals
+  //
+  input [3:0] SDMA_Req;
+  input [3:0] SDMA_Sreq;
+  output [3:0] SDMA_Done;
+  output [3:0] SDMA_Active;
+  //
+  // FB Interrupts
+  //
+  input [3:0] FB_msg_out;
+  input [7:0] FB_Int_Clr;
+  output FB_Start;
+  input FB_Busy;
+  //
+  // FB Clocks
+  //
+  output Sys_Clk0;
+  output Sys_Clk0_Rst;
+  output Sys_Clk1;
+  output Sys_Clk1_Rst;
+  //
+  // Packet FIFO
+  //
+  input Sys_PKfb_Clk;
+  output Sys_PKfb_Rst;
+  input [31:0] FB_PKfbData;
+  input [3:0] FB_PKfbPush;
+  input FB_PKfbSOF;
+  input FB_PKfbEOF;
+  output FB_PKfbOverflow;
+  //
+  // Sensor Interface
+  //
+  output [7:0] Sensor_Int;
+  output [23:0] TimeStamp;
+  //
+  // SPI Master APB Bus
+  //
+  output Sys_Pclk;
+  output Sys_Pclk_Rst;
+  input Sys_PSel;
+  input [15:0] SPIm_Paddr;
+  input SPIm_PEnable;
+  input SPIm_PWrite;
+  input [31:0] SPIm_PWdata;
+  output [31:0] SPIm_Prdata;
+  output SPIm_PReady;
+  output SPIm_PSlvErr;
+  //
+  // Misc
+  //
+  input [15:0] Device_ID;
+  //
+  // FBIO Signals
+  //
+  output [13:0] FBIO_In;
+  input [13:0] FBIO_In_En;
+  input [13:0] FBIO_Out;
+  input [13:0] FBIO_Out_En;
+  //
+  // ???
+  //
+  inout [13:0] SFBIO;
+  input Device_ID_6S;
+  input Device_ID_4S;
+  input SPIm_PWdata_26S;
+  input SPIm_PWdata_24S;
+  input SPIm_PWdata_14S;
+  input SPIm_PWdata_11S;
+  input SPIm_PWdata_0S;
+  input SPIm_Paddr_8S;
+  input SPIm_Paddr_6S;
+  input FB_PKfbPush_1S;
+  input FB_PKfbData_31S;
+  input FB_PKfbData_21S;
+  input FB_PKfbData_19S;
+  input FB_PKfbData_9S;
+  input FB_PKfbData_6S;
+  input Sys_PKfb_ClkS;
+  input FB_BusyS;
+  input WB_CLKS;
+
+
+  wire [16:0] WBs_ADR;
+  wire        WBs_CYC;
+  wire [ 3:0] WBs_BYTE_STB;
+  wire        WBs_WE;
+  wire        WBs_RD;
+  wire        WBs_STB;
+  wire [31:0] WBs_WR_DAT;
+  wire        WB_CLK;
+  reg         WB_RST;
+  wire [31:0] WBs_RD_DAT;
+  wire        WBs_ACK;
+
+  wire [ 3:0] SDMA_Req;
+  wire [ 3:0] SDMA_Sreq;
+  //reg      [3:0]  SDMA_Done;//SDMA BFM
+  //reg      [3:0]  SDMA_Active;//SDMA BFM
+  wire [ 3:0] SDMA_Done;
+  wire [ 3:0] SDMA_Active;
+
+  wire [ 3:0] FB_msg_out;
+  wire [ 7:0] FB_Int_Clr;
+  reg         FB_Start;
+  wire        FB_Busy;
+
+  wire        Sys_Clk0;
+  reg         Sys_Clk0_Rst;
+  wire        Sys_Clk1;
+  reg         Sys_Clk1_Rst;
+
+  wire        Sys_PKfb_Clk;
+  reg         Sys_PKfb_Rst;
+  wire [31:0] FB_PKfbData;
+  wire [ 3:0] FB_PKfbPush;
+  wire        FB_PKfbSOF;
+  wire        FB_PKfbEOF;
+  reg         FB_PKfbOverflow;
+
+  reg  [ 7:0] Sensor_Int;
+  reg  [23:0] TimeStamp;
+
+  reg         Sys_Pclk;
+  reg         Sys_Pclk_Rst;
+  wire        Sys_PSel;
+
+  wire [15:0] SPIm_Paddr;
+  wire        SPIm_PEnable;
+  wire        SPIm_PWrite;
+  wire [31:0] SPIm_PWdata;
+  reg  [31:0] SPIm_Prdata;
+  reg         SPIm_PReady;
+  reg         SPIm_PSlvErr;
+
+  wire [15:0] Device_ID;
+
+  reg  [13:0] FBIO_In;
+  wire [13:0] FBIO_In_En;
+  wire [13:0] FBIO_Out;
+  wire [13:0] FBIO_Out_En;
+
+  wire [13:0] SFBIO;
+  wire        Device_ID_6S;
+  wire        Device_ID_4S;
+
+  wire        SPIm_PWdata_26S;
+  wire        SPIm_PWdata_24S;
+  wire        SPIm_PWdata_14S;
+  wire        SPIm_PWdata_11S;
+  wire        SPIm_PWdata_0S;
+  wire        SPIm_Paddr_8S;
+  wire        SPIm_Paddr_6S;
+
+  wire        FB_PKfbPush_1S;
+  wire        FB_PKfbData_31S;
+  wire        FB_PKfbData_21S;
+  wire        FB_PKfbData_19S;
+  wire        FB_PKfbData_9S;
+  wire        FB_PKfbData_6S;
+  wire        Sys_PKfb_ClkS;
+
+  wire        FB_BusyS;
+  wire        WB_CLKS;
+
+
+  //------Define Parameters--------------
+  //
+
+  parameter ADDRWIDTH = 32;
+  parameter DATAWIDTH = 32;
+  parameter APERWIDTH = 17;
+
+  parameter ENABLE_AHB_REG_WR_DEBUG_MSG = 1'b1;
+  parameter ENABLE_AHB_REG_RD_DEBUG_MSG = 1'b1;
+
+  parameter       T_CYCLE_CLK_SYS_CLK0        = 200;//230;//ACSLIPTEST-230;//100;//180;//(1000.0/(80.0/16)) ; // Default EOS S3B Clock Rate
+  parameter       T_CYCLE_CLK_SYS_CLK1        = 650;//3906;//650;////83.33;//250;//30517;//(1000.0/(80.0/16)) ; // Default EOS S3B Clock Rate
+  parameter T_CYCLE_CLK_A2F_HCLK = (1000.0 / (80.0 / 12));  // Default EOS S3B Clock Rate
+
+  parameter SYS_CLK0_RESET_LOOP = 5;  //4.34;//5;
+  parameter SYS_CLK1_RESET_LOOP = 5;
+  parameter WB_CLK_RESET_LOOP = 5;
+  parameter A2F_HCLK_RESET_LOOP = 5;
+
+
+  //------Internal Signals---------------
+  //
+
+  integer        Sys_Clk0_Reset_Loop_Cnt;
+  integer        Sys_Clk1_Reset_Loop_Cnt;
+  integer        WB_CLK_Reset_Loop_Cnt;
+  integer        A2F_HCLK_Reset_Loop_Cnt;
+
+
+  wire           A2F_HCLK;
+  reg            A2F_HRESET;
+
+  wire    [31:0] A2F_HADDRS;
+  wire           A2F_HSEL;
+  wire    [ 1:0] A2F_HTRANSS;
+  wire    [ 2:0] A2F_HSIZES;
+  wire           A2F_HWRITES;
+  wire           A2F_HREADYS;
+  wire    [31:0] A2F_HWDATAS;
+
+  wire           A2F_HREADYOUTS;
+  wire           A2F_HRESPS;
+  wire    [31:0] A2F_HRDATAS;
+
+
+  //------Logic Operations---------------
+  //
+
+  // Apply Reset to Sys_Clk0 domain
+  //
+  initial begin
+
+    Sys_Clk0_Rst <= 1'b1;
+`ifndef YOSYS
+    for (
+        Sys_Clk0_Reset_Loop_Cnt = 0;
+        Sys_Clk0_Reset_Loop_Cnt < SYS_CLK0_RESET_LOOP;
+        Sys_Clk0_Reset_Loop_Cnt = Sys_Clk0_Reset_Loop_Cnt + 1
+    ) begin
+      wait(Sys_Clk0 == 1'b1) #1;
+      wait(Sys_Clk0 == 1'b0) #1;
+    end
+
+    wait(Sys_Clk0 == 1'b1) #1;
+`endif
+    Sys_Clk0_Rst <= 1'b0;
+
+  end
+
+  // Apply Reset to Sys_Clk1 domain
+  //
+  initial begin
+
+    Sys_Clk1_Rst <= 1'b1;
+`ifndef YOSYS
+    for (
+        Sys_Clk1_Reset_Loop_Cnt = 0;
+        Sys_Clk1_Reset_Loop_Cnt < SYS_CLK1_RESET_LOOP;
+        Sys_Clk1_Reset_Loop_Cnt = Sys_Clk1_Reset_Loop_Cnt + 1
+    ) begin
+      wait(Sys_Clk1 == 1'b1) #1;
+      wait(Sys_Clk1 == 1'b0) #1;
+    end
+
+    wait(Sys_Clk1 == 1'b1) #1;
+`endif
+    Sys_Clk1_Rst <= 1'b0;
+
+  end
+
+  // Apply Reset to the Wishbone domain
+  //
+  // Note: In the ASSP, this reset is distict from the reset domains for Sys_Clk[1:0].
+  //
+  initial begin
+
+    WB_RST <= 1'b1;
+`ifndef YOSYS
+    for (
+        WB_CLK_Reset_Loop_Cnt = 0;
+        WB_CLK_Reset_Loop_Cnt < WB_CLK_RESET_LOOP;
+        WB_CLK_Reset_Loop_Cnt = WB_CLK_Reset_Loop_Cnt + 1
+    ) begin
+      wait(WB_CLK == 1'b1) #1;
+      wait(WB_CLK == 1'b0) #1;
+    end
+
+    wait(WB_CLK == 1'b1) #1;
+`endif
+    WB_RST <= 1'b0;
+
+  end
+
+  // Apply Reset to the AHB Bus domain
+  //
+  // Note: The AHB bus clock domain is separate from the Sys_Clk[1:0] domains
+  initial begin
+
+    A2F_HRESET <= 1'b1;
+`ifndef YOSYS
+    for (
+        A2F_HCLK_Reset_Loop_Cnt = 0;
+        A2F_HCLK_Reset_Loop_Cnt < A2F_HCLK_RESET_LOOP;
+        A2F_HCLK_Reset_Loop_Cnt = A2F_HCLK_Reset_Loop_Cnt + 1
+    ) begin
+      wait(A2F_HCLK == 1'b1) #1;
+      wait(A2F_HCLK == 1'b0) #1;
+    end
+
+    wait(A2F_HCLK == 1'b1) #1;
+`endif
+    A2F_HRESET <= 1'b0;
+
+  end
+
+  // Initialize all outputs
+  //
+  // Note: These may be replaced in the future by BFMs as the become available.
+  //
+  //       These registers allow test bench routines to drive these signals as needed.
+  //
+  initial begin
+
+    //
+    // SDMA Signals
+    //
+    //SDMA_Done       <=  4'h0;//Added SDMA BFM
+    // SDMA_Active     <=  4'h0;//Added SDMA BFM
+
+    //
+    // FB Interrupts
+    //
+    FB_Start        <= 1'b0;
+
+    //
+    // Packet FIFO
+    //
+    Sys_PKfb_Rst    <= 1'b0;
+    FB_PKfbOverflow <= 1'b0;
+
+    //
+    // Sensor Interface
+    //
+    Sensor_Int      <= 8'h0;
+    TimeStamp       <= 24'h0;
+
+    //
+    // SPI Master APB Bus
+    //
+    Sys_Pclk        <= 1'b0;
+    Sys_Pclk_Rst    <= 1'b0;
+
+    SPIm_Prdata     <= 32'h0;
+    SPIm_PReady     <= 1'b0;
+    SPIm_PSlvErr    <= 1'b0;
+
+    //
+    // FBIO Signals
+    //
+    FBIO_In         <= 14'h0;
+
+  end
+
+
+  //------Instantiate Modules------------
+  //
+
+  ahb2fb_asynbrig #(
+      .ADDRWIDTH(ADDRWIDTH),
+      .DATAWIDTH(DATAWIDTH),
+      .APERWIDTH(APERWIDTH)
+  ) u_ffe_ahb_to_fabric_async_bridge (
+      // AHB Slave Interface to AHB Bus Matrix
+      //
+      .A2F_HCLK  (A2F_HCLK),
+      .A2F_HRESET(A2F_HRESET),
+
+      .A2F_HADDRS (A2F_HADDRS),
+      .A2F_HSEL   (A2F_HSEL),
+      .A2F_HTRANSS(A2F_HTRANSS),
+      .A2F_HSIZES (A2F_HSIZES),
+      .A2F_HWRITES(A2F_HWRITES),
+      .A2F_HREADYS(A2F_HREADYS),
+      .A2F_HWDATAS(A2F_HWDATAS),
+
+      .A2F_HREADYOUTS(A2F_HREADYOUTS),
+      .A2F_HRESPS    (A2F_HRESPS),
+      .A2F_HRDATAS   (A2F_HRDATAS),
+
+      // Fabric Wishbone Bus
+      //
+      .WB_CLK_I(WB_CLK),
+      .WB_RST_I(WB_RST),
+      .WB_DAT_I(WBs_RD_DAT),
+      .WB_ACK_I(WBs_ACK),
+
+      .WB_ADR_O     (WBs_ADR),
+      .WB_CYC_O     (WBs_CYC),
+      .WB_BYTE_STB_O(WBs_BYTE_STB),
+      .WB_WE_O      (WBs_WE),
+      .WB_RD_O      (WBs_RD),
+      .WB_STB_O     (WBs_STB),
+      .WB_DAT_O     (WBs_WR_DAT)
+
+  );
+
+
+  ahb_gen_bfm #(
+      .ADDRWIDTH                  (ADDRWIDTH),
+      .DATAWIDTH                  (DATAWIDTH),
+      .DEFAULT_AHB_ADDRESS        ({(ADDRWIDTH) {1'b1}}),
+      .STD_CLK_DLY                (2),
+      .ENABLE_AHB_REG_WR_DEBUG_MSG(ENABLE_AHB_REG_WR_DEBUG_MSG),
+      .ENABLE_AHB_REG_RD_DEBUG_MSG(ENABLE_AHB_REG_RD_DEBUG_MSG)
+  ) u_ahb_gen_bfm (
+      // AHB Slave Interface to AHB Bus Matrix
+      //
+      .A2F_HCLK  (A2F_HCLK),
+      .A2F_HRESET(A2F_HRESET),
+
+      .A2F_HADDRS (A2F_HADDRS),
+      .A2F_HSEL   (A2F_HSEL),
+      .A2F_HTRANSS(A2F_HTRANSS),
+      .A2F_HSIZES (A2F_HSIZES),
+      .A2F_HWRITES(A2F_HWRITES),
+      .A2F_HREADYS(A2F_HREADYS),
+      .A2F_HWDATAS(A2F_HWDATAS),
+
+      .A2F_HREADYOUTS(A2F_HREADYOUTS),
+      .A2F_HRESPS    (A2F_HRESPS),
+      .A2F_HRDATAS   (A2F_HRDATAS)
+
+  );
+
+  // Define the clock cycle times.
+  //
+  // Note:    Values are calculated to output in units of nS.
+  //
+  oscillator_s1 #(
+      .T_CYCLE_CLK(T_CYCLE_CLK_SYS_CLK0)
+  ) u_osc_sys_clk0 (
+      .OSC_CLK_EN(1'b1),
+      .OSC_CLK(Sys_Clk0)
+  );
+  oscillator_s1 #(
+      .T_CYCLE_CLK(T_CYCLE_CLK_SYS_CLK1)
+  ) u_osc_sys_clk1 (
+      .OSC_CLK_EN(1'b1),
+      .OSC_CLK(Sys_Clk1)
+  );
+  oscillator_s1 #(
+      .T_CYCLE_CLK(T_CYCLE_CLK_A2F_HCLK)
+  ) u_osc_a2f_hclk (
+      .OSC_CLK_EN(1'b1),
+      .OSC_CLK(A2F_HCLK)
+  );
+
+
+  //SDMA bfm
+  sdma_bfm sdma_bfm_inst0 (
+      .sdma_req_i			( SDMA_Req),
+      .sdma_sreq_i		( SDMA_Sreq),
+      .sdma_done_o		( SDMA_Done),
+      .sdma_active_o		( SDMA_Active)
+  );
+
+
+
+endmodule  /* qlal4s3b_cell_macro_bfm*/
+
+(* keep *)
+module qlal4s3b_cell_macro (
+    input WB_CLK,
+    input WBs_ACK,
+    input [31:0] WBs_RD_DAT,
+    output [3:0] WBs_BYTE_STB,
+    output WBs_CYC,
+    output WBs_WE,
+    output WBs_RD,
+    output WBs_STB,
+    output [16:0] WBs_ADR,
+    input [3:0] SDMA_Req,
+    input [3:0] SDMA_Sreq,
+    output [3:0] SDMA_Done,
+    output [3:0] SDMA_Active,
+    input [3:0] FB_msg_out,
+    input [7:0] FB_Int_Clr,
+    output FB_Start,
+    input FB_Busy,
+    output WB_RST,
+    output Sys_PKfb_Rst,
+    output Clk_C16,
+    output Clk_C16_Rst,
+    output Clk_C21,
+    output Clk_C21_Rst,
+    output Sys_Pclk,
+    output Sys_Pclk_Rst,
+    input Sys_PKfb_Clk,
+    input [31:0] FB_PKfbData,
+    output [31:0] WBs_WR_DAT,
+    input [3:0] FB_PKfbPush,
+    input FB_PKfbSOF,
+    input FB_PKfbEOF,
+    output [7:0] Sensor_Int,
+    output FB_PKfbOverflow,
+    output [23:0] TimeStamp,
+    input Sys_PSel,
+    input [15:0] SPIm_Paddr,
+    input SPIm_PEnable,
+    input SPIm_PWrite,
+    input [31:0] SPIm_PWdata,
+    output SPIm_PReady,
+    output SPIm_PSlvErr,
+    output [31:0] SPIm_Prdata,
+    input [15:0] Device_ID,
+    input [13:0] FBIO_In_En,
+    input [13:0] FBIO_Out,
+    input [13:0] FBIO_Out_En,
+    output [13:0] FBIO_In,
+    inout [13:0] SFBIO,
+    input Device_ID_6S,
+    input Device_ID_4S,
+    input SPIm_PWdata_26S,
+    input SPIm_PWdata_24S,
+    input SPIm_PWdata_14S,
+    input SPIm_PWdata_11S,
+    input SPIm_PWdata_0S,
+    input SPIm_Paddr_8S,
+    input SPIm_Paddr_6S,
+    input FB_PKfbPush_1S,
+    input FB_PKfbData_31S,
+    input FB_PKfbData_21S,
+    input FB_PKfbData_19S,
+    input FB_PKfbData_9S,
+    input FB_PKfbData_6S,
+    input Sys_PKfb_ClkS,
+    input FB_BusyS,
+    input WB_CLKS
+);
+
+
+  qlal4s3b_cell_macro_bfm u_ASSP_bfm_inst (
+      .WBs_ADR        (WBs_ADR),
+      .WBs_CYC        (WBs_CYC),
+      .WBs_BYTE_STB   (WBs_BYTE_STB),
+      .WBs_WE         (WBs_WE),
+      .WBs_RD         (WBs_RD),
+      .WBs_STB        (WBs_STB),
+      .WBs_WR_DAT     (WBs_WR_DAT),
+      .WB_CLK         (WB_CLK),
+      .WB_RST         (WB_RST),
+      .WBs_RD_DAT     (WBs_RD_DAT),
+      .WBs_ACK        (WBs_ACK),
+      //
+      // SDMA Signals
+      //
+      .SDMA_Req       (SDMA_Req),
+      .SDMA_Sreq      (SDMA_Sreq),
+      .SDMA_Done      (SDMA_Done),
+      .SDMA_Active    (SDMA_Active),
+      //
+      // FB Interrupts
+      //
+      .FB_msg_out     (FB_msg_out),
+      .FB_Int_Clr     (FB_Int_Clr),
+      .FB_Start       (FB_Start),
+      .FB_Busy        (FB_Busy),
+      //
+      // FB Clocks
+      //
+      .Sys_Clk0       (Clk_C16),
+      .Sys_Clk0_Rst   (Clk_C16_Rst),
+      .Sys_Clk1       (Clk_C21),
+      .Sys_Clk1_Rst   (Clk_C21_Rst),
+      //
+      // Packet FIFO
+      //
+      .Sys_PKfb_Clk   (Sys_PKfb_Clk),
+      .Sys_PKfb_Rst   (Sys_PKfb_Rst),
+      .FB_PKfbData    (FB_PKfbData),
+      .FB_PKfbPush    (FB_PKfbPush),
+      .FB_PKfbSOF     (FB_PKfbSOF),
+      .FB_PKfbEOF     (FB_PKfbEOF),
+      .FB_PKfbOverflow(FB_PKfbOverflow),
+      //
+      // Sensor Interface
+      //
+      .Sensor_Int     (Sensor_Int),
+      .TimeStamp      (TimeStamp),
+      //
+      // SPI Master APB Bus
+      //
+      .Sys_Pclk       (Sys_Pclk),
+      .Sys_Pclk_Rst   (Sys_Pclk_Rst),
+      .Sys_PSel       (Sys_PSel),
+      .SPIm_Paddr     (SPIm_Paddr),
+      .SPIm_PEnable   (SPIm_PEnable),
+      .SPIm_PWrite    (SPIm_PWrite),
+      .SPIm_PWdata    (SPIm_PWdata),
+      .SPIm_Prdata    (SPIm_Prdata),
+      .SPIm_PReady    (SPIm_PReady),
+      .SPIm_PSlvErr   (SPIm_PSlvErr),
+      //
+      // Misc
+      //
+      .Device_ID      (Device_ID),
+      //
+      // FBIO Signals
+      //
+      .FBIO_In        (FBIO_In),
+      .FBIO_In_En     (FBIO_In_En),
+      .FBIO_Out       (FBIO_Out),
+      .FBIO_Out_En    (FBIO_Out_En),
+      //
+      // ???
+      //
+      .SFBIO          (SFBIO),
+      .Device_ID_6S   (Device_ID_6S),
+      .Device_ID_4S   (Device_ID_4S),
+      .SPIm_PWdata_26S(SPIm_PWdata_26S),
+      .SPIm_PWdata_24S(SPIm_PWdata_24S),
+      .SPIm_PWdata_14S(SPIm_PWdata_14S),
+      .SPIm_PWdata_11S(SPIm_PWdata_11S),
+      .SPIm_PWdata_0S (SPIm_PWdata_0S),
+      .SPIm_Paddr_8S  (SPIm_Paddr_8S),
+      .SPIm_Paddr_6S  (SPIm_Paddr_6S),
+      .FB_PKfbPush_1S (FB_PKfbPush_1S),
+      .FB_PKfbData_31S(FB_PKfbData_31S),
+      .FB_PKfbData_21S(FB_PKfbData_21S),
+      .FB_PKfbData_19S(FB_PKfbData_19S),
+      .FB_PKfbData_9S (FB_PKfbData_9S),
+      .FB_PKfbData_6S (FB_PKfbData_6S),
+      .Sys_PKfb_ClkS  (Sys_PKfb_ClkS),
+      .FB_BusyS       (FB_BusyS),
+      .WB_CLKS        (WB_CLKS)
+  );
+
+endmodule  /* qlal4s3b_cell_macro */
+
+
+(* keep *)
+module gpio_cell_macro (
+
+    ESEL,
+    IE,
+    OSEL,
+    OQI,
+    OQE,
+    DS,
+    FIXHOLD,
+    IZ,
+    IQZ,
+    IQE,
+    IQC,
+    IQCS,
+    IQR,
+    WPD,
+    INEN,
+    IP
+);
+
+  input ESEL;
+  input IE;
+  input OSEL;
+  input OQI;
+  input OQE;
+  input DS;
+  input FIXHOLD;
+  output IZ;
+  output IQZ;
+  input IQE;
+  input IQC;
+  input IQCS;
+  input INEN;
+  input IQR;
+  input WPD;
+  inout IP;
+
+  reg EN_reg, OQ_reg, IQZ;
+  wire AND_OUT;
+
+  assign rstn = ~IQR;
+  assign IQCP = IQCS ? ~IQC : IQC;
+
+  always @(posedge IQCP or negedge rstn)
+    if (~rstn) EN_reg <= 1'b0;
+    else EN_reg <= IE;
+
+  always @(posedge IQCP or negedge rstn)
+    if (~rstn) OQ_reg <= 1'b0;
+    else if (OQE) OQ_reg <= OQI;
+
+
+  always @(posedge IQCP or negedge rstn)
+    if (~rstn) IQZ <= 1'b0;
+    else if (IQE) IQZ <= AND_OUT;
+
+  assign IZ = AND_OUT;
+
+  assign AND_OUT = INEN ? IP : 1'b0;
+
+  assign EN = ESEL ? IE : EN_reg;
+
+  assign OQ = OSEL ? OQI : OQ_reg;
+
+  assign IP = EN ? OQ : 1'bz;
+
+endmodule
+
+
diff --git a/yosys-plugins/ql-qlf/pp3_braminit.cc b/yosys-plugins/ql-qlf/pp3_braminit.cc
new file mode 100644
index 000000000..459f3cfc6
--- /dev/null
+++ b/yosys-plugins/ql-qlf/pp3_braminit.cc
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/sigtools.h"
+#include "kernel/yosys.h"
+#include <bitset>
+#include <stdio.h>
+#include <stdlib.h>
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+static void run_pp3_braminit(Module *module)
+{
+    for (auto cell : module->selected_cells()) {
+        uint32_t mem[2048];
+        int32_t ramDataWidth = 32;
+        int32_t ramDataDepth = 512;
+
+        log("cell type %s\n", RTLIL::id2cstr(cell->name));
+
+        /* Only consider cells we're interested in */
+        if (cell->type != ID(RAM_16K_BLK) && cell->type != ID(RAM_8K_BLK))
+            continue;
+        log("found ram block\n");
+        if (!cell->hasParam(ID(INIT_FILE)))
+            continue;
+        std::string init_file = cell->getParam(ID(INIT_FILE)).decode_string();
+        cell->unsetParam(ID(INIT_FILE));
+        if (init_file == "")
+            continue;
+
+        /* Open file */
+        log("Processing %s : %s\n", RTLIL::id2cstr(cell->name), init_file.c_str());
+        ramDataWidth = cell->getParam(ID(data_width_int)).as_int();
+        ramDataDepth = cell->getParam(ID(data_depth_int)).as_int();
+
+        std::ifstream f;
+        f.open(init_file.c_str());
+        if (f.fail()) {
+            log("Can not open file `%s`.\n", init_file.c_str());
+            continue;
+        }
+
+        /* Defaults to 0 */
+        memset(mem, 0x00, sizeof(mem));
+
+        /* Process each line */
+        bool in_comment = false;
+        int cursor = 0;
+
+        while (!f.eof()) {
+            std::string line, token;
+            std::getline(f, line);
+
+            for (int i = 0; i < GetSize(line); i++) {
+                if (in_comment && line.compare(i, 2, "*/") == 0) {
+                    line[i] = ' ';
+                    line[i + 1] = ' ';
+                    in_comment = false;
+                    continue;
+                }
+                if (!in_comment && line.compare(i, 2, "/*") == 0)
+                    in_comment = true;
+                if (in_comment)
+                    line[i] = ' ';
+            }
+
+            while (1) {
+                bool set_cursor = false;
+                long value;
+
+                token = next_token(line, " \t\r\n");
+                if (token.empty() || token.compare(0, 2, "//") == 0)
+                    break;
+
+                if (token[0] == '@') {
+                    token = token.substr(1);
+                    set_cursor = true;
+                }
+
+                const char *nptr = token.c_str();
+                char *endptr;
+                value = strtol(nptr, &endptr, 16);
+                if (!*nptr || *endptr) {
+                    log("Can not parse %s `%s` for %s.\n", set_cursor ? "address" : "value", nptr, token.c_str());
+                    continue;
+                }
+
+                if (set_cursor)
+                    cursor = value;
+                else if (cursor >= 0 && cursor < ramDataDepth)
+                    mem[cursor++] = value;
+                else
+                    log("Attempt to initialize non existent address %d\n", cursor);
+            }
+        }
+
+        // TODO: Support RAM initialization for other widths than 8, 16 and 32
+        if (ramDataWidth != 8 && ramDataWidth != 16 && ramDataWidth != 32) {
+            log("WARNING: The RAM cell '%s' has data width of %d. Initialization of this width from a file is not supported yet!\n",
+                RTLIL::id2cstr(cell->name), ramDataWidth);
+            continue;
+        }
+
+        /* Set attributes */
+        std::string val = "";
+        for (int i = ramDataDepth - 1; i >= 0; i--) {
+            if (ramDataWidth == 8)
+                val += std::bitset<8>(mem[i]).to_string();
+            else if (ramDataWidth == 16)
+                val += std::bitset<16>(mem[i]).to_string();
+            else if (ramDataWidth == 32)
+                val += std::bitset<32>(mem[i]).to_string();
+        }
+        cell->setParam(RTLIL::escape_id("INIT"), RTLIL::Const::from_string(val));
+    }
+}
+
+struct PP3BRAMInitPass : public Pass {
+    PP3BRAMInitPass() : Pass("pp3_braminit", "PP3: perform RAM Block initialization from file") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    pp3_braminit\n");
+        log("\n");
+        log("This command processes all PP3 RAM blocks with a non-empty INIT_FILE\n");
+        log("parameter and converts it into the required INIT attributes\n");
+        log("\n");
+    }
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        log_header(design, "Executing PP3_BRAMINIT pass.\n");
+
+        extra_args(args, 1, design);
+
+        for (auto module : design->selected_modules())
+            run_pp3_braminit(module);
+    }
+} PP3BRAMInitPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-read.pmg b/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-read.pmg
new file mode 100644
index 000000000..6e2bae5f3
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-read.pmg
@@ -0,0 +1,66 @@
+pattern ql_bram_asymmetric_wider_read
+
+state <SigSpec> mem_wr_data
+state <SigSpec> mem_wr_en
+state <SigSpec> mem_wr_addr
+state <SigSpec> mem_rd_data
+state <SigSpec> mem_rd_addr
+state <SigSpec> mux_ab
+state <SigSpec> mux_s
+state <SigSpec> mux_ba
+state <SigSpec> mux_input
+state <SigSpec> wr_data_shift_a
+state <SigSpec> wr_data_shift_b
+state <SigSpec> wr_en_and_a
+state <SigSpec> wr_en_and_b
+state <SigSpec> wr_en_and_y
+state <SigSpec> wr_en_shift_a
+state <SigSpec> wr_en_shift_b
+state <SigSpec> wr_en_shift_y
+
+match mem
+    select mem->type == ($mem_v2)
+    // 2 because it is a primary output connected to one cell (rq port or $shiftx cell)
+    select nusers(port(mem, \WR_DATA)) == 2
+    set mem_wr_data port(mem, \WR_DATA)
+    set mem_wr_en port(mem, \WR_EN)
+    set mem_wr_addr port(mem, \WR_ADDR)
+    set mem_rd_data port(mem, \RD_DATA)
+    set mem_rd_addr port(mem, \RD_ADDR)
+endmatch
+
+match wr_en_and
+    select wr_en_and->type == ($and)
+    set wr_en_and_a port(wr_en_and, \A)
+    set wr_en_and_b port(wr_en_and, \B)
+    set wr_en_and_y port(wr_en_and, \Y)
+endmatch
+
+match wr_en_shift
+    select wr_en_shift->type.in($shl)
+    set wr_en_shift_a port(wr_en_shift, \A)
+    set wr_en_shift_b port(wr_en_shift, \B)
+    set wr_en_shift_y port(wr_en_shift, \Y)
+endmatch
+
+match mux
+    select mux->type == ($mux)
+    choice <IdString> AB {\A, \B}
+    define <IdString> BA (AB == \A ? \B : \A)
+    index <SigSpec> port(mux, \Y) === mem_wr_en
+    index <SigSpec> port(mux, AB) === wr_en_shift_y
+    set mux_ab port(mux, AB)
+    set mux_s port(mux, \S)
+    set mux_ba port(mux, BA)
+endmatch
+
+match wr_data_shift
+    select wr_data_shift->type.in($shl)
+    index <SigSpec> port(wr_data_shift, \Y) === mem_wr_data
+    set wr_data_shift_a port(wr_data_shift, \A)
+    set wr_data_shift_b port(wr_data_shift, \B)
+endmatch
+
+code
+    accept;
+endcode
diff --git a/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-write.pmg b/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-write.pmg
new file mode 100644
index 000000000..bd5a09af0
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-bram-asymmetric-wider-write.pmg
@@ -0,0 +1,65 @@
+pattern ql_bram_asymmetric_wider_write
+
+state <SigSpec> mem_rd_data
+state <SigSpec> mem_rd_addr
+state <SigSpec> mem_wr_data
+state <SigSpec> mem_wr_addr
+state <SigSpec> mem_wr_en
+state <SigSpec> rd_data_shift_y
+state <SigSpec> rd_data_ff_q
+state <SigSpec> rd_data_ff_en
+state <SigSpec> rd_data_ff_clk
+state <SigSpec> wr_addr_ff_d
+state <SigSpec> wr_en_mux_s
+state <SigSpec> rd_addr_and_a
+state <SigSpec> rd_addr_and_b
+
+match mem
+    select mem->type == ($mem_v2)
+    // 2 because it is a primary output connected to one cell (rq port or $shiftx cell)
+    select nusers(port(mem, \RD_DATA)) == 2
+    set mem_rd_data port(mem, \RD_DATA)
+    set mem_rd_addr port(mem, \RD_ADDR)
+    set mem_wr_data port(mem, \WR_DATA)
+    set mem_wr_addr port(mem, \WR_ADDR)
+    set mem_wr_en port(mem, \WR_EN)
+endmatch
+
+match rd_data_shift
+    select rd_data_shift->type.in($shiftx)
+    index <SigSpec> port(rd_data_shift, \A) === mem_rd_data
+    set rd_data_shift_y port(rd_data_shift, \Y)
+endmatch
+
+match rd_data_ff
+    select rd_data_ff->type.in($dffe)
+    select nusers(port(rd_data_ff, \D)) == 2
+    index <SigSpec> port(rd_data_ff, \D) === rd_data_shift_y
+    set rd_data_ff_q port(rd_data_ff, \Q)
+    set rd_data_ff_en port(rd_data_ff, \EN)
+    set rd_data_ff_clk port(rd_data_ff, \CLK)
+endmatch
+
+match wr_addr_ff
+    select wr_addr_ff->type.in($dff)
+    select nusers(port(wr_addr_ff, \Q)) == 2
+    index <SigSpec> port(wr_addr_ff, \Q) === mem_wr_addr
+    set wr_addr_ff_d port(wr_addr_ff, \D)
+    optional
+endmatch
+
+match wr_en_mux
+    select wr_en_mux->type.in($mux)
+    index <SigSpec> port(wr_en_mux, \Y) === mem_wr_en[0]
+    set wr_en_mux_s port(wr_en_mux, \S)
+endmatch
+
+match rd_addr_and
+    select rd_addr_and->type.in($and)
+    set rd_addr_and_a port(rd_addr_and, \A)
+    set rd_addr_and_b port(rd_addr_and, \B)
+endmatch
+
+code
+    accept;
+endcode
diff --git a/yosys-plugins/ql-qlf/ql-bram-asymmetric.cc b/yosys-plugins/ql-qlf/ql-bram-asymmetric.cc
new file mode 100644
index 000000000..f8659ee45
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-bram-asymmetric.cc
@@ -0,0 +1,391 @@
+#include "kernel/sigtools.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#include "pmgen/ql-bram-asymmetric-wider-read.h"
+#include "pmgen/ql-bram-asymmetric-wider-write.h"
+
+void test_ql_bram_asymmetric_wider_read(ql_bram_asymmetric_wider_read_pm &pm)
+{
+    auto mem = pm.st_ql_bram_asymmetric_wider_read.mem;
+    auto mem_wr_addr = pm.st_ql_bram_asymmetric_wider_read.mem_wr_addr;
+    auto mem_rd_data = pm.st_ql_bram_asymmetric_wider_read.mem_rd_data;
+    auto mem_rd_addr = pm.st_ql_bram_asymmetric_wider_read.mem_rd_addr;
+    auto mux = pm.st_ql_bram_asymmetric_wider_read.mux;
+    auto mux_s = pm.st_ql_bram_asymmetric_wider_read.mux_s;
+    auto wr_en_shift = pm.st_ql_bram_asymmetric_wider_read.wr_en_shift;
+    auto wr_en_shift_b = pm.st_ql_bram_asymmetric_wider_read.wr_en_shift_b;
+    auto wr_data_shift = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift;
+    auto wr_data_shift_a = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift_a;
+    auto wr_data_shift_b = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift_b;
+    auto wr_en_and = pm.st_ql_bram_asymmetric_wider_read.wr_en_and;
+    auto wr_en_and_a = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_a;
+    auto wr_en_and_b = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_b;
+    auto wr_en_and_y = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_y;
+
+    // Add the BRAM cell
+    std::string name = mem->name.str() + "$asymmetric";
+    RTLIL::Cell *cell = pm.module->addCell(RTLIL::escape_id(name), mem);
+
+    // Set new type for cell so that it won't be processed by memory_bram pass
+    cell->type = IdString(RTLIL::escape_id("_$_mem_v2_asymmetric"));
+
+    // Prepare wires from memory cell side to compare against module wires
+    if (!mux_s.is_wire())
+        log_error("WR_EN input wire not found\n");
+    RTLIL::Wire *wr_en_cw = mux_s.as_wire();
+
+    // The WR address wire can be narrower
+    RTLIL::Wire *wr_addr_cw = nullptr;
+    if (mem_wr_addr.is_wire())
+        wr_addr_cw = mem_wr_addr.as_wire();
+    else if (!mem_wr_addr.chunks().empty()) {
+        auto chunk = mem_wr_addr.chunks()[0];
+        if (chunk.is_wire())
+            wr_addr_cw = chunk.wire;
+    }
+    if (!wr_addr_cw)
+        log_error("WR_ADDR input wire not found\n");
+
+    if (!wr_data_shift_a.is_wire())
+        log_error("WR_DATA input wire not found\n");
+    RTLIL::Wire *wr_data_cw = wr_data_shift_a.as_wire();
+    if (!mem_rd_addr.is_wire())
+        log_error("RD_ADDR input wire not found\n");
+    RTLIL::Wire *rd_addr_cw = mem_rd_addr.as_wire();
+    if (!mem_rd_data.is_wire())
+        log_error("RD_DATA input wire not found\n");
+    RTLIL::Wire *rd_data_cw = mem_rd_data.as_wire();
+
+    // Check if wr_en_and cell has one of its inputs connected to write address
+    RTLIL::Wire *wr_en_and_a_w = nullptr;
+    RTLIL::Wire *wr_en_and_b_w = nullptr;
+    bool has_wire = false;
+    if (wr_en_and_a.is_wire()) {
+        has_wire = true;
+        wr_en_and_a_w = wr_en_and_a.as_wire();
+    }
+    if (wr_en_and_b.is_wire()) {
+        has_wire = true;
+        wr_en_and_b_w = wr_en_and_b.as_wire();
+    }
+    if (!has_wire)
+        log_error("RD_ADDR $and cell input wire not found\n");
+    if ((wr_en_and_a_w != wr_addr_cw) & (wr_en_and_b_w != wr_addr_cw))
+        log_error("This is not the $and cell we are looking for\n");
+
+    // Compare and assign wires
+    RTLIL::Wire *wr_en_w = nullptr;
+    RTLIL::Wire *wr_addr_w = nullptr;
+    RTLIL::Wire *wr_data_w = nullptr;
+    RTLIL::Wire *rd_addr_w = nullptr;
+    RTLIL::Wire *rd_data_w = nullptr;
+
+    for (auto wire : pm.module->wires_) {
+        if (wire.second == wr_en_cw)
+            wr_en_w = wire.second;
+        if (wire.second == wr_addr_cw)
+            wr_addr_w = wire.second;
+        if (wire.second == wr_data_cw)
+            wr_data_w = wire.second;
+        if (wire.second == rd_data_cw)
+            rd_data_w = wire.second;
+        if (wire.second == rd_addr_cw)
+            rd_addr_w = wire.second;
+    }
+
+    if (!wr_en_w | !wr_addr_w | !wr_data_w | !rd_data_w | !rd_addr_w)
+        log_error("Match between RAM input wires and memory cell ports not found\n");
+
+    // Get address and data lines widths
+    int rd_addr_width = rd_addr_w->width;
+    int wr_addr_width = wr_addr_w->width;
+    int wr_data_width = wr_data_w->width;
+    int rd_data_width = rd_data_w->width;
+
+    log_debug("Set RD_ADDR_WIDTH = %d, ", rd_addr_width);
+    log_debug("WR_ADDR_WIDTH = %d, ", wr_addr_width);
+    log_debug("RD_DATA_WIDTH = %d, ", rd_data_width);
+    log_debug("WR_DATA_WIDTH = %d\n", wr_data_width);
+
+    // Set address and data lines width parameters used later in techmap
+    cell->setParam(RTLIL::escape_id("RD_ADDR_WIDTH"), RTLIL::Const(rd_addr_width));
+    cell->setParam(RTLIL::escape_id("RD_DATA_WIDTH"), RTLIL::Const(rd_data_width));
+    cell->setParam(RTLIL::escape_id("WR_ADDR_WIDTH"), RTLIL::Const(wr_addr_width));
+    cell->setParam(RTLIL::escape_id("WR_DATA_WIDTH"), RTLIL::Const(wr_data_width));
+
+    int offset;
+
+    switch (wr_data_width) {
+    case 1:
+        offset = 0;
+        break;
+    case 2:
+        offset = 1;
+        break;
+    case 4:
+        offset = 2;
+        break;
+    case 8:
+    case 9:
+        offset = 3;
+        break;
+    case 16:
+    case 18:
+        offset = 4;
+        break;
+    case 32:
+    case 36:
+        offset = 5;
+        break;
+    default:
+        offset = 0;
+        break;
+    }
+
+    if (wr_en_and_y != wr_en_shift_b.extract(offset, wr_addr_width))
+        log_error("This is not the wr_en $shl cell we are looking for\n");
+    if (wr_en_and_y != wr_data_shift_b.extract(offset, wr_addr_width))
+        log_error("This is not the wr_data $shl cell we are looking for\n");
+
+    // Bypass shift on write address line
+    cell->setPort(RTLIL::escape_id("WR_ADDR"), RTLIL::SigSpec(wr_addr_w));
+
+    // Bypass shift on write address line
+    cell->setPort(RTLIL::escape_id("WR_DATA"), RTLIL::SigSpec(wr_data_w));
+
+    // Bypass shift on write address line
+    cell->setPort(RTLIL::escape_id("WR_EN"), RTLIL::SigSpec(wr_en_w));
+
+    // Cleanup the module from unused cells
+    pm.module->remove(mem);
+    pm.module->remove(mux);
+    pm.module->remove(wr_en_shift);
+    pm.module->remove(wr_en_and);
+    pm.module->remove(wr_data_shift);
+}
+
+void test_ql_bram_asymmetric_wider_write(ql_bram_asymmetric_wider_write_pm &pm)
+{
+    auto mem = pm.st_ql_bram_asymmetric_wider_write.mem;
+    auto mem_wr_addr = pm.st_ql_bram_asymmetric_wider_write.mem_wr_addr;
+    auto mem_wr_data = pm.st_ql_bram_asymmetric_wider_write.mem_wr_data;
+    auto mem_rd_data = pm.st_ql_bram_asymmetric_wider_write.mem_rd_data;
+    auto mem_rd_addr = pm.st_ql_bram_asymmetric_wider_write.mem_rd_addr;
+    auto rd_data_shift = pm.st_ql_bram_asymmetric_wider_write.rd_data_shift;
+    auto rd_data_shift_y = pm.st_ql_bram_asymmetric_wider_write.rd_data_shift_y;
+    auto rd_data_ff = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff;
+    auto rd_data_ff_q = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_q;
+    auto rd_data_ff_en = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_en;
+    auto rd_data_ff_clk = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_clk;
+    auto wr_addr_ff = pm.st_ql_bram_asymmetric_wider_write.wr_addr_ff;
+    auto wr_addr_ff_d = pm.st_ql_bram_asymmetric_wider_write.wr_addr_ff_d;
+    auto wr_en_mux = pm.st_ql_bram_asymmetric_wider_write.wr_en_mux;
+    auto wr_en_mux_s = pm.st_ql_bram_asymmetric_wider_write.wr_en_mux_s;
+    auto rd_addr_and = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and;
+    auto rd_addr_and_a = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and_a;
+    auto rd_addr_and_b = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and_b;
+
+    // Add the BRAM cell
+    std::string name = mem->name.str() + "$asymmetric";
+    RTLIL::Cell *cell = pm.module->addCell(RTLIL::escape_id(name), mem);
+
+    // Set new type for cell so that it won't be processed by memory_bram pass
+    cell->type = IdString(RTLIL::escape_id("_$_mem_v2_asymmetric"));
+
+    // Prepare wires from memory cell side to compare against module wires
+    RTLIL::Wire *rd_data_wc = nullptr;
+    RTLIL::Wire *rd_en_wc = nullptr;
+    RTLIL::Wire *clk_wc = nullptr;
+    RTLIL::Wire *rd_addr_and_a_wc = nullptr;
+    RTLIL::Wire *rd_addr_and_b_wc = nullptr;
+
+    if (rd_data_ff) {
+        if (!rd_data_ff_q.is_wire())
+            log_error("RD_DATA input wire not found\n");
+        rd_data_wc = rd_data_ff_q.as_wire();
+        if (!rd_data_ff_en.is_wire())
+            log_error("RD_EN input wire not found\n");
+        rd_en_wc = rd_data_ff_en.as_wire();
+        if (!rd_data_ff_clk.is_wire())
+            log_error("RD_CLK input wire not found\n");
+        clk_wc = rd_data_ff_clk.as_wire();
+    } else {
+        log_error("output FF not found\n");
+    }
+
+    if (rd_addr_and) {
+        bool has_wire = false;
+        if (rd_addr_and_a.is_wire()) {
+            has_wire = true;
+            rd_addr_and_a_wc = rd_addr_and_a.as_wire();
+        }
+        if (rd_addr_and_b.is_wire()) {
+            has_wire = true;
+            rd_addr_and_b_wc = rd_addr_and_b.as_wire();
+        }
+        if (!has_wire)
+            log_error("RD_ADDR $and cell input wire not found\n");
+    } else {
+        log_debug("RD_ADDR $and cell not found\n");
+    }
+
+    RTLIL::Wire *wr_addr_wc;
+    if (wr_addr_ff) {
+        if (!wr_addr_ff_d.is_wire())
+            log_error("WR_ADDR input wire not found\n");
+        wr_addr_wc = wr_addr_ff_d.as_wire();
+    } else {
+        if (!mem_wr_addr.is_wire())
+            log_error("WR_ADDR input wire not found\n");
+        wr_addr_wc = mem_wr_addr.as_wire();
+    }
+
+    // The RD address wire can be narrower
+    RTLIL::Wire *rd_addr_wc = nullptr;
+    if (mem_rd_addr.is_wire())
+        rd_addr_wc = mem_rd_addr.as_wire();
+    else if (!mem_rd_addr.chunks().empty()) {
+        auto chunk = mem_rd_addr.chunks()[0];
+        if (chunk.is_wire())
+            rd_addr_wc = chunk.wire;
+    }
+    if (!rd_addr_wc)
+        log_error("RD_ADDR input wire not found\n");
+
+    if (!mem_wr_data.is_wire())
+        log_error("WR_DATA input wire not found\n");
+    auto wr_data_wc = mem_wr_data.as_wire();
+
+    // Check if wr_en_and cell has one of its inputs connected to write address
+
+    // Compare and assign wires
+    RTLIL::Wire *rd_addr_w = nullptr;
+    RTLIL::Wire *rd_data_w = nullptr;
+    RTLIL::Wire *rd_en_w = nullptr;
+    RTLIL::Wire *rd_clk_w = nullptr;
+    RTLIL::Wire *wr_addr_w = nullptr;
+    RTLIL::Wire *wr_data_w = nullptr;
+
+    for (auto wire : pm.module->wires_) {
+        if (wire.second == rd_addr_wc)
+            rd_addr_w = wire.second;
+        if (wire.second == rd_data_wc)
+            rd_data_w = wire.second;
+        if (wire.second == rd_en_wc)
+            rd_en_w = wire.second;
+        if (wire.second == clk_wc)
+            rd_clk_w = wire.second;
+        if (wire.second == wr_addr_wc)
+            wr_addr_w = wire.second;
+        if (wire.second == wr_data_wc)
+            wr_data_w = wire.second;
+    }
+
+    if (!rd_addr_w | !rd_data_w | !rd_en_w | !rd_clk_w | !wr_addr_w | !wr_data_w)
+        log_error("Match between RAM input wires and memory cell ports not found\n");
+
+    // Set shift output SigSpec as RD_DATA
+    cell->setPort(RTLIL::escape_id("RD_DATA"), rd_data_shift_y);
+
+    // Get address and data lines widths
+    int rd_addr_width = rd_addr_w->width;
+    int wr_addr_width = wr_addr_w->width;
+    int wr_data_width = wr_data_w->width;
+    int rd_data_width = rd_data_w->width;
+
+    log_debug("Set RD_ADDR_WIDTH = %d, ", rd_addr_width);
+    log_debug("WR_ADDR_WIDTH = %d, ", wr_addr_width);
+    log_debug("RD_DATA_WIDTH = %d, ", rd_data_width);
+    log_debug("WR_DATA_WIDTH = %d\n", wr_data_width);
+
+    // Set address and data lines width parameters used later in techmap
+    cell->setParam(RTLIL::escape_id("RD_ADDR_WIDTH"), RTLIL::Const(rd_addr_width));
+    cell->setParam(RTLIL::escape_id("RD_DATA_WIDTH"), RTLIL::Const(rd_data_width));
+    cell->setParam(RTLIL::escape_id("WR_ADDR_WIDTH"), RTLIL::Const(wr_addr_width));
+    cell->setParam(RTLIL::escape_id("WR_DATA_WIDTH"), RTLIL::Const(wr_data_width));
+
+    // Bypass read address shift and connect line straight to memory cell
+    auto rd_addr_s = RTLIL::SigSpec(rd_addr_w);
+    cell->setPort(RTLIL::escape_id("RD_ADDR"), rd_addr_s);
+
+    if (wr_addr_ff) {
+        // Bypass FF on write address line if exists
+        // wr_addr_ff_d will not be assigned if wr_addr_ff was not detected earlier
+        cell->setPort(RTLIL::escape_id("WR_ADDR"), wr_addr_ff_d);
+    } else {
+        // When there are no regs on address lines, the clock isn't connected to memory
+        // Reconnect the clock
+        auto rd_clk_s = RTLIL::SigSpec(rd_clk_w);
+        cell->setPort(RTLIL::escape_id("RD_CLK"), rd_clk_s);
+    }
+
+    // Bypass FF on Data Output and connect the output straight to RD_DATA port
+    cell->setPort(RTLIL::escape_id("RD_DATA"), rd_data_ff_q);
+
+    // Bypass MUX on WRITE ENABLE and connect the output straight to WR_EN port
+    cell->setPort(RTLIL::escape_id("WR_EN"), wr_en_mux_s);
+
+    // Connect Read Enable signal to memory cell
+    if (!rd_en_w)
+        log_error("Wire \\rce not found\n");
+    auto rd_en_s = RTLIL::SigSpec(rd_en_w);
+    cell->setPort(RTLIL::escape_id("RD_EN"), rd_en_s);
+
+    // Cleanup the module from unused cells
+    pm.module->remove(mem);
+    pm.module->remove(rd_data_shift);
+    pm.module->remove(rd_data_ff);
+    pm.module->remove(wr_en_mux);
+    if (wr_addr_ff)
+        pm.module->remove(wr_addr_ff);
+    // Check if detected $and is connected to RD_ADDR
+    if ((rd_addr_and_a_wc != rd_addr_w) & (rd_addr_and_b_wc != rd_addr_w))
+        log_error("This is not the $and cell we are looking for\n");
+    else
+        pm.module->remove(rd_addr_and);
+}
+
+struct QLBramAsymmetric : public Pass {
+
+    QLBramAsymmetric()
+        : Pass("ql_bram_asymmetric",
+               "Detects memory cells with asymmetric read and write port widths implemented with shifts and infers custom asymmetric memory cell")
+    {
+    }
+
+    void help() override
+    {
+        log("\n");
+        log("    ql_bram_asymmetric\n");
+        log("\n");
+        log("		Detects memory cells with asymmetric read and write port widths implemented with shifts and infers custom asymmetric memory "
+            "cell");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing QL_BRAM_ASYMMETRIC pass.\n");
+
+        size_t argidx;
+        for (argidx = 1; argidx < a_Args.size(); argidx++) {
+            break;
+        }
+        extra_args(a_Args, argidx, a_Design);
+
+        int found_cells;
+        for (auto module : a_Design->selected_modules()) {
+            found_cells = ql_bram_asymmetric_wider_write_pm(module, module->selected_cells())
+                            .run_ql_bram_asymmetric_wider_write(test_ql_bram_asymmetric_wider_write);
+            log_debug("found %d cells matching for wider write port\n", found_cells);
+            found_cells = ql_bram_asymmetric_wider_read_pm(module, module->selected_cells())
+                            .run_ql_bram_asymmetric_wider_read(test_ql_bram_asymmetric_wider_read);
+            log_debug("found %d cells matching for wider read port\n", found_cells);
+        }
+    }
+} QLBramAsymmetric;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-bram-split.cc b/yosys-plugins/ql-qlf/ql-bram-split.cc
new file mode 100644
index 000000000..f699ee587
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-bram-split.cc
@@ -0,0 +1,327 @@
+// Copyright (C) 2020-2022  The SymbiFlow Authors.
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier:ISC
+
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+// ============================================================================
+
+struct QlBramSplitPass : public Pass {
+
+    QlBramSplitPass() : Pass("ql_bram_split", "Infers QuickLogic k6n10f BRAM pairs that can operate independently") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    ql_bram_split [selection]\n");
+        log("\n");
+        log("    This pass identifies k6n10f 18K BRAM cells\n");
+        log("    and packs pairs of them together into final TDP36K cell that can\n");
+        log("    be split into 2x18K BRAMs.\n");
+    }
+
+    // ..........................................
+
+    /// Describes BRAM config unique to a whole BRAM cell
+    struct BramConfig {
+
+        // Port connections
+        dict<RTLIL::IdString, RTLIL::SigSpec> connections;
+
+        // TODO: Possibly include parameters here. For now we have just
+        // connections.
+
+        BramConfig() = default;
+
+        BramConfig(const BramConfig &ref) = default;
+        BramConfig(BramConfig &&ref) = default;
+
+        unsigned int hash() const { return connections.hash(); }
+
+        bool operator==(const BramConfig &ref) const { return connections == ref.connections; }
+    };
+
+    // ..........................................
+
+    // BRAM control and config ports to consider and how to map them to ports
+    // of the target BRAM cell
+    const std::vector<std::pair<std::string, std::string>> m_BramSharedPorts = {};
+    // BRAM parameters
+    const std::vector<std::string> m_BramParams = {"CFG_ABITS", "CFG_DBITS"};
+
+    // TDP BRAM 1x18 data ports for subcell #1 and how to map them to ports of the target TDP BRAM 2x18 cell
+    const std::vector<std::pair<std::string, std::string>> m_BramTDPDataPorts_0 = {
+      std::make_pair("A1ADDR", "A1ADDR"), std::make_pair("A1DATA", "A1DATA"), std::make_pair("A1EN", "A1EN"),     std::make_pair("B1ADDR", "B1ADDR"),
+      std::make_pair("B1DATA", "B1DATA"), std::make_pair("B1EN", "B1EN"),     std::make_pair("C1ADDR", "C1ADDR"), std::make_pair("C1DATA", "C1DATA"),
+      std::make_pair("C1EN", "C1EN"),     std::make_pair("CLK1", "CLK1"),     std::make_pair("CLK2", "CLK2"),     std::make_pair("D1ADDR", "D1ADDR"),
+      std::make_pair("D1DATA", "D1DATA"), std::make_pair("D1EN", "D1EN")};
+    // TDP BRAM 1x18 data ports for subcell #2 and how to map them to ports of the target TDP BRAM 2x18 cell
+    const std::vector<std::pair<std::string, std::string>> m_BramTDPDataPorts_1 = {
+      std::make_pair("A1ADDR", "E1ADDR"), std::make_pair("A1DATA", "E1DATA"), std::make_pair("A1EN", "E1EN"),     std::make_pair("B1ADDR", "F1ADDR"),
+      std::make_pair("B1DATA", "F1DATA"), std::make_pair("B1EN", "F1EN"),     std::make_pair("C1ADDR", "G1ADDR"), std::make_pair("C1DATA", "G1DATA"),
+      std::make_pair("C1EN", "G1EN"),     std::make_pair("CLK1", "CLK3"),     std::make_pair("CLK2", "CLK4"),     std::make_pair("D1ADDR", "H1ADDR"),
+      std::make_pair("D1DATA", "H1DATA"), std::make_pair("D1EN", "H1EN")};
+    // Source BRAM TDP cell type (1x18K)
+    const std::string m_Bram1x18TDPType = "$__QLF_FACTOR_BRAM18_TDP";
+    // Target BRAM TDP cell type for the split mode
+    const std::string m_Bram2x18TDPType = "BRAM2x18_TDP";
+
+    // SDP BRAM 1x18 data ports for subcell #1 and how to map them to ports of the target SDP BRAM 2x18 cell
+    const std::vector<std::pair<std::string, std::string>> m_BramSDPDataPorts_0 = {
+      std::make_pair("A1ADDR", "A1ADDR"), std::make_pair("A1DATA", "A1DATA"), std::make_pair("A1EN", "A1EN"), std::make_pair("B1ADDR", "B1ADDR"),
+      std::make_pair("B1DATA", "B1DATA"), std::make_pair("B1EN", "B1EN"),     std::make_pair("CLK1", "CLK1")};
+    // SDP BRAM 1x18 data ports for subcell #2 and how to map them to ports of the target SDP BRAM 2x18 cell
+    const std::vector<std::pair<std::string, std::string>> m_BramSDPDataPorts_1 = {
+      std::make_pair("A1ADDR", "C1ADDR"), std::make_pair("A1DATA", "C1DATA"), std::make_pair("A1EN", "C1EN"), std::make_pair("B1ADDR", "D1ADDR"),
+      std::make_pair("B1DATA", "D1DATA"), std::make_pair("B1EN", "D1EN"),     std::make_pair("CLK1", "CLK2")};
+    // Source BRAM SDP cell type (1x18K)
+    const std::string m_Bram1x18SDPType = "$__QLF_FACTOR_BRAM18_SDP";
+    // Target BRAM SDP cell type for the split mode
+    const std::string m_Bram2x18SDPType = "BRAM2x18_SDP";
+
+    /// Temporary SigBit to SigBit helper map.
+    SigMap m_SigMap;
+
+    // ..........................................
+
+    void map_ports(const std::vector<std::pair<std::string, std::string>> mapping, const RTLIL::Cell *bram_1x18, RTLIL::Cell *bram_2x18)
+    {
+        for (const auto &it : mapping) {
+            auto src = RTLIL::escape_id(it.first);
+            auto dst = RTLIL::escape_id(it.second);
+
+            size_t width;
+            bool isOutput;
+
+            std::tie(width, isOutput) = getPortInfo(bram_2x18, dst);
+
+            auto getConnection = [&](const RTLIL::Cell *cell) {
+                RTLIL::SigSpec sigspec;
+                if (cell->hasPort(src)) {
+                    const auto &sig = cell->getPort(src);
+                    sigspec.append(sig);
+                }
+                if (sigspec.bits().size() < width / 2) {
+                    if (isOutput) {
+                        for (size_t i = 0; i < width / 2 - sigspec.bits().size(); ++i) {
+                            sigspec.append(RTLIL::SigSpec());
+                        }
+                    } else {
+                        sigspec.append(RTLIL::SigSpec(RTLIL::Sx, width / 2 - sigspec.bits().size()));
+                    }
+                }
+                return sigspec;
+            };
+
+            RTLIL::SigSpec sigspec;
+            sigspec.append(getConnection(bram_1x18));
+            bram_2x18->setPort(dst, sigspec);
+        }
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing QL_BRAM_Split pass.\n");
+
+        // Parse args
+        extra_args(a_Args, 1, a_Design);
+
+        // Process modules
+        for (auto module : a_Design->selected_modules()) {
+
+            // Setup the SigMap
+            m_SigMap.clear();
+            m_SigMap.set(module);
+
+            // Assemble BRAM cell groups
+            dict<BramConfig, std::vector<RTLIL::Cell *>> groups;
+            for (auto cell : module->selected_cells()) {
+
+                // Check if this is a BRAM cell
+                if (cell->type != RTLIL::escape_id(m_Bram1x18TDPType) && cell->type != RTLIL::escape_id(m_Bram1x18SDPType)) {
+                    continue;
+                }
+
+                // Skip if it has the (* keep *) attribute set
+                if (cell->has_keep_attr()) {
+                    continue;
+                }
+
+                // Add to a group
+                const auto key = getBramConfig(cell);
+                groups[key].push_back(cell);
+            }
+
+            std::vector<const RTLIL::Cell *> cellsToRemove;
+
+            // Map cell pairs to the target BRAM 2x18 cell
+            for (const auto &it : groups) {
+                const auto &group = it.second;
+                const auto &config = it.first;
+
+                // Ensure an even number
+                size_t count = group.size();
+                if (count & 1)
+                    count--;
+
+                // Map SIMD pairs
+                for (size_t i = 0; i < count; i += 2) {
+                    const RTLIL::Cell *bram_0 = group[i];
+                    const RTLIL::Cell *bram_1 = group[i + 1];
+
+                    if (bram_0->type != bram_1->type)
+                        log_error("Unsupported BRAM configuration: one half of TDP36K is TDP, second SDP");
+
+                    std::vector<std::pair<std::string, std::string>> m_BramDataPorts_0;
+                    std::vector<std::pair<std::string, std::string>> m_BramDataPorts_1;
+                    std::string m_Bram1x18Type;
+                    std::string m_Bram2x18Type;
+                    // Distinguish between TDP and SDP
+                    if (bram_0->type == RTLIL::escape_id(m_Bram1x18TDPType)) {
+                        m_BramDataPorts_0 = m_BramTDPDataPorts_0;
+                        m_BramDataPorts_1 = m_BramTDPDataPorts_1;
+                        m_Bram1x18Type = m_Bram1x18TDPType;
+                        m_Bram2x18Type = m_Bram2x18TDPType;
+                    } else {
+                        m_BramDataPorts_0 = m_BramSDPDataPorts_0;
+                        m_BramDataPorts_1 = m_BramSDPDataPorts_1;
+                        m_Bram1x18Type = m_Bram1x18SDPType;
+                        m_Bram2x18Type = m_Bram2x18SDPType;
+                    }
+
+                    std::string name = stringf("bram_%s_%s", RTLIL::unescape_id(bram_0->name).c_str(), RTLIL::unescape_id(bram_1->name).c_str());
+
+                    log(" BRAM: %s (%s) + %s (%s) => %s (%s)\n", RTLIL::unescape_id(bram_0->name).c_str(), RTLIL::unescape_id(bram_0->type).c_str(),
+                        RTLIL::unescape_id(bram_1->name).c_str(), RTLIL::unescape_id(bram_1->type).c_str(), RTLIL::unescape_id(name).c_str(),
+                        m_Bram2x18Type.c_str());
+
+                    // Create the new cell
+                    RTLIL::Cell *bram_2x18 = module->addCell(RTLIL::escape_id(name), RTLIL::escape_id(m_Bram2x18Type));
+
+                    // Check if the target cell is known (important to know
+                    // its port widths)
+                    if (!bram_2x18->known()) {
+                        log_error(" The target cell type '%s' is not known!", m_Bram2x18Type.c_str());
+                    }
+
+                    // Connect shared ports
+                    for (const auto &it : m_BramSharedPorts) {
+                        auto src = RTLIL::escape_id(it.first);
+                        auto dst = RTLIL::escape_id(it.second);
+
+                        bram_2x18->setPort(dst, config.connections.at(src));
+                    }
+
+                    // Connect data ports
+                    // Connect first bram
+                    map_ports(m_BramDataPorts_0, bram_0, bram_2x18);
+                    // Connect second bram
+                    map_ports(m_BramDataPorts_1, bram_1, bram_2x18);
+
+                    // Set bram parameters
+                    for (const auto &it : m_BramParams) {
+                        auto val = bram_0->getParam(RTLIL::escape_id(it));
+                        bram_2x18->setParam(RTLIL::escape_id(it), val);
+                    }
+
+                    // Setting manual parameters
+                    if (bram_0->type == RTLIL::escape_id(m_Bram1x18TDPType)) {
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_B"), bram_0->getParam(RTLIL::escape_id("CFG_ENABLE_B")));
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_D"), bram_0->getParam(RTLIL::escape_id("CFG_ENABLE_D")));
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_F"), bram_1->getParam(RTLIL::escape_id("CFG_ENABLE_B")));
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_H"), bram_1->getParam(RTLIL::escape_id("CFG_ENABLE_D")));
+                    } else {
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_B"), bram_0->getParam(RTLIL::escape_id("CFG_ENABLE_B")));
+                        bram_2x18->setParam(RTLIL::escape_id("CFG_ENABLE_D"), bram_1->getParam(RTLIL::escape_id("CFG_ENABLE_B")));
+                    }
+                    if (bram_0->hasParam(RTLIL::escape_id("INIT")))
+                        bram_2x18->setParam(RTLIL::escape_id("INIT0"), bram_0->getParam(RTLIL::escape_id("INIT")));
+                    if (bram_1->hasParam(RTLIL::escape_id("INIT")))
+                        bram_2x18->setParam(RTLIL::escape_id("INIT1"), bram_1->getParam(RTLIL::escape_id("INIT")));
+
+                    // Mark BRAM parts for removal
+                    cellsToRemove.push_back(bram_0);
+                    cellsToRemove.push_back(bram_1);
+                }
+            }
+
+            // Remove old cells
+            for (const auto &cell : cellsToRemove) {
+                module->remove(const_cast<RTLIL::Cell *>(cell));
+            }
+        }
+
+        // Clear
+        m_SigMap.clear();
+    }
+
+    // ..........................................
+
+    /// Looks up port width and direction in the cell definition and returns it.
+    /// Returns (0, false) if it cannot be determined.
+    std::pair<size_t, bool> getPortInfo(RTLIL::Cell *a_Cell, RTLIL::IdString a_Port)
+    {
+        if (!a_Cell->known()) {
+            return std::make_pair(0, false);
+        }
+
+        // Get the module defining the cell (the previous condition ensures
+        // that the pointers are valid)
+        RTLIL::Module *mod = a_Cell->module->design->module(a_Cell->type);
+        if (mod == nullptr) {
+            return std::make_pair(0, false);
+        }
+
+        // Get the wire representing the port
+        RTLIL::Wire *wire = mod->wire(a_Port);
+        if (wire == nullptr) {
+            return std::make_pair(0, false);
+        }
+
+        return std::make_pair(wire->width, wire->port_output);
+    }
+
+    /// Given a BRAM cell populates and returns a BramConfig struct for it.
+    BramConfig getBramConfig(RTLIL::Cell *a_Cell)
+    {
+        BramConfig config;
+
+        for (const auto &it : m_BramSharedPorts) {
+            auto port = RTLIL::escape_id(it.first);
+
+            // Port unconnected
+            if (!a_Cell->hasPort(port)) {
+                config.connections[port] = RTLIL::SigSpec(RTLIL::Sx);
+                continue;
+            }
+
+            // Get the port connection and map it to unique SigBits
+            const auto &orgSigSpec = a_Cell->getPort(port);
+            const auto &orgSigBits = orgSigSpec.bits();
+
+            RTLIL::SigSpec newSigSpec;
+            for (size_t i = 0; i < orgSigBits.size(); ++i) {
+                auto newSigBit = m_SigMap(orgSigBits[i]);
+                newSigSpec.append(newSigBit);
+            }
+
+            // Store
+            config.connections[port] = newSigSpec;
+        }
+
+        return config;
+    }
+
+} QlBramSplitPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-dsp-io-regs.cc b/yosys-plugins/ql-qlf/ql-dsp-io-regs.cc
new file mode 100644
index 000000000..b7e9117e6
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-dsp-io-regs.cc
@@ -0,0 +1,225 @@
+#include "kernel/sigtools.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#define MODE_BITS_REGISTER_INPUTS_ID 92
+#define MODE_BITS_OUTPUT_SELECT_START_ID 81
+#define MODE_BITS_OUTPUT_SELECT_WIDTH 3
+
+// ============================================================================
+
+struct QlDspIORegs : public Pass {
+
+    const std::vector<std::string> ports2del_mult = {"load_acc", "subtract", "acc_fir", "dly_b"};
+    const std::vector<std::string> ports2del_mult_acc = {"acc_fir", "dly_b"};
+    const std::vector<std::string> ports2del_mult_add = {"dly_b"};
+    const std::vector<std::string> ports2del_extension = {"saturate_enable", "shift_right", "round"};
+
+    /// Temporary SigBit to SigBit helper map.
+    SigMap m_SigMap;
+
+    // ..........................................
+
+    QlDspIORegs() : Pass("ql_dsp_io_regs", "Changes types of QL_DSP2/QL_DSP3 depending on their configuration.") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    ql_dsp_io_regs [options] [selection]\n");
+        log("\n");
+        log("Looks for QL_DSP2/QL_DSP3 cells and changes their types depending\n");
+        log("on their configuration.\n");
+    }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing QL_DSP_IO_REGS pass.\n");
+
+        size_t argidx;
+        for (argidx = 1; argidx < a_Args.size(); argidx++) {
+            break;
+        }
+        extra_args(a_Args, argidx, a_Design);
+
+        for (auto module : a_Design->selected_modules()) {
+            ql_dsp_io_regs_pass(module);
+        }
+    }
+
+    // Returns a pair of mask and value describing constant bit connections of
+    // a SigSpec
+    std::pair<uint32_t, uint32_t> get_constant_mask_value(const RTLIL::SigSpec *sigspec)
+    {
+        uint32_t mask = 0L;
+        uint32_t value = 0L;
+
+        auto sigbits = sigspec->bits();
+        for (ssize_t i = (sigbits.size() - 1); i >= 0; --i) {
+            auto other = m_SigMap(sigbits[i]);
+
+            mask <<= 1;
+            value <<= 1;
+
+            // A known constant
+            if (!other.is_wire() && other.data != RTLIL::Sx) {
+                mask |= 0x1;
+                value |= (other.data == RTLIL::S1);
+            }
+        }
+
+        return std::make_pair(mask, value);
+    }
+
+    void ql_dsp_io_regs_pass(RTLIL::Module *module)
+    {
+        // Setup the SigMap
+        m_SigMap.clear();
+        m_SigMap.set(module);
+
+        for (auto cell : module->cells_) {
+            std::string cell_type = cell.second->type.str();
+            if (cell_type == RTLIL::escape_id("QL_DSP2") || cell_type == RTLIL::escape_id("QL_DSP3")) {
+                auto dsp = cell.second;
+
+                // If the cell does not have the "is_inferred" attribute set
+                // then don't touch it.
+                if (!dsp->has_attribute(RTLIL::escape_id("is_inferred")) || dsp->get_bool_attribute(RTLIL::escape_id("is_inferred")) == false) {
+                    continue;
+                }
+
+                bool del_clk = true;
+                bool use_dsp_cfg_params = (cell_type == RTLIL::escape_id("QL_DSP3"));
+
+                int reg_in_i;
+                int out_sel_i;
+
+                // Get DSP configuration
+                if (use_dsp_cfg_params) {
+                    // Read MODE_BITS at correct indexes
+                    auto mode_bits = &dsp->getParam(RTLIL::escape_id("MODE_BITS"));
+                    RTLIL::Const register_inputs;
+                    register_inputs = mode_bits->bits.at(MODE_BITS_REGISTER_INPUTS_ID);
+                    reg_in_i = register_inputs.as_int();
+
+                    RTLIL::Const output_select;
+                    output_select = mode_bits->extract(MODE_BITS_OUTPUT_SELECT_START_ID, MODE_BITS_OUTPUT_SELECT_WIDTH);
+                    out_sel_i = output_select.as_int();
+                } else {
+                    // Read dedicated configuration ports
+                    const RTLIL::SigSpec *register_inputs;
+                    register_inputs = &dsp->getPort(RTLIL::escape_id("register_inputs"));
+                    if (!register_inputs)
+                        log_error("register_inputs port not found!");
+                    auto reg_in_c = register_inputs->as_const();
+                    reg_in_i = reg_in_c.as_int();
+
+                    const RTLIL::SigSpec *output_select;
+                    output_select = &dsp->getPort(RTLIL::escape_id("output_select"));
+                    if (!output_select)
+                        log_error("output_select port not found!");
+                    auto out_sel_c = output_select->as_const();
+                    out_sel_i = out_sel_c.as_int();
+                }
+
+                // Get the feedback port
+                const RTLIL::SigSpec *feedback;
+                feedback = &dsp->getPort(RTLIL::escape_id("feedback"));
+                if (!feedback)
+                    log_error("feedback port not found!");
+
+                // Check if feedback is or can be set to 0 which implies MACC
+                auto feedback_con = get_constant_mask_value(feedback);
+                bool have_macc = (feedback_con.second == 0x0);
+                // log("mask=0x%08X value=0x%08X\n", consts.first, consts.second);
+                // log_error("=== END HERE ===\n");
+
+                // Build new type name
+                std::string new_type = cell_type;
+                new_type += "_MULT";
+
+                if (have_macc) {
+                    switch (out_sel_i) {
+                    case 1:
+                    case 2:
+                    case 3:
+                    case 5:
+                    case 7:
+                        del_clk = false;
+                        new_type += "ACC";
+                        break;
+                    default:
+                        break;
+                    }
+                } else {
+                    switch (out_sel_i) {
+                    case 1:
+                    case 2:
+                    case 3:
+                    case 5:
+                    case 7:
+                        new_type += "ADD";
+                        break;
+                    default:
+                        break;
+                    }
+                }
+
+                if (reg_in_i) {
+                    del_clk = false;
+                    new_type += "_REGIN";
+                }
+
+                if (out_sel_i > 3) {
+                    del_clk = false;
+                    new_type += "_REGOUT";
+                }
+
+                // Set new type name
+                dsp->type = RTLIL::IdString(new_type);
+
+                std::vector<std::string> ports2del;
+
+                if (del_clk)
+                    ports2del.push_back("clk");
+
+                switch (out_sel_i) {
+                case 0:
+                case 4:
+                case 6:
+                    ports2del.insert(ports2del.end(), ports2del_mult.begin(), ports2del_mult.end());
+                    // Mark for deleton additional configuration ports
+                    if (!use_dsp_cfg_params) {
+                        ports2del.insert(ports2del.end(), ports2del_extension.begin(), ports2del_extension.end());
+                    }
+                    break;
+                case 1:
+                case 2:
+                case 3:
+                case 5:
+                case 7:
+                    if (have_macc) {
+                        ports2del.insert(ports2del.end(), ports2del_mult_acc.begin(), ports2del_mult_acc.end());
+                    } else {
+                        ports2del.insert(ports2del.end(), ports2del_mult_add.begin(), ports2del_mult_add.end());
+                    }
+                    break;
+                }
+
+                for (auto portname : ports2del) {
+                    const RTLIL::SigSpec *port = &dsp->getPort(RTLIL::escape_id(portname));
+                    if (!port)
+                        log_error("%s port not found!", portname.c_str());
+                    dsp->connections_.erase(RTLIL::escape_id(portname));
+                }
+            }
+        }
+
+        // Clear the sigmap
+        m_SigMap.clear();
+    }
+
+} QlDspIORegs;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-dsp-macc.cc b/yosys-plugins/ql-qlf/ql-dsp-macc.cc
new file mode 100644
index 000000000..4fdfff1ca
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-dsp-macc.cc
@@ -0,0 +1,288 @@
+#include "kernel/sigtools.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#include "pmgen/ql-dsp-macc.h"
+
+// ============================================================================
+
+bool use_dsp_cfg_params;
+
+static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
+{
+    auto &st = pm.st_ql_dsp_macc;
+
+    // Reject if multiplier drives anything else than either $add or $add and
+    // $mux
+    if (st.mux == nullptr && st.mul_nusers > 2) {
+        return;
+    }
+
+    // Determine whether the output is taken from before or after the ff
+    bool out_ff;
+    if (st.ff_d_nusers == 2 && st.ff_q_nusers == 3) {
+        out_ff = true;
+    } else if (st.ff_d_nusers == 3 && st.ff_q_nusers == 2) {
+        out_ff = false;
+    } else {
+        // Illegal, cannot take the two outputs simulataneously
+        return;
+    }
+
+    // No mux, the adder can driver either the ff or the ff + output
+    if (st.mux == nullptr) {
+        if (out_ff && st.add_nusers != 2) {
+            return;
+        }
+        if (!out_ff && st.add_nusers != 3) {
+            return;
+        }
+    }
+    // Mux present, the adder cannot drive anything else
+    else {
+        if (st.add_nusers != 2) {
+            return;
+        }
+    }
+
+    // Mux can driver either the ff or the ff + output
+    if (st.mux != nullptr) {
+        if (out_ff && st.mux_nusers != 2) {
+            return;
+        }
+        if (!out_ff && st.mux_nusers != 3) {
+            return;
+        }
+    }
+
+    // Accept only posedge clocked FFs
+    if (st.ff->getParam(ID(CLK_POLARITY)).as_int() != 1) {
+        return;
+    }
+
+    // Get port widths
+    size_t a_width = GetSize(st.mul->getPort(ID(A)));
+    size_t b_width = GetSize(st.mul->getPort(ID(B)));
+    size_t z_width = GetSize(st.ff->getPort(ID(Q)));
+
+    size_t min_width = std::min(a_width, b_width);
+    size_t max_width = std::max(a_width, b_width);
+
+    // Signed / unsigned
+    bool a_signed = st.mul->getParam(ID(A_SIGNED)).as_bool();
+    bool b_signed = st.mul->getParam(ID(B_SIGNED)).as_bool();
+
+    // Determine DSP type or discard if too narrow / wide
+    RTLIL::IdString type;
+    size_t tgt_a_width;
+    size_t tgt_b_width;
+    size_t tgt_z_width;
+
+    string cell_base_name = "dsp_t1";
+    string cell_size_name = "";
+    string cell_cfg_name = "";
+    string cell_full_name = "";
+
+    if (min_width <= 2 && max_width <= 2 && z_width <= 4) {
+        // Too narrow
+        return;
+    } else if (min_width <= 9 && max_width <= 10 && z_width <= 19) {
+        cell_size_name = "_10x9x32";
+        tgt_a_width = 10;
+        tgt_b_width = 9;
+        tgt_z_width = 19;
+    } else if (min_width <= 18 && max_width <= 20 && z_width <= 38) {
+        cell_size_name = "_20x18x64";
+        tgt_a_width = 20;
+        tgt_b_width = 18;
+        tgt_z_width = 38;
+    } else {
+        // Too wide
+        return;
+    }
+
+    if (use_dsp_cfg_params)
+        cell_cfg_name = "_cfg_params";
+    else
+        cell_cfg_name = "_cfg_ports";
+
+    cell_full_name = cell_base_name + cell_size_name + cell_cfg_name;
+
+    type = RTLIL::escape_id(cell_full_name);
+    log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, RTLIL::unescape_id(type).c_str());
+
+    for (auto cell : {st.mul, st.add, st.mux, st.ff}) {
+        if (cell != nullptr) {
+            log(" %s (%s)\n", RTLIL::unescape_id(cell->name).c_str(), RTLIL::unescape_id(cell->type).c_str());
+        }
+    }
+
+    // Build the DSP cell name
+    std::string name;
+    name += RTLIL::unescape_id(st.mul->name) + "_";
+    name += RTLIL::unescape_id(st.add->name) + "_";
+    if (st.mux != nullptr) {
+        name += RTLIL::unescape_id(st.mux->name) + "_";
+    }
+    name += RTLIL::unescape_id(st.ff->name);
+
+    // Add the DSP cell
+    RTLIL::Cell *cell = pm.module->addCell(RTLIL::escape_id(name), type);
+
+    // Set attributes
+    cell->set_bool_attribute(RTLIL::escape_id("is_inferred"), true);
+
+    // Get input/output data signals
+    RTLIL::SigSpec sig_a;
+    RTLIL::SigSpec sig_b;
+    RTLIL::SigSpec sig_z;
+
+    if (a_width >= b_width) {
+        sig_a = st.mul->getPort(ID(A));
+        sig_b = st.mul->getPort(ID(B));
+    } else {
+        sig_a = st.mul->getPort(ID(B));
+        sig_b = st.mul->getPort(ID(A));
+    }
+
+    sig_z = out_ff ? st.ff->getPort(ID(Q)) : st.ff->getPort(ID(D));
+
+    // Connect input data ports, sign extend / pad with zeros
+    sig_a.extend_u0(tgt_a_width, a_signed);
+    sig_b.extend_u0(tgt_b_width, b_signed);
+    cell->setPort(RTLIL::escape_id("a_i"), sig_a);
+    cell->setPort(RTLIL::escape_id("b_i"), sig_b);
+
+    // Connect output data port, pad if needed
+    if ((size_t)GetSize(sig_z) < tgt_z_width) {
+        auto *wire = pm.module->addWire(NEW_ID, tgt_z_width - GetSize(sig_z));
+        sig_z.append(wire);
+    }
+    cell->setPort(RTLIL::escape_id("z_o"), sig_z);
+
+    // Connect clock, reset and enable
+    cell->setPort(RTLIL::escape_id("clock_i"), st.ff->getPort(ID(CLK)));
+
+    RTLIL::SigSpec rst;
+    RTLIL::SigSpec ena;
+
+    if (st.ff->hasPort(ID(ARST))) {
+        if (st.ff->getParam(ID(ARST_POLARITY)).as_int() != 1) {
+            rst = pm.module->Not(NEW_ID, st.ff->getPort(ID(ARST)));
+        } else {
+            rst = st.ff->getPort(ID(ARST));
+        }
+    } else {
+        rst = RTLIL::SigSpec(RTLIL::S0);
+    }
+
+    if (st.ff->hasPort(ID(EN))) {
+        if (st.ff->getParam(ID(EN_POLARITY)).as_int() != 1) {
+            ena = pm.module->Not(NEW_ID, st.ff->getPort(ID(EN)));
+        } else {
+            ena = st.ff->getPort(ID(EN));
+        }
+    } else {
+        ena = RTLIL::SigSpec(RTLIL::S1);
+    }
+
+    cell->setPort(RTLIL::escape_id("reset_i"), rst);
+    cell->setPort(RTLIL::escape_id("load_acc_i"), ena);
+
+    // Insert feedback_i control logic used for clearing / loading the accumulator
+    if (st.mux != nullptr) {
+        RTLIL::SigSpec sig_s = st.mux->getPort(ID(S));
+
+        // Depending on the mux port ordering insert inverter if needed
+        log_assert(st.mux_ab == ID(A) || st.mux_ab == ID(B));
+        if (st.mux_ab == ID(A)) {
+            sig_s = pm.module->Not(NEW_ID, sig_s);
+        }
+
+        // Assemble the full control signal for the feedback_i port
+        RTLIL::SigSpec sig_f;
+        sig_f.append(sig_s);
+        sig_f.append(RTLIL::S0);
+        sig_f.append(RTLIL::S0);
+        cell->setPort(RTLIL::escape_id("feedback_i"), sig_f);
+    }
+    // No acc clear/load
+    else {
+        cell->setPort(RTLIL::escape_id("feedback_i"), RTLIL::SigSpec(RTLIL::S0, 3));
+    }
+
+    // Connect control ports
+    cell->setPort(RTLIL::escape_id("unsigned_a_i"), RTLIL::SigSpec(a_signed ? RTLIL::S0 : RTLIL::S1));
+    cell->setPort(RTLIL::escape_id("unsigned_b_i"), RTLIL::SigSpec(b_signed ? RTLIL::S0 : RTLIL::S1));
+
+    // Connect config bits
+    if (use_dsp_cfg_params) {
+        cell->setParam(RTLIL::escape_id("SATURATE_ENABLE"), RTLIL::Const(RTLIL::S0));
+        cell->setParam(RTLIL::escape_id("SHIFT_RIGHT"), RTLIL::Const(RTLIL::S0, 6));
+        cell->setParam(RTLIL::escape_id("ROUND"), RTLIL::Const(RTLIL::S0));
+        cell->setParam(RTLIL::escape_id("REGISTER_INPUTS"), RTLIL::Const(RTLIL::S0));
+        // 3 - output post acc; 1 - output pre acc
+        cell->setParam(RTLIL::escape_id("OUTPUT_SELECT"), out_ff ? RTLIL::Const(1, 3) : RTLIL::Const(3, 3));
+    } else {
+        cell->setPort(RTLIL::escape_id("saturate_enable_i"), RTLIL::SigSpec(RTLIL::S0));
+        cell->setPort(RTLIL::escape_id("shift_right_i"), RTLIL::SigSpec(RTLIL::S0, 6));
+        cell->setPort(RTLIL::escape_id("round_i"), RTLIL::SigSpec(RTLIL::S0));
+        cell->setPort(RTLIL::escape_id("register_inputs_i"), RTLIL::SigSpec(RTLIL::S0));
+        // 3 - output post acc; 1 - output pre acc
+        cell->setPort(RTLIL::escape_id("output_select_i"), out_ff ? RTLIL::Const(1, 3) : RTLIL::Const(3, 3));
+    }
+
+    bool subtract = (st.add->type == RTLIL::escape_id("$sub"));
+    cell->setPort(RTLIL::escape_id("subtract_i"), RTLIL::SigSpec(subtract ? RTLIL::S1 : RTLIL::S0));
+
+    // Mark the cells for removal
+    pm.autoremove(st.mul);
+    pm.autoremove(st.add);
+    if (st.mux != nullptr) {
+        pm.autoremove(st.mux);
+    }
+    pm.autoremove(st.ff);
+}
+
+struct QlDspMacc : public Pass {
+
+    QlDspMacc() : Pass("ql_dsp_macc", "Does something") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    ql_dsp_macc [options] [selection]\n");
+        log("\n");
+        log("    -use_dsp_cfg_params\n");
+        log("        By default use DSP blocks with configuration bits available at module ports.\n");
+        log("        Specifying this forces usage of DSP block with configuration bits available as module parameters\n");
+        log("\n");
+    }
+
+    void clear_flags() override { use_dsp_cfg_params = false; }
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing QL_DSP_MACC pass.\n");
+
+        size_t argidx;
+        for (argidx = 1; argidx < a_Args.size(); argidx++) {
+            if (a_Args[argidx] == "-use_dsp_cfg_params") {
+                use_dsp_cfg_params = true;
+                continue;
+            }
+
+            break;
+        }
+        extra_args(a_Args, argidx, a_Design);
+
+        for (auto module : a_Design->selected_modules()) {
+            ql_dsp_macc_pm(module, module->selected_cells()).run_ql_dsp_macc(create_ql_macc_dsp);
+        }
+    }
+
+} QlDspMacc;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-dsp-macc.pmg b/yosys-plugins/ql-qlf/ql-dsp-macc.pmg
new file mode 100644
index 000000000..4cfd15a24
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-dsp-macc.pmg
@@ -0,0 +1,50 @@
+pattern ql_dsp_macc
+
+state <IdString> add_ba
+state <IdString> mux_ab
+
+state <int> mul_nusers
+state <int> add_nusers
+state <int> mux_nusers
+state <int> ff_d_nusers
+state <int> ff_q_nusers
+
+match mul
+    select mul->type.in($mul)
+    select nusers(port(mul, \Y)) <= 3
+    set mul_nusers nusers(port(mul, \Y))
+endmatch
+
+match add
+    select add->type.in($add, $sub)
+    choice <IdString> AB {\A, \B}
+    define <IdString> BA (AB == \A ? \B : \A)
+    index <SigSpec> port(add, AB) === port(mul, \Y)
+    select nusers(port(add, \Y)) <= 3
+    set add_nusers nusers(port(add, \Y))
+    set add_ba BA
+endmatch
+
+match mux
+    select mux->type.in($mux)
+    choice <IdString> AB {\A, \B}
+    define <IdString> BA (AB == \A ? \B : \A)
+    index <SigSpec> port(mux, AB) === port(mul, \Y)
+    index <SigSpec> port(mux, BA) === port(add, \Y)
+    select nusers(port(mux, \Y)) <= 3
+    set mux_nusers nusers(port(mux, \Y))
+    set mux_ab AB
+    optional
+endmatch
+
+match ff
+    select ff->type.in($dff, $adff, $dffe, $adffe)
+    index <SigSpec> port(ff, \D) === (mux == nullptr ? port(add, \Y) : port(mux, \Y))
+    index <SigSpec> port(ff, \Q) === port(add, add_ba)
+    set ff_d_nusers nusers(port(ff, \D))
+    set ff_q_nusers nusers(port(ff, \Q))
+endmatch
+
+code
+    accept;
+endcode
diff --git a/yosys-plugins/ql-qlf/ql-dsp-simd.cc b/yosys-plugins/ql-qlf/ql-dsp-simd.cc
new file mode 100644
index 000000000..7893eb493
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-dsp-simd.cc
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#define MODE_BITS_BASE_SIZE 80
+#define MODE_BITS_EXTENSION_SIZE 13
+
+// ============================================================================
+
+struct QlDspSimdPass : public Pass {
+
+    QlDspSimdPass() : Pass("ql_dsp_simd", "Infers QuickLogic k6n10f DSP pairs that can operate in SIMD mode") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    ql_dsp_simd [selection]\n");
+        log("\n");
+        log("    This pass identifies k6n10f DSP cells with identical configuration\n");
+        log("    and packs pairs of them together into other DSP cells that can\n");
+        log("    perform SIMD operation.\n");
+    }
+
+    // ..........................................
+
+    /// Describes DSP config unique to a whole DSP cell
+    struct DspConfig {
+
+        // Port connections
+        dict<RTLIL::IdString, RTLIL::SigSpec> connections;
+
+        // Whether DSPs pass configuration bits through ports of parameters
+        bool use_cfg_params;
+
+        // TODO: Possibly include parameters here. For now we have just
+        // connections.
+
+        DspConfig() = default;
+
+        DspConfig(const DspConfig &ref) = default;
+        DspConfig(DspConfig &&ref) = default;
+
+        unsigned int hash() const { return connections.hash(); }
+
+        bool operator==(const DspConfig &ref) const { return connections == ref.connections && use_cfg_params == ref.use_cfg_params; }
+    };
+
+    // ..........................................
+
+    // DSP control and config ports to consider and how to map them to ports
+    // of the target DSP cell
+    const std::vector<std::pair<std::string, std::string>> m_DspCfgPorts = {std::make_pair("clock_i", "clk"),
+                                                                            std::make_pair("reset_i", "reset"),
+
+                                                                            std::make_pair("feedback_i", "feedback"),
+                                                                            std::make_pair("load_acc_i", "load_acc"),
+                                                                            std::make_pair("unsigned_a_i", "unsigned_a"),
+                                                                            std::make_pair("unsigned_b_i", "unsigned_b"),
+
+                                                                            std::make_pair("subtract_i", "subtract")};
+    // For QL_DSP2 expand with configuration ports
+    const std::vector<std::pair<std::string, std::string>> m_DspCfgPorts_expand = {
+      std::make_pair("output_select_i", "output_select"), std::make_pair("saturate_enable_i", "saturate_enable"),
+      std::make_pair("shift_right_i", "shift_right"), std::make_pair("round_i", "round"), std::make_pair("register_inputs_i", "register_inputs")};
+
+    // For QL_DSP3 use parameters instead
+    const std::vector<std::string> m_DspParams2Mode = {"OUTPUT_SELECT", "SATURATE_ENABLE", "SHIFT_RIGHT", "ROUND", "REGISTER_INPUTS"};
+
+    // DSP data ports and how to map them to ports of the target DSP cell
+    const std::vector<std::pair<std::string, std::string>> m_DspDataPorts = {
+      std::make_pair("a_i", "a"), std::make_pair("b_i", "b"),         std::make_pair("acc_fir_i", "acc_fir"),
+      std::make_pair("z_o", "z"), std::make_pair("dly_b_o", "dly_b"),
+    };
+
+    // DSP parameters
+    const std::vector<std::string> m_DspParams = {"COEFF_3", "COEFF_2", "COEFF_1", "COEFF_0"};
+
+    // Source DSP cell type (SISD)
+    const std::string m_SisdDspType = "dsp_t1_10x9x32";
+    // Suffix for DSP cell with configuration parameters
+    const std::string m_SisdDspType_cfg_params_suffix = "_cfg_params";
+
+    // Target DSP cell types for the SIMD mode
+    const std::string m_SimdDspType_cfg_ports = "QL_DSP2";
+    const std::string m_SimdDspType_cfg_params = "QL_DSP3";
+
+    /// Temporary SigBit to SigBit helper map.
+    SigMap m_SigMap;
+
+    // ..........................................
+
+    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
+    {
+        log_header(a_Design, "Executing QL_DSP_SIMD pass.\n");
+
+        // Parse args
+        extra_args(a_Args, 1, a_Design);
+
+        // Process modules
+        for (auto module : a_Design->selected_modules()) {
+
+            // Setup the SigMap
+            m_SigMap.clear();
+            m_SigMap.set(module);
+
+            // Assemble DSP cell groups
+            dict<DspConfig, std::vector<RTLIL::Cell *>> groups;
+            for (auto cell : module->selected_cells()) {
+
+                // Check if this is a DSP cell we are looking for (type starts with m_SisdDspType)
+                if (strncmp(cell->type.c_str(), RTLIL::escape_id(m_SisdDspType).c_str(), RTLIL::escape_id(m_SisdDspType).size()) != 0) {
+                    continue;
+                }
+
+                // Skip if it has the (* keep *) attribute set
+                if (cell->has_keep_attr()) {
+                    continue;
+                }
+
+                // Add to a group
+                const auto key = getDspConfig(cell);
+                groups[key].push_back(cell);
+            }
+
+            std::vector<const RTLIL::Cell *> cellsToRemove;
+
+            // Map cell pairs to the target DSP SIMD cell
+            for (const auto &it : groups) {
+                const auto &group = it.second;
+                const auto &config = it.first;
+
+                bool use_cfg_params = config.use_cfg_params;
+                // Ensure an even number
+                size_t count = group.size();
+                if (count & 1)
+                    count--;
+
+                // Map SIMD pairs
+                for (size_t i = 0; i < count; i += 2) {
+                    const RTLIL::Cell *dsp_a = group[i];
+                    const RTLIL::Cell *dsp_b = group[i + 1];
+
+                    std::string name = stringf("simd_%s_%s", RTLIL::unescape_id(dsp_a->name).c_str(), RTLIL::unescape_id(dsp_b->name).c_str());
+                    std::string SimdDspType;
+
+                    if (use_cfg_params)
+                        SimdDspType = m_SimdDspType_cfg_params;
+                    else
+                        SimdDspType = m_SimdDspType_cfg_ports;
+
+                    log(" SIMD: %s (%s) + %s (%s) => %s (%s)\n", RTLIL::unescape_id(dsp_a->name).c_str(), RTLIL::unescape_id(dsp_a->type).c_str(),
+                        RTLIL::unescape_id(dsp_b->name).c_str(), RTLIL::unescape_id(dsp_b->type).c_str(), RTLIL::unescape_id(name).c_str(),
+                        SimdDspType.c_str());
+
+                    // Create the new cell
+                    RTLIL::Cell *simd = module->addCell(RTLIL::escape_id(name), RTLIL::escape_id(SimdDspType));
+
+                    // Check if the target cell is known (important to know
+                    // its port widths)
+                    if (!simd->known()) {
+                        log_error(" The target cell type '%s' is not known!", SimdDspType.c_str());
+                    }
+
+                    std::vector<std::pair<std::string, std::string>> DspCfgPorts = m_DspCfgPorts;
+                    if (!use_cfg_params)
+                        DspCfgPorts.insert(DspCfgPorts.end(), m_DspCfgPorts_expand.begin(), m_DspCfgPorts_expand.end());
+
+                    // Connect common ports
+                    for (const auto &it : DspCfgPorts) {
+                        auto sport = RTLIL::escape_id(it.first);
+                        auto dport = RTLIL::escape_id(it.second);
+
+                        simd->setPort(dport, config.connections.at(sport));
+                    }
+
+                    // Connect data ports
+                    for (const auto &it : m_DspDataPorts) {
+                        auto sport = RTLIL::escape_id(it.first);
+                        auto dport = RTLIL::escape_id(it.second);
+
+                        size_t width;
+                        bool isOutput;
+
+                        std::tie(width, isOutput) = getPortInfo(simd, dport);
+
+                        auto getConnection = [&](const RTLIL::Cell *cell) {
+                            RTLIL::SigSpec sigspec;
+                            if (cell->hasPort(sport)) {
+                                const auto &sig = cell->getPort(sport);
+                                sigspec.append(sig);
+                            }
+                            if (sigspec.bits().size() < width / 2) {
+                                if (isOutput) {
+                                    for (size_t i = 0; i < width / 2 - sigspec.bits().size(); ++i) {
+                                        sigspec.append(RTLIL::SigSpec());
+                                    }
+                                } else {
+                                    sigspec.append(RTLIL::SigSpec(RTLIL::Sx, width / 2 - sigspec.bits().size()));
+                                }
+                            }
+                            return sigspec;
+                        };
+
+                        RTLIL::SigSpec sigspec;
+                        sigspec.append(getConnection(dsp_a));
+                        sigspec.append(getConnection(dsp_b));
+                        simd->setPort(dport, sigspec);
+                    }
+
+                    // Concatenate FIR coefficient parameters into the single
+                    // MODE_BITS parameter
+                    std::vector<RTLIL::State> mode_bits;
+                    for (const auto &it : m_DspParams) {
+                        auto val_a = dsp_a->getParam(RTLIL::escape_id(it));
+                        auto val_b = dsp_b->getParam(RTLIL::escape_id(it));
+
+                        mode_bits.insert(mode_bits.end(), val_a.begin(), val_a.end());
+                        mode_bits.insert(mode_bits.end(), val_b.begin(), val_b.end());
+                    }
+                    long unsigned int mode_bits_size = MODE_BITS_BASE_SIZE;
+                    if (use_cfg_params) {
+                        // Add additional config parameters if necessary
+                        mode_bits.push_back(RTLIL::S1); // MODE_BITS[80] == F_MODE : Enable fractured mode
+                        for (const auto &it : m_DspParams2Mode) {
+                            log_assert(dsp_a->getParam(RTLIL::escape_id(it)) == dsp_b->getParam(RTLIL::escape_id(it)));
+                            auto param = dsp_a->getParam(RTLIL::escape_id(it));
+                            if (param.size() > 1) {
+                                mode_bits.insert(mode_bits.end(), param.bits.begin(), param.bits.end());
+                            } else {
+                                mode_bits.push_back(param.bits[0]);
+                            }
+                        }
+                        mode_bits_size += MODE_BITS_EXTENSION_SIZE;
+                    } else {
+                        // Enable the fractured mode by connecting the control
+                        // port.
+                        simd->setPort(RTLIL::escape_id("f_mode"), RTLIL::S1);
+                    }
+                    simd->setParam(RTLIL::escape_id("MODE_BITS"), RTLIL::Const(mode_bits));
+                    log_assert(mode_bits.size() == mode_bits_size);
+
+                    // Handle the "is_inferred" attribute. If one of the fragments
+                    // is not inferred mark the whole DSP as not inferred
+                    bool is_inferred_a =
+                      dsp_a->has_attribute(RTLIL::escape_id("is_inferred")) ? dsp_a->get_bool_attribute(RTLIL::escape_id("is_inferred")) : false;
+                    bool is_inferred_b =
+                      dsp_b->has_attribute(RTLIL::escape_id("is_inferred")) ? dsp_b->get_bool_attribute(RTLIL::escape_id("is_inferred")) : false;
+
+                    simd->set_bool_attribute(RTLIL::escape_id("is_inferred"), is_inferred_a && is_inferred_b);
+
+                    // Mark DSP parts for removal
+                    cellsToRemove.push_back(dsp_a);
+                    cellsToRemove.push_back(dsp_b);
+                }
+            }
+
+            // Remove old cells
+            for (const auto &cell : cellsToRemove) {
+                module->remove(const_cast<RTLIL::Cell *>(cell));
+            }
+        }
+
+        // Clear
+        m_SigMap.clear();
+    }
+
+    // ..........................................
+
+    /// Looks up port width and direction in the cell definition and returns it.
+    /// Returns (0, false) if it cannot be determined.
+    std::pair<size_t, bool> getPortInfo(RTLIL::Cell *a_Cell, RTLIL::IdString a_Port)
+    {
+        if (!a_Cell->known()) {
+            return std::make_pair(0, false);
+        }
+
+        // Get the module defining the cell (the previous condition ensures
+        // that the pointers are valid)
+        RTLIL::Module *mod = a_Cell->module->design->module(a_Cell->type);
+        if (mod == nullptr) {
+            return std::make_pair(0, false);
+        }
+
+        // Get the wire representing the port
+        RTLIL::Wire *wire = mod->wire(a_Port);
+        if (wire == nullptr) {
+            return std::make_pair(0, false);
+        }
+
+        return std::make_pair(wire->width, wire->port_output);
+    }
+
+    /// Given a DSP cell populates and returns a DspConfig struct for it.
+    DspConfig getDspConfig(RTLIL::Cell *a_Cell)
+    {
+        DspConfig config;
+
+        string cell_type = a_Cell->type.str();
+        string suffix = m_SisdDspType_cfg_params_suffix;
+
+        bool use_cfg_params = cell_type.size() >= suffix.size() && 0 == cell_type.compare(cell_type.size() - suffix.size(), suffix.size(), suffix);
+
+        std::vector<std::pair<std::string, std::string>> DspCfgPorts = m_DspCfgPorts;
+        if (!use_cfg_params)
+            DspCfgPorts.insert(DspCfgPorts.end(), m_DspCfgPorts_expand.begin(), m_DspCfgPorts_expand.end());
+
+        config.use_cfg_params = use_cfg_params;
+
+        for (const auto &it : DspCfgPorts) {
+            auto port = RTLIL::escape_id(it.first);
+
+            // Port unconnected
+            if (!a_Cell->hasPort(port)) {
+                config.connections[port] = RTLIL::SigSpec(RTLIL::Sx);
+                continue;
+            }
+
+            // Get the port connection and map it to unique SigBits
+            const auto &orgSigSpec = a_Cell->getPort(port);
+            const auto &orgSigBits = orgSigSpec.bits();
+
+            RTLIL::SigSpec newSigSpec;
+            for (size_t i = 0; i < orgSigBits.size(); ++i) {
+                auto newSigBit = m_SigMap(orgSigBits[i]);
+                newSigSpec.append(newSigBit);
+            }
+
+            // Store
+            config.connections[port] = newSigSpec;
+        }
+
+        return config;
+    }
+
+} QlDspSimdPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-dsp.cc b/yosys-plugins/ql-qlf/ql-dsp.cc
new file mode 100644
index 000000000..4e8e2c64f
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-dsp.cc
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/sigtools.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#include "pmgen/ql-dsp-pm.h"
+
+void create_ql_dsp(ql_dsp_pm &pm)
+{
+    auto &st = pm.st_ql_dsp;
+
+    log("Checking %s.%s for QL DSP inference.\n", log_id(pm.module), log_id(st.mul));
+
+    log_debug("ffA:    %s\n", log_id(st.ffA, "--"));
+    log_debug("ffB:    %s\n", log_id(st.ffB, "--"));
+    log_debug("ffCD:   %s\n", log_id(st.ffCD, "--"));
+    log_debug("mul:    %s\n", log_id(st.mul, "--"));
+    log_debug("ffFJKG: %s\n", log_id(st.ffFJKG, "--"));
+    log_debug("ffH:    %s\n", log_id(st.ffH, "--"));
+    log_debug("add:    %s\n", log_id(st.add, "--"));
+    log_debug("mux:    %s\n", log_id(st.mux, "--"));
+    log_debug("ffO:    %s\n", log_id(st.ffO, "--"));
+    log_debug("\n");
+
+    if (GetSize(st.sigA) > 16) {
+        log("  input A (%s) is too large (%d > 16).\n", log_signal(st.sigA), GetSize(st.sigA));
+        return;
+    }
+
+    if (GetSize(st.sigB) > 16) {
+        log("  input B (%s) is too large (%d > 16).\n", log_signal(st.sigB), GetSize(st.sigB));
+        return;
+    }
+
+    if (GetSize(st.sigO) > 33) {
+        log("  adder/accumulator (%s) is too large (%d > 33).\n", log_signal(st.sigO), GetSize(st.sigO));
+        return;
+    }
+
+    if (GetSize(st.sigH) > 32) {
+        log("  output (%s) is too large (%d > 32).\n", log_signal(st.sigH), GetSize(st.sigH));
+        return;
+    }
+
+    Cell *cell = st.mul;
+    if (cell->type == ID($mul)) {
+        log("  replacing %s with QL_DSP cell.\n", log_id(st.mul->type));
+
+        cell = pm.module->addCell(NEW_ID, ID(QL_DSP));
+        pm.module->swap_names(cell, st.mul);
+    } else
+        log_assert(cell->type == ID(QL_DSP));
+
+    // QL_DSP Input Interface
+    SigSpec A = st.sigA;
+    A.extend_u0(16, st.mul->getParam(ID::A_SIGNED).as_bool());
+    log_assert(GetSize(A) == 16);
+
+    SigSpec B = st.sigB;
+    B.extend_u0(16, st.mul->getParam(ID::B_SIGNED).as_bool());
+    log_assert(GetSize(B) == 16);
+
+    SigSpec CD = st.sigCD;
+    if (CD.empty())
+        CD = RTLIL::Const(0, 32);
+    else
+        log_assert(GetSize(CD) == 32);
+
+    cell->setPort(ID::A, A);
+    cell->setPort(ID::B, B);
+    cell->setPort(ID::C, CD.extract(16, 16));
+    cell->setPort(ID::D, CD.extract(0, 16));
+
+    cell->setParam(ID(A_REG), st.ffA ? State::S1 : State::S0);
+    cell->setParam(ID(B_REG), st.ffB ? State::S1 : State::S0);
+    cell->setParam(ID(C_REG), st.ffCD ? State::S1 : State::S0);
+    cell->setParam(ID(D_REG), st.ffCD ? State::S1 : State::S0);
+
+    // QL_DSP Output Interface
+
+    SigSpec O = st.sigO;
+    int O_width = GetSize(O);
+    if (O_width == 33) {
+        log_assert(st.add);
+        // If we have a signed multiply-add, then perform sign extension
+        if (st.add->getParam(ID::A_SIGNED).as_bool() && st.add->getParam(ID::B_SIGNED).as_bool())
+            pm.module->connect(O[32], O[31]);
+        else
+            cell->setPort(ID::CO, O[32]);
+        O.remove(O_width - 1);
+    } else
+        cell->setPort(ID::CO, pm.module->addWire(NEW_ID));
+    log_assert(GetSize(O) <= 32);
+    if (GetSize(O) < 32)
+        O.append(pm.module->addWire(NEW_ID, 32 - GetSize(O)));
+
+    cell->setPort(ID::O, O);
+
+    cell->setParam(ID::A_SIGNED, st.mul->getParam(ID::A_SIGNED).as_bool());
+    cell->setParam(ID::B_SIGNED, st.mul->getParam(ID::B_SIGNED).as_bool());
+
+    if (cell != st.mul)
+        pm.autoremove(st.mul);
+    else
+        pm.blacklist(st.mul);
+    pm.autoremove(st.ffFJKG);
+    pm.autoremove(st.add);
+}
+
+struct QlDspPass : public Pass {
+    QlDspPass() : Pass("ql_dsp", "ql: map multipliers") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    ql_dsp [options] [selection]\n");
+        log("\n");
+        log("Map multipliers ($mul/QL_DSP) and multiply-accumulate ($mul/QL_DSP + $add)\n");
+        log("cells into ql DSP resources.\n");
+        log("Pack input registers (A, B, {C,D}), pipeline registers\n");
+        log("({F,J,K,G}, H), output registers (O -- full 32-bits or lower 16-bits only); \n");
+        log("and post-adder into into the QL_DSP resource.\n");
+        log("\n");
+        log("Multiply-accumulate operations using the post-adder with feedback on the {C,D}\n");
+        log("input will be folded into the DSP. In this scenario only, resetting the\n");
+        log("the accumulator to an arbitrary value can be inferred to use the {C,D} input.\n");
+        log("\n");
+    }
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        log_header(design, "Executing ql_DSP pass (map multipliers).\n");
+
+        size_t argidx;
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            break;
+        }
+        extra_args(args, argidx, design);
+
+        for (auto module : design->selected_modules())
+            ql_dsp_pm(module, module->selected_cells()).run_ql_dsp(create_ql_dsp);
+    }
+} QlDspPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql-edif.cc b/yosys-plugins/ql-qlf/ql-edif.cc
new file mode 100644
index 000000000..a560c1e68
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql-edif.cc
@@ -0,0 +1,632 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+
+// [[CITE]] EDIF Version 2 0 0 Grammar
+// http://web.archive.org/web/20050730021644/http://www.edif.org/documentation/BNF_GRAMMAR/index.html
+
+#include "kernel/celltypes.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "kernel/sigtools.h"
+#include <string>
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str()
+#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br).c_str()
+#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str()
+
+struct EdifNames {
+    int counter;
+    char delim_left, delim_right;
+    std::set<std::string> generated_names, used_names;
+    std::map<std::string, std::string> name_map;
+
+    EdifNames() : counter(1), delim_left('['), delim_right(']') {}
+
+    std::string operator()(std::string id, bool define, bool port_rename = false, int range_left = 0, int range_right = 0)
+    {
+        if (define) {
+            std::string new_id = operator()(id, false);
+            if (port_rename)
+                return stringf("(rename %s \"%s%c%d:%d%c\")", new_id.c_str(), id.c_str(), delim_left, range_left, range_right, delim_right);
+            return new_id != id ? stringf("(rename %s \"%s\")", new_id.c_str(), id.c_str()) : id;
+        }
+
+        if (name_map.count(id) > 0)
+            return name_map.at(id);
+        if (generated_names.count(id) > 0)
+            goto do_rename;
+        if (id == "GND" || id == "VCC")
+            goto do_rename;
+
+        for (size_t i = 0; i < id.size(); i++) {
+            if ('A' <= id[i] && id[i] <= 'Z')
+                continue;
+            if ('a' <= id[i] && id[i] <= 'z')
+                continue;
+            if ('0' <= id[i] && id[i] <= '9' && i > 0)
+                continue;
+            if (id[i] == '_' && i > 0 && i != id.size() - 1)
+                continue;
+            goto do_rename;
+        }
+
+        used_names.insert(id);
+        return id;
+
+    do_rename:;
+        std::string gen_name;
+        while (1) {
+            gen_name = stringf("id%05d", counter++);
+            if (generated_names.count(gen_name) == 0 && used_names.count(gen_name) == 0)
+                break;
+        }
+        generated_names.insert(gen_name);
+        name_map[id] = gen_name;
+        return gen_name;
+    }
+};
+
+struct QLEdifBackend : public Backend {
+    QLEdifBackend() : Backend("ql_edif", "write design to EDIF netlist file") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    write_ql_edif [options] [filename]\n");
+        log("\n");
+        log("Write the current design to an EDIF netlist file.\n");
+        log("\n");
+        log("    -top top_module\n");
+        log("        set the specified module as design top module\n");
+        log("\n");
+        log("    -nogndvcc\n");
+        log("        do not create \"GND\" and \"VCC\" cells. (this will produce an error\n");
+        log("        if the design contains constant nets. use \"hilomap\" to map to custom\n");
+        log("        constant drivers first)\n");
+        log("\n");
+        log("    -gndvccy\n");
+        log("        create \"GND\" and \"VCC\" cells with \"Y\" outputs. (the default is \"G\"\n");
+        log("        for \"GND\" and \"P\" for \"VCC\".)\n");
+        log("\n");
+        log("    -attrprop\n");
+        log("        create EDIF properties for cell attributes\n");
+        log("\n");
+        log("    -keep\n");
+        log("        create extra KEEP nets by allowing a cell to drive multiple nets.\n");
+        log("\n");
+        log("    -pvector {par|bra|ang}\n");
+        log("        sets the delimiting character for module port rename clauses to\n");
+        log("        parentheses, square brackets, or angle brackets.\n");
+        log("\n");
+        log("Unfortunately there are different \"flavors\" of the EDIF file format. This\n");
+        log("command generates EDIF files for the Xilinx place&route tools. It might be\n");
+        log("necessary to make small modifications to this command when a different tool\n");
+        log("is targeted.\n");
+        log("\n");
+    }
+    void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        log_header(design, "Executing QL EDIF backend.\n");
+        std::string top_module_name;
+        bool port_rename = false;
+        bool attr_properties = false;
+        std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports;
+        bool nogndvcc = false, gndvccy = false, keepmode = false;
+        CellTypes ct(design);
+        EdifNames edif_names;
+
+        size_t argidx;
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            if (args[argidx] == "-top" && argidx + 1 < args.size()) {
+                top_module_name = args[++argidx];
+                continue;
+            }
+            if (args[argidx] == "-nogndvcc") {
+                nogndvcc = true;
+                continue;
+            }
+            if (args[argidx] == "-gndvccy") {
+                gndvccy = true;
+                continue;
+            }
+            if (args[argidx] == "-attrprop") {
+                attr_properties = true;
+                continue;
+            }
+            if (args[argidx] == "-keep") {
+                keepmode = true;
+                continue;
+            }
+            if (args[argidx] == "-pvector" && argidx + 1 < args.size()) {
+                std::string parray;
+                port_rename = true;
+                parray = args[++argidx];
+                if (parray == "par") {
+                    edif_names.delim_left = '(';
+                    edif_names.delim_right = ')';
+                } else if (parray == "ang") {
+                    edif_names.delim_left = '<';
+                    edif_names.delim_right = '>';
+                } else {
+                    edif_names.delim_left = '[';
+                    edif_names.delim_right = ']';
+                }
+                continue;
+            }
+            break;
+        }
+        extra_args(f, filename, args, argidx);
+
+        if (top_module_name.empty())
+            for (auto module : design->modules())
+                if (module->get_bool_attribute(ID::top))
+                    top_module_name = module->name.str();
+
+        for (auto module : design->modules()) {
+            if (module->get_blackbox_attribute())
+                continue;
+
+            if (top_module_name.empty())
+                top_module_name = module->name.str();
+
+            if (module->processes.size() != 0)
+                log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name));
+            if (module->memories.size() != 0)
+                log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name));
+
+            for (auto cell : module->cells()) {
+                if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) {
+                    lib_cell_ports[cell->type];
+                    for (auto p : cell->connections())
+                        lib_cell_ports[cell->type][p.first] = GetSize(p.second);
+                }
+            }
+        }
+
+        if (top_module_name.empty())
+            log_error("No module found in design!\n");
+
+        *f << stringf("(edif %s\n", EDIF_DEF(top_module_name));
+        *f << stringf("  (edifVersion 2 0 0)\n");
+        *f << stringf("  (edifLevel 0)\n");
+        *f << stringf("  (keywordMap (keywordLevel 0))\n");
+        *f << stringf("  (comment \"Generated by %s\")\n", yosys_version_str);
+
+        *f << stringf("  (external LIB\n");
+        *f << stringf("    (edifLevel 0)\n");
+        *f << stringf("    (technology (numberDefinition))\n");
+
+        if (!nogndvcc) {
+            *f << stringf("    (cell GND\n");
+            *f << stringf("      (cellType GENERIC)\n");
+            *f << stringf("      (view VIEW_NETLIST\n");
+            *f << stringf("        (viewType NETLIST)\n");
+            *f << stringf("        (interface (port %c (direction OUTPUT)))\n", gndvccy ? 'Y' : 'G');
+            *f << stringf("      )\n");
+            *f << stringf("    )\n");
+
+            *f << stringf("    (cell VCC\n");
+            *f << stringf("      (cellType GENERIC)\n");
+            *f << stringf("      (view VIEW_NETLIST\n");
+            *f << stringf("        (viewType NETLIST)\n");
+            *f << stringf("        (interface (port %c (direction OUTPUT)))\n", gndvccy ? 'Y' : 'P');
+            *f << stringf("      )\n");
+            *f << stringf("    )\n");
+        }
+
+        for (auto &cell_it : lib_cell_ports) {
+            *f << stringf("    (cell %s\n", EDIF_DEF(cell_it.first));
+            *f << stringf("      (cellType GENERIC)\n");
+            *f << stringf("      (view VIEW_NETLIST\n");
+            *f << stringf("        (viewType NETLIST)\n");
+            *f << stringf("        (interface\n");
+            for (auto &port_it : cell_it.second) {
+                const char *dir = "INOUT";
+                if (ct.cell_known(cell_it.first)) {
+                    if (!ct.cell_output(cell_it.first, port_it.first))
+                        dir = "INPUT";
+                    else if (!ct.cell_input(cell_it.first, port_it.first))
+                        dir = "OUTPUT";
+                }
+                int width = port_it.second;
+                int start = 0;
+                auto m = design->module(cell_it.first);
+                if (m) {
+                    auto w = m->wire(port_it.first);
+                    if (w) {
+                        width = GetSize(w);
+                        start = w->start_offset;
+                    }
+                }
+                if (width == 1)
+                    *f << stringf("          (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir);
+                else {
+                    for (int b = start; b < start + width; b++) {
+                        *f << stringf("          (port (rename %s_%d_ \"%s(%d)\") (direction %s))\n", EDIF_DEF(port_it.first), b,
+                                      EDIF_DEF(port_it.first), b, dir);
+                    }
+                }
+            }
+            *f << stringf("        )\n");
+            *f << stringf("      )\n");
+            *f << stringf("    )\n");
+        }
+        *f << stringf("  )\n");
+
+        std::vector<RTLIL::Module *> sorted_modules;
+
+        // extract module dependencies
+        std::map<RTLIL::Module *, std::set<RTLIL::Module *>> module_deps;
+        for (auto module : design->modules()) {
+            module_deps[module] = std::set<RTLIL::Module *>();
+            for (auto cell : module->cells())
+                if (design->module(cell->type) != nullptr)
+                    module_deps[module].insert(design->module(cell->type));
+        }
+
+        // simple good-enough topological sort
+        // (O(n*m) on n elements and depth m)
+        while (module_deps.size() > 0) {
+            size_t sorted_modules_idx = sorted_modules.size();
+            for (auto &it : module_deps) {
+                for (auto &dep : it.second)
+                    if (module_deps.count(dep) > 0)
+                        goto not_ready_yet;
+                // log("Next in topological sort: %s\n", log_id(it.first->name));
+                sorted_modules.push_back(it.first);
+            not_ready_yet:;
+            }
+            if (sorted_modules_idx == sorted_modules.size())
+                log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
+            while (sorted_modules_idx < sorted_modules.size())
+                module_deps.erase(sorted_modules.at(sorted_modules_idx++));
+        }
+
+        *f << stringf("  (library DESIGN\n");
+        *f << stringf("    (edifLevel 0)\n");
+        *f << stringf("    (technology (numberDefinition))\n");
+
+        auto add_prop = [&](IdString name, Const val) {
+            if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0)
+                *f << stringf("\n            (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str());
+            else if (val.bits.size() <= 32 && RTLIL::SigSpec(val).is_fully_def()) {
+                *f << stringf("\n            (property %s (integer %u))", EDIF_DEF(name), val.as_int());
+            } else {
+                std::string hex_string = "";
+                for (size_t i = 0; i < val.bits.size(); i += 4) {
+                    int digit_value = 0;
+                    if (i + 0 < val.bits.size() && val.bits.at(i + 0) == RTLIL::State::S1)
+                        digit_value |= 1;
+                    if (i + 1 < val.bits.size() && val.bits.at(i + 1) == RTLIL::State::S1)
+                        digit_value |= 2;
+                    if (i + 2 < val.bits.size() && val.bits.at(i + 2) == RTLIL::State::S1)
+                        digit_value |= 4;
+                    if (i + 3 < val.bits.size() && val.bits.at(i + 3) == RTLIL::State::S1)
+                        digit_value |= 8;
+                    char digit_str[2] = {"0123456789abcdef"[digit_value], 0};
+                    hex_string = std::string(digit_str) + hex_string;
+                }
+                *f << stringf("\n            (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val.bits), hex_string.c_str());
+            }
+        };
+        auto add_lut_prop = [&](IdString name, Const val, int lut_in) {
+            if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0)
+                *f << stringf("\n            (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str());
+            else if (val.bits.size() <= 32 && RTLIL::SigSpec(val).is_fully_def()) {
+                if (strstr(name.c_str(), "INIT")) {
+                    int hex_code_width = ((1 << lut_in) / 4);
+                    *f << stringf("\n            (property %s (string \"%0*X\"))", EDIF_DEF(name), hex_code_width, val.as_int());
+                } else {
+                    *f << stringf("\n            (property %s (integer %u))", EDIF_DEF(name), val.as_int());
+                }
+            } else {
+                std::string hex_string = "";
+                for (size_t i = 0; i < val.bits.size(); i += 4) {
+                    int digit_value = 0;
+                    if (i + 0 < val.bits.size() && val.bits.at(i + 0) == RTLIL::State::S1)
+                        digit_value |= 1;
+                    if (i + 1 < val.bits.size() && val.bits.at(i + 1) == RTLIL::State::S1)
+                        digit_value |= 2;
+                    if (i + 2 < val.bits.size() && val.bits.at(i + 2) == RTLIL::State::S1)
+                        digit_value |= 4;
+                    if (i + 3 < val.bits.size() && val.bits.at(i + 3) == RTLIL::State::S1)
+                        digit_value |= 8;
+                    char digit_str[2] = {"0123456789abcdef"[digit_value], 0};
+                    hex_string = std::string(digit_str) + hex_string;
+                }
+                *f << stringf("\n            (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val.bits), hex_string.c_str());
+            }
+        };
+        for (auto module : sorted_modules) {
+            if (module->get_blackbox_attribute())
+                continue;
+
+            SigMap sigmap(module);
+            std::map<RTLIL::SigSpec, std::set<std::pair<std::string, bool>>> net_join_db;
+
+            *f << stringf("    (cell %s\n", EDIF_DEF(module->name));
+            *f << stringf("      (cellType GENERIC)\n");
+            *f << stringf("      (view VIEW_NETLIST\n");
+            *f << stringf("        (viewType NETLIST)\n");
+            *f << stringf("        (interface\n");
+
+            for (auto cell : module->cells()) {
+                for (auto &conn : cell->connections())
+                    if (cell->output(conn.first))
+                        sigmap.add(conn.second);
+            }
+
+            for (auto wire : module->wires())
+                for (auto b1 : SigSpec(wire)) {
+                    auto b2 = sigmap(b1);
+
+                    if (b1 == b2 || !b2.wire)
+                        continue;
+
+                    log_assert(b1.wire != nullptr);
+
+                    Wire *w1 = b1.wire;
+                    Wire *w2 = b2.wire;
+
+                    {
+                        int c1 = w1->get_bool_attribute(ID::keep);
+                        int c2 = w2->get_bool_attribute(ID::keep);
+
+                        if (c1 > c2)
+                            goto promote;
+                        if (c1 < c2)
+                            goto nopromote;
+                    }
+
+                    {
+                        int c1 = w1->name.isPublic();
+                        int c2 = w2->name.isPublic();
+
+                        if (c1 > c2)
+                            goto promote;
+                        if (c1 < c2)
+                            goto nopromote;
+                    }
+
+                    {
+                        auto count_nontrivial_attr = [](Wire *w) {
+                            int count = w->attributes.size();
+                            count -= w->attributes.count(ID::src);
+                            count -= w->attributes.count(ID::unused_bits);
+                            return count;
+                        };
+
+                        int c1 = count_nontrivial_attr(w1);
+                        int c2 = count_nontrivial_attr(w2);
+
+                        if (c1 > c2)
+                            goto promote;
+                        if (c1 < c2)
+                            goto nopromote;
+                    }
+
+                    {
+                        int c1 = w1->port_id ? INT_MAX - w1->port_id : 0;
+                        int c2 = w2->port_id ? INT_MAX - w2->port_id : 0;
+
+                        if (c1 > c2)
+                            goto promote;
+                        if (c1 < c2)
+                            goto nopromote;
+                    }
+
+                nopromote:
+                    if (0)
+                    promote:
+                        sigmap.add(b1);
+                }
+
+            for (auto wire : module->wires()) {
+                if (wire->port_id == 0)
+                    continue;
+                const char *dir = "INOUT";
+                if (!wire->port_output)
+                    dir = "INPUT";
+                else if (!wire->port_input)
+                    dir = "OUTPUT";
+                if (wire->width == 1) {
+                    *f << stringf("          (port %s (direction %s)", EDIF_DEF(wire->name), dir);
+                    if (attr_properties)
+                        for (auto &p : wire->attributes)
+                            add_prop(p.first, p.second);
+                    *f << ")\n";
+                    RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire));
+                    net_join_db[sig].insert(make_pair(stringf("(portRef %s)", EDIF_REF(wire->name)), wire->port_input));
+                } else {
+                    int b[2];
+                    b[wire->upto ? 0 : 1] = wire->start_offset;
+                    b[wire->upto ? 1 : 0] = wire->start_offset + GetSize(wire) - 1;
+                    *f << stringf("          (port (array %s %d) (direction %s)", EDIF_DEFR(wire->name, port_rename, b[0], b[1]), wire->width, dir);
+                    if (attr_properties)
+                        for (auto &p : wire->attributes)
+                            add_prop(p.first, p.second);
+
+                    *f << ")\n";
+                    for (int i = 0; i < wire->width; i++) {
+                        RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i));
+                        net_join_db[sig].insert(
+                          make_pair(stringf("(portRef %s_%d_)", EDIF_REF(wire->name), GetSize(wire) - i - 1), wire->port_input));
+                    }
+                }
+            }
+
+            *f << stringf("        )\n");
+            *f << stringf("        (contents\n");
+
+            if (!nogndvcc) {
+                *f << stringf("          (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n");
+                *f << stringf("          (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");
+            }
+
+            for (auto cell : module->cells()) {
+                *f << stringf("          (instance %s\n", EDIF_DEF(cell->name));
+                *f << stringf("            (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type),
+                              lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : "");
+                const char *lut_pos;
+                lut_pos = strstr(cell->type.c_str(), "LUT");
+                if (lut_pos) {
+                    int lut_in = atoi(lut_pos + 3); // get the number of LUT inputs
+                    for (auto &p : cell->parameters)
+                        add_lut_prop(p.first, p.second, lut_in);
+                    if (attr_properties)
+                        for (auto &p : cell->attributes)
+                            add_lut_prop(p.first, p.second, lut_in);
+                } else {
+                    for (auto &p : cell->parameters)
+                        add_prop(p.first, p.second);
+                    if (attr_properties)
+                        for (auto &p : cell->attributes)
+                            add_prop(p.first, p.second);
+                }
+
+                *f << stringf(")\n");
+                for (auto &p : cell->connections()) {
+                    RTLIL::SigSpec sig = sigmap(p.second);
+                    for (int i = 0; i < GetSize(sig); i++)
+                        if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
+                            log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n", i, log_id(module),
+                                        log_id(cell), log_id(p.first), log_signal(sig[i]));
+                        else {
+                            int member_idx = GetSize(sig) - i - 1;
+                            auto m = design->module(cell->type);
+                            int width = sig.size();
+                            if (m) {
+                                auto w = m->wire(p.first);
+                                if (w) {
+                                    member_idx = GetSize(w) - i - 1;
+                                    width = GetSize(w);
+                                }
+                            }
+                            if (width == 1)
+                                net_join_db[sig[i]].insert(make_pair(
+                                  stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
+                            else {
+                                net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s_%d_ (instanceRef %s))", EDIF_REF(p.first),
+                                                                             width - member_idx - 1, EDIF_REF(cell->name)), // reverse IDs
+                                                                     cell->output(p.first)));
+                            }
+                        }
+                }
+            }
+
+            for (auto &it : net_join_db) {
+                RTLIL::SigBit sig = it.first;
+                if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) {
+                    if (sig == RTLIL::State::Sx) {
+                        for (auto &ref : it.second)
+                            log_warning("Exporting x-bit on %s as zero bit.\n", ref.first.c_str());
+                        sig = RTLIL::State::S0;
+                    } else if (sig == RTLIL::State::Sz) {
+                        continue;
+                    } else {
+                        for (auto &ref : it.second)
+                            log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.first.c_str());
+                        log_abort();
+                    }
+                }
+                std::string netname;
+                if (sig == RTLIL::State::S0)
+                    netname = "GND_NET";
+                else if (sig == RTLIL::State::S1)
+                    netname = "VCC_NET";
+                else {
+                    netname = log_signal(sig);
+                    for (size_t i = 0; i < netname.size(); i++)
+                        if (netname[i] == ' ' || netname[i] == '\\')
+                            netname.erase(netname.begin() + i--);
+                }
+                *f << stringf("          (net %s (joined\n", EDIF_DEF(netname));
+                for (auto &ref : it.second)
+                    *f << stringf("              %s\n", ref.first.c_str());
+                if (sig.wire == NULL) {
+                    if (nogndvcc)
+                        log_error("Design contains constant nodes (map with \"hilomap\" first).\n");
+                    if (sig == RTLIL::State::S0)
+                        *f << stringf("            (portRef %c (instanceRef GND))\n", gndvccy ? 'Y' : 'G');
+                    if (sig == RTLIL::State::S1)
+                        *f << stringf("            (portRef %c (instanceRef VCC))\n", gndvccy ? 'Y' : 'P');
+                }
+                *f << stringf("            )");
+                if (attr_properties && sig.wire != NULL)
+                    for (auto &p : sig.wire->attributes)
+                        add_prop(p.first, p.second);
+                *f << stringf("\n          )\n");
+            }
+
+            for (auto wire : module->wires()) {
+                if (!wire->get_bool_attribute(ID::keep))
+                    continue;
+
+                for (int i = 0; i < wire->width; i++) {
+                    SigBit raw_sig = RTLIL::SigSpec(wire, i);
+                    SigBit mapped_sig = sigmap(raw_sig);
+
+                    if (raw_sig == mapped_sig || net_join_db.count(mapped_sig) == 0)
+                        continue;
+
+                    std::string netname = log_signal(raw_sig);
+                    for (size_t i = 0; i < netname.size(); i++)
+                        if (netname[i] == ' ' || netname[i] == '\\')
+                            netname.erase(netname.begin() + i--);
+
+                    if (keepmode) {
+                        *f << stringf("          (net %s (joined\n", EDIF_DEF(netname));
+
+                        auto &refs = net_join_db.at(mapped_sig);
+                        for (auto &ref : refs)
+                            if (ref.second)
+                                *f << stringf("              %s\n", ref.first.c_str());
+                        *f << stringf("            )");
+
+                        if (attr_properties && raw_sig.wire != NULL)
+                            for (auto &p : raw_sig.wire->attributes)
+                                add_prop(p.first, p.second);
+
+                        *f << stringf("\n          )\n");
+                    } else {
+                        log_warning("Ignoring conflicting 'keep' property on net %s. Use -keep to generate the extra net nevertheless.\n",
+                                    EDIF_DEF(netname));
+                    }
+                }
+            }
+
+            *f << stringf("        )\n");
+            *f << stringf("      )\n");
+            *f << stringf("    )\n");
+        }
+        *f << stringf("  )\n");
+
+        *f << stringf("  (design %s\n", EDIF_DEF(top_module_name));
+        *f << stringf("    (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name));
+        *f << stringf("  )\n");
+
+        *f << stringf(")\n");
+    }
+} QLEdifBackend;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/ql_dsp.pmg b/yosys-plugins/ql-qlf/ql_dsp.pmg
new file mode 100644
index 000000000..1d87ce4dd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/ql_dsp.pmg
@@ -0,0 +1,423 @@
+pattern ql_dsp
+
+state <SigBit> clock
+state <bool> clock_pol cd_signed o_lo
+state <SigSpec> sigA sigB sigCD sigH sigO
+state <Cell*> add mux
+state <IdString> addAB muxAB
+
+state <Cell*> ffA ffB ffCD
+state <Cell*> ffFJKG ffH ffO
+//
+// subpattern
+state <bool> argSdff
+state <SigSpec> argQ argD
+udata <SigSpec> dffD dffQ
+udata <SigBit> dffclock
+udata <Cell*> dff
+udata <bool> dffclock_pol
+
+match mul
+	select mul->type.in($mul, \QL_DSP)
+	select GetSize(mul->getPort(\A)) + GetSize(mul->getPort(\B)) > 10
+endmatch
+
+code sigA sigB sigH
+	auto unextend = [](const SigSpec &sig) {
+		int i;
+		for (i = GetSize(sig)-1; i > 0; i--)
+			if (sig[i] != sig[i-1])
+				break;
+		// Do not remove non-const sign bit
+		if (sig[i].wire)
+			++i;
+		return sig.extract(0, i);
+	};
+	sigA = unextend(port(mul, \A));
+	sigB = unextend(port(mul, \B));
+
+	SigSpec O;
+	if (mul->type == $mul)
+		O = mul->getPort(\Y);
+	else if (mul->type == \QL_DSP)
+		O = mul->getPort(\O);
+	else log_abort();
+	if (GetSize(O) <= 10)
+		reject;
+
+	// Only care about those bits that are used
+	int i;
+	for (i = 0; i < GetSize(O); i++) {
+		if (nusers(O[i]) <= 1)
+			break;
+		sigH.append(O[i]);
+	}
+	// This sigM could have no users if downstream sinks (e.g. $add) is
+	//   narrower than $mul result, for example
+	if (i == 0)
+		reject;
+
+	log_assert(nusers(O.extract_end(i)) <= 1);
+endcode
+
+code argQ ffA sigA clock clock_pol
+	if (mul->type != \QL_DSP || !param(mul, \A_REG).as_bool()) {
+		argQ = sigA;
+		//subpattern(in_dffe);
+		if (dff) {
+			ffA = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+			sigA = dffD;
+		}
+	}
+endcode
+
+code argQ ffB sigB clock clock_pol
+	if (mul->type != \QL_DSP || !param(mul, \B_REG).as_bool()) {
+		argQ = sigB;
+		//subpattern(in_dffe);
+		if (dff) {
+			ffB = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+			sigB = dffD;
+		}
+	}
+endcode
+
+code argD argSdff ffFJKG sigH clock clock_pol
+	if (nusers(sigH) == 2 &&
+			(mul->type != \QL_DSP)) {
+		argD = sigH;
+		argSdff = false;
+		//subpattern(out_dffe);
+		if (dff) {
+			// F/J/K/G do not have a CE-like (hold) input
+			if (dff->hasPort(\EN))
+				goto reject_ffFJKG;
+
+			// Reset signal of F/J (IRSTTOP) and K/G (IRSTBOT)
+			//   shared with A and B
+			if (ffA) {
+				if (ffA->hasPort(\ARST) != dff->hasPort(\ARST))
+					goto reject_ffFJKG;
+				if (ffA->hasPort(\ARST)) {
+					if (port(ffA, \ARST) != port(dff, \ARST))
+						goto reject_ffFJKG;
+					if (param(ffA, \ARST_POLARITY) != param(dff, \ARST_POLARITY))
+						goto reject_ffFJKG;
+				}
+			}
+			if (ffB) {
+				if (ffB->hasPort(\ARST) != dff->hasPort(\ARST))
+					goto reject_ffFJKG;
+				if (ffB->hasPort(\ARST)) {
+					if (port(ffB, \ARST) != port(dff, \ARST))
+						goto reject_ffFJKG;
+					if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY))
+						goto reject_ffFJKG;
+				}
+			}
+
+			ffFJKG = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+			sigH = dffQ;
+
+reject_ffFJKG: 		;
+		}
+	}
+endcode
+
+code argD argSdff ffH sigH sigO clock clock_pol
+	if (ffFJKG && nusers(sigH) == 2 &&
+			(mul->type != \QL_DSP)) {
+		argD = sigH;
+		argSdff = false;
+		//subpattern(out_dffe);
+		if (dff) {
+			// H does not have a CE-like (hold) input
+			if (dff->hasPort(\EN))
+				goto reject_ffH;
+
+			// Reset signal of H (IRSTBOT) shared with B
+			if (ffB->hasPort(\ARST) != dff->hasPort(\ARST))
+				goto reject_ffH;
+			if (ffB->hasPort(\ARST)) {
+				if (port(ffB, \ARST) != port(dff, \ARST))
+					goto reject_ffH;
+				if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY))
+					goto reject_ffH;
+			}
+
+			ffH = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+			sigH = dffQ;
+
+reject_ffH:		;
+		}
+	}
+
+	sigO = sigH;
+endcode
+
+match add
+	if mul->type != \QL_DSP || (param(mul, \ENABLE_DSP).as_int() == 1)
+
+	select add->type.in($add)
+	choice <IdString> AB {\A, \B}
+	select nusers(port(add, AB)) == 2
+
+	index <SigBit> port(add, AB)[0] === sigH[0]
+	filter GetSize(port(add, AB)) <= GetSize(sigH)
+	filter port(add, AB) == sigH.extract(0, GetSize(port(add, AB)))
+	filter nusers(sigH.extract_end(GetSize(port(add, AB)))) <= 1
+	set addAB AB
+	optional
+endmatch
+
+code sigCD sigO cd_signed
+	if (add) {
+		sigCD = port(add, addAB == \A ? \B : \A);
+		cd_signed = param(add, addAB == \A ? \B_SIGNED : \A_SIGNED).as_bool();
+
+		int natural_mul_width = GetSize(sigA) + GetSize(sigB);
+		int actual_mul_width = GetSize(sigH);
+		int actual_acc_width = GetSize(sigCD);
+
+		if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width))
+			reject;
+		// If accumulator, check adder width and signedness
+		if (sigCD == sigH && (actual_acc_width != actual_mul_width) && (param(mul, \A_SIGNED).as_bool() != param(add, \A_SIGNED).as_bool()))
+			reject;
+
+		sigO = port(add, \Y);
+	}
+endcode
+
+match mux
+	select mux->type == $mux
+	choice <IdString> AB {\A, \B}
+	select nusers(port(mux, AB)) == 2
+	index <SigSpec> port(mux, AB) === sigO
+	set muxAB AB
+	optional
+endmatch
+
+code sigO
+	if (mux)
+		sigO = port(mux, \Y);
+endcode
+
+code argD argSdff ffO sigO sigCD clock clock_pol cd_signed o_lo
+	if (mul->type != \QL_DSP ||
+			// Ensure that register is not already used
+			((param(mul, \ENABLE_DSP).as_int() == 1))) {
+
+		dff = nullptr;
+
+		// First try entire sigO
+		if (nusers(sigO) == 2) {
+			argD = sigO;
+			argSdff = !mux;
+			//subpattern(out_dffe);
+		}
+
+		// Otherwise try just its least significant 16 bits
+		if (!dff && GetSize(sigO) > 16) {
+			argD = sigO.extract(0, 16);
+			if (nusers(argD) == 2) {
+				argSdff = !mux;
+				//subpattern(out_dffe);
+				o_lo = dff;
+			}
+		}
+
+		if (dff) {
+			ffO = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+
+			sigO.replace(sigO.extract(0, GetSize(dffQ)), dffQ);
+		}
+
+		// Loading value into output register is not
+		//   supported unless using accumulator
+		if (mux) {
+			if (sigCD != sigO)
+				reject;
+			sigCD = port(mux, muxAB == \B ? \A : \B);
+
+			cd_signed = add && param(add, \A_SIGNED).as_bool() && param(add, \B_SIGNED).as_bool();
+		} else if (dff && dff->hasPort(\SRST)) {
+			if (sigCD != sigO)
+				reject;
+			sigCD = param(dff, \SRST_VALUE);
+
+			cd_signed = add && param(add, \A_SIGNED).as_bool() && param(add, \B_SIGNED).as_bool();
+		}
+	}
+endcode
+
+code argQ ffCD sigCD clock clock_pol
+	if (!sigCD.empty() && sigCD != sigO &&
+			(mul->type != \QL_DSP || (!param(mul, \C_REG).as_bool() && !param(mul, \D_REG).as_bool()))) {
+		argQ = sigCD;
+		//subpattern(in_dffe);
+		if (dff) {
+			// Reset signal of C (IRSTTOP) and D (IRSTBOT)
+			//   shared with A and B
+			if (ffA) {
+				if (ffA->hasPort(\ARST) != dff->hasPort(\ARST))
+					goto reject_ffCD;
+				if (ffA->hasPort(\ARST)) {
+					if (port(ffA, \ARST) != port(dff, \ARST))
+						goto reject_ffCD;
+					if (param(ffA, \ARST_POLARITY) != param(dff, \ARST_POLARITY))
+						goto reject_ffCD;
+				}
+			}
+			if (ffB) {
+				if (ffB->hasPort(\ARST) != dff->hasPort(\ARST))
+					goto reject_ffCD;
+				if (ffB->hasPort(\ARST)) {
+					if (port(ffB, \ARST) != port(dff, \ARST))
+						goto reject_ffCD;
+					if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY))
+						goto reject_ffCD;
+				}
+			}
+
+			ffCD = dff;
+			clock = dffclock;
+			clock_pol = dffclock_pol;
+			sigCD = dffD;
+
+reject_ffCD: 		;
+		}
+	}
+endcode
+
+code sigCD
+	sigCD.extend_u0(32, cd_signed);
+endcode
+
+code
+	accept;
+endcode
+
+// #######################
+// Currently, QL_DSP performs only combinatorial operations
+// but we aim to convert it into a mac unit in the futur
+// so we're leaving the subpattern in the code, it is 
+// however not being used for now.
+
+subpattern in_dffe
+arg argD argQ clock clock_pol
+
+code
+	dff = nullptr;
+	if (argQ.empty())
+		reject;
+	for (auto c : argQ.chunks()) {
+		if (!c.wire)
+			reject;
+		if (c.wire->get_bool_attribute(\keep))
+			reject;
+		Const init = c.wire->attributes.at(\init, State::Sx);
+		if (!init.is_fully_undef() && !init.is_fully_zero())
+			reject;
+	}
+endcode
+
+match ff
+	select ff->type.in($dff, $dffe)
+	// DSP48E1 does not support clock inversion
+	select param(ff, \CLK_POLARITY).as_bool()
+
+	slice offset GetSize(port(ff, \D))
+	index <SigBit> port(ff, \Q)[offset] === argQ[0]
+
+	// Check that the rest of argQ is present
+	filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ)
+	filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ
+endmatch
+
+code argQ argD
+{
+	if (clock != SigBit()) {
+		if (port(ff, \CLK) != clock)
+			reject;
+		if (param(ff, \CLK_POLARITY).as_bool() != clock_pol)
+			reject;
+	}
+
+	SigSpec Q = port(ff, \Q);
+	dff = ff;
+	dffclock = port(ff, \CLK);
+	dffclock_pol = param(ff, \CLK_POLARITY).as_bool();
+	dffD = argQ;
+	argD = port(ff, \D);
+	argQ = Q;
+	dffD.replace(argQ, argD);
+}
+endcode
+
+// #######################
+// Currently, QL_DSP performs only combinatorial operations
+// but we aim to convert it into a mac unit in the futur
+// so we're leaving the subpattern in the code, it is 
+// however not being used for now.
+
+subpattern out_dffe
+arg argD argSdff argQ clock clock_pol
+
+code
+	dff = nullptr;
+	for (auto c : argD.chunks())
+		if (c.wire->get_bool_attribute(\keep))
+			reject;
+endcode
+
+match ff
+	select ff->type.in($dff, $dffe, $sdff, $sdffce)
+	// QL_DSP does not support clock inversion
+	select param(ff, \CLK_POLARITY).as_bool()
+
+	slice offset GetSize(port(ff, \D))
+	index <SigBit> port(ff, \D)[offset] === argD[0]
+
+	// Only allow sync reset if requested.
+	filter argSdff || ff->type.in($dff, $dffe)
+	// Check that the rest of argD is present
+	filter GetSize(port(ff, \D)) >= offset + GetSize(argD)
+	filter port(ff, \D).extract(offset, GetSize(argD)) == argD
+endmatch
+
+code argQ
+	if (ff) {
+		if (clock != SigBit()) {
+			if (port(ff, \CLK) != clock)
+				reject;
+			if (param(ff, \CLK_POLARITY).as_bool() != clock_pol)
+				reject;
+		}
+		SigSpec D = port(ff, \D);
+		SigSpec Q = port(ff, \Q);
+		argQ = argD;
+		argQ.replace(D, Q);
+
+		for (auto c : argQ.chunks()) {
+			Const init = c.wire->attributes.at(\init, State::Sx);
+			if (!init.is_fully_undef() && !init.is_fully_zero())
+				reject;
+		}
+
+		dff = ff;
+		dffQ = argQ;
+		dffclock = port(ff, \CLK);
+		dffclock_pol = param(ff, \CLK_POLARITY).as_bool();
+	}
+endcode
diff --git a/yosys-plugins/ql-qlf/qlf_k4n8/arith_map.v b/yosys-plugins/ql-qlf/qlf_k4n8/arith_map.v
new file mode 100644
index 000000000..564b72117
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k4n8/arith_map.v
@@ -0,0 +1,151 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* techmap_celltype = "$alu" *)
+module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
+    parameter A_SIGNED = 0;
+    parameter B_SIGNED = 0;
+    parameter A_WIDTH  = 1;
+    parameter B_WIDTH  = 1;
+    parameter Y_WIDTH  = 1;
+
+    parameter _TECHMAP_CONSTMSK_CI_ = 0;
+    parameter _TECHMAP_CONSTVAL_CI_ = 0;
+
+    (* force_downto *)
+    input [A_WIDTH-1:0] A;
+    (* force_downto *)
+    input [B_WIDTH-1:0] B;
+    (* force_downto *)
+    output [Y_WIDTH-1:0] X, Y;
+
+    input CI, BI;
+    (* force_downto *)
+    output [Y_WIDTH-1:0] CO;
+
+    wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+
+    (* force_downto *)
+    wire [Y_WIDTH-1:0] A_buf, B_buf;
+    \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+    \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+    (* force_downto *)
+    wire [Y_WIDTH-1:0] AA = A_buf;
+    (* force_downto *)
+    wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+    (* force_downto *)
+    wire [Y_WIDTH-1:0] C;
+
+    assign CO = C;
+
+    genvar i;
+    generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
+
+        wire ci;
+        wire co;
+
+        // First in chain
+        generate if (i == 0) begin
+
+            // CI connected to a constant
+            if (_TECHMAP_CONSTMSK_CI_ == 1) begin
+
+                localparam INIT = (_TECHMAP_CONSTVAL_CI_ == 0) ?
+                    16'b0110_0110_0000_1000:
+                    16'b1001_1001_0000_1110;
+
+                // LUT4 configured as 1-bit adder with CI=const
+                adder_lut4 #(
+                    .LUT(INIT),
+                    .IN2_IS_CIN(1'b0)
+                ) lut_ci_adder (
+                    .in({AA[i], BB[i], 1'b1, 1'b1}),
+                    .cin(), 
+                    .lut4_out(Y[i]), 
+                    .cout(ci)
+                );
+
+            // CI connected to a non-const driver
+            end else begin
+
+                // LUT4 configured as passthrough to drive CI of the next stage
+                adder_lut4 #(
+                    .LUT(16'b0000_0000_0000_1100),
+                    .IN2_IS_CIN(1'b0)
+                ) lut_ci (
+                    .in({1'b1, CI, 1'b1, 1'b1}),
+                    .cin(), 
+                    .lut4_out(), 
+                    .cout(ci)
+                );
+            end
+
+        // Not first in chain
+        end else begin
+            assign ci = C[i-1];
+
+        end endgenerate
+
+        // ....................................................
+
+        // Single 1-bit adder, mid-chain adder or non-const CI
+        // adder
+        generate if ((i == 0 && _TECHMAP_CONSTMSK_CI_ == 0) || (i > 0)) begin
+            
+            // LUT4 configured as full 1-bit adder
+            adder_lut4 #(
+                    .LUT(16'b1001_0110_0110_1000),
+                    .IN2_IS_CIN(1'b1)
+                ) lut_adder (
+                    .in({AA[i], BB[i], 1'b1, 1'b1}),
+                    .cin(ci), 
+                    .lut4_out(Y[i]), 
+                    .cout(co)
+                );
+        end else begin
+            assign co = ci;
+
+        end endgenerate
+
+        // ....................................................
+
+        // Last in chain
+        generate if (i == Y_WIDTH-1) begin
+
+            // LUT4 configured for passing its CI input to output. This should
+            // get pruned if the actual CO port is not connected anywhere.
+            adder_lut4 #(
+                    .LUT(16'b1111_0000_1111_0000),
+                    .IN2_IS_CIN(1'b1)
+                ) lut_co (
+                    .in({1'b1, 1'b1, 1'b1, 1'b1}),
+                    .cin(co),
+                    .lut4_out(C[i]),
+                    .cout()
+                );
+        // Not last in chain
+        end else begin
+            assign C[i] = co;
+
+        end endgenerate
+
+    end: slice	  
+    endgenerate
+
+    /* End implementation */
+    assign X = AA ^ BB;
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k4n8/cells_sim.v b/yosys-plugins/ql-qlf/qlf_k4n8/cells_sim.v
new file mode 100644
index 000000000..4ec10f287
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k4n8/cells_sim.v
@@ -0,0 +1,242 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* abc9_box, lib_whitebox *)
+module adder_lut4(
+   output lut4_out,
+   (* abc9_carry *)
+   output cout,
+   input [0:3] in,
+   (* abc9_carry *)
+   input cin
+);
+    parameter [0:15] LUT=0;
+    parameter IN2_IS_CIN = 0;
+
+    wire [0:3] li = (IN2_IS_CIN) ? {in[0], in[1], cin, in[3]} : {in[0], in[1], in[2], in[3]};
+
+    // Output function
+    wire [0:7] s1 = li[0] ?
+        {LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]}:
+        {LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]};
+
+    wire [0:3] s2 = li[1] ? {s1[0], s1[2], s1[4], s1[6]} : 
+                            {s1[1], s1[3], s1[5], s1[7]};
+
+    wire [0:1] s3 = li[2] ? {s2[0], s2[2]} : {s2[1], s2[3]};
+
+    assign lut4_out = li[3] ? s3[0] : s3[1];
+    
+    // Carry out function
+    assign cout = (s2[2]) ? cin : s2[3];
+endmodule
+
+(* abc9_lut=1, lib_whitebox *)
+module frac_lut4(
+   input [0:3] in,
+   output [0:1] lut2_out,
+   output lut4_out
+);
+    parameter [0:15] LUT = 0;
+    
+    // Effective LUT input
+    wire [0:3] li = in;
+
+    // Output function
+    wire [0:7] s1 = li[0] ?
+        {LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]}:
+        {LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]};
+
+    wire [0:3] s2 = li[1] ? {s1[0], s1[2], s1[4], s1[6]} : 
+                            {s1[1], s1[3], s1[5], s1[7]};
+
+    wire [0:1] s3 = li[2] ? {s2[0], s2[2]} : {s2[1], s2[3]};
+
+    assign lut2_out[0] = s2[2];
+    assign lut2_out[1] = s2[3];
+
+    assign  lut4_out = li[3] ? s3[0] : s3[1];
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module scff(
+    output reg Q,
+    input D,
+    input clk
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge clk)
+        Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dff(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge C)
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input R
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge C or negedge R)
+        if (!R)
+            Q <= 1'b0;
+        else 
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module sh_dff(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge C)
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffs(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge C or negedge S)
+        if (!S)
+            Q <= 1'b1;
+        else
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffn(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(negedge C)
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffnr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input R
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(negedge C or negedge R)
+        if (!R)
+            Q <= 1'b0;
+        else 
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffns(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(negedge C or negedge S)
+        if (!S)
+            Q <= 1'b1;
+        else
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffsr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge C or negedge S or negedge R)
+        if (!S)
+            Q <= 1'b1;
+        else if (!R)
+            Q <= 1'b0;
+        else
+            Q <= D;
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffnsr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    input C,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(negedge C or negedge S or negedge R)
+        if (!S)
+            Q <= 1'b1;
+        else if (!R)
+            Q <= 1'b0;
+        else
+            Q <= D;
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k4n8/ffs_map.v b/yosys-plugins/ql-qlf/qlf_k4n8/ffs_map.v
new file mode 100644
index 000000000..61fab5f88
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k4n8/ffs_map.v
@@ -0,0 +1,205 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$_DFF_P_ (D, Q, C);
+    input D;
+    input C;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C),  .R(1'b1), .S(1'b1));
+endmodule
+
+module \$_DFF_PN0_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(1'b1));
+endmodule
+
+module \$_DFF_PP0_ (D, Q, C, R); 
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(1'b1));
+endmodule
+
+module \$_DFF_PN1_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(1'b1), .S(R));
+endmodule
+
+module \$_DFF_PP1_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(1'b1), .S(!R));
+endmodule
+
+module \$_DFF_N_ (D, Q, C);
+    input D;
+    input C;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(1'b1), .S(1'b1));
+endmodule
+
+module \$_DFF_NN0_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(1'b1));
+endmodule
+
+module \$_DFF_NP0_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(1'b1));
+endmodule
+
+module \$_DFF_NN1_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(1'b1), .S(R));
+endmodule
+
+module \$_DFF_NP1_ (D, Q, C, R);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(1'b1), .S(!R));
+endmodule
+
+module \$_DFFSR_PPP_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(!S));
+endmodule
+
+module \$_DFFSR_PNP_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(S));
+endmodule
+
+module \$_DFFSR_PNN_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+module \$_DFFSR_PPN_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(!S));
+endmodule
+
+module \$_DFFSR_NPP_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(!S));
+endmodule
+
+module \$_DFFSR_NNP_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(!R), .S(S));
+endmodule
+
+module \$_DFFSR_NNN_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+module \$_DFFSR_NPN_ (D, Q, C, R, S);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffnsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(!S));
+endmodule
+
+module \$__SHREG_DFF_P_ (D, Q, C);
+    input D;
+    input C;
+    output Q;
+
+    parameter DEPTH = 2;
+    reg [DEPTH-2:0] q;
+    genvar i;
+    generate for (i = 0; i < DEPTH; i = i + 1) begin: slice
+
+
+        // First in chain
+        generate if (i == 0) begin
+                 sh_dff #() shreg_beg (
+                    .Q(q[i]),
+                    .D(D),
+                    .C(C)
+                );
+        end endgenerate
+        // Middle in chain
+        generate if (i > 0 && i != DEPTH-1) begin
+                 sh_dff #() shreg_mid (
+                    .Q(q[i]),
+                    .D(q[i-1]),
+                    .C(C)
+                );
+        end endgenerate
+        // Last in chain
+        generate if (i == DEPTH-1) begin
+                 sh_dff #() shreg_end (
+                    .Q(Q),
+                    .D(q[i-1]),
+                    .C(C)
+                );
+        end endgenerate
+   end: slice
+   endgenerate
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/arith_map.v b/yosys-plugins/ql-qlf/qlf_k6n10/arith_map.v
new file mode 100644
index 000000000..092120f39
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/arith_map.v
@@ -0,0 +1,84 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+//////////////////////////
+//      arithmetic      //
+//////////////////////////
+
+(* techmap_celltype = "$alu" *)
+module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
+
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	input [A_WIDTH-1:0] A;
+	input [B_WIDTH-1:0] B;
+	output [Y_WIDTH-1:0] X, Y;
+
+	input CI, BI;
+	output [Y_WIDTH-1:0] CO;
+
+	wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
+
+        (* force_downto *)
+        wire [Y_WIDTH-1:0] A_buf, B_buf;
+        \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+        \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+        (* force_downto *)
+        wire [Y_WIDTH-1:0] AA = A_buf;
+        (* force_downto *)
+        wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+	wire [Y_WIDTH: 0 ] CARRY;
+
+	assign CO[Y_WIDTH-1:0] = CARRY[Y_WIDTH:1];
+	// Due to VPR limitations regarding IO connexion to carry chain,
+	// we generate the carry chain input signal using an intermediate adder
+	// since we can connect a & b from io pads, but not cin & cout
+	generate
+	     adder intermediate_adder (
+	       .cin     ( ),
+	       .cout    (CARRY[0]),
+	       .a       (CI     ),
+	       .b       (CI     ),
+	       .sumout  (      )
+	     );
+
+	     adder first_adder (
+	       .cin     (CARRY[0]),
+	       .cout    (CARRY[1]),
+	       .a       (AA[0]  ),
+	       .b       (BB[0]  ),
+	       .sumout  (Y[0]   )
+	     );
+	endgenerate
+
+	genvar i;
+	generate for (i = 1; i < Y_WIDTH ; i = i+1) begin:gen3
+	     adder my_adder (
+	       .cin     (CARRY[i]  ),
+	       .cout    (CARRY[i+1]),
+	       .a       (AA[i]     ),
+	       .b       (BB[i]     ),
+	       .sumout  (Y[i]      )
+	     );
+	end endgenerate
+	assign X = AA ^ BB;
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/brams.txt b/yosys-plugins/ql-qlf/qlf_k6n10/brams.txt
new file mode 100644
index 000000000..93d78d59b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/brams.txt
@@ -0,0 +1,139 @@
+bram $__QLF_RAM16K_M0
+  init 1
+  abits 8
+  dbits 32
+  groups 2
+  ports  1  1
+  wrmode 0 1
+  enable 1 1
+  transp 0  0
+  clocks 1  1
+  clkpol 1  1
+endbram
+
+bram $__QLF_RAM16K_M1
+  init 1
+  abits  9
+  dbits  32
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 1
+  transp 0 0
+  clocks 1 1
+  clkpol 1 1
+endbram
+
+bram $__QLF_RAM16K_M2
+  init 1
+  abits  10
+  dbits  32
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 1
+  transp 0 0
+  clocks 1 1
+  clkpol 1 1
+endbram
+
+bram $__QLF_RAM16K_M3
+  init 1
+  abits 11
+  dbits  32
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 1
+  transp 0 0
+  clocks 1 1
+  clkpol 1 1
+endbram
+
+
+# The syn_* attributes are described in:
+# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
+attr_icase 1
+
+match $__QLF_RAM16K_M0
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min dbits 17
+  make_transp
+endmatch
+
+
+match $__QLF_RAM16K_M1
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min dbits 9
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_RAM16K_M1
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min efficiency 2
+  make_transp
+endmatch
+
+
+match $__QLF_RAM16K_M2
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min dbits 5
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_RAM16K_M2
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min efficiency 2
+  make_transp
+endmatch
+
+match $__QLF_RAM16K_M3
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  max dbits 4
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_RAM16K_M3
+  # implicitly requested RAM or ROM
+  attribute !syn_ramstyle syn_ramstyle=auto
+  attribute !syn_romstyle syn_romstyle=auto
+  attribute !ram_block
+  attribute !rom_block
+  attribute !logic_block
+  min efficiency 2
+  make_transp
+endmatch
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/brams_map.v b/yosys-plugins/ql-qlf/qlf_k6n10/brams_map.v
new file mode 100644
index 000000000..a22685cda
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/brams_map.v
@@ -0,0 +1,215 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+
+module \$__QLF_RAM16K (
+	output [31:0] RDATA,
+	input         RCLK, RE,
+	input  [8:0] RADDR,
+	input         WCLK, WE,
+	input  [8:0] WADDR,
+	input  [31:0] WENB,
+	input  [31:0] WDATA
+);
+
+	generate
+		DP_RAM16K #()
+			_TECHMAP_REPLACE_ (
+			.d_out(RDATA),
+			.rclk (RCLK ),
+			.wclk (WCLK ),
+			.ren  (RE   ),
+			.raddr(RADDR),
+			.wen  (WE   ),
+			.waddr(WADDR),
+			.wenb (WENB ),
+			.d_in (WDATA)
+		);
+	endgenerate
+
+endmodule
+
+
+module \$__QLF_RAM16K_M0 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+
+	parameter [4095:0] INIT = 4096'bx;
+
+	input CLK1;
+
+	input [8:0] A1ADDR;
+	output [31:0] A1DATA;
+	input A1EN;
+
+	input [8:0] B1ADDR;
+	input [31:0] B1DATA;
+	input B1EN;
+
+	wire [31:0] WENB;
+	assign WENB = 32'hFFFFFFFF;
+
+	\$__QLF_RAM16K #()
+		 _TECHMAP_REPLACE_ (
+		.RDATA(A1DATA),
+		.RADDR(A1ADDR),
+		.RCLK (CLK1  ),
+		.RE   (A1EN  ),
+		.WDATA(B1DATA),
+		.WADDR(B1ADDR),
+		.WCLK (CLK1  ),
+		.WE   (B1EN  ),
+		.WENB (WENB  )
+	);
+endmodule
+
+
+module \$__QLF_RAM16K_M1 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+
+	parameter [4095:0] INIT = 4096'bx;
+
+	input CLK1;
+
+	input [9:0] A1ADDR;
+	output [31:0] A1DATA;
+	input A1EN;
+
+	input [9:0] B1ADDR;
+	input [31:0] B1DATA;
+	input B1EN;
+
+	wire [31:0] WENB;
+	wire [31:0] WDATA;
+
+	generate
+		wire A1BAR;
+		assign A1BAR = ~A1ADDR[0];
+		assign WDATA = { {2{B1DATA[15:0]}}};
+	endgenerate
+
+	assign WENB = { {16{A1ADDR[0]}} , {16{A1BAR}}};
+
+
+	\$__QLF_RAM16K #()
+		 _TECHMAP_REPLACE_ (
+		.RDATA(A1DATA     ),
+		.RADDR(A1ADDR     ),
+		.RCLK (CLK1       ),
+		.RE   (A1EN       ),
+		.WDATA(WDATA      ),
+		.WADDR(B1ADDR[9:1]),
+		.WCLK (CLK1       ),
+		.WENB (WENB       ),
+		.WE   (B1EN       )
+	);
+
+endmodule
+
+module \$__QLF_RAM16K_M2 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+
+	parameter [4095:0] INIT = 4096'bx;
+
+	input CLK1;
+
+	input [10:0] A1ADDR;
+	output [31:0] A1DATA;
+	input A1EN;
+
+	input [10:0] B1ADDR;
+	input [7:0] B1DATA;
+	input B1EN;
+
+	wire [31:0] WENB;
+	wire [31:0] WDATA;
+
+	generate
+		wire A1BAR0, A1BAR1;
+		assign A1BAR0 = ~A1ADDR[0];
+		assign A1BAR1 = ~A1ADDR[1];
+		assign WDATA = { {4{B1DATA[7:0]}}};
+	endgenerate
+
+	assign WENB = { {8{A1ADDR[1]& A1ADDR[0]}},
+			{8{A1ADDR[1]& A1BAR0}}   , 
+			{8{A1BAR1   & A1ADDR[0]}}, 
+			{8{A1BAR1   & A1BAR0}}}	 ;
+
+
+	\$__QLF_RAM16K #()
+		 _TECHMAP_REPLACE_ (
+		.RDATA(A1DATA      ),
+		.RADDR(A1ADDR      ),
+		.RCLK (CLK1        ),
+		.RE   (A1EN        ),
+		.WDATA(B1DATA      ),
+		.WADDR(B1ADDR[10:2]),
+		.WCLK (CLK1        ),
+		.WENB (WENB        ),
+		.WE   (B1EN        )
+	);
+
+endmodule
+
+module \$__QLF_RAM16K_M3 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+	parameter [4095:0] INIT = 4096'bx;
+
+	input CLK1;
+
+	input [11:0] A1ADDR;
+	output [31:0] A1DATA;
+	input A1EN;
+
+	input [11:0] B1ADDR;
+	input [3:0] B1DATA;
+	input B1EN;
+
+	wire [31:0] WENB;
+	wire [31:0] WDATA;
+
+	generate
+		assign WDATA = { {8{B1DATA[3:0]}}};
+		wire A1BAR0, A1BAR1, A1BAR2;
+		assign A1BAR0 = ~A1ADDR[0];
+		assign A1BAR1 = ~A1ADDR[1];
+		assign A1BAR2 = ~A1ADDR[2];
+	endgenerate
+
+		assign WENB = { {4{A1ADDR[2] &A1ADDR[1] & A1ADDR[0]}}, 
+				{4{A1ADDR[2] &A1ADDR[1] & A1BAR0}}   , 
+				{4{A1ADDR[2] &A1BAR1    & A1ADDR[0]}}, 
+				{4{A1ADDR[2] &A1BAR1    & A1BAR0}}   , 
+				{4{A1BAR2    &A1ADDR[1] & A1ADDR[0]}}, 
+				{4{A1BAR2    &A1ADDR[1] & A1BAR0}}   , 
+				{4{A1BAR2    &A1BAR1    & A1ADDR[0]}}, 
+				{4{A1BAR2    &A1BAR1    & A1BAR0}}}  ; 
+
+	\$__QLF_RAM16K #()
+		 _TECHMAP_REPLACE_ (
+		.RDATA(A1DATA      ),
+		.RADDR(A1ADDR      ),
+		.RCLK (CLK1        ),
+		.RE   (A1EN        ),
+		.WDATA(B1DATA      ),
+		.WADDR(B1ADDR[11:3]),
+		.WCLK (CLK1        ),
+		.WENB (WENB        ),
+		.WE   (B1EN        )
+	);
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/cells_sim.v b/yosys-plugins/ql-qlf/qlf_k6n10/cells_sim.v
new file mode 100644
index 000000000..ab875f153
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/cells_sim.v
@@ -0,0 +1,461 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* abc9_box, lib_whitebox *)
+module adder(
+    output sumout,
+    output cout,
+    input a,
+    input b,
+    input cin
+);
+    assign sumout = a ^ b ^ cin;
+    assign cout = (a & b) | ((a | b) & cin);
+
+endmodule
+
+
+
+(* abc9_lut=1, lib_whitebox *)
+module frac_lut6(
+    input [0:5] in,
+    output [0:3] lut4_out,
+    output [0:1] lut5_out,
+    output lut6_out
+);
+    parameter [0:63] LUT = 0;
+    // Effective LUT input
+    wire [0:5] li = in;
+
+    // Output function
+    wire [0:31] s1 = li[0] ?
+    {LUT[0] , LUT[2] , LUT[4] , LUT[6] , LUT[8] , LUT[10], LUT[12], LUT[14], 
+     LUT[16], LUT[18], LUT[20], LUT[22], LUT[24], LUT[26], LUT[28], LUT[30],
+     LUT[32], LUT[34], LUT[36], LUT[38], LUT[40], LUT[42], LUT[44], LUT[46],
+     LUT[48], LUT[50], LUT[52], LUT[54], LUT[56], LUT[58], LUT[60], LUT[62]}:
+    {LUT[1] , LUT[3] , LUT[5] , LUT[7] , LUT[9] , LUT[11], LUT[13], LUT[15], 
+     LUT[17], LUT[19], LUT[21], LUT[23], LUT[25], LUT[27], LUT[29], LUT[31],
+     LUT[33], LUT[35], LUT[37], LUT[39], LUT[41], LUT[43], LUT[45], LUT[47],
+     LUT[49], LUT[51], LUT[53], LUT[55], LUT[57], LUT[59], LUT[61], LUT[63]};
+
+    wire [0:15] s2 = li[1] ?
+    {s1[0] , s1[2] , s1[4] , s1[6] , s1[8] , s1[10], s1[12], s1[14],
+     s1[16], s1[18], s1[20], s1[22], s1[24], s1[26], s1[28], s1[30]}:
+    {s1[1] , s1[3] , s1[5] , s1[7] , s1[9] , s1[11], s1[13], s1[15],
+     s1[17], s1[19], s1[21], s1[23], s1[25], s1[27], s1[29], s1[31]};
+
+    wire [0:7] s3 = li[2] ?
+    {s2[0], s2[2], s2[4], s2[6], s2[8], s2[10], s2[12], s2[14]}:
+    {s2[1], s2[3], s2[5], s2[7], s2[9], s2[11], s2[13], s2[15]};
+
+    wire [0:3] s4 = li[3] ? {s3[0], s3[2], s3[4], s3[6]}:
+                            {s3[1], s3[3], s3[5], s3[7]};
+
+    wire [0:1] s5 = li[4] ? {s4[0], s4[2]} : {s4[1], s4[3]};
+
+    assign lut4_out[0] = s4[0];
+    assign lut4_out[1] = s4[1];
+    assign lut4_out[2] = s4[2];
+    assign lut4_out[3] = s4[3];
+
+    assign lut5_out[0] = s5[0];
+    assign lut5_out[1] = s5[1];
+
+    assign lut6_out = li[5] ? s5[0] : s5[1];
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dff(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C)
+                Q <= D;
+          1'b1:
+            always @(negedge C)
+                Q <= D;
+    endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffr(
+    output reg Q,
+    input D,
+    input R,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge R)
+                if (R)
+                        Q <= 1'b0;
+                else
+                        Q <= D;
+          1'b1:
+            always @(negedge C or posedge R)
+                if (R)
+                        Q <= 1'b0;
+                else
+                        Q <= D;
+    endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffre(
+    output reg Q,
+    input D,
+    input R,
+    input E,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge R)
+              if (R)
+                Q <= 1'b0;
+              else if(E)
+                Q <= D;
+          1'b1:
+            always @(negedge C or posedge R)
+              if (R)
+                Q <= 1'b0;
+              else if(E)
+                Q <= D;
+        endcase
+endmodule
+
+module dffs(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else
+                Q <= D;
+        endcase
+endmodule
+
+module dffse(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input S,
+    input E
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else if(E)
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S)
+              if (S)
+                Q <= 1'b1;
+              else if(E)
+                Q <= D;
+        endcase
+endmodule
+
+module dffsr(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or negedge S or negedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else
+                Q <= D;
+          1'b1:
+            always @(negedge C or negedge S or negedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else
+                Q <= D;
+        endcase
+endmodule
+
+module dffsre(
+    output reg Q,
+    input D,
+    (* clkbuf_sink *)
+    (* invertible_pin = "IS_C_INVERTED" *)
+    input C,
+    input E,
+    input R,
+    input S
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    case(|IS_C_INVERTED)
+          1'b0:
+            always @(posedge C or posedge S or posedge R)
+              if (S)
+                Q <= 1'b1;
+              else if (R)
+                Q <= 1'b0;
+              else if (E)
+                Q <= D;
+        endcase
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module latchsre (
+    output reg Q,
+    input S,
+    input R,
+    input D,
+    input G,
+    input E
+);
+    parameter [0:0] INIT = 1'b0;
+    parameter [0:0] IS_C_INVERTED = 1'b0;
+    initial Q = INIT;
+    always @*
+            begin
+              if (R) Q <= 1'b0;
+              if (S) Q <= 1'b1;
+            else if (E && G) Q <= D;
+    end
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module scff(
+    output reg Q,
+    input D,
+    input clk
+);
+    parameter [0:0] INIT = 1'b0;
+    initial Q = INIT;
+
+    always @(posedge clk)
+            Q <= D;
+endmodule
+
+module DP_RAM16K (
+    input rclk, 
+    input wclk,
+    input wen,
+    input ren,
+    input[8:0] waddr,
+    input[8:0] raddr,
+    input[31:0] d_in,
+    input[31:0] wenb,
+    output[31:0] d_out );
+
+    _dual_port_sram memory_0 (
+                .wclk           (wclk),
+                .wen            (wen),
+                .waddr          (waddr),
+                .data_in        (d_in),
+                .rclk           (rclk),
+                .ren            (ren),
+                .raddr          (raddr),
+                .wenb		(wenb),
+                .d_out          (d_out) );
+
+endmodule
+
+module _dual_port_sram (
+    input wclk,
+    input wen,
+    input[8:0] waddr,
+    input[31:0] data_in,
+    input rclk,
+    input ren,
+    input[8:0] raddr,
+    input[31:0] wenb,
+    output[31:0] d_out );
+
+    // MODE 0:  512 x 32
+    // MODE 1: 1024 x 16
+    // MODE 2: 1024 x 8
+    // MODE 3: 2048 x 4
+        
+    integer i;
+    reg[31:0] ram[512:0];
+    reg[31:0] internal;
+    // The memory is self initialised
+        
+    initial begin
+            for (i=0;i<=512;i=i+1)
+            begin
+                ram[i] = 0;
+            end
+            internal = 31'b0; 
+    end
+    
+    wire [31:0] WMASK;
+
+    assign d_out = internal;
+    assign WMASK = wenb;
+
+    always @(posedge wclk) begin
+            if(!wen) begin
+              if (WMASK[ 0]) ram[waddr][ 0] <= data_in[ 0];
+              if (WMASK[ 1]) ram[waddr][ 1] <= data_in[ 1];
+              if (WMASK[ 2]) ram[waddr][ 2] <= data_in[ 2];
+              if (WMASK[ 3]) ram[waddr][ 3] <= data_in[ 3];
+              if (WMASK[ 4]) ram[waddr][ 4] <= data_in[ 4];
+              if (WMASK[ 5]) ram[waddr][ 5] <= data_in[ 5];
+              if (WMASK[ 6]) ram[waddr][ 6] <= data_in[ 6];
+              if (WMASK[ 7]) ram[waddr][ 7] <= data_in[ 7];
+              if (WMASK[ 8]) ram[waddr][ 8] <= data_in[ 8];
+              if (WMASK[ 9]) ram[waddr][ 9] <= data_in[ 9];
+              if (WMASK[10]) ram[waddr][10] <= data_in[10];
+              if (WMASK[11]) ram[waddr][11] <= data_in[11];
+              if (WMASK[12]) ram[waddr][12] <= data_in[12];
+              if (WMASK[13]) ram[waddr][13] <= data_in[13];
+              if (WMASK[14]) ram[waddr][14] <= data_in[14];
+              if (WMASK[15]) ram[waddr][15] <= data_in[15];
+              if (WMASK[16]) ram[waddr][16] <= data_in[16];
+              if (WMASK[17]) ram[waddr][17] <= data_in[17];
+              if (WMASK[18]) ram[waddr][18] <= data_in[18];
+              if (WMASK[19]) ram[waddr][19] <= data_in[19];
+              if (WMASK[20]) ram[waddr][20] <= data_in[20];
+              if (WMASK[21]) ram[waddr][21] <= data_in[21];
+              if (WMASK[22]) ram[waddr][22] <= data_in[22];
+              if (WMASK[23]) ram[waddr][23] <= data_in[23];
+              if (WMASK[24]) ram[waddr][24] <= data_in[24];
+              if (WMASK[25]) ram[waddr][25] <= data_in[25];
+              if (WMASK[26]) ram[waddr][26] <= data_in[26];
+              if (WMASK[27]) ram[waddr][27] <= data_in[27];
+              if (WMASK[28]) ram[waddr][28] <= data_in[28];
+              if (WMASK[29]) ram[waddr][29] <= data_in[29];
+              if (WMASK[30]) ram[waddr][30] <= data_in[30];
+              if (WMASK[31]) ram[waddr][31] <= data_in[31];
+            end
+    end
+
+    always @(posedge rclk) begin
+            if(!ren) begin
+              internal <= ram[raddr];
+            end
+    end
+endmodule
+
+module QL_DSP (
+    input CLK,
+    input [15:0] A, B, C, D,
+    output [31:0] O,
+    output CO // Currently unused, left in case we want to support signed operations in the future.
+);
+    parameter [0:0] A_REG = 0;
+    parameter [0:0] B_REG = 0;
+    parameter [0:0] C_REG = 0;
+    parameter [0:0] D_REG = 0;
+    parameter [0:0] ENABLE_DSP = 0;
+    parameter [0:0] A_SIGNED = 0;
+    parameter [0:0] B_SIGNED = 0;
+
+    wire [15:0] iA, iB, iC, iD;
+    wire [15:0] iF, iJ, iK, iG;
+
+    // Regs C and A, currently unused
+    reg [15:0] rC, rA;
+
+    assign iC = C_REG ? rC : C;
+    assign iA = A_REG ? rA : A;
+
+    // Regs B and D, currently unused
+    reg [15:0] rB, rD;
+
+    assign iB = B_REG ? rB : B;
+    assign iD = D_REG ? rD : D;
+
+    // Multiplier Stage
+    wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
+    wire [15:0] Ah, Al, Bh, Bl;
+    assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
+    assign Al = {8'b0, iA[ 7: 0]};
+    assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
+    assign Bl = {8'b0, iB[ 7: 0]};
+    assign p_Ah_Bh = Ah * Bh; // F
+    assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J
+    assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K
+    assign p_Al_Bl = Al * Bl; // G
+
+    assign iF = p_Ah_Bh;
+    assign iJ = p_Al_Bh;
+
+    assign iK = p_Ah_Bl;
+    assign iG = p_Al_Bl;
+
+    // Adder Stage
+    wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK};
+    wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ};
+    assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16);
+
+    // Output Stage
+    assign O = iL;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/dsp_map.v b/yosys-plugins/ql-qlf/qlf_k6n10/dsp_map.v
new file mode 100644
index 000000000..aa9842918
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/dsp_map.v
@@ -0,0 +1,35 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$__MUL16X16 (input [15:0] A, input [15:0] B, output [31:0] Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 0;
+	parameter B_WIDTH = 0;
+	parameter Y_WIDTH = 0;
+
+	QL_DSP #(
+		.A_REG(1'b0),
+		.B_REG(1'b0),
+		.C_REG(1'b0),
+		.D_REG(1'b0),
+		.ENABLE_DSP(1'b1),
+	) _TECHMAP_REPLACE_ (
+		.A(A),
+		.B(B),
+		.O(Y),
+	);
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/ffs_map.v b/yosys-plugins/ql-qlf/qlf_k6n10/ffs_map.v
new file mode 100644
index 000000000..9182f3702
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/ffs_map.v
@@ -0,0 +1,165 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+// Basic DFF
+
+module \$_DFF_P_ (D, C, Q);
+    input D;
+    input C;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dff _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
+endmodule
+
+// Async reset
+module \$_DFF_PP0_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
+endmodule
+
+// Async set
+module \$_DFF_PP1_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffs _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
+endmodule
+
+// Async reset, enable
+
+module  \$_DFFE_PP0P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffre  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
+endmodule
+
+// Async set, enable
+
+module  \$_DFFE_PP1P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffse  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(S));
+endmodule
+
+// Async set & reset
+
+module \$_DFFSR_PPP_ (D, C, R, S, Q);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+// Async set, reset & enable
+
+module \$_DFFSRE_PPPP_ (D, Q, C, E, R, S);
+    input D;
+    input C;
+    input E;
+    input R;
+    input S;
+    output Q;
+    dffsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
+
+// Latch with async set and reset
+module  \$_DLATCHSR_PPP_ (input E, S, R, D, output Q);
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    latchsre _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E),  .R(R), .S(S));
+endmodule
+
+// The following techmap operation are not performed right now
+// as Negative edge FF are not legalized in synth_quicklogic for qlf_k6n10
+// but in case we implement clock inversion in the future, the support is ready for it.
+
+module \$_DFF_N_ (D, C, Q);
+    input D;
+    input C;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dff #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
+endmodule
+
+module \$_DFF_NP0_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffr #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
+endmodule
+
+module \$_DFF_NP1_ (D, C, R, Q);
+    input D;
+    input C;
+    input R;
+    output Q;
+    dffs #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
+endmodule
+
+module  \$_DFFE_NP0P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffre #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R));
+endmodule
+
+module  \$_DFFE_NP1P_ (D, C, E, R, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    output Q;
+    parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
+    dffse #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(S));
+endmodule
+
+module \$_DFFSR_NPP_ (D, C, R, S, Q);
+    input D;
+    input C;
+    input R;
+    input S;
+    output Q;
+    dffsr #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R), .S(S));
+endmodule
+
+module \$_DFFSRE_PPPP_ (D, C, E, R, S, Q);
+    input D;
+    input C;
+    input E;
+    input R;
+    input S;
+    output Q;
+    dffsre #(.IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10/lut_map.v b/yosys-plugins/ql-qlf/qlf_k6n10/lut_map.v
new file mode 100644
index 000000000..9d24cba0a
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10/lut_map.v
@@ -0,0 +1,39 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`ifndef NO_LUT
+module \$lut (A, Y);
+    parameter WIDTH = 0;
+    parameter LUT = 0;
+
+    (* force_downto *)
+    input [WIDTH-1:0] A;
+    output Y;
+
+    generate
+	    if (WIDTH == 6) begin
+	       frac_lut6 #(.LUT(LUT)) _TECHMAP_REPLACE_ (.lut6_out(Y),.in(A));
+
+	    end else begin
+	       wire _TECHMAP_FAIL_ = 1;
+	    end
+    endgenerate
+
+endmodule
+`endif
+
+
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/TDP18K_FIFO.v b/yosys-plugins/ql-qlf/qlf_k6n10f/TDP18K_FIFO.v
new file mode 100644
index 000000000..41792686e
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/TDP18K_FIFO.v
@@ -0,0 +1,341 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 wire
+module TDP18K_FIFO (
+	RMODE_A_i,
+	RMODE_B_i,
+	WMODE_A_i,
+	WMODE_B_i,
+	WEN_A_i,
+	WEN_B_i,
+	REN_A_i,
+	REN_B_i,
+	CLK_A_i,
+	CLK_B_i,
+	BE_A_i,
+	BE_B_i,
+	ADDR_A_i,
+	ADDR_B_i,
+	WDATA_A_i,
+	WDATA_B_i,
+	RDATA_A_o,
+	RDATA_B_o,
+	EMPTY_o,
+	EPO_o,
+	EWM_o,
+	UNDERRUN_o,
+	FULL_o,
+	FMO_o,
+	FWM_o,
+	OVERRUN_o,
+	FLUSH_ni,
+	FMODE_i,
+);
+	parameter SYNC_FIFO_i = 1'b0;
+	parameter POWERDN_i = 1'b0;
+	parameter SLEEP_i = 1'b0;
+	parameter PROTECT_i = 1'b0;
+	parameter UPAF_i = 11'b0;
+	parameter UPAE_i = 11'b0;
+
+	input wire [2:0] RMODE_A_i;
+	input wire [2:0] RMODE_B_i;
+	input wire [2:0] WMODE_A_i;
+	input wire [2:0] WMODE_B_i;
+	input wire WEN_A_i;
+	input wire WEN_B_i;
+	input wire REN_A_i;
+	input wire REN_B_i;
+	(* clkbuf_sink *)
+	input wire CLK_A_i;
+	(* clkbuf_sink *)
+	input wire CLK_B_i;
+	input wire [1:0] BE_A_i;
+	input wire [1:0] BE_B_i;
+	input wire [13:0] ADDR_A_i;
+	input wire [13:0] ADDR_B_i;
+	input wire [17:0] WDATA_A_i;
+	input wire [17:0] WDATA_B_i;
+	output reg [17:0] RDATA_A_o;
+	output reg [17:0] RDATA_B_o;
+	output wire EMPTY_o;
+	output wire EPO_o;
+	output wire EWM_o;
+	output wire UNDERRUN_o;
+	output wire FULL_o;
+	output wire FMO_o;
+	output wire FWM_o;
+	output wire OVERRUN_o;
+	input wire FLUSH_ni;
+	input wire FMODE_i;
+	reg [17:0] wmsk_a;
+	reg [17:0] wmsk_b;
+	wire [8:0] addr_a;
+	wire [8:0] addr_b;
+	reg [4:0] addr_a_d;
+	reg [4:0] addr_b_d;
+	wire [17:0] ram_rdata_a;
+	wire [17:0] ram_rdata_b;
+	reg [17:0] aligned_wdata_a;
+	reg [17:0] aligned_wdata_b;
+	wire ren_o;
+	wire [10:0] ff_raddr;
+	wire [10:0] ff_waddr;
+	wire [13:0] ram_addr_a;
+	wire [13:0] ram_addr_b;
+	wire [3:0] ram_waddr_a;
+	wire [3:0] ram_waddr_b;
+	wire initn;
+	wire smux_rclk;
+	wire smux_wclk;
+	wire real_fmode;
+	wire [3:0] raw_fflags;
+	reg [1:0] fifo_rmode;
+	reg [1:0] fifo_wmode;
+	wire smux_clk_a;
+	wire smux_clk_b;
+	wire ram_ren_a;
+	wire ram_ren_b;
+	wire ram_wen_a;
+	wire ram_wen_b;
+	wire cen_a;
+	wire cen_b;
+	wire cen_a_n;
+	wire cen_b_n;
+	wire ram_wen_a_n;
+	wire ram_wen_b_n;
+	localparam MODE_9 = 3'b001;
+	always @(*) begin
+		fifo_rmode = (RMODE_B_i == MODE_9 ? 2'b10 : 2'b01);
+		fifo_wmode = (WMODE_A_i == MODE_9 ? 2'b10 : 2'b01);
+	end
+	assign smux_clk_a = CLK_A_i;
+	assign smux_clk_b = CLK_B_i;
+	assign real_fmode = FMODE_i;
+	assign ram_ren_b = real_fmode ? ren_o : REN_B_i;
+	assign ram_wen_a = FMODE_i ? ~FULL_o & WEN_A_i : WEN_A_i;
+	assign ram_ren_a = FMODE_i ? 0 : REN_A_i;
+	assign ram_wen_b = FMODE_i ? 1'b0 : WEN_B_i;
+	assign cen_b = ram_ren_b | ram_wen_b;
+	assign cen_a = ram_ren_a | ram_wen_a;
+	assign ram_waddr_b = real_fmode ? {ff_raddr[0], 3'b000} : ADDR_B_i[3:0];
+	assign ram_waddr_a = real_fmode ? {ff_waddr[0], 3'b000} : ADDR_A_i[3:0];
+	assign ram_addr_b = real_fmode ? {ff_raddr[10:0], 3'h0} : {ADDR_B_i[13:4], addr_b_d[3:0]};
+	assign ram_addr_a = real_fmode ? {ff_waddr[10:0], 3'h0} : {ADDR_A_i[13:4], addr_a_d[3:0]};
+	always @(posedge CLK_A_i) addr_a_d[3:0] <= ADDR_A_i[3:0];
+	always @(posedge CLK_B_i) addr_b_d[3:0] <= ADDR_B_i[3:0];
+	assign cen_a_n = ~cen_a;
+	assign ram_wen_a_n = ~ram_wen_a;
+	assign cen_b_n = ~cen_b;
+	assign ram_wen_b_n = ~ram_wen_b;
+
+	sram1024x18 uram(
+		.clk_a(smux_clk_a),
+		.cen_a(cen_a_n),
+		.wen_a(ram_wen_a_n),
+		.addr_a(ram_addr_a[13:4]),
+		.wmsk_a(wmsk_a),
+		.wdata_a(aligned_wdata_a),
+		.rdata_a(ram_rdata_a),
+		.clk_b(smux_clk_b),
+		.cen_b(cen_b_n),
+		.wen_b(ram_wen_b_n),
+		.addr_b(ram_addr_b[13:4]),
+		.wmsk_b(wmsk_b),
+		.wdata_b(aligned_wdata_b),
+		.rdata_b(ram_rdata_b)
+	);
+	fifo_ctl #(
+		.ADDR_WIDTH(11),
+		.FIFO_WIDTH(2),
+		.DEPTH(6)
+	) fifo_ctl(
+		.rclk(smux_clk_b),
+		.rst_R_n(FLUSH_ni),
+		.wclk(smux_clk_a),
+		.rst_W_n(FLUSH_ni),
+		.ren(REN_B_i),
+		.wen(ram_wen_a),
+		.sync(SYNC_FIFO_i),
+		.rmode(fifo_rmode),
+		.wmode(fifo_wmode),
+		.ren_o(ren_o),
+		.fflags({FULL_o, FMO_o, FWM_o, OVERRUN_o, EMPTY_o, EPO_o, EWM_o, UNDERRUN_o}),
+		.raddr(ff_raddr),
+		.waddr(ff_waddr),
+		.upaf(UPAF_i),
+		.upae(UPAE_i)
+	);
+	localparam MODE_1 = 3'b101;
+	localparam MODE_18 = 3'b010;
+	localparam MODE_2 = 3'b110;
+	localparam MODE_4 = 3'b100;
+	always @(*) begin : WDATA_MODE_SEL
+		if (ram_wen_a == 1) begin
+			case (WMODE_A_i)
+				MODE_18: begin
+					aligned_wdata_a = WDATA_A_i;
+					{wmsk_a[17], wmsk_a[15:8]} = (FMODE_i ? 9'h000 : (BE_A_i[1] ? 9'h000 : 9'h1ff));
+					{wmsk_a[16], wmsk_a[7:0]} = (FMODE_i ? 9'h000 : (BE_A_i[0] ? 9'h000 : 9'h1ff));
+				end
+				MODE_9: begin
+					aligned_wdata_a = {{2 {WDATA_A_i[16]}}, {2 {WDATA_A_i[7:0]}}};
+					{wmsk_a[17], wmsk_a[15:8]} = (ram_waddr_a[3] ? 9'h000 : 9'h1ff);
+					{wmsk_a[16], wmsk_a[7:0]} = (ram_waddr_a[3] ? 9'h1ff : 9'h000);
+				end
+				MODE_4: begin
+					aligned_wdata_a = {2'b00, {4 {WDATA_A_i[3:0]}}};
+					wmsk_a[17:16] = 2'b00;
+					wmsk_a[15:12] = (ram_waddr_a[3:2] == 2'b11 ? 4'h0 : 4'hf);
+					wmsk_a[11:8] = (ram_waddr_a[3:2] == 2'b10 ? 4'h0 : 4'hf);
+					wmsk_a[7:4] = (ram_waddr_a[3:2] == 2'b01 ? 4'h0 : 4'hf);
+					wmsk_a[3:0] = (ram_waddr_a[3:2] == 2'b00 ? 4'h0 : 4'hf);
+				end
+				MODE_2: begin
+					aligned_wdata_a = {2'b00, {8 {WDATA_A_i[1:0]}}};
+					wmsk_a[17:16] = 2'b00;
+					wmsk_a[15:14] = (ram_waddr_a[3:1] == 3'b111 ? 2'h0 : 2'h3);
+					wmsk_a[13:12] = (ram_waddr_a[3:1] == 3'b110 ? 2'h0 : 2'h3);
+					wmsk_a[11:10] = (ram_waddr_a[3:1] == 3'b101 ? 2'h0 : 2'h3);
+					wmsk_a[9:8] = (ram_waddr_a[3:1] == 3'b100 ? 2'h0 : 2'h3);
+					wmsk_a[7:6] = (ram_waddr_a[3:1] == 3'b011 ? 2'h0 : 2'h3);
+					wmsk_a[5:4] = (ram_waddr_a[3:1] == 3'b010 ? 2'h0 : 2'h3);
+					wmsk_a[3:2] = (ram_waddr_a[3:1] == 3'b001 ? 2'h0 : 2'h3);
+					wmsk_a[1:0] = (ram_waddr_a[3:1] == 3'b000 ? 2'h0 : 2'h3);
+				end
+				MODE_1: begin
+					aligned_wdata_a = {2'b00, {16 {WDATA_A_i[0]}}};
+					wmsk_a = 18'h0ffff;
+					wmsk_a[{1'b0, ram_waddr_a[3:0]}] = 0;
+				end
+				default: wmsk_a = 18'h3ffff;
+			endcase
+		end
+		else begin
+			aligned_wdata_a = 18'h00000;
+			wmsk_a = 18'h3ffff;
+		end
+		if (ram_wen_b == 1)
+			case (WMODE_B_i)
+				MODE_18: begin
+					aligned_wdata_b = WDATA_B_i;
+					{wmsk_b[17], wmsk_b[15:8]} = (BE_B_i[1] ? 9'h000 : 9'h1ff);
+					{wmsk_b[16], wmsk_b[7:0]} = (BE_B_i[0] ? 9'h000 : 9'h1ff);
+				end
+				MODE_9: begin
+					aligned_wdata_b = {{2 {WDATA_B_i[16]}}, {2 {WDATA_B_i[7:0]}}};
+					{wmsk_b[17], wmsk_b[15:8]} = (ram_waddr_b[3] ? 9'h000 : 9'h1ff);
+					{wmsk_b[16], wmsk_b[7:0]} = (ram_waddr_b[3] ? 9'h1ff : 9'h000);
+				end
+				MODE_4: begin
+					aligned_wdata_b = {2'b00, {4 {WDATA_B_i[3:0]}}};
+					wmsk_b[17:16] = 2'b00;
+					wmsk_b[15:12] = (ram_waddr_b[3:2] == 2'b11 ? 4'h0 : 4'hf);
+					wmsk_b[11:8] = (ram_waddr_b[3:2] == 2'b10 ? 4'h0 : 4'hf);
+					wmsk_b[7:4] = (ram_waddr_b[3:2] == 2'b01 ? 4'h0 : 4'hf);
+					wmsk_b[3:0] = (ram_waddr_b[3:2] == 2'b00 ? 4'h0 : 4'hf);
+				end
+				MODE_2: begin
+					aligned_wdata_b = {2'b00, {8 {WDATA_B_i[1:0]}}};
+					wmsk_b[17:16] = 2'b00;
+					wmsk_b[15:14] = (ram_waddr_b[3:1] == 3'b111 ? 2'h0 : 2'h3);
+					wmsk_b[13:12] = (ram_waddr_b[3:1] == 3'b110 ? 2'h0 : 2'h3);
+					wmsk_b[11:10] = (ram_waddr_b[3:1] == 3'b101 ? 2'h0 : 2'h3);
+					wmsk_b[9:8] = (ram_waddr_b[3:1] == 3'b100 ? 2'h0 : 2'h3);
+					wmsk_b[7:6] = (ram_waddr_b[3:1] == 3'b011 ? 2'h0 : 2'h3);
+					wmsk_b[5:4] = (ram_waddr_b[3:1] == 3'b010 ? 2'h0 : 2'h3);
+					wmsk_b[3:2] = (ram_waddr_b[3:1] == 3'b001 ? 2'h0 : 2'h3);
+					wmsk_b[1:0] = (ram_waddr_b[3:1] == 3'b000 ? 2'h0 : 2'h3);
+				end
+				MODE_1: begin
+					aligned_wdata_b = {2'b00, {16 {WDATA_B_i[0]}}};
+					wmsk_b = 18'h0ffff;
+					wmsk_b[{1'b0, ram_waddr_b[3:0]}] = 0;
+				end
+				default: wmsk_b = 18'h3ffff;
+			endcase
+		else begin
+			aligned_wdata_b = 18'b000000000000000000;
+			wmsk_b = 18'h3ffff;
+		end
+	end
+	always @(*) begin : RDATA_A_MODE_SEL
+		case (RMODE_A_i)
+			default: RDATA_A_o = 18'h00000;
+			MODE_18: RDATA_A_o = ram_rdata_a;
+			MODE_9: begin
+				{RDATA_A_o[17], RDATA_A_o[15:8]} = 9'h000;
+				{RDATA_A_o[16], RDATA_A_o[7:0]} = (ram_addr_a[3] ? {ram_rdata_a[17], ram_rdata_a[15:8]} : {ram_rdata_a[16], ram_rdata_a[7:0]});
+			end
+			MODE_4: begin
+				RDATA_A_o[17:4] = 14'h0000;
+				case (ram_addr_a[3:2])
+					3: RDATA_A_o[3:0] = ram_rdata_a[15:12];
+					2: RDATA_A_o[3:0] = ram_rdata_a[11:8];
+					1: RDATA_A_o[3:0] = ram_rdata_a[7:4];
+					0: RDATA_A_o[3:0] = ram_rdata_a[3:0];
+				endcase
+			end
+			MODE_2: begin
+				RDATA_A_o[17:2] = 16'h0000;
+				case (ram_addr_a[3:1])
+					7: RDATA_A_o[1:0] = ram_rdata_a[15:14];
+					6: RDATA_A_o[1:0] = ram_rdata_a[13:12];
+					5: RDATA_A_o[1:0] = ram_rdata_a[11:10];
+					4: RDATA_A_o[1:0] = ram_rdata_a[9:8];
+					3: RDATA_A_o[1:0] = ram_rdata_a[7:6];
+					2: RDATA_A_o[1:0] = ram_rdata_a[5:4];
+					1: RDATA_A_o[1:0] = ram_rdata_a[3:2];
+					0: RDATA_A_o[1:0] = ram_rdata_a[1:0];
+				endcase
+			end
+			MODE_1: begin
+				RDATA_A_o[17:1] = 17'h00000;
+				RDATA_A_o[0] = ram_rdata_a[ram_addr_a[3:0]];
+			end
+		endcase
+	end
+	always @(*)
+		case (RMODE_B_i)
+			default: RDATA_B_o = 18'h15566;
+			MODE_18: RDATA_B_o = ram_rdata_b;
+			MODE_9: begin
+				{RDATA_B_o[17], RDATA_B_o[15:8]} = 9'b000000000;
+				{RDATA_B_o[16], RDATA_B_o[7:0]} = (ram_addr_b[3] ? {ram_rdata_b[17], ram_rdata_b[15:8]} : {ram_rdata_b[16], ram_rdata_b[7:0]});
+			end
+			MODE_4:
+				case (ram_addr_b[3:2])
+					3: RDATA_B_o[3:0] = ram_rdata_b[15:12];
+					2: RDATA_B_o[3:0] = ram_rdata_b[11:8];
+					1: RDATA_B_o[3:0] = ram_rdata_b[7:4];
+					0: RDATA_B_o[3:0] = ram_rdata_b[3:0];
+				endcase
+			MODE_2:
+				case (ram_addr_b[3:1])
+					7: RDATA_B_o[1:0] = ram_rdata_b[15:14];
+					6: RDATA_B_o[1:0] = ram_rdata_b[13:12];
+					5: RDATA_B_o[1:0] = ram_rdata_b[11:10];
+					4: RDATA_B_o[1:0] = ram_rdata_b[9:8];
+					3: RDATA_B_o[1:0] = ram_rdata_b[7:6];
+					2: RDATA_B_o[1:0] = ram_rdata_b[5:4];
+					1: RDATA_B_o[1:0] = ram_rdata_b[3:2];
+					0: RDATA_B_o[1:0] = ram_rdata_b[1:0];
+				endcase
+			MODE_1: RDATA_B_o[0] = ram_rdata_b[{1'b0, ram_addr_b[3:0]}];
+		endcase
+endmodule
+`default_nettype none
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/arith_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/arith_map.v
new file mode 100644
index 000000000..908b17189
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/arith_map.v
@@ -0,0 +1,99 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+(* techmap_celltype = "$alu" *)
+module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 2;
+	parameter B_WIDTH = 2;
+	parameter Y_WIDTH = 2;
+	parameter _TECHMAP_CONSTVAL_CI_ = 0;
+	parameter _TECHMAP_CONSTMSK_CI_ = 0;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] X, Y;
+
+	input CI, BI;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] CO;
+
+
+	wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+
+	genvar i;
+	wire co;
+
+	(* force_downto *)
+	//wire [Y_WIDTH-1:0] C = {CO, CI};
+	wire [Y_WIDTH:0] C;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] S  = {AA ^ BB};
+	assign CO[Y_WIDTH-1:0] = C[Y_WIDTH:1];
+        //assign CO[Y_WIDTH-1] = co;
+
+	generate
+	     adder_carry intermediate_adder (
+	       .cin     ( ),
+	       .cout    (C[0]),
+	       .p       (1'b0),
+	       .g       (CI),
+	       .sumout    ()
+	     );
+	endgenerate
+	genvar i;
+	generate if (Y_WIDTH > 2) begin
+	  for (i = 0; i < Y_WIDTH-2; i = i + 1) begin:slice
+		adder_carry  my_adder (
+			.cin(C[i]),
+			.g(AA[i]),
+			.p(S[i]),
+			.cout(C[i+1]),
+		        .sumout(Y[i])
+		);
+	      end
+	end endgenerate
+	generate
+	     adder_carry final_adder (
+	       .cin     (C[Y_WIDTH-2]),
+	       .cout    (),
+	       .p       (1'b0),
+	       .g       (1'b0),
+	       .sumout    (co)
+	     );
+	endgenerate
+
+	assign Y[Y_WIDTH-2] = S[Y_WIDTH-2] ^ co;
+        assign C[Y_WIDTH-1] = S[Y_WIDTH-2] ? co : AA[Y_WIDTH-2];
+	assign Y[Y_WIDTH-1] = S[Y_WIDTH-1] ^ C[Y_WIDTH-1];
+        assign C[Y_WIDTH] = S[Y_WIDTH-1] ? C[Y_WIDTH-1] : AA[Y_WIDTH-1];
+
+	assign X = S;
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/brams.txt b/yosys-plugins/ql-qlf/qlf_k6n10f/brams.txt
new file mode 100644
index 000000000..3b6eb07a2
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/brams.txt
@@ -0,0 +1,158 @@
+bram $__QLF_FACTOR_BRAM36_TDP
+  init 1
+  abits 10     @a10d36
+  dbits 36     @a10d36
+  abits 10     @a10d32
+  dbits 32     @a10d32
+  abits 11     @a11d18
+  dbits 18     @a11d18
+  abits 11     @a11d16
+  dbits 16     @a11d16
+  abits 12     @a12d9
+  dbits  9     @a12d9
+  abits 12     @a12d8
+  dbits  8     @a12d8
+  abits 13     @a13d4
+  dbits  4     @a13d4
+  abits 14     @a14d2
+  dbits  2     @a14d2
+  abits 15     @a15d1
+  dbits  1     @a15d1
+  groups 4
+  ports  1 1 1 1
+  wrmode 0 1 0 1
+  enable 1 4 1 4 @a10d36 @a10d32
+  enable 1 2 1 2 @a11d18 @a11d16
+  enable 1 1 1 1 @a12d9 @a12d8 @a13d4 @a14d2 @a15d1
+  transp 0 0 0 0
+  clocks 1 1 2 2
+  clkpol 1 1 1 1
+endbram
+
+bram $__QLF_FACTOR_BRAM36_SDP
+  init 1
+  abits 10     @a10d36
+  dbits 36     @a10d36
+  abits 10     @a10d32
+  dbits 32     @a10d32
+  abits 11     @a11d18
+  dbits 18     @a11d18
+  abits 11     @a11d16
+  dbits 16     @a11d16
+  abits 12     @a12d9
+  dbits  9     @a12d9
+  abits 12     @a12d8
+  dbits  8     @a12d8
+  abits 13     @a13d4
+  dbits  4     @a13d4
+  abits 14     @a14d2
+  dbits  2     @a14d2
+  abits 15     @a15d1
+  dbits  1     @a15d1
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 4   @a10d36 @a10d32
+  enable 1 2   @a11d18 @a11d16
+  enable 1 1   @a12d9 @a12d8 @a13d4 @a14d2 @a15d1
+  transp 0 0
+  clocks 2 3
+  clkpol 2 3
+endbram
+
+bram $__QLF_FACTOR_BRAM18_TDP
+  init 1
+  abits 10     @a10d18
+  dbits 18     @a10d18
+  abits 10     @a10d16
+  dbits 16     @a10d16
+  abits 11     @a11d9
+  dbits  9     @a11d9
+  abits 11     @a11d8
+  dbits  8     @a11d8
+  abits 12     @a12d4
+  dbits  4     @a12d4
+  abits 13     @a13d2
+  dbits  2     @a13d2
+  abits 14     @a14d1
+  dbits  1     @a14d1
+  groups 4
+  ports  1 1 1 1
+  wrmode 0 1 0 1
+  enable 1 2 1 2  @a10d18 @a10d16
+  enable 1 1 1 1  @a11d9 @a11d8 @a12d4 @a13d2 @a14d1
+  transp 0 0 0 0
+  clocks 1 1 2 2
+  clkpol 1 1 2 2
+endbram
+
+bram $__QLF_FACTOR_BRAM18_SDP
+  init 1
+  abits 10     @a10d18
+  dbits 18     @a10d18
+  abits 10     @a10d16
+  dbits 16     @a10d16
+  abits 11     @a11d9
+  dbits  9     @a11d9
+  abits 11     @a11d8
+  dbits  8     @a11d8
+  abits 12     @a12d4
+  dbits  4     @a12d4
+  abits 13     @a13d2
+  dbits  2     @a13d2
+  abits 14     @a14d1
+  dbits  1     @a14d1
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 2  @a10d18 @a10d16
+  enable 1 1  @a11d9 @a11d8 @a12d4 @a13d2 @a14d1
+  transp 0 0
+  clocks 1 1
+  clkpol 1 1
+endbram
+
+match $__QLF_FACTOR_BRAM36_TDP
+  min bits 18433
+  min wports 1
+  max wports 2
+  min rports 1
+  max rports 2
+  min efficiency 1
+  shuffle_enable B
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_FACTOR_BRAM36_SDP
+  min bits 18433
+  max wports 1
+  max rports 1
+  min efficiency 1
+  shuffle_enable B
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_FACTOR_BRAM18_TDP
+  min bits 128
+  max bits 18432
+  min wports 1
+  max wports 2
+  min rports 1
+  max rports 2
+  min efficiency 1
+  shuffle_enable B
+  make_transp
+  or_next_if_better
+endmatch
+
+match $__QLF_FACTOR_BRAM18_SDP
+  min bits 128
+  max bits 18432
+  max wports 1
+  max rports 1
+  min efficiency 1
+  shuffle_enable B
+  make_transp
+endmatch
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/brams_final_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/brams_final_map.v
new file mode 100644
index 000000000..aa4bb5d86
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/brams_final_map.v
@@ -0,0 +1,482 @@
+// Copyright (C) 2020-2021  The SymbiFlow Authors.
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier:ISC
+
+`define MODE_36 3'b011	// 36 or 32-bit
+`define MODE_18 3'b010	// 18 or 16-bit
+`define MODE_9  3'b001	// 9 or 8-bit
+`define MODE_4  3'b100	// 4-bit
+`define MODE_2  3'b110	// 32-bit
+`define MODE_1  3'b101	// 32-bit
+
+module BRAM2x18_TDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, CLK3, CLK4, D1ADDR, D1DATA, D1EN, E1ADDR, E1DATA, E1EN, F1ADDR, F1DATA, F1EN, G1ADDR, G1DATA, G1EN, H1ADDR, H1DATA, H1EN);
+	parameter CFG_ABITS = 11;
+	parameter CFG_DBITS = 18;
+	parameter CFG_ENABLE_B = 4;
+	parameter CFG_ENABLE_D = 4;
+	parameter CFG_ENABLE_F = 4;
+	parameter CFG_ENABLE_H = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [18431:0] INIT0 = 18432'bx;
+	parameter [18431:0] INIT1 = 18432'bx;
+
+	input CLK1;
+	input CLK2;
+	input CLK3;
+	input CLK4;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	input [CFG_ABITS-1:0] C1ADDR;
+	output [CFG_DBITS-1:0] C1DATA;
+	input C1EN;
+
+	input [CFG_ABITS-1:0] D1ADDR;
+	input [CFG_DBITS-1:0] D1DATA;
+	input [CFG_ENABLE_D-1:0] D1EN;
+
+	input [CFG_ABITS-1:0] E1ADDR;
+	output [CFG_DBITS-1:0] E1DATA;
+	input E1EN;
+
+	input [CFG_ABITS-1:0] F1ADDR;
+	input [CFG_DBITS-1:0] F1DATA;
+	input [CFG_ENABLE_F-1:0] F1EN;
+
+	input [CFG_ABITS-1:0] G1ADDR;
+	output [CFG_DBITS-1:0] G1DATA;
+	input G1EN;
+
+	input [CFG_ABITS-1:0] H1ADDR;
+	input [CFG_DBITS-1:0] H1DATA;
+	input [CFG_ENABLE_H-1:0] H1EN;
+
+	wire FLUSH1;
+	wire FLUSH2;
+
+	wire [13:CFG_ABITS] A1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] B1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] C1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] D1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] E1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] F1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] G1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] H1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+
+	wire [13:0] A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+	wire [13:0] B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+	wire [13:0] C1ADDR_TOTAL = {C1ADDR_CMPL, C1ADDR};
+	wire [13:0] D1ADDR_TOTAL = {D1ADDR_CMPL, D1ADDR};
+	wire [13:0] E1ADDR_TOTAL = {E1ADDR_CMPL, E1ADDR};
+	wire [13:0] F1ADDR_TOTAL = {F1ADDR_CMPL, F1ADDR};
+	wire [13:0] G1ADDR_TOTAL = {G1ADDR_CMPL, G1ADDR};
+	wire [13:0] H1ADDR_TOTAL = {H1ADDR_CMPL, H1ADDR};
+
+	wire [17:CFG_DBITS] A1_RDATA_CMPL;
+	wire [17:CFG_DBITS] C1_RDATA_CMPL;
+	wire [17:CFG_DBITS] E1_RDATA_CMPL;
+	wire [17:CFG_DBITS] G1_RDATA_CMPL;
+
+	wire [17:CFG_DBITS] B1_WDATA_CMPL;
+	wire [17:CFG_DBITS] D1_WDATA_CMPL;
+	wire [17:CFG_DBITS] F1_WDATA_CMPL;
+	wire [17:CFG_DBITS] H1_WDATA_CMPL;
+
+	wire [13:0] PORT_A1_ADDR;
+	wire [13:0] PORT_A2_ADDR;
+	wire [13:0] PORT_B1_ADDR;
+	wire [13:0] PORT_B2_ADDR;
+
+	case (CFG_DBITS)
+		1: begin
+			assign PORT_A1_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? E1ADDR_TOTAL : (F1EN ? F1ADDR_TOTAL : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? G1ADDR_TOTAL : (H1EN ? H1ADDR_TOTAL : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+			};
+		end
+
+		2: begin
+			assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 1) : (B1EN ? (B1ADDR_TOTAL << 1) : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 1) : (D1EN ? (D1ADDR_TOTAL << 1) : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 1) : (F1EN ? (F1ADDR_TOTAL << 1) : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 1) : (H1EN ? (H1ADDR_TOTAL << 1) : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0
+			};
+		end
+
+		4: begin
+			assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 2) : (B1EN ? (B1ADDR_TOTAL << 2) : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 2) : (D1EN ? (D1ADDR_TOTAL << 2) : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 2) : (F1EN ? (F1ADDR_TOTAL << 2) : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 2) : (H1EN ? (H1ADDR_TOTAL << 2) : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0
+			};
+		end
+
+		8, 9: begin
+			assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 3) : (B1EN ? (B1ADDR_TOTAL << 3) : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 3) : (D1EN ? (D1ADDR_TOTAL << 3) : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 3) : (F1EN ? (F1ADDR_TOTAL << 3) : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 3) : (H1EN ? (H1ADDR_TOTAL << 3) : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0
+			};
+		end
+
+		16, 18: begin
+			assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 4) : (B1EN ? (B1ADDR_TOTAL << 4) : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 4) : (D1EN ? (D1ADDR_TOTAL << 4) : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 4) : (F1EN ? (F1ADDR_TOTAL << 4) : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 4) : (H1EN ? (H1ADDR_TOTAL << 4) : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0
+			};
+		end
+
+		default: begin
+			assign PORT_A1_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 14'd0);
+			assign PORT_B1_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 14'd0);
+			assign PORT_A2_ADDR = E1EN ? E1ADDR_TOTAL : (F1EN ? F1ADDR_TOTAL : 14'd0);
+			assign PORT_B2_ADDR = G1EN ? G1ADDR_TOTAL : (H1EN ? H1ADDR_TOTAL : 14'd0);
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+			};
+		end
+	endcase
+
+	assign FLUSH1 = 1'b0;
+	assign FLUSH2 = 1'b0;
+
+	wire [17:0] PORT_A1_RDATA;
+	wire [17:0] PORT_B1_RDATA;
+	wire [17:0] PORT_A2_RDATA;
+	wire [17:0] PORT_B2_RDATA;
+
+	wire [17:0] PORT_A1_WDATA;
+	wire [17:0] PORT_B1_WDATA;
+	wire [17:0] PORT_A2_WDATA;
+	wire [17:0] PORT_B2_WDATA;
+
+	// Assign read/write data - handle special case for 9bit mode
+	// parity bit for 9bit mode is placed in R/W port on bit #16
+	case (CFG_DBITS)
+		9: begin
+			assign A1DATA = {PORT_A1_RDATA[16], PORT_A1_RDATA[7:0]};
+			assign C1DATA = {PORT_B1_RDATA[16], PORT_B1_RDATA[7:0]};
+			assign E1DATA = {PORT_A2_RDATA[16], PORT_A2_RDATA[7:0]};
+			assign G1DATA = {PORT_B2_RDATA[16], PORT_B2_RDATA[7:0]};
+			assign PORT_A1_WDATA = {B1_WDATA_CMPL[17], B1DATA[8], B1_WDATA_CMPL[16:9], B1DATA[7:0]};
+			assign PORT_B1_WDATA = {D1_WDATA_CMPL[17], D1DATA[8], D1_WDATA_CMPL[16:9], D1DATA[7:0]};
+			assign PORT_A2_WDATA = {F1_WDATA_CMPL[17], F1DATA[8], F1_WDATA_CMPL[16:9], F1DATA[7:0]};
+			assign PORT_B2_WDATA = {H1_WDATA_CMPL[17], H1DATA[8], H1_WDATA_CMPL[16:9], H1DATA[7:0]};
+		end
+		default: begin
+			assign A1DATA = PORT_A1_RDATA[CFG_DBITS-1:0];
+			assign C1DATA = PORT_B1_RDATA[CFG_DBITS-1:0];
+			assign E1DATA = PORT_A2_RDATA[CFG_DBITS-1:0];
+			assign G1DATA = PORT_B2_RDATA[CFG_DBITS-1:0];
+			assign PORT_A1_WDATA = {B1_WDATA_CMPL, B1DATA};
+			assign PORT_B1_WDATA = {D1_WDATA_CMPL, D1DATA};
+			assign PORT_A2_WDATA = {F1_WDATA_CMPL, F1DATA};
+			assign PORT_B2_WDATA = {H1_WDATA_CMPL, H1DATA};
+
+		end
+	endcase
+
+	wire PORT_A1_CLK = CLK1;
+	wire PORT_A2_CLK = CLK3;
+	wire PORT_B1_CLK = CLK2;
+	wire PORT_B2_CLK = CLK4;
+
+	wire PORT_A1_REN = A1EN;
+	wire PORT_A1_WEN = B1EN[0];
+	wire [CFG_ENABLE_B-1:0] PORT_A1_BE = {B1EN[1],B1EN[0]};
+
+	wire PORT_A2_REN = E1EN;
+	wire PORT_A2_WEN = F1EN[0];
+	wire [CFG_ENABLE_F-1:0] PORT_A2_BE = {F1EN[1],F1EN[0]};
+
+	wire PORT_B1_REN = C1EN;
+	wire PORT_B1_WEN = D1EN[0];
+	wire [CFG_ENABLE_D-1:0] PORT_B1_BE = {D1EN[1],D1EN[0]};
+
+	wire PORT_B2_REN = G1EN;
+	wire PORT_B2_WEN = H1EN[0];
+	wire [CFG_ENABLE_H-1:0] PORT_B2_BE = {H1EN[1],H1EN[0]};
+
+	TDP36K  _TECHMAP_REPLACE_ (
+		.WDATA_A1_i(PORT_A1_WDATA),
+		.RDATA_A1_o(PORT_A1_RDATA),
+		.ADDR_A1_i(PORT_A1_ADDR),
+		.CLK_A1_i(PORT_A1_CLK),
+		.REN_A1_i(PORT_A1_REN),
+		.WEN_A1_i(PORT_A1_WEN),
+		.BE_A1_i(PORT_A1_BE),
+
+		.WDATA_A2_i(PORT_A2_WDATA),
+		.RDATA_A2_o(PORT_A2_RDATA),
+		.ADDR_A2_i(PORT_A2_ADDR),
+		.CLK_A2_i(PORT_A2_CLK),
+		.REN_A2_i(PORT_A2_REN),
+		.WEN_A2_i(PORT_A2_WEN),
+		.BE_A2_i(PORT_A2_BE),
+
+		.WDATA_B1_i(PORT_B1_WDATA),
+		.RDATA_B1_o(PORT_B1_RDATA),
+		.ADDR_B1_i(PORT_B1_ADDR),
+		.CLK_B1_i(PORT_B1_CLK),
+		.REN_B1_i(PORT_B1_REN),
+		.WEN_B1_i(PORT_B1_WEN),
+		.BE_B1_i(PORT_B1_BE),
+
+		.WDATA_B2_i(PORT_B2_WDATA),
+		.RDATA_B2_o(PORT_B2_RDATA),
+		.ADDR_B2_i(PORT_B2_ADDR),
+		.CLK_B2_i(PORT_B2_CLK),
+		.REN_B2_i(PORT_B2_REN),
+		.WEN_B2_i(PORT_B2_WEN),
+		.BE_B2_i(PORT_B2_BE),
+
+		.FLUSH1_i(FLUSH1),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
+
+module BRAM2x18_SDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, D1ADDR, D1DATA, D1EN);
+	parameter CFG_ABITS = 11;
+	parameter CFG_DBITS = 18;
+	parameter CFG_ENABLE_B = 4;
+	parameter CFG_ENABLE_D = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [18431:0] INIT0 = 18432'bx;
+	parameter [18431:0] INIT1 = 18432'bx;
+
+	input CLK1;
+	input CLK2;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	input [CFG_ABITS-1:0] C1ADDR;
+	output [CFG_DBITS-1:0] C1DATA;
+	input C1EN;
+
+	input [CFG_ABITS-1:0] D1ADDR;
+	input [CFG_DBITS-1:0] D1DATA;
+	input [CFG_ENABLE_D-1:0] D1EN;
+
+	wire FLUSH1;
+	wire FLUSH2;
+
+	wire [13:CFG_ABITS] A1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] B1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] C1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+	wire [13:CFG_ABITS] D1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+
+	wire [13:0] A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+	wire [13:0] B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+	wire [13:0] C1ADDR_TOTAL = {C1ADDR_CMPL, C1ADDR};
+	wire [13:0] D1ADDR_TOTAL = {D1ADDR_CMPL, D1ADDR};
+
+	wire [17:CFG_DBITS] A1_RDATA_CMPL;
+	wire [17:CFG_DBITS] C1_RDATA_CMPL;
+
+	wire [17:CFG_DBITS] B1_WDATA_CMPL;
+	wire [17:CFG_DBITS] D1_WDATA_CMPL;
+
+	wire [13:0] PORT_A1_ADDR;
+	wire [13:0] PORT_A2_ADDR;
+	wire [13:0] PORT_B1_ADDR;
+	wire [13:0] PORT_B2_ADDR;
+
+	case (CFG_DBITS)
+		1: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL;
+			assign PORT_A2_ADDR = C1ADDR_TOTAL;
+			assign PORT_B2_ADDR = D1ADDR_TOTAL;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+			};
+		end
+
+		2: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL << 1;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL << 1;
+			assign PORT_A2_ADDR = C1ADDR_TOTAL << 1;
+			assign PORT_B2_ADDR = D1ADDR_TOTAL << 1;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0
+			};
+		end
+
+		4: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL << 2;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL << 2;
+			assign PORT_A2_ADDR = C1ADDR_TOTAL << 2;
+			assign PORT_B2_ADDR = D1ADDR_TOTAL << 2;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0
+			};
+		end
+
+		8, 9: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL << 3;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL << 3;
+			assign PORT_A2_ADDR = C1ADDR_TOTAL << 3;
+			assign PORT_B2_ADDR = D1ADDR_TOTAL << 3;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0
+			};
+		end
+
+		16, 18: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL << 4;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL << 4;
+			assign PORT_A2_ADDR = C1ADDR_TOTAL << 4;
+			assign PORT_B2_ADDR = D1ADDR_TOTAL << 4;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0
+			};
+		end
+
+		default: begin
+			assign PORT_A1_ADDR = A1ADDR_TOTAL;
+			assign PORT_B1_ADDR = B1ADDR_TOTAL;
+			assign PORT_A2_ADDR = D1ADDR_TOTAL;
+			assign PORT_B2_ADDR = C1ADDR_TOTAL;
+			defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b1,
+				11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+				12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+			};
+		end
+	endcase
+
+	assign FLUSH1 = 1'b0;
+	assign FLUSH2 = 1'b0;
+
+	wire [17:0] PORT_A1_RDATA;
+	wire [17:0] PORT_B1_RDATA;
+	wire [17:0] PORT_A2_RDATA;
+	wire [17:0] PORT_B2_RDATA;
+
+	wire [17:0] PORT_A1_WDATA;
+	wire [17:0] PORT_B1_WDATA;
+	wire [17:0] PORT_A2_WDATA;
+	wire [17:0] PORT_B2_WDATA;
+
+	// Assign read/write data - handle special case for 9bit mode
+	// parity bit for 9bit mode is placed in R/W port on bit #16
+	case (CFG_DBITS)
+		9: begin
+			assign A1DATA = {PORT_A1_RDATA[16], PORT_A1_RDATA[7:0]};
+			assign C1DATA = {PORT_A2_RDATA[16], PORT_A2_RDATA[7:0]};
+			assign PORT_A1_WDATA = {18{1'b0}};
+			assign PORT_B1_WDATA = {B1_WDATA_CMPL[17], B1DATA[8], B1_WDATA_CMPL[16:9], B1DATA[7:0]};
+			assign PORT_A2_WDATA = {18{1'b0}};
+			assign PORT_B2_WDATA = {D1_WDATA_CMPL[17], D1DATA[8], D1_WDATA_CMPL[16:9], D1DATA[7:0]};
+		end
+		default: begin
+			assign A1DATA = PORT_A1_RDATA[CFG_DBITS-1:0];
+			assign C1DATA = PORT_A2_RDATA[CFG_DBITS-1:0];
+			assign PORT_A1_WDATA = {18{1'b1}};
+			assign PORT_B1_WDATA = {B1_WDATA_CMPL, B1DATA};
+			assign PORT_A2_WDATA = {18{1'b1}};
+			assign PORT_B2_WDATA = {D1_WDATA_CMPL, D1DATA};
+
+		end
+	endcase
+
+	wire PORT_A1_CLK = CLK1;
+	wire PORT_A2_CLK = CLK2;
+	wire PORT_B1_CLK = CLK1;
+	wire PORT_B2_CLK = CLK2;
+
+	wire PORT_A1_REN = A1EN;
+	wire PORT_A1_WEN = 1'b0;
+	wire [CFG_ENABLE_B-1:0] PORT_A1_BE = {PORT_A1_WEN,PORT_A1_WEN};
+
+	wire PORT_A2_REN = C1EN;
+	wire PORT_A2_WEN = 1'b0;
+	wire [CFG_ENABLE_D-1:0] PORT_A2_BE = {PORT_A2_WEN,PORT_A2_WEN};
+
+	wire PORT_B1_REN = 1'b0;
+	wire PORT_B1_WEN = B1EN[0];
+	wire [CFG_ENABLE_B-1:0] PORT_B1_BE = {B1EN[1],B1EN[0]};
+
+	wire PORT_B2_REN = 1'b0;
+	wire PORT_B2_WEN = D1EN[0];
+	wire [CFG_ENABLE_D-1:0] PORT_B2_BE = {D1EN[1],D1EN[0]};
+
+	TDP36K  _TECHMAP_REPLACE_ (
+		.WDATA_A1_i(PORT_A1_WDATA),
+		.RDATA_A1_o(PORT_A1_RDATA),
+		.ADDR_A1_i(PORT_A1_ADDR),
+		.CLK_A1_i(PORT_A1_CLK),
+		.REN_A1_i(PORT_A1_REN),
+		.WEN_A1_i(PORT_A1_WEN),
+		.BE_A1_i(PORT_A1_BE),
+
+		.WDATA_A2_i(PORT_A2_WDATA),
+		.RDATA_A2_o(PORT_A2_RDATA),
+		.ADDR_A2_i(PORT_A2_ADDR),
+		.CLK_A2_i(PORT_A2_CLK),
+		.REN_A2_i(PORT_A2_REN),
+		.WEN_A2_i(PORT_A2_WEN),
+		.BE_A2_i(PORT_A2_BE),
+
+		.WDATA_B1_i(PORT_B1_WDATA),
+		.RDATA_B1_o(PORT_B1_RDATA),
+		.ADDR_B1_i(PORT_B1_ADDR),
+		.CLK_B1_i(PORT_B1_CLK),
+		.REN_B1_i(PORT_B1_REN),
+		.WEN_B1_i(PORT_B1_WEN),
+		.BE_B1_i(PORT_B1_BE),
+
+		.WDATA_B2_i(PORT_B2_WDATA),
+		.RDATA_B2_o(PORT_B2_RDATA),
+		.ADDR_B2_i(PORT_B2_ADDR),
+		.CLK_B2_i(PORT_B2_CLK),
+		.REN_B2_i(PORT_B2_REN),
+		.WEN_B2_i(PORT_B2_WEN),
+		.BE_B2_i(PORT_B2_BE),
+
+		.FLUSH1_i(FLUSH1),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/brams_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/brams_map.v
new file mode 100644
index 000000000..873a5d7e9
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/brams_map.v
@@ -0,0 +1,1010 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`define MODE_36 3'b011	// 36 or 32-bit
+`define MODE_18 3'b010	// 18 or 16-bit
+`define MODE_9  3'b001	// 9 or 8-bit
+`define MODE_4  3'b100	// 4-bit
+`define MODE_2  3'b110	// 32-bit
+`define MODE_1  3'b101	// 32-bit
+
+module \$__QLF_FACTOR_BRAM36_TDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, D1ADDR, D1DATA, D1EN);
+	parameter CFG_ABITS = 10;
+	parameter CFG_DBITS = 36;
+	parameter CFG_ENABLE_B = 4;
+	parameter CFG_ENABLE_D = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [36863:0] INIT = 36864'bx;
+
+	input CLK1;
+	input CLK2;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	input [CFG_ABITS-1:0] C1ADDR;
+	output [CFG_DBITS-1:0] C1DATA;
+	input C1EN;
+
+	input [CFG_ABITS-1:0] D1ADDR;
+	input [CFG_DBITS-1:0] D1DATA;
+	input [CFG_ENABLE_B-1:0] D1EN;
+
+	wire FLUSH1;
+	wire FLUSH2;
+	wire SPLIT;
+
+	wire [14:CFG_ABITS] A1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+	wire [14:CFG_ABITS] B1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+	wire [14:CFG_ABITS] C1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+	wire [14:CFG_ABITS] D1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+
+	wire [14:0] A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+	wire [14:0] B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+	wire [14:0] C1ADDR_TOTAL = {C1ADDR_CMPL, C1ADDR};
+	wire [14:0] D1ADDR_TOTAL = {D1ADDR_CMPL, D1ADDR};
+
+	wire [35:CFG_DBITS] A1DATA_CMPL;
+	wire [35:CFG_DBITS] B1DATA_CMPL;
+	wire [35:CFG_DBITS] C1DATA_CMPL;
+	wire [35:CFG_DBITS] D1DATA_CMPL;
+
+	wire [35:0] A1DATA_TOTAL;
+	wire [35:0] B1DATA_TOTAL;
+	wire [35:0] C1DATA_TOTAL;
+	wire [35:0] D1DATA_TOTAL;
+
+	wire [14:0] PORT_A_ADDR;
+	wire [14:0] PORT_B_ADDR;
+
+	// Assign read/write data - handle special case for 9bit mode
+	// parity bit for 9bit mode is placed in R/W port on bit #16
+	case (CFG_DBITS)
+		9: begin
+			assign A1DATA = {A1DATA_TOTAL[16], A1DATA_TOTAL[7:0]};
+			assign C1DATA = {C1DATA_TOTAL[16], C1DATA_TOTAL[7:0]};
+			assign B1DATA_TOTAL = {B1DATA_CMPL[35:17], B1DATA[8], B1DATA_CMPL[16:9], B1DATA[7:0]};
+			assign D1DATA_TOTAL = {D1DATA_CMPL[35:17], D1DATA[8], D1DATA_CMPL[16:9], D1DATA[7:0]};
+		end
+		default: begin
+			assign A1DATA = A1DATA_TOTAL[CFG_DBITS-1:0];
+			assign C1DATA = C1DATA_TOTAL[CFG_DBITS-1:0];
+			assign B1DATA_TOTAL = {B1DATA_CMPL, B1DATA};
+			assign D1DATA_TOTAL = {D1DATA_CMPL, D1DATA};
+		end
+	endcase
+
+	case (CFG_DBITS)
+		1: begin
+			assign PORT_A_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 15'd0);
+			assign PORT_B_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+            };
+		end
+
+		2: begin
+			assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 1) : (B1EN ? (B1ADDR_TOTAL << 1) : 15'd0);
+			assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 1) : (D1EN ? (D1ADDR_TOTAL << 1) : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0
+            };
+		end
+
+		4: begin
+			assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 2) : (B1EN ? (B1ADDR_TOTAL << 2) : 15'd0);
+			assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 2) : (D1EN ? (D1ADDR_TOTAL << 2) : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0
+            };
+		end
+
+		8, 9: begin
+			assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 3) : (B1EN ? (B1ADDR_TOTAL << 3) : 15'd0);
+			assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 3) : (D1EN ? (D1ADDR_TOTAL << 3) : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0
+            };
+		end
+
+		16, 18: begin
+			assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 4) : (B1EN ? (B1ADDR_TOTAL << 4) : 15'd0);
+			assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 4) : (D1EN ? (D1ADDR_TOTAL << 4) : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0
+            };
+		end
+
+		32, 36: begin
+			assign PORT_A_ADDR = A1EN ? (A1ADDR_TOTAL << 5) : (B1EN ? (B1ADDR_TOTAL << 5) : 15'd0);
+			assign PORT_B_ADDR = C1EN ? (C1ADDR_TOTAL << 5) : (D1EN ? (D1ADDR_TOTAL << 5) : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+            };
+		end
+		default: begin
+			assign PORT_A_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 15'd0);
+			assign PORT_B_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 15'd0);
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+            };
+		end
+	endcase
+
+
+	assign SPLIT = 1'b0;
+	assign FLUSH1 = 1'b0;
+	assign FLUSH2 = 1'b0;
+
+	TDP36K _TECHMAP_REPLACE_ (
+		.RESET_ni(1'b1),
+		.WDATA_A1_i(B1DATA_TOTAL[17:0]),
+		.WDATA_A2_i(B1DATA_TOTAL[35:18]),
+		.RDATA_A1_o(A1DATA_TOTAL[17:0]),
+		.RDATA_A2_o(A1DATA_TOTAL[35:18]),
+		.ADDR_A1_i(PORT_A_ADDR),
+		.ADDR_A2_i(PORT_A_ADDR),
+		.CLK_A1_i(CLK1),
+		.CLK_A2_i(CLK1),
+		.REN_A1_i(A1EN),
+		.REN_A2_i(A1EN),
+		.WEN_A1_i(B1EN[0]),
+		.WEN_A2_i(B1EN[0]),
+		.BE_A1_i({B1EN[1],B1EN[0]}),
+		.BE_A2_i({B1EN[3],B1EN[2]}),
+
+		.WDATA_B1_i(D1DATA_TOTAL[17:0]),
+		.WDATA_B2_i(D1DATA_TOTAL[35:18]),
+		.RDATA_B1_o(C1DATA_TOTAL[17:0]),
+		.RDATA_B2_o(C1DATA_TOTAL[35:18]),
+		.ADDR_B1_i(PORT_B_ADDR),
+		.ADDR_B2_i(PORT_B_ADDR),
+		.CLK_B1_i(CLK2),
+		.CLK_B2_i(CLK2),
+		.REN_B1_i(C1EN),
+		.REN_B2_i(C1EN),
+		.WEN_B1_i(D1EN[0]),
+		.WEN_B2_i(D1EN[0]),
+		.BE_B1_i({D1EN[1],D1EN[0]}),
+		.BE_B2_i({D1EN[3],D1EN[2]}),
+
+		.FLUSH1_i(FLUSH1),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
+
+// ------------------------------------------------------------------------
+
+module \$__QLF_FACTOR_BRAM18_TDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, CLK3, CLK4, D1ADDR, D1DATA, D1EN);
+	parameter CFG_ABITS = 11;
+	parameter CFG_DBITS = 18;
+	parameter CFG_ENABLE_B = 4;
+	parameter CFG_ENABLE_D = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [18431:0] INIT = 18432'bx;
+
+	input CLK1;
+	input CLK2;
+	input CLK3;
+	input CLK4;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	input [CFG_ABITS-1:0] C1ADDR;
+	output [CFG_DBITS-1:0] C1DATA;
+	input C1EN;
+
+	input [CFG_ABITS-1:0] D1ADDR;
+	input [CFG_DBITS-1:0] D1DATA;
+	input [CFG_ENABLE_D-1:0] D1EN;
+
+	BRAM2x18_TDP #(
+		.CFG_ABITS(CFG_ABITS),
+		.CFG_DBITS(CFG_DBITS),
+		.CFG_ENABLE_B(CFG_ENABLE_B),
+		.CFG_ENABLE_D(CFG_ENABLE_D),
+		.CLKPOL2(CLKPOL2),
+		.CLKPOL3(CLKPOL3),
+		.INIT0(INIT),
+	) _TECHMAP_REPLACE_ (
+		.A1ADDR(A1ADDR),
+		.A1DATA(A1DATA),
+		.A1EN(A1EN),
+		.B1ADDR(B1ADDR),
+		.B1DATA(B1DATA),
+		.B1EN(B1EN),
+		.CLK1(CLK1),
+
+		.C1ADDR(C1ADDR),
+		.C1DATA(C1DATA),
+		.C1EN(C1EN),
+		.D1ADDR(D1ADDR),
+		.D1DATA(D1DATA),
+		.D1EN(D1EN),
+		.CLK2(CLK2),
+
+		.E1ADDR(),
+		.E1DATA(),
+		.E1EN(),
+		.F1ADDR(),
+		.F1DATA(),
+		.F1EN(),
+		.CLK3(),
+
+		.G1ADDR(),
+		.G1DATA(),
+		.G1EN(),
+		.H1ADDR(),
+		.H1DATA(),
+		.H1EN(),
+		.CLK4()
+	);
+endmodule
+
+module \$__QLF_FACTOR_BRAM18_SDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, CLK1, CLK2);
+	parameter CFG_ABITS = 11;
+	parameter CFG_DBITS = 18;
+	parameter CFG_ENABLE_B = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [18431:0] INIT = 18432'bx;
+
+	input CLK1;
+	input CLK2;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	BRAM2x18_SDP #(
+		.CFG_ABITS(CFG_ABITS),
+		.CFG_DBITS(CFG_DBITS),
+		.CFG_ENABLE_B(CFG_ENABLE_B),
+		.CLKPOL2(CLKPOL2),
+		.CLKPOL3(CLKPOL3),
+		.INIT0(INIT),
+	) _TECHMAP_REPLACE_ (
+		.A1ADDR(A1ADDR),
+		.A1DATA(A1DATA),
+		.A1EN(A1EN),
+		.CLK1(CLK1),
+
+		.B1ADDR(B1ADDR),
+		.B1DATA(B1DATA),
+		.B1EN(B1EN),
+		.CLK2(CLK2)
+	);
+endmodule
+
+module \$__QLF_FACTOR_BRAM36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+	parameter CFG_ABITS = 10;
+	parameter CFG_DBITS = 36;
+	parameter CFG_ENABLE_B = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+	parameter [36863:0] INIT = 36864'bx;
+
+	localparam MODE_36  = 3'b111;	// 36 or 32-bit
+	localparam MODE_18  = 3'b110;	// 18 or 16-bit
+	localparam MODE_9   = 3'b101;	// 9 or 8-bit
+	localparam MODE_4   = 3'b100;	// 4-bit
+	localparam MODE_2   = 3'b010;	// 32-bit
+	localparam MODE_1   = 3'b001;	// 32-bit
+
+	input CLK2;
+	input CLK3;
+
+	input [CFG_ABITS-1:0] A1ADDR;
+	output [CFG_DBITS-1:0] A1DATA;
+	input A1EN;
+
+	input [CFG_ABITS-1:0] B1ADDR;
+	input [CFG_DBITS-1:0] B1DATA;
+	input [CFG_ENABLE_B-1:0] B1EN;
+
+	wire [14:0] A1ADDR_15;
+	wire [14:0] B1ADDR_15;
+
+	wire [35:0] DOBDO;
+
+	wire [14:CFG_ABITS] A1ADDR_CMPL;
+	wire [14:CFG_ABITS] B1ADDR_CMPL;
+	wire [35:CFG_DBITS] A1DATA_CMPL;
+	wire [35:CFG_DBITS] B1DATA_CMPL;
+
+	wire [14:0] A1ADDR_TOTAL;
+	wire [14:0] B1ADDR_TOTAL;
+	wire [35:0] A1DATA_TOTAL;
+	wire [35:0] B1DATA_TOTAL;
+
+	wire FLUSH1;
+	wire FLUSH2;
+
+	assign A1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+	assign B1ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+
+	assign A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+	assign B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+
+	// Assign read/write data - handle special case for 9bit mode
+	// parity bit for 9bit mode is placed in R/W port on bit #16
+	case (CFG_DBITS)
+		9: begin
+			assign A1DATA = {A1DATA_TOTAL[16], A1DATA_TOTAL[7:0]};
+			assign B1DATA_TOTAL = {B1DATA_CMPL[35:17], B1DATA[8], B1DATA_CMPL[16:9], B1DATA[7:0]};
+		end
+		default: begin
+			assign A1DATA = A1DATA_TOTAL[CFG_DBITS-1:0];
+			assign B1DATA_TOTAL = {B1DATA_CMPL, B1DATA};
+		end
+	endcase
+
+	case (CFG_DBITS)
+		1: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL;
+			assign B1ADDR_15 = B1ADDR_TOTAL;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+            };
+		end
+
+		2: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL << 1;
+			assign B1ADDR_15 = B1ADDR_TOTAL << 1;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0
+            };
+		end
+
+		4: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL << 2;
+			assign B1ADDR_15 = B1ADDR_TOTAL << 2;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0
+            };
+		end
+		8, 9: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL << 3;
+			assign B1ADDR_15 = B1ADDR_TOTAL << 3;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0
+            };
+		end
+
+		16, 18: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL << 4;
+			assign B1ADDR_15 = B1ADDR_TOTAL << 4;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0
+            };
+		end
+		32, 36: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL << 5;
+			assign B1ADDR_15 = B1ADDR_TOTAL << 5;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+            };
+		end
+		default: begin
+			assign A1ADDR_15 = A1ADDR_TOTAL;
+			assign B1ADDR_15 = B1ADDR_TOTAL;
+            defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+            };
+		end
+	endcase
+
+
+	assign FLUSH1 = 1'b0;
+	assign FLUSH2 = 1'b0;
+
+	TDP36K _TECHMAP_REPLACE_ (
+		.RESET_ni(1'b1),
+		.WDATA_A1_i(18'h3FFFF),
+		.WDATA_A2_i(18'h3FFFF),
+		.RDATA_A1_o(A1DATA_TOTAL[17:0]),
+		.RDATA_A2_o(A1DATA_TOTAL[35:18]),
+		.ADDR_A1_i(A1ADDR_15),
+		.ADDR_A2_i(A1ADDR_15),
+		.CLK_A1_i(CLK2),
+		.CLK_A2_i(CLK2),
+		.REN_A1_i(A1EN),
+		.REN_A2_i(A1EN),
+		.WEN_A1_i(1'b0),
+		.WEN_A2_i(1'b0),
+		.BE_A1_i({A1EN, A1EN}),
+		.BE_A2_i({A1EN, A1EN}),
+
+		.WDATA_B1_i(B1DATA_TOTAL[17:0]),
+		.WDATA_B2_i(B1DATA_TOTAL[35:18]),
+		.RDATA_B1_o(DOBDO[17:0]),
+		.RDATA_B2_o(DOBDO[35:18]),
+		.ADDR_B1_i(B1ADDR_15),
+		.ADDR_B2_i(B1ADDR_15),
+		.CLK_B1_i(CLK3),
+		.CLK_B2_i(CLK3),
+		.REN_B1_i(1'b0),
+		.REN_B2_i(1'b0),
+		.WEN_B1_i(B1EN[0]),
+		.WEN_B2_i(B1EN[0]),
+		.BE_B1_i(B1EN[1:0]),
+		.BE_B2_i(B1EN[3:2]),
+
+		.FLUSH1_i(FLUSH1),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
+
+(* techmap_celltype = "_$_mem_v2_asymmetric" *)
+module \$__QLF_FACTOR_BRAM36_SDP_ASYMMETRIC (RD_ADDR, RD_ARST, RD_CLK, RD_DATA, RD_EN, RD_SRST, WR_ADDR, WR_CLK, WR_DATA, WR_EN);
+	parameter CFG_ABITS = 10;
+	parameter CFG_DBITS = 36;
+	parameter CFG_ENABLE_B = 4;
+
+	parameter CLKPOL2 = 1;
+	parameter CLKPOL3 = 1;
+
+	parameter RD_ADDR_WIDTH = 11;
+	parameter RD_DATA_WIDTH = 16;
+	parameter WR_ADDR_WIDTH = 10;
+	parameter WR_DATA_WIDTH = 32;
+
+	parameter ABITS = 0;
+	parameter MEMID = 0;
+	parameter [36863:0] INIT = 36864'bx;
+	parameter OFFSET = 0;
+	parameter RD_ARST_VALUE = 0;
+	parameter RD_CE_OVER_SRST = 0;
+	parameter RD_CLK_ENABLE = 0;
+	parameter RD_CLK_POLARITY = 0;
+	parameter RD_COLLISION_X_MASK = 0;
+	parameter RD_INIT_VALUE = 0;
+	parameter RD_PORTS = 0;
+	parameter RD_SRST_VALUE = 0;
+	parameter RD_TRANSPARENCY_MASK = 0;
+	parameter RD_WIDE_CONTINUATION = 0;
+	parameter SIZE = 0;
+	parameter WIDTH = 0;
+	parameter WR_CLK_ENABLE = 0;
+	parameter WR_CLK_POLARITY = 0;
+	parameter WR_PORTS = 0;
+	parameter WR_PRIORITY_MASK = 0;
+	parameter WR_WIDE_CONTINUATION = 0;
+
+	localparam MODE_36  = 3'b111;	// 36 or 32-bit
+	localparam MODE_18  = 3'b110;	// 18 or 16-bit
+	localparam MODE_9   = 3'b101;	// 9 or 8-bit
+	localparam MODE_4   = 3'b100;	// 4-bit
+	localparam MODE_2   = 3'b010;	// 32-bit
+	localparam MODE_1   = 3'b001;	// 32-bit
+
+	localparam READ_DATA_BITS_TO_SKIP = 36 - RD_DATA_WIDTH;
+
+	input RD_CLK;
+	input WR_CLK;
+	input RD_ARST;
+	input RD_SRST;
+
+	input [RD_ADDR_WIDTH-1:0] RD_ADDR;
+	output [RD_DATA_WIDTH-1:0] RD_DATA;
+	input RD_EN;
+
+	input [WR_ADDR_WIDTH-1:0] WR_ADDR;
+	input [WR_DATA_WIDTH-1:0] WR_DATA;
+	input [CFG_ENABLE_B-1:0] WR_EN;
+
+	wire [14:RD_ADDR_WIDTH] RD_ADDR_CMPL;
+	wire [14:WR_ADDR_WIDTH] WR_ADDR_CMPL;
+	wire [35:RD_DATA_WIDTH] RD_DATA_CMPL;
+	wire [35:WR_DATA_WIDTH] WR_DATA_CMPL;
+
+	wire [14:0] RD_ADDR_TOTAL;
+	wire [14:0] WR_ADDR_TOTAL;
+	wire [35:0] RD_DATA_TOTAL;
+	wire [35:0] WR_DATA_TOTAL;
+
+	wire [14:0] RD_ADDR_SHIFTED;
+	wire [14:0] WR_ADDR_SHIFTED;
+
+	wire FLUSH1;
+	wire FLUSH2;
+
+	assign RD_ADDR_CMPL = {15-RD_ADDR_WIDTH{1'b0}};
+	assign WR_ADDR_CMPL = {15-WR_ADDR_WIDTH{1'b0}};
+
+	assign RD_ADDR_TOTAL = {RD_ADDR_CMPL, RD_ADDR};
+	assign WR_ADDR_TOTAL = {WR_ADDR_CMPL, WR_ADDR};
+
+	assign WR_DATA_TOTAL = {WR_DATA_CMPL, WR_DATA};
+
+	// Assign parameters
+	case (RD_DATA_WIDTH)
+		1: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_2, `MODE_1, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_2, `MODE_1, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_4, `MODE_1, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_4, `MODE_1, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_9, `MODE_1, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_9, `MODE_1, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_18, `MODE_1, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_18, `MODE_1, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_36, `MODE_1, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_36, `MODE_1, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		2: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_1, `MODE_2, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_1, `MODE_2, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_2, `MODE_2, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_4, `MODE_2, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_4, `MODE_2, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_9, `MODE_2, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_9, `MODE_2, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_18, `MODE_2, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_18, `MODE_2, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_36, `MODE_2, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_36, `MODE_2, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_2, `MODE_1, `MODE_2, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_2, `MODE_1, `MODE_2, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		4: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_1, `MODE_4, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_1, `MODE_4, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_2, `MODE_4, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_2, `MODE_4, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_4, `MODE_4, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_9, `MODE_4, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_9, `MODE_4, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_18, `MODE_4, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_18, `MODE_4, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_36, `MODE_4, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_36, `MODE_4, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_4, `MODE_1, `MODE_4, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_4, `MODE_1, `MODE_4, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		8, 9: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_1, `MODE_9, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_1, `MODE_9, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_2, `MODE_9, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_2, `MODE_9, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_4, `MODE_9, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_4, `MODE_9, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_9, `MODE_9, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_18, `MODE_9, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_18, `MODE_9, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_36, `MODE_9, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_36, `MODE_9, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_9, `MODE_1, `MODE_9, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_9, `MODE_1, `MODE_9, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		16, 18: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_1, `MODE_18, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_1, `MODE_18, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_2, `MODE_18, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_2, `MODE_18, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_4, `MODE_18, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_4, `MODE_18, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_9, `MODE_18, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_9, `MODE_18, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_18, `MODE_18, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_36, `MODE_18, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_36, `MODE_18, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_18, `MODE_1, `MODE_18, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_18, `MODE_1, `MODE_18, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		32, 36: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_1, `MODE_36, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_1, `MODE_36, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_2, `MODE_36, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_2, `MODE_36, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_4, `MODE_36, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_4, `MODE_36, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_9, `MODE_36, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_9, `MODE_36, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_18, `MODE_36, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_18, `MODE_36, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_36, `MODE_36, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_36, `MODE_1, `MODE_36, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_36, `MODE_1, `MODE_36, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+		default: begin
+			case (WR_DATA_WIDTH)
+				1: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+					};
+				end
+				2: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_2, `MODE_1, `MODE_2, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_2, `MODE_1, `MODE_2, 1'd0
+					};
+				end
+				4: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_4, `MODE_1, `MODE_4, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_4, `MODE_1, `MODE_4, 1'd0
+					};
+				end
+				8, 9: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_9, `MODE_1, `MODE_9, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_9, `MODE_1, `MODE_9, 1'd0
+					};
+				end
+				16, 18: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_18, `MODE_1, `MODE_18, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_18, `MODE_1, `MODE_18, 1'd0
+					};
+				end
+				32, 36: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_36, `MODE_1, `MODE_36, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_36, `MODE_1, `MODE_36, 1'd0
+					};
+				end
+				default: begin
+					defparam _TECHMAP_REPLACE_.MODE_BITS = { 1'b0,
+						11'd10, 11'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0,
+						12'd10, 12'd10, 4'd0, `MODE_1, `MODE_1, `MODE_1, `MODE_1, 1'd0
+					};
+				end
+			endcase
+		end
+	endcase
+
+	// Apply shift
+	case (RD_DATA_WIDTH)
+		1: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL;
+		end
+		2: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL << 1;
+		end
+		4: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL << 2;
+		end
+		8, 9: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL << 3;
+		end
+		16, 18: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL << 4;
+		end
+		32, 36: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL << 5;
+		end
+		default: begin
+			assign RD_ADDR_SHIFTED = RD_ADDR_TOTAL;
+		end
+	endcase
+
+	case (WR_DATA_WIDTH)
+		1: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL;
+		end
+		2: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL << 1;
+		end
+		4: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL << 2;
+		end
+		8, 9: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL << 3;
+		end
+		16, 18: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL << 4;
+		end
+		32, 36: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL << 5;
+		end
+		default: begin
+			assign WR_ADDR_SHIFTED = WR_ADDR_TOTAL;
+		end
+	endcase
+
+	assign FLUSH1 = 1'b0;
+	assign FLUSH2 = 1'b0;
+
+	// TODO configure per width
+	wire [17:0] PORT_A1_RDATA;
+	wire [17:0] PORT_A2_RDATA;
+	always @(PORT_A1_RDATA, PORT_A2_RDATA) begin
+		if (RD_DATA_WIDTH > 18)
+			{RD_DATA_CMPL, RD_DATA} <= {PORT_A2_RDATA[17 - (READ_DATA_BITS_TO_SKIP / 2):17 - (READ_DATA_BITS_TO_SKIP / 2)], PORT_A1_RDATA[17 - (READ_DATA_BITS_TO_SKIP / 2):17 - (READ_DATA_BITS_TO_SKIP / 2)],PORT_A2_RDATA[17 - (READ_DATA_BITS_TO_SKIP / 2):0], PORT_A1_RDATA[17 - (READ_DATA_BITS_TO_SKIP / 2):0]};
+		else
+			{RD_DATA_CMPL, RD_DATA} <= {PORT_A1_RDATA[17 - (READ_DATA_BITS_TO_SKIP-18):17 - (READ_DATA_BITS_TO_SKIP-18)], PORT_A1_RDATA[17 - (READ_DATA_BITS_TO_SKIP-18):0]};
+	end
+
+	wire [17:0] PORT_A1_WDATA = {WR_DATA_CMPL, WR_DATA[15:0]};
+	wire [17:0] PORT_A2_WDATA = {WR_DATA_CMPL, WR_DATA[31:16]};
+	// TODO configure per width
+
+	wire PORT_A1_CLK = RD_CLK;
+	wire PORT_A2_CLK = RD_CLK;
+
+	wire PORT_A1_REN = RD_EN;
+	wire PORT_A1_WEN = WR_EN;
+	wire [1:0] PORT_A1_BE = {PORT_A1_WEN, PORT_A1_WEN};
+
+	wire PORT_A2_REN = RD_EN;
+	wire PORT_A2_WEN = WR_EN;
+	wire [1:0] PORT_A2_BE = {PORT_A2_WEN, PORT_A2_WEN};
+
+	TDP36K _TECHMAP_REPLACE_ (
+		.RESET_ni(1'b1),
+
+		.WDATA_A1_i(PORT_A1_WDATA),
+		.RDATA_A1_o(),
+		.ADDR_A1_i(WR_ADDR_SHIFTED),
+		.CLK_A1_i(PORT_A1_CLK),
+		.REN_A1_i(1'b0),
+		.WEN_A1_i(PORT_A1_WEN),
+		.BE_A1_i(PORT_A1_BE),
+
+		.WDATA_B1_i(),
+		.RDATA_B1_o(PORT_A1_RDATA),
+		.ADDR_B1_i(RD_ADDR_SHIFTED),
+		.CLK_B1_i(PORT_A1_CLK),
+		.REN_B1_i(PORT_A1_REN),
+		.WEN_B1_i(1'b0),
+		.BE_B1_i(PORT_A1_BE),
+
+		.WDATA_A2_i(PORT_A2_WDATA),
+		.RDATA_A2_o(),
+		.ADDR_A2_i(WR_ADDR_SHIFTED),
+		.CLK_A2_i(PORT_A2_CLK),
+		.REN_A2_i(1'b0),
+		.WEN_A2_i(PORT_A2_WEN),
+		.BE_A2_i(PORT_A2_BE),
+
+		.WDATA_B2_i(),
+		.RDATA_B2_o(PORT_A2_RDATA),
+		.ADDR_B2_i(RD_ADDR_SHIFTED),
+		.CLK_B2_i(PORT_A2_CLK),
+		.REN_B2_i(PORT_A2_REN),
+		.WEN_B2_i(1'b0),
+		.BE_B2_i(PORT_A2_BE),
+
+		.FLUSH1_i(FLUSH1),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/cells_sim.v b/yosys-plugins/ql-qlf/qlf_k6n10f/cells_sim.v
new file mode 100644
index 000000000..26ac9aeb9
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/cells_sim.v
@@ -0,0 +1,1691 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
+
+(* abc9_flop, lib_whitebox *)
+module sh_dff(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C
+);
+
+    initial Q <= 1'b0;
+    always @(posedge C)
+        Q <= D;
+
+endmodule
+
+(* abc9_box, lib_blackbox *)
+module adder_carry(
+    output wire sumout,
+    output wire cout,
+    input wire p,
+    input wire g,
+    input wire cin
+);
+    assign sumout = p ^ cin;
+    assign cout = p ? cin : g;
+
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module adder_lut5(
+   output wire lut5_out,
+   (* abc9_carry *)
+   output wire cout,
+   input wire [0:4] in,
+   (* abc9_carry *)
+   input wire cin
+);
+    parameter [0:15] LUT=0;
+    parameter IN2_IS_CIN = 0;
+
+    wire [0:4] li = (IN2_IS_CIN) ? {in[0], in[1], cin, in[3], in[4]} : {in[0], in[1], in[2], in[3],in[4]};
+
+    // Output function
+    wire [0:15] s1 = li[0] ?
+        {LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14], LUT[16], LUT[18], LUT[20], LUT[22], LUT[24], LUT[26], LUT[28], LUT[30]}:
+        {LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15], LUT[17], LUT[19], LUT[21], LUT[23], LUT[25], LUT[27], LUT[29], LUT[31]};
+
+    wire [0:7] s2 = li[1] ? {s1[0], s1[2], s1[4], s1[6], s1[8], s1[10], s1[12], s1[14]} :
+                            {s1[1], s1[3], s1[5], s1[7], s1[9], s1[11], s1[13], s1[15]};
+
+    wire [0:3] s3 = li[2] ? {s2[0], s2[2], s2[4], s2[6]} : {s2[1], s2[3], s2[5], s2[7]};
+    wire [0:1] s4 = li[3] ? {s3[0], s3[2]} : {s3[1], s3[3]};
+
+    assign lut5_out = li[4] ? s4[0] : s4[1];
+
+    // Carry out function
+    assign cout = (s3[2]) ? cin : s3[3];
+
+endmodule
+
+(* abc9_lut=1, lib_whitebox *)
+module frac_lut6(
+    input wire [0:5] in,
+    output wire [0:3] lut4_out,
+    output wire [0:1] lut5_out,
+    output wire lut6_out
+);
+    parameter [0:63] LUT = 0;
+    // Effective LUT input
+    wire [0:5] li = in;
+
+    // Output function
+    wire [0:31] s1 = li[0] ?
+    {LUT[0] , LUT[2] , LUT[4] , LUT[6] , LUT[8] , LUT[10], LUT[12], LUT[14], 
+     LUT[16], LUT[18], LUT[20], LUT[22], LUT[24], LUT[26], LUT[28], LUT[30],
+     LUT[32], LUT[34], LUT[36], LUT[38], LUT[40], LUT[42], LUT[44], LUT[46],
+     LUT[48], LUT[50], LUT[52], LUT[54], LUT[56], LUT[58], LUT[60], LUT[62]}:
+    {LUT[1] , LUT[3] , LUT[5] , LUT[7] , LUT[9] , LUT[11], LUT[13], LUT[15], 
+     LUT[17], LUT[19], LUT[21], LUT[23], LUT[25], LUT[27], LUT[29], LUT[31],
+     LUT[33], LUT[35], LUT[37], LUT[39], LUT[41], LUT[43], LUT[45], LUT[47],
+     LUT[49], LUT[51], LUT[53], LUT[55], LUT[57], LUT[59], LUT[61], LUT[63]};
+
+    wire [0:15] s2 = li[1] ?
+    {s1[0] , s1[2] , s1[4] , s1[6] , s1[8] , s1[10], s1[12], s1[14],
+     s1[16], s1[18], s1[20], s1[22], s1[24], s1[26], s1[28], s1[30]}:
+    {s1[1] , s1[3] , s1[5] , s1[7] , s1[9] , s1[11], s1[13], s1[15],
+     s1[17], s1[19], s1[21], s1[23], s1[25], s1[27], s1[29], s1[31]};
+
+    wire [0:7] s3 = li[2] ?
+    {s2[0], s2[2], s2[4], s2[6], s2[8], s2[10], s2[12], s2[14]}:
+    {s2[1], s2[3], s2[5], s2[7], s2[9], s2[11], s2[13], s2[15]};
+
+    wire [0:3] s4 = li[3] ? {s3[0], s3[2], s3[4], s3[6]}:
+                            {s3[1], s3[3], s3[5], s3[7]};
+
+    wire [0:1] s5 = li[4] ? {s4[0], s4[2]} : {s4[1], s4[3]};
+
+    assign lut4_out[0] = s4[0];
+    assign lut4_out[1] = s4[1];
+    assign lut4_out[2] = s4[2];
+    assign lut4_out[3] = s4[3];
+
+    assign lut5_out[0] = s5[0];
+    assign lut5_out[1] = s5[1];
+
+    assign lut6_out = li[5] ? s5[0] : s5[1];
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dff(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C
+);
+    initial Q <= 1'b0;
+
+    always @(posedge C)
+      Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffn(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C
+);
+    initial Q <= 1'b0;
+
+    always @(negedge C)
+      Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffsre(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C,
+    input wire E,
+    input wire R,
+    input wire S
+);
+    initial Q <= 1'b0;
+
+    always @(posedge C or negedge S or negedge R)
+      if (!R)
+        Q <= 1'b0;
+      else if (!S)
+        Q <= 1'b1;
+      else if (E)
+        Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module dffnsre(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C,
+    input wire E,
+    input wire R,
+    input wire S
+);
+    initial Q <= 1'b0;
+
+    always @(negedge C or negedge S or negedge R)
+      if (!R)
+        Q <= 1'b0;
+      else if (!S)
+        Q <= 1'b1;
+      else if (E)
+        Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module sdffsre(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C,
+    input wire E,
+    input wire R,
+    input wire S
+);
+    initial Q <= 1'b0;
+
+    always @(posedge C)
+      if (!R)
+        Q <= 1'b0;
+      else if (!S)
+        Q <= 1'b1;
+      else if (E)
+        Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module sdffnsre(
+    output reg Q,
+    input wire D,
+    (* clkbuf_sink *)
+    input wire C,
+    input wire E,
+    input wire R,
+    input wire S
+);
+    initial Q <= 1'b0;
+
+    always @(negedge C)
+      if (!R)
+        Q <= 1'b0;
+      else if (!S)
+        Q <= 1'b1;
+      else if (E)
+        Q <= D;
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module latchsre (
+    output reg Q,
+    input wire S,
+    input wire R,
+    input wire D,
+    input wire G,
+    input wire E
+);
+    initial Q <= 1'b0;
+
+    always @*
+      begin
+        if (!R)
+          Q <= 1'b0;
+        else if (!S)
+          Q <= 1'b1;
+        else if (E && G)
+          Q <= D;
+      end
+
+endmodule
+
+(* abc9_flop, lib_whitebox *)
+module latchnsre (
+    output reg Q,
+    input wire S,
+    input wire R,
+    input wire D,
+    input wire G,
+    input wire E
+);
+    initial Q <= 1'b0;
+
+    always @*
+      begin
+        if (!R)
+          Q <= 1'b0;
+        else if (!S)
+          Q <= 1'b1;
+        else if (E && !G)
+          Q <= D;
+      end
+
+endmodule
+
+
+module TDP_BRAM18 (
+    (* clkbuf_sink *)
+    input wire CLOCKA,
+    (* clkbuf_sink *)
+    input wire CLOCKB,
+    input wire READENABLEA,
+    input wire READENABLEB,
+    input wire [13:0] ADDRA,
+    input wire [13:0] ADDRB,
+    input wire [15:0] WRITEDATAA,
+    input wire [15:0] WRITEDATAB,
+    input wire [1:0] WRITEDATAAP,
+    input wire [1:0] WRITEDATABP,
+    input wire WRITEENABLEA,
+    input wire WRITEENABLEB,
+    input wire [1:0] BYTEENABLEA,
+    input wire [1:0] BYTEENABLEB,
+    //input wire [2:0] WRITEDATAWIDTHA,
+    //input wire [2:0] WRITEDATAWIDTHB,
+    //input wire [2:0] READDATAWIDTHA,
+    //input wire [2:0] READDATAWIDTHB,
+    output wire [15:0] READDATAA,
+    output wire [15:0] READDATAB,
+    output wire [1:0] READDATAAP,
+    output wire [1:0] READDATABP
+);
+    parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter integer READ_WIDTH_A = 0;
+    parameter integer READ_WIDTH_B = 0;
+    parameter integer WRITE_WIDTH_A = 0;
+    parameter integer WRITE_WIDTH_B = 0;
+
+endmodule
+
+module TDP36K (
+    RESET_ni,
+    WEN_A1_i,
+    WEN_B1_i,
+    REN_A1_i,
+    REN_B1_i,
+    CLK_A1_i,
+    CLK_B1_i,
+    BE_A1_i,
+    BE_B1_i,
+    ADDR_A1_i,
+    ADDR_B1_i,
+    WDATA_A1_i,
+    WDATA_B1_i,
+    RDATA_A1_o,
+    RDATA_B1_o,
+    FLUSH1_i,
+    WEN_A2_i,
+    WEN_B2_i,
+    REN_A2_i,
+    REN_B2_i,
+    CLK_A2_i,
+    CLK_B2_i,
+    BE_A2_i,
+    BE_B2_i,
+    ADDR_A2_i,
+    ADDR_B2_i,
+    WDATA_A2_i,
+    WDATA_B2_i,
+    RDATA_A2_o,
+    RDATA_B2_o,
+    FLUSH2_i
+);
+    parameter [80:0] MODE_BITS = 81'd0;
+
+    // First 18K RAMFIFO (41 bits)
+    localparam [ 0:0] SYNC_FIFO1_i  = MODE_BITS[0];
+    localparam [ 2:0] RMODE_A1_i    = MODE_BITS[3 : 1];
+    localparam [ 2:0] RMODE_B1_i    = MODE_BITS[6 : 4];
+    localparam [ 2:0] WMODE_A1_i    = MODE_BITS[9 : 7];
+    localparam [ 2:0] WMODE_B1_i    = MODE_BITS[12:10];
+    localparam [ 0:0] FMODE1_i      = MODE_BITS[13];
+    localparam [ 0:0] POWERDN1_i    = MODE_BITS[14];
+    localparam [ 0:0] SLEEP1_i      = MODE_BITS[15];
+    localparam [ 0:0] PROTECT1_i    = MODE_BITS[16];
+    localparam [11:0] UPAE1_i       = MODE_BITS[28:17];
+    localparam [11:0] UPAF1_i       = MODE_BITS[40:29];
+
+    // Second 18K RAMFIFO (39 bits)
+    localparam [ 0:0] SYNC_FIFO2_i  = MODE_BITS[41];
+    localparam [ 2:0] RMODE_A2_i    = MODE_BITS[44:42];
+    localparam [ 2:0] RMODE_B2_i    = MODE_BITS[47:45];
+    localparam [ 2:0] WMODE_A2_i    = MODE_BITS[50:48];
+    localparam [ 2:0] WMODE_B2_i    = MODE_BITS[53:51];
+    localparam [ 0:0] FMODE2_i      = MODE_BITS[54];
+    localparam [ 0:0] POWERDN2_i    = MODE_BITS[55];
+    localparam [ 0:0] SLEEP2_i      = MODE_BITS[56];
+    localparam [ 0:0] PROTECT2_i    = MODE_BITS[57];
+    localparam [10:0] UPAE2_i       = MODE_BITS[68:58];
+    localparam [10:0] UPAF2_i       = MODE_BITS[79:69];
+
+    // Split (1 bit)
+    localparam [ 0:0] SPLIT_i       = MODE_BITS[80];
+
+    parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+    parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+
+    input wire RESET_ni;
+    input wire WEN_A1_i;
+    input wire WEN_B1_i;
+    input wire REN_A1_i;
+    input wire REN_B1_i;
+    (* clkbuf_sink *)
+    input wire CLK_A1_i;
+    (* clkbuf_sink *)
+    input wire CLK_B1_i;
+    input wire [1:0] BE_A1_i;
+    input wire [1:0] BE_B1_i;
+    input wire [14:0] ADDR_A1_i;
+    input wire [14:0] ADDR_B1_i;
+    input wire [17:0] WDATA_A1_i;
+    input wire [17:0] WDATA_B1_i;
+    output reg [17:0] RDATA_A1_o;
+    output reg [17:0] RDATA_B1_o;
+    input wire FLUSH1_i;
+    input wire WEN_A2_i;
+    input wire WEN_B2_i;
+    input wire REN_A2_i;
+    input wire REN_B2_i;
+    (* clkbuf_sink *)
+    input wire CLK_A2_i;
+    (* clkbuf_sink *)
+    input wire CLK_B2_i;
+    input wire [1:0] BE_A2_i;
+    input wire [1:0] BE_B2_i;
+    input wire [13:0] ADDR_A2_i;
+    input wire [13:0] ADDR_B2_i;
+    input wire [17:0] WDATA_A2_i;
+    input wire [17:0] WDATA_B2_i;
+    output reg [17:0] RDATA_A2_o;
+    output reg [17:0] RDATA_B2_o;
+    input wire FLUSH2_i;
+    wire EMPTY2;
+    wire EPO2;
+    wire EWM2;
+    wire FULL2;
+    wire FMO2;
+    wire FWM2;
+    wire EMPTY1;
+    wire EPO1;
+    wire EWM1;
+    wire FULL1;
+    wire FMO1;
+    wire FWM1;
+    wire UNDERRUN1;
+    wire OVERRUN1;
+    wire UNDERRUN2;
+    wire OVERRUN2;
+    wire UNDERRUN3;
+    wire OVERRUN3;
+    wire EMPTY3;
+    wire EPO3;
+    wire EWM3;
+    wire FULL3;
+    wire FMO3;
+    wire FWM3;
+    wire ram_fmode1;
+    wire ram_fmode2;
+    wire [17:0] ram_rdata_a1;
+    wire [17:0] ram_rdata_b1;
+    wire [17:0] ram_rdata_a2;
+    wire [17:0] ram_rdata_b2;
+    reg [17:0] ram_wdata_a1;
+    reg [17:0] ram_wdata_b1;
+    reg [17:0] ram_wdata_a2;
+    reg [17:0] ram_wdata_b2;
+    reg [14:0] laddr_a1;
+    reg [14:0] laddr_b1;
+    wire [13:0] ram_addr_a1;
+    wire [13:0] ram_addr_b1;
+    wire [13:0] ram_addr_a2;
+    wire [13:0] ram_addr_b2;
+    wire smux_clk_a1;
+    wire smux_clk_b1;
+    wire smux_clk_a2;
+    wire smux_clk_b2;
+    reg [1:0] ram_be_a1;
+    reg [1:0] ram_be_a2;
+    reg [1:0] ram_be_b1;
+    reg [1:0] ram_be_b2;
+    wire [2:0] ram_rmode_a1;
+    wire [2:0] ram_wmode_a1;
+    wire [2:0] ram_rmode_b1;
+    wire [2:0] ram_wmode_b1;
+    wire [2:0] ram_rmode_a2;
+    wire [2:0] ram_wmode_a2;
+    wire [2:0] ram_rmode_b2;
+    wire [2:0] ram_wmode_b2;
+    wire ram_ren_a1;
+    wire ram_ren_b1;
+    wire ram_ren_a2;
+    wire ram_ren_b2;
+    wire ram_wen_a1;
+    wire ram_wen_b1;
+    wire ram_wen_a2;
+    wire ram_wen_b2;
+    wire ren_o;
+    wire [11:0] ff_raddr;
+    wire [11:0] ff_waddr;
+    reg [35:0] fifo_rdata;
+    wire [1:0] fifo_rmode;
+    wire [1:0] fifo_wmode;
+    wire [1:0] bwl;
+    wire [17:0] pl_dout0;
+    wire [17:0] pl_dout1;
+    wire sclk_a1;
+    wire sclk_b1;
+    wire sclk_a2;
+    wire sclk_b2;
+    wire sreset;
+    wire flush1;
+    wire flush2;
+    assign sreset = RESET_ni;
+    assign flush1 = ~FLUSH1_i;
+    assign flush2 = ~FLUSH2_i;
+    assign ram_fmode1 = FMODE1_i & SPLIT_i;
+    assign ram_fmode2 = FMODE2_i & SPLIT_i;
+    assign smux_clk_a1 = CLK_A1_i;
+    assign smux_clk_b1 = (FMODE1_i ? (SYNC_FIFO1_i ? CLK_A1_i : CLK_B1_i) : CLK_B1_i);
+    assign smux_clk_a2 = (SPLIT_i ? CLK_A2_i : CLK_A1_i);
+    assign smux_clk_b2 = (SPLIT_i ? (FMODE2_i ? (SYNC_FIFO2_i ? CLK_A2_i : CLK_B2_i) : CLK_B2_i) : (FMODE1_i ? (SYNC_FIFO1_i ? CLK_A1_i : CLK_B1_i) : CLK_B1_i));
+    assign sclk_a1 = smux_clk_a1;
+    assign sclk_a2 = smux_clk_a2;
+    assign sclk_b1 = smux_clk_b1;
+    assign sclk_b2 = smux_clk_b2;
+    assign ram_ren_a1 = (SPLIT_i ? REN_A1_i : (FMODE1_i ? 0 : REN_A1_i));
+    assign ram_ren_a2 = (SPLIT_i ? REN_A2_i : (FMODE1_i ? 0 : REN_A1_i));
+    assign ram_ren_b1 = (SPLIT_i ? REN_B1_i : (FMODE1_i ? ren_o : REN_B1_i));
+    assign ram_ren_b2 = (SPLIT_i ? REN_B2_i : (FMODE1_i ? ren_o : REN_B1_i));
+    localparam MODE_36 = 3'b011;
+    assign ram_wen_a1 = (SPLIT_i ? WEN_A1_i : (FMODE1_i ? ~FULL3 & WEN_A1_i : (WMODE_A1_i == MODE_36 ? WEN_A1_i : WEN_A1_i & ~ADDR_A1_i[4])));
+    assign ram_wen_a2 = (SPLIT_i ? WEN_A2_i : (FMODE1_i ? ~FULL3 & WEN_A1_i : (WMODE_A1_i == MODE_36 ? WEN_A1_i : WEN_A1_i & ADDR_A1_i[4])));
+    assign ram_wen_b1 = (SPLIT_i ? WEN_B1_i : (WMODE_B1_i == MODE_36 ? WEN_B1_i : WEN_B1_i & ~ADDR_B1_i[4]));
+    assign ram_wen_b2 = (SPLIT_i ? WEN_B2_i : (WMODE_B1_i == MODE_36 ? WEN_B1_i : WEN_B1_i & ADDR_B1_i[4]));
+    assign ram_addr_a1 = (SPLIT_i ? ADDR_A1_i[13:0] : (FMODE1_i ? {ff_waddr[11:2], ff_waddr[0], 3'b000} : {ADDR_A1_i[14:5], ADDR_A1_i[3:0]}));
+    assign ram_addr_b1 = (SPLIT_i ? ADDR_B1_i[13:0] : (FMODE1_i ? {ff_raddr[11:2], ff_raddr[0], 3'b000} : {ADDR_B1_i[14:5], ADDR_B1_i[3:0]}));
+    assign ram_addr_a2 = (SPLIT_i ? ADDR_A2_i[13:0] : (FMODE1_i ? {ff_waddr[11:2], ff_waddr[0], 3'b000} : {ADDR_A1_i[14:5], ADDR_A1_i[3:0]}));
+    assign ram_addr_b2 = (SPLIT_i ? ADDR_B2_i[13:0] : (FMODE1_i ? {ff_raddr[11:2], ff_raddr[0], 3'b000} : {ADDR_B1_i[14:5], ADDR_B1_i[3:0]}));
+    assign bwl = (SPLIT_i ? ADDR_A1_i[4:3] : (FMODE1_i ? ff_waddr[1:0] : ADDR_A1_i[4:3]));
+    localparam MODE_18 = 3'b010;
+    localparam MODE_9 = 3'b001;
+    always @(*) begin : WDATA_SEL
+        case (SPLIT_i)
+            1: begin
+                ram_wdata_a1 = WDATA_A1_i;
+                ram_wdata_a2 = WDATA_A2_i;
+                ram_wdata_b1 = WDATA_B1_i;
+                ram_wdata_b2 = WDATA_B2_i;
+                ram_be_a2 = BE_A2_i;
+                ram_be_b2 = BE_B2_i;
+                ram_be_a1 = BE_A1_i;
+                ram_be_b1 = BE_B1_i;
+            end
+            0: begin
+                case (WMODE_A1_i)
+                    MODE_36: begin
+                        ram_wdata_a1 = WDATA_A1_i;
+                        ram_wdata_a2 = WDATA_A2_i;
+                        ram_be_a2 = (FMODE1_i ? 2'b11 : BE_A2_i);
+                        ram_be_a1 = (FMODE1_i ? 2'b11 : BE_A1_i);
+                    end
+                    MODE_18: begin
+                        ram_wdata_a1 = WDATA_A1_i;
+                        ram_wdata_a2 = WDATA_A1_i;
+                        ram_be_a1 = (FMODE1_i ? (ff_waddr[1] ? 2'b00 : 2'b11) : BE_A1_i);
+                        ram_be_a2 = (FMODE1_i ? (ff_waddr[1] ? 2'b11 : 2'b00) : BE_A1_i);
+                    end
+                    MODE_9: begin
+                        ram_wdata_a1[7:0] = WDATA_A1_i[7:0];
+                        ram_wdata_a1[16] = WDATA_A1_i[16];
+                        ram_wdata_a1[15:8] = WDATA_A1_i[7:0];
+                        ram_wdata_a1[17] = WDATA_A1_i[16];
+                        ram_wdata_a2[7:0] = WDATA_A1_i[7:0];
+                        ram_wdata_a2[16] = WDATA_A1_i[16];
+                        ram_wdata_a2[15:8] = WDATA_A1_i[7:0];
+                        ram_wdata_a2[17] = WDATA_A1_i[16];
+                        case (bwl)
+                            0: {ram_be_a2, ram_be_a1} = 4'b0001;
+                            1: {ram_be_a2, ram_be_a1} = 4'b0010;
+                            2: {ram_be_a2, ram_be_a1} = 4'b0100;
+                            3: {ram_be_a2, ram_be_a1} = 4'b1000;
+                        endcase
+                    end
+                    default: begin
+                        ram_wdata_a1 = WDATA_A1_i;
+                        ram_wdata_a2 = WDATA_A1_i;
+                        ram_be_a2 = (FMODE1_i ? 2'b11 : BE_A1_i);
+                        ram_be_a1 = (FMODE1_i ? 2'b11 : BE_A1_i);
+                    end
+                endcase
+                case (WMODE_B1_i)
+                    MODE_36: begin
+                        ram_wdata_b1 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B1_i);
+                        ram_wdata_b2 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B2_i);
+                        ram_be_b2 = BE_B2_i;
+                        ram_be_b1 = BE_B1_i;
+                    end
+                    MODE_18: begin
+                        ram_wdata_b1 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B1_i);
+                        ram_wdata_b2 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B1_i);
+                        ram_be_b1 = BE_B1_i;
+                        ram_be_b2 = BE_B1_i;
+                    end
+                    MODE_9: begin
+                        ram_wdata_b1[7:0] = WDATA_B1_i[7:0];
+                        ram_wdata_b1[16] = WDATA_B1_i[16];
+                        ram_wdata_b1[15:8] = WDATA_B1_i[7:0];
+                        ram_wdata_b1[17] = WDATA_B1_i[16];
+                        ram_wdata_b2[7:0] = WDATA_B1_i[7:0];
+                        ram_wdata_b2[16] = WDATA_B1_i[16];
+                        ram_wdata_b2[15:8] = WDATA_B1_i[7:0];
+                        ram_wdata_b2[17] = WDATA_B1_i[16];
+                        case (ADDR_B1_i[4:3])
+                            0: {ram_be_b2, ram_be_b1} = 4'b0001;
+                            1: {ram_be_b2, ram_be_b1} = 4'b0010;
+                            2: {ram_be_b2, ram_be_b1} = 4'b0100;
+                            3: {ram_be_b2, ram_be_b1} = 4'b1000;
+                        endcase
+                    end
+                    default: begin
+                        ram_wdata_b1 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B1_i);
+                        ram_wdata_b2 = (FMODE1_i ? 18'b000000000000000000 : WDATA_B1_i);
+                        ram_be_b2 = BE_B1_i;
+                        ram_be_b1 = BE_B1_i;
+                    end
+                endcase
+            end
+        endcase
+    end
+    assign ram_rmode_a1 = (SPLIT_i ? (RMODE_A1_i == MODE_36 ? MODE_18 : RMODE_A1_i) : (RMODE_A1_i == MODE_36 ? MODE_18 : RMODE_A1_i));
+    assign ram_rmode_a2 = (SPLIT_i ? (RMODE_A2_i == MODE_36 ? MODE_18 : RMODE_A2_i) : (RMODE_A1_i == MODE_36 ? MODE_18 : RMODE_A1_i));
+    assign ram_wmode_a1 = (SPLIT_i ? (WMODE_A1_i == MODE_36 ? MODE_18 : WMODE_A1_i) : (WMODE_A1_i == MODE_36 ? MODE_18 : (FMODE1_i ? MODE_18 : WMODE_A1_i)));
+    assign ram_wmode_a2 = (SPLIT_i ? (WMODE_A2_i == MODE_36 ? MODE_18 : WMODE_A2_i) : (WMODE_A1_i == MODE_36 ? MODE_18 : (FMODE1_i ? MODE_18 : WMODE_A1_i)));
+    assign ram_rmode_b1 = (SPLIT_i ? (RMODE_B1_i == MODE_36 ? MODE_18 : RMODE_B1_i) : (RMODE_B1_i == MODE_36 ? MODE_18 : (FMODE1_i ? MODE_18 : RMODE_B1_i)));
+    assign ram_rmode_b2 = (SPLIT_i ? (RMODE_B2_i == MODE_36 ? MODE_18 : RMODE_B2_i) : (RMODE_B1_i == MODE_36 ? MODE_18 : (FMODE1_i ? MODE_18 : RMODE_B1_i)));
+    assign ram_wmode_b1 = (SPLIT_i ? (WMODE_B1_i == MODE_36 ? MODE_18 : WMODE_B1_i) : (WMODE_B1_i == MODE_36 ? MODE_18 : WMODE_B1_i));
+    assign ram_wmode_b2 = (SPLIT_i ? (WMODE_B2_i == MODE_36 ? MODE_18 : WMODE_B2_i) : (WMODE_B1_i == MODE_36 ? MODE_18 : WMODE_B1_i));
+    always @(*) begin : FIFO_READ_SEL
+        case (RMODE_B1_i)
+            MODE_36: fifo_rdata = {ram_rdata_b2[17:16], ram_rdata_b1[17:16], ram_rdata_b2[15:0], ram_rdata_b1[15:0]};
+            MODE_18: fifo_rdata = (ff_raddr[1] ? {18'b000000000000000000, ram_rdata_b2} : {18'b000000000000000000, ram_rdata_b1});
+            MODE_9:
+                case (ff_raddr[1:0])
+                    0: fifo_rdata = {19'b0000000000000000000, ram_rdata_b1[16], 8'b00000000, ram_rdata_b1[7:0]};
+                    1: fifo_rdata = {19'b0000000000000000000, ram_rdata_b1[17], 8'b00000000, ram_rdata_b1[15:8]};
+                    2: fifo_rdata = {19'b0000000000000000000, ram_rdata_b2[16], 8'b00000000, ram_rdata_b2[7:0]};
+                    3: fifo_rdata = {19'b0000000000000000000, ram_rdata_b2[17], 8'b00000000, ram_rdata_b2[15:8]};
+                endcase
+            default: fifo_rdata = {ram_rdata_b2, ram_rdata_b1};
+        endcase
+    end
+    localparam MODE_1 = 3'b101;
+    localparam MODE_2 = 3'b110;
+    localparam MODE_4 = 3'b100;
+    always @(*) begin : RDATA_SEL
+        case (SPLIT_i)
+            1: begin
+                RDATA_A1_o = (FMODE1_i ? {10'b0000000000, EMPTY1, EPO1, EWM1, UNDERRUN1, FULL1, FMO1, FWM1, OVERRUN1} : ram_rdata_a1);
+                RDATA_B1_o = ram_rdata_b1;
+                RDATA_A2_o = (FMODE2_i ? {10'b0000000000, EMPTY2, EPO2, EWM2, UNDERRUN2, FULL2, FMO2, FWM2, OVERRUN2} : ram_rdata_a2);
+                RDATA_B2_o = ram_rdata_b2;
+            end
+            0: begin
+                if (FMODE1_i) begin
+                    RDATA_A1_o = {10'b0000000000, EMPTY3, EPO3, EWM3, UNDERRUN3, FULL3, FMO3, FWM3, OVERRUN3};
+                    RDATA_A2_o = 18'b000000000000000000;
+                end
+                else
+                    case (RMODE_A1_i)
+                        MODE_36: begin
+                            RDATA_A1_o = {ram_rdata_a1[17:0]};
+                            RDATA_A2_o = {ram_rdata_a2[17:0]};
+                        end
+                        MODE_18: begin
+                            RDATA_A1_o = (laddr_a1[4] ? ram_rdata_a2 : ram_rdata_a1);
+                            RDATA_A2_o = 18'b000000000000000000;
+                        end
+                        MODE_9: begin
+                            RDATA_A1_o = (laddr_a1[4] ? {{2 {ram_rdata_a2[16]}}, {2 {ram_rdata_a2[7:0]}}} : {{2 {ram_rdata_a1[16]}}, {2 {ram_rdata_a1[7:0]}}});
+                            RDATA_A2_o = 18'b000000000000000000;
+                        end
+                        MODE_4: begin
+                            RDATA_A2_o = 18'b000000000000000000;
+                            RDATA_A1_o[17:4] = 14'b00000000000000;
+                            RDATA_A1_o[3:0] = (laddr_a1[4] ? ram_rdata_a2[3:0] : ram_rdata_a1[3:0]);
+                        end
+                        MODE_2: begin
+                            RDATA_A2_o = 18'b000000000000000000;
+                            RDATA_A1_o[17:2] = 16'b0000000000000000;
+                            RDATA_A1_o[1:0] = (laddr_a1[4] ? ram_rdata_a2[1:0] : ram_rdata_a1[1:0]);
+                        end
+                        MODE_1: begin
+                            RDATA_A2_o = 18'b000000000000000000;
+                            RDATA_A1_o[17:1] = 17'b00000000000000000;
+                            RDATA_A1_o[0] = (laddr_a1[4] ? ram_rdata_a2[0] : ram_rdata_a1[0]);
+                        end
+                        default: begin
+                            RDATA_A1_o = {ram_rdata_a2[1:0], ram_rdata_a1[15:0]};
+                            RDATA_A2_o = {ram_rdata_a2[17:16], ram_rdata_a1[17:16], ram_rdata_a2[15:2]};
+                        end
+                    endcase
+                case (RMODE_B1_i)
+                    MODE_36: begin
+                        RDATA_B1_o = {ram_rdata_b1};
+                        RDATA_B2_o = {ram_rdata_b2};
+                    end
+                    MODE_18: begin
+                        RDATA_B1_o = (FMODE1_i ? fifo_rdata[17:0] : (laddr_b1[4] ? ram_rdata_b2 : ram_rdata_b1));
+                        RDATA_B2_o = 18'b000000000000000000;
+                    end
+                    MODE_9: begin
+                        RDATA_B1_o = (FMODE1_i ? {fifo_rdata[17:0]} : (laddr_b1[4] ? {1'b0, ram_rdata_b2[16], 8'b00000000, ram_rdata_b2[7:0]} : {1'b0, ram_rdata_b1[16], 8'b00000000, ram_rdata_b1[7:0]}));
+                        RDATA_B2_o = 18'b000000000000000000;
+                    end
+                    MODE_4: begin
+                        RDATA_B2_o = 18'b000000000000000000;
+                        RDATA_B1_o[17:4] = 14'b00000000000000;
+                        RDATA_B1_o[3:0] = (laddr_b1[4] ? ram_rdata_b2[3:0] : ram_rdata_b1[3:0]);
+                    end
+                    MODE_2: begin
+                        RDATA_B2_o = 18'b000000000000000000;
+                        RDATA_B1_o[17:2] = 16'b0000000000000000;
+                        RDATA_B1_o[1:0] = (laddr_b1[4] ? ram_rdata_b2[1:0] : ram_rdata_b1[1:0]);
+                    end
+                    MODE_1: begin
+                        RDATA_B2_o = 18'b000000000000000000;
+                        RDATA_B1_o[17:1] = 17'b00000000000000000;
+                        RDATA_B1_o[0] = (laddr_b1[4] ? ram_rdata_b2[0] : ram_rdata_b1[0]);
+                    end
+                    default: begin
+                        RDATA_B1_o = ram_rdata_b1;
+                        RDATA_B2_o = ram_rdata_b2;
+                    end
+                endcase
+            end
+        endcase
+    end
+    always @(posedge sclk_a1 or negedge sreset)
+        if (sreset == 0)
+            laddr_a1 <= 1'sb0;
+        else
+            laddr_a1 <= ADDR_A1_i;
+    always @(posedge sclk_b1 or negedge sreset)
+        if (sreset == 0)
+            laddr_b1 <= 1'sb0;
+        else
+            laddr_b1 <= ADDR_B1_i;
+    assign fifo_wmode = ((WMODE_A1_i == MODE_36) ? 2'b00 : ((WMODE_A1_i == MODE_18) ? 2'b01 : ((WMODE_A1_i == MODE_9) ? 2'b10 : 2'b00)));
+    assign fifo_rmode = ((RMODE_B1_i == MODE_36) ? 2'b00 : ((RMODE_B1_i == MODE_18) ? 2'b01 : ((RMODE_B1_i == MODE_9) ? 2'b10 : 2'b00)));
+    fifo_ctl #(
+        .ADDR_WIDTH(12),
+        .FIFO_WIDTH(3'd4),
+        .DEPTH(7)
+    ) fifo36_ctl(
+        .rclk(sclk_b1),
+        .rst_R_n(flush1),
+        .wclk(sclk_a1),
+        .rst_W_n(flush1),
+        .ren(REN_B1_i),
+        .wen(ram_wen_a1),
+        .sync(SYNC_FIFO1_i),
+        .rmode(fifo_rmode),
+        .wmode(fifo_wmode),
+        .ren_o(ren_o),
+        .fflags({FULL3, FMO3, FWM3, OVERRUN3, EMPTY3, EPO3, EWM3, UNDERRUN3}),
+        .raddr(ff_raddr),
+        .waddr(ff_waddr),
+        .upaf(UPAF1_i),
+        .upae(UPAE1_i)
+    );
+    TDP18K_FIFO #(
+        .UPAF_i(UPAF1_i[10:0]),
+        .UPAE_i(UPAE1_i[10:0]),
+        .SYNC_FIFO_i(SYNC_FIFO1_i),
+        .POWERDN_i(POWERDN1_i),
+        .SLEEP_i(SLEEP1_i),
+        .PROTECT_i(PROTECT1_i)
+    )u1(
+        .RMODE_A_i(ram_rmode_a1),
+        .RMODE_B_i(ram_rmode_b1),
+        .WMODE_A_i(ram_wmode_a1),
+        .WMODE_B_i(ram_wmode_b1),
+        .WEN_A_i(ram_wen_a1),
+        .WEN_B_i(ram_wen_b1),
+        .REN_A_i(ram_ren_a1),
+        .REN_B_i(ram_ren_b1),
+        .CLK_A_i(sclk_a1),
+        .CLK_B_i(sclk_b1),
+        .BE_A_i(ram_be_a1),
+        .BE_B_i(ram_be_b1),
+        .ADDR_A_i(ram_addr_a1),
+        .ADDR_B_i(ram_addr_b1),
+        .WDATA_A_i(ram_wdata_a1),
+        .WDATA_B_i(ram_wdata_b1),
+        .RDATA_A_o(ram_rdata_a1),
+        .RDATA_B_o(ram_rdata_b1),
+        .EMPTY_o(EMPTY1),
+        .EPO_o(EPO1),
+        .EWM_o(EWM1),
+        .UNDERRUN_o(UNDERRUN1),
+        .FULL_o(FULL1),
+        .FMO_o(FMO1),
+        .FWM_o(FWM1),
+        .OVERRUN_o(OVERRUN1),
+        .FLUSH_ni(flush1),
+        .FMODE_i(ram_fmode1)
+    );
+    TDP18K_FIFO #(
+        .UPAF_i(UPAF2_i),
+        .UPAE_i(UPAE2_i),
+        .SYNC_FIFO_i(SYNC_FIFO2_i),
+        .POWERDN_i(POWERDN2_i),
+        .SLEEP_i(SLEEP2_i),
+        .PROTECT_i(PROTECT2_i)
+    )u2(
+        .RMODE_A_i(ram_rmode_a2),
+        .RMODE_B_i(ram_rmode_b2),
+        .WMODE_A_i(ram_wmode_a2),
+        .WMODE_B_i(ram_wmode_b2),
+        .WEN_A_i(ram_wen_a2),
+        .WEN_B_i(ram_wen_b2),
+        .REN_A_i(ram_ren_a2),
+        .REN_B_i(ram_ren_b2),
+        .CLK_A_i(sclk_a2),
+        .CLK_B_i(sclk_b2),
+        .BE_A_i(ram_be_a2),
+        .BE_B_i(ram_be_b2),
+        .ADDR_A_i(ram_addr_a2),
+        .ADDR_B_i(ram_addr_b2),
+        .WDATA_A_i(ram_wdata_a2),
+        .WDATA_B_i(ram_wdata_b2),
+        .RDATA_A_o(ram_rdata_a2),
+        .RDATA_B_o(ram_rdata_b2),
+        .EMPTY_o(EMPTY2),
+        .EPO_o(EPO2),
+        .EWM_o(EWM2),
+        .UNDERRUN_o(UNDERRUN2),
+        .FULL_o(FULL2),
+        .FMO_o(FMO2),
+        .FWM_o(FWM2),
+        .OVERRUN_o(OVERRUN2),
+        .FLUSH_ni(flush2),
+        .FMODE_i(ram_fmode2)
+    );
+endmodule
+
+module BRAM2x18_TDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, CLK3, CLK4, D1ADDR, D1DATA, D1EN, E1ADDR, E1DATA, E1EN, F1ADDR, F1DATA, F1EN, G1ADDR, G1DATA, G1EN, H1ADDR, H1DATA, H1EN);
+    parameter CFG_ABITS = 11;
+    parameter CFG_DBITS = 18;
+    parameter CFG_ENABLE_B = 4;
+    parameter CFG_ENABLE_D = 4;
+    parameter CFG_ENABLE_F = 4;
+    parameter CFG_ENABLE_H = 4;
+
+    parameter CLKPOL2 = 1;
+    parameter CLKPOL3 = 1;
+    parameter [18431:0] INIT0 = 18432'bx;
+    parameter [18431:0] INIT1 = 18432'bx;
+
+    localparam MODE_36 = 3'b011; // 36- or 32-bit
+    localparam MODE_18 = 3'b010; // 18- or 16-bit
+    localparam MODE_9 = 3'b001; // 9- or 8-bit
+    localparam MODE_4 = 3'b100; // 4-bit
+    localparam MODE_2 = 3'b110; // 2-bit
+    localparam MODE_1 = 3'b101; // 1-bit
+
+    input CLK1;
+    input CLK2;
+    input CLK3;
+    input CLK4;
+
+    input [CFG_ABITS-1:0] A1ADDR;
+    output [CFG_DBITS-1:0] A1DATA;
+    input A1EN;
+
+    input [CFG_ABITS-1:0] B1ADDR;
+    input [CFG_DBITS-1:0] B1DATA;
+    input [CFG_ENABLE_B-1:0] B1EN;
+
+    input [CFG_ABITS-1:0] C1ADDR;
+    output [CFG_DBITS-1:0] C1DATA;
+    input C1EN;
+
+    input [CFG_ABITS-1:0] D1ADDR;
+    input [CFG_DBITS-1:0] D1DATA;
+    input [CFG_ENABLE_D-1:0] D1EN;
+
+    input [CFG_ABITS-1:0] E1ADDR;
+    output [CFG_DBITS-1:0] E1DATA;
+    input E1EN;
+
+    input [CFG_ABITS-1:0] F1ADDR;
+    input [CFG_DBITS-1:0] F1DATA;
+    input [CFG_ENABLE_F-1:0] F1EN;
+
+    input [CFG_ABITS-1:0] G1ADDR;
+    output [CFG_DBITS-1:0] G1DATA;
+    input G1EN;
+
+    input [CFG_ABITS-1:0] H1ADDR;
+    input [CFG_DBITS-1:0] H1DATA;
+    input [CFG_ENABLE_H-1:0] H1EN;
+
+    wire FLUSH1;
+    wire FLUSH2;
+    wire SPLIT;
+
+    wire [13:CFG_ABITS] A1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] B1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] C1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] D1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] E1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] F1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] G1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] H1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+
+    wire [13:0] A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+    wire [13:0] B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+    wire [13:0] C1ADDR_TOTAL = {C1ADDR_CMPL, C1ADDR};
+    wire [13:0] D1ADDR_TOTAL = {D1ADDR_CMPL, D1ADDR};
+    wire [13:0] E1ADDR_TOTAL = {E1ADDR_CMPL, E1ADDR};
+    wire [13:0] F1ADDR_TOTAL = {F1ADDR_CMPL, F1ADDR};
+    wire [13:0] G1ADDR_TOTAL = {G1ADDR_CMPL, G1ADDR};
+    wire [13:0] H1ADDR_TOTAL = {H1ADDR_CMPL, H1ADDR};
+
+    wire [17:CFG_DBITS] A1_RDATA_CMPL;
+    wire [17:CFG_DBITS] C1_RDATA_CMPL;
+    wire [17:CFG_DBITS] E1_RDATA_CMPL;
+    wire [17:CFG_DBITS] G1_RDATA_CMPL;
+
+    wire [17:CFG_DBITS] B1_WDATA_CMPL;
+    wire [17:CFG_DBITS] D1_WDATA_CMPL;
+    wire [17:CFG_DBITS] F1_WDATA_CMPL;
+    wire [17:CFG_DBITS] H1_WDATA_CMPL;
+
+    wire [13:0] PORT_A1_ADDR;
+    wire [13:0] PORT_A2_ADDR;
+    wire [13:0] PORT_B1_ADDR;
+    wire [13:0] PORT_B2_ADDR;
+
+    case (CFG_DBITS)
+        1: begin
+            assign PORT_A1_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? E1ADDR_TOTAL : (F1EN ? F1ADDR_TOTAL : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? G1ADDR_TOTAL : (H1EN ? H1ADDR_TOTAL : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0
+            };
+        end
+
+        2: begin
+            assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 1) : (B1EN ? (B1ADDR_TOTAL << 1) : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 1) : (D1EN ? (D1ADDR_TOTAL << 1) : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 1) : (F1EN ? (F1ADDR_TOTAL << 1) : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 1) : (H1EN ? (H1ADDR_TOTAL << 1) : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0
+            };
+        end
+
+        4: begin
+            assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 2) : (B1EN ? (B1ADDR_TOTAL << 2) : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 2) : (D1EN ? (D1ADDR_TOTAL << 2) : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 2) : (F1EN ? (F1ADDR_TOTAL << 2) : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 2) : (H1EN ? (H1ADDR_TOTAL << 2) : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0
+            };
+        end
+
+        8, 9: begin
+            assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 3) : (B1EN ? (B1ADDR_TOTAL << 3) : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 3) : (D1EN ? (D1ADDR_TOTAL << 3) : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 3) : (F1EN ? (F1ADDR_TOTAL << 3) : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 3) : (H1EN ? (H1ADDR_TOTAL << 3) : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0
+            };
+        end
+
+        16, 18: begin
+            assign PORT_A1_ADDR = A1EN ? (A1ADDR_TOTAL << 4) : (B1EN ? (B1ADDR_TOTAL << 4) : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? (C1ADDR_TOTAL << 4) : (D1EN ? (D1ADDR_TOTAL << 4) : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? (E1ADDR_TOTAL << 4) : (F1EN ? (F1ADDR_TOTAL << 4) : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? (G1ADDR_TOTAL << 4) : (H1EN ? (H1ADDR_TOTAL << 4) : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0
+            };
+        end
+
+        default: begin
+            assign PORT_A1_ADDR = A1EN ? A1ADDR_TOTAL : (B1EN ? B1ADDR_TOTAL : 14'd0);
+            assign PORT_B1_ADDR = C1EN ? C1ADDR_TOTAL : (D1EN ? D1ADDR_TOTAL : 14'd0);
+            assign PORT_A2_ADDR = E1EN ? E1ADDR_TOTAL : (F1EN ? F1ADDR_TOTAL : 14'd0);
+            assign PORT_B2_ADDR = G1EN ? G1ADDR_TOTAL : (H1EN ? H1ADDR_TOTAL : 14'd0);
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0
+            };
+        end
+    endcase
+
+    assign FLUSH1 = 1'b0;
+    assign FLUSH2 = 1'b0;
+
+    wire [17:0] PORT_A1_RDATA = {A1_RDATA_CMPL, A1DATA};
+    wire [17:0] PORT_B1_RDATA = {C1_RDATA_CMPL, C1DATA};
+    wire [17:0] PORT_A2_RDATA = {E1_RDATA_CMPL, E1DATA};
+    wire [17:0] PORT_B2_RDATA = {G1_RDATA_CMPL, G1DATA};
+
+    wire [17:0] PORT_A1_WDATA = {B1_WDATA_CMPL, B1DATA};
+    wire [17:0] PORT_B1_WDATA = {D1_WDATA_CMPL, D1DATA};
+    wire [17:0] PORT_A2_WDATA = {F1_WDATA_CMPL, F1DATA};
+    wire [17:0] PORT_B2_WDATA = {H1_WDATA_CMPL, H1DATA};
+
+    wire PORT_A1_CLK = CLK1;
+    wire PORT_A2_CLK = CLK3;
+    wire PORT_B1_CLK = CLK2;
+    wire PORT_B2_CLK = CLK4;
+
+    wire PORT_A1_REN = A1EN;
+    wire PORT_A1_WEN = B1EN[0];
+    wire [CFG_ENABLE_B-1:0] PORT_A1_BE = {B1EN[1],B1EN[0]};
+
+    wire PORT_A2_REN = E1EN;
+    wire PORT_A2_WEN = F1EN[0];
+    wire [CFG_ENABLE_F-1:0] PORT_A2_BE = {F1EN[1],F1EN[0]};
+
+    wire PORT_B1_REN = C1EN;
+    wire PORT_B1_WEN = D1EN[0];
+    wire [CFG_ENABLE_D-1:0] PORT_B1_BE = {D1EN[1],D1EN[0]};
+
+    wire PORT_B2_REN = G1EN;
+    wire PORT_B2_WEN = H1EN[0];
+    wire [CFG_ENABLE_H-1:0] PORT_B2_BE = {H1EN[1],H1EN[0]};
+
+    TDP36K bram_2x18k (
+        .WDATA_A1_i(PORT_A1_WDATA),
+        .RDATA_A1_o(PORT_A1_RDATA),
+        .ADDR_A1_i(PORT_A1_ADDR),
+        .CLK_A1_i(PORT_A1_CLK),
+        .REN_A1_i(PORT_A1_REN),
+        .WEN_A1_i(PORT_A1_WEN),
+        .BE_A1_i(PORT_A1_BE),
+
+        .WDATA_A2_i(PORT_A2_WDATA),
+        .RDATA_A2_o(PORT_A2_RDATA),
+        .ADDR_A2_i(PORT_A2_ADDR),
+        .CLK_A2_i(PORT_A2_CLK),
+        .REN_A2_i(PORT_A2_REN),
+        .WEN_A2_i(PORT_A2_WEN),
+        .BE_A2_i(PORT_A2_BE),
+
+        .WDATA_B1_i(PORT_B1_WDATA),
+        .RDATA_B1_o(PORT_B1_RDATA),
+        .ADDR_B1_i(PORT_B1_ADDR),
+        .CLK_B1_i(PORT_B1_CLK),
+        .REN_B1_i(PORT_B1_REN),
+        .WEN_B1_i(PORT_B1_WEN),
+        .BE_B1_i(PORT_B1_BE),
+
+        .WDATA_B2_i(PORT_B2_WDATA),
+        .RDATA_B2_o(PORT_B2_RDATA),
+        .ADDR_B2_i(PORT_B2_ADDR),
+        .CLK_B2_i(PORT_B2_CLK),
+        .REN_B2_i(PORT_B2_REN),
+        .WEN_B2_i(PORT_B2_WEN),
+        .BE_B2_i(PORT_B2_BE),
+
+        .FLUSH1_i(FLUSH1),
+        .FLUSH2_i(FLUSH2)
+    );
+endmodule
+
+module BRAM2x18_SDP (A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN, C1ADDR, C1DATA, C1EN, CLK1, CLK2, D1ADDR, D1DATA, D1EN);
+    parameter CFG_ABITS = 11;
+    parameter CFG_DBITS = 18;
+    parameter CFG_ENABLE_B = 4;
+    parameter CFG_ENABLE_D = 4;
+
+    parameter CLKPOL2 = 1;
+    parameter CLKPOL3 = 1;
+    parameter [18431:0] INIT0 = 18432'bx;
+    parameter [18431:0] INIT1 = 18432'bx;
+
+    localparam MODE_36 = 3'b011; // 36- or 32-bit
+    localparam MODE_18 = 3'b010; // 18- or 16-bit
+    localparam MODE_9 = 3'b001; // 9- or 8-bit
+    localparam MODE_4 = 3'b100; // 4-bit
+    localparam MODE_2 = 3'b110; // 2-bit
+    localparam MODE_1 = 3'b101; // 1-bit
+
+    input CLK1;
+    input CLK2;
+
+    input [CFG_ABITS-1:0] A1ADDR;
+    output [CFG_DBITS-1:0] A1DATA;
+    input A1EN;
+
+    input [CFG_ABITS-1:0] B1ADDR;
+    input [CFG_DBITS-1:0] B1DATA;
+    input [CFG_ENABLE_B-1:0] B1EN;
+
+    input [CFG_ABITS-1:0] C1ADDR;
+    output [CFG_DBITS-1:0] C1DATA;
+    input C1EN;
+
+    input [CFG_ABITS-1:0] D1ADDR;
+    input [CFG_DBITS-1:0] D1DATA;
+    input [CFG_ENABLE_D-1:0] D1EN;
+
+    wire FLUSH1;
+    wire FLUSH2;
+
+    wire [13:CFG_ABITS] A1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] B1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] C1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+    wire [13:CFG_ABITS] D1ADDR_CMPL = {14-CFG_ABITS{1'b0}};
+
+    wire [13:0] A1ADDR_TOTAL = {A1ADDR_CMPL, A1ADDR};
+    wire [13:0] B1ADDR_TOTAL = {B1ADDR_CMPL, B1ADDR};
+    wire [13:0] C1ADDR_TOTAL = {C1ADDR_CMPL, C1ADDR};
+    wire [13:0] D1ADDR_TOTAL = {D1ADDR_CMPL, D1ADDR};
+
+    wire [17:CFG_DBITS] A1_RDATA_CMPL;
+    wire [17:CFG_DBITS] C1_RDATA_CMPL;
+
+    wire [17:CFG_DBITS] B1_WDATA_CMPL;
+    wire [17:CFG_DBITS] D1_WDATA_CMPL;
+
+    wire [13:0] PORT_A1_ADDR;
+    wire [13:0] PORT_A2_ADDR;
+    wire [13:0] PORT_B1_ADDR;
+    wire [13:0] PORT_B2_ADDR;
+
+    case (CFG_DBITS)
+        1: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL;
+            assign PORT_A2_ADDR = C1ADDR_TOTAL;
+            assign PORT_B2_ADDR = D1ADDR_TOTAL;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0
+            };
+        end
+
+        2: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL << 1;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL << 1;
+            assign PORT_A2_ADDR = C1ADDR_TOTAL << 1;
+            assign PORT_B2_ADDR = D1ADDR_TOTAL << 1;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0
+            };
+        end
+
+        4: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL << 2;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL << 2;
+            assign PORT_A2_ADDR = C1ADDR_TOTAL << 2;
+            assign PORT_B2_ADDR = D1ADDR_TOTAL << 2;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0
+            };
+        end
+
+        8, 9: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL << 3;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL << 3;
+            assign PORT_A2_ADDR = C1ADDR_TOTAL << 3;
+            assign PORT_B2_ADDR = D1ADDR_TOTAL << 3;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0
+            };
+        end
+
+        16, 18: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL << 4;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL << 4;
+            assign PORT_A2_ADDR = C1ADDR_TOTAL << 4;
+            assign PORT_B2_ADDR = D1ADDR_TOTAL << 4;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0
+            };
+        end
+
+        default: begin
+            assign PORT_A1_ADDR = A1ADDR_TOTAL;
+            assign PORT_B1_ADDR = B1ADDR_TOTAL;
+            assign PORT_A2_ADDR = D1ADDR_TOTAL;
+            assign PORT_B2_ADDR = C1ADDR_TOTAL;
+            defparam bram_2x18k.MODE_BITS = { 1'b1,
+                11'd10, 11'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0
+            };
+        end
+    endcase
+
+    assign FLUSH1 = 1'b0;
+    assign FLUSH2 = 1'b0;
+
+    wire [17:0] PORT_A1_RDATA;
+    wire [17:0] PORT_B1_RDATA;
+    wire [17:0] PORT_A2_RDATA;
+    wire [17:0] PORT_B2_RDATA;
+
+    wire [17:0] PORT_A1_WDATA;
+    wire [17:0] PORT_B1_WDATA;
+    wire [17:0] PORT_A2_WDATA;
+    wire [17:0] PORT_B2_WDATA;
+
+    // Assign read/write data - handle special case for 9bit mode
+    // parity bit for 9bit mode is placed in R/W port on bit #16
+    case (CFG_DBITS)
+        9: begin
+            assign A1DATA = {PORT_A1_RDATA[16], PORT_A1_RDATA[7:0]};
+            assign C1DATA = {PORT_A2_RDATA[16], PORT_A2_RDATA[7:0]};
+            assign PORT_A1_WDATA = {18{1'b0}};
+            assign PORT_B1_WDATA = {B1_WDATA_CMPL[17], B1DATA[8], B1_WDATA_CMPL[16:9], B1DATA[7:0]};
+            assign PORT_A2_WDATA = {18{1'b0}};
+            assign PORT_B2_WDATA = {D1_WDATA_CMPL[17], D1DATA[8], D1_WDATA_CMPL[16:9], D1DATA[7:0]};
+        end
+        default: begin
+            assign A1DATA = PORT_A1_RDATA[CFG_DBITS-1:0];
+            assign C1DATA = PORT_A2_RDATA[CFG_DBITS-1:0];
+            assign PORT_A1_WDATA = {18{1'b1}};
+            assign PORT_B1_WDATA = {B1_WDATA_CMPL, B1DATA};
+            assign PORT_A2_WDATA = {18{1'b1}};
+            assign PORT_B2_WDATA = {D1_WDATA_CMPL, D1DATA};
+
+        end
+    endcase
+
+    wire PORT_A1_CLK = CLK1;
+    wire PORT_A2_CLK = CLK2;
+    wire PORT_B1_CLK = CLK1;
+    wire PORT_B2_CLK = CLK2;
+
+    wire PORT_A1_REN = A1EN;
+    wire PORT_A1_WEN = 1'b0;
+    wire [CFG_ENABLE_B-1:0] PORT_A1_BE = {PORT_A1_WEN,PORT_A1_WEN};
+
+    wire PORT_A2_REN = C1EN;
+    wire PORT_A2_WEN = 1'b0;
+    wire [CFG_ENABLE_D-1:0] PORT_A2_BE = {PORT_A2_WEN,PORT_A2_WEN};
+
+    wire PORT_B1_REN = 1'b0;
+    wire PORT_B1_WEN = B1EN[0];
+    wire [CFG_ENABLE_B-1:0] PORT_B1_BE = {B1EN[1],B1EN[0]};
+
+    wire PORT_B2_REN = 1'b0;
+    wire PORT_B2_WEN = D1EN[0];
+    wire [CFG_ENABLE_D-1:0] PORT_B2_BE = {D1EN[1],D1EN[0]};
+
+    TDP36K  bram_2x18k (
+        .WDATA_A1_i(PORT_A1_WDATA),
+        .RDATA_A1_o(PORT_A1_RDATA),
+        .ADDR_A1_i(PORT_A1_ADDR),
+        .CLK_A1_i(PORT_A1_CLK),
+        .REN_A1_i(PORT_A1_REN),
+        .WEN_A1_i(PORT_A1_WEN),
+        .BE_A1_i(PORT_A1_BE),
+
+        .WDATA_A2_i(PORT_A2_WDATA),
+        .RDATA_A2_o(PORT_A2_RDATA),
+        .ADDR_A2_i(PORT_A2_ADDR),
+        .CLK_A2_i(PORT_A2_CLK),
+        .REN_A2_i(PORT_A2_REN),
+        .WEN_A2_i(PORT_A2_WEN),
+        .BE_A2_i(PORT_A2_BE),
+
+        .WDATA_B1_i(PORT_B1_WDATA),
+        .RDATA_B1_o(PORT_B1_RDATA),
+        .ADDR_B1_i(PORT_B1_ADDR),
+        .CLK_B1_i(PORT_B1_CLK),
+        .REN_B1_i(PORT_B1_REN),
+        .WEN_B1_i(PORT_B1_WEN),
+        .BE_B1_i(PORT_B1_BE),
+
+        .WDATA_B2_i(PORT_B2_WDATA),
+        .RDATA_B2_o(PORT_B2_RDATA),
+        .ADDR_B2_i(PORT_B2_ADDR),
+        .CLK_B2_i(PORT_B2_CLK),
+        .REN_B2_i(PORT_B2_REN),
+        .WEN_B2_i(PORT_B2_WEN),
+        .BE_B2_i(PORT_B2_BE),
+
+        .FLUSH1_i(FLUSH1),
+        .FLUSH2_i(FLUSH2)
+    );
+endmodule
+
+module \_$_mem_v2_asymmetric (RD_ADDR, RD_ARST, RD_CLK, RD_DATA, RD_EN, RD_SRST, WR_ADDR, WR_CLK, WR_DATA, WR_EN);
+    localparam CFG_ABITS = 10;
+    localparam CFG_DBITS = 36;
+    localparam CFG_ENABLE_B = 4;
+
+    localparam CLKPOL2 = 1;
+    localparam CLKPOL3 = 1;
+
+    parameter READ_ADDR_WIDTH = 11;
+    parameter READ_DATA_WIDTH = 16;
+    parameter WRITE_ADDR_WIDTH = 10;
+    parameter WRITE_DATA_WIDTH = 32;
+    parameter ABITS = 0;
+    parameter MEMID = 0;
+    parameter [36863:0] INIT = 36864'bx;
+    parameter OFFSET = 0;
+    parameter RD_ARST_VALUE = 0;
+    parameter RD_CE_OVER_SRST = 0;
+    parameter RD_CLK_ENABLE = 0;
+    parameter RD_CLK_POLARITY = 0;
+    parameter RD_COLLISION_X_MASK = 0;
+    parameter RD_INIT_VALUE = 0;
+    parameter RD_PORTS = 0;
+    parameter RD_SRST_VALUE = 0;
+    parameter RD_TRANSPARENCY_MASK = 0;
+    parameter RD_WIDE_CONTINUATION = 0;
+    parameter SIZE = 0;
+    parameter WIDTH = 0;
+    parameter WR_CLK_ENABLE = 0;
+    parameter WR_CLK_POLARITY = 0;
+    parameter WR_PORTS = 0;
+    parameter WR_PRIORITY_MASK = 0;
+    parameter WR_WIDE_CONTINUATION = 0;
+
+    localparam MODE_36  = 3'b111;   // 36 or 32-bit
+    localparam MODE_18  = 3'b110;   // 18 or 16-bit
+    localparam MODE_9   = 3'b101;   // 9 or 8-bit
+    localparam MODE_4   = 3'b100;   // 4-bit
+    localparam MODE_2   = 3'b010;   // 32-bit
+    localparam MODE_1   = 3'b001;   // 32-bit
+
+    input RD_CLK;
+    input WR_CLK;
+    input RD_ARST;
+    input RD_SRST;
+
+    input [CFG_ABITS-1:0] RD_ADDR;
+    output [CFG_DBITS-1:0] RD_DATA;
+    input RD_EN;
+
+    input [CFG_ABITS-1:0] WR_ADDR;
+    input [CFG_DBITS-1:0] WR_DATA;
+    input [CFG_ENABLE_B-1:0] WR_EN;
+
+    wire [14:0] RD_ADDR_15;
+    wire [14:0] WR_ADDR_15;
+
+    wire [35:0] DOBDO;
+
+    wire [14:CFG_ABITS] RD_ADDR_CMPL;
+    wire [14:CFG_ABITS] WR_ADDR_CMPL;
+    wire [35:CFG_DBITS] RD_DATA_CMPL;
+    wire [35:CFG_DBITS] WR_DATA_CMPL;
+
+    wire [14:0] RD_ADDR_TOTAL;
+    wire [14:0] WR_ADDR_TOTAL;
+    wire [35:0] RD_DATA_TOTAL;
+    wire [35:0] WR_DATA_TOTAL;
+
+    wire FLUSH1;
+    wire FLUSH2;
+
+    assign RD_ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+    assign WR_ADDR_CMPL = {15-CFG_ABITS{1'b0}};
+
+    assign RD_ADDR_TOTAL = {RD_ADDR_CMPL, RD_ADDR};
+    assign WR_ADDR_TOTAL = {WR_ADDR_CMPL, WR_ADDR};
+
+    assign RD_DATA_TOTAL = {RD_DATA_CMPL, RD_DATA};
+    assign WR_DATA_TOTAL = {WR_DATA_CMPL, WR_DATA};
+
+    case (CFG_DBITS)
+        1: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_1, MODE_1, MODE_1, MODE_1, 1'd0
+            };
+        end
+
+        2: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL << 1;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL << 1;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_2, MODE_2, MODE_2, MODE_2, 1'd0
+            };
+        end
+
+        4: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL << 2;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL << 2;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_4, MODE_4, MODE_4, MODE_4, 1'd0
+            };
+        end
+        8, 9: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL << 3;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL << 3;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_9, MODE_9, MODE_9, MODE_9, 1'd0
+            };
+        end
+
+        16, 18: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL << 4;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL << 4;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_18, MODE_18, MODE_18, MODE_18, 1'd0
+            };
+        end
+        32, 36: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL << 5;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL << 5;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0
+            };
+        end
+        default: begin
+            assign RD_ADDR_15 = RD_ADDR_TOTAL;
+            assign WR_ADDR_15 = WR_ADDR_TOTAL;
+            defparam bram_asymmetric.MODE_BITS = { 1'b0,
+                11'd10, 11'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0,
+                12'd10, 12'd10, 4'd0, MODE_36, MODE_36, MODE_36, MODE_36, 1'd0
+            };
+        end
+    endcase
+
+    assign FLUSH1 = 1'b0;
+    assign FLUSH2 = 1'b0;
+
+    TDP36K bram_asymmetric (
+        .RESET_ni(1'b1),
+        .WDATA_A1_i(18'h3FFFF),
+        .WDATA_A2_i(18'h3FFFF),
+        .RDATA_A1_o(RD_DATA_TOTAL[17:0]),
+        .RDATA_A2_o(RD_DATA_TOTAL[35:18]),
+        .ADDR_A1_i(RD_ADDR_15),
+        .ADDR_A2_i(RD_ADDR_15),
+        .CLK_A1_i(RD_CLK),
+        .CLK_A2_i(RD_CLK),
+        .REN_A1_i(RD_EN),
+        .REN_A2_i(RD_EN),
+        .WEN_A1_i(1'b0),
+        .WEN_A2_i(1'b0),
+        .BE_A1_i({RD_EN, RD_EN}),
+        .BE_A2_i({RD_EN, RD_EN}),
+
+        .WDATA_B1_i(WR_DATA[17:0]),
+        .WDATA_B2_i(WR_DATA[35:18]),
+        .RDATA_B1_o(DOBDO[17:0]),
+        .RDATA_B2_o(DOBDO[35:18]),
+        .ADDR_B1_i(WR_ADDR_15),
+        .ADDR_B2_i(WR_ADDR_15),
+        .CLK_B1_i(WR_CLK),
+        .CLK_B2_i(WR_CLK),
+        .REN_B1_i(1'b0),
+        .REN_B2_i(1'b0),
+        .WEN_B1_i(WR_EN[0]),
+        .WEN_B2_i(WR_EN[0]),
+        .BE_B1_i(WR_EN[1:0]),
+        .BE_B2_i(WR_EN[3:2]),
+
+        .FLUSH1_i(FLUSH1),
+        .FLUSH2_i(FLUSH2)
+    );
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_final_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_final_map.v
new file mode 100644
index 000000000..9eae617b9
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_final_map.v
@@ -0,0 +1,265 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module dsp_t1_20x18x64_cfg_ports (
+    input  [19:0] a_i,
+    input  [17:0] b_i,
+    input  [ 5:0] acc_fir_i,
+    output [37:0] z_o,
+    output [17:0] dly_b_o,
+
+    input         clock_i,
+    input         reset_i,
+
+    input  [2:0]  feedback_i,
+    input         load_acc_i,
+    input         unsigned_a_i,
+    input         unsigned_b_i,
+
+    input  [2:0]  output_select_i,
+    input         saturate_enable_i,
+    input  [5:0]  shift_right_i,
+    input         round_i,
+    input         subtract_i,
+    input         register_inputs_i
+);
+
+    parameter [19:0] COEFF_0 = 20'd0;
+    parameter [19:0] COEFF_1 = 20'd0;
+    parameter [19:0] COEFF_2 = 20'd0;
+    parameter [19:0] COEFF_3 = 20'd0;
+
+    QL_DSP2 # (
+        .MODE_BITS          ({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) _TECHMAP_REPLACE_ (
+        .a                  (a_i),
+        .b                  (b_i),
+        .acc_fir            (acc_fir_i),
+        .z                  (z_o),
+        .dly_b              (dly_b_o),
+
+        .clk                (clock_i),
+        .reset              (reset_i),
+
+        .feedback           (feedback_i),
+        .load_acc           (load_acc_i),
+        .unsigned_a         (unsigned_a_i),
+        .unsigned_b         (unsigned_b_i),
+
+        .f_mode             (1'b0), // No fracturation
+        .output_select      (output_select_i),
+        .saturate_enable    (saturate_enable_i),
+        .shift_right        (shift_right_i),
+        .round              (round_i),
+        .subtract           (subtract_i),
+        .register_inputs    (register_inputs_i)
+    );
+
+endmodule
+
+module dsp_t1_10x9x32_cfg_ports (
+    input  [ 9:0] a_i,
+    input  [ 8:0] b_i,
+    input  [ 5:0] acc_fir_i,
+    output [18:0] z_o,
+    output [ 8:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input         clock_i,
+    input         reset_i,
+
+    input  [2:0]  feedback_i,
+    input         load_acc_i,
+    input         unsigned_a_i,
+    input         unsigned_b_i,
+
+    input  [2:0]  output_select_i,
+    input         saturate_enable_i,
+    input  [5:0]  shift_right_i,
+    input         round_i,
+    input         subtract_i,
+    input         register_inputs_i
+);
+
+    parameter [9:0] COEFF_0 = 10'd0;
+    parameter [9:0] COEFF_1 = 10'd0;
+    parameter [9:0] COEFF_2 = 10'd0;
+    parameter [9:0] COEFF_3 = 10'd0;
+
+    wire [37:0] z;
+    wire [17:0] dly_b;
+
+    QL_DSP2 # (
+        .MODE_BITS          ({10'd0, COEFF_3,
+                              10'd0, COEFF_2,
+                              10'd0, COEFF_1,
+                              10'd0, COEFF_0})
+    ) _TECHMAP_REPLACE_ (
+        .a                  ({10'd0, a_i}),
+        .b                  ({ 9'd0, b_i}),
+        .acc_fir            (acc_fir_i),
+        .z                  (z),
+        .dly_b              (dly_b),
+
+        .clk                (clock_i),
+        .reset              (reset_i),
+
+        .feedback           (feedback_i),
+        .load_acc           (load_acc_i),
+        .unsigned_a         (unsigned_a_i),
+        .unsigned_b         (unsigned_b_i),
+
+        .f_mode             (1'b1), // Enable fractuation, Use the lower half
+        .output_select      (output_select_i),
+        .saturate_enable    (saturate_enable_i),
+        .shift_right        (shift_right_i),
+        .round              (round_i),
+        .subtract           (subtract_i),
+        .register_inputs    (register_inputs_i)
+    );
+
+    assign z_o = z[18:0];
+    assign dly_b_o = dly_b_o[8:0];
+
+endmodule
+
+module dsp_t1_20x18x64_cfg_params (
+    input  [19:0] a_i,
+    input  [17:0] b_i,
+    input  [ 5:0] acc_fir_i,
+    output [37:0] z_o,
+    output [17:0] dly_b_o,
+
+    input         clock_i,
+    input         reset_i,
+
+    input  [2:0]  feedback_i,
+    input         load_acc_i,
+    input         unsigned_a_i,
+    input         unsigned_b_i,
+    input         subtract_i
+);
+
+    parameter [19:0] COEFF_0 = 20'd0;
+    parameter [19:0] COEFF_1 = 20'd0;
+    parameter [19:0] COEFF_2 = 20'd0;
+    parameter [19:0] COEFF_3 = 20'd0;
+
+    parameter [2:0] OUTPUT_SELECT   = 3'd0;
+    parameter [0:0] SATURATE_ENABLE = 1'd0;
+    parameter [5:0] SHIFT_RIGHT     = 6'd0;
+    parameter [0:0] ROUND           = 1'd0;
+    parameter [0:0] REGISTER_INPUTS = 1'd0;
+
+    QL_DSP3 # (
+        .MODE_BITS ({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            1'b0, // Not fractured
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) _TECHMAP_REPLACE_ (
+        .a                  (a_i),
+        .b                  (b_i),
+        .acc_fir            (acc_fir_i),
+        .z                  (z_o),
+        .dly_b              (dly_b_o),
+
+        .clk                (clock_i),
+        .reset              (reset_i),
+
+        .feedback           (feedback_i),
+        .load_acc           (load_acc_i),
+        .unsigned_a         (unsigned_a_i),
+        .unsigned_b         (unsigned_b_i),
+        .subtract           (subtract_i)
+    );
+
+endmodule
+
+module dsp_t1_10x9x32_cfg_params (
+    input  [ 9:0] a_i,
+    input  [ 8:0] b_i,
+    input  [ 5:0] acc_fir_i,
+    output [18:0] z_o,
+    output [ 8:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input         clock_i,
+    input         reset_i,
+
+    input  [2:0]  feedback_i,
+    input         load_acc_i,
+    input         unsigned_a_i,
+    input         unsigned_b_i,
+    input         subtract_i
+);
+
+    parameter [9:0] COEFF_0 = 10'd0;
+    parameter [9:0] COEFF_1 = 10'd0;
+    parameter [9:0] COEFF_2 = 10'd0;
+    parameter [9:0] COEFF_3 = 10'd0;
+
+    parameter [2:0] OUTPUT_SELECT   = 3'd0;
+    parameter [0:0] SATURATE_ENABLE = 1'd0;
+    parameter [5:0] SHIFT_RIGHT     = 6'd0;
+    parameter [0:0] ROUND           = 1'd0;
+    parameter [0:0] REGISTER_INPUTS = 1'd0;
+
+    wire [37:0] z;
+    wire [17:0] dly_b;
+
+    QL_DSP3 # (
+        .MODE_BITS  ({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            1'b1, // Fractured
+            10'd0, COEFF_3,
+            10'd0, COEFF_2,
+            10'd0, COEFF_1,
+            10'd0, COEFF_0
+        })
+    ) _TECHMAP_REPLACE_ (
+        .a                  ({10'd0, a_i}),
+        .b                  ({ 9'd0, b_i}),
+        .acc_fir            (acc_fir_i),
+        .z                  (z),
+        .dly_b              (dly_b),
+
+        .clk                (clock_i),
+        .reset              (reset_i),
+
+        .feedback           (feedback_i),
+        .load_acc           (load_acc_i),
+        .unsigned_a         (unsigned_a_i),
+        .unsigned_b         (unsigned_b_i),
+        .subtract           (subtract_i)
+    );
+
+    assign z_o = z[18:0];
+    assign dly_b_o = dly_b_o[8:0];
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_map.v
new file mode 100644
index 000000000..bb9f05283
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_map.v
@@ -0,0 +1,147 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module \$__QL_MUL20X18 (input [19:0] A, input [17:0] B, output [37:0] Y);
+    parameter A_SIGNED = 0;
+    parameter B_SIGNED = 0;
+    parameter A_WIDTH = 0;
+    parameter B_WIDTH = 0;
+    parameter Y_WIDTH = 0;
+
+    wire [19:0] a;
+    wire [17:0] b;
+    wire [37:0] z;
+
+    assign a = (A_WIDTH == 20) ? A :
+               (A_SIGNED) ? {{(20 - A_WIDTH){A[A_WIDTH-1]}}, A} :
+                            {{(20 - A_WIDTH){1'b0}},         A};
+
+    assign b = (B_WIDTH == 18) ? B :
+               (B_SIGNED) ? {{(18 - B_WIDTH){B[B_WIDTH-1]}}, B} :
+                            {{(18 - B_WIDTH){1'b0}},         B};
+
+    generate if (`USE_DSP_CFG_PARAMS == 0) begin
+        (* is_inferred=1 *)
+        dsp_t1_20x18x64_cfg_ports _TECHMAP_REPLACE_ (
+            .a_i                (a),
+            .b_i                (b),
+            .acc_fir_i          (6'd0),
+            .z_o                (z),
+
+            .feedback_i         (3'd0),
+            .load_acc_i         (1'b0),
+            .unsigned_a_i       (!A_SIGNED),
+            .unsigned_b_i       (!B_SIGNED),
+
+            .output_select_i    (3'd0),
+            .saturate_enable_i  (1'b0),
+            .shift_right_i      (6'd0),
+            .round_i            (1'b0),
+            .subtract_i         (1'b0),
+            .register_inputs_i  (1'b0)
+        );
+    end else begin
+        (* is_inferred=1 *)
+        dsp_t1_20x18x64_cfg_params #(
+            .OUTPUT_SELECT      (3'd0),
+            .SATURATE_ENABLE    (1'b0),
+            .SHIFT_RIGHT        (6'd0),
+            .ROUND              (1'b0),
+            .REGISTER_INPUTS    (1'b0)
+        ) TECHMAP_REPLACE_ (
+            .a_i                (a),
+            .b_i                (b),
+            .acc_fir_i          (6'd0),
+            .z_o                (z),
+
+            .feedback_i         (3'd0),
+            .load_acc_i         (1'b0),
+            .unsigned_a_i       (!A_SIGNED),
+            .unsigned_b_i       (!B_SIGNED),
+
+            .subtract_i         (1'b0)
+        );
+    end endgenerate
+
+    assign Y = z;
+
+endmodule
+
+module \$__QL_MUL10X9 (input [9:0] A, input [8:0] B, output [18:0] Y);
+    parameter A_SIGNED = 0;
+    parameter B_SIGNED = 0;
+    parameter A_WIDTH = 0;
+    parameter B_WIDTH = 0;
+    parameter Y_WIDTH = 0;
+
+    wire [ 9:0] a;
+    wire [ 8:0] b;
+    wire [18:0] z;
+
+    assign a = (A_WIDTH == 10) ? A :
+               (A_SIGNED) ? {{(10 - A_WIDTH){A[A_WIDTH-1]}}, A} :
+                            {{(10 - A_WIDTH){1'b0}},         A};
+
+    assign b = (B_WIDTH ==  9) ? B :
+               (B_SIGNED) ? {{( 9 - B_WIDTH){B[B_WIDTH-1]}}, B} :
+                            {{( 9 - B_WIDTH){1'b0}},         B};
+
+    generate if (`USE_DSP_CFG_PARAMS == 0) begin
+        (* is_inferred=1 *)
+        dsp_t1_10x9x32_cfg_ports _TECHMAP_REPLACE_ (
+            .a_i                (a),
+            .b_i                (b),
+            .acc_fir_i          (6'd0),
+            .z_o                (z),
+
+            .feedback_i         (3'd0),
+            .load_acc_i         (1'b0),
+            .unsigned_a_i       (!A_SIGNED),
+            .unsigned_b_i       (!B_SIGNED),
+
+            .output_select_i    (3'd0),
+            .saturate_enable_i  (1'b0),
+            .shift_right_i      (6'd0),
+            .round_i            (1'b0),
+            .subtract_i         (1'b0),
+            .register_inputs_i  (1'b0)
+        );
+    end else begin
+        (* is_inferred=1 *)
+        dsp_t1_10x9x32_cfg_params #(
+            .OUTPUT_SELECT      (3'd0),
+            .SATURATE_ENABLE    (1'b0),
+            .SHIFT_RIGHT        (6'd0),
+            .ROUND              (1'b0),
+            .REGISTER_INPUTS    (1'b0)
+        ) TECHMAP_REPLACE_ (
+            .a_i                (a),
+            .b_i                (b),
+            .acc_fir_i          (6'd0),
+            .z_o                (z),
+
+            .feedback_i         (3'd0),
+            .load_acc_i         (1'b0),
+            .unsigned_a_i       (!A_SIGNED),
+            .unsigned_b_i       (!B_SIGNED),
+
+            .subtract_i         (1'b0)
+        );
+    end endgenerate
+
+    assign Y = z;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_sim.v b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_sim.v
new file mode 100644
index 000000000..14ec751dd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/dsp_sim.v
@@ -0,0 +1,2423 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
+
+(* blackbox *)
+module QL_DSP1 (
+    input wire [19:0] a,
+    input wire [17:0] b,
+    (* clkbuf_sink *)
+    input wire clk0,
+    (* clkbuf_sink *)
+    input wire clk1,
+    input wire [ 1:0] feedback0,
+    input wire [ 1:0] feedback1,
+    input wire        load_acc0,
+    input wire        load_acc1,
+    input wire        reset0,
+    input wire        reset1,
+    output reg [37:0] z
+);
+    parameter MODE_BITS = 27'b00000000000000000000000000;
+endmodule  /* QL_DSP1 */
+
+
+
+// ---------------------------------------- //
+// ----- DSP cells simulation modules ----- //
+// --------- Control bits in ports -------- //
+// ---------------------------------------- //
+
+module QL_DSP2 ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    input  wire [ 5:0] acc_fir,
+    output wire [37:0] z,
+    output wire [17:0] dly_b,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       load_acc,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+
+    input  wire       f_mode,
+    input  wire [2:0] output_select,
+    input  wire       saturate_enable,
+    input  wire [5:0] shift_right,
+    input  wire       round,
+    input  wire       subtract,
+    input  wire       register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam NBITS_ACC = 64;
+    localparam NBITS_A = 20;
+    localparam NBITS_B = 18;
+    localparam NBITS_Z = 38;
+
+    wire [NBITS_Z-1:0] dsp_full_z;
+    wire [(NBITS_Z/2)-1:0] dsp_frac0_z;
+    wire [(NBITS_Z/2)-1:0] dsp_frac1_z;
+
+    wire [NBITS_B-1:0] dsp_full_dly_b;
+    wire [(NBITS_B/2)-1:0] dsp_frac0_dly_b;
+    wire [(NBITS_B/2)-1:0] dsp_frac1_dly_b;
+
+    assign z = f_mode ? {dsp_frac1_z, dsp_frac0_z} : dsp_full_z;
+    assign dly_b = f_mode ? {dsp_frac1_dly_b, dsp_frac0_dly_b} : dsp_full_dly_b;
+
+    // Output used when fmode == 1
+        dsp_t1_sim_cfg_ports #(
+        .NBITS_A(NBITS_A/2),
+            .NBITS_B(NBITS_B/2),
+            .NBITS_ACC(NBITS_ACC/2),
+            .NBITS_Z(NBITS_Z/2)
+        ) dsp_frac0 (
+            .a_i(a[(NBITS_A/2)-1:0]),
+            .b_i(b[(NBITS_B/2)-1:0]),
+            .z_o(dsp_frac0_z),
+            .dly_b_o(dsp_frac0_dly_b),
+
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .saturate_enable_i(saturate_enable),
+            .output_select_i(output_select),
+            .round_i(round),
+            .shift_right_i(shift_right),
+            .subtract_i(subtract),
+            .register_inputs_i(register_inputs),
+            .coef_0_i(COEFF_0[(NBITS_A/2)-1:0]),
+            .coef_1_i(COEFF_1[(NBITS_A/2)-1:0]),
+            .coef_2_i(COEFF_2[(NBITS_A/2)-1:0]),
+            .coef_3_i(COEFF_3[(NBITS_A/2)-1:0])
+        );
+
+    // Output used when fmode == 1
+        dsp_t1_sim_cfg_ports #(
+        .NBITS_A(NBITS_A/2),
+            .NBITS_B(NBITS_B/2),
+            .NBITS_ACC(NBITS_ACC/2),
+            .NBITS_Z(NBITS_Z/2)
+        ) dsp_frac1 (
+            .a_i(a[NBITS_A-1:NBITS_A/2]),
+            .b_i(b[NBITS_B-1:NBITS_B/2]),
+            .z_o(dsp_frac1_z),
+            .dly_b_o(dsp_frac1_dly_b),
+
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .saturate_enable_i(saturate_enable),
+            .output_select_i(output_select),
+            .round_i(round),
+            .shift_right_i(shift_right),
+            .subtract_i(subtract),
+            .register_inputs_i(register_inputs),
+            .coef_0_i(COEFF_0[NBITS_A-1:NBITS_A/2]),
+            .coef_1_i(COEFF_1[NBITS_A-1:NBITS_A/2]),
+            .coef_2_i(COEFF_2[NBITS_A-1:NBITS_A/2]),
+            .coef_3_i(COEFF_3[NBITS_A-1:NBITS_A/2])
+        );
+
+    // Output used when fmode == 0
+        dsp_t1_sim_cfg_ports #(
+            .NBITS_A(NBITS_A),
+            .NBITS_B(NBITS_B),
+            .NBITS_ACC(NBITS_ACC),
+            .NBITS_Z(NBITS_Z)
+        ) dsp_full (
+            .a_i(a),
+            .b_i(b),
+            .z_o(dsp_full_z),
+            .dly_b_o(dsp_full_dly_b),
+
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .saturate_enable_i(saturate_enable),
+            .output_select_i(output_select),
+            .round_i(round),
+            .shift_right_i(shift_right),
+            .subtract_i(subtract),
+            .register_inputs_i(register_inputs),
+            .coef_0_i(COEFF_0),
+            .coef_1_i(COEFF_1),
+            .coef_2_i(COEFF_2),
+            .coef_3_i(COEFF_3)
+        );
+endmodule
+
+module QL_DSP2_MULT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+
+    input  wire       f_mode,
+    input  wire [2:0] output_select,
+    input  wire       register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .reset(reset),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .output_select(output_select),      // unregistered output: a * b (0)
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULT_REGIN ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+
+    input  wire       f_mode,
+    input  wire [2:0] output_select,
+    input  wire       register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // unregistered output: a * b (0)
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module QL_DSP2_MULT_REGOUT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+    input  wire       f_mode,
+    input  wire [2:0] output_select,
+    input  wire       register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: a * b (4)
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULT_REGIN_REGOUT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+    input  wire       f_mode,
+    input  wire [2:0] output_select,
+    input  wire       register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: a * b (4)
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTADD (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .reset(reset),
+
+        .output_select(output_select),      // unregistered output: ACCin (2, 3)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTADD_REGIN (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // unregistered output: ACCin (2, 3)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTADD_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: ACCin (6, 7)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTADD_REGIN_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: ACCin (6, 7)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTACC (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire        load_acc,
+    input  wire [ 2:0] feedback,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // unregistered output: ACCout (1)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTACC_REGIN (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // unregistered output: ACCout (1)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTACC_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: ACCout (5)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // unregistered inputs
+    );
+endmodule
+
+module QL_DSP2_MULTACC_REGIN_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+
+    input  wire        f_mode,
+    input  wire [ 2:0] output_select,
+    input  wire        saturate_enable,
+    input  wire [ 5:0] shift_right,
+    input  wire        round,
+    input  wire        subtract,
+    input  wire        register_inputs
+);
+
+    parameter [79:0] MODE_BITS = 80'd0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .f_mode(f_mode),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+
+        .output_select(output_select),      // registered output: ACCout (5)
+        .saturate_enable(saturate_enable),
+        .shift_right(shift_right),
+        .round(round),
+        .subtract(subtract),
+        .register_inputs(register_inputs)   // registered inputs
+    );
+endmodule
+
+module dsp_t1_20x18x64_cfg_ports (
+    input  wire [19:0] a_i,
+    input  wire [17:0] b_i,
+    input  wire [ 5:0] acc_fir_i,
+    output wire [37:0] z_o,
+    output wire [17:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input  wire        clock_i,
+    input  wire        reset_i,
+
+    input  wire [ 2:0] feedback_i,
+    input  wire        load_acc_i,
+    input  wire        unsigned_a_i,
+    input  wire        unsigned_b_i,
+
+    input  wire [ 2:0] output_select_i,
+    input  wire        saturate_enable_i,
+    input  wire [ 5:0] shift_right_i,
+    input  wire        round_i,
+    input  wire        subtract_i,
+    input  wire        register_inputs_i
+);
+
+    parameter [19:0] COEFF_0 = 20'd0;
+    parameter [19:0] COEFF_1 = 20'd0;
+    parameter [19:0] COEFF_2 = 20'd0;
+    parameter [19:0] COEFF_3 = 20'd0;
+
+    QL_DSP2 #(
+        .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0})
+    ) dsp (
+        .a(a_i),
+        .b(b_i),
+        .z(z_o),
+        .dly_b(dly_b_o),
+
+        .f_mode(1'b0),  // 20x18x64 DSP
+
+        .acc_fir(acc_fir_i),
+        .feedback(feedback_i),
+        .load_acc(load_acc_i),
+
+        .unsigned_a(unsigned_a_i),
+        .unsigned_b(unsigned_b_i),
+
+        .clk(clock_i),
+        .reset(reset_i),
+
+        .saturate_enable(saturate_enable_i),
+        .output_select(output_select_i),
+        .round(round_i),
+        .shift_right(shift_right_i),
+        .subtract(subtract_i),
+        .register_inputs(register_inputs_i)
+    );
+endmodule
+
+module dsp_t1_10x9x32_cfg_ports (
+    input  wire [ 9:0] a_i,
+    input  wire [ 8:0] b_i,
+    input  wire [ 5:0] acc_fir_i,
+    output wire [18:0] z_o,
+    output wire [ 8:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input  wire        clock_i,
+    input  wire        reset_i,
+
+    input  wire [ 2:0] feedback_i,
+    input  wire        load_acc_i,
+    input  wire        unsigned_a_i,
+    input  wire        unsigned_b_i,
+
+    input  wire [ 2:0] output_select_i,
+    input  wire        saturate_enable_i,
+    input  wire [ 5:0] shift_right_i,
+    input  wire        round_i,
+    input  wire        subtract_i,
+    input  wire        register_inputs_i
+);
+
+    parameter [9:0] COEFF_0 = 10'd0;
+    parameter [9:0] COEFF_1 = 10'd0;
+    parameter [9:0] COEFF_2 = 10'd0;
+    parameter [9:0] COEFF_3 = 10'd0;
+
+    wire [18:0] z_rem;
+    wire [8:0] dly_b_rem;
+
+    QL_DSP2 #(
+        .MODE_BITS({10'd0, COEFF_3,
+                    10'd0, COEFF_2,
+                    10'd0, COEFF_1,
+                    10'd0, COEFF_0})
+    ) dsp (
+        .a({10'd0, a_i}),
+        .b({9'd0, b_i}),
+        .z({z_rem, z_o}),
+        .dly_b({dly_b_rem, dly_b_o}),
+
+        .f_mode(1'b1),  // 10x9x32 DSP
+
+        .acc_fir(acc_fir_i),
+        .feedback(feedback_i),
+        .load_acc(load_acc_i),
+
+        .unsigned_a(unsigned_a_i),
+        .unsigned_b(unsigned_b_i),
+
+        .clk(clock_i),
+        .reset(reset_i),
+
+        .saturate_enable(saturate_enable_i),
+        .output_select(output_select_i),
+        .round(round_i),
+        .shift_right(shift_right_i),
+        .subtract(subtract_i),
+        .register_inputs(register_inputs_i)
+    );
+endmodule
+
+module dsp_t1_sim_cfg_ports # (
+    parameter NBITS_ACC  = 64,
+    parameter NBITS_A    = 20,
+    parameter NBITS_B    = 18,
+    parameter NBITS_Z    = 38
+)(
+    input  wire [NBITS_A-1:0] a_i,
+    input  wire [NBITS_B-1:0] b_i,
+    output wire [NBITS_Z-1:0] z_o,
+    output reg  [NBITS_B-1:0] dly_b_o,
+
+    input  wire [5:0]         acc_fir_i,
+    input  wire [2:0]         feedback_i,
+    input  wire               load_acc_i,
+
+    input  wire               unsigned_a_i,
+    input  wire               unsigned_b_i,
+
+    input  wire               clock_i,
+    input  wire               s_reset,
+
+    input  wire               saturate_enable_i,
+    input  wire [2:0]         output_select_i,
+    input  wire               round_i,
+    input  wire [5:0]         shift_right_i,
+    input  wire               subtract_i,
+    input  wire               register_inputs_i,
+    input  wire [NBITS_A-1:0] coef_0_i,
+    input  wire [NBITS_A-1:0] coef_1_i,
+    input  wire [NBITS_A-1:0] coef_2_i,
+    input  wire [NBITS_A-1:0] coef_3_i
+);
+
+// FIXME: The version of Icarus Verilog from Conda seems not to recognize the
+// $error macro. Disable this sanity check for now because of that.
+`ifndef __ICARUS__
+    if (NBITS_ACC < NBITS_A + NBITS_B)
+        $error("NBITS_ACC must be > NBITS_A + NBITS_B");
+`endif
+
+    // Input registers
+    reg  [NBITS_A-1:0]  r_a;
+    reg  [NBITS_B-1:0]  r_b;
+    reg  [5:0]          r_acc_fir;
+    reg                 r_unsigned_a;
+    reg                 r_unsigned_b;
+    reg                 r_load_acc;
+    reg  [2:0]          r_feedback;
+    reg  [5:0]          r_shift_d1;
+    reg  [5:0]          r_shift_d2;
+    reg         r_subtract;
+    reg         r_sat;
+    reg         r_rnd;
+    reg [NBITS_ACC-1:0] acc;
+
+    initial begin
+        r_a          <= 0;
+        r_b          <= 0;
+
+        r_acc_fir    <= 0;
+        r_unsigned_a <= 0;
+        r_unsigned_b <= 0;
+        r_feedback   <= 0;
+        r_shift_d1   <= 0;
+        r_shift_d2   <= 0;
+        r_subtract   <= 0;
+        r_load_acc   <= 0;
+        r_sat        <= 0;
+        r_rnd        <= 0;
+    end
+
+    always @(posedge clock_i or posedge s_reset) begin
+        if (s_reset) begin
+
+            r_a <= 'h0;
+            r_b <= 'h0;
+
+            r_acc_fir    <= 0;
+            r_unsigned_a <= 0;
+            r_unsigned_b <= 0;
+            r_feedback   <= 0;
+            r_shift_d1   <= 0;
+            r_shift_d2   <= 0;
+            r_subtract   <= 0;
+            r_load_acc   <= 0;
+            r_sat    <= 0;
+            r_rnd    <= 0;
+
+        end else begin
+
+            r_a <= a_i;
+            r_b <= b_i;
+
+            r_acc_fir    <= acc_fir_i;
+            r_unsigned_a <= unsigned_a_i;
+            r_unsigned_b <= unsigned_b_i;
+            r_feedback   <= feedback_i;
+            r_shift_d1   <= shift_right_i;
+            r_shift_d2   <= r_shift_d1;
+            r_subtract   <= subtract_i;
+            r_load_acc   <= load_acc_i;
+            r_sat    <= r_sat;
+            r_rnd    <= r_rnd;
+
+        end
+    end
+
+    // Registered / non-registered input path select
+    wire [NBITS_A-1:0]  a = register_inputs_i ? r_a : a_i;
+    wire [NBITS_B-1:0]  b = register_inputs_i ? r_b : b_i;
+
+    wire [5:0] acc_fir = register_inputs_i ? r_acc_fir : acc_fir_i;
+    wire       unsigned_a = register_inputs_i ? r_unsigned_a : unsigned_a_i;
+    wire       unsigned_b = register_inputs_i ? r_unsigned_b : unsigned_b_i;
+    wire [2:0] feedback   = register_inputs_i ? r_feedback   : feedback_i;
+    wire       load_acc   = register_inputs_i ? r_load_acc   : load_acc_i;
+    wire       subtract   = register_inputs_i ? r_subtract   : subtract_i;
+    wire       sat    = register_inputs_i ? r_sat : saturate_enable_i;
+    wire       rnd    = register_inputs_i ? r_rnd : round_i;
+
+    // Shift right control
+    wire [5:0] shift_d1 = register_inputs_i ? r_shift_d1 : shift_right_i;
+    wire [5:0] shift_d2 = output_select_i[1] ? shift_d1 : r_shift_d2;
+
+    // Multiplier
+    wire unsigned_mode = unsigned_a & unsigned_b;
+    wire [NBITS_A-1:0] mult_a;
+    assign mult_a = (feedback == 3'h0) ?   a :
+                    (feedback == 3'h1) ?   a :
+                    (feedback == 3'h2) ?   a :
+                    (feedback == 3'h3) ?   acc[NBITS_A-1:0] :
+                    (feedback == 3'h4) ?   coef_0_i :
+                    (feedback == 3'h5) ?   coef_1_i :
+                    (feedback == 3'h6) ?   coef_2_i :
+                       coef_3_i;    // if feedback == 3'h7
+
+    wire [NBITS_B-1:0] mult_b = (feedback == 2'h2) ? {NBITS_B{1'b0}}  : b;
+
+    wire [NBITS_A-1:0] mult_sgn_a = mult_a[NBITS_A-1];
+    wire [NBITS_A-1:0] mult_mag_a = (mult_sgn_a && !unsigned_a) ? (~mult_a + 1) : mult_a;
+    wire [NBITS_B-1:0] mult_sgn_b = mult_b[NBITS_B-1];
+    wire [NBITS_B-1:0] mult_mag_b = (mult_sgn_b && !unsigned_b) ? (~mult_b + 1) : mult_b;
+
+    wire [NBITS_A+NBITS_B-1:0] mult_mag = mult_mag_a * mult_mag_b;
+    wire mult_sgn = (mult_sgn_a && !unsigned_a) ^ (mult_sgn_b && !unsigned_b);
+
+    wire [NBITS_A+NBITS_B-1:0] mult = (unsigned_a && unsigned_b) ?
+        (mult_a * mult_b) : (mult_sgn ? (~mult_mag + 1) : mult_mag);
+
+    // Sign extension
+    wire [NBITS_ACC-1:0] mult_xtnd = unsigned_mode ?
+        {{(NBITS_ACC-NBITS_A-NBITS_B){1'b0}},                    mult[NBITS_A+NBITS_B-1:0]} :
+        {{(NBITS_ACC-NBITS_A-NBITS_B){mult[NBITS_A+NBITS_B-1]}}, mult[NBITS_A+NBITS_B-1:0]};
+
+    // Adder
+    wire [NBITS_ACC-1:0] acc_fir_int = unsigned_a ? {{(NBITS_ACC-NBITS_A){1'b0}},         a} :
+                                                    {{(NBITS_ACC-NBITS_A){a[NBITS_A-1]}}, a} ;
+
+    wire [NBITS_ACC-1:0] add_a = (subtract) ? (~mult_xtnd + 1) : mult_xtnd;
+    wire [NBITS_ACC-1:0] add_b = (feedback_i == 3'h0) ? acc :
+                                 (feedback_i == 3'h1) ? {{NBITS_ACC}{1'b0}} : (acc_fir_int << acc_fir);
+
+    wire [NBITS_ACC-1:0] add_o = add_a + add_b;
+
+    // Accumulator
+    initial acc <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset) acc <= 'h0;
+        else begin
+            if (load_acc)
+                acc <= add_o;
+            else
+                acc <= acc;
+        end
+
+    // Adder/accumulator output selection
+    wire [NBITS_ACC-1:0] acc_out = (output_select_i[1]) ? add_o : acc;
+
+    // Round, shift, saturate
+    wire [NBITS_ACC-1:0] acc_rnd = (rnd && (shift_right_i != 0)) ? (acc_out + ({{(NBITS_ACC-1){1'b0}}, 1'b1} << (shift_right_i - 1))) :
+                                                                    acc_out;
+
+    wire [NBITS_ACC-1:0] acc_shr = (unsigned_mode) ? (acc_rnd  >> shift_right_i) :
+                                                     (acc_rnd >>> shift_right_i);
+
+    wire [NBITS_ACC-1:0] acc_sat_u = (acc_shr[NBITS_ACC-1:NBITS_Z] != 0) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{NBITS_Z{1'b1}}} :
+                                                                           {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}};
+
+    wire [NBITS_ACC-1:0] acc_sat_s = ((|acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b0) ||
+                                      (&acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b1)) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}} :
+                                                                                   {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_ACC-1],{NBITS_Z-1{~acc_shr[NBITS_ACC-1]}}}};
+
+    wire [NBITS_ACC-1:0] acc_sat = (sat) ? ((unsigned_mode) ? acc_sat_u : acc_sat_s) : acc_shr;
+
+    // Output signals
+    wire [NBITS_Z-1:0]  z0;
+    reg  [NBITS_Z-1:0]  z1;
+    wire [NBITS_Z-1:0]  z2;
+
+    assign z0 = mult_xtnd[NBITS_Z-1:0];
+    assign z2 = acc_sat[NBITS_Z-1:0];
+
+    initial z1 <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset)
+            z1 <= 0;
+        else begin
+            z1 <= (output_select_i == 3'b100) ? z0 : z2;
+        end
+
+    // Output mux
+    assign z_o = (output_select_i == 3'h0) ?   z0 :
+                 (output_select_i == 3'h1) ?   z2 :
+                 (output_select_i == 3'h2) ?   z2 :
+                 (output_select_i == 3'h3) ?   z2 :
+                 (output_select_i == 3'h4) ?   z1 :
+                 (output_select_i == 3'h5) ?   z1 :
+                 (output_select_i == 3'h6) ?   z1 :
+                           z1;  // if output_select_i == 3'h7
+
+    // B input delayed passthrough
+    initial dly_b_o <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset)
+            dly_b_o <= 0;
+        else
+            dly_b_o <= b_i;
+
+endmodule
+
+
+
+// ---------------------------------------- //
+// ----- DSP cells simulation modules ----- //
+// ------ Control bits in parameters ------ //
+// ---------------------------------------- //
+
+module QL_DSP3 ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    input  wire [ 5:0] acc_fir,
+    output wire [37:0] z,
+    output wire [17:0] dly_b,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       load_acc,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b,
+    input  wire       subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    localparam NBITS_ACC = 64;
+    localparam NBITS_A = 20;
+    localparam NBITS_B = 18;
+    localparam NBITS_Z = 38;
+
+    // Fractured
+    generate if(F_MODE == 1'b1) begin
+
+        wire [(NBITS_Z/2)-1:0] dsp_frac0_z;
+        wire [(NBITS_Z/2)-1:0] dsp_frac1_z;
+
+        wire [(NBITS_B/2)-1:0] dsp_frac0_dly_b;
+        wire [(NBITS_B/2)-1:0] dsp_frac1_dly_b;
+
+        dsp_t1_sim_cfg_params #(
+            .NBITS_A            (NBITS_A/2),
+            .NBITS_B            (NBITS_B/2),
+            .NBITS_ACC          (NBITS_ACC/2),
+            .NBITS_Z            (NBITS_Z/2),
+            .OUTPUT_SELECT      (OUTPUT_SELECT),
+            .SATURATE_ENABLE    (SATURATE_ENABLE),
+            .SHIFT_RIGHT        (SHIFT_RIGHT),
+            .ROUND              (ROUND),
+            .REGISTER_INPUTS    (REGISTER_INPUTS)
+        ) dsp_frac0 (
+            .a_i(a[(NBITS_A/2)-1:0]),
+            .b_i(b[(NBITS_B/2)-1:0]),
+            .z_o(dsp_frac0_z),
+            .dly_b_o(dsp_frac0_dly_b),
+
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .subtract_i(subtract),
+            .coef_0_i(COEFF_0[(NBITS_A/2)-1:0]),
+            .coef_1_i(COEFF_1[(NBITS_A/2)-1:0]),
+            .coef_2_i(COEFF_2[(NBITS_A/2)-1:0]),
+            .coef_3_i(COEFF_3[(NBITS_A/2)-1:0])
+        );
+
+        dsp_t1_sim_cfg_params #(
+            .NBITS_A            (NBITS_A/2),
+            .NBITS_B            (NBITS_B/2),
+            .NBITS_ACC          (NBITS_ACC/2),
+            .NBITS_Z            (NBITS_Z/2),
+            .OUTPUT_SELECT      (OUTPUT_SELECT),
+            .SATURATE_ENABLE    (SATURATE_ENABLE),
+            .SHIFT_RIGHT        (SHIFT_RIGHT),
+            .ROUND              (ROUND),
+            .REGISTER_INPUTS    (REGISTER_INPUTS)
+        ) dsp_frac1 (
+            .a_i(a[NBITS_A-1:NBITS_A/2]),
+            .b_i(b[NBITS_B-1:NBITS_B/2]),
+            .z_o(dsp_frac1_z),
+            .dly_b_o(dsp_frac1_dly_b),
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .subtract_i(subtract),
+            .coef_0_i(COEFF_0[NBITS_A-1:NBITS_A/2]),
+            .coef_1_i(COEFF_1[NBITS_A-1:NBITS_A/2]),
+            .coef_2_i(COEFF_2[NBITS_A-1:NBITS_A/2]),
+            .coef_3_i(COEFF_3[NBITS_A-1:NBITS_A/2])
+        );
+
+        assign z = {dsp_frac1_z, dsp_frac0_z};
+        assign dly_b = {dsp_frac1_dly_b, dsp_frac0_dly_b};
+
+    // Whole
+    end else begin
+
+        dsp_t1_sim_cfg_params #(
+            .NBITS_A            (NBITS_A),
+            .NBITS_B            (NBITS_B),
+            .NBITS_ACC          (NBITS_ACC),
+            .NBITS_Z            (NBITS_Z),
+            .OUTPUT_SELECT      (OUTPUT_SELECT),
+            .SATURATE_ENABLE    (SATURATE_ENABLE),
+            .SHIFT_RIGHT        (SHIFT_RIGHT),
+            .ROUND              (ROUND),
+            .REGISTER_INPUTS    (REGISTER_INPUTS)
+        ) dsp_full (
+            .a_i(a),
+            .b_i(b),
+            .z_o(z),
+            .dly_b_o(dly_b),
+
+            .acc_fir_i(acc_fir),
+            .feedback_i(feedback),
+            .load_acc_i(load_acc),
+
+            .unsigned_a_i(unsigned_a),
+            .unsigned_b_i(unsigned_b),
+
+            .clock_i(clk),
+            .s_reset(reset),
+
+            .subtract_i(subtract),
+            .coef_0_i(COEFF_0),
+            .coef_1_i(COEFF_1),
+            .coef_2_i(COEFF_2),
+            .coef_3_i(COEFF_3)
+        );
+
+    end endgenerate
+
+endmodule
+
+module QL_DSP3_MULT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+    input  wire       unsigned_a,
+    input  wire       unsigned_b
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];    // unregistered output: a * b (0)
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];       // unregistered inputs
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .reset(reset),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b)
+    );
+endmodule
+
+module QL_DSP3_MULT_REGIN ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+
+    input  wire       unsigned_a,
+    input  wire       unsigned_b
+);
+
+    wire [37:0] dly_b_o;
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];    // unregistered output: a * b (0)
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];       // registered inputs
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset)
+    );
+endmodule
+
+module QL_DSP3_MULT_REGOUT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+
+    input  wire       unsigned_a,
+    input  wire       unsigned_b
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];    // registered output: a * b (4)
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];       // unregistered inputs
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset)
+    );
+endmodule
+
+module QL_DSP3_MULT_REGIN_REGOUT ( // TODO: Name subject to change
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire       clk,
+    input  wire       reset,
+
+    input  wire [2:0] feedback,
+
+    input  wire       unsigned_a,
+    input  wire       unsigned_b
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];    // registered output: a * b (4)
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];       // unregistered inputs
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset)
+    );
+endmodule
+
+module QL_DSP3_MULTADD (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTADD_REGIN (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTADD_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTADD_REGIN_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire [ 5:0] acc_fir,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .acc_fir(acc_fir),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTACC (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTACC_REGIN (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTACC_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module QL_DSP3_MULTACC_REGIN_REGOUT (
+    input  wire [19:0] a,
+    input  wire [17:0] b,
+    output wire [37:0] z,
+
+    (* clkbuf_sink *)
+    input  wire        clk,
+    input  wire        reset,
+
+    input  wire [ 2:0] feedback,
+    input  wire        load_acc,
+    input  wire        unsigned_a,
+    input  wire        unsigned_b,
+    input  wire        subtract
+);
+
+    parameter [92:0] MODE_BITS = 93'b0;
+
+    localparam [19:0] COEFF_0 = MODE_BITS[19:0];
+    localparam [19:0] COEFF_1 = MODE_BITS[39:20];
+    localparam [19:0] COEFF_2 = MODE_BITS[59:40];
+    localparam [19:0] COEFF_3 = MODE_BITS[79:60];
+
+    localparam [0:0] F_MODE          = MODE_BITS[80];
+    localparam [2:0] OUTPUT_SELECT   = MODE_BITS[83:81];
+    localparam [0:0] SATURATE_ENABLE = MODE_BITS[84];
+    localparam [5:0] SHIFT_RIGHT     = MODE_BITS[90:85];
+    localparam [0:0] ROUND           = MODE_BITS[91];
+    localparam [0:0] REGISTER_INPUTS = MODE_BITS[92];
+
+    QL_DSP3 #(
+        .MODE_BITS({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            F_MODE,
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a),
+        .b(b),
+        .z(z),
+
+        .feedback(feedback),
+        .load_acc(load_acc),
+
+        .unsigned_a(unsigned_a),
+        .unsigned_b(unsigned_b),
+
+        .clk(clk),
+        .reset(reset),
+        .subtract(subtract)
+    );
+endmodule
+
+module dsp_t1_20x18x64_cfg_params (
+    input  wire [19:0] a_i,
+    input  wire [17:0] b_i,
+    input  wire [ 5:0] acc_fir_i,
+    output wire [37:0] z_o,
+    output wire [17:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input  wire        clock_i,
+    input  wire        reset_i,
+
+    input  wire [ 2:0] feedback_i,
+    input  wire        load_acc_i,
+    input  wire        unsigned_a_i,
+    input  wire        unsigned_b_i,
+    input  wire        subtract_i
+);
+
+    parameter [19:0] COEFF_0 = 20'b0;
+    parameter [19:0] COEFF_1 = 20'b0;
+    parameter [19:0] COEFF_2 = 20'b0;
+    parameter [19:0] COEFF_3 = 20'b0;
+
+    parameter [2:0] OUTPUT_SELECT   = 3'b0;
+    parameter [0:0] SATURATE_ENABLE = 1'b0;
+    parameter [5:0] SHIFT_RIGHT     = 6'b0;
+    parameter [0:0] ROUND           = 1'b0;
+    parameter [0:0] REGISTER_INPUTS = 1'b0;
+
+    QL_DSP3 #(
+        .MODE_BITS ({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            1'b0, // Not fractured
+            COEFF_3,
+            COEFF_2,
+            COEFF_1,
+            COEFF_0
+        })
+    ) dsp (
+        .a(a_i),
+        .b(b_i),
+        .z(z_o),
+        .dly_b(dly_b_o),
+
+        .acc_fir(acc_fir_i),
+        .feedback(feedback_i),
+        .load_acc(load_acc_i),
+
+        .unsigned_a(unsigned_a_i),
+        .unsigned_b(unsigned_b_i),
+
+        .clk(clock_i),
+        .reset(reset_i),
+        .subtract(subtract_i)
+    );
+endmodule
+
+module dsp_t1_10x9x32_cfg_params (
+    input  wire [ 9:0] a_i,
+    input  wire [ 8:0] b_i,
+    input  wire [ 5:0] acc_fir_i,
+    output wire [18:0] z_o,
+    output wire [ 8:0] dly_b_o,
+
+    (* clkbuf_sink *)
+    input  wire        clock_i,
+    input  wire        reset_i,
+
+    input  wire [ 2:0] feedback_i,
+    input  wire        load_acc_i,
+    input  wire        unsigned_a_i,
+    input  wire        unsigned_b_i,
+    input  wire        subtract_i
+);
+
+    parameter [9:0] COEFF_0 = 10'b0;
+    parameter [9:0] COEFF_1 = 10'b0;
+    parameter [9:0] COEFF_2 = 10'b0;
+    parameter [9:0] COEFF_3 = 10'b0;
+
+    parameter [2:0] OUTPUT_SELECT   = 3'b0;
+    parameter [0:0] SATURATE_ENABLE = 1'b0;
+    parameter [5:0] SHIFT_RIGHT     = 6'b0;
+    parameter [0:0] ROUND           = 1'b0;
+    parameter [0:0] REGISTER_INPUTS = 1'b0;
+
+    wire [18:0] z_rem;
+    wire [8:0] dly_b_rem;
+
+    QL_DSP3 #(
+        .MODE_BITS ({
+            REGISTER_INPUTS,
+            ROUND,
+            SHIFT_RIGHT,
+            SATURATE_ENABLE,
+            OUTPUT_SELECT,
+            1'b1, // Fractured
+            10'd0, COEFF_3,
+            10'd0, COEFF_2,
+            10'd0, COEFF_1,
+            10'd0, COEFF_0
+        })
+    ) dsp (
+        .a({10'b0, a_i}),
+        .b({9'b0, b_i}),
+        .z({z_rem, z_o}),
+        .dly_b({dly_b_rem, dly_b_o}),
+
+        .acc_fir(acc_fir_i),
+        .feedback(feedback_i),
+        .load_acc(load_acc_i),
+
+        .unsigned_a(unsigned_a_i),
+        .unsigned_b(unsigned_b_i),
+
+        .clk(clock_i),
+        .reset(reset_i),
+        .subtract(subtract_i)
+    );
+endmodule
+
+module dsp_t1_sim_cfg_params # (
+    parameter NBITS_ACC  = 64,
+    parameter NBITS_A    = 20,
+    parameter NBITS_B    = 18,
+    parameter NBITS_Z    = 38,
+
+    parameter [2:0] OUTPUT_SELECT   = 3'b0,
+    parameter [0:0] SATURATE_ENABLE = 1'b0,
+    parameter [5:0] SHIFT_RIGHT     = 6'b0,
+    parameter [0:0] ROUND           = 1'b0,
+    parameter [0:0] REGISTER_INPUTS = 1'b0
+)(
+    input  wire [NBITS_A-1:0] a_i,
+    input  wire [NBITS_B-1:0] b_i,
+    output wire [NBITS_Z-1:0] z_o,
+    output reg  [NBITS_B-1:0] dly_b_o,
+
+    input  wire [5:0]         acc_fir_i,
+    input  wire [2:0]         feedback_i,
+    input  wire               load_acc_i,
+
+    input  wire               unsigned_a_i,
+    input  wire               unsigned_b_i,
+
+    input  wire               clock_i,
+    input  wire               s_reset,
+
+    input  wire               subtract_i,
+    input  wire [NBITS_A-1:0] coef_0_i,
+    input  wire [NBITS_A-1:0] coef_1_i,
+    input  wire [NBITS_A-1:0] coef_2_i,
+    input  wire [NBITS_A-1:0] coef_3_i
+);
+
+// FIXME: The version of Icarus Verilog from Conda seems not to recognize the
+// $error macro. Disable this sanity check for now because of that.
+`ifndef __ICARUS__
+    if (NBITS_ACC < NBITS_A + NBITS_B)
+        $error("NBITS_ACC must be > NBITS_A + NBITS_B");
+`endif
+
+    // Input registers
+    reg  [NBITS_A-1:0]  r_a;
+    reg  [NBITS_B-1:0]  r_b;
+    reg  [5:0]          r_acc_fir;
+    reg                 r_unsigned_a;
+    reg                 r_unsigned_b;
+    reg                 r_load_acc;
+    reg  [2:0]          r_feedback;
+    reg  [5:0]          r_shift_d1;
+    reg  [5:0]          r_shift_d2;
+    reg         r_subtract;
+    reg         r_sat;
+    reg         r_rnd;
+    reg [NBITS_ACC-1:0] acc;
+
+    initial begin
+        r_a          <= 0;
+        r_b          <= 0;
+
+        r_acc_fir    <= 0;
+        r_unsigned_a <= 0;
+        r_unsigned_b <= 0;
+        r_feedback   <= 0;
+        r_shift_d1   <= 0;
+        r_shift_d2   <= 0;
+        r_subtract   <= 0;
+        r_load_acc   <= 0;
+        r_sat        <= 0;
+        r_rnd        <= 0;
+    end
+
+    always @(posedge clock_i or posedge s_reset) begin
+        if (s_reset) begin
+
+            r_a <= 'h0;
+            r_b <= 'h0;
+
+            r_acc_fir    <= 0;
+            r_unsigned_a <= 0;
+            r_unsigned_b <= 0;
+            r_feedback   <= 0;
+            r_shift_d1   <= 0;
+            r_shift_d2   <= 0;
+            r_subtract   <= 0;
+            r_load_acc   <= 0;
+            r_sat    <= 0;
+            r_rnd    <= 0;
+
+        end else begin
+
+            r_a <= a_i;
+            r_b <= b_i;
+
+            r_acc_fir    <= acc_fir_i;
+            r_unsigned_a <= unsigned_a_i;
+            r_unsigned_b <= unsigned_b_i;
+            r_feedback   <= feedback_i;
+            r_shift_d1   <= SHIFT_RIGHT;
+            r_shift_d2   <= r_shift_d1;
+            r_subtract   <= subtract_i;
+            r_load_acc   <= load_acc_i;
+            r_sat    <= r_sat;
+            r_rnd    <= r_rnd;
+
+        end
+    end
+
+    // Registered / non-registered input path select
+    wire [NBITS_A-1:0]  a = REGISTER_INPUTS ? r_a : a_i;
+    wire [NBITS_B-1:0]  b = REGISTER_INPUTS ? r_b : b_i;
+
+    wire [5:0] acc_fir = REGISTER_INPUTS ? r_acc_fir : acc_fir_i;
+    wire       unsigned_a = REGISTER_INPUTS ? r_unsigned_a : unsigned_a_i;
+    wire       unsigned_b = REGISTER_INPUTS ? r_unsigned_b : unsigned_b_i;
+    wire [2:0] feedback   = REGISTER_INPUTS ? r_feedback   : feedback_i;
+    wire       load_acc   = REGISTER_INPUTS ? r_load_acc   : load_acc_i;
+    wire       subtract   = REGISTER_INPUTS ? r_subtract   : subtract_i;
+    wire       sat    = REGISTER_INPUTS ? r_sat : SATURATE_ENABLE;
+    wire       rnd    = REGISTER_INPUTS ? r_rnd : ROUND;
+
+    // Shift right control
+    wire [5:0] shift_d1 = REGISTER_INPUTS ? r_shift_d1 : SHIFT_RIGHT;
+    wire [5:0] shift_d2 = OUTPUT_SELECT[1] ? shift_d1 : r_shift_d2;
+
+    // Multiplier
+    wire unsigned_mode = unsigned_a & unsigned_b;
+    wire [NBITS_A-1:0] mult_a;
+    assign mult_a = (feedback == 3'h0) ?   a :
+                    (feedback == 3'h1) ?   a :
+                    (feedback == 3'h2) ?   a :
+                    (feedback == 3'h3) ?   acc[NBITS_A-1:0] :
+                    (feedback == 3'h4) ?   coef_0_i :
+                    (feedback == 3'h5) ?   coef_1_i :
+                    (feedback == 3'h6) ?   coef_2_i :
+                       coef_3_i;    // if feedback == 3'h7
+
+    wire [NBITS_B-1:0] mult_b = (feedback == 2'h2) ? {NBITS_B{1'b0}}  : b;
+
+    wire [NBITS_A-1:0] mult_sgn_a = mult_a[NBITS_A-1];
+    wire [NBITS_A-1:0] mult_mag_a = (mult_sgn_a && !unsigned_a) ? (~mult_a + 1) : mult_a;
+    wire [NBITS_B-1:0] mult_sgn_b = mult_b[NBITS_B-1];
+    wire [NBITS_B-1:0] mult_mag_b = (mult_sgn_b && !unsigned_b) ? (~mult_b + 1) : mult_b;
+
+    wire [NBITS_A+NBITS_B-1:0] mult_mag = mult_mag_a * mult_mag_b;
+    wire mult_sgn = (mult_sgn_a && !unsigned_a) ^ (mult_sgn_b && !unsigned_b);
+
+    wire [NBITS_A+NBITS_B-1:0] mult = (unsigned_a && unsigned_b) ?
+        (mult_a * mult_b) : (mult_sgn ? (~mult_mag + 1) : mult_mag);
+
+    // Sign extension
+    wire [NBITS_ACC-1:0] mult_xtnd = unsigned_mode ?
+        {{(NBITS_ACC-NBITS_A-NBITS_B){1'b0}},                    mult[NBITS_A+NBITS_B-1:0]} :
+        {{(NBITS_ACC-NBITS_A-NBITS_B){mult[NBITS_A+NBITS_B-1]}}, mult[NBITS_A+NBITS_B-1:0]};
+
+    // Adder
+    wire [NBITS_ACC-1:0] acc_fir_int = unsigned_a ? {{(NBITS_ACC-NBITS_A){1'b0}},         a} :
+                                                    {{(NBITS_ACC-NBITS_A){a[NBITS_A-1]}}, a} ;
+
+    wire [NBITS_ACC-1:0] add_a = (subtract) ? (~mult_xtnd + 1) : mult_xtnd;
+    wire [NBITS_ACC-1:0] add_b = (feedback_i == 3'h0) ? acc :
+                                 (feedback_i == 3'h1) ? {{NBITS_ACC}{1'b0}} : (acc_fir_int << acc_fir);
+
+    wire [NBITS_ACC-1:0] add_o = add_a + add_b;
+
+    // Accumulator
+    initial acc <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset) acc <= 'h0;
+        else begin
+            if (load_acc)
+                acc <= add_o;
+            else
+                acc <= acc;
+        end
+
+    // Adder/accumulator output selection
+    wire [NBITS_ACC-1:0] acc_out = (OUTPUT_SELECT[1]) ? add_o : acc;
+
+    // Round, shift, saturate
+    wire [NBITS_ACC-1:0] acc_rnd = (rnd && (SHIFT_RIGHT != 0)) ? (acc_out + ({{(NBITS_ACC-1){1'b0}}, 1'b1} << (SHIFT_RIGHT - 1))) :
+                                                                    acc_out;
+
+    wire [NBITS_ACC-1:0] acc_shr = (unsigned_mode) ? (acc_rnd  >> SHIFT_RIGHT) :
+                                                     (acc_rnd >>> SHIFT_RIGHT);
+
+    wire [NBITS_ACC-1:0] acc_sat_u = (acc_shr[NBITS_ACC-1:NBITS_Z] != 0) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{NBITS_Z{1'b1}}} :
+                                                                           {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}};
+
+    wire [NBITS_ACC-1:0] acc_sat_s = ((|acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b0) ||
+                                      (&acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b1)) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}} :
+                                                                                   {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_ACC-1],{NBITS_Z-1{~acc_shr[NBITS_ACC-1]}}}};
+
+    wire [NBITS_ACC-1:0] acc_sat = (sat) ? ((unsigned_mode) ? acc_sat_u : acc_sat_s) : acc_shr;
+
+    // Output signals
+    wire [NBITS_Z-1:0]  z0;
+    reg  [NBITS_Z-1:0]  z1;
+    wire [NBITS_Z-1:0]  z2;
+
+    assign z0 = mult_xtnd[NBITS_Z-1:0];
+    assign z2 = acc_sat[NBITS_Z-1:0];
+
+    initial z1 <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset)
+            z1 <= 0;
+        else begin
+            z1 <= (OUTPUT_SELECT == 3'b100) ? z0 : z2;
+        end
+
+    // Output mux
+    assign z_o = (OUTPUT_SELECT == 3'h0) ?   z0 :
+                 (OUTPUT_SELECT == 3'h1) ?   z2 :
+                 (OUTPUT_SELECT == 3'h2) ?   z2 :
+                 (OUTPUT_SELECT == 3'h3) ?   z2 :
+                 (OUTPUT_SELECT == 3'h4) ?   z1 :
+                 (OUTPUT_SELECT == 3'h5) ?   z1 :
+                 (OUTPUT_SELECT == 3'h6) ?   z1 :
+                           z1;  // if OUTPUT_SELECT == 3'h7
+
+    // B input delayed passthrough
+    initial dly_b_o <= 0;
+
+    always @(posedge clock_i or posedge s_reset)
+        if (s_reset)
+            dly_b_o <= 0;
+        else
+            dly_b_o <= b_i;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/ffs_map.v b/yosys-plugins/ql-qlf/qlf_k6n10f/ffs_map.v
new file mode 100644
index 000000000..26fa6ed36
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/ffs_map.v
@@ -0,0 +1,133 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+// DFF, asynchronous set/reset, enable
+module \$_DFFSRE_PNNP_ (C, S, R, E, D, Q);
+    input  C;
+    input  S;
+    input  R;
+    input  E;
+    input  D;
+    output Q;
+    dffsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
+
+module \$_DFFSRE_NNNP_ (C, S, R, E, D, Q);
+    input  C;
+    input  S;
+    input  R;
+    input  E;
+    input  D;
+    output Q;
+    dffnsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(S));
+endmodule
+
+// DFF, synchronous set or reset, enable
+module \$_SDFFE_PN0P_ (D, C, R, E, Q);
+    input  D;
+    input  C;
+    input  R;
+    input  E;
+    output Q;
+    sdffsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(1'b1));
+endmodule
+
+module \$_SDFFE_PN1P_ (D, C, R, E, Q);
+    input  D;
+    input  C;
+    input  R;
+    input  E;
+    output Q;
+    sdffsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(1'b1), .S(R));
+endmodule
+
+module \$_SDFFE_NN0P_ (D, C, R, E, Q);
+    input  D;
+    input  C;
+    input  R;
+    input  E;
+    output Q;
+    sdffnsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(R), .S(1'b1));
+endmodule
+
+module \$_SDFFE_NN1P_ (D, C, R, E, Q);
+    input  D;
+    input  C;
+    input  R;
+    input  E;
+    output Q;
+    sdffnsre _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .E(E), .R(1'b1), .S(R));
+endmodule
+
+// Latch, no set/reset, no enable
+module  \$_DLATCH_P_ (input E, D, output Q);
+    latchsre  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E), .R(1'b1), .S(1'b1));
+endmodule
+
+module  \$_DLATCH_N_ (input E, D, output Q);
+    latchnsre _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E), .R(1'b1), .S(1'b1));
+endmodule
+
+// Latch with async set and reset and enable
+module  \$_DLATCHSR_PPP_ (input E, S, R, D, output Q);
+    latchsre  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E),  .R(!R), .S(!S));
+endmodule
+
+module  \$_DLATCHSR_NPP_ (input E, S, R, D, output Q);
+    latchnsre _TECHMAP_REPLACE_ (.D(D), .Q(Q), .E(1'b1), .G(E),  .R(!R), .S(!S));
+endmodule
+
+module \$__SHREG_DFF_P_ (D, Q, C);
+    input  D;
+    input  C;
+    output Q;
+
+    parameter DEPTH = 2;
+
+    reg [DEPTH-2:0] q;
+
+    genvar i;
+    generate for (i = 0; i < DEPTH; i = i + 1) begin: slice
+
+        // First in chain
+        generate if (i == 0) begin
+                 sh_dff #() shreg_beg (
+                    .Q(q[i]),
+                    .D(D),
+                    .C(C)
+                );
+        end endgenerate
+        // Middle in chain
+        generate if (i > 0 && i != DEPTH-1) begin
+                 sh_dff #() shreg_mid (
+                    .Q(q[i]),
+                    .D(q[i-1]),
+                    .C(C)
+                );
+        end endgenerate
+        // Last in chain
+        generate if (i == DEPTH-1) begin
+                 sh_dff #() shreg_end (
+                    .Q(Q),
+                    .D(q[i-1]),
+                    .C(C)
+                );
+        end endgenerate
+   end: slice
+   endgenerate
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/sram1024x18.v b/yosys-plugins/ql-qlf/qlf_k6n10f/sram1024x18.v
new file mode 100644
index 000000000..864b886ac
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/sram1024x18.v
@@ -0,0 +1,134 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 wire
+module sram1024x18 (
+	clk_a,
+	cen_a,
+	wen_a,
+	addr_a,
+	wmsk_a,
+	wdata_a,
+	rdata_a,
+	clk_b,
+	cen_b,
+	wen_b,
+	addr_b,
+	wmsk_b,
+	wdata_b,
+	rdata_b
+);
+	(* clkbuf_sink *)
+	input wire clk_a;
+	input wire cen_a;
+	input wire wen_a;
+	input wire [9:0] addr_a;
+	input wire [17:0] wmsk_a;
+	input wire [17:0] wdata_a;
+	output reg [17:0] rdata_a;
+	(* clkbuf_sink *)
+	input wire clk_b;
+	input wire cen_b;
+	input wire wen_b;
+	input wire [9:0] addr_b;
+	input wire [17:0] wmsk_b;
+	input wire [17:0] wdata_b;
+	output reg [17:0] rdata_b;
+	reg [17:0] ram [1023:0];
+	reg [9:0] laddr_a;
+	reg [9:0] laddr_b;
+	reg lcen_a;
+	reg lwen_a;
+	reg [17:0] lwdata_a;
+	reg lcen_b;
+	reg lwen_b;
+	reg [17:0] lwdata_b;
+	reg [17:0] lwmsk_a;
+	reg [17:0] lwmsk_b;
+	always @(posedge clk_a) begin
+		laddr_a <= addr_a;
+		lwdata_a <= wdata_a;
+		lwmsk_a <= wmsk_a;
+		lcen_a <= cen_a;
+		lwen_a <= wen_a;
+	end
+	always @(posedge clk_b) begin
+		laddr_b <= addr_b;
+		lwdata_b <= wdata_b;
+		lwmsk_b <= wmsk_b;
+		lcen_b <= cen_b;
+		lwen_b <= wen_b;
+	end
+	always @(*) begin
+		if ((lwen_b == 0) && (lcen_b == 0)) begin
+			ram[laddr_b][0] = (lwmsk_b[0] ? ram[laddr_b][0] : lwdata_b[0]);
+			ram[laddr_b][1] = (lwmsk_b[1] ? ram[laddr_b][1] : lwdata_b[1]);
+			ram[laddr_b][2] = (lwmsk_b[2] ? ram[laddr_b][2] : lwdata_b[2]);
+			ram[laddr_b][3] = (lwmsk_b[3] ? ram[laddr_b][3] : lwdata_b[3]);
+			ram[laddr_b][4] = (lwmsk_b[4] ? ram[laddr_b][4] : lwdata_b[4]);
+			ram[laddr_b][5] = (lwmsk_b[5] ? ram[laddr_b][5] : lwdata_b[5]);
+			ram[laddr_b][6] = (lwmsk_b[6] ? ram[laddr_b][6] : lwdata_b[6]);
+			ram[laddr_b][7] = (lwmsk_b[7] ? ram[laddr_b][7] : lwdata_b[7]);
+			ram[laddr_b][8] = (lwmsk_b[8] ? ram[laddr_b][8] : lwdata_b[8]);
+			ram[laddr_b][9] = (lwmsk_b[9] ? ram[laddr_b][9] : lwdata_b[9]);
+			ram[laddr_b][10] = (lwmsk_b[10] ? ram[laddr_b][10] : lwdata_b[10]);
+			ram[laddr_b][11] = (lwmsk_b[11] ? ram[laddr_b][11] : lwdata_b[11]);
+			ram[laddr_b][12] = (lwmsk_b[12] ? ram[laddr_b][12] : lwdata_b[12]);
+			ram[laddr_b][13] = (lwmsk_b[13] ? ram[laddr_b][13] : lwdata_b[13]);
+			ram[laddr_b][14] = (lwmsk_b[14] ? ram[laddr_b][14] : lwdata_b[14]);
+			ram[laddr_b][15] = (lwmsk_b[15] ? ram[laddr_b][15] : lwdata_b[15]);
+			ram[laddr_b][16] = (lwmsk_b[16] ? ram[laddr_b][16] : lwdata_b[16]);
+			ram[laddr_b][17] = (lwmsk_b[17] ? ram[laddr_b][17] : lwdata_b[17]);
+			lwen_b = 1;
+		end
+		if (lcen_b == 0) begin
+			rdata_b = ram[laddr_b];
+			lcen_b = 1;
+		end
+		else
+			rdata_b = rdata_b;
+	end
+	always @(*) begin
+		if ((lwen_a == 0) && (lcen_a == 0)) begin
+			ram[laddr_a][0] = (lwmsk_a[0] ? ram[laddr_a][0] : lwdata_a[0]);
+			ram[laddr_a][1] = (lwmsk_a[1] ? ram[laddr_a][1] : lwdata_a[1]);
+			ram[laddr_a][2] = (lwmsk_a[2] ? ram[laddr_a][2] : lwdata_a[2]);
+			ram[laddr_a][3] = (lwmsk_a[3] ? ram[laddr_a][3] : lwdata_a[3]);
+			ram[laddr_a][4] = (lwmsk_a[4] ? ram[laddr_a][4] : lwdata_a[4]);
+			ram[laddr_a][5] = (lwmsk_a[5] ? ram[laddr_a][5] : lwdata_a[5]);
+			ram[laddr_a][6] = (lwmsk_a[6] ? ram[laddr_a][6] : lwdata_a[6]);
+			ram[laddr_a][7] = (lwmsk_a[7] ? ram[laddr_a][7] : lwdata_a[7]);
+			ram[laddr_a][8] = (lwmsk_a[8] ? ram[laddr_a][8] : lwdata_a[8]);
+			ram[laddr_a][9] = (lwmsk_a[9] ? ram[laddr_a][9] : lwdata_a[9]);
+			ram[laddr_a][10] = (lwmsk_a[10] ? ram[laddr_a][10] : lwdata_a[10]);
+			ram[laddr_a][11] = (lwmsk_a[11] ? ram[laddr_a][11] : lwdata_a[11]);
+			ram[laddr_a][12] = (lwmsk_a[12] ? ram[laddr_a][12] : lwdata_a[12]);
+			ram[laddr_a][13] = (lwmsk_a[13] ? ram[laddr_a][13] : lwdata_a[13]);
+			ram[laddr_a][14] = (lwmsk_a[14] ? ram[laddr_a][14] : lwdata_a[14]);
+			ram[laddr_a][15] = (lwmsk_a[15] ? ram[laddr_a][15] : lwdata_a[15]);
+			ram[laddr_a][16] = (lwmsk_a[16] ? ram[laddr_a][16] : lwdata_a[16]);
+			ram[laddr_a][17] = (lwmsk_a[17] ? ram[laddr_a][17] : lwdata_a[17]);
+			lwen_a = 1;
+		end
+		if (lcen_a == 0) begin
+			rdata_a = ram[laddr_a];
+			lcen_a = 1;
+		end
+		else
+			rdata_a = rdata_a;
+	end
+endmodule
+`default_nettype none
diff --git a/yosys-plugins/ql-qlf/qlf_k6n10f/ufifo_ctl.v b/yosys-plugins/ql-qlf/qlf_k6n10f/ufifo_ctl.v
new file mode 100644
index 000000000..441f6bc4a
--- /dev/null
+++ b/yosys-plugins/ql-qlf/qlf_k6n10f/ufifo_ctl.v
@@ -0,0 +1,620 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 wire
+module fifo_ctl (
+	raddr,
+	waddr,
+	fflags,
+	ren_o,
+	sync,
+	rmode,
+	wmode,
+	rclk,
+	rst_R_n,
+	wclk,
+	rst_W_n,
+	ren,
+	wen,
+	upaf,
+	upae
+);
+	parameter ADDR_WIDTH = 11;
+	parameter FIFO_WIDTH = 3'd2;
+	parameter DEPTH = 6;
+	output wire [ADDR_WIDTH - 1:0] raddr;
+	output wire [ADDR_WIDTH - 1:0] waddr;
+	output wire [7:0] fflags;
+	output wire ren_o;
+	input wire sync;
+	input wire [1:0] rmode;
+	input wire [1:0] wmode;
+	(* clkbuf_sink *)
+	input wire rclk;
+	input wire rst_R_n;
+	(* clkbuf_sink *)
+	input wire wclk;
+	input wire rst_W_n;
+	input wire ren;
+	input wire wen;
+	input wire [ADDR_WIDTH - 1:0] upaf;
+	input wire [ADDR_WIDTH - 1:0] upae;
+	localparam ADDR_PLUS_ONE = ADDR_WIDTH + 1;
+	reg [ADDR_WIDTH:0] pushtopop1;
+	reg [ADDR_WIDTH:0] pushtopop2;
+	reg [ADDR_WIDTH:0] poptopush1;
+	reg [ADDR_WIDTH:0] poptopush2;
+	wire [ADDR_WIDTH:0] pushtopop0;
+	wire [ADDR_WIDTH:0] poptopush0;
+	wire [ADDR_WIDTH:0] smux_poptopush;
+	wire [ADDR_WIDTH:0] smux_pushtopop;
+	assign smux_poptopush = (sync ? poptopush0 : poptopush2);
+	assign smux_pushtopop = (sync ? pushtopop0 : pushtopop2);
+	always @(posedge rclk or negedge rst_R_n)
+		if (~rst_R_n) begin
+			pushtopop1 <= 'h0;
+			pushtopop2 <= 'h0;
+		end
+		else begin
+			pushtopop1 = pushtopop0;
+			pushtopop2 = pushtopop1;
+		end
+	always @(posedge wclk or negedge rst_W_n)
+		if (~rst_W_n) begin
+			poptopush1 <= 'h0;
+			poptopush2 <= 'h0;
+		end
+		else begin
+			poptopush1 <= poptopush0;
+			poptopush2 <= poptopush1;
+		end
+	fifo_push #(
+		.ADDR_WIDTH(ADDR_WIDTH),
+		.DEPTH(DEPTH)
+	) u_fifo_push(
+		.wclk(wclk),
+		.wen(wen),
+		.rst_n(rst_W_n),
+		.rmode(rmode),
+		.wmode(wmode),
+		.gcout(pushtopop0),
+		.gcin(smux_poptopush),
+		.ff_waddr(waddr),
+		.pushflags(fflags[7:4]),
+		.upaf(upaf)
+	);
+	fifo_pop #(
+		.ADDR_WIDTH(ADDR_WIDTH),
+		.FIFO_WIDTH(FIFO_WIDTH),
+		.DEPTH(DEPTH)
+	) u_fifo_pop(
+		.rclk(rclk),
+		.ren_in(ren),
+		.rst_n(rst_R_n),
+		.rmode(rmode),
+		.wmode(wmode),
+		.ren_o(ren_o),
+		.gcout(poptopush0),
+		.gcin(smux_pushtopop),
+		.out_raddr(raddr),
+		.popflags(fflags[3:0]),
+		.upae(upae)
+	);
+endmodule
+module fifo_push (
+	pushflags,
+	gcout,
+	ff_waddr,
+	rst_n,
+	wclk,
+	wen,
+	rmode,
+	wmode,
+	gcin,
+	upaf
+);
+	parameter ADDR_WIDTH = 11;
+	parameter DEPTH = 6;
+	output wire [3:0] pushflags;
+	output wire [ADDR_WIDTH:0] gcout;
+	output wire [ADDR_WIDTH - 1:0] ff_waddr;
+	input rst_n;
+	(* clkbuf_sink *)
+	input wclk;
+	input wen;
+	input [1:0] rmode;
+	input [1:0] wmode;
+	input [ADDR_WIDTH:0] gcin;
+	input [ADDR_WIDTH - 1:0] upaf;
+	localparam ADDR_PLUS_ONE = ADDR_WIDTH + 1;
+	reg full_next;
+	reg full;
+	reg paf_next;
+	reg paf;
+	reg fmo;
+	reg fmo_next;
+	reg overflow;
+	reg p1;
+	reg p2;
+	reg f1;
+	reg f2;
+	reg q1;
+	reg q2;
+	reg [1:0] gmode;
+	reg [ADDR_WIDTH:0] waddr;
+	reg [ADDR_WIDTH:0] raddr;
+	reg [ADDR_WIDTH:0] gcout_reg;
+	reg [ADDR_WIDTH:0] gcout_next;
+	reg [ADDR_WIDTH:0] raddr_next;
+	reg [ADDR_WIDTH - 1:0] paf_thresh;
+	wire overflow_next;
+	wire [ADDR_WIDTH:0] waddr_next;
+	wire [ADDR_WIDTH:0] gc8out_next;
+	wire [ADDR_WIDTH - 1:0] gc16out_next;
+	wire [ADDR_WIDTH - 2:0] gc32out_next;
+	wire [ADDR_WIDTH:0] tmp;
+	wire [ADDR_WIDTH:0] next_count;
+	wire [ADDR_WIDTH:0] count;
+	wire [ADDR_WIDTH:0] fbytes;
+	genvar i;
+	assign next_count = fbytes - (waddr_next >= raddr_next ? waddr_next - raddr_next : (~raddr_next + waddr_next) + 1);
+	assign count = fbytes - (waddr >= raddr ? waddr - raddr : (~raddr + waddr) + 1);
+	assign fbytes = 1 << (DEPTH + 5);
+	always @(*) begin
+		paf_thresh = wmode[1] ? upaf : (wmode[0] ? upaf << 1 : upaf << 2);
+	end
+	always @(*)
+		case (wmode)
+			2'h0, 2'h1, 2'h2: begin
+				full_next = (wen ? f1 : f2);
+				fmo_next = (wen ? p1 : p2);
+				paf_next = (wen ? q1 : q2);
+			end
+			default: begin
+				full_next = 1'b0;
+				fmo_next = 1'b0;
+				paf_next = 1'b0;
+			end
+		endcase
+	always @(*) begin : PUSH_FULL_FLAGS
+		f1 = 1'b0;
+		f2 = 1'b0;
+		p1 = 1'b0;
+		p2 = 1'b0;
+		q1 = next_count < {1'b0, paf_thresh};
+		q2 = count < {1'b0, paf_thresh};
+		case (wmode)
+			2'h0:
+				case (DEPTH)
+					3'h6: begin
+						f1 = {~waddr_next[11], waddr_next[10:2]} == raddr_next[11:2];
+						f2 = {~waddr[11], waddr[10:2]} == raddr_next[11:2];
+						p1 = ((waddr_next[10:2] + 1) & 9'h1ff) == raddr_next[10:2];
+						p2 = ((waddr[10:2] + 1) & 9'h1ff) == raddr_next[10:2];
+					end
+					3'h5: begin
+						f1 = {~waddr_next[10], waddr_next[9:2]} == raddr_next[10:2];
+						f2 = {~waddr[10], waddr[9:2]} == raddr_next[10:2];
+						p1 = ((waddr_next[9:2] + 1) & 8'hff) == raddr_next[9:2];
+						p2 = ((waddr[9:2] + 1) & 8'hff) == raddr_next[9:2];
+					end
+					3'h4: begin
+						f1 = {~waddr_next[9], waddr_next[8:2]} == raddr_next[9:2];
+						f2 = {~waddr[9], waddr[8:2]} == raddr_next[9:2];
+						p1 = ((waddr_next[8:2] + 1) & 7'h7f) == raddr_next[8:2];
+						p2 = ((waddr[8:2] + 1) & 7'h7f) == raddr_next[8:2];
+					end
+					3'h3: begin
+						f1 = {~waddr_next[8], waddr_next[7:2]} == raddr_next[8:2];
+						f2 = {~waddr[8], waddr[7:2]} == raddr_next[8:2];
+						p1 = ((waddr_next[7:2] + 1) & 6'h3f) == raddr_next[7:2];
+						p2 = ((waddr[7:2] + 1) & 6'h3f) == raddr_next[7:2];
+					end
+					3'h2: begin
+						f1 = {~waddr_next[7], waddr_next[6:2]} == raddr_next[7:2];
+						f2 = {~waddr[7], waddr[6:2]} == raddr_next[7:2];
+						p1 = ((waddr_next[6:2] + 1) & 5'h1f) == raddr_next[6:2];
+						p2 = ((waddr[6:2] + 1) & 5'h1f) == raddr_next[6:2];
+					end
+					3'h1: begin
+						f1 = {~waddr_next[6], waddr_next[5:2]} == raddr_next[6:2];
+						f2 = {~waddr[6], waddr[5:2]} == raddr_next[6:2];
+						p1 = ((waddr_next[5:2] + 1) & 4'hf) == raddr_next[5:2];
+						p2 = ((waddr[5:2] + 1) & 4'hf) == raddr_next[5:2];
+					end
+					3'h0: begin
+						f1 = {~waddr_next[5], waddr_next[4:2]} == raddr_next[5:2];
+						f2 = {~waddr[5], waddr[4:2]} == raddr_next[5:2];
+						p1 = ((waddr_next[4:2] + 1) & 3'h7) == raddr_next[4:2];
+						p2 = ((waddr[4:2] + 1) & 3'h7) == raddr_next[4:2];
+					end
+					3'h7: begin
+						f1 = {~waddr_next[ADDR_WIDTH], waddr_next[ADDR_WIDTH - 1:2]} == raddr_next[ADDR_WIDTH:2];
+						f2 = {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH - 1:2]} == raddr_next[ADDR_WIDTH:2];
+						p1 = ((waddr_next[ADDR_WIDTH - 1:2] + 1) & {ADDR_WIDTH - 2 {1'b1}}) == raddr_next[ADDR_WIDTH - 1:2];
+						p2 = ((waddr[ADDR_WIDTH - 1:2] + 1) & {ADDR_WIDTH - 2 {1'b1}}) == raddr_next[ADDR_WIDTH - 1:2];
+					end
+				endcase
+			2'h1:
+				case (DEPTH)
+					3'h6: begin
+						f1 = {~waddr_next[11], waddr_next[10:1]} == raddr_next[11:1];
+						f2 = {~waddr[11], waddr[10:1]} == raddr_next[11:1];
+						p1 = ((waddr_next[10:1] + 1) & 10'h3ff) == raddr_next[10:1];
+						p2 = ((waddr[10:1] + 1) & 10'h3ff) == raddr_next[10:1];
+					end
+					3'h5: begin
+						f1 = {~waddr_next[10], waddr_next[9:1]} == raddr_next[10:1];
+						f2 = {~waddr[10], waddr[9:1]} == raddr_next[10:1];
+						p1 = ((waddr_next[9:1] + 1) & 9'h1ff) == raddr_next[9:1];
+						p2 = ((waddr[9:1] + 1) & 9'h1ff) == raddr_next[9:1];
+					end
+					3'h4: begin
+						f1 = {~waddr_next[9], waddr_next[8:1]} == raddr_next[9:1];
+						f2 = {~waddr[9], waddr[8:1]} == raddr_next[9:1];
+						p1 = ((waddr_next[8:1] + 1) & 8'hff) == raddr_next[8:1];
+						p2 = ((waddr[8:1] + 1) & 8'hff) == raddr_next[8:1];
+					end
+					3'h3: begin
+						f1 = {~waddr_next[8], waddr_next[7:1]} == raddr_next[8:1];
+						f2 = {~waddr[8], waddr[7:1]} == raddr_next[8:1];
+						p1 = ((waddr_next[7:1] + 1) & 7'h7f) == raddr_next[7:1];
+						p2 = ((waddr[7:1] + 1) & 7'h7f) == raddr_next[7:1];
+					end
+					3'h2: begin
+						f1 = {~waddr_next[7], waddr_next[6:1]} == raddr_next[7:1];
+						f2 = {~waddr[7], waddr[6:1]} == raddr_next[7:1];
+						p1 = ((waddr_next[6:1] + 1) & 6'h3f) == raddr_next[6:1];
+						p2 = ((waddr[6:1] + 1) & 6'h3f) == raddr_next[6:1];
+					end
+					3'h1: begin
+						f1 = {~waddr_next[6], waddr_next[5:1]} == raddr_next[6:1];
+						f2 = {~waddr[6], waddr[5:1]} == raddr_next[6:1];
+						p1 = ((waddr_next[5:1] + 1) & 5'h1f) == raddr_next[5:1];
+						p2 = ((waddr[5:1] + 1) & 5'h1f) == raddr_next[5:1];
+					end
+					3'h0: begin
+						f1 = {~waddr_next[5], waddr_next[4:1]} == raddr_next[5:1];
+						f2 = {~waddr[5], waddr[4:1]} == raddr_next[5:1];
+						p1 = ((waddr_next[4:1] + 1) & 4'hf) == raddr_next[4:1];
+						p2 = ((waddr[4:1] + 1) & 4'hf) == raddr_next[4:1];
+					end
+					3'h7: begin
+						f1 = {~waddr_next[ADDR_WIDTH], waddr_next[ADDR_WIDTH - 1:1]} == raddr_next[ADDR_WIDTH:1];
+						f2 = {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH - 1:1]} == raddr_next[ADDR_WIDTH:1];
+						p1 = ((waddr_next[ADDR_WIDTH - 1:1] + 1) & {ADDR_WIDTH - 1 {1'b1}}) == raddr_next[ADDR_WIDTH - 1:1];
+						p2 = ((waddr[ADDR_WIDTH - 1:1] + 1) & {ADDR_WIDTH - 1 {1'b1}}) == raddr_next[ADDR_WIDTH - 1:1];
+					end
+				endcase
+			2'h2:
+				case (DEPTH)
+					3'h6: begin
+						f1 = {~waddr_next[11], waddr_next[10:0]} == raddr_next[11:0];
+						f2 = {~waddr[11], waddr[10:0]} == raddr_next[11:0];
+						p1 = ((waddr_next[10:0] + 1) & 11'h7ff) == raddr_next[10:0];
+						p2 = ((waddr[10:0] + 1) & 11'h7ff) == raddr_next[10:0];
+					end
+					3'h5: begin
+						f1 = {~waddr_next[10], waddr_next[9:0]} == raddr_next[10:0];
+						f2 = {~waddr[10], waddr[9:0]} == raddr_next[10:0];
+						p1 = ((waddr_next[9:0] + 1) & 10'h3ff) == raddr_next[9:0];
+						p2 = ((waddr[9:0] + 1) & 10'h3ff) == raddr_next[9:0];
+					end
+					3'h4: begin
+						f1 = {~waddr_next[9], waddr_next[8:0]} == raddr_next[9:0];
+						f2 = {~waddr[9], waddr[8:0]} == raddr_next[9:0];
+						p1 = ((waddr_next[8:0] + 1) & 9'h1ff) == raddr_next[8:0];
+						p2 = ((waddr[8:0] + 1) & 9'h1ff) == raddr_next[8:0];
+					end
+					3'h3: begin
+						f1 = {~waddr_next[8], waddr_next[7:0]} == raddr_next[8:0];
+						f2 = {~waddr[8], waddr[7:0]} == raddr_next[8:0];
+						p1 = ((waddr_next[7:0] + 1) & 8'hff) == raddr_next[7:0];
+						p2 = ((waddr[7:0] + 1) & 8'hff) == raddr_next[7:0];
+					end
+					3'h2: begin
+						f1 = {~waddr_next[7], waddr_next[6:0]} == raddr_next[7:0];
+						f2 = {~waddr[7], waddr[6:0]} == raddr_next[7:0];
+						p1 = ((waddr_next[6:0] + 1) & 7'h7f) == raddr_next[6:0];
+						p2 = ((waddr[6:0] + 1) & 7'h7f) == raddr_next[6:0];
+					end
+					3'h1: begin
+						f1 = {~waddr_next[6], waddr_next[5:0]} == raddr_next[6:0];
+						f2 = {~waddr[6], waddr[5:0]} == raddr_next[6:0];
+						p1 = ((waddr_next[5:0] + 1) & 6'h3f) == raddr_next[5:0];
+						p2 = ((waddr[5:0] + 1) & 6'h3f) == raddr_next[5:0];
+					end
+					3'h0: begin
+						f1 = {~waddr_next[5], waddr_next[4:0]} == raddr_next[5:0];
+						f2 = {~waddr[5], waddr[4:0]} == raddr_next[5:0];
+						p1 = ((waddr_next[4:0] + 1) & 5'h1f) == raddr_next[4:0];
+						p2 = ((waddr[4:0] + 1) & 5'h1f) == raddr_next[4:0];
+					end
+					3'h7: begin
+						f1 = {~waddr_next[ADDR_WIDTH], waddr_next[ADDR_WIDTH - 1:0]} == raddr_next[ADDR_WIDTH:0];
+						f2 = {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH - 1:0]} == raddr_next[ADDR_WIDTH:0];
+						p1 = ((waddr_next[ADDR_WIDTH - 1:0] + 1) & {ADDR_WIDTH {1'b1}}) == raddr_next[ADDR_WIDTH - 1:0];
+						p2 = ((waddr[ADDR_WIDTH - 1:0] + 1) & {ADDR_WIDTH {1'b1}}) == raddr_next[ADDR_WIDTH - 1:0];
+					end
+				endcase
+			2'h3: begin
+				f1 = 1'b0;
+				f2 = 1'b0;
+				p1 = 1'b0;
+				p2 = 1'b0;
+			end
+		endcase
+	end
+	always @(*)
+		case (wmode)
+			2'h0: gmode = 2'h0;
+			2'h1: gmode = (rmode == 2'h0 ? 2'h0 : 2'h1);
+			2'h2: gmode = (rmode == 2'h2 ? 2'h2 : rmode);
+			2'h3: gmode = 2'h3;
+		endcase
+	assign gc8out_next = (waddr_next >> 1) ^ waddr_next;
+	assign gc16out_next = (waddr_next >> 2) ^ (waddr_next >> 1);
+	assign gc32out_next = (waddr_next >> 3) ^ (waddr_next >> 2);
+	always @(*)
+		if (wen)
+			case (gmode)
+				2'h2: gcout_next = gc8out_next;
+				2'h1: gcout_next = {1'b0, gc16out_next};
+				2'h0: gcout_next = {2'b00, gc32out_next};
+				default: gcout_next = {ADDR_PLUS_ONE {1'b0}};
+			endcase
+		else
+			gcout_next = {ADDR_PLUS_ONE {1'b0}};
+	always @(posedge wclk or negedge rst_n)
+		if (~rst_n) begin
+			full <= 1'b0;
+			fmo <= 1'b0;
+			paf <= 1'b0;
+			raddr <= {ADDR_PLUS_ONE {1'b0}};
+		end
+		else begin
+			full <= full_next;
+			fmo <= fmo_next;
+			paf <= paf_next;
+			case (gmode)
+				0: raddr <= raddr_next & {{ADDR_WIDTH - 1 {1'b1}}, 2'b00};
+				1: raddr <= raddr_next & {{ADDR_WIDTH {1'b1}}, 1'b0};
+				2: raddr <= raddr_next & {ADDR_WIDTH + 1 {1'b1}};
+				3: raddr <= 12'h000;
+			endcase
+		end
+	assign overflow_next = full & wen;
+	always @(posedge wclk or negedge rst_n)
+		if (~rst_n)
+			overflow <= 1'b0;
+		else if (wen == 1'b1)
+			overflow <= overflow_next;
+	always @(posedge wclk or negedge rst_n)
+		if (~rst_n) begin
+			waddr <= {ADDR_WIDTH + 1 {1'b0}};
+			gcout_reg <= {ADDR_WIDTH + 1 {1'b0}};
+		end
+		else if (wen == 1'b1) begin
+			waddr <= waddr_next;
+			gcout_reg <= gcout_next;
+		end
+	assign gcout = gcout_reg;
+	generate
+		for (i = 0; i < (ADDR_WIDTH + 1); i = i + 1) begin : genblk1
+			assign tmp[i] = ^(gcin >> i);
+		end
+	endgenerate
+	always @(*)
+		case (gmode)
+			2'h0: raddr_next = {tmp[ADDR_WIDTH - 2:0], 2'b00} & {{ADDR_WIDTH - 1 {1'b1}}, 2'b00};
+			2'h1: raddr_next = {tmp[ADDR_WIDTH - 1:0], 1'b0} & {{ADDR_WIDTH {1'b1}}, 1'b0};
+			2'h2: raddr_next = {tmp[ADDR_WIDTH:0]} & {ADDR_WIDTH + 1 {1'b1}};
+			default: raddr_next = {ADDR_WIDTH + 1 {1'b0}};
+		endcase
+	assign ff_waddr = waddr[ADDR_WIDTH - 1:0];
+	assign pushflags = {full, fmo, paf, overflow};
+	assign waddr_next = waddr + (wmode == 2'h0 ? 'h4 : (wmode == 2'h1 ? 'h2 : 'h1));
+endmodule
+module fifo_pop (
+	ren_o,
+	popflags,
+	out_raddr,
+	gcout,
+	rst_n,
+	rclk,
+	ren_in,
+	rmode,
+	wmode,
+	gcin,
+	upae
+);
+	parameter ADDR_WIDTH = 11;
+	parameter FIFO_WIDTH = 3'd2;
+	parameter DEPTH = 6;
+	output wire ren_o;
+	output wire [3:0] popflags;
+	output reg [ADDR_WIDTH - 1:0] out_raddr;
+	output wire [ADDR_WIDTH:0] gcout;
+	input rst_n;
+	(* clkbuf_sink *)
+	input rclk;
+	input ren_in;
+	input [1:0] rmode;
+	input [1:0] wmode;
+	input [ADDR_WIDTH:0] gcin;
+	input [ADDR_WIDTH - 1:0] upae;
+	localparam ADDR_PLUS_ONE = ADDR_WIDTH + 1;
+	reg empty;
+	reg epo;
+	reg pae;
+	reg underflow;
+	reg e1;
+	reg e2;
+	reg o1;
+	reg o2;
+	reg q1;
+	reg q2;
+	reg [1:0] bwl_sel;
+	reg [1:0] gmode;
+	reg [ADDR_WIDTH - 1:0] ff_raddr;
+	reg [ADDR_WIDTH:0] waddr;
+	reg [ADDR_WIDTH:0] raddr;
+	reg [ADDR_WIDTH:0] gcout_reg;
+	reg [ADDR_WIDTH:0] gcout_next;
+	reg [ADDR_WIDTH:0] waddr_next;
+	reg [ADDR_WIDTH - 1:0] pae_thresh;
+	wire ren_out;
+	wire empty_next;
+	wire pae_next;
+	wire epo_next;
+	wire [ADDR_WIDTH - 2:0] gc32out_next;
+	wire [ADDR_WIDTH - 1:0] gc16out_next;
+	wire [ADDR_WIDTH:0] gc8out_next;
+	wire [ADDR_WIDTH:0] raddr_next;
+	wire [ADDR_WIDTH - 1:0] ff_raddr_next;
+	wire [ADDR_WIDTH:0] tmp;
+	wire [ADDR_PLUS_ONE:0] next_count;
+	wire [ADDR_PLUS_ONE:0] count;
+	wire [ADDR_PLUS_ONE:0] fbytes;
+	genvar i;
+	assign next_count = waddr - raddr_next;
+	assign count = waddr - raddr;
+	assign fbytes = 1 << (DEPTH + 5);
+	always @(*) pae_thresh = rmode[1] ? upae : (rmode[0] ? upae << 1 : upae << 2);
+	assign ren_out = (empty ? 1'b1 : ren_in);
+	always @(*)
+		case (rmode)
+			2'h0: gmode = 2'h0;
+			2'h1: gmode = (wmode == 2'h0 ? 2'h0 : 2'h1);
+			2'h2: gmode = (wmode == 2'h2 ? 2'h2 : wmode);
+			2'h3: gmode = 2'h3;
+		endcase
+	always @(*) begin
+		e1 = 1'b0;
+		e2 = 1'b0;
+		o1 = 1'b0;
+		o2 = 1'b0;
+		q1 = next_count < {1'b0, pae_thresh};
+		q2 = count < {1'b0, pae_thresh};
+		case (rmode)
+			2'h0: begin
+				e1 = raddr_next[ADDR_WIDTH:2] == waddr_next[ADDR_WIDTH:2];
+				e2 = raddr[ADDR_WIDTH:2] == waddr_next[ADDR_WIDTH:2];
+				o1 = (raddr_next[ADDR_WIDTH:2] + 1) == waddr_next[ADDR_WIDTH:2];
+				o2 = (raddr[ADDR_WIDTH:2] + 1) == waddr_next[ADDR_WIDTH:2];
+			end
+			2'h1: begin
+				e1 = raddr_next[ADDR_WIDTH:1] == waddr_next[ADDR_WIDTH:1];
+				e2 = raddr[ADDR_WIDTH:1] == waddr_next[ADDR_WIDTH:1];
+				o1 = (raddr_next[ADDR_WIDTH:1] + 1) == waddr_next[ADDR_WIDTH:1];
+				o2 = (raddr[ADDR_WIDTH:1] + 1) == waddr_next[ADDR_WIDTH:1];
+			end
+			2'h2: begin
+				e1 = raddr_next[ADDR_WIDTH:0] == waddr_next[ADDR_WIDTH:0];
+				e2 = raddr[ADDR_WIDTH:0] == waddr_next[ADDR_WIDTH:0];
+				o1 = (raddr_next[ADDR_WIDTH:0] + 1) == waddr_next[ADDR_WIDTH:0];
+				o2 = (raddr[ADDR_WIDTH:0] + 1) == waddr_next[11:0];
+			end
+			2'h3: begin
+				e1 = 1'b0;
+				e2 = 1'b0;
+				o1 = 1'b0;
+				o2 = 1'b0;
+			end
+		endcase
+	end
+	assign empty_next = (ren_in & !empty ? e1 : e2);
+	assign epo_next = (ren_in & !empty ? o1 : o2);
+	assign pae_next = (ren_in & !empty ? q1 : q2);
+	always @(posedge rclk or negedge rst_n)
+		if (~rst_n) begin
+			empty <= 1'b1;
+			pae <= 1'b1;
+			epo <= 1'b0;
+		end
+		else begin
+			empty <= empty_next;
+			pae <= pae_next;
+			epo <= epo_next;
+		end
+	assign gc8out_next = (raddr_next >> 1) ^ raddr_next;
+	assign gc16out_next = (raddr_next >> 2) ^ (raddr_next >> 1);
+	assign gc32out_next = (raddr_next >> 3) ^ (raddr_next >> 2);
+	always @(*)
+		if (ren_in)
+			case (gmode)
+				2'h2: gcout_next = gc8out_next;
+				2'h1: gcout_next = {1'b0, gc16out_next};
+				2'h0: gcout_next = {2'b00, gc32out_next};
+				default: gcout_next = 'h0;
+			endcase
+		else
+			gcout_next = 'h0;
+	always @(posedge rclk or negedge rst_n)
+		if (~rst_n)
+			waddr <= 12'h000;
+		else
+			waddr <= waddr_next;
+	always @(posedge rclk or negedge rst_n)
+		if (~rst_n) begin
+			underflow <= 1'b0;
+			bwl_sel <= 2'h0;
+			gcout_reg <= 12'h000;
+		end
+		else if (ren_in) begin
+			underflow <= empty;
+			if (!empty) begin
+				bwl_sel <= raddr_next[1:0];
+				gcout_reg <= gcout_next;
+			end
+		end
+	generate
+		for (i = 0; i < (ADDR_WIDTH + 1); i = i + 1) begin : genblk1
+			assign tmp[i] = ^(gcin >> i);
+		end
+	endgenerate
+	always @(*)
+		case (gmode)
+			2'h0: waddr_next = {tmp[ADDR_WIDTH - 2:0], 2'b00} & {{ADDR_WIDTH - 1 {1'b1}}, 2'b00};
+			2'h1: waddr_next = {tmp[ADDR_WIDTH - 1:0], 1'b0} & {{ADDR_WIDTH {1'b1}}, 1'b0};
+			2'h2: waddr_next = {tmp[ADDR_WIDTH:0]} & {ADDR_PLUS_ONE {1'b1}};
+			default: waddr_next = {ADDR_PLUS_ONE {1'b0}};
+		endcase
+	assign ff_raddr_next = ff_raddr + (rmode == 2'h0 ? 'h4 : (rmode == 2'h1 ? 'h2 : 'h1));
+	assign raddr_next = raddr + (rmode == 2'h0 ? 'h4 : (rmode == 2'h1 ? 'h2 : 'h1));
+	always @(posedge rclk or negedge rst_n)
+		if (~rst_n)
+			ff_raddr <= 1'sb0;
+		else if (empty & ~empty_next)
+			ff_raddr <= raddr_next[ADDR_WIDTH - 1:0];
+		else if ((ren_in & !empty) & ~empty_next)
+			ff_raddr <= ff_raddr_next;
+	always @(posedge rclk or negedge rst_n)
+		if (~rst_n)
+			raddr <= 12'h000;
+		else if (ren_in & !empty)
+			raddr <= raddr_next;
+	always @(*)
+		case (FIFO_WIDTH)
+			3'h2: out_raddr = {ff_raddr[ADDR_WIDTH - 1:1], bwl_sel[0]};
+			3'h4: out_raddr = {ff_raddr[ADDR_WIDTH - 1:2], bwl_sel};
+			default: out_raddr = ff_raddr[ADDR_WIDTH - 1:0];
+		endcase
+	assign ren_o = ren_out;
+	assign gcout = gcout_reg;
+	assign popflags = {empty, epo, pae, underflow};
+endmodule
+`default_nettype none
diff --git a/yosys-plugins/ql-qlf/quicklogic_eqn.cc b/yosys-plugins/ql-qlf/quicklogic_eqn.cc
new file mode 100644
index 000000000..b82a1b286
--- /dev/null
+++ b/yosys-plugins/ql-qlf/quicklogic_eqn.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/sigtools.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct QuicklogicEqnPass : public Pass {
+    QuicklogicEqnPass() : Pass("quicklogic_eqn", "Quicklogic: Calculate equations for luts") {}
+    void help() override
+    {
+        log("\n");
+        log("    quicklogic_eqn [selection]\n");
+        log("\n");
+        log("Calculate equations for luts since bitstream generator depends on it.\n");
+        log("\n");
+    }
+
+    Const init2eqn(Const init, int inputs)
+    {
+        std::string init_bits = init.as_string();
+        const char *names[] = {"I0", "I1", "I2", "I3", "I4"};
+
+        std::string eqn;
+        int width = (int)pow(2, inputs);
+        for (int i = 0; i < width; i++) {
+            if (init_bits[width - 1 - i] == '1') {
+                eqn += "(";
+                for (int j = 0; j < inputs; j++) {
+                    if (i & (1 << j))
+                        eqn += names[j];
+                    else
+                        eqn += std::string("~") + names[j];
+
+                    if (j != (inputs - 1))
+                        eqn += "*";
+                }
+                eqn += ")+";
+            }
+        }
+        if (eqn.empty())
+            return Const("0");
+        eqn = eqn.substr(0, eqn.length() - 1);
+        return Const(eqn);
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        log_header(design, "Executing Quicklogic_EQN pass (calculate equations for luts).\n");
+
+        extra_args(args, args.size(), design);
+
+        int cnt = 0;
+        for (auto module : design->selected_modules()) {
+            for (auto cell : module->selected_cells()) {
+                if (cell->type == ID(LUT1)) {
+                    cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT), 1));
+                    cnt++;
+                }
+                if (cell->type == ID(LUT2)) {
+                    cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT), 2));
+                    cnt++;
+                }
+                if (cell->type == ID(LUT3)) {
+                    cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT), 3));
+                    cnt++;
+                }
+                if (cell->type == ID(LUT4)) {
+                    cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT), 4));
+                    cnt++;
+                }
+                if (cell->type == ID(LUT5)) {
+                    cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT), 5));
+                    cnt++;
+                }
+            }
+        }
+        log_header(design, "Updated %d of LUT* elements with equation.\n", cnt);
+    }
+} QuicklogicEqnPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/synth_quicklogic.cc b/yosys-plugins/ql-qlf/synth_quicklogic.cc
new file mode 100644
index 000000000..2816daade
--- /dev/null
+++ b/yosys-plugins/ql-qlf/synth_quicklogic.cc
@@ -0,0 +1,522 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/celltypes.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#define XSTR(val) #val
+#define STR(val) XSTR(val)
+
+#ifndef PASS_NAME
+#define PASS_NAME synth_quicklogic
+#endif
+
+struct SynthQuickLogicPass : public ScriptPass {
+
+    SynthQuickLogicPass() : ScriptPass(STR(PASS_NAME), "Synthesis for QuickLogic FPGAs") {}
+
+    void help() override
+    {
+        log("\n");
+        log("   %s [options]\n", STR(PASS_NAME));
+        log("This command runs synthesis for QuickLogic FPGAs\n");
+        log("\n");
+        log("    -top <module>\n");
+        log("         use the specified module as top module\n");
+        log("\n");
+        log("    -family <family>\n");
+        log("        run synthesis for the specified QuickLogic architecture\n");
+        log("        generate the synthesis netlist for the specified family.\n");
+        log("        supported values:\n");
+        log("        - pp3      : pp3 \n");
+        log("        - qlf_k4n8 : qlf_k4n8 \n");
+        log("        - qlf_k6n10: qlf_k6n10 \n");
+        log("        - qlf_k6n10f: qlf_k6n10f \n");
+        log("\n");
+        log("    -no_abc_opt\n");
+        log("        By default most of ABC logic optimization features is\n");
+        log("        enabled. Specifying this switch turns them off.\n");
+        log("\n");
+        log("    -edif <file>\n");
+        log("        write the design to the specified edif file. writing of an output file\n");
+        log("        is omitted if this parameter is not specified.\n");
+        log("\n");
+        log("    -blif <file>\n");
+        log("        write the design to the specified BLIF file. writing of an output file\n");
+        log("        is omitted if this parameter is not specified.\n");
+        log("\n");
+        log("    -verilog <file>\n");
+        log("        write the design to the specified verilog file. writing of an output file\n");
+        log("        is omitted if this parameter is not specified.\n");
+        log("\n");
+        log("    -no_dsp\n");
+        log("        By default use DSP blocks in output netlist.\n");
+        log("        do not use DSP blocks to implement multipliers and associated logic\n");
+        log("\n");
+        log("    -use_dsp_cfg_params\n");
+        log("        By default use DSP blocks with configuration bits available at module ports.\n");
+        log("        Specifying this forces usage of DSP block with configuration bits available as module parameters\n");
+        log("\n");
+        log("    -no_adder\n");
+        log("        By default use adder cells in output netlist.\n");
+        log("        Specifying this switch turns it off.\n");
+        log("\n");
+        log("    -no_bram\n");
+        log("        By default use Block RAM in output netlist.\n");
+        log("        Specifying this switch turns it off.\n");
+        log("\n");
+        log("    -no_ff_map\n");
+        log("        By default ff techmap is turned on. Specifying this switch turns it off.\n");
+        log("\n");
+        log("    -nosdff\n");
+        log("        By default infer synchronous S/R flip-flops for architectures\n");
+        log("        that support them. \n");
+        log("        Specifying this switch turns it off.\n");
+        log("\n");
+        log("\n");
+        log("The following commands are executed by this synthesis command:\n");
+        help_script();
+        log("\n");
+    }
+
+    string top_opt, edif_file, blif_file, family, currmodule, verilog_file, use_dsp_cfg_params;
+    bool nodsp;
+    bool inferAdder;
+    bool inferBram;
+    bool abcOpt;
+    bool abc9;
+    bool noffmap;
+    bool nosdff;
+
+    void clear_flags() override
+    {
+        top_opt = "-auto-top";
+        edif_file = "";
+        blif_file = "";
+        verilog_file = "";
+        currmodule = "";
+        family = "qlf_k4n8";
+        inferAdder = true;
+        inferBram = true;
+        abcOpt = true;
+        abc9 = true;
+        noffmap = false;
+        nodsp = false;
+        nosdff = false;
+        use_dsp_cfg_params = "";
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        string run_from, run_to;
+        clear_flags();
+
+        size_t argidx;
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            if (args[argidx] == "-run" && argidx + 1 < args.size()) {
+                size_t pos = args[argidx + 1].find(':');
+                if (pos == std::string::npos) {
+                    run_from = args[++argidx];
+                    run_to = args[argidx];
+                } else {
+                    run_from = args[++argidx].substr(0, pos);
+                    run_to = args[argidx].substr(pos + 1);
+                }
+                continue;
+            }
+            if (args[argidx] == "-top" && argidx + 1 < args.size()) {
+                top_opt = "-top " + args[++argidx];
+                continue;
+            }
+            if (args[argidx] == "-edif" && argidx + 1 < args.size()) {
+                edif_file = args[++argidx];
+                continue;
+            }
+
+            if (args[argidx] == "-family" && argidx + 1 < args.size()) {
+                family = args[++argidx];
+                continue;
+            }
+            if (args[argidx] == "-blif" && argidx + 1 < args.size()) {
+                blif_file = args[++argidx];
+                continue;
+            }
+            if (args[argidx] == "-verilog" && argidx + 1 < args.size()) {
+                verilog_file = args[++argidx];
+                continue;
+            }
+            if (args[argidx] == "-no_dsp") {
+                nodsp = true;
+                continue;
+            }
+            if (args[argidx] == "-use_dsp_cfg_params") {
+                use_dsp_cfg_params = " -use_dsp_cfg_params";
+                continue;
+            }
+            if (args[argidx] == "-no_adder") {
+                inferAdder = false;
+                continue;
+            }
+            if (args[argidx] == "-no_bram") {
+                inferBram = false;
+                continue;
+            }
+            if (args[argidx] == "-no_abc_opt") {
+                abcOpt = false;
+                continue;
+            }
+            if (args[argidx] == "-no_abc9") {
+                abc9 = false;
+                continue;
+            }
+            if (args[argidx] == "-no_ff_map") {
+                noffmap = true;
+                continue;
+            }
+            if (args[argidx] == "-nosdff") {
+                nosdff = true;
+                continue;
+            }
+
+            break;
+        }
+        extra_args(args, argidx, design);
+
+        if (!design->full_selection())
+            log_cmd_error("This command only operates on fully selected designs!\n");
+
+        if (family != "pp3" && family != "qlf_k4n8" && family != "qlf_k6n10" && family != "qlf_k6n10f")
+            log_cmd_error("Invalid family specified: '%s'\n", family.c_str());
+
+        if (family != "pp3") {
+            abc9 = false;
+        }
+
+        if (family == "qlf_k4n8") {
+            nosdff = true;
+        }
+
+        if (abc9 && design->scratchpad_get_int("abc9.D", 0) == 0) {
+            log_warning("delay target has not been set via SDC or scratchpad; assuming 12 MHz clock.\n");
+            design->scratchpad_set_int("abc9.D", 41667); // 12MHz = 83.33.. ns; divided by two to allow for interconnect delay.
+        }
+
+        log_header(design, "Executing SYNTH_QUICKLOGIC pass.\n");
+        log_push();
+
+        run_script(design, run_from, run_to);
+
+        log_pop();
+    }
+
+    void script() override
+    {
+        if (check_label("begin")) {
+            std::string family_path = " +/quicklogic/" + family;
+            std::string readVelArgs;
+
+            // Read simulation library
+            readVelArgs = family_path + "/cells_sim.v";
+            if (family == "qlf_k6n10f")
+                readVelArgs += family_path + "/dsp_sim.v";
+
+            // Use -nomem2reg here to prevent Yosys from complaining about
+            // some block ram cell models. After all the only part of the cells
+            // library required here is cell port definitions plus specify blocks.
+            run("read_verilog -lib -specify -nomem2reg +/quicklogic/common/cells_sim.v" + readVelArgs);
+            run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+        }
+
+        if (check_label("prepare")) {
+            run("proc");
+            run("flatten");
+            if (family == "pp3") {
+                run("tribuf -logic");
+            }
+            run("deminout");
+            run("opt_expr");
+            run("opt_clean");
+        }
+
+        std::string noDFFArgs;
+        if (nosdff) {
+            noDFFArgs += " -nosdff";
+        }
+        if (family == "qlf_k4n8") {
+            noDFFArgs += " -nodffe";
+        }
+
+        if (check_label("coarse")) {
+            run("check");
+            run("opt -nodffe -nosdff");
+            run("fsm");
+            run("opt" + noDFFArgs);
+            run("wreduce");
+            run("peepopt");
+            run("opt_clean");
+            run("share");
+
+            if (family == "qlf_k6n10") {
+                if (help_mode || !nodsp) {
+                    run("memory_dff");
+                    run("wreduce t:$mul");
+                    run("techmap -map +/mul2dsp.v -map +/quicklogic/" + family +
+                          "/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
+                          "-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
+                          "-D DSP_NAME=$__MUL16X16",
+                        "(for qlf_k6n10 if not -no_dsp)");
+                    run("select a:mul2dsp", "              (for qlf_k6n10 if not -no_dsp)");
+                    run("setattr -unset mul2dsp", "        (for qlf_k6n10 if not -no_dsp)");
+                    run("opt_expr -fine", "                (for qlf_k6n10 if not -no_dsp)");
+                    run("wreduce", "                       (for qlf_k6n10 if not -no_dsp)");
+                    run("select -clear", "                 (for qlf_k6n10 if not -no_dsp)");
+                    run("ql_dsp", "                        (for qlf_k6n10 if not -no_dsp)");
+                    run("chtype -set $mul t:$__soft_mul", "(for qlf_k6n10 if not -no_dsp)");
+                }
+            } else if (family == "qlf_k6n10f") {
+
+                struct DspParams {
+                    size_t a_maxwidth;
+                    size_t b_maxwidth;
+                    size_t a_minwidth;
+                    size_t b_minwidth;
+                    std::string type;
+                };
+
+                const std::vector<DspParams> dsp_rules = {
+                  {20, 18, 11, 10, "$__QL_MUL20X18"},
+                  {10, 9, 4, 4, "$__QL_MUL10X9"},
+                };
+
+                if (help_mode) {
+                    run("wreduce t:$mul", "                  (for qlf_k6n10f if not -no_dsp)");
+                    run("ql_dsp_macc" + use_dsp_cfg_params, "(for qlf_k6n10f if not -no_dsp)");
+                    run("techmap -map +/mul2dsp.v [...]", "  (for qlf_k6n10f if not -no_dsp)");
+                    run("chtype -set $mul t:$__soft_mul", "  (for qlf_k6n10f if not -no_dsp)");
+                    run("techmap -map +/quicklogic/" + family + "/dsp_map.v", "(for qlf_k6n10f if not -no_dsp)");
+                    if (use_dsp_cfg_params.empty())
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0", "(for qlf_k6n10f if not -no_dsp)");
+                    else
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=1", "(for qlf_k6n10f if not -no_dsp)");
+                    run("ql_dsp_simd                   ", "(for qlf_k6n10f if not -no_dsp)");
+                    run("techmap -map +/quicklogic/" + family + "/dsp_final_map.v", "(for qlf_k6n10f if not -no_dsp)");
+                    run("ql_dsp_io_regs");
+                } else if (!nodsp) {
+
+                    run("wreduce t:$mul");
+                    run("ql_dsp_macc" + use_dsp_cfg_params);
+
+                    for (const auto &rule : dsp_rules) {
+                        run(stringf("techmap -map +/mul2dsp.v "
+                                    "-D DSP_A_MAXWIDTH=%zu -D DSP_B_MAXWIDTH=%zu "
+                                    "-D DSP_A_MINWIDTH=%zu -D DSP_B_MINWIDTH=%zu "
+                                    "-D DSP_NAME=%s",
+                                    rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.type.c_str()));
+                        run("chtype -set $mul t:$__soft_mul");
+                    }
+                    if (use_dsp_cfg_params.empty())
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0");
+                    else
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=1");
+                    run("ql_dsp_simd");
+                    run("techmap -map +/quicklogic/" + family + "/dsp_final_map.v");
+                    run("ql_dsp_io_regs");
+                }
+            }
+
+            run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+            run("opt_expr");
+            run("opt_clean");
+            run("alumacc");
+            run("pmuxtree");
+            run("opt" + noDFFArgs);
+            run("memory -nomap");
+            run("opt_clean");
+        }
+
+        if (family == "qlf_k6n10f") {
+            run("ql_bram_asymmetric");
+        }
+
+        if (check_label("map_bram", "(skip if -no_bram)") && (family == "qlf_k6n10" || family == "qlf_k6n10f" || family == "pp3") && inferBram) {
+            run("memory_bram -rules +/quicklogic/" + family + "/brams.txt");
+            if (family == "pp3") {
+                run("pp3_braminit");
+            }
+            run("ql_bram_split                   ", "(for qlf_k6n10f if not -no_bram)");
+            run("techmap -autoproc -map +/quicklogic/" + family + "/brams_map.v");
+            if (family == "qlf_k6n10f") {
+                run("techmap -map +/quicklogic/" + family + "/brams_final_map.v");
+            }
+        }
+
+        if (check_label("map_ffram")) {
+            run("opt -fast -mux_undef -undriven -fine" + noDFFArgs);
+            run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
+                "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
+                "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+            run("opt -undriven -fine" + noDFFArgs);
+        }
+
+        if (check_label("map_gates")) {
+            if (inferAdder && (family == "qlf_k4n8" || family == "qlf_k6n10" || family == "qlf_k6n10f")) {
+                run("techmap -map +/techmap.v -map +/quicklogic/" + family + "/arith_map.v");
+            } else {
+                run("techmap");
+            }
+            run("opt -fast" + noDFFArgs);
+            if (family == "pp3") {
+                run("muxcover -mux8 -mux4");
+            }
+            run("opt_expr");
+            run("opt_merge");
+            run("opt_clean");
+            run("opt" + noDFFArgs);
+        }
+
+        if (check_label("map_ffs")) {
+            run("opt_expr");
+            if (family == "qlf_k4n8") {
+                run("shregmap -minlen 8 -maxlen 8");
+                run("dfflegalize -cell $_DFF_P_ 0 -cell $_DFF_P??_ 0 -cell $_DFF_N_ 0 -cell $_DFF_N??_ 0 -cell $_DFFSR_???_ 0");
+            } else if (family == "qlf_k6n10") {
+                run("dfflegalize -cell $_DFF_P_ 0 -cell $_DFF_PP?_ 0 -cell $_DFFE_PP?P_ 0 -cell $_DFFSR_PPP_ 0 -cell $_DFFSRE_PPPP_ 0 -cell "
+                    "$_DLATCHSR_PPP_ 0");
+                //    In case we add clock inversion in the future.
+                //    run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_DFFSR_?PP_ 0 -cell $_DFFSRE_?PPP_ 0 -cell
+                //    $_DLATCH_SRPPP_ 0");
+            } else if (family == "qlf_k6n10f") {
+                run("shregmap -minlen 8 -maxlen 20");
+                // FIXME: dfflegalize seems to leave $_DLATCH_[NP]_ even if it
+                // is not allowed. So we allow them and map them later to
+                // $_DLATCHSR_[NP]NN_.
+                std::string legalizeArgs = " -cell $_DFFSRE_?NNP_ 0 -cell $_DLATCHSR_?NN_ 0 -cell $_DLATCH_?_ 0";
+                if (!nosdff) {
+                    legalizeArgs += " -cell $_SDFFE_?N?P_ 0";
+                }
+                run("dfflegalize" + legalizeArgs);
+            } else if (family == "pp3") {
+                run("dfflegalize -cell $_DFFSRE_PPPP_ 0 -cell $_DLATCH_?_ x");
+                run("techmap -map +/quicklogic/" + family + "/cells_map.v");
+            }
+            std::string techMapArgs = " -map +/techmap.v -map +/quicklogic/" + family + "/ffs_map.v";
+            if (!noffmap) {
+                run("techmap " + techMapArgs);
+            }
+            if (family == "pp3") {
+                run("opt_expr -mux_undef");
+            }
+            run("opt_merge");
+            run("opt_clean");
+            run("opt" + noDFFArgs);
+        }
+
+        if (check_label("map_luts")) {
+            if (abcOpt) {
+                if (family == "qlf_k6n10" || family == "qlf_k6n10f") {
+                    run("abc -lut 6 ");
+                } else if (family == "qlf_k4n8") {
+                    run("abc -lut 4 ");
+                } else if (family == "pp3") {
+                    run("techmap -map +/quicklogic/" + family + "/latches_map.v");
+                    if (abc9) {
+                        run("read_verilog -lib -specify -icells +/quicklogic/" + family + "/abc9_model.v");
+                        run("techmap -map +/quicklogic/" + family + "/abc9_map.v");
+                        run("abc9 -maxlut 4 -dff");
+                        run("techmap -map +/quicklogic/" + family + "/abc9_unmap.v");
+                    } else {
+                        std::string lutDefs = "+/quicklogic/" + family + "/lutdefs.txt";
+                        rewrite_filename(lutDefs);
+
+                        std::string abcArgs = "+read_lut," + lutDefs +
+                                              ";"
+                                              "strash;ifraig;scorr;dc2;dretime;strash;dch,-f;if;mfs2;" // Common Yosys ABC script
+                                              "sweep;eliminate;if;mfs;lutpack;"                        // Optimization script
+                                              "dress";                                                 // "dress" to preserve names
+
+                        run("abc -script " + abcArgs);
+                    }
+                }
+            }
+            run("clean");
+            run("opt_lut");
+        }
+
+        if (check_label("map_cells") && (family == "qlf_k6n10" || family == "pp3")) {
+            std::string techMapArgs;
+            techMapArgs = "-map +/quicklogic/" + family + "/lut_map.v";
+            run("techmap " + techMapArgs);
+            run("clean");
+        }
+
+        if (check_label("check")) {
+            run("autoname");
+            run("hierarchy -check");
+            run("stat");
+            run("check -noinit");
+        }
+
+        if (check_label("iomap") && family == "pp3") {
+            run("clkbufmap -inpad ckpad Q:P");
+            run("iopadmap -bits -outpad outpad A:P -inpad inpad Q:P -tinoutpad bipad EN:Q:A:P A:top");
+        }
+
+        if (check_label("finalize")) {
+            if (family == "pp3") {
+                run("setundef -zero -params -undriven");
+            }
+            if (family == "pp3" || (check_label("edif") && (!edif_file.empty()))) {
+                run("hilomap -hicell logic_1 a -locell logic_0 a -singleton A:top");
+            }
+            run("opt_clean -purge");
+            run("check");
+            run("blackbox =A:whitebox");
+        }
+
+        if (check_label("blif")) {
+            if (!blif_file.empty()) {
+                if (inferAdder) {
+                    run(stringf("write_blif -param %s", help_mode ? "<file-name>" : blif_file.c_str()));
+                } else {
+                    run(stringf("write_blif %s", help_mode ? "<file-name>" : blif_file.c_str()));
+                }
+            }
+        }
+
+        if (check_label("edif") && (!edif_file.empty())) {
+            run("splitnets -ports -format ()");
+            run("quicklogic_eqn");
+
+            run(stringf("write_ql_edif -nogndvcc -attrprop -pvector par %s %s", this->currmodule.c_str(), edif_file.c_str()));
+        }
+
+        if (check_label("verilog")) {
+            if (!verilog_file.empty()) {
+                run("write_verilog -noattr -nohex " + verilog_file);
+            }
+        }
+    }
+
+} SynthQuicklogicPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/ql-qlf/tests/.gitignore b/yosys-plugins/ql-qlf/tests/.gitignore
new file mode 100644
index 000000000..9766475a4
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/.gitignore
@@ -0,0 +1 @@
+ok
diff --git a/yosys-plugins/ql-qlf/tests/Makefile b/yosys-plugins/ql-qlf/tests/Makefile
new file mode 100644
index 000000000..661e92ece
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/Makefile
@@ -0,0 +1,80 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# The bram test will be enable in a future PR after it's been fixed.
+
+TESTS = \
+	consts \
+	dffs \
+	latches \
+	shreg \
+	iob_no_flatten \
+	full_adder \
+	mac_unit \
+	multiplier \
+	logic \
+	mux \
+	tribuf \
+	fsm \
+	pp3_bram \
+	qlf_k6n10f/dsp_mult \
+	qlf_k6n10f/dsp_simd \
+	qlf_k6n10f/dsp_macc \
+	qlf_k6n10f/dsp_madd
+#	qlf_k6n10_bram \
+
+SIM_TESTS = \
+    qlf_k6n10f/sim_dsp_mult_cfg_ports \
+    qlf_k6n10f/sim_dsp_mult_cfg_params \
+    qlf_k6n10f/sim_dsp_mult_r_cfg_ports \
+    qlf_k6n10f/sim_dsp_mult_r_cfg_params \
+    qlf_k6n10f/sim_dsp_fir_cfg_ports \
+    qlf_k6n10f/sim_dsp_fir_cfg_params \
+    qlf_k6n10f/sim_dsp_simd_cfg_ports \
+    qlf_k6n10f/sim_dsp_simd_cfg_params \
+    qlf_k6n10f/sim_tc36fifo
+
+# Those tests perform synthesis and simulation of synthesis results
+POST_SYNTH_SIM_TESTS = \
+    qlf_k6n10f/bram_tdp \
+    qlf_k6n10f/bram_sdp \
+    qlf_k6n10f/bram_tdp_split \
+    qlf_k6n10f/bram_sdp_split \
+    qlf_k6n10f/dsp_mult_post_synth_sim \
+    qlf_k6n10f/dsp_simd_post_synth_sim \
+    qlf_k6n10f/bram_asymmetric_wider_write \
+    qlf_k6n10f/bram_asymmetric_wider_read
+
+include $(shell pwd)/../../Makefile_test.common
+
+consts_verify = true
+dffs_verify = true
+shreg_verify = true
+iob_no_flatten_verify = true
+latches_verify = true
+full_adder_verify = true
+mac_unit_verify = true
+multiplier_verify = true
+logic_verify = true
+mux_verify = true
+tribuf_verify = true
+fsm_verify = true
+pp3_bram_verify = true
+qlf_k6n10f-dsp_mult_verify = true
+qlf_k6n10f-dsp_simd_verify = true
+qlf_k6n10f-dsp_macc_verify = true
+qlf_k6n10f-dsp_madd_verify = true
+#qlf_k6n10_bram_verify = true
diff --git a/yosys-plugins/ql-qlf/tests/consts/consts.tcl b/yosys-plugins/ql-qlf/tests/consts/consts.tcl
new file mode 100644
index 000000000..270f6790c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/consts/consts.tcl
@@ -0,0 +1,14 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+synth_quicklogic -top my_top -family pp3
+stat
+yosys cd my_top
+select -assert-count 1 t:my_lut
+select -assert-count 1 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
diff --git a/yosys-plugins/ql-qlf/tests/consts/consts.v b/yosys-plugins/ql-qlf/tests/consts/consts.v
new file mode 100644
index 000000000..59e411cfa
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/consts/consts.v
@@ -0,0 +1,45 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+(* keep_hierarchy *)
+module my_lut (
+    input  wire [3:0] i,
+    output wire       o
+);
+
+  LUT4 #(
+      .INIT(16'hAAAA)
+  ) my_lut (
+      .I0(i[0]),
+      .I1(i[1]),
+      .I2(i[2]),
+      .I3(1'bx),
+      .O (o)
+  );
+
+endmodule
+
+module my_top (
+    input  wire i,
+    output wire o
+);
+
+  my_lut my_lut (
+      .i({1'b0, 1'b1, i}),
+      .o(o)
+  );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/dffs/dffs.tcl b/yosys-plugins/ql-qlf/tests/dffs/dffs.tcl
new file mode 100644
index 000000000..4e8792eab
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/dffs/dffs.tcl
@@ -0,0 +1,1048 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# =============================================================================
+# qlf_k4n8
+
+# DFF
+hierarchy -top my_dff
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8 -top my_dff
+synth_quicklogic -family qlf_k4n8 -top my_dff
+design -load postopt
+yosys cd my_dff
+stat
+select -assert-count 1 t:dffsr
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffr_p
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffr_p_2
+yosys cd my_dffr_p_2
+stat
+select -assert-count 2 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFR (negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffr_n
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:dffsr
+
+# DFFS (posedge SET)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffs_p
+yosys cd my_dffs_p
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFS (negedge SET)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffs_n
+yosys cd my_dffs_n
+stat
+select -assert-count 1 t:dffsr
+
+# DFFN
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffn
+yosys cd my_dffn
+stat
+select -assert-count 1 t:dffnsr
+
+
+# DFFNR (negedge CLK posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffnr_p
+yosys cd my_dffnr_p
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 1 t:\$lut
+
+# DFFNR (negedge CLK negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffnr_n
+yosys cd my_dffnr_n
+stat
+select -assert-count 1 t:dffnsr
+
+# DFFNS (negedge CLK posedge SET)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffns_p
+yosys cd my_dffns_p
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 1 t:\$lut
+
+# DFFS (negedge CLK negedge SET)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffns_n
+yosys cd my_dffns_n
+stat
+select -assert-count 1 t:dffnsr
+
+# DFFSR (posedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_ppp
+yosys cd my_dffsr_ppp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_pnp
+yosys cd my_dffsr_pnp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_ppn
+yosys cd my_dffsr_ppn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (posedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_pnn
+yosys cd my_dffsr_pnn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (negedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_npp
+yosys cd my_dffsr_npp
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_nnp
+yosys cd my_dffsr_nnp
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_npn
+yosys cd my_dffsr_npn
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (negedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k4n8 -top my_dffsr_nnn
+yosys cd my_dffsr_nnn
+stat
+select -assert-count 1 t:dffnsr
+select -assert-count 1 t:\$lut
+
+design -reset
+
+# =============================================================================
+# qlf_k6n10
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# DFF
+hierarchy -top my_dff
+yosys proc
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10 -top my_dff
+design -load postopt
+yosys cd my_dff
+stat
+select -assert-count 1 t:dff
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_p
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffr
+
+# DFFR (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_p_2
+yosys cd my_dffr_p_2
+stat
+select -assert-count 2 t:dffr
+
+# DFFR (negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffr_n
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:dffr
+select -assert-count 1 t:\$lut
+
+#DFFRE (posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffre_p
+yosys cd my_dffre_p
+stat
+select -assert-count 1 t:dffre
+
+#DFFRE (negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffre_n
+yosys cd my_dffre_n
+stat
+select -assert-count 1 t:dffre
+select -assert-count 1 t:\$lut
+
+# DFFS (posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffs_p
+yosys cd my_dffs_p
+stat
+select -assert-count 1 t:dffs
+
+# DFFS (negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffs_n
+yosys cd my_dffs_n
+stat
+select -assert-count 1 t:dffs
+select -assert-count 1 t:\$lut
+
+# DFFSE (posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffse_p
+yosys cd my_dffse_p
+stat
+select -assert-count 1 t:dffse
+
+# DFFSE (negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffse_n
+yosys cd my_dffse_n
+stat
+select -assert-count 1 t:dffse
+
+# DFFN
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffn
+yosys cd my_dffn
+stat
+select -assert-count 1 t:dff
+select -assert-count 1 t:\$lut
+
+# DFFNR (negedge CLK posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffnr_p
+yosys cd my_dffnr_p
+stat
+select -assert-count 1 t:dffr
+select -assert-count 1 t:\$lut
+
+# DFFNR (negedge CLK negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffnr_n
+yosys cd my_dffnr_n
+stat
+select -assert-count 1 t:dffr
+select -assert-count 2 t:\$lut
+
+# DFFNS (negedge CLK posedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffns_p
+yosys cd my_dffns_p
+stat
+select -assert-count 1 t:dffs
+select -assert-count 1 t:\$lut
+
+# DFFS (negedge CLK negedge SET)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffns_n
+yosys cd my_dffns_n
+stat
+select -assert-count 1 t:dffs
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_ppp
+yosys cd my_dffsr_ppp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (posedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_pnp
+yosys cd my_dffsr_pnp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 1 t:\$lut
+
+# DFFSR (posedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_ppn
+yosys cd my_dffsr_ppn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (posedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_pnn
+yosys cd my_dffsr_pnn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_npp
+yosys cd my_dffsr_npp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_nnp
+yosys cd my_dffsr_nnp
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 2 t:\$lut
+
+# DFFSR (negedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_npn
+yosys cd my_dffsr_npn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 3 t:\$lut
+
+# DFFSR (negedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsr_nnn
+yosys cd my_dffsr_nnn
+stat
+select -assert-count 1 t:dffsr
+select -assert-count 3 t:\$lut
+
+# DFFSRE (posedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_ppp
+yosys cd my_dffsre_ppp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE (posedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_pnp
+yosys cd my_dffsre_pnp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE (posedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_ppn
+yosys cd my_dffsre_ppn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (posedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_pnn
+yosys cd my_dffsre_pnn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK posedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_npp
+yosys cd my_dffsre_npp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK negedge SET posedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_nnp
+yosys cd my_dffsre_nnp
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 2 t:\$lut
+
+# DFFSRE (negedge CLK posedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_npn
+yosys cd my_dffsre_npn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 3 t:\$lut
+
+# DFFSRE (negedge CLK negedge SET negedge RST)
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_dffsre_nnn
+yosys cd my_dffsre_nnn
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 3 t:\$lut
+
+design -reset
+
+# =============================================================================
+# qlf_k6n10f (with synchronous S/R flip-flops)
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# DFF
+hierarchy -top my_dff
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dff
+design -load postopt
+yosys cd my_dff
+stat
+select -assert-count 1 t:sdffsre
+
+# DFFN
+design -load read
+hierarchy -top my_dffn
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffn
+design -load postopt
+yosys cd my_dffn
+stat
+select -assert-count 1 t:sdffnsre
+
+
+# DFFSRE from DFFR_N
+design -load read
+hierarchy -top my_dffr_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffr_n
+design -load postopt
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFR_P
+design -load read
+hierarchy -top my_dffr_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffr_p
+design -load postopt
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE from DFFRE_N
+design -load read
+hierarchy -top my_dffre_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffre_n
+design -load postopt
+yosys cd my_dffre_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFRE_P
+design -load read
+hierarchy -top my_dffre_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffre_p
+design -load postopt
+yosys cd my_dffre_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+
+# DFFSRE from DFFS_N
+design -load read
+hierarchy -top my_dffs_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffs_n
+design -load postopt
+yosys cd my_dffs_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFS_P
+design -load read
+hierarchy -top my_dffs_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffs_p
+design -load postopt
+yosys cd my_dffs_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE from DFFSE_N
+design -load read
+hierarchy -top my_dffse_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffse_n
+design -load postopt
+yosys cd my_dffse_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFSE_P
+design -load read
+hierarchy -top my_dffse_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffse_p
+design -load postopt
+yosys cd my_dffse_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+
+# SDFFSRE from SDFFR_N
+design -load read
+hierarchy -top my_sdffr_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffr_n
+design -load postopt
+yosys cd my_sdffr_n
+stat
+select -assert-count 1 t:sdffsre
+
+# SDFFSRE from SDFFR_P
+design -load read
+hierarchy -top my_sdffr_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffr_p
+design -load postopt
+yosys cd my_sdffr_p
+stat
+select -assert-count 1 t:sdffsre
+select -assert-count 1 t:\$lut
+
+# SDFFSRE from SDFFS_N
+design -load read
+hierarchy -top my_sdffs_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffs_n
+design -load postopt
+yosys cd my_sdffs_n
+stat
+select -assert-count 1 t:sdffsre
+
+# SDFFSRE from SDFFS_P
+design -load read
+hierarchy -top my_sdffs_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffs_p
+design -load postopt
+yosys cd my_sdffs_p
+stat
+select -assert-count 1 t:sdffsre
+select -assert-count 1 t:\$lut
+
+
+# SDFFNSRE from SDFFNR_N
+design -load read
+hierarchy -top my_sdffnr_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffnr_n
+design -load postopt
+yosys cd my_sdffnr_n
+stat
+select -assert-count 1 t:sdffnsre
+
+# SDFFNSRE from SDFFRN_P
+design -load read
+hierarchy -top my_sdffnr_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffnr_p
+design -load postopt
+yosys cd my_sdffnr_p
+stat
+select -assert-count 1 t:sdffnsre
+select -assert-count 1 t:\$lut
+
+# SDFFNSRE from SDFFNS_N
+design -load read
+hierarchy -top my_sdffns_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffns_n
+design -load postopt
+yosys cd my_sdffns_n
+stat
+select -assert-count 1 t:sdffnsre
+
+# SDFFSRE from SDFFNS_P
+design -load read
+hierarchy -top my_sdffns_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_sdffns_p
+design -load postopt
+yosys cd my_sdffns_p
+stat
+select -assert-count 1 t:sdffnsre
+select -assert-count 1 t:\$lut
+
+
+# LATCH
+design -load read
+hierarchy -top my_latch
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latch
+design -load postopt
+yosys cd my_latch
+stat
+select -assert-count 1 t:latchsre
+
+# LATCHN
+design -load read
+hierarchy -top my_latchn
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchn
+design -load postopt
+yosys cd my_latchn
+stat
+select -assert-count 1 t:latchnsre
+
+
+## LATCHSRE from LATCHR_N
+#design -load read
+#hierarchy -top my_latchr_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchr_n
+#design -load postopt
+#yosys cd my_latchr_n
+#stat
+#select -assert-count 1 t:latchr_n
+#
+## LATCHSRE from LATCHR_P
+#design -load read
+#hierarchy -top my_latchr_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchr_p
+#design -load postopt
+#yosys cd my_latchr_p
+#stat
+#select -assert-count 1 t:latchr_p
+#select -assert-count 1 t:\$lut
+#
+## LATCHSRE from LATCHS_N
+#design -load read
+#hierarchy -top my_latchs_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchs_n
+#design -load postopt
+#yosys cd my_latchs_n
+#stat
+#select -assert-count 1 t:latchs_n
+#
+## LATCHSRE from LATCHS_P
+#design -load read
+#hierarchy -top my_latchs_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchs_p
+#design -load postopt
+#yosys cd my_latchs_p
+#stat
+#select -assert-count 1 t:latchs_p
+#select -assert-count 1 t:\$lut
+#
+#
+## LATCHSRE from LATCHNR_N
+#design -load read
+#hierarchy -top my_latchnr_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchnr_n
+#design -load postopt
+#yosys cd my_latchnr_n
+#stat
+#select -assert-count 1 t:latchnr_n
+#
+## LATCHSRE from LATCHNR_P
+#design -load read
+#hierarchy -top my_latchnr_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchnr_p
+#design -load postopt
+#yosys cd my_latchnr_p
+#stat
+#select -assert-count 1 t:latchnr_p
+#select -assert-count 1 t:\$lut
+#
+## LATCHSRE from LATCHNS_N
+#design -load read
+#hierarchy -top my_latchns_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchns_n
+#design -load postopt
+#yosys cd my_latchns_n
+#stat
+#select -assert-count 1 t:latchns_n
+#
+## LATCHSRE from LATCHNS_P
+#design -load read
+#hierarchy -top my_latchns_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchns_p
+#design -load postopt
+#yosys cd my_latchns_p
+#stat
+#select -assert-count 1 t:latchns_p
+#select -assert-count 1 t:\$lut
+
+
+design -reset
+
+# =============================================================================
+# qlf_k6n10f (no synchronous S/R flip-flops)
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# DFF
+hierarchy -top my_dff
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dff -nosdff
+design -load postopt
+yosys cd my_dff
+stat
+select -assert-count 1 t:dffsre
+
+# DFFN
+design -load read
+hierarchy -top my_dffn
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffn -nosdff
+design -load postopt
+yosys cd my_dffn
+stat
+select -assert-count 1 t:dffnsre
+
+
+# DFFSRE from DFFR_N
+design -load read
+hierarchy -top my_dffr_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffr_n -nosdff
+design -load postopt
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFR_P
+design -load read
+hierarchy -top my_dffr_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffr_p -nosdff
+design -load postopt
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE from DFFRE_N
+design -load read
+hierarchy -top my_dffre_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffre_n -nosdff
+design -load postopt
+yosys cd my_dffre_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFRE_P
+design -load read
+hierarchy -top my_dffre_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffre_p -nosdff
+design -load postopt
+yosys cd my_dffre_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+
+# DFFSRE from DFFS_N
+design -load read
+hierarchy -top my_dffs_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffs_n -nosdff
+design -load postopt
+yosys cd my_dffs_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFS_P
+design -load read
+hierarchy -top my_dffs_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffs_p -nosdff
+design -load postopt
+yosys cd my_dffs_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+# DFFSRE from DFFSE_N
+design -load read
+hierarchy -top my_dffse_n
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffse_n -nosdff
+design -load postopt
+yosys cd my_dffse_n
+stat
+select -assert-count 1 t:dffsre
+
+# DFFSRE from DFFSE_P
+design -load read
+hierarchy -top my_dffse_p
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_dffse_p -nosdff
+design -load postopt
+yosys cd my_dffse_p
+stat
+select -assert-count 1 t:dffsre
+select -assert-count 1 t:\$lut
+
+
+# LATCH
+design -load read
+hierarchy -top my_latch
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latch -nosdff
+design -load postopt
+yosys cd my_latch
+stat
+select -assert-count 1 t:latchsre
+
+# LATCHN
+design -load read
+hierarchy -top my_latchn
+yosys proc
+equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchn -nosdff
+design -load postopt
+yosys cd my_latchn
+stat
+select -assert-count 1 t:latchnsre
+
+
+## LATCHSRE from LATCHR_N
+#design -load read
+#hierarchy -top my_latchr_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchr_n -nosdff
+#design -load postopt
+#yosys cd my_latchr_n
+#stat
+#select -assert-count 1 t:latchr_n
+#
+## LATCHSRE from LATCHR_P
+#design -load read
+#hierarchy -top my_latchr_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchr_p -nosdff
+#design -load postopt
+#yosys cd my_latchr_p
+#stat
+#select -assert-count 1 t:latchr_p
+#select -assert-count 1 t:\$lut
+#
+## LATCHSRE from LATCHS_N
+#design -load read
+#hierarchy -top my_latchs_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchs_n -nosdff
+#design -load postopt
+#yosys cd my_latchs_n
+#stat
+#select -assert-count 1 t:latchs_n
+#
+## LATCHSRE from LATCHS_P
+#design -load read
+#hierarchy -top my_latchs_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchs_p -nosdff
+#design -load postopt
+#yosys cd my_latchs_p
+#stat
+#select -assert-count 1 t:latchs_p
+#select -assert-count 1 t:\$lut
+#
+#
+## LATCHSRE from LATCHNR_N
+#design -load read
+#hierarchy -top my_latchnr_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchnr_n -nosdff
+#design -load postopt
+#yosys cd my_latchnr_n
+#stat
+#select -assert-count 1 t:latchnr_n
+#
+## LATCHSRE from LATCHNR_P
+#design -load read
+#hierarchy -top my_latchnr_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchnr_p -nosdff
+#design -load postopt
+#yosys cd my_latchnr_p
+#stat
+#select -assert-count 1 t:latchnr_p
+#select -assert-count 1 t:\$lut
+#
+## LATCHSRE from LATCHNS_N
+#design -load read
+#hierarchy -top my_latchns_n
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchns_n -nosdff
+#design -load postopt
+#yosys cd my_latchns_n
+#stat
+#select -assert-count 1 t:latchns_n
+#
+## LATCHSRE from LATCHNS_P
+#design -load read
+#hierarchy -top my_latchns_p
+#yosys proc
+#equiv_opt -assert -async2sync -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f -top my_latchns_p -nosdff
+#design -load postopt
+#yosys cd my_latchns_p
+#stat
+#select -assert-count 1 t:latchns_p
+#select -assert-count 1 t:\$lut
+
+design -reset
+
+# =============================================================================
+
+# DFF on pp3 device
+design -reset
+
+# DFF on pp3 device
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# DFF
+hierarchy -top my_dff
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_dff
+design -load postopt
+yosys cd my_dff
+stat
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:ckpad
+select -assert-count 1 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+
+# DFFE
+design -load read
+hierarchy -top my_dffe
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_dffe
+design -load postopt
+yosys cd my_dffe
+stat
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:ckpad
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:logic_0
+
+# ADFF a.k.a. DFFR_P
+design -load read
+hierarchy -top my_dffr_p
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_dffr_p
+design -load postopt
+yosys cd my_dffr_p
+stat
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 1 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 2 t:ckpad
+
+select -assert-none t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+# ADFFN a.k.a. DFFR_N
+design -load read
+hierarchy -top my_dffr_n
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_dffr_n
+design -load postopt
+yosys cd my_dffr_n
+stat
+select -assert-count 1 t:LUT1
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT1 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+# DFFS (posedge, sync set)
+design -load read
+hierarchy -top my_sdffs_p
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_sdffs_p
+design -load postopt
+yosys cd my_sdffs_p
+stat
+select -assert-count 1 t:LUT2
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
+# DFFS (negedge, sync reset)
+design -load read
+hierarchy -top my_sdffns_p
+yosys proc
+equiv_opt -async2sync -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3 -top my_sdffns_p
+design -load postopt
+yosys cd my_sdffns_p
+stat
+select -assert-count 1 t:LUT1
+select -assert-count 1 t:LUT2
+select -assert-count 1 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT1 t:LUT2 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
diff --git a/yosys-plugins/ql-qlf/tests/dffs/dffs.v b/yosys-plugins/ql-qlf/tests/dffs/dffs.v
new file mode 100644
index 000000000..e29b7f341
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/dffs/dffs.v
@@ -0,0 +1,639 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module my_dff (
+    input d,
+    clk,
+    output reg q
+);
+  always @(posedge clk) q <= d;
+endmodule
+
+module my_dffe (
+    input d,
+    clk,
+    en,
+    output reg q
+);
+  initial begin
+    q = 0;
+  end
+  always @(posedge clk) if (en) q <= d;
+endmodule
+
+module my_dffr_p (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  always @(posedge clk or posedge clr)
+    if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffr_p_2 (
+    input d1,
+    input d2,
+    clk,
+    clr,
+    output reg q1,
+    output reg q2
+);
+  always @(posedge clk or posedge clr)
+    if (clr) begin
+      q1 <= 1'b0;
+      q2 <= 1'b0;
+    end else begin
+      q1 <= d1;
+      q2 <= d2;
+    end
+endmodule
+
+module my_dffr_n (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  always @(posedge clk or negedge clr)
+    if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffre_p (
+    input d,
+    clk,
+    clr,
+    en,
+    output reg q
+);
+  always @(posedge clk or posedge clr)
+    if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffre_n (
+    input d,
+    clk,
+    clr,
+    en,
+    output reg q
+);
+  always @(posedge clk or negedge clr)
+    if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffs_p (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  always @(posedge clk or posedge pre)
+    if (pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_dffs_n (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  always @(posedge clk or negedge pre)
+    if (!pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_dffse_p (
+    input d,
+    clk,
+    pre,
+    en,
+    output reg q
+);
+  always @(posedge clk or posedge pre)
+    if (pre) q <= 1'b1;
+    else if (en) q <= d;
+endmodule
+
+module my_dffse_n (
+    input d,
+    clk,
+    pre,
+    en,
+    output reg q
+);
+  always @(posedge clk or negedge pre)
+    if (!pre) q <= 1'b1;
+    else if (en) q <= d;
+endmodule
+
+module my_dffn (
+    input d,
+    clk,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk) q <= d;
+endmodule
+
+module my_dffnr_p (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge clr)
+    if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffnr_n (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge clr)
+    if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+
+module my_dffns_p (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre)
+    if (pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_dffns_n (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre)
+    if (!pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_dffsr_ppp (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_pnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_ppn (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_pnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_npp (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_nnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_npn (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsr_nnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_dffsre_ppp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_pnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_ppn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_pnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(posedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_npp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or posedge clr)
+    if (pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_nnp (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or posedge clr)
+    if (!pre) q <= 1'b1;
+    else if (clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_npn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or posedge pre or negedge clr)
+    if (pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_dffsre_nnn (
+    input d,
+    clk,
+    pre,
+    clr,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @(negedge clk or negedge pre or negedge clr)
+    if (!pre) q <= 1'b1;
+    else if (!clr) q <= 1'b0;
+    else if (en) q <= d;
+endmodule
+
+module my_sdffr_n (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 0;
+  always @(posedge clk)
+    if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_sdffs_n (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 0;
+  always @(posedge clk)
+    if (!pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_sdffnr_n (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 0;
+  always @(negedge clk)
+    if (!clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_sdffns_n(
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 0;
+  always @(negedge clk)
+    if (!pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_sdffr_p (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 0;
+  always @(posedge clk)
+    if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_sdffs_p (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 0;
+  always @(posedge clk)
+    if (pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+module my_sdffnr_p (
+    input d,
+    clk,
+    clr,
+    output reg q
+);
+  initial q <= 0;
+  always @(negedge clk)
+    if (clr) q <= 1'b0;
+    else q <= d;
+endmodule
+
+module my_sdffns_p (
+    input d,
+    clk,
+    pre,
+    output reg q
+);
+  initial q <= 0;
+  always @(negedge clk)
+    if (pre) q <= 1'b1;
+    else q <= d;
+endmodule
+
+
+module my_latch (
+    input  wire d, g,
+    output reg  q
+);
+    always @(*)
+        if (g) q <= d;
+endmodule
+
+module my_latchn (
+    input  wire d, g,
+    output reg  q
+);
+    always @(*)
+        if (!g) q <= d;
+endmodule
+
+
+module my_latchs_p (
+    input  wire d, g, s,
+    output reg  q
+);
+    always @(*)
+        if (s)
+            q <= 1'b1;
+        else if (g)
+            q <= d;
+endmodule
+
+module my_latchs_n (
+    input  wire d, g, s,
+    output reg  q
+);
+    always @(*)
+        if (!s)
+            q <= 1'b1;
+        else if (g)
+            q <= d;
+endmodule
+
+module my_latchr_p (
+    input  wire d, g, r,
+    output reg  q
+);
+    always @(*)
+        if (r)
+            q <= 1'b0;
+        else if (g)
+            q <= d;
+endmodule
+
+module my_latchr_n (
+    input  wire d, g, r,
+    output reg  q
+);
+    always @(*)
+        if (!r)
+            q <= 1'b0;
+        else if (g)
+            q <= d;
+endmodule
+
+
+module my_latchns_p (
+    input  wire d, g, s,
+    output reg  q
+);
+    always @(*)
+        if (s)
+            q <= 1'b1;
+        else if (!g)
+            q <= d;
+endmodule
+
+module my_latchns_n (
+    input  wire d, g, s,
+    output reg  q
+);
+    always @(*)
+        if (!s)
+            q <= 1'b1;
+        else if (!g)
+            q <= d;
+endmodule
+
+module my_latchnr_p (
+    input  wire d, g, r,
+    output reg  q
+);
+    always @(*)
+        if (r)
+            q <= 1'b0;
+        else if (!g)
+            q <= d;
+endmodule
+
+module my_latchnr_n (
+    input  wire d, g, r,
+    output reg  q
+);
+    always @(*)
+        if (!r)
+            q <= 1'b0;
+        else if (!g)
+            q <= d;
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/fsm/fsm.tcl b/yosys-plugins/ql-qlf/tests/fsm/fsm.tcl
new file mode 100644
index 000000000..61a1e108e
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/fsm/fsm.tcl
@@ -0,0 +1,30 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+hierarchy -top fsm
+yosys proc
+flatten
+
+equiv_opt -run :prove -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+async2sync
+miter -equiv -make_assert -flatten gold gate miter
+sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
+
+design -load postopt
+yosys cd fsm
+
+select -assert-count 1 t:LUT2
+select -assert-count 9 t:LUT3
+select -assert-count 4 t:dffepc
+select -assert-count 1 t:logic_0
+select -assert-count 1 t:logic_1
+select -assert-count 3 t:inpad
+select -assert-count 2 t:outpad
+select -assert-count 1 t:ckpad
+
+select -assert-none t:LUT2 t:LUT3 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D
+
diff --git a/yosys-plugins/ql-qlf/tests/fsm/fsm.v b/yosys-plugins/ql-qlf/tests/fsm/fsm.v
new file mode 100644
index 000000000..beea38a8b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/fsm/fsm.v
@@ -0,0 +1,76 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module fsm (
+    clock,
+    reset,
+    req_0,
+    req_1,
+    gnt_0,
+    gnt_1
+);
+  input clock, reset, req_0, req_1;
+  output gnt_0, gnt_1;
+  wire clock, reset, req_0, req_1;
+  reg gnt_0, gnt_1;
+
+  parameter SIZE = 3;
+  parameter IDLE = 3'b001;
+  parameter GNT0 = 3'b010;
+  parameter GNT1 = 3'b100;
+  parameter GNT2 = 3'b101;
+
+  reg [SIZE-1:0] state;
+  reg [SIZE-1:0] next_state;
+
+  always @(posedge clock) begin : FSM
+    if (reset == 1'b1) begin
+      state <= #1 IDLE;
+      gnt_0 <= 0;
+      gnt_1 <= 0;
+    end else
+      case (state)
+        IDLE:
+        if (req_0 == 1'b1) begin
+          state <= #1 GNT0;
+          gnt_0 <= 1;
+        end else if (req_1 == 1'b1) begin
+          gnt_1 <= 1;
+          state <= #1 GNT0;
+        end else begin
+          state <= #1 IDLE;
+        end
+        GNT0:
+        if (req_0 == 1'b1) begin
+          state <= #1 GNT0;
+        end else begin
+          gnt_0 <= 0;
+          state <= #1 IDLE;
+        end
+        GNT1:
+        if (req_1 == 1'b1) begin
+          state <= #1 GNT2;
+          gnt_1 <= req_0;
+        end
+        GNT2:
+        if (req_0 == 1'b1) begin
+          state <= #1 GNT1;
+          gnt_1 <= req_1;
+        end
+        default: state <= #1 IDLE;
+      endcase
+  end
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/full_adder/full_adder.tcl b/yosys-plugins/ql-qlf/tests/full_adder/full_adder.tcl
new file mode 100644
index 000000000..83b68cb8c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/full_adder/full_adder.tcl
@@ -0,0 +1,155 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+# Equivalence check for adder synthesis for qlf-k4n8
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top full_adder
+yosys proc
+equiv_opt -assert -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8
+
+design -reset
+
+# Equivalence check for subtractor synthesis
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top subtractor
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8
+design -reset
+
+# Equivalence check for comparator synthesis
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top comparator
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8
+design -reset
+
+# Equivalence check for adder synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top full_adder
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10
+design -load postopt
+yosys cd full_adder
+stat
+select -assert-count 6 t:adder
+
+design -reset
+
+# Equivalence check for subtractor synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top subtractor
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10
+design -load postopt
+yosys cd subtractor
+stat
+select -assert-count 6 t:adder
+
+design -reset
+
+# Equivalence check for comparator synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top comparator
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10
+design -load postopt
+yosys cd comparator
+stat
+select -assert-count 5 t:adder
+
+design -reset
+
+# Equivalence check for adder synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top full_adder
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f
+design -load postopt
+yosys cd full_adder
+stat
+select -assert-count 5 t:adder_carry
+
+design -reset
+
+# Equivalence check for subtractor synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top subtractor
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f
+design -load postopt
+yosys cd subtractor
+stat
+select -assert-count 5 t:adder_carry
+
+design -reset
+
+# Equivalence check for comparator synthesis for qlf-k6n10
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top comparator
+yosys proc
+equiv_opt -assert  -map +/quicklogic/qlf_k6n10f/cells_sim.v synth_quicklogic -family qlf_k6n10f
+design -load postopt
+yosys cd comparator
+stat
+select -assert-count 4 t:adder_carry
+
+design -reset
+
+# Equivalence check for adder synthesis for pp3
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top full_adder
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd full_adder
+
+stat
+select -assert-count 2 t:LUT2
+select -assert-count 6 t:LUT3
+select -assert-count 8 t:inpad
+select -assert-count 5 t:outpad
+
+select -assert-none t:LUT2 t:LUT3 t:inpad t:outpad %% t:* %D
+
+
+design -reset
+
+# Equivalence check for subtractor synthesis for pp3
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top subtractor
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd subtractor
+
+stat
+select -assert-count 2 t:LUT2
+select -assert-count 6 t:LUT3
+select -assert-count 8 t:inpad
+select -assert-count 5 t:outpad
+
+select -assert-none t:LUT2 t:LUT3 t:inpad t:outpad %% t:* %D
+
+design -reset
+
+# Equivalence check for comparator synthesis for pp3
+read_verilog -icells -DWIDTH=4 $::env(DESIGN_TOP).v
+hierarchy -check -top comparator
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd comparator
+
+stat
+
+# Types and counts of LUTs inferred seem to differ depending on the way Yosys
+# is built. In any case the equivalence check passes. Disabling cell count
+# assertions for now.
+# I've opened an issue https://github.com/SymbiFlow/yosys-f4pga-plugins/issues/284
+
+#select -assert-count 3 t:LUT2
+#select -assert-count 2 t:LUT4
+#select -assert-count 8 t:inpad
+#select -assert-count 1 t:outpad
+#select -assert-none t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D
diff --git a/yosys-plugins/ql-qlf/tests/full_adder/full_adder.v b/yosys-plugins/ql-qlf/tests/full_adder/full_adder.v
new file mode 100644
index 000000000..dad416312
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/full_adder/full_adder.v
@@ -0,0 +1,46 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module full_adder (
+    input  wire [`WIDTH-1:0] A,
+    input  wire [`WIDTH-1:0] B,
+    output wire [`WIDTH  :0] S,
+);
+
+    // Implicit adder
+    assign S = A + B;
+
+endmodule
+
+module subtractor (
+    input  wire [`WIDTH-1:0] A,
+    input  wire [`WIDTH-1:0] B,
+    output wire [`WIDTH  :0] S,
+);
+
+    // Implicit subtractor
+    assign S = A - B;
+
+endmodule
+
+module comparator (
+    input  wire [`WIDTH-1:0] A,
+    input  wire [`WIDTH-1:0] B,
+    output wire CO,
+);
+    assign CO = (A <= B) ? 1'b1 : 1'b0;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.tcl b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.tcl
new file mode 100644
index 000000000..6e6ccb5bd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.tcl
@@ -0,0 +1,19 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+synth_quicklogic -family qlf_k4n8 -top my_top
+yosys stat
+yosys cd my_top
+select -assert-count 2 t:dffsr
+
+design -reset
+
+read_verilog $::env(DESIGN_TOP).v
+
+synth_quicklogic -family qlf_k6n10 -top my_top
+yosys stat
+yosys cd my_top
+select -assert-count 2 t:dff
diff --git a/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.v b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.v
new file mode 100644
index 000000000..2b64567bf
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.v
@@ -0,0 +1,58 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module my_dff (
+    input d,
+    clk,
+    output reg q
+);
+  always @(posedge clk) q <= d;
+endmodule
+
+module my_top (
+    inout  wire pad,
+    input  wire i,
+    input  wire t,
+    output wire o,
+    input  wire clk
+);
+
+  wire i_r;
+  wire t_r;
+  wire o_r;
+
+  // IOB
+  assign pad = (t_r) ? i_r : 1'bz;
+  assign o_r = pad;
+
+  // DFFs
+  my_dff dff_i (
+      i,
+      clk,
+      i_r
+  );
+  my_dff dff_t (
+      t,
+      clk,
+      t_r
+  );
+  my_dff dff_o (
+      o_r,
+      clk,
+      o
+  );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.ys b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.ys
new file mode 100644
index 000000000..1dfc87c27
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/iob_no_flatten/iob_no_flatten.ys
@@ -0,0 +1,7 @@
+plugin -i ql-qlf
+read_verilog ./iob_no_flatten.v
+
+synth_quicklogic -family qlf_k4n8 -top my_top
+stat
+cd my_top
+select -assert-count 2 t:$_DFF_P_
diff --git a/yosys-plugins/ql-qlf/tests/latches/latches.tcl b/yosys-plugins/ql-qlf/tests/latches/latches.tcl
new file mode 100644
index 000000000..72b31d831
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/latches/latches.tcl
@@ -0,0 +1,89 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+# Tests for qlf_k6n10 family
+# LATCHP
+design -load read
+synth_quicklogic -family qlf_k6n10 -top latchp
+yosys cd latchp
+stat
+select -assert-count 1 t:latchsre
+
+# LATCHN
+design -load read
+synth_quicklogic -family qlf_k6n10 -top latchn
+yosys cd latchn
+stat
+select -assert-count 1 t:\$lut
+select -assert-count 1 t:latchsre
+
+# LATCHSRE
+design -load read
+synth_quicklogic -family qlf_k6n10 -top my_latchsre
+yosys cd my_latchsre
+stat
+select -assert-count 2 t:\$lut
+select -assert-count 1 t:latchsre
+
+## Tests for qlf_k4n8 family
+## Currently disabled cause latch aren't supported
+## in synth_quicklogic for that family
+## LATCHP
+#synth_quicklogic -family qlf_k4n8 -top latchp
+#yosys cd latchp
+#stat
+#select -assert-count 1 t:\$_DLATCH_P_
+#
+## LATCHP no init
+#design -load read
+#synth_quicklogic -family qlf_k4n8 -top latchp_noinit
+#yosys cd latchp_noinit
+#stat
+#select -assert-count 1 t:\$_DLATCH_P_
+
+# Latches for PP3
+
+# LATCHP
+design -load read
+hierarchy -top latchp_noinit
+yosys proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic -family pp3 -top latchp_noinit
+yosys cd latchp_noinit
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+# LATCHN
+design -load read
+hierarchy -top latchn
+yosys proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic -family pp3 -top latchn
+yosys cd latchn
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+# LATCHSRE
+design -load read
+hierarchy -top my_latchsre
+yosys proc
+# Can't run any sort of equivalence check because latches are blown to LUTs
+synth_quicklogic -family pp3 -top my_latchsre
+yosys cd my_latchsre
+select -assert-count 1 t:LUT2
+select -assert-count 1 t:LUT4
+select -assert-count 5 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT2 t:LUT4 t:inpad t:outpad %% t:* %D
+
diff --git a/yosys-plugins/ql-qlf/tests/latches/latches.v b/yosys-plugins/ql-qlf/tests/latches/latches.v
new file mode 100644
index 000000000..4d691b375
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/latches/latches.v
@@ -0,0 +1,57 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module latchp (
+    input d,
+    clk,
+    en,
+    output reg q
+);
+  initial q <= 1'b0;
+  always @* if (en) q <= d;
+endmodule
+
+module latchn (
+    input d,
+    clk,
+    en,
+    output reg q
+);
+  always @* if (!en) q <= d;
+endmodule
+
+module my_latchsre (
+    input d,
+    clk,
+    en,
+    clr,
+    pre,
+    output reg q
+);
+  always @*
+    if (clr) q <= 1'b0;
+    else if (pre) q <= 1'b1;
+    else if (en) q <= d;
+endmodule
+
+module latchp_noinit (
+    input d,
+    clk,
+    en,
+    output reg q
+);
+  always @* if (en) q <= d;
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/logic/logic.tcl b/yosys-plugins/ql-qlf/tests/logic/logic.tcl
new file mode 100644
index 000000000..b1de9f73c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/logic/logic.tcl
@@ -0,0 +1,46 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+#Logic test for qlf_k4n8 device
+read_verilog $::env(DESIGN_TOP).v
+hierarchy -top top
+yosys proc
+equiv_opt -assert -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8
+design -load postopt
+yosys cd top
+
+stat
+select -assert-count 9 t:\$lut
+
+design -reset
+
+#Logic test for qlf_k6n10 device
+read_verilog $::env(DESIGN_TOP).v
+hierarchy -top top
+yosys proc
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10
+design -load postopt
+yosys cd top
+
+stat
+select -assert-count 9 t:\$lut
+
+design -reset
+
+#Logic test for pp3 device
+read_verilog $::env(DESIGN_TOP).v
+hierarchy -top top
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd top
+
+stat
+select -assert-count 1 t:LUT1
+select -assert-count 6 t:LUT2
+select -assert-count 2 t:LUT3
+select -assert-count 8 t:inpad
+select -assert-count 10 t:outpad
+
+select -assert-none t:LUT1 t:LUT2 t:LUT3 t:inpad t:outpad %% t:* %D
diff --git a/yosys-plugins/ql-qlf/tests/logic/logic.v b/yosys-plugins/ql-qlf/tests/logic/logic.v
new file mode 100644
index 000000000..cdf1fca40
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/logic/logic.v
@@ -0,0 +1,40 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input [0:7] in,
+    output B1,
+    B2,
+    B3,
+    B4,
+    B5,
+    B6,
+    B7,
+    B8,
+    B9,
+    B10
+);
+  assign B1  = in[0] & in[1];
+  assign B2  = in[0] | in[1];
+  assign B3  = in[0]~&in[1];
+  assign B4  = in[0]~|in[1];
+  assign B5  = in[0] ^ in[1];
+  assign B6  = in[0] ~^ in[1];
+  assign B7  = ~in[0];
+  assign B8  = in[0];
+  assign B9  = in[0:1] && in[2:3];
+  assign B10 = in[0:1] || in[2:3];
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/logic/logic.ys b/yosys-plugins/ql-qlf/tests/logic/logic.ys
new file mode 100644
index 000000000..037896c37
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/logic/logic.ys
@@ -0,0 +1,10 @@
+plugin -i ql-qlf
+read_verilog ./logic.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/quicklogic/qlf_k4n8/cells_sim.v synth_quicklogic -family qlf_k4n8
+design -load postopt
+cd top
+
+stat
+select -assert-count 9 t:$lut
diff --git a/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.tcl b/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.tcl
new file mode 100644
index 000000000..0db32a985
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.tcl
@@ -0,0 +1,22 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+set TOP "mac_unit"
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+#Infer QL_DSP
+hierarchy -top $TOP
+synth_quicklogic -family qlf_k6n10 -top $TOP
+yosys cd $TOP
+stat
+select -assert-count 1 t:QL_DSP
+
+#Test no_dsp arg
+design -load read
+hierarchy -top $TOP
+synth_quicklogic -family qlf_k6n10 -top $TOP -no_dsp
+yosys cd $TOP
+stat
+select -assert-count 0 t:QL_DSP
diff --git a/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.v b/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.v
new file mode 100644
index 000000000..7644ef710
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/mac_unit/mac_unit.v
@@ -0,0 +1,28 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mac_unit (
+    a,
+    b,
+    out
+);
+  parameter DATA_WIDTH = 16;
+  input [DATA_WIDTH - 1 : 0] a, b;
+  output [2*DATA_WIDTH - 1 : 0] out;
+
+  assign out = a * b + out;
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/multiplier/multiplier.tcl b/yosys-plugins/ql-qlf/tests/multiplier/multiplier.tcl
new file mode 100644
index 000000000..5c783c258
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/multiplier/multiplier.tcl
@@ -0,0 +1,22 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+set TOP "mult16x16"
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+#Infer QL_DSP
+hierarchy -top $TOP
+synth_quicklogic -family qlf_k6n10 -top $TOP
+yosys cd $TOP
+stat
+select -assert-count 1 t:QL_DSP
+
+#Test no_dsp arg
+design -load read
+hierarchy -top $TOP
+synth_quicklogic -family qlf_k6n10 -top $TOP -no_dsp
+yosys cd $TOP
+stat
+select -assert-count 0 t:QL_DSP
diff --git a/yosys-plugins/ql-qlf/tests/multiplier/multiplier.v b/yosys-plugins/ql-qlf/tests/multiplier/multiplier.v
new file mode 100644
index 000000000..a5522653c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/multiplier/multiplier.v
@@ -0,0 +1,27 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mult16x16 (
+    a,
+    b,
+    out
+);
+  parameter DATA_WIDTH = 16;
+  input [DATA_WIDTH - 1 : 0] a, b;
+  output [2*DATA_WIDTH - 1 : 0] out;
+
+  assign out = a * b;
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/mux/mux.tcl b/yosys-plugins/ql-qlf/tests/mux/mux.tcl
new file mode 100644
index 000000000..3d0f94981
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/mux/mux.tcl
@@ -0,0 +1,56 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+hierarchy -top mux2
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd mux2
+select -assert-count 1 t:LUT3
+select -assert-count 3 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux4
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd mux4
+select -assert-count 3 t:LUT3
+select -assert-count 6 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux8
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd mux8
+select -assert-count 1 t:LUT1
+select -assert-count 1 t:LUT3
+select -assert-count 2 t:mux4x0
+select -assert-count 11 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT1 t:LUT3 t:mux4x0 t:inpad t:outpad %% t:* %D
+
+design -load read
+hierarchy -top mux16
+yosys proc
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd mux16
+select -assert-count 1 t:LUT3
+select -assert-count 2 t:mux8x0
+select -assert-count 20 t:inpad
+select -assert-count 1 t:outpad
+
+select -assert-none t:LUT3 t:mux8x0 t:inpad t:outpad %% t:* %D
diff --git a/yosys-plugins/ql-qlf/tests/mux/mux.v b/yosys-plugins/ql-qlf/tests/mux/mux.v
new file mode 100644
index 000000000..6ec90d19e
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/mux/mux.v
@@ -0,0 +1,91 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mux2 (
+    S,
+    A,
+    B,
+    Y
+);
+  input S;
+  input A, B;
+  output reg Y;
+
+  always @(*) Y = (S) ? B : A;
+endmodule
+
+module mux4 (
+    S,
+    D,
+    Y
+);
+  input [1:0] S;
+  input [3:0] D;
+  output Y;
+
+  reg Y;
+  wire [1:0] S;
+  wire [3:0] D;
+
+  always @* begin
+    case (S)
+      0: Y = D[0];
+      1: Y = D[1];
+      2: Y = D[2];
+      3: Y = D[3];
+    endcase
+  end
+endmodule
+
+module mux8 (
+    S,
+    D,
+    Y
+);
+  input [2:0] S;
+  input [7:0] D;
+  output Y;
+
+  reg Y;
+  wire [2:0] S;
+  wire [7:0] D;
+
+  always @* begin
+    case (S)
+      0: Y = D[0];
+      1: Y = D[1];
+      2: Y = D[2];
+      3: Y = D[3];
+      4: Y = D[4];
+      5: Y = D[5];
+      6: Y = D[6];
+      7: Y = D[7];
+    endcase
+  end
+endmodule
+
+module mux16 (
+    D,
+    S,
+    Y
+);
+  input [15:0] D;
+  input [3:0] S;
+  output Y;
+
+  assign Y = D[S];
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/pp3_bram/init.txt b/yosys-plugins/ql-qlf/tests/pp3_bram/init.txt
new file mode 100644
index 000000000..9d8fb6f10
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/pp3_bram/init.txt
@@ -0,0 +1,6 @@
+@000
+1234
+5678
+ABCD
+EFFF
+
diff --git a/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.tcl b/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.tcl
new file mode 100644
index 000000000..eadfda3cd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.tcl
@@ -0,0 +1,47 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+design -save read
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_9_16
+yosys cd top_bram_9_16
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 35 t:inpad
+select -assert-count 16 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_9_32
+yosys cd top_bram_9_32
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 51 t:inpad
+select -assert-count 32 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+design -load read
+synth_quicklogic -family pp3 -top top_bram_10_16
+yosys cd top_bram_10_16
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 37 t:inpad
+select -assert-count 16 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+# BRAM initialization from file using pp3_braminig pass test
+design -load read
+synth_quicklogic -family pp3 -top top_bram_init
+yosys cd top_bram_init
+stat
+select -assert-count 1 t:ckpad
+select -assert-count 39 t:inpad
+select -assert-count 18 t:outpad
+select -assert-count 1 t:ram8k_2x1_cell_macro
+
+set INIT 8192'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efffabcd56781234
+select -assert-count 1 t:ram8k_2x1_cell_macro r:INIT=$INIT \%i
+
diff --git a/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.v b/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.v
new file mode 100644
index 000000000..9adf5cfc7
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/pp3_bram/pp3_bram.v
@@ -0,0 +1,190 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module my_ram (
+    CLK,
+    WADR,
+    WDAT,
+    WEN,
+    RADR,
+    RDAT,
+    REN
+);
+
+  parameter DBITS = 36;
+  parameter ABITS = 9;
+
+  input wire CLK;
+
+  input wire [ABITS-1:0] WADR;
+  input wire [DBITS-1:0] WDAT;
+  input wire WEN;
+
+  input wire [ABITS-1:0] RADR;
+  output reg [DBITS-1:0] RDAT;
+  input wire REN;
+
+  localparam SIZE = 1 << ABITS;
+  reg [DBITS-1:0] mem[0:SIZE-1];
+
+  always @(posedge CLK) begin
+    if (WEN) mem[WADR] <= WDAT;
+  end
+
+  always @(posedge CLK) begin
+    RDAT <= mem[RADR];
+  end
+
+endmodule
+
+// ============================================================================
+
+module top_bram_9_16 (
+    CLK,
+    WADR,
+    WDAT,
+    WEN,
+    RADR,
+    RDAT
+);
+
+  input wire CLK;
+
+  input wire [8 : 0] WADR;
+  input wire [15:0] WDAT;
+  input wire WEN;
+
+  input wire [8 : 0] RADR;
+  output wire [15:0] RDAT;
+
+  my_ram #(
+      .DBITS(16),
+      .ABITS(9)
+  ) the_ram (
+      .CLK (CLK),
+      .WADR(WADR),
+      .WDAT(WDAT),
+      .WEN (WEN),
+      .RADR(RADR),
+      .RDAT(RDAT),
+      .REN (1'b0)
+  );
+
+endmodule
+
+module top_bram_9_32 (
+    CLK,
+    WADR,
+    WDAT,
+    WEN,
+    RADR,
+    RDAT
+);
+
+  input wire CLK;
+
+  input wire [8 : 0] WADR;
+  input wire [31:0] WDAT;
+  input wire WEN;
+
+  input wire [8 : 0] RADR;
+  output wire [31:0] RDAT;
+
+  my_ram #(
+      .DBITS(32),
+      .ABITS(9)
+  ) the_ram (
+      .CLK (CLK),
+      .WADR(WADR),
+      .WDAT(WDAT),
+      .WEN (WEN),
+      .RADR(RADR),
+      .RDAT(RDAT),
+      .REN (1'b0)
+  );
+
+endmodule
+
+module top_bram_10_16 (
+    CLK,
+    WADR,
+    WDAT,
+    WEN,
+    RADR,
+    RDAT
+);
+
+  input wire CLK;
+
+  input wire [9 : 0] WADR;
+  input wire [15:0] WDAT;
+  input wire WEN;
+
+  input wire [9 : 0] RADR;
+  output wire [15:0] RDAT;
+
+  my_ram #(
+      .DBITS(16),
+      .ABITS(10)
+  ) the_ram (
+      .CLK (CLK),
+      .WADR(WADR),
+      .WDAT(WDAT),
+      .WEN (WEN),
+      .RADR(RADR),
+      .RDAT(RDAT),
+      .REN (1'b0)
+  );
+
+endmodule
+
+module top_bram_init (
+    CLK,
+    WADR,
+    WDAT,
+    WEN,
+    RADR,
+    RDAT
+);
+
+  input wire CLK;
+
+  input wire [9 : 0] WADR;
+  input wire [17:0] WDAT;
+  input wire WEN;
+
+  input wire [9 : 0] RADR;
+  output wire [17:0] RDAT;
+
+  RAM_8K_BLK #(
+      .INIT_FILE     ("init.txt"),
+      .addr_int      (9),
+      .data_depth_int(1 << 9),
+      .data_width_int(16)
+  ) the_ram (
+      .WClk   (CLK),
+      .RClk   (CLK),
+      .WClk_En(1'b1),
+      .RClk_En(1'b1),
+      .WA     (WADR),
+      .WD     (WDAT),
+      .WEN    (WEN),
+      .RA     (RADR),
+      .RD     (RDAT)
+  );
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.tcl
new file mode 100644
index 000000000..5275fa53f
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.tcl
@@ -0,0 +1,27 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+hierarchy -top BRAM_32x512
+yosys proc
+yosys memory
+equiv_opt -assert -map +/quicklogic/qlf_k6n10_cells_sim.v synth_quicklogic -family qlf_k6n10 -top BRAM_32x512
+
+design -load read
+synth_quicklogic -family qlf_k6n10 -top BRAM_16x1024
+yosys cd BRAM_16x1024
+stat
+select -assert-count 1 t:DP_RAM16K
+
+design -load read
+synth_quicklogic -family qlf_k6n10 -top BRAM_8x2048
+yosys cd BRAM_16x1024
+stat
+select -assert-count 1 t:DP_RAM16K
+
+design -load read
+synth_quicklogic -family qlf_k6n10 -top BRAM_4x4096
+yosys cd BRAM_16x1024
+stat
+select -assert-count 1 t:DP_RAM16K
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.v
new file mode 100644
index 000000000..f8b0587aa
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.v
@@ -0,0 +1,184 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module BRAM #(parameter AWIDTH = 9,
+              parameter DWIDTH = 32)
+       (clk,
+        rce,
+        ra,
+        rq,
+        wce,
+        wa,
+        wd);
+
+        input  clk;
+
+        input                   rce;
+        input      [AWIDTH-1:0] ra;
+        output reg [DWIDTH-1:0] rq;
+
+        input                   wce;
+        input      [AWIDTH-1:0] wa;
+        input      [DWIDTH-1:0] wd;
+
+        reg        [DWIDTH-1:0] memory[0:AWIDTH-1];
+
+        always @(posedge clk) begin
+                if (rce)
+                        rq <= memory[ra];
+
+                if (wce)
+                        memory[wa] <= wd;
+        end
+
+        integer i;
+        initial
+        begin
+                for(i = 0; i < AWIDTH-1; i = i + 1)
+                        memory[i] = 0;
+        end
+
+endmodule
+
+module BRAM_32x512(
+        clk,
+        rce,
+        ra,
+        rq,
+        wce,
+        wa,
+        wd
+);
+
+        parameter AWIDTH = 9;
+        parameter DWIDTH = 32;
+
+        input  			clk;
+        input                   rce;
+        input      [AWIDTH-1:0] ra;
+        output reg [DWIDTH-1:0] rq;
+        input                   wce;
+        input      [AWIDTH-1:0] wa;
+        input      [DWIDTH-1:0] wd;
+
+        BRAM #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+        BRAM_32x512 (   .clk(clk),
+                        .rce(rce),
+                        .ra(ra),
+                        .rq(rq),
+                        .wce(wce),
+                        .wa(wa),
+                        .wd(wd));
+
+endmodule
+
+module BRAM_16x1024(
+        clk,
+        rce,
+        ra,
+        rq,
+        wce,
+        wa,
+        wd
+);
+
+        parameter AWIDTH = 10;
+        parameter DWIDTH = 16;
+
+        input  			clk;
+        input                   rce;
+        input      [AWIDTH-1:0] ra;
+        output reg [DWIDTH-1:0] rq;
+        input                   wce;
+        input      [AWIDTH-1:0] wa;
+        input      [DWIDTH-1:0] wd;
+
+        BRAM #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+        BRAM_16x1024 (  .clk(clk),
+                        .rce(rce),
+                        .ra(ra),
+                        .rq(rq),
+                        .wce(wce),
+                        .wa(wa),
+                        .wd(wd));
+
+
+endmodule
+
+module BRAM_8x2048(
+        clk,
+        rce,
+        ra,
+        rq,
+        wce,
+        wa,
+        wd
+);
+
+        parameter AWIDTH = 11;
+        parameter DWIDTH = 8;
+
+        input  			clk;
+        input                   rce;
+        input      [AWIDTH-1:0] ra;
+        output reg [DWIDTH-1:0] rq;
+        input                   wce;
+        input      [AWIDTH-1:0] wa;
+        input      [DWIDTH-1:0] wd;
+
+        BRAM #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+        BRAM_8x2048 (   .clk(clk),
+                        .rce(rce),
+                        .ra(ra),
+                        .rq(rq),
+                        .wce(wce),
+                        .wa(wa),
+                        .wd(wd));
+
+
+endmodule
+
+module BRAM_4x4096(
+        clk,
+        rce,
+        ra,
+        rq,
+        wce,
+        wa,
+        wd
+);
+
+        parameter AWIDTH = 12;
+        parameter DWIDTH = 4;
+
+        input  			clk;
+        input                   rce;
+        input      [AWIDTH-1:0] ra;
+        output reg [DWIDTH-1:0] rq;
+        input                   wce;
+        input      [AWIDTH-1:0] wa;
+        input      [DWIDTH-1:0] wd;
+
+        BRAM #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+        BRAM_4x4096 (   .clk(clk),
+                        .rce(rce),
+                        .ra(ra),
+                        .rq(rq),
+                        .wce(wce),
+                        .wa(wa),
+                        .wd(wd));
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.ys b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.ys
new file mode 100644
index 000000000..20228ca6f
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10_bram/bram.ys
@@ -0,0 +1,48 @@
+plugin -i ql-qlf
+
+read_verilog ./bram.v
+design -save read
+
+#BRAM 32x512
+
+hierarchy -top BRAM_32x512
+proc
+memory
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10 -top BRAM_32x512
+design -load postopt
+cd BRAM_32x512
+stat
+select -assert-count 1 t:DP_RAM16K
+
+#BRAM 16x1024
+
+hierarchy -top BRAM_32x512
+proc
+memory
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10 -top BRAM_16x1024
+design -load postopt
+cd BRAM_16x1024
+stat
+select -assert-count 1 t:DP_RAM16K
+
+#BRAM 8x2048
+
+hierarchy -top BRAM_8x2048
+proc
+memory
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10 -top BRAM_8x2048
+design -load postopt
+cd BRAM_8x2048
+stat
+select -assert-count 1 t:DP_RAM16K
+
+#BRAM 4x4096
+
+hierarchy -top BRAM_4x4096
+proc
+memory
+equiv_opt -assert -map +/quicklogic/qlf_k6n10/cells_sim.v synth_quicklogic -family qlf_k6n10 -top BRAM_4x4096
+design -load postopt
+cd BRAM_4x4096
+stat
+select -assert-count 1 t:DP_RAM16K
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.tcl
new file mode 100644
index 000000000..b413b43ae
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.tcl
@@ -0,0 +1,53 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_tdp
+
+select spram_16x2048_32x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_16x2048_32x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_16x2048_32x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_8x4096_16x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_8x4096_16x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_8x4096_16x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_8x2048_16x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_8x2048_16x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_8x2048_16x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_8x4096_32x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_8x4096_32x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_8x4096_32x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.v
new file mode 100644
index 000000000..a792980aa
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/bram_asymmetric_wider_read.v
@@ -0,0 +1,127 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module spram_16x2048_32x1024 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [9:0] ra;
+	output reg [31:0] rq;
+	input wce;
+	input [10:0] wa;
+	input [15:0] wd;
+	reg [31:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+		if (wce)
+			memory[wa / 2][(wa % 2) * 16+:16] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_8x2048_16x1024 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [9:0] ra;
+	output reg [15:0] rq;
+	input wce;
+	input [10:0] wa;
+	input [7:0] wd;
+	reg [15:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+		if (wce)
+			memory[wa / 2][(wa % 2) * 8+:8] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_8x4096_16x2048 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [10:0] ra;
+	output reg [15:0] rq;
+	input wce;
+	input [11:0] wa;
+	input [7:0] wd;
+	reg [15:0] memory [0:2047];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+		if (wce)
+			memory[wa / 2][(wa % 2) * 8+:8] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 2048; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_8x4096_32x1024 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [9:0] ra;
+	output reg [31:0] rq;
+	input wce;
+	input [11:0] wa;
+	input [7:0] wd;
+	reg [31:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+		if (wce)
+			memory[wa / 4][(wa % 4) * 8+:8] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/Makefile
new file mode 100644
index 000000000..7774a8a13
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/Makefile
@@ -0,0 +1,46 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram_asymmetric_wider_read_tb.v
+POST_SYNTH = spram_16x2048_32x1024_post_synth spram_8x4096_16x2048_post_synth spram_8x2048_16x1024_post_synth spram_8x4096_32x1024_post_synth
+READ_ADDR_WIDTH = 10 11 10 10
+WRITE_ADDR_WIDTH = 11 12 11 12
+READ_DATA_WIDTH = 32 16 16 32
+WRITE_DATA_WIDTH = 16 8 8 8
+TOP = spram_16x2048_32x1024 spram_8x4096_16x2048 spram_8x2048_16x1024 spram_8x4096_32x1024
+READ_ADDR_DEFINES = $(foreach awidth, $(READ_ADDR_WIDTH),-DREAD_ADDR_WIDTH="$(awidth)")
+WRITE_ADDR_DEFINES = $(foreach awidth, $(WRITE_ADDR_WIDTH),-DWRITE_ADDR_WIDTH="$(awidth)")
+READ_DATA_DEFINES = $(foreach dwidth, $(READ_DATA_WIDTH),-DREAD_DATA_WIDTH="$(dwidth)")
+WRITE_DATA_DEFINES = $(foreach dwidth, $(WRITE_DATA_WIDTH),-DWRITE_DATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(READ_ADDR_DEFINES)) $(word $(1),$(WRITE_ADDR_DEFINES)) $(word $(1),$(READ_DATA_DEFINES)) $(word $(1),$(WRITE_DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/bram_asymmetric_wider_read_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/bram_asymmetric_wider_read_tb.v
new file mode 100644
index 000000000..bb6d22020
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_read/sim/bram_asymmetric_wider_read_tb.v
@@ -0,0 +1,157 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+	reg rce;
+	reg [`READ_ADDR_WIDTH-1:0] ra;
+	wire [`READ_DATA_WIDTH-1:0] rq;
+	reg wce;
+	reg [`WRITE_ADDR_WIDTH-1:0] wa;
+	reg [`WRITE_DATA_WIDTH-1:0] wd;
+
+	initial clk = 0;
+	initial ra = 0;
+	initial rce = 0;
+	initial forever #(PERIOD / 2.0) clk = ~clk;
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+
+	reg [`READ_DATA_WIDTH-1:0] expected;
+
+	always @(posedge clk) begin
+		case (`READ_DATA_WIDTH / `WRITE_DATA_WIDTH)
+			1: expected <= (a | (a << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}};
+			2: expected <= ((((2*a+1) | ((2*a+1) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}}) << `WRITE_DATA_WIDTH) |
+					(((2*a) | ((2*a) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}});
+			4: expected <= (((4*a) | ((4*a) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}}) |
+				      ((((4*a+1) | ((4*a+1) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}}) << `WRITE_DATA_WIDTH) |
+				      ((((4*a+2) | ((4*a+2) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}}) << (2 * `WRITE_DATA_WIDTH)) |
+				      ((((4*a+3) | ((4*a+3) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}}) << (3 * `WRITE_DATA_WIDTH));
+			default: expected <= ((a) | ((a) << 20) | 20'h55000) & {`WRITE_DATA_WIDTH{1'b1}};
+		endcase
+	end
+
+	wire error = ((a != 0) && read_test) ? rq !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1;
+	end
+
+	reg read_test;
+	initial read_test = 0;
+
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`WRITE_ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				wa = a;
+				wd = a | (a << 20) | 20'h55000;
+				wce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`READ_ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, rq, expected, a);
+				end
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_16x2048_32x1024": begin
+			spram_16x2048_32x1024 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_8x4096_16x2048": begin
+			spram_8x4096_16x2048 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_8x2048_16x1024": begin
+			spram_8x2048_16x1024 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_8x4096_32x1024": begin
+			spram_8x4096_32x1024 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.tcl
new file mode 100644
index 000000000..9d086bb09
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.tcl
@@ -0,0 +1,53 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_tdp
+
+select spram_16x1024_8x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_16x1024_8x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_16x1024_8x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_16x2048_8x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_16x2048_8x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_16x2048_8x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_32x1024_16x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_32x1024_16x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_32x1024_16x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
+
+select -clear
+design -load bram_tdp
+select spram_32x1024_8x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top spram_32x1024_8x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/spram_32x1024_8x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+select -assert-count 1 t:*
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.v
new file mode 100644
index 000000000..803d43c18
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/bram_asymmetric_wider_write.v
@@ -0,0 +1,127 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module spram_16x1024_8x2048 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [10:0] ra;
+	output reg [7:0] rq;
+	input wce;
+	input [9:0] wa;
+	input [15:0] wd;
+	reg [15:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra / 2][(ra % 2) * 8+:8];
+		if (wce)
+			memory[wa] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_16x2048_8x4096 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [11:0] ra;
+	output reg [7:0] rq;
+	input wce;
+	input [10:0] wa;
+	input [15:0] wd;
+	reg [15:0] memory [0:2047];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra / 2][(ra % 2) * 8+:8];
+		if (wce)
+			memory[wa] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 2048; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_32x1024_16x2048 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [10:0] ra;
+	output reg [15:0] rq;
+	input wce;
+	input [9:0] wa;
+	input [31:0] wd;
+	reg [31:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra / 2][(ra % 2) * 16+:16];
+		if (wce)
+			memory[wa] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
+
+module spram_32x1024_8x4096 (
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+	input clk;
+	input rce;
+	input [11:0] ra;
+	output reg [7:0] rq;
+	input wce;
+	input [9:0] wa;
+	input [31:0] wd;
+	reg [31:0] memory [0:1023];
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra / 4][(ra % 4) * 8+:8];
+		if (wce)
+			memory[wa] <= wd;
+	end
+	integer i;
+	initial for (i = 0; i < 1024; i = i + 1)
+		memory[i] = 0;
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/Makefile
new file mode 100644
index 000000000..e176322c4
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/Makefile
@@ -0,0 +1,46 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram_asymmetric_wider_write_tb.v
+POST_SYNTH = spram_16x2048_8x4096_post_synth spram_16x1024_8x2048_post_synth spram_32x1024_8x4096_post_synth spram_32x1024_16x2048_post_synth
+READ_ADDR_WIDTH = 12 11 12 11
+WRITE_ADDR_WIDTH = 11 10 10 10
+READ_DATA_WIDTH = 8 8 8 16
+WRITE_DATA_WIDTH = 16 16 32 32
+TOP = spram_16x2048_8x4096 spram_16x1024_8x2048 spram_32x1024_8x4096 spram_32x1024_16x2048
+READ_ADDR_DEFINES = $(foreach awidth, $(READ_ADDR_WIDTH),-DREAD_ADDR_WIDTH="$(awidth)")
+WRITE_ADDR_DEFINES = $(foreach awidth, $(WRITE_ADDR_WIDTH),-DWRITE_ADDR_WIDTH="$(awidth)")
+READ_DATA_DEFINES = $(foreach dwidth, $(READ_DATA_WIDTH),-DREAD_DATA_WIDTH="$(dwidth)")
+WRITE_DATA_DEFINES = $(foreach dwidth, $(WRITE_DATA_WIDTH),-DWRITE_DATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(READ_ADDR_DEFINES)) $(word $(1),$(WRITE_ADDR_DEFINES)) $(word $(1),$(READ_DATA_DEFINES)) $(word $(1),$(WRITE_DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/bram_asymmetric_wider_write_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/bram_asymmetric_wider_write_tb.v
new file mode 100644
index 000000000..d5e56a67b
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_asymmetric_wider_write/sim/bram_asymmetric_wider_write_tb.v
@@ -0,0 +1,164 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+	reg rce;
+	reg [`READ_ADDR_WIDTH-1:0] ra;
+	wire [`READ_DATA_WIDTH-1:0] rq;
+	reg wce;
+	reg [`WRITE_ADDR_WIDTH-1:0] wa;
+	reg [`WRITE_DATA_WIDTH-1:0] wd;
+
+	initial clk = 0;
+	initial ra = 0;
+	initial rce = 0;
+	initial forever #(PERIOD / 2.0) clk = ~clk;
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+
+	reg [`READ_DATA_WIDTH-1:0] expected;
+
+	always @(posedge clk) begin
+		case (`WRITE_DATA_WIDTH / `READ_DATA_WIDTH)
+			1: expected <= (a | (a << 20) | 20'h55000) & {`READ_DATA_WIDTH{1'b1}};
+			2:
+				if (a % 2)
+					expected <= (((a/2) | ((a/2) << 20) | 20'h55000) >> `READ_DATA_WIDTH) & {`READ_DATA_WIDTH{1'b1}};
+				else
+					expected <= ((a/2) | ((a/2) << 20) | 20'h55000) & {`READ_DATA_WIDTH{1'b1}};
+			4:
+				case (a % 4)
+					0: expected <= ((a/4) | ((a/4) << 20) | 20'h55000) & {`READ_DATA_WIDTH{1'b1}};
+					1: expected <= (((a/4) | ((a/4) << 20) | 20'h55000) >> `READ_DATA_WIDTH) & {`READ_DATA_WIDTH{1'b1}};
+					2: expected <= (((a/4) | ((a/4) << 20) | 20'h55000) >> (2 * `READ_DATA_WIDTH)) & {`READ_DATA_WIDTH{1'b1}};
+					3: expected <= (((a/4) | ((a/4) << 20) | 20'h55000) >> (3 * `READ_DATA_WIDTH)) & {`READ_DATA_WIDTH{1'b1}};
+					default: expected <= ((a/4) | ((a/4) << 20) | 20'h55000) & {`READ_DATA_WIDTH{1'b1}};
+				endcase
+			default: expected <= ((a/2) | ((a/2) << 20) | 20'h55000) & {`READ_DATA_WIDTH{1'b1}};
+		endcase
+	end
+
+	wire error = ((a != 0) && read_test) ? rq !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1;
+	end
+
+	reg read_test;
+	initial read_test = 0;
+
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`WRITE_ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				wa = a;
+				wd = a | (a << 20) | 20'h55000;
+				wce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`READ_ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, rq, expected, a);
+				end
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"spram_16x2048_8x4096": begin
+			spram_16x2048_8x4096 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_16x1024_8x2048": begin
+			spram_16x1024_8x2048 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_32x1024_8x4096": begin
+			spram_32x1024_8x4096 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"spram_32x1024_16x2048": begin
+			spram_32x1024_16x2048 #() simple (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl
new file mode 100644
index 000000000..f8567ce66
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.tcl
@@ -0,0 +1,105 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_sdp
+
+select BRAM_SDP_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_36x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_32x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_32x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_32x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_18x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_18x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_18x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_16x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_16x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_16x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_9x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_9x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_9x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_8x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_8x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_8x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_4x8192
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_4x8192
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_4x8192_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_2x16384
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_2x16384
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_2x16384_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp
+select BRAM_SDP_1x32768
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_1x32768
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_1x32768_post_synth.v
+select -assert-count 1 t:TDP36K
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.v
new file mode 100644
index 000000000..568b708d5
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/bram_sdp.v
@@ -0,0 +1,347 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module BRAM_SDP #(parameter AWIDTH = 9,
+parameter DWIDTH = 32)(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+	input  			clk;
+
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output reg [DWIDTH-1:0] rq;
+
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+	reg        [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1];
+
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+
+		if (wce)
+			memory[wa] <= wd;
+	end
+
+	integer i;
+	initial
+	begin
+		for(i = 0; i < (1<<AWIDTH)-1; i = i + 1)
+			memory[i] = 0;
+	end
+
+endmodule
+
+module BRAM_SDP_36x1024(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 36;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_36x1024 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+endmodule
+
+module BRAM_SDP_32x1024(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 32;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_32x1024 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+endmodule
+
+module BRAM_SDP_18x2048(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 18;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_18x2048 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+
+endmodule
+
+module BRAM_SDP_16x2048(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 16;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_16x2048 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+
+endmodule
+
+module BRAM_SDP_9x4096(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 9;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_9x4096 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+
+endmodule
+
+module BRAM_SDP_8x4096(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 8;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_8x4096 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+
+endmodule
+
+module BRAM_SDP_4x8192(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 13;
+parameter DWIDTH = 4;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_4x8192 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+endmodule
+
+module BRAM_SDP_2x16384(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 14;
+parameter DWIDTH = 2;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_2x16384 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+endmodule
+
+module BRAM_SDP_1x32768(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+parameter AWIDTH = 15;
+parameter DWIDTH = 1;
+
+	input  			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output     [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+BRAM_SDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_1x32678 (.clk(clk),
+		 .rce(rce),
+		 .ra(ra),
+		 .rq(rq),
+		 .wce(wce),
+		 .wa(wa),
+		 .wd(wd));
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/Makefile
new file mode 100644
index 000000000..cb2471b83
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/Makefile
@@ -0,0 +1,48 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram_sdp_tb.v
+POST_SYNTH = bram_sdp_36x1024_post_synth bram_sdp_32x1024_post_synth bram_sdp_18x2048_post_synth bram_sdp_16x2048_post_synth bram_sdp_9x4096_post_synth bram_sdp_8x4096_post_synth bram_sdp_4x8192_post_synth bram_sdp_2x16384_post_synth bram_sdp_1x32768_post_synth
+ADDR_WIDTH = 10 10 11 11 12 12 13 14 15
+DATA_WIDTH = 36 32 18 16 9 8 4 2 1
+TOP = BRAM_SDP_36x1024 BRAM_SDP_32x1024 BRAM_SDP_18x2048 BRAM_SDP_16x2048 BRAM_SDP_9x4096 BRAM_SDP_8x4096 BRAM_SDP_4x8192 BRAM_SDP_2x16384 BRAM_SDP_1x32768
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
+	$(call simulate_post_synth,5)
+	$(call simulate_post_synth,6)
+	$(call simulate_post_synth,7)
+	$(call simulate_post_synth,8)
+	$(call simulate_post_synth,9)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v
new file mode 100644
index 000000000..30b365ab6
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp/sim/bram_sdp_tb.v
@@ -0,0 +1,203 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk;
+	reg rce;
+	reg [`ADDR_WIDTH-1:0] ra;
+	wire [`DATA_WIDTH-1:0] rq;
+	reg wce;
+	reg [`ADDR_WIDTH-1:0] wa;
+	reg [`DATA_WIDTH-1:0] wd;
+
+	initial clk = 0;
+	initial ra = 0;
+	initial rce = 0;
+	initial forever #(PERIOD / 2.0) clk = ~clk;
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+
+	reg done;
+	initial done = 1'b0;
+
+	reg [`DATA_WIDTH-1:0] expected;
+
+	always @(posedge clk) begin
+		expected <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error = ((a != 0) && read_test) ? rq !== expected : 0;
+
+	integer error_cnt = 0;
+	always @ (posedge clk)
+	begin
+		if (error)
+			error_cnt <= error_cnt + 1'b1;
+	end
+
+	reg read_test;
+	initial read_test = 0;
+
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				wa = a;
+				wd = a | (a << 20) | 20'h55000;
+				wce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) wce = 0;
+			end
+		end
+		// Read data
+		read_test = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH); a = a + ADDR_INCR) begin
+			@(negedge clk) begin
+				ra = a;
+				rce = 1;
+			end
+			@(posedge clk) begin
+				#(PERIOD/10) rce = 0;
+				if ( rq !== expected) begin
+					$display("%d: FAIL: mismatch act=%x exp=%x at %x", $time, rq, expected, a);
+				end else begin
+					$display("%d: OK: act=%x exp=%x at %x", $time, rq, expected, a);
+				end
+			end
+		end
+		done = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk) begin
+		if (done)
+			$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"BRAM_SDP_36x1024": begin
+			BRAM_SDP_36x1024 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_32x1024": begin
+			BRAM_SDP_32x1024 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_18x2048": begin
+			BRAM_SDP_18x2048 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_16x2048": begin
+			BRAM_SDP_16x2048 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_9x4096": begin
+			BRAM_SDP_9x4096 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_8x4096": begin
+			BRAM_SDP_8x4096 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_4x8192": begin
+			BRAM_SDP_4x8192 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_2x16384": begin
+			BRAM_SDP_2x16384 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+		"BRAM_SDP_1x32768": begin
+			BRAM_SDP_1x32768 #() bram (
+				.clk(clk),
+				.rce(rce),
+				.ra(ra),
+				.rq(rq),
+				.wce(wce),
+				.wa(wa),
+				.wd(wd)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.tcl
new file mode 100644
index 000000000..a296d8c07
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.tcl
@@ -0,0 +1,83 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_sdp_split
+
+select BRAM_SDP_SPLIT_2x18x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x18x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x18x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x16x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x16x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x16x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x9x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x9x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x9x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x8x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x8x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x8x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x4x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x4x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x4x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x2x8192
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x2x8192
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x2x8192_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_sdp_split
+select BRAM_SDP_SPLIT_2x1x16384
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_SDP_SPLIT_2x1x16384
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_sdp_split_2x1x16384_post_synth.v
+select -assert-count 1 t:TDP36K
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.v
new file mode 100644
index 000000000..48dbebd48
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/bram_sdp_split.v
@@ -0,0 +1,479 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+module BRAM_SDP_SPLIT #(parameter AWIDTH = 9,
+parameter DWIDTH = 32)(
+	clk,
+	rce,
+	ra,
+	rq,
+	wce,
+	wa,
+	wd
+);
+
+	input			clk;
+	input                   rce;
+	input      [AWIDTH-1:0] ra;
+	output reg [DWIDTH-1:0] rq;
+	input                   wce;
+	input      [AWIDTH-1:0] wa;
+	input      [DWIDTH-1:0] wd;
+
+	reg        [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1];
+
+	always @(posedge clk) begin
+		if (rce)
+			rq <= memory[ra];
+
+		if (wce)
+			memory[wa] <= wd;
+	end
+
+	integer i;
+	initial
+	begin
+		for(i = 0; i < (1<<AWIDTH)-1; i = i + 1)
+			memory[i] = 0;
+	end
+
+endmodule
+
+module BRAM_SDP_SPLIT_2x18K #(parameter AWIDTH = 10, parameter DWIDTH = 18)(
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_0 (.clk(clk_0),
+		 .rce(rce_0),
+		 .ra(ra_0),
+		 .rq(rq_0),
+		 .wce(wce_0),
+		 .wa(wa_0),
+		 .wd(wd_0));
+
+BRAM_SDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_1 (.clk(clk_1),
+		 .rce(rce_1),
+		 .ra(ra_1),
+		 .rq(rq_1),
+		 .wce(wce_1),
+		 .wa(wa_1),
+		 .wd(wd_1));
+endmodule
+
+
+module BRAM_SDP_SPLIT_2x18x1024 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 18;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x18x1024 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+
+module BRAM_SDP_SPLIT_2x16x1024 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 16;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x16x1024 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+
+module BRAM_SDP_SPLIT_2x9x2048 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 9;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x9x2048 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+module BRAM_SDP_SPLIT_2x8x2048 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 8;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x8x2048 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+module BRAM_SDP_SPLIT_2x4x4096 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 4;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x4x4096 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+module BRAM_SDP_SPLIT_2x2x8192 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 13;
+parameter DWIDTH = 2;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x2x8192 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
+module BRAM_SDP_SPLIT_2x1x16384 (
+	clk_0,
+	rce_0,
+	ra_0,
+	rq_0,
+	wce_0,
+	wa_0,
+	wd_0,
+
+	clk_1,
+	rce_1,
+	ra_1,
+	rq_1,
+	wce_1,
+	wa_1,
+	wd_1
+);
+
+parameter AWIDTH = 14;
+parameter DWIDTH = 1;
+
+	input			clk_0;
+	input                   rce_0;
+	input      [AWIDTH-1:0] ra_0;
+	output     [DWIDTH-1:0] rq_0;
+	input                   wce_0;
+	input      [AWIDTH-1:0] wa_0;
+	input      [DWIDTH-1:0] wd_0;
+	input			clk_1;
+	input                   rce_1;
+	input      [AWIDTH-1:0] ra_1;
+	output     [DWIDTH-1:0] rq_1;
+	input                   wce_1;
+	input      [AWIDTH-1:0] wa_1;
+	input      [DWIDTH-1:0] wd_1;
+
+BRAM_SDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_SDP_SPLIT_2x1x16384 (
+		 .clk_0(clk_0),
+		 .rce_0(rce_0),
+		 .ra_0(ra_0),
+		 .rq_0(rq_0),
+		 .wce_0(wce_0),
+		 .wa_0(wa_0),
+		 .wd_0(wd_0),
+		 .clk_1(clk_1),
+		 .rce_1(rce_1),
+		 .ra_1(ra_1),
+		 .rq_1(rq_1),
+		 .wce_1(wce_1),
+		 .wa_1(wa_1),
+		 .wd_1(wd_1));
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/Makefile
new file mode 100644
index 000000000..e678b7c5c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/Makefile
@@ -0,0 +1,38 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = bram_sdp_split_tb.v
+POST_SYNTH = bram_sdp_split_2x18x1024_post_synth bram_sdp_split_2x16x1024_post_synth bram_sdp_split_2x9x2048_post_synth bram_sdp_split_2x8x2048_post_synth bram_sdp_split_2x4x4096_post_synth bram_sdp_split_2x2x8192_post_synth bram_sdp_split_2x1x16384_post_synth
+ADDR_WIDTH = 10 10 11 11 12 13 14
+DATA_WIDTH = 18 16 9 8 4 2 1
+TOP = BRAM_SDP_SPLIT_2x18x1024 BRAM_SDP_SPLIT_2x16x1024 BRAM_SDP_SPLIT_2x9x2048 BRAM_SDP_SPLIT_2x8x2048 BRAM_SDP_SPLIT_2x4x4096 BRAM_SDP_SPLIT_2x2x8192 BRAM_SDP_SPLIT_2x1x16384
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
+	$(call simulate_post_synth,5)
+	$(call simulate_post_synth,6)
+	$(call simulate_post_synth,7)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/bram_sdp_split_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/bram_sdp_split_tb.v
new file mode 100644
index 000000000..9515eb426
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_sdp_split/sim/bram_sdp_split_tb.v
@@ -0,0 +1,296 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_0;
+	reg rce_0;
+	reg [`ADDR_WIDTH-1:0] ra_0;
+	wire [`DATA_WIDTH-1:0] rq_0;
+	reg wce_0;
+	reg [`ADDR_WIDTH-1:0] wa_0;
+	reg [`DATA_WIDTH-1:0] wd_0;
+
+	reg clk_1;
+	reg rce_1;
+	reg [`ADDR_WIDTH-1:0] ra_1;
+	wire [`DATA_WIDTH-1:0] rq_1;
+	reg wce_1;
+	reg [`ADDR_WIDTH-1:0] wa_1;
+	reg [`DATA_WIDTH-1:0] wd_1;
+
+
+	initial clk_0 = 0;
+	initial clk_1 = 0;
+	initial ra_0 = 0;
+	initial ra_1 = 0;
+	initial rce_0 = 0;
+	initial rce_1 = 0;
+	initial forever #(PERIOD / 2.0) clk_0 = ~clk_0;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_1 = ~clk_1;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_0;
+	reg done_1;
+	initial done_0 = 1'b0;
+	initial done_1 = 1'b0;
+	wire done_sim = done_0 & done_1;
+
+	reg [`DATA_WIDTH-1:0] expected_0;
+	reg [`DATA_WIDTH-1:0] expected_1;
+
+	reg read_test_0;
+	reg read_test_1;
+	initial read_test_0 = 0;
+	initial read_test_1 = 0;
+
+	always @(posedge clk_0) begin
+		expected_0 <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+	always @(posedge clk_1) begin
+		expected_1 <= ((b+1) | ((b+1) << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error_0 = ((a != 0) && read_test_0) ? (rq_0 !== expected_0) : 0;
+	wire error_1 = ((b != (1<<`ADDR_WIDTH) / 2) && read_test_1) ? (rq_1 !== expected_1) : 0;
+
+	integer error_0_cnt = 0;
+	integer error_1_cnt = 0;
+
+	always @ (posedge clk_0)
+	begin
+		if (error_0)
+			error_0_cnt <= error_0_cnt + 1'b1;
+	end
+	always @ (posedge clk_1)
+	begin
+		if (error_1)
+			error_1_cnt <= error_1_cnt + 1'b1;
+	end
+
+	// PART 0
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				wa_0 = a;
+				wd_0 = a | (a << 20) | 20'h55000;
+				wce_0 = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) wce_0 = 0;
+			end
+		end
+		// Read data
+		read_test_0 = 1;
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_0) begin
+				ra_0 = a;
+				rce_0 = 1;
+			end
+			@(posedge clk_0) begin
+				#(PERIOD/10) rce_0 = 0;
+				if ( rq_0 !== expected_0) begin
+					$display("%d: PORT 0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_0, expected_0, a);
+				end else begin
+					$display("%d: PORT 0: OK: act=%x exp=%x at %x", $time, rq_0, expected_0, a);
+				end
+			end
+		end
+		done_0 = 1'b1;
+	end
+
+	// PART 1
+	initial #(1) begin
+		// Write data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				wa_1 = b;
+				wd_1 = (b+1) | ((b+1) << 20) | 20'h55000;
+				wce_1 = 1;
+			end
+			@(posedge clk_1) begin
+				#(PERIOD/10) wce_1 = 0;
+			end
+		end
+		// Read data
+		read_test_1 = 1;
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_1) begin
+				ra_1 = b;
+				rce_1 = 1;
+			end
+			@(posedge clk_1) begin
+				#(PERIOD/10) rce_1 = 0;
+				if ( rq_1 !== expected_1) begin
+					$display("%d: PORT 1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_1, expected_1, b);
+				end else begin
+					$display("%d: PORT 1: OK: act=%x exp=%x at %x", $time, rq_1, expected_1, b);
+				end
+			end
+		end
+		done_1 = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_0, posedge clk_1) begin
+		if (done_sim)
+			$finish_and_return( (error_0_cnt == 0 & error_1_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"BRAM_SDP_SPLIT_2x18x1024": begin
+			BRAM_SDP_SPLIT_2x18x1024 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x16x1024": begin
+			BRAM_SDP_SPLIT_2x16x1024 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x9x2048": begin
+			BRAM_SDP_SPLIT_2x9x2048 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x8x2048": begin
+			BRAM_SDP_SPLIT_2x8x2048 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x4x4096": begin
+			BRAM_SDP_SPLIT_2x4x4096 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x2x8192": begin
+			BRAM_SDP_SPLIT_2x2x8192 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+		"BRAM_SDP_SPLIT_2x1x16384": begin
+			BRAM_SDP_SPLIT_2x1x16384 #() bram (
+				.clk_0(clk_0),
+				.rce_0(rce_0),
+				.ra_0(ra_0),
+				.rq_0(rq_0),
+				.wce_0(wce_0),
+				.wa_0(wa_0),
+				.wd_0(wd_0),
+
+				.clk_1(clk_1),
+				.rce_1(rce_1),
+				.ra_1(ra_1),
+				.rq_1(rq_1),
+				.wce_1(wce_1),
+				.wa_1(wa_1),
+				.wd_1(wd_1)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.tcl
new file mode 100644
index 000000000..8ef0e9da4
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.tcl
@@ -0,0 +1,105 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_tdp
+
+select BRAM_TDP_36x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_36x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_36x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_32x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_32x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_32x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_18x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_18x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_18x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_16x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_16x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_16x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_9x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_9x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_9x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_8x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_8x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_8x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_4x8192
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_4x8192
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_4x8192_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_2x16384
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_2x16384
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_2x16384_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp
+select BRAM_TDP_1x32768
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_1x32768
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_1x32768_post_synth.v
+select -assert-count 1 t:TDP36K
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.v
new file mode 100644
index 000000000..090cc24f8
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/bram_tdp.v
@@ -0,0 +1,561 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module BRAM_TDP #(parameter AWIDTH = 10,
+parameter DWIDTH = 36)(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output reg [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output reg [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+	reg        [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1];
+
+	always @(posedge clk_a) begin
+		if (rce_a)
+			rq_a <= memory[ra_a];
+
+		if (wce_a)
+			memory[wa_a] <= wd_a;
+	end
+
+	always @(posedge clk_b) begin
+		if (rce_b)
+			rq_b <= memory[ra_b];
+
+		if (wce_b)
+			memory[wa_b] <= wd_b;
+	end
+
+	integer i;
+	initial
+	begin
+		for(i = 0; i < (1<<AWIDTH)-1; i = i + 1)
+			memory[i] = 0;
+	end
+
+endmodule
+
+module BRAM_TDP_36x1024(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 36;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_36x1024 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+
+endmodule
+
+module BRAM_TDP_32x1024(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 32;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_32x1024 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+
+endmodule
+
+module BRAM_TDP_18x2048(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 18;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_18x2048 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_16x2048(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 16;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_16x2048 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_9x4096(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 9;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_9x4096 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_8x4096(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 8;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_8x4096 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_4x8192(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 13;
+parameter DWIDTH = 4;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_4x8192 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_2x16384(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 14;
+parameter DWIDTH = 2;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_2x16384 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
+
+module BRAM_TDP_1x32768(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+parameter AWIDTH = 15;
+parameter DWIDTH = 1;
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output     [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output     [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+BRAM_TDP #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_2x32768 (.clk_a(clk_a),
+		 .rce_a(rce_a),
+		 .ra_a(ra_a),
+		 .rq_a(rq_a),
+		 .wce_a(wce_a),
+		 .wa_a(wa_a),
+		 .wd_a(wd_a),
+		 .clk_b(clk_b),
+		 .rce_b(rce_b),
+		 .ra_b(ra_b),
+		 .rq_b(rq_b),
+		 .wce_b(wce_b),
+		 .wa_b(wa_b),
+		 .wd_b(wd_b));
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/Makefile
new file mode 100644
index 000000000..f5baa6df3
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/Makefile
@@ -0,0 +1,48 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = bram_tdp_tb.v
+POST_SYNTH = bram_tdp_36x1024_post_synth bram_tdp_32x1024_post_synth bram_tdp_18x2048_post_synth bram_tdp_16x2048_post_synth bram_tdp_9x4096_post_synth bram_tdp_8x4096_post_synth bram_tdp_4x8192_post_synth bram_tdp_2x16384_post_synth bram_tdp_1x32768_post_synth
+ADDR_WIDTH = 10 10 11 11 12 12 13 14 15
+DATA_WIDTH = 36 32 18 16 9 8 4 2 1
+TOP = BRAM_TDP_36x1024 BRAM_TDP_32x1024 BRAM_TDP_18x2048 BRAM_TDP_16x2048 BRAM_TDP_9x4096 BRAM_TDP_8x4096 BRAM_TDP_4x8192 BRAM_TDP_2x16384 BRAM_TDP_1x32768
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+# FIXME: $(call simulate_post_synth,5)
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
+	$(call simulate_post_synth,5)
+	$(call simulate_post_synth,6)
+	$(call simulate_post_synth,7)
+	$(call simulate_post_synth,8)
+	$(call simulate_post_synth,9)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/bram_tdp_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/bram_tdp_tb.v
new file mode 100644
index 000000000..3495bedfd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp/sim/bram_tdp_tb.v
@@ -0,0 +1,325 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_a;
+	reg rce_a;
+	reg [`ADDR_WIDTH-1:0] ra_a;
+	wire [`DATA_WIDTH-1:0] rq_a;
+	reg wce_a;
+	reg [`ADDR_WIDTH-1:0] wa_a;
+	reg [`DATA_WIDTH-1:0] wd_a;
+
+	reg clk_b;
+	reg rce_b;
+	reg [`ADDR_WIDTH-1:0] ra_b;
+	wire [`DATA_WIDTH-1:0] rq_b;
+	reg wce_b;
+	reg [`ADDR_WIDTH-1:0] wa_b;
+	reg [`DATA_WIDTH-1:0] wd_b;
+
+
+	initial clk_a = 0;
+	initial clk_b = 0;
+	initial ra_a = 0;
+	initial ra_b = 0;
+	initial rce_a = 0;
+	initial rce_b = 0;
+	initial forever #(PERIOD / 2.0) clk_a = ~clk_a;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_b = ~clk_b;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_a;
+	reg done_b;
+	initial done_a = 1'b0;
+	initial done_b = 1'b0;
+	wire done_sim = done_a & done_b;
+
+	reg [`DATA_WIDTH-1:0] expected_a;
+	reg [`DATA_WIDTH-1:0] expected_b;
+
+	always @(posedge clk_a) begin
+		expected_a <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+	always @(posedge clk_b) begin
+		expected_b <= (b | (b << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error_a = a != 0 ? rq_a !== expected_a : 0;
+	wire error_b = b != (1<<`ADDR_WIDTH) / 2 ? rq_b !== expected_b : 0;
+
+	integer error_a_cnt = 0;
+	integer error_b_cnt = 0;
+
+	always @ (posedge clk_a)
+	begin
+		if (error_a)
+			error_a_cnt <= error_a_cnt + 1'b1;
+	end
+	always @ (posedge clk_b)
+	begin
+		if (error_b)
+			error_b_cnt <= error_b_cnt + 1'b1;
+	end
+	// PORT A
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				wa_a = a;
+				wd_a = a | (a << 20) | 20'h55000;
+				wce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) wce_a = 0;
+			end
+		end
+		// Read data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				ra_a = a;
+				rce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) rce_a = 0;
+				if ( rq_a !== expected_a) begin
+					$display("%d: PORT A: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a, expected_a, a);
+				end else begin
+					$display("%d: PORT A: OK: act=%x exp=%x at %x", $time, rq_a, expected_a, a);
+				end
+			end
+		end
+		done_a = 1'b1;
+	end
+
+	// PORT B
+	initial #(1) begin
+		// Write data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				wa_b = b;
+				wd_b = b | (b << 20) | 20'h55000;
+				wce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) wce_b = 0;
+			end
+		end
+		// Read data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				ra_b = b;
+				rce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) rce_b = 0;
+				if ( rq_b !== expected_b) begin
+					$display("%d: PORT B: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b, expected_b, b);
+				end else begin
+					$display("%d: PORT B: OK: act=%x exp=%x at %x", $time, rq_b, expected_b, b);
+				end
+			end
+		end
+		done_b = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_a, posedge clk_b) begin
+		if (done_sim)
+			$finish_and_return( (error_a_cnt == 0 & error_b_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"BRAM_TDP_36x1024": begin
+			BRAM_TDP_36x1024 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_32x1024": begin
+			BRAM_TDP_32x1024 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_18x2048": begin
+			BRAM_TDP_18x2048 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_16x2048": begin
+			BRAM_TDP_16x2048 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_9x4096": begin
+			BRAM_TDP_9x4096 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_8x4096": begin
+			BRAM_TDP_8x4096 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_4x8192": begin
+			BRAM_TDP_4x8192 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_2x16384": begin
+			BRAM_TDP_2x16384 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+		"BRAM_TDP_1x32768": begin
+			BRAM_TDP_1x32768 #() bram (
+				.clk_a(clk_a),
+				.rce_a(rce_a),
+				.ra_a(ra_a),
+				.rq_a(rq_a),
+				.wce_a(wce_a),
+				.wa_a(wa_a),
+				.wd_a(wd_a),
+				.clk_b(clk_b),
+				.rce_b(rce_b),
+				.ra_b(ra_b),
+				.rq_b(rq_b),
+				.wce_b(wce_b),
+				.wa_b(wa_b),
+				.wd_b(wd_b)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.tcl
new file mode 100644
index 000000000..9a8921ec8
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.tcl
@@ -0,0 +1,83 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save bram_tdp_split
+
+select BRAM_TDP_SPLIT_2x18x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x18x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x18x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x16x1024
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x16x1024
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x16x1024_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x9x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x9x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x9x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x8x2048
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x8x2048
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x8x2048_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x4x4096
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x4x4096
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x4x4096_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x2x8192
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x2x8192
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x2x8192_post_synth.v
+select -assert-count 1 t:TDP36K
+
+select -clear
+design -load bram_tdp_split
+select BRAM_TDP_SPLIT_2x1x16384
+select *
+synth_quicklogic -family qlf_k6n10f -top BRAM_TDP_SPLIT_2x1x16384
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/bram_tdp_split_2x1x16384_post_synth.v
+select -assert-count 1 t:TDP36K
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.v
new file mode 100644
index 000000000..001efa095
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/bram_tdp_split.v
@@ -0,0 +1,863 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+module BRAM_TDP_SPLIT #(parameter AWIDTH = 9,
+parameter DWIDTH = 32)(
+	clk_a,
+	rce_a,
+	ra_a,
+	rq_a,
+	wce_a,
+	wa_a,
+	wd_a,
+
+	clk_b,
+	rce_b,
+	ra_b,
+	rq_b,
+	wce_b,
+	wa_b,
+	wd_b
+);
+
+	input			clk_a;
+	input                   rce_a;
+	input      [AWIDTH-1:0] ra_a;
+	output reg [DWIDTH-1:0] rq_a;
+	input                   wce_a;
+	input      [AWIDTH-1:0] wa_a;
+	input      [DWIDTH-1:0] wd_a;
+
+	input			clk_b;
+	input                   rce_b;
+	input      [AWIDTH-1:0] ra_b;
+	output reg [DWIDTH-1:0] rq_b;
+	input                   wce_b;
+	input      [AWIDTH-1:0] wa_b;
+	input      [DWIDTH-1:0] wd_b;
+
+	reg        [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1];
+
+	always @(posedge clk_a) begin
+		if (rce_a)
+			rq_a <= memory[ra_a];
+
+		if (wce_a)
+			memory[wa_a] <= wd_a;
+	end
+
+	always @(posedge clk_b) begin
+		if (rce_b)
+			rq_b <= memory[ra_b];
+
+		if (wce_b)
+			memory[wa_b] <= wd_b;
+	end
+
+	integer i;
+	initial
+	begin
+		for(i = 0; i < (1<<AWIDTH)-1; i = i + 1)
+			memory[i] = 0;
+	end
+
+endmodule
+
+module BRAM_TDP_SPLIT_2x18K #(parameter AWIDTH = 10, parameter DWIDTH = 18)(
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_0 (.clk_a(clk_a_0),
+		 .rce_a(rce_a_0),
+		 .ra_a(ra_a_0),
+		 .rq_a(rq_a_0),
+		 .wce_a(wce_a_0),
+		 .wa_a(wa_a_0),
+		 .wd_a(wd_a_0),
+		 .clk_b(clk_b_0),
+		 .rce_b(rce_b_0),
+		 .ra_b(ra_b_0),
+		 .rq_b(rq_b_0),
+		 .wce_b(wce_b_0),
+		 .wa_b(wa_b_0),
+		 .wd_b(wd_b_0));
+
+BRAM_TDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_1 (.clk_a(clk_a_1),
+		 .rce_a(rce_a_1),
+		 .ra_a(ra_a_1),
+		 .rq_a(rq_a_1),
+		 .wce_a(wce_a_1),
+		 .wa_a(wa_a_1),
+		 .wd_a(wd_a_1),
+		 .clk_b(clk_b_1),
+		 .rce_b(rce_b_1),
+		 .ra_b(ra_b_1),
+		 .rq_b(rq_b_1),
+		 .wce_b(wce_b_1),
+		 .wa_b(wa_b_1),
+		 .wd_b(wd_b_1));
+endmodule
+
+
+module BRAM_TDP_SPLIT_2x18x1024 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 18;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x18x1024 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+
+module BRAM_TDP_SPLIT_2x16x1024 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 10;
+parameter DWIDTH = 16;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x16x1024 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+
+module BRAM_TDP_SPLIT_2x9x2048 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 9;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x9x2048 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+module BRAM_TDP_SPLIT_2x8x2048 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 11;
+parameter DWIDTH = 8;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x8x2048 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+module BRAM_TDP_SPLIT_2x4x4096 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 12;
+parameter DWIDTH = 4;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x4x4096 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+module BRAM_TDP_SPLIT_2x2x8192 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 13;
+parameter DWIDTH = 2;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x2x8192 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
+module BRAM_TDP_SPLIT_2x1x16384 (
+	clk_a_0,
+	rce_a_0,
+	ra_a_0,
+	rq_a_0,
+	wce_a_0,
+	wa_a_0,
+	wd_a_0,
+
+	clk_a_1,
+	rce_a_1,
+	ra_a_1,
+	rq_a_1,
+	wce_a_1,
+	wa_a_1,
+	wd_a_1,
+
+	clk_b_0,
+	rce_b_0,
+	ra_b_0,
+	rq_b_0,
+	wce_b_0,
+	wa_b_0,
+	wd_b_0,
+
+	clk_b_1,
+	rce_b_1,
+	ra_b_1,
+	rq_b_1,
+	wce_b_1,
+	wa_b_1,
+	wd_b_1
+);
+
+parameter AWIDTH = 14;
+parameter DWIDTH = 1;
+
+	input			clk_a_0;
+	input                   rce_a_0;
+	input      [AWIDTH-1:0] ra_a_0;
+	output     [DWIDTH-1:0] rq_a_0;
+	input                   wce_a_0;
+	input      [AWIDTH-1:0] wa_a_0;
+	input      [DWIDTH-1:0] wd_a_0;
+	input			clk_b_0;
+	input                   rce_b_0;
+	input      [AWIDTH-1:0] ra_b_0;
+	output     [DWIDTH-1:0] rq_b_0;
+	input                   wce_b_0;
+	input      [AWIDTH-1:0] wa_b_0;
+	input      [DWIDTH-1:0] wd_b_0;
+
+	input			clk_a_1;
+	input                   rce_a_1;
+	input      [AWIDTH-1:0] ra_a_1;
+	output     [DWIDTH-1:0] rq_a_1;
+	input                   wce_a_1;
+	input      [AWIDTH-1:0] wa_a_1;
+	input      [DWIDTH-1:0] wd_a_1;
+	input			clk_b_1;
+	input                   rce_b_1;
+	input      [AWIDTH-1:0] ra_b_1;
+	output     [DWIDTH-1:0] rq_b_1;
+	input                   wce_b_1;
+	input      [AWIDTH-1:0] wa_b_1;
+	input      [DWIDTH-1:0] wd_b_1;
+
+BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
+	BRAM_TDP_SPLIT_2x1x16384 (
+		 .clk_a_0(clk_a_0),
+		 .rce_a_0(rce_a_0),
+		 .ra_a_0(ra_a_0),
+		 .rq_a_0(rq_a_0),
+		 .wce_a_0(wce_a_0),
+		 .wa_a_0(wa_a_0),
+		 .wd_a_0(wd_a_0),
+		 .clk_b_0(clk_b_0),
+		 .rce_b_0(rce_b_0),
+		 .ra_b_0(ra_b_0),
+		 .rq_b_0(rq_b_0),
+		 .wce_b_0(wce_b_0),
+		 .wa_b_0(wa_b_0),
+		 .wd_b_0(wd_b_0),
+		 .clk_a_1(clk_a_1),
+		 .rce_a_1(rce_a_1),
+		 .ra_a_1(ra_a_1),
+		 .rq_a_1(rq_a_1),
+		 .wce_a_1(wce_a_1),
+		 .wa_a_1(wa_a_1),
+		 .wd_a_1(wd_a_1),
+		 .clk_b_1(clk_b_1),
+		 .rce_b_1(rce_b_1),
+		 .ra_b_1(ra_b_1),
+		 .rq_b_1(rq_b_1),
+		 .wce_b_1(wce_b_1),
+		 .wa_b_1(wa_b_1),
+		 .wd_b_1(wd_b_1));
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/Makefile
new file mode 100644
index 000000000..a065bb277
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/Makefile
@@ -0,0 +1,38 @@
+# Copyright (C) 2019-2022 The SymbiFlow Authors
+#
+# Use of this source code is governed by a ISC-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/ISC
+#
+# SPDX-License-Identifier: ISC
+
+TESTBENCH = bram_tdp_split_tb.v
+POST_SYNTH = bram_tdp_split_2x18x1024_post_synth bram_tdp_split_2x16x1024_post_synth bram_tdp_split_2x9x2048_post_synth bram_tdp_split_2x8x2048_post_synth bram_tdp_split_2x4x4096_post_synth bram_tdp_split_2x2x8192_post_synth bram_tdp_split_2x1x16384_post_synth
+ADDR_WIDTH = 10 10 11 11 12 13 14
+DATA_WIDTH = 18 16 9 8 4 2 1
+TOP = BRAM_TDP_SPLIT_2x18x1024 BRAM_TDP_SPLIT_2x16x1024 BRAM_TDP_SPLIT_2x9x2048 BRAM_TDP_SPLIT_2x8x2048 BRAM_TDP_SPLIT_2x4x4096 BRAM_TDP_SPLIT_2x2x8192 BRAM_TDP_SPLIT_2x1x16384
+ADDR_DEFINES = $(foreach awidth, $(ADDR_WIDTH),-DADDR_WIDTH="$(awidth)")
+DATA_DEFINES = $(foreach dwidth, $(DATA_WIDTH),-DDATA_WIDTH="$(dwidth)")
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(ADDR_DEFINES)) $(word $(1),$(DATA_DEFINES)) $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+#FIXME: $(call simulate_post_synth,3)
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
+	$(call simulate_post_synth,4)
+	$(call simulate_post_synth,5)
+	$(call simulate_post_synth,6)
+	$(call simulate_post_synth,7)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/bram_tdp_split_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/bram_tdp_split_tb.v
new file mode 100644
index 000000000..5ff822d2c
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/bram_tdp_split/sim/bram_tdp_split_tb.v
@@ -0,0 +1,415 @@
+// Copyright (C) 2019-2022 The SymbiFlow Authors
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier: ISC
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module TB;
+	localparam PERIOD = 50;
+	localparam ADDR_INCR = 1;
+
+	reg clk_a;
+	reg rce_a;
+	reg [`ADDR_WIDTH-1:0] ra_a;
+	wire [`DATA_WIDTH-1:0] rq_a_0;
+	wire [`DATA_WIDTH-1:0] rq_a_1;
+	reg wce_a;
+	reg [`ADDR_WIDTH-1:0] wa_a;
+	reg [`DATA_WIDTH-1:0] wd_a_0;
+	reg [`DATA_WIDTH-1:0] wd_a_1;
+
+	reg clk_b;
+	reg rce_b;
+	reg [`ADDR_WIDTH-1:0] ra_b;
+	wire [`DATA_WIDTH-1:0] rq_b_0;
+	wire [`DATA_WIDTH-1:0] rq_b_1;
+	reg wce_b;
+	reg [`ADDR_WIDTH-1:0] wa_b;
+	reg [`DATA_WIDTH-1:0] wd_b_0;
+	reg [`DATA_WIDTH-1:0] wd_b_1;
+
+
+	initial clk_a = 0;
+	initial clk_b = 0;
+	initial ra_a = 0;
+	initial ra_b = 0;
+	initial rce_a = 0;
+	initial rce_b = 0;
+	initial forever #(PERIOD / 2.0) clk_a = ~clk_a;
+	initial begin
+		#(PERIOD / 4.0);
+		forever #(PERIOD / 2.0) clk_b = ~clk_b;
+	end
+	initial begin
+		$dumpfile(`STRINGIFY(`VCD));
+		$dumpvars;
+	end
+
+	integer a;
+	integer b;
+
+	reg done_a;
+	reg done_b;
+	initial done_a = 1'b0;
+	initial done_b = 1'b0;
+	wire done_sim = done_a & done_b;
+
+	reg [`DATA_WIDTH-1:0] expected_a_0;
+	reg [`DATA_WIDTH-1:0] expected_a_1;
+	reg [`DATA_WIDTH-1:0] expected_b_0;
+	reg [`DATA_WIDTH-1:0] expected_b_1;
+
+	always @(posedge clk_a) begin
+		expected_a_0 <= (a | (a << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+		expected_a_1 <= ((a+1) | ((a+1) << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+	always @(posedge clk_b) begin
+		expected_b_0 <= ((b+2) | ((b+2) << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+		expected_b_1 <= ((b+3) | ((b+3) << 20) | 20'h55000) & {`DATA_WIDTH{1'b1}};
+	end
+
+	wire error_a_0 = a != 0 ? (rq_a_0 !== expected_a_0) : 0;
+	wire error_a_1 = a != 0 ? (rq_a_1 !== expected_a_1) : 0;
+	wire error_b_0 = b != (1<<`ADDR_WIDTH) / 2 ? (rq_b_0 !== expected_b_0) : 0;
+	wire error_b_1 = b != (1<<`ADDR_WIDTH) / 2 ? (rq_b_1 !== expected_b_1) : 0;
+
+	integer error_a_0_cnt = 0;
+	integer error_a_1_cnt = 0;
+	integer error_b_0_cnt = 0;
+	integer error_b_1_cnt = 0;
+
+	always @ (posedge clk_a)
+	begin
+		if (error_a_0)
+			error_a_0_cnt <= error_a_0_cnt + 1'b1;
+		if (error_a_1)
+			error_a_1_cnt <= error_a_1_cnt + 1'b1;
+	end
+	always @ (posedge clk_b)
+	begin
+		if (error_b_0)
+			error_b_0_cnt <= error_b_0_cnt + 1'b1;
+		if (error_b_1)
+			error_b_1_cnt <= error_b_1_cnt + 1'b1;
+	end
+
+	// PORTs A
+	initial #(1) begin
+		// Write data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				wa_a = a;
+				wd_a_0 = a | (a << 20) | 20'h55000;
+				wd_a_1 = (a+1) | ((a+1) << 20) | 20'h55000;
+				wce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) wce_a = 0;
+			end
+		end
+		// Read data
+		for (a = 0; a < (1<<`ADDR_WIDTH) / 2; a = a + ADDR_INCR) begin
+			@(negedge clk_a) begin
+				ra_a = a;
+				rce_a = 1;
+			end
+			@(posedge clk_a) begin
+				#(PERIOD/10) rce_a = 0;
+				if ( rq_a_0 !== expected_a_0) begin
+					$display("%d: PORT A0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a_0, expected_a_0, a);
+				end else begin
+					$display("%d: PORT A0: OK: act=%x exp=%x at %x", $time, rq_a_0, expected_a_0, a);
+				end
+				if ( rq_a_1 !== expected_a_1) begin
+					$display("%d: PORT A1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_a_1, expected_a_1, a);
+				end else begin
+					$display("%d: PORT A1: OK: act=%x exp=%x at %x", $time, rq_a_1, expected_a_1, a);
+				end
+			end
+		end
+		done_a = 1'b1;
+	end
+
+	// PORTs B
+	initial #(1) begin
+		// Write data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				wa_b = b;
+				wd_b_0 = (b+2) | ((b+2) << 20) | 20'h55000;
+				wd_b_1 = (b+3) | ((b+3) << 20) | 20'h55000;
+				wce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) wce_b = 0;
+			end
+		end
+		// Read data
+		for (b = (1<<`ADDR_WIDTH) / 2; b < (1<<`ADDR_WIDTH); b = b + ADDR_INCR) begin
+			@(negedge clk_b) begin
+				ra_b = b;
+				rce_b = 1;
+			end
+			@(posedge clk_b) begin
+				#(PERIOD/10) rce_b = 0;
+				if ( rq_b_0 !== expected_b_0) begin
+					$display("%d: PORT B0: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b_0, expected_b_0, b);
+				end else begin
+					$display("%d: PORT B0: OK: act=%x exp=%x at %x", $time, rq_b_0, expected_b_0, b);
+				end
+				if ( rq_b_1 !== expected_b_1) begin
+					$display("%d: PORT B1: FAIL: mismatch act=%x exp=%x at %x", $time, rq_b_1, expected_b_1, b);
+				end else begin
+					$display("%d: PORT B1: OK: act=%x exp=%x at %x", $time, rq_b_1, expected_b_1, b);
+				end
+			end
+		end
+		done_b = 1'b1;
+	end
+
+	// Scan for simulation finish
+	always @(posedge clk_a, posedge clk_b) begin
+		if (done_sim)
+			$finish_and_return( (error_a_0_cnt == 0 & error_b_0_cnt == 0 & error_a_1_cnt == 0 & error_b_1_cnt == 0) ? 0 : -1 );
+	end
+
+	case (`STRINGIFY(`TOP))
+		"BRAM_TDP_SPLIT_2x18x1024": begin
+			BRAM_TDP_SPLIT_2x18x1024 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x16x1024": begin
+			BRAM_TDP_SPLIT_2x16x1024 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x9x2048": begin
+			BRAM_TDP_SPLIT_2x9x2048 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x8x2048": begin
+			BRAM_TDP_SPLIT_2x8x2048 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x4x4096": begin
+			BRAM_TDP_SPLIT_2x4x4096 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x2x8192": begin
+			BRAM_TDP_SPLIT_2x2x8192 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+		"BRAM_TDP_SPLIT_2x1x16384": begin
+			BRAM_TDP_SPLIT_2x1x16384 #() bram (
+				.clk_a_0(clk_a),
+				.rce_a_0(rce_a),
+				.ra_a_0(ra_a),
+				.rq_a_0(rq_a_0),
+				.wce_a_0(wce_a),
+				.wa_a_0(wa_a),
+				.wd_a_0(wd_a_0),
+				.clk_b_0(clk_b),
+				.rce_b_0(rce_b),
+				.ra_b_0(ra_b),
+				.rq_b_0(rq_b_0),
+				.wce_b_0(wce_b),
+				.wa_b_0(wa_b),
+				.wd_b_0(wd_b_0),
+
+				.clk_a_1(clk_a),
+				.rce_a_1(rce_a),
+				.ra_a_1(ra_a),
+				.rq_a_1(rq_a_1),
+				.wce_a_1(wce_a),
+				.wa_a_1(wa_a),
+				.wd_a_1(wd_a_1),
+				.clk_b_1(clk_b),
+				.rce_b_1(rce_b),
+				.ra_b_1(ra_b),
+				.rq_b_1(rq_b_1),
+				.wce_b_1(wce_b),
+				.wa_b_1(wa_b),
+				.wd_b_1(wd_b_1)
+			);
+		end
+	endcase
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.tcl
new file mode 100644
index 000000000..377689af2
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.tcl
@@ -0,0 +1,80 @@
+# For some tests the equiv_induct pass seems to hang if opt_expr + opt_clean
+# are not invoked after techmapping. Therefore this function is used instead
+# of the equiv_opt pass.
+proc check_equiv {top use_cfg_params} {
+    hierarchy -top ${top}
+
+    design -save preopt
+
+    if {${use_cfg_params} == 1} {
+        synth_quicklogic -family qlf_k6n10f -top ${top} -use_dsp_cfg_params
+    } else {
+        stat
+        synth_quicklogic -family qlf_k6n10f -top ${top}
+    }
+
+    design -stash postopt
+
+    design -copy-from preopt  -as gold A:top
+    design -copy-from postopt -as gate A:top
+
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/cells_sim.v
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/dsp_sim.v
+    yosys proc
+    opt_expr
+    opt_clean -purge
+
+    async2sync
+    equiv_make gold gate equiv
+    equiv_induct equiv
+    equiv_status -assert equiv
+
+    return
+}
+
+# Test inference of 2 available DSP variants
+# * top - design name
+# * expected_cell_suffix - suffix of the cell that should be the result
+#           of the inference, eg. _MULT, _MACC_REGIN, MADD_REGIN_REGOUT
+proc test_dsp_design {top expected_cell_suffix} {
+    set TOP ${top}
+    # Infer DSP with configuration bits passed through ports
+    # We expect QL_DSP2 cells inferred
+    set USE_DSP_CFG_PARAMS 0
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${top}
+    select -assert-count 1 t:QL_DSP2${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    # Infer DSP with configuration bits passed through parameters
+    # We expect QL_DSP3 cells inferred
+    set USE_DSP_CFG_PARAMS 1
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}
+    select -assert-count 1 t:QL_DSP3${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    return
+}
+
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+read_verilog dsp_macc.v
+design -save read
+
+test_dsp_design "macc_simple"               "_MULTACC"
+test_dsp_design "macc_simple_clr"           "_MULTACC"
+test_dsp_design "macc_simple_arst"          "_MULTACC"
+test_dsp_design "macc_simple_ena"           "_MULTACC"
+test_dsp_design "macc_simple_arst_clr_ena"  "_MULTACC"
+test_dsp_design "macc_simple_preacc"        "_MULTACC"
+test_dsp_design "macc_simple_preacc_clr"    "_MULTACC"
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.v
new file mode 100644
index 000000000..dd9549a5f
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_macc/dsp_macc.v
@@ -0,0 +1,121 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module macc_simple (
+    input  wire        clk,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    always @(posedge clk)
+        Z <= Z + (A * B);
+
+endmodule
+
+module macc_simple_clr (
+    input  wire        clk,
+    input  wire        clr,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    always @(posedge clk)
+        if (clr) Z <=     (A * B);
+        else     Z <= Z + (A * B);
+
+endmodule
+
+module macc_simple_arst (
+    input  wire        clk,
+    input  wire        rst,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    always @(posedge clk or posedge rst)
+        if (rst) Z <= 0;
+        else     Z <= Z + (A * B);
+
+endmodule
+
+module macc_simple_ena (
+    input  wire        clk,
+    input  wire        ena,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    always @(posedge clk)
+        if (ena) Z <= Z + (A * B);
+
+endmodule
+
+module macc_simple_arst_clr_ena (
+    input  wire        clk,
+    input  wire        rst,
+    input  wire        clr,
+    input  wire        ena,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    always @(posedge clk or posedge rst)
+        if (rst)     Z <= 0;
+        else if (ena) begin
+            if (clr) Z <=     (A * B);
+            else     Z <= Z + (A * B);
+        end
+
+endmodule
+
+module macc_simple_preacc (
+    input  wire        clk,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output wire [15:0] Z
+);
+
+    reg [15:0] acc;
+
+    assign Z = acc + (A * B);
+
+    always @(posedge clk)
+        acc <= Z;
+
+endmodule
+
+module macc_simple_preacc_clr (
+    input  wire        clk,
+    input  wire        clr,
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output reg  [15:0] Z
+);
+
+    reg [15:0] acc;
+
+    assign Z = (clr) ? (A * B) : (acc + (A * B));
+
+    always @(posedge clk)
+        acc <= Z;
+
+endmodule
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.tcl
new file mode 100644
index 000000000..eeefa6061
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.tcl
@@ -0,0 +1,78 @@
+# For some tests the equiv_induct pass seems to hang if opt_expr + opt_clean
+# are not invoked after techmapping. Therefore this function is used instead
+# of the equiv_opt pass.
+proc check_equiv {top use_cfg_params} {
+    hierarchy -top ${top}
+
+    design -save preopt
+
+    if {${use_cfg_params} == 1} {
+        synth_quicklogic -family qlf_k6n10f -top ${top} -use_dsp_cfg_params
+    } else {
+        stat
+        synth_quicklogic -family qlf_k6n10f -top ${top}
+    }
+
+    design -stash postopt
+
+    design -copy-from preopt  -as gold A:top
+    design -copy-from postopt -as gate A:top
+
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/cells_sim.v
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/dsp_sim.v
+    yosys proc
+    opt_expr
+    opt_clean -purge
+
+    async2sync
+    equiv_make gold gate equiv
+    equiv_induct equiv
+    equiv_status -assert equiv
+
+    return
+}
+
+proc test_dsp_design {top expected_cell_suffix} {
+    set TOP ${top}
+    # Infer DSP with configuration bits passed through ports
+    # We expect QL_DSP2 cells inferred
+    set USE_DSP_CFG_PARAMS 0
+    design -load read
+    hierarchy -top ${TOP}_ports
+    check_equiv ${TOP}_ports ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}_ports
+    select -assert-count 1 t:QL_DSP2${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    # Infer DSP with configuration bits passed through parameters
+    # We expect QL_DSP3 cells inferred
+    set USE_DSP_CFG_PARAMS 1
+    design -load read
+    hierarchy -top ${TOP}_params
+    check_equiv ${TOP}_params ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}_params
+    select -assert-count 1 t:QL_DSP3${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    return
+}
+
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+read_verilog dsp_madd.v
+design -save read
+
+test_dsp_design "madd_simple"               "_MULTADD"
+
+#test_dsp_design "macc_simple"               "_MULTACC"
+#test_dsp_design "macc_simple_clr"           "_MULTACC"
+#test_dsp_design "macc_simple_arst"          "_MULTACC"
+#test_dsp_design "macc_simple_ena"           "_MULTACC"
+#test_dsp_design "macc_simple_arst_clr_ena"  "_MULTACC"
+#test_dsp_design "macc_simple_preacc"        "_MULTACC"
+#test_dsp_design "macc_simple_preacc_clr"    "_MULTACC"
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.v
new file mode 100644
index 000000000..1a02667e2
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_madd/dsp_madd.v
@@ -0,0 +1,104 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module madd_simple_ports (
+    input  wire [ 9:0] A,
+    input  wire [ 8:0] B,
+    input  wire [ 1:0] C,
+    output reg  [18:0] Z
+);
+
+    // There is no support for autmoatic inference of multiply+add hence the
+    // DSP cell needs to be instanced manually.
+    //
+    // To test the type change the "is_inferred" attribute is set here
+    // explicitily to mimic possible inference
+
+    // B * coeff[C] + A
+    (* is_inferred=1 *)
+    dsp_t1_10x9x32_cfg_ports # (
+        .COEFF_0            (10'h011),
+        .COEFF_1            (10'h022),
+        .COEFF_2            (10'h033),
+        .COEFF_3            (10'h044)
+    ) dsp (
+        .a_i                (A),
+        .b_i                (B),
+        .acc_fir_i          (6'd0),
+        .z_o                (Z),
+        .dly_b_o            (),
+
+        .feedback_i         ({1'b1, C}), // 4-7
+        .output_select_i    (3'd3),
+        .register_inputs_i  (1'b0),
+
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+        .load_acc_i         (1'b1),
+
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0)
+    );
+
+endmodule
+
+module madd_simple_params (
+    input  wire [ 9:0] A,
+    input  wire [ 8:0] B,
+    input  wire [ 1:0] C,
+    output reg  [18:0] Z
+);
+
+    // There is no support for autmoatic inference of multiply+add hence the
+    // DSP cell needs to be instanced manually.
+    //
+    // To test the type change the "is_inferred" attribute is set here
+    // explicitily to mimic possible inference
+
+    // B * coeff[C] + A
+    (* is_inferred=1 *)
+    dsp_t1_10x9x32_cfg_params # (
+        .COEFF_0            (10'h011),
+        .COEFF_1            (10'h022),
+        .COEFF_2            (10'h033),
+        .COEFF_3            (10'h044),
+
+        .OUTPUT_SELECT      (3'd3),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b0)
+    ) dsp (
+        .a_i                (A),
+        .b_i                (B),
+        .acc_fir_i          (6'd0),
+        .z_o                (Z),
+        .dly_b_o            (),
+
+        .feedback_i         ({1'b1, C}), // 4-7
+
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+        .load_acc_i         (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+endmodule
+
+// ............................................................................
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.tcl
new file mode 100644
index 000000000..aea70766f
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.tcl
@@ -0,0 +1,77 @@
+# For some tests the equiv_induct pass seems to hang if opt_expr + opt_clean
+# are not invoked after techmapping. Therefore this function is used instead
+# of the equiv_opt pass.
+proc check_equiv {top use_cfg_params} {
+    hierarchy -top ${top}
+
+    design -save preopt
+
+    if {${use_cfg_params} == 1} {
+        synth_quicklogic -family qlf_k6n10f -top ${top} -use_dsp_cfg_params
+    } else {
+        stat
+        synth_quicklogic -family qlf_k6n10f -top ${top}
+    }
+
+    design -stash postopt
+
+    design -copy-from preopt  -as gold A:top
+    design -copy-from postopt -as gate A:top
+
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/cells_sim.v
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/dsp_sim.v
+    yosys proc
+    opt_expr
+    opt_clean -purge
+
+    async2sync
+    equiv_make gold gate equiv
+    equiv_induct equiv
+    equiv_status -assert equiv
+
+    return
+}
+
+# Test inference of 2 available DSP variants
+# * top - design name
+# * expected_cell_suffix - suffix of the cell that should be the result
+#           of the inference, eg. _MULT, _MACC_REGIN, MADD_REGIN_REGOUT
+proc test_dsp_design {top expected_cell_suffix} {
+    set TOP ${top}
+    # Infer DSP with configuration bits passed through ports
+    # We expect QL_DSP2 cells inferred
+    set USE_DSP_CFG_PARAMS 0
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${top}
+    select -assert-count 1 t:QL_DSP2${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    # Infer DSP with configuration bits passed through parameters
+    # We expect QL_DSP3 cells inferred
+    set USE_DSP_CFG_PARAMS 1
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}
+    select -assert-count 1 t:QL_DSP3${expected_cell_suffix}
+    select -assert-count 1 t:*
+
+    return
+}
+
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+read_verilog dsp_mult.v
+design -save read
+
+test_dsp_design "mult_16x16"    "_MULT"
+test_dsp_design "mult_20x18"    "_MULT"
+test_dsp_design "mult_8x8"      "_MULT"
+test_dsp_design "mult_10x9"     "_MULT"
+test_dsp_design "mult_8x8_s"    "_MULT"
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.v
new file mode 100644
index 000000000..8baf45d17
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult/dsp_mult.v
@@ -0,0 +1,65 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module mult_16x16 (
+    input  wire [15:0] A,
+    input  wire [15:0] B,
+    output wire [31:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
+
+module mult_20x18 (
+    input  wire [19:0] A,
+    input  wire [17:0] B,
+    output wire [37:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
+
+module mult_8x8 (
+    input  wire [ 7:0] A,
+    input  wire [ 7:0] B,
+    output wire [15:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
+
+module mult_10x9 (
+    input  wire [ 9:0] A,
+    input  wire [ 8:0] B,
+    output wire [18:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
+
+module mult_8x8_s (
+    input  wire signed [ 7:0] A,
+    input  wire signed [ 7:0] B,
+    output wire signed [15:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.tcl
new file mode 100644
index 000000000..8ef551f17
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.tcl
@@ -0,0 +1,27 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save dsp_mult_post_synth_sim
+
+select dsp_mult
+select *
+synth_quicklogic -family qlf_k6n10f -top dsp_mult
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dsp_mult_ports_post_synth.v
+select -assert-count 1 t:QL_DSP2_MULT
+
+select -clear
+design -load dsp_mult_post_synth_sim
+select dsp_mult
+select *
+synth_quicklogic -family qlf_k6n10f -top dsp_mult -use_dsp_cfg_params
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/dsp_mult_params_post_synth.v
+select -assert-count 1 t:QL_DSP3_MULT
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.v
new file mode 100644
index 000000000..e9cec3c6a
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/dsp_mult_post_synth_sim.v
@@ -0,0 +1,25 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module dsp_mult (
+    input  wire [19:0] A,
+    input  wire [17:0] B,
+    output wire [37:0] Z
+);
+
+    assign Z = A * B;
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/Makefile
new file mode 100644
index 000000000..10f1cc171
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/Makefile
@@ -0,0 +1,36 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = dsp_mult_post_synth_sim_tb.v
+POST_SYNTH = dsp_mult_ports_post_synth dsp_mult_params_post_synth
+TOP = dsp_mult dsp_mult
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/dsp_mult_post_synth_sim_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/dsp_mult_post_synth_sim_tb.v
new file mode 100644
index 000000000..809aaeec8
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_mult_post_synth_sim/sim/dsp_mult_post_synth_sim_tb.v
@@ -0,0 +1,82 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #1 clk <= ~clk;
+
+    // Data Clock
+    reg dclk;
+    initial dclk <= 1'b0;
+    always #2 dclk <= ~dclk;
+
+    // Input data / reference
+    reg [19:0] A0;
+
+    reg [17:0] B0;
+
+    reg [37:0] C0;
+
+    always @(negedge dclk) begin
+        A0 = $random;
+        B0 = $random;
+
+        C0 <= A0 * B0;
+    end
+
+    // UUT
+    wire [37:0] Z0;
+
+    case (`STRINGIFY(`TOP))
+        "dsp_mult": begin
+            dsp_mult dsp0 (
+                .A(A0),
+                .B(B0),
+                .Z(Z0)
+            );
+        end
+    endcase
+
+    // Error detection
+    wire error0 = (Z0 !== C0) && (C0 !== 38'bx);
+
+    // Error counting
+    integer error_count = 0;
+
+    always @(posedge clk) begin
+        if (error0) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_0: FAIL: mismatch act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0, A0, B0);
+        end else begin
+            $display("%d: DSP_0: OK: act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0, A0, B0);
+        end
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`STRINGIFY(`VCD));
+        $dumpvars;
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.tcl
new file mode 100644
index 000000000..5f65729fc
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.tcl
@@ -0,0 +1,117 @@
+# For some tests the equiv_induct pass seems to hang if opt_expr + opt_clean
+# are not invoked after techmapping. Therefore this function is used instead
+# of the equiv_opt pass.
+proc check_equiv {top use_cfg_params} {
+    hierarchy -top ${top}
+
+    design -save preopt
+
+    if {${use_cfg_params} == 1} {
+        synth_quicklogic -family qlf_k6n10f -top ${top} -use_dsp_cfg_params
+    } else {
+        stat
+        synth_quicklogic -family qlf_k6n10f -top ${top}
+    }
+
+    design -stash postopt
+
+    design -copy-from preopt  -as gold A:top
+    design -copy-from postopt -as gate A:top
+
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/cells_sim.v
+    techmap -wb -autoproc -map +/quicklogic/qlf_k6n10f/dsp_sim.v
+    yosys proc
+    opt_expr
+    opt_clean
+
+    async2sync
+    equiv_make gold gate equiv
+    equiv_induct equiv
+    equiv_status -assert equiv
+
+    return
+}
+
+# Test inference of DSP variant
+# Infer DSP with configuration bits passed through ports
+# We expect QL_DSP2 cells
+# * top - design name
+# * expected_cell_suffix - suffix of the cell that should be the result
+#           of the inference, eg. _MULT, _MACC_REGIN, MADD_REGIN_REGOUT
+# * cells2match - how much expected cells should be asserted
+proc test_dsp_cfg_ports {top expected_cell_suffix cells2match} {
+    set TOP ${top}
+    set USE_DSP_CFG_PARAMS 0
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${top}
+    select -assert-count ${cells2match} t:QL_DSP2${expected_cell_suffix}
+    select -assert-count 0 t:dsp_t1_10x9x32_cfg_ports
+    select -assert-count 0 t:dsp_t1_20x18x64_cfg_ports
+
+    return
+}
+
+# Test inference of DSP variant
+# Infer DSP with configuration bits passed through parameters
+# We expect QL_DSP3 cells inferred
+# * top - design name
+# * expected_cell_suffix - suffix of the cell that should be the result
+#           of the inference, eg. _MULT, _MACC_REGIN, MADD_REGIN_REGOUT
+# * cells2match - how much expected cells should be asserted
+proc test_dsp_cfg_params {top expected_cell_suffix cells2match} {
+    set TOP ${top}
+    set USE_DSP_CFG_PARAMS 1
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}
+    select -assert-count ${cells2match} t:QL_DSP3${expected_cell_suffix}
+    select -assert-count 0 t:dsp_t1_10x9x32_cfg_params
+    select -assert-count 0 t:dsp_t1_20x18x64_cfg_params
+
+    return
+}
+
+# Test special case of inference of DSP
+# Infer DSPs with configuration bits conflict
+# One internal module use parameters, the other one ports
+# We expect one QL_DSP2 and one QL_DSP3 inferred
+# * top - design name
+# * expected_cell_suffix - suffix of the cell that should be the result
+#           of the inference, eg. _MULT, _MACC_REGIN, MADD_REGIN_REGOUT
+proc test_dsp_cfg_conflict {top expected_cell_suffix} {
+    set TOP ${top}
+    set USE_DSP_CFG_PARAMS 0
+    design -load read
+    hierarchy -top $TOP
+    check_equiv ${TOP} ${USE_DSP_CFG_PARAMS}
+    design -load postopt
+    yosys cd ${TOP}
+    select -assert-count 2 t:QL_DSP2${expected_cell_suffix}
+    select -assert-count 0 t:dsp_t1_10x9x32_cfg_ports
+    select -assert-count 0 t:dsp_t1_20x18x64_cfg_ports
+    select -assert-count 0 t:dsp_t1_10x9x32_cfg_params
+    select -assert-count 0 t:dsp_t1_20x18x64_cfg_params
+
+    return
+}
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf}
+yosys -import  ;# ingest plugin commands
+
+read_verilog dsp_simd.v
+design -save read
+
+test_dsp_cfg_ports      "simd_mult_explicit_ports"      ""       1
+test_dsp_cfg_params     "simd_mult_explicit_params"     ""       1
+test_dsp_cfg_ports      "simd_mult_inferred"            "_MULT"  1
+test_dsp_cfg_params     "simd_mult_inferred"            "_MULT"  1
+test_dsp_cfg_ports      "simd_mult_odd_ports"           ""       2
+test_dsp_cfg_params     "simd_mult_odd_params"          ""       2
+test_dsp_cfg_ports      "simd_mult_conflict_ports"      ""       2
+test_dsp_cfg_conflict   "simd_mult_conflict_config"     ""
+
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.v
new file mode 100644
index 000000000..0b86a53ec
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd/dsp_simd.v
@@ -0,0 +1,414 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module simd_mult_explicit_ports (
+    input  wire         clk,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+endmodule
+
+module simd_mult_explicit_params (
+    input  wire         clk,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+endmodule
+
+module simd_mult_inferred (
+    input  wire         clk,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output reg  [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output reg  [15:0]  z1
+);
+
+    always @(posedge clk)
+        z0 <= a0 * b0;
+
+    always @(posedge clk)
+        z1 <= a1 * b1;
+
+endmodule
+
+module simd_mult_odd_ports (
+    input  wire         clk,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1,
+
+    input  wire [ 7:0]  a2,
+    input  wire [ 7:0]  b2,
+    output wire [15:0]  z2
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_2 (
+        .a_i    (a2),
+        .b_i    (b2),
+        .z_o    (z2),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+endmodule
+
+module simd_mult_odd_params (
+    input  wire         clk,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1,
+
+    input  wire [ 7:0]  a2,
+    input  wire [ 7:0]  b2,
+    output wire [15:0]  z2
+);
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_2 (
+        .a_i    (a2),
+        .b_i    (b2),
+        .z_o    (z2),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+endmodule
+
+module simd_mult_conflict_ports (
+    input  wire         clk0,
+    input  wire         clk1,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk0),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk1),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+endmodule
+
+module simd_mult_conflict_config (
+    input  wire         clk0,
+    input  wire         clk1,
+
+    input  wire [ 7:0]  a0,
+    input  wire [ 7:0]  b0,
+    output wire [15:0]  z0,
+
+    input  wire [ 7:0]  a1,
+    input  wire [ 7:0]  b1,
+    output wire [15:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk0),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk1),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b0)
+    );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.tcl b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.tcl
new file mode 100644
index 000000000..5fbc441b5
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.tcl
@@ -0,0 +1,38 @@
+yosys -import
+
+if { [info procs ql-qlf-k6n10f] == {} } { plugin -i ql-qlf }
+yosys -import  ;
+
+read_verilog $::env(DESIGN_TOP).v
+design -save dsp_simd
+
+select simd_mult
+select *
+synth_quicklogic -family qlf_k6n10f -top simd_mult
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/simd_mult_post_synth.v
+select -assert-count 1 t:QL_DSP2_MULT
+
+select -clear
+design -load dsp_simd
+select simd_mult_explicit_ports
+select *
+synth_quicklogic -family qlf_k6n10f -top simd_mult_explicit_ports
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/simd_mult_explicit_ports_post_synth.v
+select -assert-count 1 t:QL_DSP2
+
+select -clear
+design -load dsp_simd
+select simd_mult_explicit_params
+select *
+synth_quicklogic -family qlf_k6n10f -top simd_mult_explicit_params -use_dsp_cfg_params
+opt_expr -undriven
+opt_clean
+stat
+write_verilog sim/simd_mult_explicit_params_post_synth.v
+select -assert-count 1 t:QL_DSP3
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.v
new file mode 100644
index 000000000..3b2a96b6d
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/dsp_simd_post_synth_sim.v
@@ -0,0 +1,145 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module simd_mult (
+    input  wire         clk,
+
+    input  wire [ 9:0]  a0,
+    input  wire [ 8:0]  b0,
+    output reg  [18:0]  z0,
+
+    input  wire [ 9:0]  a1,
+    input  wire [ 8:0]  b1,
+    output reg  [18:0]  z1
+);
+
+    always @(posedge clk)
+        z0 <= a0 * b0;
+
+    always @(posedge clk)
+        z1 <= a1 * b1;
+
+endmodule
+
+module simd_mult_explicit_ports (
+    input  wire         clk,
+
+    input  wire [ 9:0]  a0,
+    input  wire [ 9:0]  b0,
+    output wire [18:0]  z0,
+
+    input  wire [ 9:0]  a1,
+    input  wire [ 9:0]  b1,
+    output wire [18:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+endmodule
+
+module simd_mult_explicit_params (
+    input  wire         clk,
+
+    input  wire [ 9:0]  a0,
+    input  wire [ 9:0]  b0,
+    output wire [18:0]  z0,
+
+    input  wire [ 9:0]  a1,
+    input  wire [ 9:0]  b1,
+    output wire [18:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_0 (
+        .a_i    (a0),
+        .b_i    (b0),
+        .z_o    (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_1 (
+        .a_i    (a1),
+        .b_i    (b1),
+        .z_o    (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/Makefile b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/Makefile
new file mode 100644
index 000000000..9c08400c5
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/Makefile
@@ -0,0 +1,37 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTBENCH = dsp_simd_post_synth_sim_tb.v
+POST_SYNTH = simd_mult_post_synth simd_mult_explicit_ports_post_synth simd_mult_explicit_params_post_synth
+TOP = simd_mult simd_mult_explicit_ports simd_mult_explicit_params
+TOP_DEFINES = $(foreach top, $(TOP),-DTOP="$(top)")
+VCD_DEFINES = $(foreach vcd, $(POST_SYNTH),-DVCD="$(vcd).vcd")
+
+SIM_LIBS = $(shell find ../../../../qlf_k6n10f -name "*.v" -not -name "*_map.v")
+
+define simulate_post_synth
+	@iverilog  -vvvv -g2005 $(word $(1),$(TOP_DEFINES)) $(word $(1),$(VCD_DEFINES)) -o $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).v $(SIM_LIBS) $(TESTBENCH) > $(word $(1),$(POST_SYNTH)).vvp.log 2>&1
+	@vvp -vvvv $(word $(1),$(POST_SYNTH)).vvp > $(word $(1),$(POST_SYNTH)).vcd.log 2>&1
+endef
+
+define clean_post_synth_sim
+	@rm -rf  $(word $(1),$(POST_SYNTH)).vcd $(word $(1),$(POST_SYNTH)).vvp $(word $(1),$(POST_SYNTH)).vvp.log $(word $(1),$(POST_SYNTH)).vcd.log
+endef
+
+sim:
+	$(call simulate_post_synth,1)
+	$(call simulate_post_synth,2)
+	$(call simulate_post_synth,3)
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/dsp_simd_post_synth_sim_tb.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/dsp_simd_post_synth_sim_tb.v
new file mode 100644
index 000000000..e658988b0
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/dsp_simd_post_synth_sim/sim/dsp_simd_post_synth_sim_tb.v
@@ -0,0 +1,132 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+`define STRINGIFY(x) `"x`"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #1 clk <= ~clk;
+
+    // Data Clock
+    reg dclk;
+    initial dclk <= 1'b0;
+    always #2 dclk <= ~dclk;
+
+    // Input data / reference
+    reg [9:0] A0;
+    reg [9:0] A1;
+
+    reg [8:0] B0;
+    reg [8:0] B1;
+
+    reg [18:0] C0;
+    reg [18:0] C1;
+
+    always @(negedge dclk) begin
+        A0 = $random;
+        B0 = $random;
+
+        C0 <= A0 * B0;
+
+        A1 = $random;
+        B1 = $random;
+
+        C1 <= A1 * B1;
+    end
+
+    // UUT
+    wire [18:0] Z0;
+    wire [18:0] Z1;
+
+    case (`STRINGIFY(`TOP))
+        "simd_mult": begin
+            simd_mult dsp0 (
+                .clk(clk),
+                .a0(A0),
+                .a1(A1),
+                .b0(B0),
+                .b1(B1),
+                .z0(Z0),
+                .z1(Z1));
+        end
+        "simd_mult_explicit_ports": begin
+            simd_mult_explicit_ports dsp1 (
+                .clk(clk),
+                .a0(A0),
+                .a1(A1),
+                .b0(B0),
+                .b1(B1),
+                .z0(Z0),
+                .z1(Z1));
+        end
+        "simd_mult_explicit_params": begin
+            simd_mult_explicit_params dsp1 (
+                .clk(clk),
+                .a0(A0),
+                .a1(A1),
+                .b0(B0),
+                .b1(B1),
+                .z0(Z0),
+                .z1(Z1));
+        end
+    endcase
+
+    reg [18:0] C0_r;
+    reg [18:0] C1_r;
+
+    always @(posedge clk) begin
+        C0_r = C0;
+        C1_r = C1;
+    end
+
+    // Error detection
+    wire error0 = (Z0 !== C0_r) && (C0_r !== 19'bx);
+    wire error1 = (Z1 !== C1_r) && (C0_r !== 19'bx);
+
+    // Error counting
+    integer error_count = 0;
+
+    always @(posedge clk) begin
+        if (error0) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_0: FAIL: mismatch act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end else begin
+            $display("%d: DSP_0: OK: act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end
+    end
+
+    always @(posedge clk) begin
+        if (error1) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_1: FAIL: mismatch act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end else begin
+            $display("%d: DSP_1: OK: act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`STRINGIFY(`VCD));
+        $dumpvars;
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_params/sim_dsp_fir_cfg_params.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_params/sim_dsp_fir_cfg_params.v
new file mode 100644
index 000000000..1fb0e0402
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_params/sim_dsp_fir_cfg_params.v
@@ -0,0 +1,151 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #2  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Filter control
+    reg [2:0] fcnt;
+    reg [3:0] dcnt;
+
+    initial begin
+        fcnt <= 0;
+        dcnt <= 0;
+    end
+
+    // MAC cycle counter
+    always @(posedge clk)
+        if (rst) fcnt <= 0;
+        else begin
+            if (fcnt == 4)
+                fcnt <= 0;
+            else
+                fcnt <= fcnt + 1;
+        end
+
+    wire stb = (fcnt == 4);
+
+    // Data address counter
+    always @(posedge clk)
+        if (rst)      dcnt <= 0;
+        else if (stb) dcnt <= dcnt + 1;
+
+    // Filter coeffs (S0.19)
+    reg signed [19:0] coeff;
+    always @(*) case (fcnt)
+        2'd0: coeff <= 20'h0000B;
+        2'd1: coeff <= 20'h0000E;
+        2'd2: coeff <= 20'h0000E;
+        2'd3: coeff <= 20'h0000F;
+
+        default: coeff <= 20'h00000;
+    endcase
+
+    // Input data (S0.17)
+    reg signed [17:0] data;
+    always @(*) case (dcnt)
+        'd0:  data  <= 18'h00400;
+        'd1:  data  <= 18'h00000;
+        'd2:  data  <= 18'h00000;
+        'd3:  data  <= 18'h00000;
+        'd4:  data  <= 18'h00000;
+        'd5:  data  <= 18'h00000;
+        'd6:  data  <= 18'h00000;
+        'd7:  data  <= 18'h00000;
+        'd8:  data  <= 18'h00800;
+        default data <= 18'h00000;
+    endcase
+
+    // UUT
+    wire signed [5:0] acc_fir_i = 6'h0;
+    wire signed [19:0] A = coeff;
+    wire signed [17:0] B = data;
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_params # (
+        .SHIFT_RIGHT        (6'd10),
+        .REGISTER_INPUTS    (1'b0),
+        .OUTPUT_SELECT      (3'h1),
+        .ROUND              (1'b1),
+        .SATURATE_ENABLE    (1'b1)
+    ) uut (
+        .clock_i            (clk),
+        .s_reset            (rst),
+        .a_i                ((!stb) ? A : 20'h0),
+        .b_i                ((!stb) ? B : 18'h0),
+        .acc_fir_i          ((!stb) ? acc_fir_i : 4'h0),
+        .unsigned_a_i       (1'b0),
+        .unsigned_b_i       (1'b0),
+        .feedback_i         (stb),
+        .load_acc_i         (1'b1),
+        .subtract_i         (1'b0),
+        .z_o                (Z)
+    );
+
+    // Output counter
+    integer ocnt;
+    initial ocnt <= 0;
+
+    always @(posedge clk)
+        if (stb) ocnt <= ocnt + 1;
+
+    // Expected output data
+    reg signed [31:0] odata;
+    always @(*) case (ocnt)
+    'd0: odata <= 32'h000036;
+    'd1: odata <= 32'h000000;
+    'd2: odata <= 32'h000000;
+    'd3: odata <= 32'h000000;
+    'd4: odata <= 32'h000000;
+    'd5: odata <= 32'h000000;
+    'd6: odata <= 32'h000000;
+    'd7: odata <= 32'h000000;
+    'd8: odata <= 32'h00006C;
+    default: odata <= 32'h000000;
+    endcase
+
+    // Error detection
+    wire error = stb && (odata !== Z[31:0]);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #150 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_ports/sim_dsp_fir_cfg_ports.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_ports/sim_dsp_fir_cfg_ports.v
new file mode 100644
index 000000000..003d776bd
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_fir_cfg_ports/sim_dsp_fir_cfg_ports.v
@@ -0,0 +1,151 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #2  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Filter control
+    reg [2:0] fcnt;
+    reg [3:0] dcnt;
+
+    initial begin
+        fcnt <= 0;
+        dcnt <= 0;
+    end
+
+    // MAC cycle counter
+    always @(posedge clk)
+        if (rst) fcnt <= 0;
+        else begin
+            if (fcnt == 4)
+                fcnt <= 0;
+            else
+                fcnt <= fcnt + 1;
+        end
+
+    wire stb = (fcnt == 4);
+
+    // Data address counter
+    always @(posedge clk)
+        if (rst)      dcnt <= 0;
+        else if (stb) dcnt <= dcnt + 1;
+
+    // Filter coeffs (S0.19)
+    reg signed [19:0] coeff;
+    always @(*) case (fcnt)
+        2'd0: coeff <= 20'h0000B;
+        2'd1: coeff <= 20'h0000E;
+        2'd2: coeff <= 20'h0000E;
+        2'd3: coeff <= 20'h0000F;
+
+        default: coeff <= 20'h00000;
+    endcase
+
+    // Input data (S0.17)
+    reg signed [17:0] data;
+    always @(*) case (dcnt)
+        'd0:  data  <= 18'h00400;
+        'd1:  data  <= 18'h00000;
+        'd2:  data  <= 18'h00000;
+        'd3:  data  <= 18'h00000;
+        'd4:  data  <= 18'h00000;
+        'd5:  data  <= 18'h00000;
+        'd6:  data  <= 18'h00000;
+        'd7:  data  <= 18'h00000;
+        'd8:  data  <= 18'h00800;
+        default data <= 18'h00000;
+    endcase
+
+    // UUT
+    wire signed [5:0] acc_fir_i = 6'h0;
+    wire signed [19:0] A = coeff;
+    wire signed [17:0] B = data;
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_ports # (
+    ) uut (
+        .clock_i            (clk),
+        .s_reset            (rst),
+        .a_i                ((!stb) ? A : 20'h0),
+        .b_i                ((!stb) ? B : 18'h0),
+        .acc_fir_i          ((!stb) ? acc_fir_i : 4'h0),
+        .unsigned_a_i       (1'b0),
+        .unsigned_b_i       (1'b0),
+        .feedback_i         (stb),
+        .load_acc_i         (1'b1),
+        .shift_right_i      (6'd10),
+        .register_inputs_i  (1'b0),
+        .output_select_i    (3'h1),
+        .round_i            (1'b1),
+        .saturate_enable_i  (1'b1),
+        .subtract_i         (1'b0),
+        .z_o                (Z)
+    );
+
+    // Output counter
+    integer ocnt;
+    initial ocnt <= 0;
+
+    always @(posedge clk)
+        if (stb) ocnt <= ocnt + 1;
+
+    // Expected output data
+    reg signed [31:0] odata;
+    always @(*) case (ocnt)
+    'd0: odata <= 32'h000036;
+    'd1: odata <= 32'h000000;
+    'd2: odata <= 32'h000000;
+    'd3: odata <= 32'h000000;
+    'd4: odata <= 32'h000000;
+    'd5: odata <= 32'h000000;
+    'd6: odata <= 32'h000000;
+    'd7: odata <= 32'h000000;
+    'd8: odata <= 32'h00006C;
+    default: odata <= 32'h000000;
+    endcase
+
+    // Error detection
+    wire error = stb && (odata !== Z[31:0]);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #150 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_params/sim_dsp_mult_cfg_params.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_params/sim_dsp_mult_cfg_params.v
new file mode 100644
index 000000000..33419489d
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_params/sim_dsp_mult_cfg_params.v
@@ -0,0 +1,78 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #1  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Input data / reference
+    reg signed [19:0] A;
+    reg signed [17:0] B;
+    reg signed [37:0] C;
+
+    always @(posedge clk) begin
+        A = $random;
+        B = $random;
+
+        C <= A * B;
+    end
+
+    // UUT
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_params # (
+        .REGISTER_INPUTS    (1'h0),
+        .OUTPUT_SELECT      (3'h0)
+    ) uut (
+        .a_i                (A),
+        .b_i                (B),
+        .unsigned_a_i       (1'h0),
+        .unsigned_b_i       (1'h0),
+        .feedback_i         (3'h0),
+        .z_o                (Z)
+    );
+
+    // Error detection
+    wire error = (Z !== C);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_ports/sim_dsp_mult_cfg_ports.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_ports/sim_dsp_mult_cfg_ports.v
new file mode 100644
index 000000000..5f71bfdff
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_cfg_ports/sim_dsp_mult_cfg_ports.v
@@ -0,0 +1,77 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+`timescale 1ns/1ps
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #1  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Input data / reference
+    reg signed [19:0] A;
+    reg signed [17:0] B;
+    reg signed [37:0] C;
+
+    always @(posedge clk) begin
+        A = $random;
+        B = $random;
+
+        C <= A * B;
+    end
+
+    // UUT
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_ports uut (
+        .a_i                (A),
+        .b_i                (B),
+        .unsigned_a_i       (1'h0),
+        .unsigned_b_i       (1'h0),
+        .feedback_i         (3'h0),
+        .register_inputs_i  (1'h0),
+        .output_select_i    (3'h0),
+        .z_o                (Z)
+    );
+
+    // Error detection
+    wire error = (Z !== C);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_params/sim_dsp_mult_r_cfg_params.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_params/sim_dsp_mult_r_cfg_params.v
new file mode 100644
index 000000000..305b83a43
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_params/sim_dsp_mult_r_cfg_params.v
@@ -0,0 +1,89 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #1  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Input data / reference
+    reg signed [19:0] A;
+    reg signed [17:0] B;
+    reg signed [37:0] C;
+
+    // Shift data change half a clock cycle
+    // to make registered inputs apparent
+    initial begin
+        forever begin
+            A = $random;
+            B = $random;
+
+            C <= A * B;
+        #1.5;
+        end
+    end
+
+    // UUT
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_params # (
+        .REGISTER_INPUTS    (1'h1),
+        .OUTPUT_SELECT      (3'h0)
+    ) uut (
+        .a_i                (A),
+        .b_i                (B),
+        .unsigned_a_i       (1'h0),
+        .unsigned_b_i       (1'h0),
+        .feedback_i         (3'h0),
+        .clock_i            (clk),
+        .z_o                (Z)
+    );
+
+    // Error detection
+    reg [37:0] r_C;
+    initial r_C <= 0;
+    always @(posedge clk)
+        r_C <= C;
+
+    wire error = (Z !== r_C);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #100 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_ports/sim_dsp_mult_r_cfg_ports.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_ports/sim_dsp_mult_r_cfg_ports.v
new file mode 100644
index 000000000..261d2a349
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_mult_r_cfg_ports/sim_dsp_mult_r_cfg_ports.v
@@ -0,0 +1,88 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #0.5 clk <= ~clk;
+
+    // Reset
+    reg rst;
+    initial begin
+            rst <= 1'b0;
+        #1  rst <= 1'b1;
+        #2  rst <= 1'b0;
+    end
+
+    // Input data / reference
+    reg signed [19:0] A;
+    reg signed [17:0] B;
+    reg signed [37:0] C;
+
+    // Shift data change half a clock cycle
+    // to make registered inputs apparent
+    initial begin
+        forever begin
+            A = $random;
+            B = $random;
+
+            C <= A * B;
+        #1.5;
+        end
+    end
+
+    // UUT
+    wire signed [37:0] Z;
+
+    dsp_t1_sim_cfg_ports uut (
+        .a_i                (A),
+        .b_i                (B),
+        .unsigned_a_i       (1'h0),
+        .unsigned_b_i       (1'h0),
+        .feedback_i         (3'h0),
+        .register_inputs_i  (1'h1),
+        .output_select_i    (3'h0),
+        .clock_i            (clk),
+        .z_o                (Z)
+    );
+
+    // Error detection
+    reg [37:0] r_C;
+    initial r_C <= 0;
+    always @(posedge clk)
+        r_C <= C;
+
+    wire error = (Z !== r_C);
+
+    // Error counting
+    integer error_count;
+    initial error_count <= 0;
+    always @(posedge clk) begin
+        if (error) error_count <= error_count + 1;
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars(0, tb);
+        #100 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_params/sim_dsp_simd_cfg_params.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_params/sim_dsp_simd_cfg_params.v
new file mode 100644
index 000000000..50c21e8da
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_params/sim_dsp_simd_cfg_params.v
@@ -0,0 +1,164 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+`timescale 1ns/1ps
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #1 clk <= ~clk;
+
+    // Data Clock
+    reg dclk;
+    initial dclk <= 1'b0;
+    always #2 dclk <= ~dclk;
+
+    // Input data / reference
+    reg [9:0] A0;
+    reg [9:0] A1;
+
+    reg [8:0] B0;
+    reg [8:0] B1;
+
+    reg [18:0] C0;
+    reg [18:0] C1;
+
+    always @(negedge dclk) begin
+        A0 = $random;
+        B0 = $random;
+
+        C0 <= A0 * B0;
+
+        A1 = $random;
+        B1 = $random;
+
+        C1 <= A1 * B1;
+    end
+
+    // UUT
+    wire [18:0] Z0;
+    wire [18:0] Z1;
+
+    simd_mult_explicit_params dsp1 (
+        .clk(clk),
+        .a0(A0),
+        .a1(A1),
+        .b0(B0),
+        .b1(B1),
+        .z0(Z0),
+        .z1(Z1)
+    );
+
+    reg [18:0] C0_r;
+    reg [18:0] C1_r;
+
+    always @(posedge clk) begin
+        C0_r = C0;
+        C1_r = C1;
+    end
+
+    // Error detection
+    wire error0 = (Z0 !== C0_r) && (C0_r !== 19'bx);
+    wire error1 = (Z1 !== C1_r) && (C0_r !== 19'bx);
+
+    // Error counting
+    integer error_count = 0;
+
+    always @(posedge clk) begin
+        if (error0) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_0: FAIL: mismatch act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end else begin
+            $display("%d: DSP_0: OK: act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end
+    end
+
+    always @(posedge clk) begin
+        if (error1) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_1: FAIL: mismatch act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end else begin
+            $display("%d: DSP_1: OK: act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars;
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
+
+module simd_mult_explicit_params (
+    input  wire         clk,
+
+    input  wire [ 9:0]  a0,
+    input  wire [ 8:0]  b0,
+    output wire [18:0]  z0,
+
+    input  wire [ 9:0]  a1,
+    input  wire [ 8:0]  b1,
+    output wire [18:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_0 (
+        .a_i                (a0),
+        .b_i                (b0),
+        .z_o                (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+    dsp_t1_10x9x32_cfg_params #(
+        .OUTPUT_SELECT      (3'd0),
+        .SATURATE_ENABLE    (1'b0),
+        .SHIFT_RIGHT        (6'd0),
+        .ROUND              (1'b0),
+        .REGISTER_INPUTS    (1'b1)
+    ) dsp_1 (
+        .a_i                (a1),
+        .b_i                (b1),
+        .z_o                (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .subtract_i         (1'b0)
+    );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_ports/sim_dsp_simd_cfg_ports.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_ports/sim_dsp_simd_cfg_ports.v
new file mode 100644
index 000000000..021792c72
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_dsp_simd_cfg_ports/sim_dsp_simd_cfg_ports.v
@@ -0,0 +1,162 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "qlf_k6n10f/cells_sim.v"
+`timescale 1ns/1ps
+
+module tb();
+
+    // Clock
+    reg clk;
+    initial clk <= 1'b0;
+    always #1 clk <= ~clk;
+
+    // Data Clock
+    reg dclk;
+    initial dclk <= 1'b0;
+    always #2 dclk <= ~dclk;
+
+    // Input data / reference
+    reg [9:0] A0;
+    reg [9:0] A1;
+
+    reg [8:0] B0;
+    reg [8:0] B1;
+
+    reg [18:0] C0;
+    reg [18:0] C1;
+
+    always @(negedge dclk) begin
+        A0 = $random;
+        B0 = $random;
+
+        C0 <= A0 * B0;
+
+        A1 = $random;
+        B1 = $random;
+
+        C1 <= A1 * B1;
+    end
+
+    // UUT
+    wire [18:0] Z0;
+    wire [18:0] Z1;
+
+    simd_mult_explicit_ports dsp1 (
+        .clk(clk),
+        .a0(A0),
+        .a1(A1),
+        .b0(B0),
+        .b1(B1),
+        .z0(Z0),
+        .z1(Z1)
+    );
+
+    reg [18:0] C0_r;
+    reg [18:0] C1_r;
+
+    always @(posedge clk) begin
+        C0_r = C0;
+        C1_r = C1;
+    end
+
+    // Error detection
+    wire error0 = (Z0 !== C0_r) && (C0_r !== 19'bx);
+    wire error1 = (Z1 !== C1_r) && (C0_r !== 19'bx);
+
+    // Error counting
+    integer error_count = 0;
+
+    always @(posedge clk) begin
+        if (error0) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_0: FAIL: mismatch act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end else begin
+            $display("%d: DSP_0: OK: act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
+        end
+    end
+
+    always @(posedge clk) begin
+        if (error1) begin
+            error_count <= error_count + 1'b1;
+            $display("%d: DSP_1: FAIL: mismatch act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end else begin
+            $display("%d: DSP_1: OK: act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
+        end
+    end
+
+    // Simulation control / data dump
+    initial begin
+        $dumpfile(`VCD_FILE);
+        $dumpvars;
+        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
+    end
+
+endmodule
+
+module simd_mult_explicit_ports (
+    input  wire         clk,
+
+    input  wire [ 9:0]  a0,
+    input  wire [ 8:0]  b0,
+    output wire [18:0]  z0,
+
+    input  wire [ 9:0]  a1,
+    input  wire [ 8:0]  b1,
+    output wire [18:0]  z1
+);
+
+    dsp_t1_10x9x32_cfg_ports dsp_0 (
+        .a_i                (a0),
+        .b_i                (b0),
+        .z_o                (z0),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+    dsp_t1_10x9x32_cfg_ports dsp_1 (
+        .a_i                (a1),
+        .b_i                (b1),
+        .z_o                (z1),
+
+        .clock_i            (clk),
+
+        .feedback_i         (3'd0),
+        .load_acc_i         (1'b0),
+        .unsigned_a_i       (1'b1),
+        .unsigned_b_i       (1'b1),
+
+        .output_select_i    (3'd0),
+        .saturate_enable_i  (1'b0),
+        .shift_right_i      (6'd0),
+        .round_i            (1'b0),
+        .subtract_i         (1'b0),
+        .register_inputs_i  (1'b1)
+    );
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_tc36fifo/sim_tc36fifo.v b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_tc36fifo/sim_tc36fifo.v
new file mode 100644
index 000000000..105967b99
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/qlf_k6n10f/sim_tc36fifo/sim_tc36fifo.v
@@ -0,0 +1,2355 @@
+// Copyright (C) 2022  The SymbiFlow Authors.
+//
+// Use of this source code is governed by a ISC-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/ISC
+//
+// SPDX-License-Identifier:ISC
+
+`include "qlf_k6n10f/cells_sim.v"
+`timescale 1ns/1ps
+
+module tb;
+	localparam [11:0] UPAE1 = 10;
+	localparam [11:0] UPAF1 = 10;
+	localparam [10:0] UPAE2 = 10;
+	localparam [10:0] UPAF2 = 10;
+	localparam [0:0] SPLIT = 0;
+	localparam [0:0] SYNC_FIFO1 = 0;
+	localparam [0:0] SYNC_FIFO2 = 0;
+	localparam [0:0] FMODE1 = 1;
+	localparam [0:0] POWERDN1 = 0;
+	localparam [0:0] SLEEP1 = 0;
+	localparam [0:0] PROTECT1 = 0;
+	localparam [0:0] FMODE2 = 0;
+	localparam [0:0] POWERDN2 = 0;
+	localparam [0:0] SLEEP2 = 0;
+	localparam [0:0] PROTECT2 = 0;
+	localparam [2:0] RMODE_A1 = MODE_36;
+	localparam [2:0] RMODE_B1 = MODE_36;
+	localparam [2:0] WMODE_A1 = MODE_36;
+	localparam [2:0] WMODE_B1 = MODE_36;
+	localparam [2:0] RMODE_A2 = MODE_36;
+	localparam [2:0] RMODE_B2 = MODE_36;
+	localparam [2:0] WMODE_A2 = MODE_36;
+	localparam [2:0] WMODE_B2 = MODE_36;
+
+	localparam W_PERIOD = 30;
+	localparam R_PERIOD = 29;
+	reg WEN_A1;
+	reg WEN_B1;
+	reg REN_A1;
+	reg REN_B1;
+	reg CLK_A1;
+	reg CLK_B1;
+	reg [1:0] BE_A1;
+	reg [1:0] BE_B1;
+	reg [14:0] ADDR_A1;
+	reg [14:0] ADDR_B1;
+	reg [17:0] WDATA_A1;
+	reg [17:0] WDATA_B1;
+	wire [17:0] RDATA_A1;
+	wire [17:0] RDATA_B1;
+	wire UNDERRUN1;
+	wire OVERRUN1;
+	wire UNDERRUN2;
+	wire OVERRUN2;
+	wire EMPTY1;
+	wire EPO1;
+	wire EWM1;
+	wire FULL1;
+	wire FMO1;
+	wire FWM1;
+	reg FLUSH1;
+	reg WEN_A2;
+	reg WEN_B2;
+	reg REN_A2;
+	reg REN_B2;
+	reg CLK_A2;
+	reg CLK_B2;
+	reg [1:0] BE_A2;
+	reg [1:0] BE_B2;
+	wire [13:0] ADDR_A2;
+	wire [13:0] ADDR_B2;
+	reg [17:0] WDATA_A2;
+	reg [17:0] WDATA_B2;
+	wire [17:0] RDATA_A2;
+	wire [17:0] RDATA_B2;
+	wire EMPTY2;
+	wire EPO2;
+	wire EWM2;
+	wire FULL2;
+	wire FMO2;
+	wire FWM2;
+	reg FLUSH2;
+	wire [17:0] RDATA_A18;
+	wire [17:0] RDATA_B18;
+	wire [8:0] RDATA_A9;
+	wire [8:0] RDATA_B9;
+	wire [35:0] expected_data_a;
+	wire [35:0] expected_data_b;
+	wire [35:0] last_expected_a;
+	wire [35:0] last_expected_b;
+	wire [17:0] last_expected_a18;
+	wire [17:0] last_expected_b18;
+	wire [8:0] last_expected_a9;
+	wire [8:0] last_expected_b9;
+	wire [14:0] last_addr_a;
+	wire [14:0] last_addr_b;
+	wire valid_a;
+	wire valid_b;
+	wire [3:0] index4_a;
+	wire [3:0] index4_b;
+	wire [1:0] index2_a;
+	wire [1:0] index2_b;
+	wire index_a;
+	wire index_b;
+	reg last_empty1;
+	wire last_empty2;
+	wire [35:0] fifo_dout;
+	wire [35:0] fifo_din;
+	localparam MODE_36 = 3'b011;
+	task fA_36x36;
+		begin
+			$display("%d: Fifo 36-bit write 36-bit read", $time);
+			FLUSH1 = 1;
+			@(posedge CLK_A1);
+			@(posedge CLK_B1);
+			FLUSH1 = 0;
+		end
+	endtask
+	task fA_push36;
+		input [35:0] data;
+		begin
+			@(negedge CLK_A1) begin
+				WDATA_A2 = data[35:18];
+				WDATA_A1 = data[17:0];
+				WEN_A1 = 1;
+			end
+			@(posedge CLK_A1)
+				#(2) WEN_A1 = 0;
+		end
+	endtask
+	task fA_pop;
+		input [35:0] expected;
+		input [35:0] msk;
+		begin
+			if (last_empty1 || EMPTY1)
+				while (EMPTY1 == 1) begin
+					@(posedge CLK_B1);
+				end
+			if (({RDATA_B2, RDATA_B1} & msk) !== expected) begin
+				$display("%d: POP FIFO ERROR: mismatch: expected = %9x mask = %5x, actuall = %9x", $time, expected, msk, {RDATA_B2, RDATA_B1});
+				error_cnt = error_cnt + 1'b1;
+			end
+			@(negedge CLK_B1) REN_B1 = 1;
+			@(posedge CLK_B1)
+				#(2) REN_B1 = 0;
+		end
+	endtask
+	integer wcount_a;
+	integer rcount_a;
+	integer state_a;
+	integer wcount_b;
+	integer rcount_b;
+	integer state_b;
+	integer error_cnt = 0;
+	initial CLK_A1 = 0;
+	initial CLK_B1 = 0;
+	initial CLK_A2 = 0;
+	initial CLK_B2 = 0;
+	initial forever #(R_PERIOD) CLK_A1 = ~CLK_A1;
+	initial forever #(W_PERIOD) CLK_B1 = ~CLK_B1;
+	initial forever #(R_PERIOD) CLK_A2 = ~CLK_A2;
+	initial forever #(W_PERIOD) CLK_B2 = ~CLK_B2;
+	initial begin
+		$dumpfile(`VCD_FILE);
+		$dumpvars(0, tb);
+	end
+	initial #(1) begin
+		WEN_A1 = 0;
+		REN_A1 = 0;
+		WEN_B1 = 0;
+		REN_B1 = 0;
+		BE_A1 = 2'b11;
+		BE_A2 = 2'b11;
+		BE_B1 = 2'b11;
+		BE_B2 = 2'b11;
+		ADDR_A1 = 14'b00000000000000;
+		ADDR_B1 = 14'b00000000000000;
+		WDATA_A1 = 18'b000000000000000000;
+		WDATA_B1 = 18'h00000;
+		wcount_a = 0;
+		rcount_a = 0;
+		state_a = 0;
+		wcount_b = 0;
+		rcount_b = 0;
+		state_b = 0;
+		WEN_A2 = 0;
+		REN_A2 = 0;
+		WEN_B2 = 0;
+		REN_B2 = 0;
+		FLUSH1 = 0;
+		FLUSH2 = 0;
+	end
+	initial begin
+		#(100)
+		@(posedge CLK_A1);
+		@(posedge CLK_B1);
+	end
+	assign fifo_dout = {RDATA_B2, RDATA_B1};
+	assign fifo_din = {WDATA_A2, WDATA_A1};
+	assign {EMPTY1, EPO1, EWM1, UNDERRUN1, FULL1, FMO1, FWM1, OVERRUN1} = RDATA_A1[7:0];
+	assign {EMPTY2, EPO2, EWM2, UNDERRUN2, FULL2, FMO2, FWM2, OVERRUN2} = RDATA_A2[7:0];
+	always @(posedge CLK_B1) last_empty1 <= EMPTY1;
+	always @(*)
+		case (state_a)
+			0: begin
+				fA_36x36;
+				if (!EMPTY1) begin
+					$display("%d: FIFO ERROR: EMPTY flag not set", $time);
+					error_cnt = error_cnt + 1'b1;
+				end
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				if (!EMPTY1) begin
+					$display("%d: FIFO ERROR: EMPTY flag not set", $time);
+					error_cnt = error_cnt + 1'b1;
+				end
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				if (!EMPTY1) begin
+					$display("%d: FIFO ERROR: EMPTY flag not set", $time);
+					error_cnt = error_cnt + 1'b1;
+				end
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				fA_push36(36'h0a5a5a5a5);
+				fA_push36(36'h05a5a5a5a);
+				if (!FULL1) begin
+					$display("%d: FIFO ERROR: FULL flag not set", $time);
+					error_cnt = error_cnt + 1'b1;
+				end
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				fA_pop(36'h0a5a5a5a5, {36 {1'b1}});
+				fA_pop(36'h05a5a5a5a, {36 {1'b1}});
+				if (!EMPTY1) begin
+					$display("%d: FIFO ERROR: EMPTY flag not set", $time);
+					error_cnt = error_cnt + 1'b1;
+				end
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				@(posedge CLK_A1);
+				@(posedge CLK_B1);
+				$finish_and_return( (error_cnt == 0) ? 0 : -1 );
+			end
+		endcase
+
+	TDP36K #(
+		.MODE_BITS({SPLIT, UPAF2, UPAE2, PROTECT2, SLEEP2, POWERDN2, FMODE2, WMODE_B2, WMODE_A2, RMODE_B2, RMODE_A2, SYNC_FIFO2, UPAF1, UPAE1, PROTECT1, SLEEP1, POWERDN1, FMODE1, WMODE_B1, WMODE_A1, RMODE_B1, RMODE_A1, SYNC_FIFO1})
+	)tdp36_1(
+		.CLK_A1_i(CLK_A1),
+		.CLK_B1_i(CLK_B1),
+		.WEN_A1_i(WEN_A1),
+		.WEN_B1_i(WEN_B1),
+		.REN_A1_i(REN_A1),
+		.REN_B1_i(REN_B1),
+		.BE_A1_i(BE_A1),
+		.BE_B1_i(BE_B1),
+		.ADDR_A1_i(ADDR_A1),
+		.ADDR_B1_i(ADDR_B1),
+		.WDATA_A1_i(WDATA_A1),
+		.WDATA_B1_i(WDATA_B1),
+		.RDATA_A1_o(RDATA_A1),
+		.RDATA_B1_o(RDATA_B1),
+		.FLUSH1_i(FLUSH1),
+		.CLK_A2_i(CLK_A2),
+		.CLK_B2_i(CLK_B2),
+		.WEN_A2_i(WEN_A2),
+		.WEN_B2_i(WEN_B2),
+		.REN_A2_i(REN_A2),
+		.REN_B2_i(REN_B2),
+		.BE_A2_i(BE_A2),
+		.BE_B2_i(BE_B2),
+		.ADDR_A2_i(ADDR_A2),
+		.ADDR_B2_i(ADDR_B2),
+		.WDATA_A2_i(WDATA_A2),
+		.WDATA_B2_i(WDATA_B2),
+		.RDATA_A2_o(RDATA_A2),
+		.RDATA_B2_o(RDATA_B2),
+		.FLUSH2_i(FLUSH2)
+	);
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/shreg/shreg.tcl b/yosys-plugins/ql-qlf/tests/shreg/shreg.tcl
new file mode 100644
index 000000000..fe4b6333d
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/shreg/shreg.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+synth_quicklogic -family qlf_k4n8 -top top
+stat
+select -assert-count 8 t:sh_dff
+
+design -reset
+
+read_verilog $::env(DESIGN_TOP).v
+synth_quicklogic -family qlf_k6n10f -top top
+stat
+select -assert-count 8 t:sh_dff
+
diff --git a/yosys-plugins/ql-qlf/tests/shreg/shreg.v b/yosys-plugins/ql-qlf/tests/shreg/shreg.v
new file mode 100644
index 000000000..7e8f47101
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/shreg/shreg.v
@@ -0,0 +1,29 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input  wire I,
+    input  wire C,
+    output wire O
+);
+
+  reg [7:0] shift_register;
+
+  always @(posedge C) shift_register <= {shift_register[6:0], I};
+
+  assign O = shift_register[7];
+
+endmodule
diff --git a/yosys-plugins/ql-qlf/tests/tribuf/tribuf.tcl b/yosys-plugins/ql-qlf/tests/tribuf/tribuf.tcl
new file mode 100644
index 000000000..0d759b5c0
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/tribuf/tribuf.tcl
@@ -0,0 +1,19 @@
+yosys -import
+if { [info procs quicklogic_eqn] == {} } { plugin -i ql-qlf }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+hierarchy -top tristate
+yosys proc
+tribuf
+flatten
+synth
+equiv_opt -assert -map +/quicklogic/pp3/cells_sim.v -map +/simcells.v synth_quicklogic -family pp3
+design -load postopt
+yosys cd tristate
+select -assert-count 2 t:inpad
+select -assert-count 1 t:outpad
+select -assert-count 1 t:\$_TBUF_
+select -assert-none t:inpad t:outpad t:\$_TBUF_ %% t:* %D
+
diff --git a/yosys-plugins/ql-qlf/tests/tribuf/tribuf.v b/yosys-plugins/ql-qlf/tests/tribuf/tribuf.v
new file mode 100644
index 000000000..b94b10326
--- /dev/null
+++ b/yosys-plugins/ql-qlf/tests/tribuf/tribuf.v
@@ -0,0 +1,28 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module tristate (
+    en,
+    i,
+    o
+);
+  input en;
+  input i;
+  output reg o;
+
+  always @(en or i) o <= (en) ? i : 1'bZ;
+endmodule
+
diff --git a/yosys-plugins/requirements.txt b/yosys-plugins/requirements.txt
new file mode 100644
index 000000000..ba26f044d
--- /dev/null
+++ b/yosys-plugins/requirements.txt
@@ -0,0 +1 @@
+# make-env needs a requirements.txt file, even though it's empty
diff --git a/yosys-plugins/sdc/Makefile b/yosys-plugins/sdc/Makefile
new file mode 100644
index 000000000..3ae63e07b
--- /dev/null
+++ b/yosys-plugins/sdc/Makefile
@@ -0,0 +1,26 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = sdc
+SOURCES = buffers.cc \
+          clocks.cc \
+          propagation.cc \
+          sdc.cc \
+          sdc_writer.cc \
+          set_false_path.cc \
+          set_max_delay.cc \
+          set_clock_groups.cc
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/sdc/buffers.cc b/yosys-plugins/sdc/buffers.cc
new file mode 100644
index 000000000..9c2308a4b
--- /dev/null
+++ b/yosys-plugins/sdc/buffers.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "buffers.h"
+#include <cassert>
+#include <cmath>
+
+const std::vector<std::string> Pll::inputs = {"CLKIN1", "CLKIN2"};
+const std::vector<std::string> Pll::outputs = {"CLKOUT0", "CLKOUT1", "CLKOUT2", "CLKOUT3", "CLKOUT4", "CLKOUT5"};
+const float Pll::delay = 0;
+const std::string Pll::name = "PLLE2_ADV";
+
+Pll::Pll(RTLIL::Cell *cell, float input_clock_period, float input_clock_rising_edge) : ClockDivider({"PLLE2_ADV"})
+{
+    assert(RTLIL::unescape_id(cell->type) == "PLLE2_ADV");
+    FetchParams(cell);
+    CheckInputClockPeriod(cell, input_clock_period);
+    CalculateOutputClockPeriods();
+    CalculateOutputClockWaveforms(input_clock_rising_edge);
+}
+
+void Pll::CheckInputClockPeriod(RTLIL::Cell *cell, float input_clock_period)
+{
+    float abs_diff = fabs(ClkinPeriod() - input_clock_period);
+    bool approx_equal = abs_diff < std::max(ClkinPeriod(), input_clock_period) * 10 * std::numeric_limits<float>::epsilon();
+    if (!approx_equal) {
+        log_cmd_error("CLKIN[1/2]_PERIOD doesn't match the virtual clock constraint "
+                      "propagated to the CLKIN[1/2] input of the clock divider cell: "
+                      "%s.\nInput clock period: %f, CLKIN[1/2]_PERIOD: %f\n",
+                      RTLIL::id2cstr(cell->name), input_clock_period, ClkinPeriod());
+    }
+}
+
+void Pll::FetchParams(RTLIL::Cell *cell)
+{
+    clkin1_period = FetchParam(cell, "CLKIN1_PERIOD", 0.0);
+    clkin2_period = FetchParam(cell, "CLKIN2_PERIOD", 0.0);
+    clk_mult = FetchParam(cell, "CLKFBOUT_MULT", 5.0);
+    clk_fbout_phase = FetchParam(cell, "CLKFBOUT_PHASE", 0.0);
+    divclk_divisor = FetchParam(cell, "DIVCLK_DIVIDE", 1.0);
+    for (auto output : outputs) {
+        // CLKOUT[0-5]_DUTY_CYCLE
+        clkout_duty_cycle[output] = FetchParam(cell, output + "_DUTY_CYCLE", 0.5);
+        // CLKOUT[0-5]_DIVIDE
+        clkout_divisor[output] = FetchParam(cell, output + "_DIVIDE", 1.0);
+        // CLKOUT[0-5]_PHASE
+        clkout_phase[output] = FetchParam(cell, output + "_PHASE", 0.0);
+    }
+}
+
+void Pll::CalculateOutputClockPeriods()
+{
+    for (auto output : outputs) {
+        // CLKOUT[0-5]_PERIOD = CLKIN1_PERIOD * CLKOUT[0-5]_DIVIDE *
+        // DIVCLK_DIVIDE / CLKFBOUT_MULT
+        clkout_period[output] = ClkinPeriod() * clkout_divisor.at(output) / clk_mult * divclk_divisor;
+    }
+}
+
+void Pll::CalculateOutputClockWaveforms(float input_clock_rising_edge)
+{
+    for (auto output : outputs) {
+        float output_clock_period = clkout_period.at(output);
+        clkout_rising_edge[output] =
+          fmod(input_clock_rising_edge - (clk_fbout_phase / 360.0) * ClkinPeriod() + output_clock_period * (clkout_phase[output] / 360.0),
+               output_clock_period);
+        clkout_falling_edge[output] = fmod(clkout_rising_edge[output] + clkout_duty_cycle[output] * output_clock_period, output_clock_period);
+    }
+}
+
+float Pll::FetchParam(RTLIL::Cell *cell, std::string &&param_name, float default_value)
+{
+    RTLIL::IdString param(RTLIL::escape_id(param_name));
+    if (cell->hasParam(param)) {
+        auto param_obj = cell->parameters.at(param);
+        std::string value;
+        if (param_obj.flags & RTLIL::CONST_FLAG_STRING) {
+            value = param_obj.decode_string();
+        } else {
+            value = std::to_string(param_obj.as_int());
+        }
+        return std::stof(value);
+    }
+    return default_value;
+}
diff --git a/yosys-plugins/sdc/buffers.h b/yosys-plugins/sdc/buffers.h
new file mode 100644
index 000000000..1665b4d3e
--- /dev/null
+++ b/yosys-plugins/sdc/buffers.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _BUFFERS_H_
+#define _BUFFERS_H_
+
+#include "kernel/rtlil.h"
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+USING_YOSYS_NAMESPACE
+
+struct Buffer {
+    Buffer(float delay, const std::string &type, const std::string &output) : delay(delay), type(type), output(output) {}
+    float delay;
+    std::string type;
+    std::string output;
+};
+
+struct IBuf : Buffer {
+    IBuf() : Buffer(0, "IBUF", "O"){};
+};
+
+struct Bufg : Buffer {
+    Bufg() : Buffer(0, "BUFG", "O"){};
+};
+
+struct ClockDivider {
+    std::string type;
+};
+
+struct Pll : public ClockDivider {
+    Pll() : ClockDivider({"PLLE2_ADV"}) {}
+    Pll(RTLIL::Cell *cell, float input_clock_period, float input_clock_rising_edge);
+
+    // Helper function to fetch a cell parameter or return a default value
+    static float FetchParam(RTLIL::Cell *cell, std::string &&param_name, float default_value);
+
+    // Get the period of the input clock
+    // TODO Add support for CLKINSEL
+    float ClkinPeriod() { return clkin1_period; }
+
+    static const std::vector<std::string> inputs;
+    static const std::vector<std::string> outputs;
+    std::unordered_map<std::string, float> clkout_period;
+    std::unordered_map<std::string, float> clkout_duty_cycle;
+    std::unordered_map<std::string, float> clkout_rising_edge;
+    std::unordered_map<std::string, float> clkout_falling_edge;
+
+  private:
+    // Approximate equality check of the input clock period and specified in
+    // CLKIN[1/2]_PERIOD parameter
+    void CheckInputClockPeriod(RTLIL::Cell *cell, float input_clock_period);
+
+    // Fetch cell's parameters needed for further calculations
+    void FetchParams(RTLIL::Cell *cell);
+
+    // Calculate the period on the output clocks
+    void CalculateOutputClockPeriods();
+
+    // Calculate the rising and falling edges of the output clocks
+    void CalculateOutputClockWaveforms(float input_clock_rising_edge);
+
+    static const float delay;
+    static const std::string name;
+    std::unordered_map<std::string, float> clkout_divisor;
+    std::unordered_map<std::string, float> clkout_phase;
+    float clkin1_period;
+    float clkin2_period;
+    float divclk_divisor;
+    float clk_mult;
+    float clk_fbout_phase;
+};
+
+#endif // _BUFFERS_H_
diff --git a/yosys-plugins/sdc/clocks.cc b/yosys-plugins/sdc/clocks.cc
new file mode 100644
index 000000000..a1c4a7a78
--- /dev/null
+++ b/yosys-plugins/sdc/clocks.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "clocks.h"
+#include "kernel/register.h"
+#include "propagation.h"
+#include <cassert>
+#include <cmath>
+#include <regex>
+
+void Clock::Add(const std::string &name, RTLIL::Wire *wire, float period, float rising_edge, float falling_edge, ClockType type)
+{
+    wire->set_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL"), "yes");
+    wire->set_bool_attribute(RTLIL::escape_id("IS_GENERATED"), type == GENERATED);
+    wire->set_bool_attribute(RTLIL::escape_id("IS_EXPLICIT"), type == EXPLICIT);
+    wire->set_bool_attribute(RTLIL::escape_id("IS_PROPAGATED"), type == PROPAGATED);
+    wire->set_string_attribute(RTLIL::escape_id("CLASS"), "clock");
+    wire->set_string_attribute(RTLIL::escape_id("NAME"), name);
+    wire->set_string_attribute(RTLIL::escape_id("SOURCE_WIRES"), Clock::WireName(wire));
+    wire->set_string_attribute(RTLIL::escape_id("PERIOD"), std::to_string(period));
+    std::string waveform(std::to_string(rising_edge) + " " + std::to_string(falling_edge));
+    wire->set_string_attribute(RTLIL::escape_id("WAVEFORM"), waveform);
+}
+
+void Clock::Add(const std::string &name, std::vector<RTLIL::Wire *> wires, float period, float rising_edge, float falling_edge, ClockType type)
+{
+    std::for_each(wires.begin(), wires.end(), [&](RTLIL::Wire *wire) { Add(name, wire, period, rising_edge, falling_edge, type); });
+}
+
+void Clock::Add(RTLIL::Wire *wire, float period, float rising_edge, float falling_edge, ClockType type)
+{
+    Add(Clock::WireName(wire), wire, period, rising_edge, falling_edge, type);
+}
+
+float Clock::Period(RTLIL::Wire *clock_wire)
+{
+    if (!clock_wire->has_attribute(RTLIL::escape_id("PERIOD"))) {
+        log_cmd_error("PERIOD has not been specified on wire '%s'.\n", WireName(clock_wire).c_str());
+    }
+    float period(0);
+    std::string period_str;
+    try {
+        period_str = clock_wire->get_string_attribute(RTLIL::escape_id("PERIOD"));
+        period = std::stof(period_str);
+    } catch (const std::invalid_argument &e) {
+        log_cmd_error("Incorrect value '%s' specifed on PERIOD attribute for wire "
+                      "'%s'.\nPERIOD needs to be a float value.\n",
+                      period_str.c_str(), WireName(clock_wire).c_str());
+    }
+    return period;
+}
+
+std::pair<float, float> Clock::Waveform(RTLIL::Wire *clock_wire)
+{
+    if (!clock_wire->has_attribute(RTLIL::escape_id("WAVEFORM"))) {
+        float period(Period(clock_wire));
+        if (!period) {
+            log_cmd_error("Neither PERIOD nor WAVEFORM has been specified for wire %s\n", WireName(clock_wire).c_str());
+            return std::make_pair(0, 0);
+        }
+        float falling_edge = period / 2;
+        log_warning("Waveform has not been specified on wire '%s'.\nDefault value {0 %f} "
+                    "will be used\n",
+                    WireName(clock_wire).c_str(), falling_edge);
+        return std::make_pair(0, falling_edge);
+    }
+    float rising_edge(0);
+    float falling_edge(0);
+    std::string waveform(clock_wire->get_string_attribute(RTLIL::escape_id("WAVEFORM")));
+    if (std::sscanf(waveform.c_str(), "%f %f", &rising_edge, &falling_edge) != 2) {
+        log_cmd_error("Incorrect value '%s' specifed on WAVEFORM attribute for wire "
+                      "'%s'.\nWAVEFORM needs to be specified in form of '<rising_edge> "
+                      "<falling_edge>' where the edge values are floats.\n",
+                      waveform.c_str(), WireName(clock_wire).c_str());
+    }
+    return std::make_pair(rising_edge, falling_edge);
+}
+
+float Clock::RisingEdge(RTLIL::Wire *clock_wire) { return Waveform(clock_wire).first; }
+
+float Clock::FallingEdge(RTLIL::Wire *clock_wire) { return Waveform(clock_wire).second; }
+
+std::string Clock::Name(RTLIL::Wire *clock_wire)
+{
+    if (clock_wire->has_attribute(RTLIL::escape_id("NAME"))) {
+        return clock_wire->get_string_attribute(RTLIL::escape_id("NAME"));
+    }
+    return WireName(clock_wire);
+}
+
+std::string Clock::WireName(RTLIL::Wire *clock_wire)
+{
+    if (!clock_wire) {
+        return std::string();
+    }
+    return AddEscaping(RTLIL::unescape_id(clock_wire->name));
+}
+
+std::string Clock::SourceWireName(RTLIL::Wire *clock_wire)
+{
+    if (clock_wire->has_attribute(RTLIL::escape_id("SOURCE_WIRES"))) {
+        return clock_wire->get_string_attribute(RTLIL::escape_id("SOURCE_WIRES"));
+    }
+    return Name(clock_wire);
+}
+
+bool Clock::GetClockWireBoolAttribute(RTLIL::Wire *wire, const std::string &attribute_name)
+{
+    if (wire->has_attribute(RTLIL::escape_id(attribute_name))) {
+        return wire->get_bool_attribute(RTLIL::escape_id(attribute_name));
+    }
+    return false;
+}
+
+const std::map<std::string, RTLIL::Wire *> Clocks::GetClocks(RTLIL::Design *design)
+{
+    std::map<std::string, RTLIL::Wire *> clock_wires;
+    RTLIL::Module *top_module = design->top_module();
+    for (auto &wire_obj : top_module->wires_) {
+        auto &wire = wire_obj.second;
+        if (wire->has_attribute(RTLIL::escape_id("CLOCK_SIGNAL"))) {
+            if (wire->get_string_attribute(RTLIL::escape_id("CLOCK_SIGNAL")) == "yes") {
+                clock_wires.insert(std::make_pair(Clock::WireName(wire), wire));
+            }
+        }
+    }
+    return clock_wires;
+}
+
+void Clocks::UpdateAbc9DelayTarget(RTLIL::Design *design)
+{
+    std::map<std::string, RTLIL::Wire *> clock_wires = Clocks::GetClocks(design);
+
+    for (auto &clock_wire : clock_wires) {
+        auto &wire = clock_wire.second;
+        float period = Clock::Period(wire);
+
+        // Set the ABC9 delay to the shortest clock period in the design.
+        //
+        // By convention, delays in Yosys are in picoseconds, but ABC9 has
+        // no information on interconnect delay, so target half the specified
+        // clock period to give timing slack; otherwise ABC9 may produce a
+        // mapping that cannot meet the specified clock.
+        int abc9_delay = design->scratchpad_get_int("abc9.D", INT32_MAX);
+        int period_ps = period * 1000.0 / 2.0;
+        design->scratchpad_set_int("abc9.D", std::min(abc9_delay, period_ps));
+    }
+}
diff --git a/yosys-plugins/sdc/clocks.h b/yosys-plugins/sdc/clocks.h
new file mode 100644
index 000000000..47fc5dfc9
--- /dev/null
+++ b/yosys-plugins/sdc/clocks.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _CLOCKS_H_
+#define _CLOCKS_H_
+
+#include "buffers.h"
+#include "kernel/rtlil.h"
+#include <map>
+#include <vector>
+
+USING_YOSYS_NAMESPACE
+
+class NaturalPropagation;
+class BufferPropagation;
+class ClockDividerPropagation;
+class Propagation;
+
+class Clock
+{
+  public:
+    // We distinguish the following types of clock:
+    // * EXPLICIT - added with create_clocks command
+    // * GENERATED - propagated from explicit clocks changing the clock's parameters
+    // * PROPAGATED - propagated from explicit clocks but with the same parameters as the driver
+    enum ClockType { EXPLICIT, GENERATED, PROPAGATED };
+    static void Add(const std::string &name, RTLIL::Wire *wire, float period, float rising_edge, float falling_edge, ClockType type);
+    static void Add(const std::string &name, std::vector<RTLIL::Wire *> wires, float period, float rising_edge, float falling_edge, ClockType type);
+    static void Add(RTLIL::Wire *wire, float period, float rising_edge, float falling_edge, ClockType type);
+    static float Period(RTLIL::Wire *clock_wire);
+    static float RisingEdge(RTLIL::Wire *clock_wire);
+    static float FallingEdge(RTLIL::Wire *clock_wire);
+    static std::string Name(RTLIL::Wire *clock_wire);
+    static std::string WireName(RTLIL::Wire *wire);
+    static std::string AddEscaping(const std::string &name) { return std::regex_replace(name, std::regex{"\\$"}, "\\$"); }
+    static std::string SourceWireName(RTLIL::Wire *clock_wire);
+    static bool IsPropagated(RTLIL::Wire *wire) { return GetClockWireBoolAttribute(wire, "IS_PROPAGATED"); }
+
+    static bool IsGenerated(RTLIL::Wire *wire) { return GetClockWireBoolAttribute(wire, "IS_GENERATED"); }
+
+    static bool IsExplicit(RTLIL::Wire *wire) { return GetClockWireBoolAttribute(wire, "IS_EXPLICIT"); }
+
+  private:
+    static std::pair<float, float> Waveform(RTLIL::Wire *clock_wire);
+
+    static bool GetClockWireBoolAttribute(RTLIL::Wire *wire, const std::string &attribute_name);
+};
+
+class Clocks
+{
+  public:
+    static const std::map<std::string, RTLIL::Wire *> GetClocks(RTLIL::Design *design);
+    static void UpdateAbc9DelayTarget(RTLIL::Design *design);
+};
+
+#endif // _CLOCKS_H_
diff --git a/yosys-plugins/sdc/propagation.cc b/yosys-plugins/sdc/propagation.cc
new file mode 100644
index 000000000..dd7718ea8
--- /dev/null
+++ b/yosys-plugins/sdc/propagation.cc
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "propagation.h"
+#include <cassert>
+
+USING_YOSYS_NAMESPACE
+
+void Propagation::PropagateThroughBuffers(Buffer buffer)
+{
+    for (auto &clock : Clocks::GetClocks(design_)) {
+        auto &clock_wire = clock.second;
+#ifdef SDC_DEBUG
+        log("Clock wire %s\n", Clock::WireName(clock_wire).c_str());
+#endif
+        auto buf_wires = FindSinkWiresForCellType(clock_wire, buffer.type, buffer.output);
+        int path_delay(0);
+        for (auto wire : buf_wires) {
+#ifdef SDC_DEBUG
+            log("%s wire: %s\n", buffer.type.c_str(), RTLIL::id2cstr(wire->name));
+#endif
+            path_delay += buffer.delay;
+            Clock::Add(wire, Clock::Period(clock_wire), Clock::RisingEdge(clock_wire) + path_delay, Clock::FallingEdge(clock_wire) + path_delay,
+                       Clock::PROPAGATED);
+        }
+    }
+}
+
+std::vector<RTLIL::Wire *> Propagation::FindSinkWiresForCellType(RTLIL::Wire *driver_wire, const std::string &cell_type, const std::string &cell_port)
+{
+    std::vector<RTLIL::Wire *> wires;
+    if (!driver_wire) {
+        return wires;
+    }
+    auto cell = FindSinkCellOfType(driver_wire, cell_type);
+    RTLIL::Wire *wire = FindSinkWireOnPort(cell, cell_port);
+    if (wire) {
+        wires.push_back(wire);
+        auto further_wires = FindSinkWiresForCellType(wire, cell_type, cell_port);
+        std::copy(further_wires.begin(), further_wires.end(), std::back_inserter(wires));
+    }
+    return wires;
+}
+
+RTLIL::Cell *Propagation::FindSinkCellOfType(RTLIL::Wire *wire, const std::string &type)
+{
+    RTLIL::Cell *sink_cell = NULL;
+    if (!wire) {
+        return sink_cell;
+    }
+    RTLIL::Module *top_module = design_->top_module();
+    assert(top_module);
+    std::string base_selection = top_module->name.str() + "/w:" + wire->name.str();
+    pass_->extra_args(std::vector<std::string>{base_selection, "%co:+" + type, base_selection, "%d"}, 0, design_);
+    auto selected_cells = top_module->selected_cells();
+    // FIXME Handle more than one sink
+    assert(selected_cells.size() <= 1);
+    if (selected_cells.size() > 0) {
+        sink_cell = selected_cells.at(0);
+#ifdef SDC_DEBUG
+        log("Found sink cell: %s\n", RTLIL::unescape_id(sink_cell->name).c_str());
+#endif
+    }
+    return sink_cell;
+}
+
+RTLIL::Cell *Propagation::FindSinkCellOnPort(RTLIL::Wire *wire, const std::string &port)
+{
+    RTLIL::Cell *sink_cell = NULL;
+    if (!wire) {
+        return sink_cell;
+    }
+    RTLIL::Module *top_module = design_->top_module();
+    assert(top_module);
+    std::string base_selection = top_module->name.str() + "/w:" + wire->name.str();
+    pass_->extra_args(std::vector<std::string>{base_selection, "%co:+[" + port + "]", base_selection, "%d"}, 0, design_);
+    auto selected_cells = top_module->selected_cells();
+    // FIXME Handle more than one sink
+    assert(selected_cells.size() <= 1);
+    if (selected_cells.size() > 0) {
+        sink_cell = selected_cells.at(0);
+#ifdef SDC_DEBUG
+        log("Found sink cell: %s\n", RTLIL::unescape_id(sink_cell->name).c_str());
+#endif
+    }
+    return sink_cell;
+}
+
+bool Propagation::WireHasSinkCell(RTLIL::Wire *wire)
+{
+    if (!wire) {
+        return false;
+    }
+    RTLIL::Module *top_module = design_->top_module();
+    assert(top_module);
+    std::string base_selection = top_module->name.str() + "/w:" + wire->name.str();
+    pass_->extra_args(std::vector<std::string>{base_selection, "%co:*", base_selection, "%d"}, 0, design_);
+    auto selected_cells = top_module->selected_cells();
+    return selected_cells.size() > 0;
+}
+
+RTLIL::Wire *Propagation::FindSinkWireOnPort(RTLIL::Cell *cell, const std::string &port_name)
+{
+    RTLIL::Wire *sink_wire = NULL;
+    if (!cell) {
+        return sink_wire;
+    }
+    RTLIL::Module *top_module = design_->top_module();
+    assert(top_module);
+    std::string base_selection = top_module->name.str() + "/c:" + cell->name.str();
+    pass_->extra_args(std::vector<std::string>{base_selection, "%co:+[" + port_name + "]", base_selection, "%d"}, 0, design_);
+    auto selected_wires = top_module->selected_wires();
+    // FIXME Handle more than one sink
+    assert(selected_wires.size() <= 1);
+    if (selected_wires.size() > 0) {
+        sink_wire = selected_wires.at(0);
+#ifdef SDC_DEBUG
+        log("Found sink wire: %s\n", RTLIL::unescape_id(sink_wire->name).c_str());
+#endif
+    }
+    return sink_wire;
+}
+
+void NaturalPropagation::Run()
+{
+#ifdef SDC_DEBUG
+    log("Start natural clock propagation\n");
+#endif
+    for (auto &clock : Clocks::GetClocks(design_)) {
+        auto &clock_wire = clock.second;
+#ifdef SDC_DEBUG
+        log("Processing clock %s\n", RTLIL::id2cstr(clock_wire->name));
+#endif
+        auto aliases = FindAliasWires(clock_wire);
+        Clock::Add(Clock::WireName(clock_wire), aliases, Clock::Period(clock_wire), Clock::RisingEdge(clock_wire), Clock::FallingEdge(clock_wire),
+                   Clock::PROPAGATED);
+    }
+#ifdef SDC_DEBUG
+    log("Finish natural clock propagation\n\n");
+#endif
+}
+
+std::vector<RTLIL::Wire *> NaturalPropagation::FindAliasWires(RTLIL::Wire *wire)
+{
+    RTLIL::Module *top_module = design_->top_module();
+    assert(top_module);
+    std::vector<RTLIL::Wire *> alias_wires;
+    pass_->extra_args(std::vector<std::string>{top_module->name.str() + "/w:" + wire->name.str(), "%a"}, 0, design_);
+    for (auto module : design_->selected_modules()) {
+        for (auto wire : module->selected_wires()) {
+            alias_wires.push_back(wire);
+        }
+    }
+    return alias_wires;
+}
+
+void BufferPropagation::Run()
+{
+#ifdef SDC_DEBUG
+    log("Start buffer clock propagation\n");
+    log("IBUF pass\n");
+#endif
+    PropagateThroughBuffers(IBuf());
+#ifdef SDC_DEBUG
+    log("BUFG pass\n");
+#endif
+    PropagateThroughBuffers(Bufg());
+#ifdef SDC_DEBUG
+    log("Finish buffer clock propagation\n\n");
+#endif
+}
+
+void ClockDividerPropagation::Run()
+{
+#ifdef SDC_DEBUG
+    log("Start clock divider clock propagation\n");
+#endif
+    PropagateThroughClockDividers(Pll());
+    PropagateThroughBuffers(Bufg());
+#ifdef SDC_DEBUG
+    log("Finish clock divider clock propagation\n\n");
+#endif
+}
+
+void ClockDividerPropagation::PropagateThroughClockDividers(ClockDivider divider)
+{
+    for (auto &clock : Clocks::GetClocks(design_)) {
+        auto &clock_wire = clock.second;
+#ifdef SDC_DEBUG
+        log("Processing clock %s\n", Clock::WireName(clock_wire).c_str());
+#endif
+        PropagateClocksForCellType(clock_wire, divider.type);
+    }
+}
+
+void ClockDividerPropagation::PropagateClocksForCellType(RTLIL::Wire *driver_wire, const std::string &cell_type)
+{
+    if (cell_type == "PLLE2_ADV") {
+        RTLIL::Cell *cell = NULL;
+        for (auto input : Pll::inputs) {
+            cell = FindSinkCellOnPort(driver_wire, input);
+            if (cell and RTLIL::unescape_id(cell->type) == cell_type) {
+                break;
+            }
+        }
+        if (!cell) {
+            return;
+        }
+        Pll pll(cell, Clock::Period(driver_wire), Clock::RisingEdge(driver_wire));
+        for (auto output : Pll::outputs) {
+            RTLIL::Wire *wire = FindSinkWireOnPort(cell, output);
+            // Don't add clocks on dangling wires
+            // TODO Remove the workaround with the WireHasSinkCell check once the following issue is fixed:
+            // https://github.com/SymbiFlow/yosys-f4pga-plugins/issues/59
+            if (wire && WireHasSinkCell(wire)) {
+                float clkout_period(pll.clkout_period.at(output));
+                float clkout_rising_edge(pll.clkout_rising_edge.at(output));
+                float clkout_falling_edge(pll.clkout_falling_edge.at(output));
+                Clock::Add(wire, clkout_period, clkout_rising_edge, clkout_falling_edge, Clock::GENERATED);
+            }
+        }
+    }
+}
diff --git a/yosys-plugins/sdc/propagation.h b/yosys-plugins/sdc/propagation.h
new file mode 100644
index 000000000..cb47cd070
--- /dev/null
+++ b/yosys-plugins/sdc/propagation.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _PROPAGATION_H_
+#define _PROPAGATION_H_
+
+#include "clocks.h"
+
+USING_YOSYS_NAMESPACE
+
+class Propagation
+{
+  public:
+    Propagation(RTLIL::Design *design, Pass *pass) : design_(design), pass_(pass) {}
+    virtual ~Propagation() {}
+
+    virtual void Run() = 0;
+
+  protected:
+    RTLIL::Design *design_;
+    Pass *pass_;
+
+    // This propagation doesn't change the clock so the sink wire is only marked
+    // as propagated clock signal, but has the properties of the driving clock
+    void PropagateThroughBuffers(Buffer buffer);
+    std::vector<RTLIL::Wire *> FindSinkWiresForCellType(RTLIL::Wire *driver_wire, const std::string &cell_type, const std::string &cell_port);
+    RTLIL::Cell *FindSinkCellOfType(RTLIL::Wire *wire, const std::string &type);
+    RTLIL::Cell *FindSinkCellOnPort(RTLIL::Wire *wire, const std::string &port);
+    RTLIL::Wire *FindSinkWireOnPort(RTLIL::Cell *cell, const std::string &port_name);
+    bool WireHasSinkCell(RTLIL::Wire *wire);
+};
+
+class NaturalPropagation : public Propagation
+{
+  public:
+    NaturalPropagation(RTLIL::Design *design, Pass *pass) : Propagation(design, pass) {}
+
+    void Run() override;
+    std::vector<RTLIL::Wire *> FindAliasWires(RTLIL::Wire *wire);
+};
+
+class BufferPropagation : public Propagation
+{
+  public:
+    BufferPropagation(RTLIL::Design *design, Pass *pass) : Propagation(design, pass) {}
+
+    void Run() override;
+};
+
+class ClockDividerPropagation : public Propagation
+{
+  public:
+    ClockDividerPropagation(RTLIL::Design *design, Pass *pass) : Propagation(design, pass) {}
+
+    void Run() override;
+    void PropagateClocksForCellType(RTLIL::Wire *driver_wire, const std::string &cell_type);
+    void PropagateThroughClockDividers(ClockDivider divider);
+};
+#endif // PROPAGATION_H_
diff --git a/yosys-plugins/sdc/sdc.cc b/yosys-plugins/sdc/sdc.cc
new file mode 100644
index 000000000..fd153c67b
--- /dev/null
+++ b/yosys-plugins/sdc/sdc.cc
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 <algorithm>
+#include <array>
+#include <istream>
+#include <iterator>
+#include <map>
+#include <memory>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "clocks.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "propagation.h"
+#include "sdc_writer.h"
+#include "set_clock_groups.h"
+#include "set_false_path.h"
+#include "set_max_delay.h"
+
+USING_YOSYS_NAMESPACE
+
+PRIVATE_NAMESPACE_BEGIN
+
+struct ReadSdcCmd : public Frontend {
+    ReadSdcCmd() : Frontend("sdc", "Read SDC file") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    read_sdc <filename>\n");
+        log("\n");
+        log("Read SDC file.\n");
+        log("\n");
+    }
+
+    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *) override
+    {
+        if (args.size() < 2) {
+            log_cmd_error("Missing script file.\n");
+        }
+        log("\nReading clock constraints file(SDC)\n\n");
+        size_t argidx = 1;
+        extra_args(f, filename, args, argidx);
+        std::string content{std::istreambuf_iterator<char>(*f), std::istreambuf_iterator<char>()};
+        log("%s\n", content.c_str());
+        Tcl_Interp *interp = yosys_get_tcl_interp();
+        if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
+            log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
+        }
+    }
+};
+
+struct WriteSdcCmd : public Backend {
+    WriteSdcCmd(SdcWriter &sdc_writer) : Backend("sdc", "Write SDC file"), sdc_writer_(sdc_writer) {}
+
+    void help() override
+    {
+        log("\n");
+        log("    write_sdc [-include_propagated_clocks] <filename>\n");
+        log("\n");
+        log("Write SDC file.\n");
+        log("\n");
+        log("    -include_propagated_clocks\n");
+        log("       Write out all propagated clocks");
+        log("\n");
+    }
+
+    void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        size_t argidx;
+        bool include_propagated = false;
+        if (args.size() < 2) {
+            log_cmd_error("Missing output file.\n");
+        }
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            std::string arg = args[argidx];
+            if (arg == "-include_propagated_clocks" && argidx + 1 < args.size()) {
+                include_propagated = true;
+                continue;
+            }
+            break;
+        }
+        log("\nWriting out clock constraints file(SDC)\n");
+        extra_args(f, filename, args, argidx);
+        sdc_writer_.WriteSdc(design, *f, include_propagated);
+    }
+
+    SdcWriter &sdc_writer_;
+};
+
+struct CreateClockCmd : public Pass {
+    CreateClockCmd() : Pass("create_clock", "Create clock object") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    create_clock [ -name clock_name ] -period period_value "
+            "[-waveform <edge_list>] <target>\n");
+        log("Define a clock.\n");
+        log("If name is not specified then the name of the first target is "
+            "selected as the clock's name.\n");
+        log("Period is expressed in nanoseconds.\n");
+        log("The waveform option specifies the duty cycle (the rising a "
+            "falling edges) of the clock.\n");
+        log("It is specified as a list of two elements/time values: the first "
+            "rising edge and the next falling edge.\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        size_t argidx;
+        std::string name;
+        bool is_waveform_specified(false);
+        float rising_edge(0);
+        float falling_edge(0);
+        float period(0);
+        if (args.size() < 4) {
+            log_cmd_error("Incorrect number of arguments\n");
+        }
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            std::string arg = args[argidx];
+            if (arg == "-add" && argidx + 1 < args.size()) {
+                continue;
+            }
+            if (arg == "-name" && argidx + 1 < args.size()) {
+                name = args[++argidx];
+                continue;
+            }
+            if (arg == "-period" && argidx + 1 < args.size()) {
+                period = std::stof(args[++argidx]);
+                continue;
+            }
+            if (arg == "-waveform" && argidx + 1 < args.size()) {
+                std::string edges(args[++argidx]);
+                std::copy_if(edges.begin(), edges.end(), edges.begin(), [](char c) { return c != '{' or c != '}'; });
+                std::stringstream ss(edges);
+                ss >> rising_edge >> falling_edge;
+                is_waveform_specified = true;
+                continue;
+            }
+            break;
+        }
+        if (period <= 0) {
+            log_cmd_error("Incorrect period value\n");
+        }
+        // Add "w:" prefix to selection arguments to enforce wire object
+        // selection
+        AddWirePrefix(args, argidx);
+        extra_args(args, argidx, design);
+        // If clock name is not specified then take the name of the first target
+        std::vector<RTLIL::Wire *> selected_wires;
+        for (auto module : design->modules()) {
+            if (!design->selected(module)) {
+                continue;
+            }
+            for (auto wire : module->wires()) {
+                if (design->selected(module, wire)) {
+#ifdef SDC_DEBUG
+                    log("Selected wire %s\n", RTLIL::unescape_id(wire->name).c_str());
+#endif
+                    selected_wires.push_back(wire);
+                }
+            }
+        }
+        if (selected_wires.size() == 0) {
+            log_cmd_error("Target selection is empty\n");
+        }
+        if (name.empty()) {
+            name = RTLIL::unescape_id(selected_wires.at(0)->name);
+        }
+        if (!is_waveform_specified) {
+            rising_edge = 0;
+            falling_edge = period / 2;
+        }
+        Clock::Add(name, selected_wires, period, rising_edge, falling_edge, Clock::EXPLICIT);
+    }
+
+    void AddWirePrefix(std::vector<std::string> &args, size_t argidx)
+    {
+        auto selection_begin = args.begin() + argidx;
+        std::transform(selection_begin, args.end(), selection_begin, [](std::string &w) { return "w:" + w; });
+    }
+};
+
+struct GetClocksCmd : public Pass {
+    GetClocksCmd() : Pass("get_clocks", "Create clock object") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    get_clocks [-include_generated_clocks] [-of <nets>] "
+            "[<patterns>]\n");
+        log("\n");
+        log("Returns all clocks in the design.\n");
+        log("\n");
+        log("    -include_generated_clocks\n");
+        log("        Include auto-generated clocks.\n");
+        log("\n");
+        log("    -of\n");
+        log("        Get clocks of these nets.\n");
+        log("\n");
+        log("    <pattern>\n");
+        log("        Pattern of clock names. Default are all clocks in the "
+            "design.\n");
+        log("\n");
+    }
+
+    std::vector<std::string> extract_list(const std::string &args)
+    {
+        std::vector<std::string> port_list;
+        std::stringstream ss(args);
+        std::istream_iterator<std::string> begin(ss);
+        std::istream_iterator<std::string> end;
+        std::copy(begin, end, std::back_inserter(port_list));
+        return port_list;
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+
+        // Parse command arguments
+        bool include_generated_clocks(false);
+        std::vector<std::string> clocks_nets;
+        size_t argidx(0);
+
+        // Parse command switches
+        for (argidx = 1; argidx < args.size(); argidx++) {
+            std::string arg = args[argidx];
+            if (arg == "-include_generated_clocks") {
+                include_generated_clocks = true;
+                continue;
+            }
+            if (arg == "-of" and argidx + 1 < args.size()) {
+                clocks_nets = extract_list(args[++argidx]);
+#ifdef SDC_DEBUG
+                for (auto clock_net : clocks_nets) {
+                    log("Clock filter %s\n", clock_net.c_str());
+                }
+#endif
+                continue;
+            }
+            if (arg.size() > 0 and arg[0] == '-') {
+                log_cmd_error("Unknown option %s.\n", arg.c_str());
+            }
+
+            break;
+        }
+
+        // Parse object patterns
+        std::vector<std::string> clocks_list(args.begin() + argidx, args.end());
+
+        // Fetch clocks in the design
+        std::map<std::string, RTLIL::Wire *> clocks(Clocks::GetClocks(design));
+        if (clocks.size() == 0) {
+            log_warning("No clocks found in design\n");
+        }
+
+        // Extract clocks into tcl list
+        Tcl_Interp *interp = yosys_get_tcl_interp();
+        Tcl_Obj *tcl_list = Tcl_NewListObj(0, NULL);
+        for (auto &clock : clocks) {
+            // Skip propagated clocks (i.e. clock wires with the same parameters
+            // as the master clocks they originate from
+            if (Clock::IsPropagated(clock.second)) {
+                continue;
+            }
+            // Skip generated clocks if -include_generated_clocks is not specified
+            if (Clock::IsGenerated(clock.second) and !include_generated_clocks) {
+                continue;
+            }
+            // Check if clock name is in the list of design clocks
+            if (clocks_list.size() > 0 and std::find(clocks_list.begin(), clocks_list.end(), clock.first) == clocks_list.end()) {
+                continue;
+            }
+            // Check if clock wire is in the -of list
+            if (clocks_nets.size() > 0 and std::find(clocks_nets.begin(), clocks_nets.end(), Clock::WireName(clock.second)) == clocks_nets.end()) {
+                continue;
+            }
+            auto &wire = clock.second;
+            const char *name = RTLIL::id2cstr(wire->name);
+            Tcl_Obj *name_obj = Tcl_NewStringObj(name, -1);
+            Tcl_ListObjAppendElement(interp, tcl_list, name_obj);
+        }
+        Tcl_SetObjResult(interp, tcl_list);
+    }
+};
+
+struct PropagateClocksCmd : public Pass {
+    PropagateClocksCmd() : Pass("propagate_clocks", "Propagate clock information") {}
+
+    void help() override
+    {
+        log("\n");
+        log("    propagate_clocks\n");
+        log("\n");
+        log("Propagate clock information throughout the design.\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        if (args.size() > 1) {
+            log_warning("Command accepts no arguments.\nAll will be ignored.\n");
+        }
+        if (!design->top_module()) {
+            log_cmd_error("No top module selected\n");
+        }
+
+        std::array<std::unique_ptr<Propagation>, 2> passes{std::unique_ptr<Propagation>(new BufferPropagation(design, this)),
+                                                           std::unique_ptr<Propagation>(new ClockDividerPropagation(design, this))};
+
+        log("Perform clock propagation\n");
+
+        for (auto &pass : passes) {
+            pass->Run();
+        }
+
+        Clocks::UpdateAbc9DelayTarget(design);
+    }
+};
+
+class SdcPlugin
+{
+  public:
+    SdcPlugin() : write_sdc_cmd_(sdc_writer_), set_false_path_cmd_(sdc_writer_), set_max_delay_cmd_(sdc_writer_), set_clock_groups_cmd_(sdc_writer_)
+    {
+        log("Loaded SDC plugin\n");
+    }
+
+    ReadSdcCmd read_sdc_cmd_;
+    WriteSdcCmd write_sdc_cmd_;
+    CreateClockCmd create_clock_cmd_;
+    GetClocksCmd get_clocks_cmd_;
+    PropagateClocksCmd propagate_clocks_cmd_;
+    SetFalsePath set_false_path_cmd_;
+    SetMaxDelay set_max_delay_cmd_;
+    SetClockGroups set_clock_groups_cmd_;
+
+  private:
+    SdcWriter sdc_writer_;
+} SdcPlugin;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/sdc/sdc_writer.cc b/yosys-plugins/sdc/sdc_writer.cc
new file mode 100644
index 000000000..22157ca71
--- /dev/null
+++ b/yosys-plugins/sdc/sdc_writer.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "sdc_writer.h"
+
+USING_YOSYS_NAMESPACE
+
+const std::map<ClockGroups::ClockGroupRelation, std::string> ClockGroups::relation_name_map = {
+  {NONE, ""}, {ASYNCHRONOUS, "asynchronous"}, {PHYSICALLY_EXCLUSIVE, "physically_exclusive"}, {LOGICALLY_EXCLUSIVE, "logically_exclusive"}};
+
+void SdcWriter::AddFalsePath(FalsePath false_path) { false_paths_.push_back(false_path); }
+
+void SdcWriter::SetMaxDelay(TimingPath timing_path) { timing_paths_.push_back(timing_path); }
+
+void SdcWriter::AddClockGroup(ClockGroups::ClockGroup clock_group, ClockGroups::ClockGroupRelation relation)
+{
+    clock_groups_.Add(clock_group, relation);
+}
+
+void SdcWriter::WriteSdc(RTLIL::Design *design, std::ostream &file, bool include_propagated)
+{
+    WriteClocks(design, file, include_propagated);
+    WriteFalsePaths(file);
+    WriteMaxDelay(file);
+    WriteClockGroups(file);
+}
+
+void SdcWriter::WriteClocks(RTLIL::Design *design, std::ostream &file, bool include_propagated)
+{
+    for (auto &clock : Clocks::GetClocks(design)) {
+        auto &clock_wire = clock.second;
+        // FIXME: Input port nets are not found in VPR
+        if (clock_wire->port_input) {
+            continue;
+        }
+        // Write out only GENERATED and EXPLICIT clocks
+        if (Clock::IsPropagated(clock_wire) and !include_propagated) {
+            continue;
+        }
+        file << "create_clock -period " << Clock::Period(clock_wire);
+        file << " -waveform {" << Clock::RisingEdge(clock_wire) << " " << Clock::FallingEdge(clock_wire) << "}";
+        file << " " << Clock::SourceWireName(clock_wire);
+        file << std::endl;
+    }
+}
+
+void SdcWriter::WriteFalsePaths(std::ostream &file)
+{
+    for (auto path : false_paths_) {
+        file << "set_false_path";
+        if (!path.from_pin.empty()) {
+            file << " -from " << path.from_pin;
+        }
+        if (!path.through_pin.empty()) {
+            file << " -through " << path.through_pin;
+        }
+        if (!path.to_pin.empty()) {
+            file << " -to " << path.to_pin;
+        }
+        file << std::endl;
+    }
+}
+
+void SdcWriter::WriteMaxDelay(std::ostream &file)
+{
+    for (auto path : timing_paths_) {
+        file << "set_max_delay " << path.max_delay;
+        if (!path.from_pin.empty()) {
+            file << " -from " << path.from_pin;
+        }
+        if (!path.to_pin.empty()) {
+            file << " -to " << path.to_pin;
+        }
+        file << std::endl;
+    }
+}
+
+void SdcWriter::WriteClockGroups(std::ostream &file)
+{
+    for (size_t relation = 0; relation <= ClockGroups::CLOCK_GROUP_RELATION_SIZE; relation++) {
+        auto clock_groups = clock_groups_.GetGroups(static_cast<ClockGroups::ClockGroupRelation>(relation));
+        if (clock_groups.size() == 0) {
+            continue;
+        }
+        file << "create_clock_groups ";
+        for (auto group : clock_groups) {
+            file << "-group ";
+            for (auto signal : group) {
+                file << signal << " ";
+            }
+        }
+        if (relation != ClockGroups::ClockGroupRelation::NONE) {
+            file << "-" + ClockGroups::relation_name_map.at(static_cast<ClockGroups::ClockGroupRelation>(relation));
+        }
+        file << std::endl;
+    }
+}
diff --git a/yosys-plugins/sdc/sdc_writer.h b/yosys-plugins/sdc/sdc_writer.h
new file mode 100644
index 000000000..354881e2f
--- /dev/null
+++ b/yosys-plugins/sdc/sdc_writer.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _SDC_WRITER_H_
+#define _SDC_WRITER_H_
+#include "clocks.h"
+#include <map>
+
+USING_YOSYS_NAMESPACE
+
+struct FalsePath {
+    std::string from_pin;
+    std::string to_pin;
+    std::string through_pin;
+};
+
+struct TimingPath {
+    std::string from_pin;
+    std::string to_pin;
+    float max_delay;
+};
+
+struct ClockGroups {
+    enum ClockGroupRelation { NONE, ASYNCHRONOUS, PHYSICALLY_EXCLUSIVE, LOGICALLY_EXCLUSIVE, CLOCK_GROUP_RELATION_SIZE };
+    using ClockGroup = std::vector<std::string>;
+    static const std::map<ClockGroupRelation, std::string> relation_name_map;
+
+    void Add(ClockGroup &group, ClockGroupRelation relation) { groups_[relation].push_back(group); }
+    std::vector<ClockGroup> GetGroups(ClockGroupRelation relation)
+    {
+        if (groups_.count(relation)) {
+            return groups_.at(relation);
+        }
+        return std::vector<ClockGroup>();
+    }
+    size_t size() { return groups_.size(); }
+
+  private:
+    std::map<ClockGroupRelation, std::vector<ClockGroup>> groups_;
+};
+
+class SdcWriter
+{
+  public:
+    void AddFalsePath(FalsePath false_path);
+    void SetMaxDelay(TimingPath timing_path);
+    void AddClockGroup(ClockGroups::ClockGroup clock_group, ClockGroups::ClockGroupRelation relation);
+    void WriteSdc(RTLIL::Design *design, std::ostream &file, bool include_propagated);
+
+  private:
+    void WriteClocks(RTLIL::Design *design, std::ostream &file, bool include_propagated);
+    void WriteFalsePaths(std::ostream &file);
+    void WriteMaxDelay(std::ostream &file);
+    void WriteClockGroups(std::ostream &file);
+
+    std::vector<FalsePath> false_paths_;
+    std::vector<TimingPath> timing_paths_;
+    ClockGroups clock_groups_;
+};
+
+#endif // _SDC_WRITER_H_
diff --git a/yosys-plugins/sdc/set_clock_groups.cc b/yosys-plugins/sdc/set_clock_groups.cc
new file mode 100644
index 000000000..3a64c3183
--- /dev/null
+++ b/yosys-plugins/sdc/set_clock_groups.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "set_clock_groups.h"
+#include "kernel/log.h"
+#include <regex>
+
+USING_YOSYS_NAMESPACE
+
+void SetClockGroups::help()
+{
+    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+    log("\n");
+    log("   set_clock_groups [-quiet] [-group <args>] [-asynchronous] \n");
+    log("\n");
+    log("Set exclusive or asynchronous clock groups\n");
+    log("\n");
+    log("Print the output to stdout too. This is useful when all Yosys is "
+        "executed.\n");
+    log("\n");
+    log("    -quiet\n");
+    log("        Don't print the result of the execution to stdout.\n");
+    log("\n");
+    log("    -group\n");
+    log("        List of clocks to be included in the clock group.\n");
+    log("\n");
+    log("    -asynchronous\n");
+    log("       The specified clocks are asynchronous to each other.\n");
+    log("\n");
+}
+
+void SetClockGroups::execute(std::vector<std::string> args, RTLIL::Design *design)
+{
+    RTLIL::Module *top_module = design->top_module();
+    if (top_module == nullptr) {
+        log_cmd_error("No top module detected\n");
+    }
+
+    size_t argidx;
+    bool is_quiet = false;
+    std::vector<ClockGroups::ClockGroup> clock_groups;
+    auto clock_groups_relation = ClockGroups::NONE;
+
+    // Parse command arguments
+    for (argidx = 1; argidx < args.size(); argidx++) {
+        std::string arg = args[argidx];
+        if (arg == "-quiet") {
+            is_quiet = true;
+            continue;
+        }
+
+        // Parse clock groups relation: asynchronous, logically_exclusive, physically_exclusive
+        auto is_relation_arg = [arg](std::pair<ClockGroups::ClockGroupRelation, std::string> relation) {
+            if (arg.substr(1) == relation.second) {
+                return true;
+            }
+            return false;
+        };
+        auto relation_map_it = std::find_if(ClockGroups::relation_name_map.begin(), ClockGroups::relation_name_map.end(), is_relation_arg);
+        if (relation_map_it != ClockGroups::relation_name_map.end()) {
+            clock_groups_relation = relation_map_it->first;
+            continue;
+        }
+
+        if (arg == "-group" and argidx + 1 < args.size()) {
+            ClockGroups::ClockGroup clock_group;
+            while (argidx + 1 < args.size() and args[argidx + 1][0] != '-') {
+                clock_group.push_back(args[++argidx]);
+            }
+            clock_groups.push_back(clock_group);
+            continue;
+        }
+
+        if (arg.size() > 0 and arg[0] == '-') {
+            log_cmd_error("Unknown option %s.\n", arg.c_str());
+        }
+
+        break;
+    }
+
+    if (clock_groups.size()) {
+        if (!is_quiet) {
+            std::string msg = ClockGroups::relation_name_map.at(clock_groups_relation);
+            msg += (!msg.empty()) ? " " : "";
+            log("Adding %sclock group with following clocks:\n", msg.c_str());
+        }
+        size_t count(0);
+        for (auto &group : clock_groups) {
+            sdc_writer_.AddClockGroup(group, clock_groups_relation);
+            if (!is_quiet) {
+                log("%zu: ", count++);
+                for (auto clk : group) {
+                    log("%s ", clk.c_str());
+                }
+                log("\n");
+            }
+        }
+    }
+}
diff --git a/yosys-plugins/sdc/set_clock_groups.h b/yosys-plugins/sdc/set_clock_groups.h
new file mode 100644
index 000000000..22d90033f
--- /dev/null
+++ b/yosys-plugins/sdc/set_clock_groups.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _SET_CLOCK_GROUPS_H_
+#define _SET_CLOCK_GROUPS_H_
+
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "sdc_writer.h"
+
+USING_YOSYS_NAMESPACE
+
+struct SetClockGroups : public Pass {
+    SetClockGroups(SdcWriter &sdc_writer) : Pass("set_clock_groups", "Set exclusive or asynchronous clock groups"), sdc_writer_(sdc_writer) {}
+
+    void help() override;
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override;
+
+    SdcWriter &sdc_writer_;
+};
+
+#endif //_SET_CLOCK_GROUPS_H_
diff --git a/yosys-plugins/sdc/set_false_path.cc b/yosys-plugins/sdc/set_false_path.cc
new file mode 100644
index 000000000..112a2848b
--- /dev/null
+++ b/yosys-plugins/sdc/set_false_path.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "set_false_path.h"
+#include "kernel/log.h"
+#include "sdc_writer.h"
+#include <regex>
+
+USING_YOSYS_NAMESPACE
+
+void SetFalsePath::help()
+{
+    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+    log("\n");
+    log("   set_false_path [-quiet] [-from <net_name>] [-to <net_name>] \n");
+    log("\n");
+    log("Set false path on the specified net\n");
+    log("\n");
+    log("Print the output to stdout too. This is useful when all Yosys is "
+        "executed.\n");
+    log("\n");
+    log("    -quiet\n");
+    log("        Don't print the result of the execution to stdout.\n");
+    log("\n");
+    log("    -from\n");
+    log("        List of start points or clocks.\n");
+    log("\n");
+    log("    -to\n");
+    log("        List of end points or clocks.\n");
+    log("\n");
+    log("    -through\n");
+    log("        List of through points or clocks.\n");
+    log("\n");
+}
+
+void SetFalsePath::execute(std::vector<std::string> args, RTLIL::Design *design)
+{
+    RTLIL::Module *top_module = design->top_module();
+    if (top_module == nullptr) {
+        log_cmd_error("No top module detected\n");
+    }
+
+    size_t argidx;
+    bool is_quiet = false;
+    std::string from_pin;
+    std::string to_pin;
+    std::string through_pin;
+
+    // Parse command arguments
+    for (argidx = 1; argidx < args.size(); argidx++) {
+        std::string arg = args[argidx];
+        if (arg == "-quiet") {
+            is_quiet = true;
+            continue;
+        }
+
+        if (arg == "-from" and argidx + 1 < args.size()) {
+            from_pin = args[++argidx];
+            continue;
+        }
+
+        if (arg == "-to" and argidx + 1 < args.size()) {
+            to_pin = args[++argidx];
+            continue;
+        }
+
+        if (arg == "-through" and argidx + 1 < args.size()) {
+            through_pin = args[++argidx];
+            continue;
+        }
+
+        if (arg.size() > 0 and arg[0] == '-') {
+            log_cmd_error("Unknown option %s.\n", arg.c_str());
+        }
+
+        break;
+    }
+    if (!is_quiet) {
+        std::string msg = (from_pin.empty()) ? "" : "-from " + from_pin;
+        msg += (through_pin.empty()) ? "" : " -through " + through_pin;
+        msg += (to_pin.empty()) ? "" : " -to " + to_pin;
+        log("Adding false path %s\n", msg.c_str());
+    }
+    sdc_writer_.AddFalsePath(FalsePath{.from_pin = from_pin, .to_pin = to_pin, .through_pin = through_pin});
+}
diff --git a/yosys-plugins/sdc/set_false_path.h b/yosys-plugins/sdc/set_false_path.h
new file mode 100644
index 000000000..a779aa4d8
--- /dev/null
+++ b/yosys-plugins/sdc/set_false_path.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _SET_FALSE_PATH_H_
+#define _SET_FALSE_PATH_H_
+
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "sdc_writer.h"
+
+USING_YOSYS_NAMESPACE
+
+struct SetFalsePath : public Pass {
+    SetFalsePath(SdcWriter &sdc_writer) : Pass("set_false_path", "Set false path on net"), sdc_writer_(sdc_writer) {}
+
+    void help() override;
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override;
+
+    SdcWriter &sdc_writer_;
+};
+
+#endif //_SET_FALSE_PATH_H_
diff --git a/yosys-plugins/sdc/set_max_delay.cc b/yosys-plugins/sdc/set_max_delay.cc
new file mode 100644
index 000000000..4bf27540f
--- /dev/null
+++ b/yosys-plugins/sdc/set_max_delay.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "set_max_delay.h"
+#include "kernel/log.h"
+#include "sdc_writer.h"
+
+USING_YOSYS_NAMESPACE
+
+void SetMaxDelay::help()
+{
+    //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+    log("\n");
+    log("   set_max_delay [-quiet] [-from <arg>] [-to <arg>] \n");
+    log("\n");
+    log("Specify maximum delay for timing paths\n");
+    log("\n");
+    log("Print the output to stdout too. This is useful when all Yosys is "
+        "executed.\n");
+    log("\n");
+    log("    -quiet\n");
+    log("        Don't print the result of the execution to stdout.\n");
+    log("\n");
+    log("    -from\n");
+    log("        List of start points or clocks.\n");
+    log("\n");
+    log("    -to\n");
+    log("        List of end points or clocks.\n");
+    log("\n");
+}
+
+void SetMaxDelay::execute(std::vector<std::string> args, RTLIL::Design *design)
+{
+    RTLIL::Module *top_module = design->top_module();
+    if (top_module == nullptr) {
+        log_cmd_error("No top module detected\n");
+    }
+
+    size_t argidx;
+    bool is_quiet = false;
+    std::string from_pin;
+    std::string to_pin;
+    float max_delay(0.0);
+
+    // Parse command arguments
+    for (argidx = 1; argidx < args.size(); argidx++) {
+        std::string arg = args[argidx];
+        if (arg == "-quiet") {
+            is_quiet = true;
+            continue;
+        }
+
+        if (arg == "-from" and argidx + 1 < args.size()) {
+            from_pin = args[++argidx];
+            log("From: %s\n", from_pin.c_str());
+            continue;
+        }
+
+        if (arg == "-to" and argidx + 1 < args.size()) {
+            to_pin = args[++argidx];
+            log("To: %s\n", to_pin.c_str());
+            continue;
+        }
+
+        if (arg.size() > 0 and arg[0] == '-') {
+            log_cmd_error("Unknown option %s.\n", arg.c_str());
+        }
+
+        max_delay = std::stof(args[argidx]);
+    }
+
+    if (!is_quiet) {
+        std::string msg = (from_pin.empty()) ? "" : "-from " + from_pin;
+        msg += (to_pin.empty()) ? "" : " -to " + to_pin;
+        log("Adding max path delay of %f on path %s\n", max_delay, msg.c_str());
+    }
+    sdc_writer_.SetMaxDelay(TimingPath{.from_pin = from_pin, .to_pin = to_pin, .max_delay = max_delay});
+}
diff --git a/yosys-plugins/sdc/set_max_delay.h b/yosys-plugins/sdc/set_max_delay.h
new file mode 100644
index 000000000..6f3e50de6
--- /dev/null
+++ b/yosys-plugins/sdc/set_max_delay.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _SET_MAX_DELAY_H_
+#define _SET_MAX_DELAY_H_
+
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "sdc_writer.h"
+
+USING_YOSYS_NAMESPACE
+
+struct SetMaxDelay : public Pass {
+    SetMaxDelay(SdcWriter &sdc_writer) : Pass("set_max_delay", "Specify maximum delay for timing paths"), sdc_writer_(sdc_writer) {}
+
+    void help() override;
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override;
+
+    SdcWriter &sdc_writer_;
+};
+
+#endif //_SET_MAX_DELAY_H_
diff --git a/yosys-plugins/sdc/tests/Makefile b/yosys-plugins/sdc/tests/Makefile
new file mode 100644
index 000000000..06f0c7385
--- /dev/null
+++ b/yosys-plugins/sdc/tests/Makefile
@@ -0,0 +1,70 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# abc9 - test that abc9.D is correctly set after importing a clock.
+# counter, counter2, pll - test buffer and clock divider propagation
+# set_false_path - test the set_false_path command
+# set_max_delay - test the set_max_delay command
+# set_clock_groups - test the set_clock_groups command
+# restore_from_json - test clock propagation when design restored from json instead verilog
+# period_check - test if the clock propagation fails if a clock wire is missing the PERIOD attribute
+# waveform_check - test if the WAVEFORM attribute value is correct on wire
+# period_format_check - test if PERIOD attribute value is correct on wire
+
+TESTS = abc9 \
+	counter \
+	counter2 \
+	pll \
+	pll_div \
+	pll_fbout_phase \
+	pll_approx_equal \
+	pll_dangling_wires \
+	pll_propagated \
+	set_false_path \
+	set_max_delay \
+	set_clock_groups \
+	restore_from_json \
+	period_check \
+	waveform_check \
+	period_format_check \
+	get_clocks \
+	create_clock_add
+
+UNIT_TESTS = escaping
+
+include $(shell pwd)/../../Makefile_test.common
+
+abc9_verify = true
+counter_verify = $(call diff_test,counter,sdc) && $(call diff_test,counter,txt)
+counter2_verify = $(call diff_test,counter2,sdc) && $(call diff_test,counter2,txt)
+pll_verify = $(call diff_test,pll,sdc)
+pll_div_verify = $(call diff_test,pll_div,sdc)
+pll_fbout_phase_verify = $(call diff_test,pll_fbout_phase,sdc)
+pll_approx_equal_verify = $(call diff_test,pll_approx_equal,sdc)
+pll_dangling_wires_verify = $(call diff_test,pll_dangling_wires,sdc)
+pll_propagated_verify = $(call diff_test,pll_propagated,sdc)
+set_false_path_verify = $(call diff_test,set_false_path,sdc)
+set_max_delay_verify = $(call diff_test,set_max_delay,sdc)
+set_clock_groups_verify = $(call diff_test,set_clock_groups,sdc)
+restore_from_json_verify = diff restore_from_json/restore_from_json_1.sdc restore_from_json/restore_from_json_2.sdc
+period_check_verify = true
+period_check_negative = 1
+waveform_check_verify = true
+waveform_check_negative = 1
+period_format_check_verify = true
+period_format_check_negative = 1
+get_clocks_verify = $(call diff_test,get_clocks,txt)
+create_clock_add_verify = $(call diff_test,create_clock_add,sdc) && $(call diff_test,create_clock_add,txt)
diff --git a/yosys-plugins/sdc/tests/abc9/abc9.input.sdc b/yosys-plugins/sdc/tests/abc9/abc9.input.sdc
new file mode 100644
index 000000000..0a192c363
--- /dev/null
+++ b/yosys-plugins/sdc/tests/abc9/abc9.input.sdc
@@ -0,0 +1,3 @@
+create_clock -period 10 clk1
+create_clock -period 20 clk2
+propagate_clocks
diff --git a/yosys-plugins/sdc/tests/abc9/abc9.tcl b/yosys-plugins/sdc/tests/abc9/abc9.tcl
new file mode 100644
index 000000000..ba7133469
--- /dev/null
+++ b/yosys-plugins/sdc/tests/abc9/abc9.tcl
@@ -0,0 +1,12 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+# ensure abc9.D is unset
+scratchpad -assert-unset abc9.D
+
+read_verilog $::env(DESIGN_TOP).v
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# check that abc9.D was set to half the fastest clock period in the design
+scratchpad -assert abc9.D 5000
diff --git a/yosys-plugins/sdc/tests/abc9/abc9.v b/yosys-plugins/sdc/tests/abc9/abc9.v
new file mode 100644
index 000000000..a2038ab36
--- /dev/null
+++ b/yosys-plugins/sdc/tests/abc9/abc9.v
@@ -0,0 +1,34 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input  clk1,
+    clk2,
+    output led1,
+    led2
+);
+
+  reg [15:0] counter1 = 0;
+  reg [15:0] counter2 = 0;
+
+  assign led1 = counter1[15];
+  assign led2 = counter2[15];
+
+  always @(posedge clk1) counter1 <= counter1 + 1;
+
+  always @(posedge clk2) counter2 <= counter2 + 1;
+
+endmodule
diff --git a/yosys-plugins/sdc/tests/counter/counter.golden.sdc b/yosys-plugins/sdc/tests/counter/counter.golden.sdc
new file mode 100644
index 000000000..cfa90cba8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter/counter.golden.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk_int_1
diff --git a/yosys-plugins/sdc/tests/counter/counter.golden.txt b/yosys-plugins/sdc/tests/counter/counter.golden.txt
new file mode 100644
index 000000000..9301c2dd6
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter/counter.golden.txt
@@ -0,0 +1,2 @@
+clk clk2 clk_int_1
+clk clk2 clk_int_1
diff --git a/yosys-plugins/sdc/tests/counter/counter.input.sdc b/yosys-plugins/sdc/tests/counter/counter.input.sdc
new file mode 100644
index 000000000..01debad8a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter/counter.input.sdc
@@ -0,0 +1,2 @@
+create_clock -period 10.0 -waveform {0.000 5.000} clk_int_1
+create_clock -period 10.0 -name clk -waveform {0.000 5.000} clk clk2
diff --git a/yosys-plugins/sdc/tests/counter/counter.tcl b/yosys-plugins/sdc/tests/counter/counter.tcl
new file mode 100644
index 000000000..275c2f0f8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter/counter.tcl
@@ -0,0 +1,29 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Read the design's timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write the clocks to file
+set fh [open [test_output_path "counter.txt"] w]
+puts $fh [get_clocks]
+puts $fh [get_clocks -include_generated_clocks]
+close $fh
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "counter.sdc"]
+write_json [test_output_path "counter.json"]
diff --git a/yosys-plugins/sdc/tests/counter/counter.v b/yosys-plugins/sdc/tests/counter/counter.v
new file mode 100644
index 000000000..acda4b651
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter/counter.v
@@ -0,0 +1,74 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/counter2/counter2.golden.sdc b/yosys-plugins/sdc/tests/counter2/counter2.golden.sdc
new file mode 100644
index 000000000..cfa90cba8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter2/counter2.golden.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk_int_1
diff --git a/yosys-plugins/sdc/tests/counter2/counter2.golden.txt b/yosys-plugins/sdc/tests/counter2/counter2.golden.txt
new file mode 100644
index 000000000..c7ecd76e8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter2/counter2.golden.txt
@@ -0,0 +1 @@
+clk clk2 clk_int_1
diff --git a/yosys-plugins/sdc/tests/counter2/counter2.input.sdc b/yosys-plugins/sdc/tests/counter2/counter2.input.sdc
new file mode 100644
index 000000000..3b1ac05ba
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter2/counter2.input.sdc
@@ -0,0 +1,3 @@
+create_clock -period 10.0 -waveform {0.000 5.000} clk_int_1
+create_clock -period 10.0 clk
+create_clock -period 10.0 -waveform {1.000 6.000} clk2
diff --git a/yosys-plugins/sdc/tests/counter2/counter2.tcl b/yosys-plugins/sdc/tests/counter2/counter2.tcl
new file mode 100644
index 000000000..5b01c4164
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter2/counter2.tcl
@@ -0,0 +1,25 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Read the design's timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write the clocks to file
+set fh [open [test_output_path "counter2.txt"] w]
+set clocks [get_clocks]
+puts $fh $clocks
+close $fh
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "counter2.sdc"]
diff --git a/yosys-plugins/sdc/tests/counter2/counter2.v b/yosys-plugins/sdc/tests/counter2/counter2.v
new file mode 100644
index 000000000..acda4b651
--- /dev/null
+++ b/yosys-plugins/sdc/tests/counter2/counter2.v
@@ -0,0 +1,74 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.sdc b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.sdc
new file mode 100644
index 000000000..cfa90cba8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk_int_1
diff --git a/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.txt b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.txt
new file mode 100644
index 000000000..9301c2dd6
--- /dev/null
+++ b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.golden.txt
@@ -0,0 +1,2 @@
+clk clk2 clk_int_1
+clk clk2 clk_int_1
diff --git a/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.input.sdc b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.input.sdc
new file mode 100644
index 000000000..f22823fd3
--- /dev/null
+++ b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.input.sdc
@@ -0,0 +1,2 @@
+create_clock -add -period 10.0 -waveform {0.000 5.000} clk_int_1
+create_clock -add -period 10.0 -name clk -waveform {0.000 5.000} clk clk2
diff --git a/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.tcl b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.tcl
new file mode 100644
index 000000000..cf2869a00
--- /dev/null
+++ b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.tcl
@@ -0,0 +1,29 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Read the design's timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write the clocks to file
+set fh [open [test_output_path $::env(DESIGN_TOP).txt] w]
+puts $fh [get_clocks]
+puts $fh [get_clocks -include_generated_clocks]
+close $fh
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path $::env(DESIGN_TOP).sdc]
+write_json [test_output_path $::env(DESIGN_TOP).json]
diff --git a/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.v b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.v
new file mode 100644
index 000000000..acda4b651
--- /dev/null
+++ b/yosys-plugins/sdc/tests/create_clock_add/create_clock_add.v
@@ -0,0 +1,74 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/escaping/escaping.test.cc b/yosys-plugins/sdc/tests/escaping/escaping.test.cc
new file mode 100644
index 000000000..a26a84970
--- /dev/null
+++ b/yosys-plugins/sdc/tests/escaping/escaping.test.cc
@@ -0,0 +1,11 @@
+#include <clocks.h>
+
+#include <gtest/gtest.h>
+
+TEST(ClockTest, EscapeDollarSign)
+{
+    // convert wire_name to wire_name, i.e. unchanged
+    EXPECT_EQ(Clock::AddEscaping("wire_name"), "wire_name");
+    // convert $wire_name to \$wire_name
+    EXPECT_EQ(Clock::AddEscaping("$wire_name"), "\\$wire_name");
+}
diff --git a/yosys-plugins/sdc/tests/get_clocks/get_clocks.golden.txt b/yosys-plugins/sdc/tests/get_clocks/get_clocks.golden.txt
new file mode 100644
index 000000000..13196ee9a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/get_clocks/get_clocks.golden.txt
@@ -0,0 +1,6 @@
+clk clk2 clk_int_1
+clk clk2 clk_int_1 main_clkout0
+clk2
+clk_int_1
+clk clk2 clk_int_1
+clk clk2 clk_int_1
diff --git a/yosys-plugins/sdc/tests/get_clocks/get_clocks.input.sdc b/yosys-plugins/sdc/tests/get_clocks/get_clocks.input.sdc
new file mode 100644
index 000000000..01debad8a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/get_clocks/get_clocks.input.sdc
@@ -0,0 +1,2 @@
+create_clock -period 10.0 -waveform {0.000 5.000} clk_int_1
+create_clock -period 10.0 -name clk -waveform {0.000 5.000} clk clk2
diff --git a/yosys-plugins/sdc/tests/get_clocks/get_clocks.tcl b/yosys-plugins/sdc/tests/get_clocks/get_clocks.tcl
new file mode 100644
index 000000000..71b3079da
--- /dev/null
+++ b/yosys-plugins/sdc/tests/get_clocks/get_clocks.tcl
@@ -0,0 +1,35 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+if { [info procs get_nets] == {} } { plugin -i design_introspection }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+#synth_xilinx
+
+# Read the design's timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write the clocks to file
+set fh [open [test_output_path "get_clocks.txt"] w]
+
+puts $fh [get_clocks]
+
+puts $fh [get_clocks -include_generated_clocks]
+
+puts $fh [get_clocks -include_generated_clocks clk2]
+
+puts $fh [get_clocks -of [get_nets clk_int_1 clk1] -include_generated_clocks clk_int_1]
+
+puts $fh [get_clocks -of [get_nets]]
+
+puts $fh [get_clocks -of [concat [get_nets clk2] [get_nets clk_int_1 clk]]]
+
+close $fh
diff --git a/yosys-plugins/sdc/tests/get_clocks/get_clocks.v b/yosys-plugins/sdc/tests/get_clocks/get_clocks.v
new file mode 100644
index 000000000..4f9211791
--- /dev/null
+++ b/yosys-plugins/sdc/tests/get_clocks/get_clocks.v
@@ -0,0 +1,94 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  reg [1:0] cnt2 = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_inst (
+      .I(clk),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+  );
+
+  wire main_clkout0_bufg;
+  BUFG bufg (.I(main_clkout0), .O(main_clkout0_bufg));
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  always @(posedge main_clkout0_bufg) begin
+    cnt2 <= cnt2 + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[2:0] = {cnt2[0], cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/period_check/period_check.tcl b/yosys-plugins/sdc/tests/period_check/period_check.tcl
new file mode 100644
index 000000000..01101aed8
--- /dev/null
+++ b/yosys-plugins/sdc/tests/period_check/period_check.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "period_check.sdc"]
diff --git a/yosys-plugins/sdc/tests/period_check/period_check.v b/yosys-plugins/sdc/tests/period_check/period_check.v
new file mode 100644
index 000000000..64f4af5d7
--- /dev/null
+++ b/yosys-plugins/sdc/tests/period_check/period_check.v
@@ -0,0 +1,75 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* CLOCK_SIGNAL = "yes", WAVEFORM = "0 5" *)
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/period_format_check/period_format_check.tcl b/yosys-plugins/sdc/tests/period_format_check/period_format_check.tcl
new file mode 100644
index 000000000..ea0ea3146
--- /dev/null
+++ b/yosys-plugins/sdc/tests/period_format_check/period_format_check.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "period_format_check.sdc"]
diff --git a/yosys-plugins/sdc/tests/period_format_check/period_format_check.v b/yosys-plugins/sdc/tests/period_format_check/period_format_check.v
new file mode 100644
index 000000000..5ed26b7d6
--- /dev/null
+++ b/yosys-plugins/sdc/tests/period_format_check/period_format_check.v
@@ -0,0 +1,75 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* CLOCK_SIGNAL = "yes", PERIOD = "bad value", WAVEFORM = "0 5" *)
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll/pll.golden.sdc b/yosys-plugins/sdc/tests/pll/pll.golden.sdc
new file mode 100644
index 000000000..dc34210ed
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll/pll.golden.sdc
@@ -0,0 +1,3 @@
+create_clock -period 10 -waveform {2.5 7.5} main_clkout0
+create_clock -period 2.5 -waveform {0 1.25} main_clkout1
+create_clock -period 5 -waveform {1.25 3.75} main_clkout2
diff --git a/yosys-plugins/sdc/tests/pll/pll.input.sdc b/yosys-plugins/sdc/tests/pll/pll.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll/pll.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll/pll.tcl b/yosys-plugins/sdc/tests/pll/pll.tcl
new file mode 100644
index 000000000..c7318de65
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll/pll.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "pll.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll/pll.v b/yosys-plugins/sdc/tests/pll/pll.v
new file mode 100644
index 000000000..41e38a2af
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll/pll.v
@@ -0,0 +1,121 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input cpu_reset,
+    input data_in,
+    output [5:0] data_out
+);
+
+  wire [5:0] data_out;
+  wire builder_pll_fb;
+  wire fdce_0_out, fdce_1_out;
+  wire main_locked;
+
+  wire clk_ibuf;
+  IBUF ibuf_clk(.I(clk), .O(clk_ibuf));
+
+  wire clk_bufg;
+  BUFG bufg_clk(.I(clk_ibuf), .O(clk_bufg));
+
+  FDCE FDCE_0 (
+      .D  (data_in),
+      .C  (clk_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (fdce_0_out)
+  );
+
+  FDCE FDCE_1 (
+      .D  (fdce_0_out),
+      .C  (clk_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[0])
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .CLKOUT1_DIVIDE(2'd3),
+      .CLKOUT1_PHASE(0.0),
+      .CLKOUT2_DIVIDE(3'd6),
+      .CLKOUT2_PHASE(90.0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .CLKOUT2(main_clkout2),
+      .LOCKED(main_locked)
+  );
+
+  wire main_clkout0_bufg;
+  wire main_clkout1_bufg;
+  wire main_clkout2_bufg;
+
+  BUFG bufg_clkout0 (.I(main_clkout0), .O(main_clkout0_bufg));
+  BUFG bufg_clkout1 (.I(main_clkout1), .O(main_clkout1_bufg));
+  BUFG bufg_clkout2 (.I(main_clkout2), .O(main_clkout2_bufg));
+
+  FDCE FDCE_PLLx1_PH90 (
+      .D  (data_in),
+      .C  (main_clkout0_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[1])
+  );
+
+  FDCE FDCE_PLLx4_PH0_0 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[2])
+  );
+
+  FDCE FDCE_PLLx4_PH0_1 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[3])
+  );
+
+  FDCE FDCE_PLLx4_PH0_2 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[4])
+  );
+
+  FDCE FDCE_PLLx2_PH90_0 (
+      .D  (data_in),
+      .C  (main_clkout2_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[5])
+  );
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.golden.sdc b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.golden.sdc
new file mode 100644
index 000000000..597a2ef14
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.golden.sdc
@@ -0,0 +1,3 @@
+create_clock -period 9.99999 -waveform {0 5} main_clkout_x1
+create_clock -period 5 -waveform {-2.5 0} main_clkout_x2
+create_clock -period 2.5 -waveform {-1.875 -0.624999} main_clkout_x4
diff --git a/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.input.sdc b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.tcl b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.tcl
new file mode 100644
index 000000000..87b05cd63
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "pll_approx_equal.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.v b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.v
new file mode 100644
index 000000000..1befb828a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_approx_equal/pll_approx_equal.v
@@ -0,0 +1,107 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input cpu_reset,
+    input data_in,
+    output [5:0] data_out
+);
+
+  wire [5:0] data_out;
+  wire builder_pll_fb;
+  wire fdce_0_out, fdce_1_out;
+  wire main_locked;
+
+  FDCE FDCE_0 (
+      .D  (data_in),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (fdce_0_out)
+  );
+
+  FDCE FDCE_1 (
+      .D  (fdce_0_out),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[0])
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKFBOUT_PHASE(90.0),
+      .CLKIN1_PERIOD(9.99999),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .CLKOUT1_DIVIDE(3'd6),
+      .CLKOUT1_PHASE(0.0),
+      .CLKOUT2_DIVIDE(2'd3),
+      .CLKOUT2_PHASE(90.0),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout_x1),
+      .CLKOUT1(main_clkout_x2),
+      .CLKOUT2(main_clkout_x4),
+      .LOCKED(main_locked)
+  );
+
+  FDCE FDCE_PLLx1_PH90 (
+      .D  (data_in),
+      .C  (main_clkout_x1),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[1])
+  );
+
+  FDCE FDCE_PLLx4_PH0_0 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[2])
+  );
+
+  FDCE FDCE_PLLx4_PH0_1 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[3])
+  );
+
+  FDCE FDCE_PLLx4_PH0_2 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[4])
+  );
+
+  FDCE FDCE_PLLx2_PH90_0 (
+      .D  (data_in),
+      .C  (main_clkout_x4),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[5])
+  );
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.golden.sdc b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.golden.sdc
new file mode 100644
index 000000000..66658210a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.golden.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} main_clkout0
diff --git a/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.input.sdc b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.tcl b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.tcl
new file mode 100644
index 000000000..de162b7a1
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "pll_dangling_wires.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.v b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.v
new file mode 100644
index 000000000..4db1d892a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_dangling_wires/pll_dangling_wires.v
@@ -0,0 +1,57 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input  clk,
+    input  cpu_reset,
+    input  data_in,
+    output data_out
+);
+
+  wire data_out;
+  wire builder_pll_fb;
+  wire main_locked;
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(0.0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .CLKOUT2(main_clkout2),
+      .CLKOUT3(main_clkout3),
+      .CLKOUT4(main_clkout4),
+      .LOCKED(main_locked)
+  );
+
+  FDCE FDCE_PLLx1_PH0 (
+      .D  (data_in),
+      .C  (main_clkout0),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out)
+  );
+
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll_div/pll_div.golden.sdc b/yosys-plugins/sdc/tests/pll_div/pll_div.golden.sdc
new file mode 100644
index 000000000..72b451355
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_div/pll_div.golden.sdc
@@ -0,0 +1,3 @@
+create_clock -period 20 -waveform {5 15} main_clkout0
+create_clock -period 5 -waveform {0 2.5} main_clkout1
+create_clock -period 10 -waveform {2.5 7.5} main_clkout2
diff --git a/yosys-plugins/sdc/tests/pll_div/pll_div.input.sdc b/yosys-plugins/sdc/tests/pll_div/pll_div.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_div/pll_div.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll_div/pll_div.tcl b/yosys-plugins/sdc/tests/pll_div/pll_div.tcl
new file mode 100644
index 000000000..a556779c3
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_div/pll_div.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "pll_div.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll_div/pll_div.v b/yosys-plugins/sdc/tests/pll_div/pll_div.v
new file mode 100644
index 000000000..00e83a184
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_div/pll_div.v
@@ -0,0 +1,107 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input cpu_reset,
+    input data_in,
+    output [5:0] data_out
+);
+
+  wire [5:0] data_out;
+  wire builder_pll_fb;
+  wire fdce_0_out, fdce_1_out;
+  wire main_locked;
+
+  FDCE FDCE_0 (
+      .D  (data_in),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (fdce_0_out)
+  );
+
+  FDCE FDCE_1 (
+      .D  (fdce_0_out),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[0])
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .CLKOUT1_DIVIDE(2'd3),
+      .CLKOUT1_PHASE(0.0),
+      .CLKOUT2_DIVIDE(3'd6),
+      .CLKOUT2_PHASE(90.0),
+      .DIVCLK_DIVIDE(2'd2),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .CLKOUT2(main_clkout2),
+      .LOCKED(main_locked)
+  );
+
+  FDCE FDCE_PLLx1_PH90 (
+      .D  (data_in),
+      .C  (main_clkout0),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[1])
+  );
+
+  FDCE FDCE_PLLx4_PH0_0 (
+      .D  (data_in),
+      .C  (main_clkout1),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[2])
+  );
+
+  FDCE FDCE_PLLx4_PH0_1 (
+      .D  (data_in),
+      .C  (main_clkout1),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[3])
+  );
+
+  FDCE FDCE_PLLx4_PH0_2 (
+      .D  (data_in),
+      .C  (main_clkout1),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[4])
+  );
+
+  FDCE FDCE_PLLx2_PH90_0 (
+      .D  (data_in),
+      .C  (main_clkout2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[5])
+  );
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.golden.sdc b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.golden.sdc
new file mode 100644
index 000000000..5dc709178
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.golden.sdc
@@ -0,0 +1,3 @@
+create_clock -period 10 -waveform {0 5} main_clkout_x1
+create_clock -period 5 -waveform {-2.5 0} main_clkout_x2
+create_clock -period 2.5 -waveform {-1.875 -0.625} main_clkout_x4
diff --git a/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.input.sdc b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.tcl b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.tcl
new file mode 100644
index 000000000..c32663080
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "pll_fbout_phase.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.v b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.v
new file mode 100644
index 000000000..036b1a8b0
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_fbout_phase/pll_fbout_phase.v
@@ -0,0 +1,107 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input cpu_reset,
+    input data_in,
+    output [5:0] data_out
+);
+
+  wire [5:0] data_out;
+  wire builder_pll_fb;
+  wire fdce_0_out, fdce_1_out;
+  wire main_locked;
+
+  FDCE FDCE_0 (
+      .D  (data_in),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (fdce_0_out)
+  );
+
+  FDCE FDCE_1 (
+      .D  (fdce_0_out),
+      .C  (clk),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[0])
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKFBOUT_PHASE(90.0),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .CLKOUT1_DIVIDE(3'd6),
+      .CLKOUT1_PHASE(0.0),
+      .CLKOUT2_DIVIDE(2'd3),
+      .CLKOUT2_PHASE(90.0),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout_x1),
+      .CLKOUT1(main_clkout_x2),
+      .CLKOUT2(main_clkout_x4),
+      .LOCKED(main_locked)
+  );
+
+  FDCE FDCE_PLLx1_PH90 (
+      .D  (data_in),
+      .C  (main_clkout_x1),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[1])
+  );
+
+  FDCE FDCE_PLLx4_PH0_0 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[2])
+  );
+
+  FDCE FDCE_PLLx4_PH0_1 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[3])
+  );
+
+  FDCE FDCE_PLLx4_PH0_2 (
+      .D  (data_in),
+      .C  (main_clkout_x2),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[4])
+  );
+
+  FDCE FDCE_PLLx2_PH90_0 (
+      .D  (data_in),
+      .C  (main_clkout_x4),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[5])
+  );
+endmodule
diff --git a/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.golden.sdc b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.golden.sdc
new file mode 100644
index 000000000..4bad8095a
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.golden.sdc
@@ -0,0 +1,8 @@
+create_clock -period 10 -waveform {0 5} clk_bufg
+create_clock -period 10 -waveform {0 5} clk_ibuf
+create_clock -period 10 -waveform {2.5 7.5} main_clkout0
+create_clock -period 10 -waveform {2.5 7.5} main_clkout0_bufg
+create_clock -period 2.5 -waveform {0 1.25} main_clkout1
+create_clock -period 2.5 -waveform {0 1.25} main_clkout1_bufg
+create_clock -period 5 -waveform {1.25 3.75} main_clkout2
+create_clock -period 5 -waveform {1.25 3.75} main_clkout2_bufg
diff --git a/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.input.sdc b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.input.sdc
new file mode 100644
index 000000000..00354d767
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.input.sdc
@@ -0,0 +1 @@
+create_clock -period 10 -waveform {0 5} clk
diff --git a/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.tcl b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.tcl
new file mode 100644
index 000000000..6f8d32057
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.tcl
@@ -0,0 +1,20 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -noclkbuf -run prepare:check
+
+# Read the design timing constraints
+read_sdc $::env(DESIGN_TOP).input.sdc
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc -include_propagated_clocks [test_output_path "pll_propagated.sdc"]
diff --git a/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.v b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.v
new file mode 100644
index 000000000..41e38a2af
--- /dev/null
+++ b/yosys-plugins/sdc/tests/pll_propagated/pll_propagated.v
@@ -0,0 +1,121 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    input cpu_reset,
+    input data_in,
+    output [5:0] data_out
+);
+
+  wire [5:0] data_out;
+  wire builder_pll_fb;
+  wire fdce_0_out, fdce_1_out;
+  wire main_locked;
+
+  wire clk_ibuf;
+  IBUF ibuf_clk(.I(clk), .O(clk_ibuf));
+
+  wire clk_bufg;
+  BUFG bufg_clk(.I(clk_ibuf), .O(clk_bufg));
+
+  FDCE FDCE_0 (
+      .D  (data_in),
+      .C  (clk_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (fdce_0_out)
+  );
+
+  FDCE FDCE_1 (
+      .D  (fdce_0_out),
+      .C  (clk_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[0])
+  );
+
+  PLLE2_ADV #(
+      .CLKFBOUT_MULT(4'd12),
+      .CLKIN1_PERIOD(10.0),
+      .CLKOUT0_DIVIDE(4'd12),
+      .CLKOUT0_PHASE(90.0),
+      .CLKOUT1_DIVIDE(2'd3),
+      .CLKOUT1_PHASE(0.0),
+      .CLKOUT2_DIVIDE(3'd6),
+      .CLKOUT2_PHASE(90.0),
+      .DIVCLK_DIVIDE(1'd1),
+      .REF_JITTER1(0.01),
+      .STARTUP_WAIT("FALSE")
+  ) PLLE2_ADV (
+      .CLKFBIN(builder_pll_fb),
+      .CLKIN1(clk),
+      .RST(cpu_reset),
+      .CLKFBOUT(builder_pll_fb),
+      .CLKOUT0(main_clkout0),
+      .CLKOUT1(main_clkout1),
+      .CLKOUT2(main_clkout2),
+      .LOCKED(main_locked)
+  );
+
+  wire main_clkout0_bufg;
+  wire main_clkout1_bufg;
+  wire main_clkout2_bufg;
+
+  BUFG bufg_clkout0 (.I(main_clkout0), .O(main_clkout0_bufg));
+  BUFG bufg_clkout1 (.I(main_clkout1), .O(main_clkout1_bufg));
+  BUFG bufg_clkout2 (.I(main_clkout2), .O(main_clkout2_bufg));
+
+  FDCE FDCE_PLLx1_PH90 (
+      .D  (data_in),
+      .C  (main_clkout0_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[1])
+  );
+
+  FDCE FDCE_PLLx4_PH0_0 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[2])
+  );
+
+  FDCE FDCE_PLLx4_PH0_1 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[3])
+  );
+
+  FDCE FDCE_PLLx4_PH0_2 (
+      .D  (data_in),
+      .C  (main_clkout1_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[4])
+  );
+
+  FDCE FDCE_PLLx2_PH90_0 (
+      .D  (data_in),
+      .C  (main_clkout2_bufg),
+      .CE (1'b1),
+      .CLR(1'b0),
+      .Q  (data_out[5])
+  );
+endmodule
diff --git a/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.tcl b/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.tcl
new file mode 100644
index 000000000..a04e2f348
--- /dev/null
+++ b/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.tcl
@@ -0,0 +1,18 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+synth_xilinx
+create_clock -period 10 clk
+propagate_clocks
+
+# Clean processes before writing JSON.
+yosys proc
+
+write_sdc [test_output_path "restore_from_json_1.sdc"]
+write_json [test_output_path "restore_from_json.json"]
+
+design -push
+read_json [test_output_path "restore_from_json.json"]
+write_sdc [test_output_path "restore_from_json_2.sdc"]
diff --git a/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.v b/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.v
new file mode 100644
index 000000000..0ba4dead5
--- /dev/null
+++ b/yosys-plugins/sdc/tests/restore_from_json/restore_from_json.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input  clk,
+    input  i,
+    output o
+);
+
+  reg [0:0] outff = 0;
+
+  assign o = outff;
+
+  always @(posedge clk) begin
+    outff <= i;
+  end
+
+endmodule
diff --git a/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.golden.sdc b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.golden.sdc
new file mode 100644
index 000000000..162e4d077
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.golden.sdc
@@ -0,0 +1,4 @@
+create_clock_groups -group clk1 clk2 
+create_clock_groups -group clk3 clk4 -group clk11 clk12 -group clk13 clk14 -asynchronous
+create_clock_groups -group clk7 clk8 -group clk9 clk10 -physically_exclusive
+create_clock_groups -group clk5 clk6 -logically_exclusive
diff --git a/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.tcl b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.tcl
new file mode 100644
index 000000000..1994806cb
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.tcl
@@ -0,0 +1,15 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+set_clock_groups -group clk1 clk2
+set_clock_groups -asynchronous -group clk3 clk4
+set_clock_groups -group clk5 clk6 -logically_exclusive
+set_clock_groups -group clk7 clk8 -physically_exclusive -group clk9 clk10
+set_clock_groups -quiet -group clk11 clk12 -asynchronous -group clk13 clk14
+
+write_sdc [test_output_path "set_clock_groups.sdc"]
diff --git a/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.v b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.v
new file mode 100644
index 000000000..d8a6411db
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_clock_groups/set_clock_groups.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/sdc/tests/set_false_path/set_false_path.golden.sdc b/yosys-plugins/sdc/tests/set_false_path/set_false_path.golden.sdc
new file mode 100644
index 000000000..b90bd9b31
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_false_path/set_false_path.golden.sdc
@@ -0,0 +1,4 @@
+set_false_path -to inter_wire
+set_false_path -from clk
+set_false_path -from clk -to bottom_inst.I
+set_false_path -through bottom_inst.I
diff --git a/yosys-plugins/sdc/tests/set_false_path/set_false_path.tcl b/yosys-plugins/sdc/tests/set_false_path/set_false_path.tcl
new file mode 100644
index 000000000..e755e7e39
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_false_path/set_false_path.tcl
@@ -0,0 +1,21 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+# -to inter_wire net
+set_false_path -to inter_wire
+
+# -from clk net (quiet)
+set_false_path -quiet -from clk
+
+# -from clk to bottom_inst/I
+set_false_path -from clk -to bottom_inst.I
+
+# -through bottom_inst/I
+set_false_path -through bottom_inst.I
+
+write_sdc [test_output_path "set_false_path.sdc"]
diff --git a/yosys-plugins/sdc/tests/set_false_path/set_false_path.v b/yosys-plugins/sdc/tests/set_false_path/set_false_path.v
new file mode 100644
index 000000000..d8a6411db
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_false_path/set_false_path.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.golden.sdc b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.golden.sdc
new file mode 100644
index 000000000..02ed95df6
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.golden.sdc
@@ -0,0 +1,3 @@
+set_max_delay 1 -to inter_wire
+set_max_delay 2 -from clk
+set_max_delay 3 -from clk -to bottom_inst.I
diff --git a/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.tcl b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.tcl
new file mode 100644
index 000000000..4957485c1
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.tcl
@@ -0,0 +1,18 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+# -to inter_wire net
+set_max_delay 1 -to inter_wire
+
+# -from clk net (quiet)
+set_max_delay 2 -quiet -from clk
+
+# -from clk to bottom_inst/I
+set_max_delay 3 -from clk -to bottom_inst.I
+
+write_sdc [test_output_path "set_max_delay.sdc"]
diff --git a/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.v b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.v
new file mode 100644
index 000000000..d8a6411db
--- /dev/null
+++ b/yosys-plugins/sdc/tests/set_max_delay/set_max_delay.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* async_reg = "true", mr_ff = "true", dont_touch = "true" *) input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/sdc/tests/waveform_check/waveform_check.tcl b/yosys-plugins/sdc/tests/waveform_check/waveform_check.tcl
new file mode 100644
index 000000000..63bbe295f
--- /dev/null
+++ b/yosys-plugins/sdc/tests/waveform_check/waveform_check.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_sdc] == {} } { plugin -i sdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog -specify -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+hierarchy -check -auto-top
+# Start flow after library reading
+synth_xilinx -flatten -abc9 -nosrl -nodsp -iopad -run prepare:check
+
+# Propagate the clocks
+propagate_clocks
+
+# Write out the SDC file after the clock propagation step
+write_sdc [test_output_path "waveform_check.sdc"]
diff --git a/yosys-plugins/sdc/tests/waveform_check/waveform_check.v b/yosys-plugins/sdc/tests/waveform_check/waveform_check.v
new file mode 100644
index 000000000..c647225e1
--- /dev/null
+++ b/yosys-plugins/sdc/tests/waveform_check/waveform_check.v
@@ -0,0 +1,75 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    (* CLOCK_SIGNAL = "yes", PERIOD = "10", WAVEFORM = "bad value" *)
+    input clk,
+    input clk2,
+    input [1:0] in,
+    output [5:0] out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int_1, clk_int_2;
+  IBUF ibuf_proxy (
+      .I(clk),
+      .O(ibuf_proxy_out)
+  );
+  IBUF ibuf_inst (
+      .I(ibuf_proxy_out),
+      .O(ibuf_out)
+  );
+  assign clk_int_1 = ibuf_out;
+  assign clk_int_2 = clk_int_1;
+
+  always @(posedge clk_int_2) begin
+    cnt <= cnt + 1;
+  end
+
+  middle middle_inst_1 (
+      .clk(ibuf_out),
+      .out(out[2])
+  );
+  middle middle_inst_2 (
+      .clk(clk_int_1),
+      .out(out[3])
+  );
+  middle middle_inst_3 (
+      .clk(clk_int_2),
+      .out(out[4])
+  );
+  middle middle_inst_4 (
+      .clk(clk2),
+      .out(out[5])
+  );
+
+  assign out[1:0] = {cnt[0], in[0]};
+endmodule
+
+module middle (
+    input  clk,
+    output out
+);
+
+  reg [1:0] cnt = 0;
+  wire clk_int;
+  assign clk_int = clk;
+  always @(posedge clk_int) begin
+    cnt <= cnt + 1;
+  end
+
+  assign out = cnt[0];
+endmodule
diff --git a/yosys-plugins/systemverilog/Makefile b/yosys-plugins/systemverilog/Makefile
new file mode 100644
index 000000000..1b162be0b
--- /dev/null
+++ b/yosys-plugins/systemverilog/Makefile
@@ -0,0 +1,37 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = systemverilog
+SOURCES = UhdmAst.cc \
+	  uhdmastfrontend.cc \
+	  uhdmcommonfrontend.cc \
+	  uhdmsurelogastfrontend.cc \
+	  uhdmastreport.cc
+
+# Directory to search for Surelog and UHDM libraries
+UHDM_INSTALL_DIR ?= /usr/local
+
+include ../Makefile_plugin.common
+
+CPPFLAGS += -std=c++17 -Wall -W -Wextra \
+              -Wno-deprecated-declarations \
+              -Wno-unused-parameter \
+              -I${UHDM_INSTALL_DIR}/include \
+	      -I${UHDM_INSTALL_DIR}/include/Surelog
+
+CXXFLAGS += -Wno-unused-parameter
+LDFLAGS += -L${UHDM_INSTALL_DIR}/lib/uhdm -L${UHDM_INSTALL_DIR}/lib/surelog -L${UHDM_INSTALL_DIR}/lib -L${UHDM_INSTALL_DIR}/lib64/uhdm -L${UHDM_INSTALL_DIR}/lib64/surelog -L${UHDM_INSTALL_DIR}/lib64
+LDLIBS += -Wl,--whole-archive -luhdm -Wl,--no-whole-archive -lsurelog -lantlr4-runtime -lflatbuffers -lcapnp -lkj -ldl -lutil -lm -lrt -lpthread
diff --git a/yosys-plugins/systemverilog/README.md b/yosys-plugins/systemverilog/README.md
new file mode 100644
index 000000000..cdd2edd48
--- /dev/null
+++ b/yosys-plugins/systemverilog/README.md
@@ -0,0 +1,117 @@
+# SystemVerilog Plugin
+
+Reads SystemVerilog and UHDM files and processes them into Yosys AST.
+
+The plugin adds the following commands:
+
+* `read_systemverilog`
+* `read_uhdm`
+
+A more detailed help on the supported commands can be obtained by running `help <command_name>` in Yosys.
+
+Please see the dedicated [integration repository](https://github.com/antmicro/yosys-uhdm-plugin-integration) which contains more information about installation and usage of this plugin.
+This repository also runs dedicated CI pipelines that perform extensive testing of this plugin.
+
+## Installation
+
+A pre-built binary can be downloaded from the [release page](https://github.com/antmicro/yosys-uhdm-plugin-integration/releases).
+The release archive contains an installation script that detects Yosys installation and installs the plugin.
+
+To build from sources please refer to the [integration repository](https://github.com/antmicro/yosys-uhdm-plugin-integration).
+
+## Usage
+
+Usage of the plugin is very simple.
+
+This paragraph describes the synthesis process given the following `counter.sv` file:
+
+```
+module top (
+  input clk,
+  output [3:0] led
+);
+  localparam BITS = 4;
+  localparam LOG2DELAY = 22;
+
+  wire bufg;
+  BUFG bufgctrl (
+      .I(clk),
+      .O(bufg)
+  );
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+  always @(posedge bufg) begin
+    counter <= counter + 1;
+  end
+  assign led[3:0] = counter >> LOG2DELAY;
+endmodule
+```
+
+To load the plugin, execute `plugin -i systemverilog`.
+Then to load SystemVerilog sources, execute `read_systemverilog`.
+The rest of the flow is exactly the same as without the plugin.
+
+To synthesize the `counter.sv` file:
+
+```
+yosys> plugin -i systemverilog
+yosys> read_systemverilog  counter.v
+1. Executing Verilog with UHDM frontend.
+[INF:CM0023] Creating log file ./slpp_all/surelog.log.
+[WRN:PA0205] counter.v:1: No timescale set for "top".
+[INF:CP0300] Compilation...
+[INF:CP0303] counter.v:1: Compile module "work@top".
+(...)
+Generating RTLIL representation for module `\top'.
+
+yosys> synth_xilinx
+
+2. Executing SYNTH_XILINX pass.
+
+(...)
+
+3.50. Printing statistics.
+
+=== top ===
+
+   Number of wires:                 10
+   Number of wire bits:            167
+   Number of public wires:           4
+   Number of public wire bits:      32
+   Number of memories:               0
+   Number of memory bits:            0
+   Number of processes:              0
+   Number of cells:                 40
+     BUFG                            1
+     CARRY4                          7
+     FDRE                           26
+     IBUF                            1
+     INV                             1
+     OBUF                            4
+
+   Estimated number of LCs:          0
+
+3.51. Executing CHECK pass (checking for obvious problems).
+Checking module top...
+Found and reported 0 problems.
+
+yosys> write_edif counter.edif
+
+4. Executing EDIF backend.
+
+```
+As a result we get a `counter.edif` file that can be further processed to get the bitstream.
+
+### Parsing multiple files
+When parsing multiple files you can either pass them together to the `read_systemverilog` command
+or read them one by one using `-defer` flag. In the latter case, you will need to call 
+`readsystemverilog -link` after processing all files to elaborate them. An example flow would
+look like below:
+```
+plugin -i systemverilog
+# Read each file separately
+read_systemverilog -defer dut.sv
+read_systemverilog -defer top.sv
+# Finish reading files, elaborate the design
+read_systemverilog -link
+# Continue Yosys flow...
+```
diff --git a/yosys-plugins/systemverilog/UhdmAst.cc b/yosys-plugins/systemverilog/UhdmAst.cc
new file mode 100644
index 000000000..6580d0d69
--- /dev/null
+++ b/yosys-plugins/systemverilog/UhdmAst.cc
@@ -0,0 +1,4342 @@
+#include <algorithm>
+#include <cstring>
+#include <functional>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include "UhdmAst.h"
+#include "frontends/ast/ast.h"
+#include "libs/sha1/sha1.h"
+
+// UHDM
+#include <uhdm/uhdm.h>
+#include <uhdm/vpi_user.h>
+
+YOSYS_NAMESPACE_BEGIN
+
+/*static*/ const IdString &UhdmAst::partial()
+{
+    static const IdString id("\\partial");
+    return id;
+}
+/*static*/ const IdString &UhdmAst::packed_ranges()
+{
+    static const IdString id("\\packed_ranges");
+    return id;
+}
+/*static*/ const IdString &UhdmAst::unpacked_ranges()
+{
+    static const IdString id("\\unpacked_ranges");
+    return id;
+}
+/*static*/ const IdString &UhdmAst::force_convert()
+{
+    static const IdString id("\\force_convert");
+    return id;
+}
+/*static*/ const IdString &UhdmAst::is_imported()
+{
+    static const IdString id("\\is_imported");
+    return id;
+}
+
+static void sanitize_symbol_name(std::string &name)
+{
+    if (!name.empty()) {
+        auto pos = name.find_last_of('@');
+        name = name.substr(pos + 1);
+        // symbol names must begin with '\'
+        name.insert(0, "\\");
+    }
+}
+
+static std::string get_name(vpiHandle obj_h, bool prefer_full_name = false)
+{
+    auto first_check = prefer_full_name ? vpiFullName : vpiName;
+    auto last_check = prefer_full_name ? vpiName : vpiFullName;
+    std::string name;
+    if (auto s = vpi_get_str(first_check, obj_h)) {
+        name = s;
+    } else if (auto s = vpi_get_str(vpiDefName, obj_h)) {
+        name = s;
+    } else if (auto s = vpi_get_str(last_check, obj_h)) {
+        name = s;
+    }
+    if (name.rfind('.') != std::string::npos) {
+        name = name.substr(name.rfind('.') + 1);
+    }
+    sanitize_symbol_name(name);
+    return name;
+}
+
+static std::string strip_package_name(std::string name)
+{
+    auto sep_index = name.find("::");
+    if (sep_index != string::npos) {
+        name = name.substr(sep_index + 1);
+        name[0] = '\\';
+    }
+    return name;
+}
+
+static std::string get_object_name(vpiHandle obj_h, const std::vector<int> &name_fields = {vpiName})
+{
+    std::string objectName;
+    for (auto name : name_fields) {
+        if (auto s = vpi_get_str(name, obj_h)) {
+            objectName = s;
+            sanitize_symbol_name(objectName);
+            break;
+        }
+    }
+    return objectName;
+}
+
+static AST::AstNode *make_range(int left, int right, bool is_signed = false)
+{
+    // generate a pre-validated range node for a fixed signal range.
+    auto range = new AST::AstNode(AST::AST_RANGE);
+    range->range_left = left;
+    range->range_right = right;
+    range->range_valid = true;
+    range->children.push_back(AST::AstNode::mkconst_int(left, true));
+    range->children.push_back(AST::AstNode::mkconst_int(right, true));
+    range->is_signed = is_signed;
+    return range;
+}
+
+static void copy_packed_unpacked_attribute(AST::AstNode *from, AST::AstNode *to)
+{
+    if (!to->attributes.count(UhdmAst::packed_ranges()))
+        to->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+    if (!to->attributes.count(UhdmAst::unpacked_ranges()))
+        to->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+    if (from->attributes.count(UhdmAst::packed_ranges())) {
+        for (auto r : from->attributes[UhdmAst::packed_ranges()]->children) {
+            to->attributes[UhdmAst::packed_ranges()]->children.push_back(r->clone());
+        }
+    }
+    if (from->attributes.count(UhdmAst::unpacked_ranges())) {
+        for (auto r : from->attributes[UhdmAst::unpacked_ranges()]->children) {
+            to->attributes[UhdmAst::unpacked_ranges()]->children.push_back(r->clone());
+        }
+    }
+}
+
+#include "UhdmAstUpstream.cc"
+
+static int get_max_offset_struct(AST::AstNode *node)
+{
+    // get the width from the MS member in the struct
+    // as members are laid out from left to right in the packed wire
+    log_assert(node->type == AST::AST_STRUCT || node->type == AST::AST_UNION);
+    while (node->range_left < 0) {
+        node = node->children[0];
+    }
+    return node->range_left;
+}
+
+static void visitEachDescendant(AST::AstNode *node, const std::function<void(AST::AstNode *)> &f)
+{
+    for (auto child : node->children) {
+        f(child);
+        visitEachDescendant(child, f);
+    }
+}
+
+static void add_multirange_wire(AST::AstNode *node, std::vector<AST::AstNode *> packed_ranges, std::vector<AST::AstNode *> unpacked_ranges,
+                                bool reverse = true)
+{
+    node->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+    if (!packed_ranges.empty()) {
+        if (reverse)
+            std::reverse(packed_ranges.begin(), packed_ranges.end());
+        node->attributes[UhdmAst::packed_ranges()]->children.insert(node->attributes[UhdmAst::packed_ranges()]->children.end(), packed_ranges.begin(),
+                                                                    packed_ranges.end());
+    }
+
+    node->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+    if (!unpacked_ranges.empty()) {
+        if (reverse)
+            std::reverse(unpacked_ranges.begin(), unpacked_ranges.end());
+        node->attributes[UhdmAst::unpacked_ranges()]->children.insert(node->attributes[UhdmAst::unpacked_ranges()]->children.end(),
+                                                                      unpacked_ranges.begin(), unpacked_ranges.end());
+    }
+}
+
+static size_t add_multirange_attribute(AST::AstNode *wire_node, const std::vector<AST::AstNode *> ranges)
+{
+    size_t size = 1;
+    for (size_t i = 0; i < ranges.size(); i++) {
+        log_assert(AST_INTERNAL::current_ast_mod);
+        if (ranges[i]->children.size() == 1) {
+            ranges[i]->children.push_back(ranges[i]->children[0]->clone());
+        }
+        while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
+        }
+        // this workaround case, where yosys doesn't follow id2ast and simplifies it to resolve constant
+        if (ranges[i]->children[0]->id2ast) {
+            while (ranges[i]->children[0]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
+            }
+        }
+        if (ranges[i]->children[1]->id2ast) {
+            while (ranges[i]->children[1]->id2ast->simplify(true, false, false, 1, -1, false, false)) {
+            }
+        }
+        while (ranges[i]->simplify(true, false, false, 1, -1, false, false)) {
+        }
+        log_assert(ranges[i]->children[0]->type == AST::AST_CONSTANT);
+        log_assert(ranges[i]->children[1]->type == AST::AST_CONSTANT);
+        if (wire_node->type != AST::AST_STRUCT_ITEM) {
+            wire_node->multirange_dimensions.push_back(min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer));
+            wire_node->multirange_swapped.push_back(ranges[i]->range_swapped);
+        }
+        auto elem_size = max(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer) -
+                         min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer) + 1;
+        if (wire_node->type != AST::AST_STRUCT_ITEM || (wire_node->type == AST::AST_STRUCT_ITEM && i == 0)) {
+            wire_node->multirange_dimensions.push_back(elem_size);
+        }
+        size *= elem_size;
+    }
+    return size;
+}
+
+static AST::AstNode *convert_range(AST::AstNode *id, const std::vector<AST::AstNode *> packed_ranges,
+                                   const std::vector<AST::AstNode *> unpacked_ranges, int i)
+{
+    log_assert(AST_INTERNAL::current_ast_mod);
+    log_assert(AST_INTERNAL::current_scope.count(id->str));
+    AST::AstNode *wire_node = AST_INTERNAL::current_scope[id->str];
+    log_assert(!wire_node->multirange_dimensions.empty());
+    int elem_size = 1;
+    std::vector<int> single_elem_size;
+    single_elem_size.push_back(elem_size);
+    for (size_t j = 0; (j + 1) < wire_node->multirange_dimensions.size(); j = j + 2) {
+        elem_size *= wire_node->multirange_dimensions[j + 1] - wire_node->multirange_dimensions[j];
+        single_elem_size.push_back(elem_size);
+    }
+    std::reverse(single_elem_size.begin(), single_elem_size.end());
+    log_assert(i < static_cast<int>(unpacked_ranges.size() + packed_ranges.size()));
+    log_assert(!id->children.empty());
+    AST::AstNode *result = nullptr;
+    // we want to start converting from the end
+    if (i < static_cast<int>(id->children.size()) - 1) {
+        result = convert_range(id, packed_ranges, unpacked_ranges, i + 1);
+    }
+    // special case, we want to select whole wire
+    if (id->children.size() == 0 && i == 0) {
+        result = make_range(single_elem_size[i] - 1, 0);
+    } else {
+        AST::AstNode *range_left = nullptr;
+        AST::AstNode *range_right = nullptr;
+        if (id->children[i]->children.size() == 2) {
+            range_left = id->children[i]->children[0]->clone();
+            range_right = id->children[i]->children[1]->clone();
+        } else {
+            range_left = id->children[i]->children[0]->clone();
+            range_right = id->children[i]->children[0]->clone();
+        }
+        if (!wire_node->multirange_swapped.empty()) {
+            bool is_swapped = wire_node->multirange_swapped[wire_node->multirange_swapped.size() - i - 1];
+            auto right_idx = wire_node->multirange_dimensions.size() - (i * 2) - 2;
+            if (is_swapped) {
+                auto left_idx = wire_node->multirange_dimensions.size() - (i * 2) - 1;
+                auto elem_size = wire_node->multirange_dimensions[left_idx] - wire_node->multirange_dimensions[right_idx];
+                range_left = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_left->clone());
+                range_right = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_right->clone());
+            } else if (wire_node->multirange_dimensions[right_idx] != 0) {
+                range_left =
+                  new AST::AstNode(AST::AST_SUB, range_left, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
+                range_right =
+                  new AST::AstNode(AST::AST_SUB, range_right, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
+            }
+        }
+        range_left =
+          new AST::AstNode(AST::AST_SUB,
+                           new AST::AstNode(AST::AST_MUL, new AST::AstNode(AST::AST_ADD, range_left->clone(), AST::AstNode::mkconst_int(1, false)),
+                                            AST::AstNode::mkconst_int(single_elem_size[i + 1], false)),
+                           AST::AstNode::mkconst_int(1, false));
+        range_right = new AST::AstNode(AST::AST_MUL, range_right->clone(), AST::AstNode::mkconst_int(single_elem_size[i + 1], false));
+        if (result) {
+            range_right = new AST::AstNode(AST::AST_ADD, range_right->clone(), result->children[1]->clone());
+            range_left = new AST::AstNode(AST::AST_SUB, new AST::AstNode(AST::AST_ADD, range_right->clone(), result->children[0]->clone()),
+                                          result->children[1]->clone());
+        }
+        result = new AST::AstNode(AST::AST_RANGE, range_left, range_right);
+    }
+    // return range from *current* selected range
+    // in the end, it results in whole selected range
+    id->basic_prep = true;
+    return result;
+}
+
+static void resolve_wiretype(AST::AstNode *wire_node)
+{
+    AST::AstNode *wiretype_node = nullptr;
+    if (!wire_node->children.empty()) {
+        if (wire_node->children[0]->type == AST::AST_WIRETYPE) {
+            wiretype_node = wire_node->children[0];
+        }
+    }
+    if (wire_node->children.size() > 1) {
+        if (wire_node->children[1]->type == AST::AST_WIRETYPE) {
+            wiretype_node = wire_node->children[1];
+        }
+    }
+    if (wiretype_node == nullptr)
+        return;
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    // First check if it has already defined ranges
+    if (wire_node->attributes.count(UhdmAst::packed_ranges())) {
+        for (auto r : wire_node->attributes[UhdmAst::packed_ranges()]->children) {
+            packed_ranges.push_back(r->clone());
+        }
+    }
+    if (wire_node->attributes.count(UhdmAst::unpacked_ranges())) {
+        for (auto r : wire_node->attributes[UhdmAst::unpacked_ranges()]->children) {
+            unpacked_ranges.push_back(r->clone());
+        }
+    }
+    AST::AstNode *wiretype_ast = nullptr;
+    log_assert(AST_INTERNAL::current_scope.count(wiretype_node->str));
+    wiretype_ast = AST_INTERNAL::current_scope[wiretype_node->str];
+    // we need to setup current top ast as this simplify
+    // needs to have access to all already definied ids
+    while (wire_node->simplify(true, false, false, 1, -1, false, false)) {
+    }
+    if (wiretype_ast->children[0]->type == AST::AST_STRUCT && wire_node->type == AST::AST_WIRE) {
+        auto struct_width = get_max_offset_struct(wiretype_ast->children[0]);
+        wire_node->range_left = struct_width;
+        wire_node->children[0]->range_left = struct_width;
+        wire_node->children[0]->children[0]->integer = struct_width;
+    }
+    if (wiretype_ast && wire_node->attributes.count(ID::wiretype)) {
+        log_assert(wiretype_ast->type == AST::AST_TYPEDEF);
+        wire_node->attributes[ID::wiretype]->id2ast = wiretype_ast->children[0];
+    }
+    if ((wire_node->children[0]->type == AST::AST_RANGE || (wire_node->children.size() > 1 && wire_node->children[1]->type == AST::AST_RANGE)) &&
+        wire_node->multirange_dimensions.empty()) {
+        if (wiretype_ast && !wiretype_ast->children.empty() && wiretype_ast->children[0]->attributes.count(UhdmAst::packed_ranges()) &&
+            wiretype_ast->children[0]->attributes.count(UhdmAst::unpacked_ranges())) {
+            for (auto r : wiretype_ast->children[0]->attributes[UhdmAst::packed_ranges()]->children) {
+                packed_ranges.push_back(r->clone());
+            }
+            for (auto r : wiretype_ast->children[0]->attributes[UhdmAst::unpacked_ranges()]->children) {
+                unpacked_ranges.push_back(r->clone());
+            }
+        } else {
+            if (wire_node->children[0]->type == AST::AST_RANGE)
+                packed_ranges.push_back(wire_node->children[0]);
+            else if (wire_node->children[1]->type == AST::AST_RANGE)
+                packed_ranges.push_back(wire_node->children[1]);
+            else
+                log_error("Unhandled case in resolve_wiretype!\n");
+        }
+        AST::AstNode *value = nullptr;
+        if (wire_node->children[0]->type != AST::AST_RANGE) {
+            value = wire_node->children[0]->clone();
+        }
+        wire_node->children.clear();
+        if (value)
+            wire_node->children.push_back(value);
+        wire_node->attributes[UhdmAst::packed_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+        if (!packed_ranges.empty()) {
+            std::reverse(packed_ranges.begin(), packed_ranges.end());
+            wire_node->attributes[UhdmAst::packed_ranges()]->children.insert(wire_node->attributes[UhdmAst::packed_ranges()]->children.end(),
+                                                                             packed_ranges.begin(), packed_ranges.end());
+        }
+
+        wire_node->attributes[UhdmAst::unpacked_ranges()] = AST::AstNode::mkconst_int(1, false, 1);
+        if (!unpacked_ranges.empty()) {
+            wire_node->attributes[UhdmAst::unpacked_ranges()]->children.insert(wire_node->attributes[UhdmAst::unpacked_ranges()]->children.end(),
+                                                                               unpacked_ranges.begin(), unpacked_ranges.end());
+        }
+    }
+}
+
+static void add_force_convert_attribute(AST::AstNode *wire_node, int val = 1)
+{
+    wire_node->attributes[UhdmAst::force_convert()] = AST::AstNode::mkconst_int(val, true);
+}
+
+static void check_memories(AST::AstNode *module_node)
+{
+    std::map<std::string, AST::AstNode *> memories;
+    visitEachDescendant(module_node, [&](AST::AstNode *node) {
+        if (node->str == "\\$readmemh") {
+            if (node->children.size() != 2 || node->children[1]->str.empty() || node->children[1]->type != AST::AST_IDENTIFIER) {
+                log_error("%s:%d: Wrong usage of '\\$readmemh'\n", node->filename.c_str(), node->location.first_line);
+            }
+            if (memories[node->children[1]->str])
+                add_force_convert_attribute(memories[node->children[1]->str], 0);
+        }
+        if (node->type == AST::AST_WIRE) {
+            const std::vector<AST::AstNode *> packed_ranges =
+              node->attributes.count(UhdmAst::packed_ranges()) ? node->attributes[UhdmAst::packed_ranges()]->children : std::vector<AST::AstNode *>();
+            const std::vector<AST::AstNode *> unpacked_ranges = node->attributes.count(UhdmAst::unpacked_ranges())
+                                                                  ? node->attributes[UhdmAst::unpacked_ranges()]->children
+                                                                  : std::vector<AST::AstNode *>();
+            if (packed_ranges.size() == 1 && unpacked_ranges.size() == 1) {
+                log_assert(!memories.count(node->str));
+                memories[node->str] = node;
+            }
+        }
+        if (node->type == AST::AST_IDENTIFIER && memories.count(node->str)) {
+            if (!memories[node->str]->attributes.count(UhdmAst::force_convert()) && node->children.size() == 0) {
+                add_force_convert_attribute(memories[node->str]);
+            }
+        }
+    });
+}
+
+// This function is workaround missing support for multirange (with n-ranges) packed/unpacked nodes
+// It converts multirange node to single-range node and translates access to this node
+// to correct range
+static void convert_packed_unpacked_range(AST::AstNode *wire_node)
+{
+    resolve_wiretype(wire_node);
+    const std::vector<AST::AstNode *> packed_ranges = wire_node->attributes.count(UhdmAst::packed_ranges())
+                                                        ? wire_node->attributes[UhdmAst::packed_ranges()]->children
+                                                        : std::vector<AST::AstNode *>();
+    const std::vector<AST::AstNode *> unpacked_ranges = wire_node->attributes.count(UhdmAst::unpacked_ranges())
+                                                          ? wire_node->attributes[UhdmAst::unpacked_ranges()]->children
+                                                          : std::vector<AST::AstNode *>();
+    if (packed_ranges.empty() && unpacked_ranges.empty()) {
+        wire_node->attributes.erase(UhdmAst::packed_ranges());
+        wire_node->attributes.erase(UhdmAst::unpacked_ranges());
+        wire_node->range_valid = true;
+        return;
+    }
+    size_t size = 1;
+    size_t packed_size = 1;
+    size_t unpacked_size = 1;
+    std::vector<AST::AstNode *> ranges;
+    bool convert_node = packed_ranges.size() > 1 || unpacked_ranges.size() > 1 || wire_node->attributes.count(ID::wiretype) ||
+                        wire_node->type == AST::AST_PARAMETER || wire_node->type == AST::AST_LOCALPARAM ||
+                        ((wire_node->is_input || wire_node->is_output) && ((packed_ranges.size() > 0 || unpacked_ranges.size() > 0))) ||
+                        (wire_node->attributes.count(UhdmAst::force_convert()) && wire_node->attributes[UhdmAst::force_convert()]->integer == 1);
+    // Convert only when atleast 1 of the ranges has more then 1 range
+    if (convert_node) {
+        if (wire_node->multirange_dimensions.empty()) {
+            packed_size = add_multirange_attribute(wire_node, packed_ranges);
+            unpacked_size = add_multirange_attribute(wire_node, unpacked_ranges);
+            size = packed_size * unpacked_size;
+            ranges.push_back(make_range(size - 1, 0));
+        }
+    } else {
+        for (auto r : packed_ranges) {
+            ranges.push_back(r->clone());
+        }
+        for (auto r : unpacked_ranges) {
+            ranges.push_back(r->clone());
+        }
+        // if there is only one packed and one unpacked range,
+        // and wire is not port wire, change type to AST_MEMORY
+        if (wire_node->type == AST::AST_WIRE && packed_ranges.size() == 1 && unpacked_ranges.size() == 1 && !wire_node->is_input &&
+            !wire_node->is_output) {
+            wire_node->type = AST::AST_MEMORY;
+        }
+    }
+
+    if (wire_node->type == AST::AST_STRUCT_ITEM || wire_node->type == AST::AST_STRUCT) {
+        wire_node->attributes.erase(UhdmAst::packed_ranges());
+        wire_node->attributes.erase(UhdmAst::unpacked_ranges());
+    }
+
+    // Insert new range
+    wire_node->children.insert(wire_node->children.end(), ranges.begin(), ranges.end());
+}
+
+static AST::AstNode *expand_dot(const AST::AstNode *current_struct, const AST::AstNode *search_node)
+{
+    AST::AstNode *current_struct_elem = nullptr;
+    auto search_str = search_node->str.find("\\") == 0 ? search_node->str.substr(1) : search_node->str;
+    auto struct_elem_it =
+      std::find_if(current_struct->children.begin(), current_struct->children.end(), [&](AST::AstNode *node) { return node->str == search_str; });
+    if (struct_elem_it == current_struct->children.end()) {
+        current_struct->dumpAst(NULL, "struct >");
+        log_error("Couldn't find search elem: %s in struct\n", search_str.c_str());
+    }
+    current_struct_elem = *struct_elem_it;
+
+    AST::AstNode *left = nullptr, *right = nullptr;
+    if (current_struct_elem->type == AST::AST_STRUCT_ITEM) {
+        left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true);
+        right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true);
+    } else if (current_struct_elem->type == AST::AST_STRUCT) {
+        // Struct can have multiple range, so to get size of 1 struct,
+        // we get left range for first children, and right range for last children
+        left = AST::AstNode::mkconst_int(current_struct_elem->children.front()->range_left, true);
+        right = AST::AstNode::mkconst_int(current_struct_elem->children.back()->range_right, true);
+    } else {
+        // Structs currently can only have AST_STRUCT or AST_STRUCT_ITEM
+        // so, it should never happen
+        log_error("Found %s elem in struct that is currently unsupported!\n", type2str(current_struct_elem->type).c_str());
+    }
+
+    auto elem_size =
+      new AST::AstNode(AST::AST_ADD, new AST::AstNode(AST::AST_SUB, left->clone(), right->clone()), AST::AstNode::mkconst_int(1, true));
+    AST::AstNode *sub_dot = nullptr;
+    AST::AstNode *struct_range = nullptr;
+
+    for (auto c : search_node->children) {
+        if (c->type == static_cast<int>(AST::AST_DOT)) {
+            // There should be only 1 AST_DOT node children
+            log_assert(!sub_dot);
+            sub_dot = expand_dot(current_struct_elem, c);
+        }
+        if (c->type == AST::AST_RANGE) {
+            // Currently supporting only 1 range
+            log_assert(!struct_range);
+            struct_range = c;
+        }
+    }
+    if (sub_dot) {
+        // First select correct element in first struct
+        delete left;
+        delete right;
+        left = sub_dot->children[0];
+        right = sub_dot->children[1];
+    }
+    if (struct_range) {
+        // now we have correct element set,
+        // but we still need to set correct struct
+        log_assert(!struct_range->children.empty());
+        if (current_struct_elem->type == AST::AST_STRUCT_ITEM) {
+            // if we selecting range of struct item, just add this range
+            // to our current select
+            if (struct_range->children.size() == 2) {
+                auto range_size = new AST::AstNode(
+                  AST::AST_ADD, new AST::AstNode(AST::AST_SUB, struct_range->children[0]->clone(), struct_range->children[1]->clone()),
+                  AST::AstNode::mkconst_int(1, true));
+                right = new AST::AstNode(AST::AST_ADD, right->clone(), struct_range->children[1]->clone());
+                left = new AST::AstNode(
+                  AST::AST_ADD, left,
+                  new AST::AstNode(AST::AST_ADD, struct_range->children[1]->clone(), new AST::AstNode(AST::AST_SUB, range_size, elem_size->clone())));
+            } else if (struct_range->children.size() == 1) {
+                if (!current_struct_elem->multirange_dimensions.empty()) {
+                    right = new AST::AstNode(AST::AST_ADD, right,
+                                             new AST::AstNode(AST::AST_MUL, struct_range->children[0]->clone(),
+                                                              AST::AstNode::mkconst_int(current_struct_elem->multirange_dimensions.back(), true)));
+                    delete left;
+                    left = new AST::AstNode(AST::AST_ADD, right->clone(),
+                                            AST::AstNode::mkconst_int(current_struct_elem->multirange_dimensions.back() - 1, true));
+                } else {
+                    right = new AST::AstNode(AST::AST_ADD, right, struct_range->children[0]->clone());
+                    delete left;
+                    left = right->clone();
+                }
+            } else {
+                struct_range->dumpAst(NULL, "range >");
+                log_error("Unhandled range select (AST_STRUCT_ITEM) in AST_DOT!\n");
+            }
+        } else if (current_struct_elem->type == AST::AST_STRUCT) {
+            if (struct_range->children.size() == 2) {
+                right = new AST::AstNode(AST::AST_ADD, right, struct_range->children[1]->clone());
+                auto range_size = new AST::AstNode(
+                  AST::AST_ADD, new AST::AstNode(AST::AST_SUB, struct_range->children[0]->clone(), struct_range->children[1]->clone()),
+                  AST::AstNode::mkconst_int(1, true));
+                left = new AST::AstNode(AST::AST_ADD, left, new AST::AstNode(AST::AST_SUB, range_size, elem_size->clone()));
+            } else if (struct_range->children.size() == 1) {
+                AST::AstNode *mul = new AST::AstNode(AST::AST_MUL, elem_size->clone(), struct_range->children[0]->clone());
+
+                left = new AST::AstNode(AST::AST_ADD, left, mul);
+                right = new AST::AstNode(AST::AST_ADD, right, mul->clone());
+            } else {
+                struct_range->dumpAst(NULL, "range >");
+                log_error("Unhandled range select (AST_STRUCT) in AST_DOT!\n");
+            }
+        } else {
+            log_error("Found %s elem in struct that is currently unsupported!\n", type2str(current_struct_elem->type).c_str());
+        }
+    }
+    // Return range from the begining of *current* struct
+    // When all AST_DOT are expanded it will return range
+    // from original wire
+    return new AST::AstNode(AST::AST_RANGE, left, right);
+}
+
+static AST::AstNode *convert_dot(AST::AstNode *wire_node, AST::AstNode *node, AST::AstNode *dot)
+{
+    AST::AstNode *struct_node = nullptr;
+    if (wire_node->type == AST::AST_STRUCT) {
+        struct_node = wire_node;
+    } else if (wire_node->attributes.count(ID::wiretype)) {
+        log_assert(wire_node->attributes[ID::wiretype]->id2ast);
+        struct_node = wire_node->attributes[ID::wiretype]->id2ast;
+    }
+    log_assert(struct_node);
+    auto expanded = expand_dot(struct_node, dot);
+    if (node->children[0]->type == AST::AST_RANGE) {
+        int struct_size_int = get_max_offset_struct(struct_node) + 1;
+        log_assert(!wire_node->multirange_dimensions.empty());
+        int range = wire_node->multirange_dimensions.back() - 1;
+        if (!wire_node->attributes[UhdmAst::unpacked_ranges()]->children.empty() &&
+            wire_node->attributes[UhdmAst::unpacked_ranges()]->children.back()->range_left == range) {
+            expanded->children[1] = new AST::AstNode(
+              AST::AST_ADD, expanded->children[1],
+              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32),
+                               new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(range, true, 32), node->children[0]->children[0]->clone())));
+            expanded->children[0] = new AST::AstNode(
+              AST::AST_ADD, expanded->children[0],
+              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32),
+                               new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(range, true, 32), node->children[0]->children[0]->clone())));
+        } else {
+            expanded->children[1] = new AST::AstNode(
+              AST::AST_ADD, expanded->children[1],
+              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32), node->children[0]->children[0]->clone()));
+            expanded->children[0] = new AST::AstNode(
+              AST::AST_ADD, expanded->children[0],
+              new AST::AstNode(AST::AST_MUL, AST::AstNode::mkconst_int(struct_size_int, true, 32), node->children[0]->children[0]->clone()));
+        }
+    }
+    return expanded;
+}
+
+static void setup_current_scope(std::unordered_map<std::string, AST::AstNode *> top_nodes, AST::AstNode *current_top_node)
+{
+    for (auto it = top_nodes.begin(); it != top_nodes.end(); it++) {
+        if (!it->second)
+            continue;
+        if (it->second->type == AST::AST_PACKAGE) {
+            for (auto &o : it->second->children) {
+                // import only parameters
+                if (o->type == AST::AST_TYPEDEF || o->type == AST::AST_PARAMETER || o->type == AST::AST_LOCALPARAM) {
+                    // add imported nodes to current scope
+                    AST_INTERNAL::current_scope[it->second->str + std::string("::") + o->str.substr(1)] = o;
+                    AST_INTERNAL::current_scope[o->str] = o;
+                } else if (o->type == AST::AST_ENUM) {
+                    AST_INTERNAL::current_scope[o->str] = o;
+                    for (auto c : o->children) {
+                        AST_INTERNAL::current_scope[c->str] = c;
+                    }
+                }
+            }
+        }
+    }
+    for (auto &o : current_top_node->children) {
+        if (o->type == AST::AST_TYPEDEF || o->type == AST::AST_PARAMETER || o->type == AST::AST_LOCALPARAM) {
+            AST_INTERNAL::current_scope[o->str] = o;
+        } else if (o->type == AST::AST_ENUM) {
+            AST_INTERNAL::current_scope[o->str] = o;
+            for (auto c : o->children) {
+                AST_INTERNAL::current_scope[c->str] = c;
+            }
+        }
+    }
+    // hackish way of setting current_ast_mod as it is required
+    // for simplify to get references for already defined ids
+    AST_INTERNAL::current_ast_mod = current_top_node;
+    log_assert(AST_INTERNAL::current_ast_mod != nullptr);
+}
+
+static int range_width_local(AST::AstNode *node, AST::AstNode *rnode)
+{
+    log_assert(rnode->type == AST::AST_RANGE);
+    if (!rnode->range_valid) {
+        log_file_error(node->filename, node->location.first_line, "Size must be constant in packed struct/union member %s\n", node->str.c_str());
+    }
+    // note: range swapping has already been checked for
+    return rnode->range_left - rnode->range_right + 1;
+}
+
+static void save_struct_array_width_local(AST::AstNode *node, int width)
+{
+    // stash the stride for the array
+    node->multirange_dimensions.push_back(width);
+}
+
+static int simplify_struct(AST::AstNode *snode, int base_offset, AST::AstNode *parent_node)
+{
+    // Struct members will be laid out in the structure contiguously from left to right.
+    // Union members all have zero offset from the start of the union.
+    // Determine total packed size and assign offsets.  Store these in the member node.
+    bool is_union = (snode->type == AST::AST_UNION);
+    int offset = 0;
+    int packed_width = -1;
+    for (auto s : snode->children) {
+        if (s->type == AST::AST_RANGE) {
+            while (s->simplify(true, false, false, 1, -1, false, false)) {
+            };
+        }
+    }
+    // embeded struct or union with range?
+    auto it = std::remove_if(snode->children.begin(), snode->children.end(), [](AST::AstNode *node) { return node->type == AST::AST_RANGE; });
+    std::vector<AST::AstNode *> ranges(it, snode->children.end());
+    snode->children.erase(it, snode->children.end());
+    if (!ranges.empty()) {
+        if (ranges.size() > 1) {
+            log_file_error(ranges[1]->filename, ranges[1]->location.first_line,
+                           "Currently support for custom-type with range is limited to single range\n");
+        }
+        for (auto range : ranges) {
+            snode->multirange_dimensions.push_back(min(range->range_left, range->range_right));
+            snode->multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
+            snode->multirange_swapped.push_back(range->range_swapped);
+        }
+    }
+    // examine members from last to first
+    for (auto it = snode->children.rbegin(); it != snode->children.rend(); ++it) {
+        auto node = *it;
+        int width;
+        if (node->type == AST::AST_STRUCT || node->type == AST::AST_UNION) {
+            // embedded struct or union
+            width = simplify_struct(node, base_offset + offset, parent_node);
+            if (!node->multirange_dimensions.empty()) {
+                int number_of_structs = 1;
+                number_of_structs = node->multirange_dimensions.back();
+                width *= number_of_structs;
+            }
+            // set range of struct
+            node->range_right = base_offset + offset;
+            node->range_left = base_offset + offset + width - 1;
+            node->range_valid = true;
+        } else {
+            log_assert(node->type == AST::AST_STRUCT_ITEM);
+            if (node->children.size() > 0 && node->children[0]->type == AST::AST_RANGE) {
+                // member width e.g. bit [7:0] a
+                width = range_width_local(node, node->children[0]);
+                if (node->children.size() == 2) {
+                    if (node->children[1]->type == AST::AST_RANGE) {
+                        // unpacked array e.g. bit [63:0] a [0:3]
+                        auto rnode = node->children[1];
+                        int array_count = range_width_local(node, rnode);
+                        if (array_count == 1) {
+                            // C-type array size e.g. bit [63:0] a [4]
+                            array_count = rnode->range_left;
+                        }
+                        save_struct_array_width_local(node, width);
+                        width *= array_count;
+                    } else {
+                        // array element must be single bit for a packed array
+                        log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n",
+                                       node->str.c_str());
+                    }
+                }
+                // range nodes are now redundant
+                for (AST::AstNode *child : node->children)
+                    delete child;
+                node->children.clear();
+            } else if (node->children.size() == 1 && node->children[0]->type == AST::AST_MULTIRANGE) {
+                // packed 2D array, e.g. bit [3:0][63:0] a
+                auto rnode = node->children[0];
+                if (rnode->children.size() != 2) {
+                    // packed arrays can only be 2D
+                    log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n", node->str.c_str());
+                }
+                int array_count = range_width_local(node, rnode->children[0]);
+                width = range_width_local(node, rnode->children[1]);
+                save_struct_array_width_local(node, width);
+                width *= array_count;
+                // range nodes are now redundant
+                for (AST::AstNode *child : node->children)
+                    delete child;
+                node->children.clear();
+            } else if (node->range_left < 0) {
+                // 1 bit signal: bit, logic or reg
+                width = 1;
+            } else {
+                // already resolved and compacted
+                width = node->range_left - node->range_right + 1;
+            }
+            if (is_union) {
+                node->range_right = base_offset;
+                node->range_left = base_offset + width - 1;
+            } else {
+                node->range_right = base_offset + offset;
+                node->range_left = base_offset + offset + width - 1;
+            }
+            node->range_valid = true;
+        }
+        if (is_union) {
+            // check that all members have the same size
+            if (packed_width == -1) {
+                // first member
+                packed_width = width;
+            } else {
+                if (packed_width != width) {
+
+                    log_file_error(node->filename, node->location.first_line, "member %s of a packed union has %d bits, expecting %d\n",
+                                   node->str.c_str(), width, packed_width);
+                }
+            }
+        } else {
+            offset += width;
+        }
+    }
+    if (!snode->str.empty() && parent_node && parent_node->type != AST::AST_TYPEDEF && parent_node->type != AST::AST_STRUCT &&
+        AST_INTERNAL::current_scope.count(snode->str) != 0) {
+        AST_INTERNAL::current_scope[snode->str]->attributes[ID::wiretype] = AST::AstNode::mkconst_str(snode->str);
+        AST_INTERNAL::current_scope[snode->str]->attributes[ID::wiretype]->id2ast = snode;
+    }
+    return (is_union ? packed_width : offset);
+}
+
+static void add_members_to_scope_local(AST::AstNode *snode, std::string name)
+{
+    // add all the members in a struct or union to local scope
+    // in case later referenced in assignments
+    log_assert(snode->type == AST::AST_STRUCT || snode->type == AST::AST_UNION);
+    for (auto *node : snode->children) {
+        auto member_name = name + "." + node->str;
+        AST_INTERNAL::current_scope[member_name] = node;
+        if (node->type != AST::AST_STRUCT_ITEM) {
+            // embedded struct or union
+            add_members_to_scope_local(node, name + "." + node->str);
+        }
+    }
+}
+
+static AST::AstNode *make_packed_struct_local(AST::AstNode *template_node, std::string &name)
+{
+    // create a wire for the packed struct
+    auto wnode = new AST::AstNode(AST::AST_WIRE);
+    wnode->str = name;
+    wnode->is_logic = true;
+    wnode->range_valid = true;
+    wnode->is_signed = template_node->is_signed;
+    int offset = get_max_offset_struct(template_node);
+    auto range = make_range(offset, 0);
+    copy_packed_unpacked_attribute(template_node, wnode);
+    wnode->attributes[UhdmAst::packed_ranges()]->children.insert(wnode->attributes[UhdmAst::packed_ranges()]->children.begin(), range);
+    // make sure this node is the one in scope for this name
+    AST_INTERNAL::current_scope[name] = wnode;
+    // add all the struct members to scope under the wire's name
+    add_members_to_scope_local(template_node, name);
+    return wnode;
+}
+
+static void simplify_format_string(AST::AstNode *current_node)
+{
+    std::string sformat = current_node->children[0]->str;
+    std::string preformatted_string = "";
+    int next_arg = 1;
+    for (size_t i = 0; i < sformat.length(); i++) {
+        if (sformat[i] == '%') {
+            AST::AstNode *node_arg = current_node->children[next_arg];
+            char cformat = sformat[++i];
+            if (cformat == 'b' or cformat == 'B') {
+                node_arg->simplify(true, false, false, 1, -1, false, false);
+                if (node_arg->type != AST::AST_CONSTANT)
+                    log_file_error(current_node->filename, current_node->location.first_line,
+                                   "Failed to evaluate system task `%s' with non-constant argument.\n", current_node->str.c_str());
+
+                RTLIL::Const val = node_arg->bitsAsConst();
+                for (int j = val.size() - 1; j >= 0; j--) {
+                    // We add ACII value of 0 to convert number to character
+                    preformatted_string += ('0' + val[j]);
+                }
+                delete current_node->children[next_arg];
+                current_node->children.erase(current_node->children.begin() + next_arg);
+            } else {
+                next_arg++;
+                preformatted_string += std::string("%") + cformat;
+            }
+        } else {
+            preformatted_string += sformat[i];
+        }
+    }
+    delete current_node->children[0];
+    current_node->children[0] = AST::AstNode::mkconst_str(preformatted_string);
+}
+
+static void simplify(AST::AstNode *current_node, AST::AstNode *parent_node)
+{
+    auto dot_it =
+      std::find_if(current_node->children.begin(), current_node->children.end(), [](auto c) { return c->type == static_cast<int>(AST::AST_DOT); });
+    AST::AstNode *dot = (dot_it != current_node->children.end()) ? *dot_it : nullptr;
+
+    AST::AstNode *expanded = nullptr;
+    if (dot) {
+        if (!AST_INTERNAL::current_scope.count(current_node->str)) {
+            // for accessing elements currently unsupported with AST_DOT
+            // fallback to "." notation
+            AST::AstNode *prefix_node = nullptr;
+            AST::AstNode *parent_node = current_node;
+            while (dot && !dot->str.empty()) {
+                // it is not possible for AST_RANGE to be after AST::DOT (see process_hier_path function)
+                if (parent_node->children[0]->type == AST::AST_RANGE) {
+                    if (parent_node->children[1]->type == AST::AST_RANGE)
+                        log_error("Multirange in AST_DOT is currently unsupported\n");
+
+                    dot->type = AST::AST_IDENTIFIER;
+                    simplify(dot, nullptr);
+                    AST::AstNode *range_const = parent_node->children[0]->children[0];
+                    prefix_node = new AST::AstNode(AST::AST_PREFIX, range_const->clone(), dot->clone());
+                    break;
+                } else {
+                    current_node->str += "." + dot->str.substr(1);
+                    dot_it =
+                      std::find_if(dot->children.begin(), dot->children.end(), [](auto c) { return c->type == static_cast<int>(AST::AST_DOT); });
+                    parent_node = dot;
+                    dot = (dot_it != dot->children.end()) ? *dot_it : nullptr;
+                }
+            }
+            current_node->delete_children();
+            if (prefix_node != nullptr) {
+                current_node->type = AST::AST_PREFIX;
+                current_node->children = prefix_node->children;
+            }
+        } else {
+            auto wire_node = AST_INTERNAL::current_scope[current_node->str];
+            // make sure wire_node is already simplified
+            simplify(wire_node, nullptr);
+            expanded = convert_dot(wire_node, current_node, dot);
+        }
+    }
+    if (expanded) {
+        for (size_t i = 0; i < current_node->children.size(); i++) {
+            delete current_node->children[i];
+        }
+        current_node->children.clear();
+        current_node->children.push_back(expanded->clone());
+        current_node->basic_prep = true;
+        expanded = nullptr;
+    }
+    // First simplify children
+    for (size_t i = 0; i < current_node->children.size(); i++) {
+        simplify(current_node->children[i], current_node);
+    }
+    switch (current_node->type) {
+    case AST::AST_TYPEDEF:
+    case AST::AST_ENUM:
+    case AST::AST_FUNCTION:
+        AST_INTERNAL::current_scope[current_node->str] = current_node;
+        break;
+    case AST::AST_WIRE:
+    case AST::AST_PARAMETER:
+    case AST::AST_LOCALPARAM:
+        AST_INTERNAL::current_scope[current_node->str] = current_node;
+        convert_packed_unpacked_range(current_node);
+        break;
+    case AST::AST_IDENTIFIER:
+        if (!current_node->children.empty() && !current_node->basic_prep) {
+            log_assert(AST_INTERNAL::current_ast_mod);
+            if (!AST_INTERNAL::current_scope.count(current_node->str)) {
+                break;
+            }
+            AST::AstNode *wire_node = AST_INTERNAL::current_scope[current_node->str];
+            simplify(wire_node, nullptr);
+            const std::vector<AST::AstNode *> packed_ranges = wire_node->attributes.count(UhdmAst::packed_ranges())
+                                                                ? wire_node->attributes[UhdmAst::packed_ranges()]->children
+                                                                : std::vector<AST::AstNode *>();
+            const std::vector<AST::AstNode *> unpacked_ranges = wire_node->attributes.count(UhdmAst::unpacked_ranges())
+                                                                  ? wire_node->attributes[UhdmAst::unpacked_ranges()]->children
+                                                                  : std::vector<AST::AstNode *>();
+            if ((wire_node->type == AST::AST_WIRE || wire_node->type == AST::AST_PARAMETER || wire_node->type == AST::AST_LOCALPARAM) &&
+                !(packed_ranges.empty() && unpacked_ranges.empty()) && !(packed_ranges.size() + unpacked_ranges.size() == 1)) {
+                auto result = convert_range(current_node, packed_ranges, unpacked_ranges, 0);
+                for (size_t i = 0; i < current_node->children.size(); i++) {
+                    delete current_node->children[i];
+                }
+                current_node->children.clear();
+                current_node->children.push_back(result);
+            }
+        }
+        break;
+    case AST::AST_STRUCT:
+    case AST::AST_UNION:
+        simplify_struct(current_node, 0, parent_node);
+        // instance rather than just a type in a typedef or outer struct?
+        if (!current_node->str.empty() && current_node->str[0] == '\\') {
+            // instance so add a wire for the packed structure
+            auto wnode = make_packed_struct_local(current_node, current_node->str);
+            convert_packed_unpacked_range(wnode);
+            log_assert(AST_INTERNAL::current_ast_mod);
+            AST_INTERNAL::current_ast_mod->children.push_back(wnode);
+            AST_INTERNAL::current_scope[wnode->str]->attributes[ID::wiretype] = AST::AstNode::mkconst_str(current_node->str);
+            AST_INTERNAL::current_scope[wnode->str]->attributes[ID::wiretype]->id2ast = current_node;
+        }
+
+        current_node->basic_prep = true;
+        break;
+    case AST::AST_STRUCT_ITEM:
+        AST_INTERNAL::current_scope[current_node->str] = current_node;
+        convert_packed_unpacked_range(current_node);
+        while (current_node->simplify(true, false, false, 1, -1, false, false)) {
+        };
+        break;
+    case AST::AST_TCALL:
+        if (current_node->str == "$display" || current_node->str == "$write")
+            simplify_format_string(current_node);
+        break;
+    default:
+        break;
+    }
+}
+
+static void clear_current_scope()
+{
+    // Remove clear current_scope from package nodes
+    AST_INTERNAL::current_scope.clear();
+    // unset current_ast_mod
+    AST_INTERNAL::current_ast_mod = nullptr;
+}
+
+void UhdmAst::visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f)
+{
+    for (auto child : child_node_types) {
+        vpiHandle itr = vpi_iterate(child, parent_handle);
+        while (vpiHandle vpi_child_obj = vpi_scan(itr)) {
+            UhdmAst uhdm_ast(this, shared, indent + "  ");
+            auto *child_node = uhdm_ast.process_object(vpi_child_obj);
+            f(child_node);
+            vpi_release_handle(vpi_child_obj);
+        }
+        vpi_release_handle(itr);
+    }
+}
+
+void UhdmAst::visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f)
+{
+    for (auto child : child_node_types) {
+        vpiHandle itr = vpi_handle(child, parent_handle);
+        if (itr) {
+            UhdmAst uhdm_ast(this, shared, indent + "  ");
+            auto *child_node = uhdm_ast.process_object(itr);
+            f(child_node);
+        }
+        vpi_release_handle(itr);
+    }
+}
+
+void UhdmAst::visit_range(vpiHandle obj_h, const std::function<void(AST::AstNode *)> &f)
+{
+    std::vector<AST::AstNode *> range_nodes;
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { range_nodes.push_back(node); });
+    if (range_nodes.size() > 1) {
+        auto multirange_node = new AST::AstNode(AST::AST_MULTIRANGE);
+        multirange_node->children = range_nodes;
+        f(multirange_node);
+    } else if (!range_nodes.empty()) {
+        f(range_nodes[0]);
+    }
+}
+
+void UhdmAst::visit_default_expr(vpiHandle obj_h)
+{
+    UhdmAst initial_ast(parent, shared, indent);
+    UhdmAst block_ast(&initial_ast, shared, indent);
+    block_ast.visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *expr_node) {
+        auto mod = find_ancestor({AST::AST_MODULE});
+        AST::AstNode *initial_node = nullptr;
+        AST::AstNode *block_node = nullptr;
+        auto assign_node = new AST::AstNode(AST::AST_ASSIGN_EQ);
+        auto id_node = new AST::AstNode(AST::AST_IDENTIFIER);
+        id_node->str = current_node->str;
+
+        for (auto child : mod->children) {
+            if (child->type == AST::AST_INITIAL) {
+                initial_node = child;
+                break;
+            }
+        }
+        // Ensure single AST_INITIAL node is located in AST_MODULE
+        // before any AST_ALWAYS
+        if (initial_node == nullptr) {
+            initial_node = new AST::AstNode(AST::AST_INITIAL);
+            auto insert_it = find_if(mod->children.begin(), mod->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ALWAYS); });
+            mod->children.insert(insert_it, initial_node);
+        }
+        // Ensure single AST_BLOCK node in AST_INITIAL
+        if (!initial_node->children.empty() && initial_node->children[0]) {
+            block_node = initial_node->children[0];
+        } else {
+            block_node = new AST::AstNode(AST::AST_BLOCK);
+            initial_node->children.push_back(block_node);
+        }
+        auto block_child =
+          find_if(block_node->children.begin(), block_node->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ASSIGN_EQ); });
+        // Insert AST_ASSIGN_EQ nodes that came from
+        // custom_var or int_var before any other AST_ASSIGN_EQ
+        // Especially before ones explicitly placed in initial block in source code
+        block_node->children.insert(block_child, assign_node);
+        assign_node->children.push_back(id_node);
+        initial_ast.current_node = initial_node;
+        block_ast.current_node = block_node;
+        assign_node->children.push_back(expr_node);
+    });
+}
+
+AST::AstNode *UhdmAst::process_value(vpiHandle obj_h)
+{
+    s_vpi_value val;
+    vpi_get_value(obj_h, &val);
+    std::string strValType;
+    if (val.format) { // Needed to handle parameter nodes without typespecs and constants
+        switch (val.format) {
+        case vpiScalarVal:
+            return AST::AstNode::mkconst_int(val.value.scalar, false, 1);
+        case vpiBinStrVal: {
+            strValType = "'b";
+            break;
+        }
+        case vpiDecStrVal: {
+            strValType = "'d";
+            break;
+        }
+        case vpiHexStrVal: {
+            strValType = "'h";
+            break;
+        }
+        case vpiOctStrVal: {
+            strValType = "'o";
+            break;
+        }
+        // Surelog reports constant integers as a unsigned, but by default int is signed
+        // so we are treating here UInt in the same way as if they would be Int
+        case vpiUIntVal:
+        case vpiIntVal: {
+            int size = -1;
+            bool is_signed = false;
+            // Surelog sometimes report size as part of vpiTypespec (e.g. int_typespec)
+            // if it is the case, we need to set size to the left_range of first packed range
+            visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+                if (node && node->attributes.count(UhdmAst::packed_ranges()) && node->attributes[UhdmAst::packed_ranges()]->children.size() &&
+                    node->attributes[UhdmAst::packed_ranges()]->children[0]->children.size()) {
+                    size = node->attributes[UhdmAst::packed_ranges()]->children[0]->children[0]->integer + 1;
+                }
+            });
+            if (size == -1) {
+                size = vpi_get(vpiSize, obj_h);
+            }
+            // Surelog by default returns 64 bit numbers and stardard says that they shall be at least 32bits
+            // yosys is assuming that int/uint is 32 bit, so we are setting here correct size
+            // NOTE: it *shouldn't* break on explicite 64 bit const values, as they *should* be handled
+            // above by vpi*StrVal
+            if (size == 64) {
+                size = 32;
+                is_signed = true;
+            }
+            auto c = AST::AstNode::mkconst_int(val.value.integer, is_signed, size > 0 ? size : 32);
+            if (size == 0 || size == -1)
+                c->is_unsized = true;
+            return c;
+        }
+        case vpiRealVal:
+            return mkconst_real(val.value.real);
+        case vpiStringVal:
+            return AST::AstNode::mkconst_str(val.value.str);
+        default: {
+            const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
+            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+            report_error("%s:%d: Encountered unhandled constant format %d\n", object->VpiFile().c_str(), object->VpiLineNo(), val.format);
+        }
+        }
+        // handle vpiBinStrVal, vpiDecStrVal and vpiHexStrVal
+        if (std::strchr(val.value.str, '\'')) {
+            return VERILOG_FRONTEND::const2ast(val.value.str, 0, false);
+        } else {
+            auto size = vpi_get(vpiSize, obj_h);
+            if (size == 0) {
+                auto c = AST::AstNode::mkconst_int(atoi(val.value.str), true, 32);
+                c->is_unsized = true;
+                return c;
+            } else {
+                return VERILOG_FRONTEND::const2ast(std::to_string(size) + strValType + val.value.str, 0, false);
+            }
+        }
+    }
+    return nullptr;
+}
+
+void UhdmAst::transform_breaks_continues(AST::AstNode *loop, AST::AstNode *decl_block)
+{
+    AST::AstNode *break_wire = nullptr;
+    AST::AstNode *continue_wire = nullptr;
+    // Creates a 1-bit wire with the given name
+    const auto make_cond_var = [this](const std::string &var_name) {
+        auto cond_var =
+          make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {AST::AstNode::mkconst_int(0, false), AST::AstNode::mkconst_int(0, false)}),
+                                        AST::AstNode::mkconst_int(0, false)});
+        cond_var->str = var_name;
+        cond_var->is_reg = true;
+        return cond_var;
+    };
+    // Creates a conditional like 'if (!casevar) block'
+    auto make_case = [this](AST::AstNode *block, const std::string &casevar_name) {
+        auto *case_node = make_ast_node(AST::AST_CASE);
+        auto *id = make_identifier(casevar_name);
+        case_node->children.push_back(id);
+        auto *constant = AST::AstNode::mkconst_int(0, false, 1);
+        auto *cond_node = make_ast_node(AST::AST_COND);
+        cond_node->children.push_back(constant);
+        cond_node->children.push_back(block);
+        case_node->children.push_back(cond_node);
+        return case_node;
+    };
+    // Pre-declare this function to be able to call it recursively
+    std::function<bool(AST::AstNode *)> transform_block;
+    // Transforms the given block if it has a break or continue; recurses into child blocks; return true if a break/continue was encountered
+    transform_block = [&](AST::AstNode *block) {
+        auto wrap_and_transform = [&](decltype(block->children)::iterator it) {
+            // Move the (it, end()) statements into a new block under 'if (!continue) {...}'
+            auto *new_block = make_ast_node(AST::AST_BLOCK, {it, block->children.end()});
+            block->children.erase(it, block->children.end());
+            auto *case_node = make_case(new_block, continue_wire->str);
+            block->children.push_back(case_node);
+            transform_block(new_block);
+        };
+
+        for (auto it = block->children.begin(); it != block->children.end(); it++) {
+            auto type = static_cast<int>((*it)->type);
+            switch (type) {
+            case AST::AST_BLOCK: {
+                if (transform_block(*it)) {
+                    // If there was a break/continue, we need to wrap the rest of the block in an if
+                    wrap_and_transform(it + 1);
+                    return true;
+                }
+                break;
+            }
+            case AST::AST_CASE: {
+                // Go over each block in a case
+                bool has_jump = false;
+                for (auto *node : (*it)->children) {
+                    if (node->type == AST::AST_COND)
+                        has_jump = has_jump || transform_block(node->children.back());
+                }
+                if (has_jump) {
+                    // If there was a break/continue, we need to wrap the rest of the block in an if
+                    wrap_and_transform(it + 1);
+                    return true;
+                }
+                break;
+            }
+            case AST::AST_BREAK:
+            case AST::AST_CONTINUE: {
+                std::for_each(it, block->children.end(), [](auto *node) { delete node; });
+                block->children.erase(it, block->children.end());
+                if (!continue_wire)
+                    continue_wire = make_cond_var("$continue");
+                auto *continue_id = make_identifier(continue_wire->str);
+                block->children.push_back(make_ast_node(AST::AST_ASSIGN_EQ, {continue_id, AST::AstNode::mkconst_int(1, false)}));
+                if (type == AST::AST_BREAK) {
+                    if (!break_wire)
+                        break_wire = make_cond_var("$break");
+                    auto *break_id = make_identifier(break_wire->str);
+                    block->children.push_back(make_ast_node(AST::AST_ASSIGN_EQ, {break_id, AST::AstNode::mkconst_int(1, false)}));
+                }
+                return true;
+            }
+            }
+        }
+        return false;
+    };
+
+    // Actual transformation starts here
+    transform_block(loop->children.back());
+    if (continue_wire) {
+        auto *continue_id = make_identifier(continue_wire->str);
+        // Reset $continue each iteration
+        auto *continue_assign = make_ast_node(AST::AST_ASSIGN_EQ, {continue_id, AST::AstNode::mkconst_int(0, false)});
+        decl_block->children.insert(decl_block->children.begin(), continue_wire);
+        loop->children.back()->children.insert(loop->children.back()->children.begin(), continue_assign);
+    }
+    if (break_wire) {
+        auto *break_id = make_identifier(break_wire->str);
+        // Reset $break before the loop
+        auto *break_assign = make_ast_node(AST::AST_ASSIGN_EQ, {break_id, AST::AstNode::mkconst_int(0, false)});
+        decl_block->children.insert(decl_block->children.begin(), break_assign);
+        decl_block->children.insert(decl_block->children.begin(), break_wire);
+        if (loop->type == AST::AST_REPEAT || loop->type == AST::AST_FOR) {
+            // Wrap loop body in 'if (!break) {...}'
+            // Changing the for loop condition won't work here,
+            // as then simplify fails with error "2nd expression of procedural for-loop is not constant!"
+            auto *case_node = make_case(loop->children.back(), break_wire->str);
+            auto *new_block = make_ast_node(AST::AST_BLOCK);
+            new_block->children.push_back(case_node);
+            new_block->str = loop->children.back()->str;
+            loop->children.back() = new_block;
+        } else if (loop->type == AST::AST_WHILE) {
+            // Add the break var to the loop condition
+            auto *break_id = make_identifier(break_wire->str);
+            AST::AstNode *&loop_cond = loop->children[0];
+            loop_cond = make_ast_node(AST::AST_LOGIC_AND, {make_ast_node(AST::AST_LOGIC_NOT, {break_id}), loop_cond});
+        } else {
+            log_error("break unsupported for this loop type");
+        }
+    }
+}
+
+AST::AstNode *UhdmAst::make_ast_node(AST::AstNodeType type, std::vector<AST::AstNode *> children, bool prefer_full_name)
+{
+    auto node = new AST::AstNode(type);
+    node->str = get_name(obj_h, prefer_full_name);
+    auto it = node_renames.find(node->str);
+    if (it != node_renames.end())
+        node->str = it->second;
+    if (auto filename = vpi_get_str(vpiFile, obj_h)) {
+        node->filename = filename;
+    }
+    if (unsigned int line = vpi_get(vpiLineNo, obj_h)) {
+        node->location.first_line = node->location.last_line = line;
+    }
+    node->children = children;
+    return node;
+}
+
+AST::AstNode *UhdmAst::make_identifier(const std::string &name)
+{
+    auto *node = make_ast_node(AST::AST_IDENTIFIER);
+    node->str = name;
+    return node;
+}
+
+void UhdmAst::process_packed_array_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    current_node = make_ast_node(AST::AST_WIRE);
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+    visit_one_to_one({vpiElemTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node && node->type == AST::AST_STRUCT) {
+            auto str = current_node->str;
+            node->cloneInto(current_node);
+            current_node->str = str;
+            delete node;
+        } else if (node) {
+            current_node->str = node->str;
+            if (node->type == AST::AST_ENUM && !node->children.empty()) {
+                for (auto c : node->children[0]->children) {
+                    if (c->type == AST::AST_RANGE && c->str.empty())
+                        packed_ranges.push_back(c->clone());
+                }
+            }
+            delete node;
+        }
+    });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+static void add_or_replace_child(AST::AstNode *parent, AST::AstNode *child)
+{
+    if (!child->str.empty()) {
+        auto it = std::find_if(parent->children.begin(), parent->children.end(),
+                               [child](AST::AstNode *existing_child) { return existing_child->str == child->str; });
+        if (it != parent->children.end()) {
+            // If port direction is already set, copy it to replaced child node
+            if ((*it)->is_input || (*it)->is_output) {
+                child->is_input = (*it)->is_input;
+                child->is_output = (*it)->is_output;
+                child->port_id = (*it)->port_id;
+                if (child->type == AST::AST_MEMORY)
+                    child->type = AST::AST_WIRE;
+            }
+            if (!(*it)->children.empty() && child->children.empty()) {
+                // This is a bit ugly, but if the child we're replacing has children and
+                // our node doesn't, we copy its children to not lose any information
+                for (auto grandchild : (*it)->children) {
+                    child->children.push_back(grandchild->clone());
+                    if (child->type == AST::AST_WIRE && grandchild->type == AST::AST_WIRETYPE)
+                        child->is_custom_type = true;
+                }
+            }
+            if ((*it)->attributes.count(UhdmAst::packed_ranges()) && child->attributes.count(UhdmAst::packed_ranges())) {
+                if ((!(*it)->attributes[UhdmAst::packed_ranges()]->children.empty() &&
+                     child->attributes[UhdmAst::packed_ranges()]->children.empty())) {
+                    child->attributes[UhdmAst::packed_ranges()] = (*it)->attributes[UhdmAst::packed_ranges()]->clone();
+                }
+            }
+            if ((*it)->attributes.count(UhdmAst::unpacked_ranges()) && child->attributes.count(UhdmAst::unpacked_ranges())) {
+                if ((!(*it)->attributes[UhdmAst::unpacked_ranges()]->children.empty() &&
+                     child->attributes[UhdmAst::unpacked_ranges()]->children.empty())) {
+                    child->attributes[UhdmAst::unpacked_ranges()] = (*it)->attributes[UhdmAst::unpacked_ranges()]->clone();
+                }
+            }
+            // Surelog doesn't report correct sign value for param_assign nodes
+            // and only default vpiParameter node have correct sign value, so
+            // if we are overriding parameter, copy sign value from current node to the new node
+            if (((*it)->type == AST::AST_PARAMETER || (*it)->type == AST::AST_LOCALPARAM) && child->children.size() && (*it)->children.size()) {
+                child->children[0]->is_signed = (*it)->children[0]->is_signed;
+            }
+            delete *it;
+            *it = child;
+            return;
+        }
+        parent->children.push_back(child);
+    } else if (child->type == AST::AST_INITIAL) {
+        // Special case for initials
+        // Ensure that there is only one AST_INITIAL in the design
+        // And there is only one AST_BLOCK inside that initial
+        // Copy nodes from child initial to parent initial
+        auto initial_node_it =
+          find_if(parent->children.begin(), parent->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_INITIAL); });
+        if (initial_node_it != parent->children.end()) {
+            AST::AstNode *initial_node = *initial_node_it;
+
+            // simplify assumes that initial has a block under it
+            // In case we don't have one (there were no statements under the initial), let's add it
+            if (initial_node->children.empty()) {
+                initial_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
+            }
+
+            log_assert(initial_node->children[0]->type == AST::AST_BLOCK);
+            log_assert(!(child->children.empty()));
+            log_assert(child->children[0]->type == AST::AST_BLOCK);
+
+            AST::AstNode *block_node = initial_node->children[0];
+            AST::AstNode *child_block_node = child->children[0];
+
+            // Place the contents of child block node inside parent block
+            for (auto child_block_child : child_block_node->children)
+                block_node->children.push_back(child_block_child->clone());
+            // Place the remaining contents of child initial node inside the parent initial
+            for (auto initial_child = child->children.begin() + 1; initial_child != child->children.end(); ++initial_child) {
+                initial_node->children.push_back((*initial_child)->clone());
+            }
+        } else {
+            // Parent AST_INITIAL does not exist
+            // Place child AST_INITIAL before AST_ALWAYS if found
+            auto insert_it =
+              find_if(parent->children.begin(), parent->children.end(), [](AST::AstNode *node) { return (node->type == AST::AST_ALWAYS); });
+            parent->children.insert(insert_it, 1, child);
+        }
+    } else {
+        parent->children.push_back(child);
+    }
+}
+
+void UhdmAst::make_cell(vpiHandle obj_h, AST::AstNode *cell_node, AST::AstNode *type_node)
+{
+    if (cell_node->children.empty() || (!cell_node->children.empty() && cell_node->children[0]->type != AST::AST_CELLTYPE)) {
+        auto typeNode = new AST::AstNode(AST::AST_CELLTYPE);
+        typeNode->str = type_node->str;
+        cell_node->children.insert(cell_node->children.begin(), typeNode);
+    }
+    // Add port connections as arguments
+    vpiHandle port_itr = vpi_iterate(vpiPort, obj_h);
+    while (vpiHandle port_h = vpi_scan(port_itr)) {
+        std::string arg_name;
+        if (auto s = vpi_get_str(vpiName, port_h)) {
+            arg_name = s;
+            sanitize_symbol_name(arg_name);
+        }
+        auto arg_node = new AST::AstNode(AST::AST_ARGUMENT);
+        arg_node->str = arg_name;
+        arg_node->filename = cell_node->filename;
+        arg_node->location = cell_node->location;
+        visit_one_to_one({vpiHighConn}, port_h, [&](AST::AstNode *node) {
+            if (node) {
+                if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
+                    node->type = AST::AST_IDENTIFIER;
+                }
+                arg_node->children.push_back(node);
+            }
+        });
+        cell_node->children.push_back(arg_node);
+        shared.report.mark_handled(port_h);
+        vpi_release_handle(port_h);
+    }
+    vpi_release_handle(port_itr);
+}
+
+void UhdmAst::move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode *type_node)
+{
+    auto typedef_node = new AST::AstNode(AST::AST_TYPEDEF);
+    typedef_node->location = type_node->location;
+    typedef_node->filename = type_node->filename;
+    typedef_node->str = strip_package_name(type_node->str);
+    for (auto c : current_node->children) {
+        if (c->str == typedef_node->str) {
+            return;
+        }
+    }
+    if (type_node->type == AST::AST_STRUCT) {
+        type_node->str.clear();
+        typedef_node->children.push_back(type_node);
+        current_node->children.push_back(typedef_node);
+    } else if (type_node->type == AST::AST_ENUM) {
+        if (type_node->attributes.count("\\enum_base_type")) {
+            auto base_type = type_node->attributes["\\enum_base_type"];
+            auto wire_node = new AST::AstNode(AST::AST_WIRE);
+            wire_node->is_reg = true;
+            for (auto c : base_type->children) {
+                std::string enum_item_str = "\\enum_value_";
+                log_assert(!c->children.empty());
+                log_assert(c->children[0]->type == AST::AST_CONSTANT);
+                int width = 1;
+                bool is_signed = c->children[0]->is_signed;
+                if (c->children.size() == 2) {
+                    width = c->children[1]->children[0]->integer + 1;
+                }
+                RTLIL::Const val = c->children[0]->bitsAsConst(width, is_signed);
+                enum_item_str.append(val.as_string());
+                wire_node->attributes[enum_item_str.c_str()] = AST::AstNode::mkconst_str(c->str);
+            }
+            typedef_node->children.push_back(wire_node);
+            current_node->children.push_back(typedef_node);
+            delete type_node;
+        } else {
+            type_node->str = "$enum" + std::to_string(shared.next_enum_id());
+            auto wire_node = new AST::AstNode(AST::AST_WIRE);
+            wire_node->is_reg = true;
+            wire_node->attributes["\\enum_type"] = AST::AstNode::mkconst_str(type_node->str);
+            if (!type_node->children.empty() && type_node->children[0]->children.size() > 1) {
+                wire_node->children.push_back(type_node->children[0]->children[1]->clone());
+            } else {
+                // Add default range
+                wire_node->children.push_back(make_range(31, 0));
+            }
+            typedef_node->children.push_back(wire_node);
+            current_node->children.push_back(type_node);
+            current_node->children.push_back(typedef_node);
+        }
+    } else {
+        type_node->str.clear();
+        typedef_node->children.push_back(type_node);
+        current_node->children.push_back(typedef_node);
+    }
+}
+
+AST::AstNode *UhdmAst::find_ancestor(const std::unordered_set<AST::AstNodeType> &types)
+{
+    auto searched_node = this;
+    while (searched_node) {
+        if (searched_node->current_node) {
+            if (types.find(searched_node->current_node->type) != types.end()) {
+                return searched_node->current_node;
+            }
+        }
+        searched_node = searched_node->parent;
+    }
+    return nullptr;
+}
+
+void UhdmAst::process_design()
+{
+    current_node = make_ast_node(AST::AST_DESIGN);
+    visit_one_to_many({UHDM::uhdmallInterfaces, UHDM::uhdmallPackages, UHDM::uhdmtopPackages, UHDM::uhdmallModules, UHDM::uhdmtopModules}, obj_h,
+                      [&](AST::AstNode *node) {
+                          if (node) {
+                              shared.top_nodes[node->str] = node;
+                          }
+                      });
+    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {});
+    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+        if (node)
+            move_type_to_new_typedef(current_node, node);
+    });
+    for (auto pair : shared.top_nodes) {
+        if (!pair.second)
+            continue;
+        if (pair.second->type == AST::AST_PACKAGE) {
+            check_memories(pair.second);
+            setup_current_scope(shared.top_nodes, pair.second);
+            simplify(pair.second, nullptr);
+            clear_current_scope();
+        }
+    }
+    // Once we walked everything, unroll that as children of this node
+    for (auto &pair : shared.top_nodes) {
+        if (!pair.second)
+            continue;
+        if (!pair.second->get_bool_attribute(UhdmAst::partial())) {
+            if (pair.second->type == AST::AST_PACKAGE)
+                current_node->children.insert(current_node->children.begin(), pair.second);
+            else {
+                check_memories(pair.second);
+                setup_current_scope(shared.top_nodes, pair.second);
+                simplify(pair.second, nullptr);
+                clear_current_scope();
+                current_node->children.push_back(pair.second);
+            }
+        } else {
+            log_warning("Removing unused module: %s from the design.\n", pair.second->str.c_str());
+            // TODO: This should be properly erased from the module, but it seems that it's
+            // needed to resolve scope
+            delete pair.second;
+            pair.second = nullptr;
+        }
+    }
+}
+
+void UhdmAst::simplify_parameter(AST::AstNode *parameter, AST::AstNode *module_node)
+{
+    setup_current_scope(shared.top_nodes, shared.current_top_node);
+    visitEachDescendant(shared.current_top_node, [&](AST::AstNode *current_scope_node) {
+        if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
+            current_scope_node->type == AST::AST_LOCALPARAM) {
+            if (current_scope_node->type == AST::AST_TYPEDEF)
+                simplify(current_scope_node, nullptr);
+            AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
+        }
+    });
+    if (module_node) {
+        visitEachDescendant(module_node, [&](AST::AstNode *current_scope_node) {
+            if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
+                current_scope_node->type == AST::AST_LOCALPARAM) {
+                AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
+            }
+        });
+    }
+    // first apply custom simplification step if needed
+    simplify(parameter, nullptr);
+    // then simplify parameter to AST_CONSTANT or AST_REALVALUE
+    while (parameter->simplify(true, false, false, 1, -1, false, false)) {
+    }
+    clear_current_scope();
+}
+
+void UhdmAst::process_module()
+{
+    std::string type = vpi_get_str(vpiDefName, obj_h);
+    std::string name = vpi_get_str(vpiName, obj_h) ? vpi_get_str(vpiName, obj_h) : type;
+    bool is_module_instance = type != name;
+    sanitize_symbol_name(type);
+    sanitize_symbol_name(name);
+    type = strip_package_name(type);
+    name = strip_package_name(name);
+    if (!is_module_instance) {
+        if (shared.top_nodes.find(type) != shared.top_nodes.end()) {
+            current_node = shared.top_nodes[type];
+            shared.current_top_node = current_node;
+            auto process_it = std::find_if(current_node->children.begin(), current_node->children.end(),
+                                           [](auto node) { return node->type == AST::AST_INITIAL || node->type == AST::AST_ALWAYS; });
+            auto children_after_process = std::vector<AST::AstNode *>(process_it, current_node->children.end());
+            current_node->children.erase(process_it, current_node->children.end());
+            visit_one_to_many({vpiModule, vpiInterface, vpiParameter, vpiParamAssign, vpiPort, vpiNet, vpiArrayNet, vpiTaskFunc, vpiGenScopeArray,
+                               vpiContAssign, vpiVariables},
+                              obj_h, [&](AST::AstNode *node) {
+                                  if (node) {
+                                      add_or_replace_child(current_node, node);
+                                  }
+                              });
+            // Primitives will have the same names (like "and"), so we need to make sure we don't replace them
+            visit_one_to_many({vpiPrimitive}, obj_h, [&](AST::AstNode *node) {
+                if (node) {
+                    current_node->children.push_back(node);
+                }
+            });
+            current_node->children.insert(current_node->children.end(), children_after_process.begin(), children_after_process.end());
+
+            auto it = current_node->attributes.find(UhdmAst::partial());
+            if (it != current_node->attributes.end()) {
+                delete it->second;
+                current_node->attributes.erase(it);
+            }
+        } else {
+            current_node = make_ast_node(AST::AST_MODULE);
+            current_node->str = type;
+            shared.top_nodes[current_node->str] = current_node;
+            shared.current_top_node = current_node;
+            current_node->attributes[UhdmAst::partial()] = AST::AstNode::mkconst_int(1, false, 1);
+            visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+                if (node) {
+                    move_type_to_new_typedef(current_node, node);
+                }
+            });
+            visit_one_to_many({vpiModule, vpiInterface, vpiTaskFunc, vpiParameter, vpiParamAssign, vpiPort, vpiNet, vpiArrayNet, vpiGenScopeArray,
+                               vpiContAssign, vpiProcess, vpiClockingBlock, vpiAssertion},
+                              obj_h, [&](AST::AstNode *node) {
+                                  if (node) {
+                                      if (node->type == AST::AST_ASSIGN && node->children.size() < 2)
+                                          return;
+                                      add_or_replace_child(current_node, node);
+                                  }
+                              });
+        }
+    } else {
+        // Not a top module, create instance
+        current_node = make_ast_node(AST::AST_CELL);
+        std::string module_parameters;
+        visit_one_to_many({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
+            if (node && node->type == AST::AST_PARAMETER) {
+                if (node->children[0]->type != AST::AST_CONSTANT) {
+                    if (shared.top_nodes.count(type)) {
+                        simplify_parameter(node, shared.top_nodes[type]);
+                        log_assert(node->children[0]->type == AST::AST_CONSTANT || node->children[0]->type == AST::AST_REALVALUE);
+                    }
+                }
+                if (shared.top_nodes.count(type)) {
+                    if (!node->children[0]->str.empty())
+                        module_parameters += node->str + "=" + node->children[0]->str;
+                    else
+                        module_parameters +=
+                          node->str + "=" + std::to_string(node->children[0]->bits.size()) + "'d" + std::to_string(node->children[0]->integer);
+                }
+                delete node;
+            }
+        });
+        // rename module in same way yosys do
+        std::string module_name;
+        if (module_parameters.size() > 60)
+            module_name = "$paramod$" + sha1(module_parameters) + type;
+        else if (!module_parameters.empty())
+            module_name = "$paramod" + type + module_parameters;
+        else
+            module_name = type;
+        auto module_node = shared.top_nodes[module_name];
+        auto cell_instance = vpi_get(vpiCellInstance, obj_h);
+        if (!module_node) {
+            module_node = shared.top_nodes[type];
+            if (!module_node) {
+                module_node = new AST::AstNode(AST::AST_MODULE);
+                module_node->str = type;
+                module_node->attributes[UhdmAst::partial()] = AST::AstNode::mkconst_int(2, false, 1);
+                cell_instance = 1;
+                module_name = type;
+            }
+            if (!module_parameters.empty()) {
+                module_node = module_node->clone();
+            }
+        }
+        module_node->str = module_name;
+        shared.top_nodes[module_node->str] = module_node;
+        if (cell_instance) {
+            module_node->attributes[ID::whitebox] = AST::AstNode::mkconst_int(1, false, 1);
+        }
+        visit_one_to_many({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                if (node->children[0]->type != AST::AST_CONSTANT) {
+                    if (shared.top_nodes[type]) {
+                        simplify_parameter(node, module_node);
+                        log_assert(node->children[0]->type == AST::AST_CONSTANT || node->children[0]->type == AST::AST_REALVALUE);
+                    }
+                }
+                auto parent_node = std::find_if(module_node->children.begin(), module_node->children.end(), [&](AST::AstNode *child) -> bool {
+                    return ((child->type == AST::AST_PARAMETER) || (child->type == AST::AST_LOCALPARAM)) && child->str == node->str &&
+                           // skip real parameters as they are currently not working: https://github.com/alainmarcel/Surelog/issues/1035
+                           child->type != AST::AST_REALVALUE;
+                });
+                if (parent_node != module_node->children.end()) {
+                    if ((*parent_node)->type == AST::AST_PARAMETER) {
+                        if (cell_instance ||
+                            (!node->children.empty() &&
+                             node->children[0]->type !=
+                               AST::AST_CONSTANT)) { // if cell is a blackbox or we need to simplify parameter first, left setting parameters to yosys
+                            // We only want to add AST_PARASET for parameters that is different than already set
+                            // to match the name yosys gives to the module.
+                            // Note: this should also be applied for other (not only cell_instance) modules
+                            // but as we are using part of the modules parsed by sv2v and other
+                            // part by uhdm, we need to always rename module if it is parametrized,
+                            // Otherwise, verilog frontend can use module parsed by uhdm and try to set
+                            // parameters, but this module would be already parametrized
+                            if ((node->children[0]->integer != (*parent_node)->children[0]->integer ||
+                                 node->children[0]->str != (*parent_node)->children[0]->str)) {
+                                node->type = AST::AST_PARASET;
+                                current_node->children.push_back(node);
+                            }
+                        } else {
+                            add_or_replace_child(module_node, node);
+                        }
+                    } else {
+                        add_or_replace_child(module_node, node);
+                    }
+                } else if ((module_node->attributes.count(UhdmAst::partial()) && module_node->attributes[UhdmAst::partial()]->integer == 2)) {
+                    // When module definition is not parsed by Surelog, left setting parameters to yosys
+                    node->type = AST::AST_PARASET;
+                    current_node->children.push_back(node);
+                }
+            }
+        });
+        // TODO: setting keep attribute probably shouldn't be needed,
+        // but without this, modules that are generated in genscope are removed
+        // for now lets just add this attribute
+        module_node->attributes[ID::keep] = AST::AstNode::mkconst_int(1, false, 1);
+        if (module_node->attributes.count(UhdmAst::partial())) {
+            AST::AstNode *attr = module_node->attributes.at(UhdmAst::partial());
+            if (attr->type == AST::AST_CONSTANT)
+                if (attr->integer == 1) {
+                    delete attr;
+                    module_node->attributes.erase(UhdmAst::partial());
+                }
+        }
+        auto typeNode = new AST::AstNode(AST::AST_CELLTYPE);
+        typeNode->str = module_node->str;
+        current_node->children.insert(current_node->children.begin(), typeNode);
+        auto old_top = shared.current_top_node;
+        shared.current_top_node = module_node;
+        visit_one_to_many({vpiVariables, vpiNet, vpiArrayNet}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                add_or_replace_child(module_node, node);
+            }
+        });
+        visit_one_to_many({vpiInterface, vpiModule, vpiPort, vpiGenScopeArray}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                add_or_replace_child(module_node, node);
+            }
+        });
+        make_cell(obj_h, current_node, module_node);
+        shared.current_top_node = old_top;
+    }
+}
+
+void UhdmAst::process_struct_typespec()
+{
+    current_node = make_ast_node(AST::AST_STRUCT);
+    visit_one_to_many({vpiTypespecMember}, obj_h, [&](AST::AstNode *node) {
+        if (node->children.size() > 0 && node->children[0]->type == AST::AST_ENUM) {
+            log_assert(node->children.size() == 1);
+            log_assert(!node->children[0]->children.empty());
+            log_assert(!node->children[0]->children[0]->children.empty());
+            // TODO: add missing enum_type attribute
+            auto range = make_range(0, 0);
+            // check if single enum element is larger than 1 bit
+            if (node->children[0]->children[0]->children.size() == 2) {
+                range = node->children[0]->children[0]->children[1]->clone();
+            }
+            delete node->children[0];
+            node->children.clear();
+            node->children.push_back(range);
+        }
+        current_node->children.push_back(node);
+    });
+}
+
+void UhdmAst::process_union_typespec()
+{
+    current_node = make_ast_node(AST::AST_UNION);
+    visit_one_to_many({vpiTypespecMember}, obj_h, [&](AST::AstNode *node) {
+        if (node->children.size() > 0 && node->children[0]->type == AST::AST_ENUM) {
+            log_assert(node->children.size() == 1);
+            log_assert(!node->children[0]->children.empty());
+            log_assert(!node->children[0]->children[0]->children.empty());
+            // TODO: add missing enum_type attribute
+            auto range = make_range(0, 0);
+            // check if single enum element is larger than 1 bit
+            if (node->children[0]->children[0]->children.size() == 2) {
+                range = node->children[0]->children[0]->children[1]->clone();
+            }
+            delete node->children[0];
+            node->children.clear();
+            node->children.push_back(range);
+        }
+        current_node->children.push_back(node);
+    });
+}
+
+void UhdmAst::process_array_typespec()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    visit_one_to_one({vpiElemTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node && node->type == AST::AST_STRUCT) {
+            auto str = current_node->str;
+            node->cloneInto(current_node);
+            current_node->str = str;
+            delete node;
+        }
+    });
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_typespec_member()
+{
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    current_node = make_ast_node(AST::AST_STRUCT_ITEM);
+    current_node->str = current_node->str.substr(1);
+    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
+    int typespec_type = vpi_get(vpiType, typespec_h);
+    const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
+    const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+    switch (typespec_type) {
+    case vpiBitTypespec:
+    case vpiLogicTypespec: {
+        current_node->is_logic = true;
+        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        shared.report.mark_handled(typespec_h);
+        break;
+    }
+    case vpiByteTypespec: {
+        current_node->is_signed = true;
+        packed_ranges.push_back(make_range(7, 0));
+        shared.report.mark_handled(typespec_h);
+        break;
+    }
+    case vpiShortIntTypespec: {
+        current_node->is_signed = true;
+        packed_ranges.push_back(make_range(15, 0));
+        shared.report.mark_handled(typespec_h);
+        break;
+    }
+    case vpiIntTypespec:
+    case vpiIntegerTypespec: {
+        current_node->is_signed = true;
+        packed_ranges.push_back(make_range(31, 0));
+        shared.report.mark_handled(typespec_h);
+        break;
+    }
+    case vpiTimeTypespec:
+    case vpiLongIntTypespec: {
+        current_node->is_signed = true;
+        packed_ranges.push_back(make_range(63, 0));
+        shared.report.mark_handled(typespec_h);
+        break;
+    }
+    case vpiStructTypespec:
+    case vpiUnionTypespec:
+    case vpiEnumTypespec: {
+        visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+            if (typespec_type == vpiStructTypespec || typespec_type == vpiUnionTypespec) {
+                auto str = current_node->str;
+                node->cloneInto(current_node);
+                current_node->str = str;
+                delete node;
+            } else if (typespec_type == vpiEnumTypespec) {
+                current_node->children.push_back(node);
+            } else {
+                delete node;
+            }
+        });
+        break;
+    }
+    case vpiPackedArrayTypespec:
+        visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+            if (node && node->type == AST::AST_STRUCT) {
+                auto str = current_node->str;
+                if (node->attributes.count(UhdmAst::packed_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
+                        packed_ranges.push_back(r->clone());
+                    }
+                    std::reverse(packed_ranges.begin(), packed_ranges.end());
+                    node->attributes.erase(UhdmAst::packed_ranges());
+                }
+                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
+                        unpacked_ranges.push_back(r->clone());
+                    }
+                    node->attributes.erase(UhdmAst::unpacked_ranges());
+                }
+                node->cloneInto(current_node);
+                current_node->str = str;
+                current_node->children.insert(current_node->children.end(), packed_ranges.begin(), packed_ranges.end());
+                packed_ranges.clear();
+                delete node;
+            } else if (node) {
+                auto str = current_node->str;
+                if (node->attributes.count(UhdmAst::packed_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
+                        packed_ranges.push_back(r->clone());
+                    }
+                    std::reverse(packed_ranges.begin(), packed_ranges.end());
+                    node->attributes.erase(UhdmAst::packed_ranges());
+                }
+                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
+                        unpacked_ranges.push_back(r->clone());
+                    }
+                    node->attributes.erase(UhdmAst::unpacked_ranges());
+                }
+                node->cloneInto(current_node);
+                current_node->str = str;
+                current_node->type = AST::AST_STRUCT_ITEM;
+                delete node;
+            }
+        });
+        break;
+    case vpiVoidTypespec: {
+        report_error("%s:%d: Void typespecs are currently unsupported", object->VpiFile().c_str(), object->VpiLineNo());
+        break;
+    }
+    case vpiClassTypespec: {
+        report_error("%s:%d: Class typespecs are unsupported", object->VpiFile().c_str(), object->VpiLineNo());
+        break;
+    }
+    default: {
+        report_error("%s:%d: Encountered unhandled typespec in process_typespec_member: '%s' of type '%s'\n", object->VpiFile().c_str(),
+                     object->VpiLineNo(), object->VpiName().c_str(), UHDM::VpiTypeName(typespec_h).c_str());
+        break;
+    }
+    }
+    vpi_release_handle(typespec_h);
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_enum_typespec()
+{
+    current_node = make_ast_node(AST::AST_ENUM);
+    visit_one_to_one({vpiTypedefAlias}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->attributes["\\enum_base_type"] = node->clone();
+        }
+    });
+    visit_one_to_many({vpiEnumConst}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+    vpiHandle typespec_h = vpi_handle(vpiBaseTypespec, obj_h);
+    if (typespec_h) {
+        int typespec_type = vpi_get(vpiType, typespec_h);
+        switch (typespec_type) {
+        case vpiLogicTypespec: {
+            current_node->is_logic = true;
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiByteTypespec:
+        case vpiIntTypespec:
+        case vpiIntegerTypespec: {
+            current_node->is_signed = true;
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiBitTypespec: {
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        default: {
+            const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
+            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+            report_error("%s:%d: Encountered unhandled typespec in process_enum_typespec: '%s' of type '%s'\n", object->VpiFile().c_str(),
+                         object->VpiLineNo(), object->VpiName().c_str(), UHDM::VpiTypeName(typespec_h).c_str());
+            break;
+        }
+        }
+        vpi_release_handle(typespec_h);
+    }
+}
+
+void UhdmAst::process_enum_const()
+{
+    current_node = make_ast_node(AST::AST_ENUM_ITEM);
+    AST::AstNode *constant_node = process_value(obj_h);
+    if (constant_node) {
+        constant_node->filename = current_node->filename;
+        constant_node->location = current_node->location;
+        current_node->children.push_back(constant_node);
+        current_node->children.push_back(make_range(constant_node->range_left, constant_node->range_right, true));
+    }
+}
+
+void UhdmAst::process_custom_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node->str.empty()) {
+            // anonymous typespec, move the children to variable
+            current_node->type = node->type;
+            copy_packed_unpacked_attribute(node, current_node);
+            current_node->children = std::move(node->children);
+        } else {
+            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+            wiretype_node->str = node->str;
+            current_node->children.push_back(wiretype_node);
+        }
+        delete node;
+    });
+    auto type = vpi_get(vpiType, obj_h);
+    if (type == vpiEnumVar || type == vpiStructVar || type == vpiUnionVar) {
+        visit_default_expr(obj_h);
+    }
+    current_node->is_custom_type = true;
+}
+
+void UhdmAst::process_int_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    auto left_const = AST::AstNode::mkconst_int(31, true);
+    auto right_const = AST::AstNode::mkconst_int(0, true);
+    auto range = new AST::AstNode(AST::AST_RANGE, left_const, right_const);
+    current_node->children.push_back(range);
+    current_node->is_signed = true;
+    visit_default_expr(obj_h);
+}
+
+void UhdmAst::process_real_var()
+{
+    auto module_node = find_ancestor({AST::AST_MODULE});
+    auto wire_node = make_ast_node(AST::AST_WIRE);
+    auto left_const = AST::AstNode::mkconst_int(63, true);
+    auto right_const = AST::AstNode::mkconst_int(0, true);
+    auto range = new AST::AstNode(AST::AST_RANGE, left_const, right_const);
+    wire_node->children.push_back(range);
+    wire_node->is_signed = true;
+    module_node->children.push_back(wire_node);
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    visit_default_expr(obj_h);
+}
+
+void UhdmAst::process_array_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node->str.empty()) {
+            // anonymous typespec, move the children to variable
+            current_node->type = node->type;
+            current_node->children = std::move(node->children);
+        } else {
+            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+            wiretype_node->str = node->str;
+            current_node->children.push_back(wiretype_node);
+            current_node->is_custom_type = true;
+        }
+        delete node;
+    });
+    vpiHandle itr = vpi_iterate(vpi_get(vpiType, obj_h) == vpiArrayVar ? vpiReg : vpiElement, obj_h);
+    while (vpiHandle reg_h = vpi_scan(itr)) {
+        if (vpi_get(vpiType, reg_h) == vpiStructVar || vpi_get(vpiType, reg_h) == vpiEnumVar) {
+            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
+                if (node->str.empty()) {
+                    // anonymous typespec, move the children to variable
+                    current_node->type = node->type;
+                    current_node->children = std::move(node->children);
+                } else {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                }
+                delete node;
+            });
+        } else if (vpi_get(vpiType, reg_h) == vpiLogicVar) {
+            current_node->is_logic = true;
+            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
+                if (node->str.empty()) {
+                    // anonymous typespec, move the children to variable
+                    current_node->type = node->type;
+                    current_node->children = std::move(node->children);
+                } else {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                }
+                delete node;
+            });
+            visit_one_to_many({vpiRange}, reg_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        } else if (vpi_get(vpiType, reg_h) == vpiIntVar) {
+            packed_ranges.push_back(make_range(31, 0));
+            visit_default_expr(reg_h);
+        }
+        vpi_release_handle(reg_h);
+    }
+    vpi_release_handle(itr);
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    visit_default_expr(obj_h);
+}
+
+void UhdmAst::process_packed_array_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node->str.empty()) {
+            // anonymous typespec, move the children to variable
+            current_node->type = node->type;
+            current_node->children = std::move(node->children);
+        } else {
+            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+            wiretype_node->str = node->str;
+            current_node->children.push_back(wiretype_node);
+            current_node->is_custom_type = true;
+        }
+        delete node;
+    });
+    vpiHandle itr = vpi_iterate(vpi_get(vpiType, obj_h) == vpiArrayVar ? vpiReg : vpiElement, obj_h);
+    while (vpiHandle reg_h = vpi_scan(itr)) {
+        if (vpi_get(vpiType, reg_h) == vpiStructVar || vpi_get(vpiType, reg_h) == vpiEnumVar) {
+            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
+                if (node->str.empty()) {
+                    // anonymous typespec, move the children to variable
+                    current_node->type = node->type;
+                    current_node->children = std::move(node->children);
+                } else {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                }
+                delete node;
+            });
+        } else if (vpi_get(vpiType, reg_h) == vpiLogicVar) {
+            current_node->is_logic = true;
+            visit_one_to_one({vpiTypespec}, reg_h, [&](AST::AstNode *node) {
+                if (node->str.empty()) {
+                    // anonymous typespec, move the children to variable
+                    current_node->type = node->type;
+                    current_node->children = std::move(node->children);
+                } else {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                }
+                delete node;
+            });
+            visit_one_to_many({vpiRange}, reg_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        } else if (vpi_get(vpiType, reg_h) == vpiIntVar) {
+            packed_ranges.push_back(make_range(31, 0));
+            visit_default_expr(reg_h);
+        }
+        vpi_release_handle(reg_h);
+    }
+    vpi_release_handle(itr);
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    visit_default_expr(obj_h);
+}
+
+void UhdmAst::process_param_assign()
+{
+    current_node = make_ast_node(AST::AST_PARAMETER);
+    visit_one_to_one({vpiLhs}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->type = node->type;
+            current_node->str = node->str;
+            // Here we need to copy any ranges that is already present in lhs,
+            // but we want to skip actual value, as it is set in rhs
+            for (auto *c : node->children) {
+                if (c->type != AST::AST_CONSTANT) {
+                    current_node->children.push_back(c->clone());
+                }
+            }
+            copy_packed_unpacked_attribute(node, current_node);
+            if (node->attributes.count(UhdmAst::is_imported())) {
+                current_node->attributes[UhdmAst::is_imported()] = node->attributes[UhdmAst::is_imported()]->clone();
+            }
+            current_node->is_custom_type = node->is_custom_type;
+            shared.param_types[current_node->str] = shared.param_types[node->str];
+            delete node;
+        }
+    });
+    visit_one_to_one({vpiRhs}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->children.size() > 1 && (node->children[1]->type == AST::AST_PARAMETER || node->children[1]->type == AST::AST_LOCALPARAM)) {
+                node->children[1]->type = AST::AST_IDENTIFIER;
+            }
+            current_node->children.insert(current_node->children.begin(), node);
+        }
+    });
+}
+
+void UhdmAst::process_cont_assign_var_init()
+{
+    current_node = make_ast_node(AST::AST_INITIAL);
+    auto block_node = make_ast_node(AST::AST_BLOCK);
+    auto assign_node = make_ast_node(AST::AST_ASSIGN_LE);
+    block_node->children.push_back(assign_node);
+    current_node->children.push_back(block_node);
+
+    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type == AST::AST_WIRE || node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
+                assign_node->children.push_back(new AST::AstNode(AST::AST_IDENTIFIER));
+                assign_node->children.back()->str = node->str;
+            } else {
+                assign_node->children.push_back(node);
+            }
+        }
+    });
+}
+
+void UhdmAst::process_cont_assign_net()
+{
+    current_node = make_ast_node(AST::AST_ASSIGN);
+
+    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type == AST::AST_WIRE || node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
+                current_node->children.push_back(new AST::AstNode(AST::AST_IDENTIFIER));
+                current_node->children.back()->str = node->str;
+            } else {
+                current_node->children.push_back(node);
+            }
+        }
+    });
+}
+
+void UhdmAst::process_cont_assign()
+{
+    auto net_decl_assign = vpi_get(vpiNetDeclAssign, obj_h);
+    vpiHandle node_lhs_h = vpi_handle(vpiLhs, obj_h);
+    auto lhs_net_type = vpi_get(vpiNetType, node_lhs_h);
+    vpi_release_handle(node_lhs_h);
+
+    // Check if lhs is a subtype of a net
+    bool isNet;
+    if (lhs_net_type >= vpiWire && lhs_net_type <= vpiUwire)
+        isNet = true;
+    else
+        // lhs is a variable
+        isNet = false;
+    if (net_decl_assign && !isNet)
+        process_cont_assign_var_init();
+    else
+        process_cont_assign_net();
+}
+
+void UhdmAst::process_assignment()
+{
+    auto type = vpi_get(vpiBlocking, obj_h) == 1 ? AST::AST_ASSIGN_EQ : AST::AST_ASSIGN_LE;
+    current_node = make_ast_node(type);
+    visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
+                node->type = AST::AST_IDENTIFIER;
+            }
+            current_node->children.push_back(node);
+        }
+    });
+    if (current_node->children.size() == 1 && current_node->children[0]->type == AST::AST_WIRE) {
+        auto top_node = find_ancestor({AST::AST_MODULE});
+        if (!top_node)
+            return;
+        top_node->children.push_back(current_node->children[0]->clone());
+        current_node = nullptr;
+    }
+}
+
+void UhdmAst::process_packed_array_net()
+{
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    current_node = make_ast_node(AST::AST_WIRE);
+    visit_one_to_many({vpiElement}, obj_h, [&](AST::AstNode *node) {
+        if (node && GetSize(node->children) == 1)
+            current_node->children.push_back(node->children[0]);
+        current_node->is_custom_type = node->is_custom_type;
+    });
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_array_net(const UHDM::BaseClass *object)
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    vpiHandle itr = vpi_iterate(vpiNet, obj_h);
+    std::vector<AST::AstNode *> packed_ranges;
+    std::vector<AST::AstNode *> unpacked_ranges;
+    while (vpiHandle net_h = vpi_scan(itr)) {
+        auto net_type = vpi_get(vpiType, net_h);
+        if (net_type == vpiLogicNet) {
+            current_node->is_logic = true;
+            current_node->is_signed = vpi_get(vpiSigned, net_h);
+            vpiHandle typespec_h = vpi_handle(vpiTypespec, net_h);
+            if (!typespec_h) {
+                typespec_h = vpi_handle(vpiTypespec, obj_h);
+            }
+            if (typespec_h) {
+                visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+                vpi_release_handle(typespec_h);
+            } else {
+                visit_one_to_many({vpiRange}, net_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+            }
+            shared.report.mark_handled(net_h);
+        } else if (net_type == vpiStructNet) {
+            visit_one_to_one({vpiTypespec}, net_h, [&](AST::AstNode *node) {
+                if (node->str.empty()) {
+                    // anonymous typespec, move the children to variable
+                    current_node->type = node->type;
+                    current_node->children = std::move(node->children);
+                } else {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                }
+                delete node;
+            });
+        }
+        vpi_release_handle(net_h);
+    }
+    vpi_release_handle(itr);
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_package()
+{
+    current_node = make_ast_node(AST::AST_PACKAGE);
+    shared.current_top_node = current_node;
+    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            move_type_to_new_typedef(current_node, node);
+        }
+    });
+    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            node->str = strip_package_name(node->str);
+            for (auto c : node->children) {
+                c->str = strip_package_name(c->str);
+            }
+            add_or_replace_child(current_node, node);
+        }
+    });
+    visit_one_to_many({vpiTaskFunc}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_interface()
+{
+    std::string type = vpi_get_str(vpiDefName, obj_h);
+    std::string name = vpi_get_str(vpiName, obj_h) ? vpi_get_str(vpiName, obj_h) : type;
+    sanitize_symbol_name(type);
+    sanitize_symbol_name(name);
+    AST::AstNode *elaboratedInterface;
+    // Check if we have encountered this object before
+    if (shared.top_nodes.find(type) != shared.top_nodes.end()) {
+        // Was created before, fill missing
+        elaboratedInterface = shared.top_nodes[type];
+        visit_one_to_many({vpiPort}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                add_or_replace_child(elaboratedInterface, node);
+            }
+        });
+    } else {
+        // Encountered for the first time
+        elaboratedInterface = new AST::AstNode(AST::AST_INTERFACE);
+        elaboratedInterface->str = name;
+        visit_one_to_many({vpiNet, vpiPort, vpiModport}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                add_or_replace_child(elaboratedInterface, node);
+            }
+        });
+    }
+    shared.top_nodes[elaboratedInterface->str] = elaboratedInterface;
+    if (name != type) {
+        // Not a top module, create instance
+        current_node = make_ast_node(AST::AST_CELL);
+        make_cell(obj_h, current_node, elaboratedInterface);
+    } else {
+        current_node = elaboratedInterface;
+    }
+}
+
+void UhdmAst::process_modport()
+{
+    current_node = make_ast_node(AST::AST_MODPORT);
+    visit_one_to_many({vpiIODecl}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_io_decl()
+{
+    current_node = nullptr;
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) { current_node = node; });
+    if (current_node == nullptr) {
+        current_node = make_ast_node(AST::AST_MODPORTMEMBER);
+        visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
+    }
+    std::reverse(unpacked_ranges.begin(), unpacked_ranges.end());
+
+    visit_one_to_one({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (!node->str.empty()) {
+                auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                wiretype_node->str = node->str;
+                // wiretype needs to be 1st node (if port have also another range nodes)
+                current_node->children.insert(current_node->children.begin(), wiretype_node);
+                current_node->is_custom_type = true;
+            } else {
+                // anonymous typedef, just move children
+                for (auto child : node->children) {
+                    current_node->children.push_back(child->clone());
+                }
+                if (node->attributes.count(UhdmAst::packed_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
+                        packed_ranges.push_back(r->clone());
+                    }
+                }
+                if (node->attributes.count(UhdmAst::unpacked_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::unpacked_ranges()]->children) {
+                        unpacked_ranges.push_back(r->clone());
+                    }
+                }
+                current_node->is_logic = node->is_logic;
+                current_node->is_reg = node->is_reg;
+            }
+            delete node;
+        }
+    });
+    if (const int n = vpi_get(vpiDirection, obj_h)) {
+        if (n == vpiInput) {
+            current_node->is_input = true;
+        } else if (n == vpiOutput) {
+            current_node->is_output = true;
+        } else if (n == vpiInout) {
+            current_node->is_input = true;
+            current_node->is_output = true;
+        }
+    }
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges, false);
+}
+
+void UhdmAst::process_always()
+{
+    current_node = make_ast_node(AST::AST_ALWAYS);
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            AST::AstNode *block = nullptr;
+            if (node->type != AST::AST_BLOCK) {
+                block = new AST::AstNode(AST::AST_BLOCK, node);
+            } else {
+                block = node;
+            }
+            current_node->children.push_back(block);
+        } else {
+            // create empty block
+            current_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
+        }
+    });
+    switch (vpi_get(vpiAlwaysType, obj_h)) {
+    case vpiAlwaysComb:
+        current_node->attributes[ID::always_comb] = AST::AstNode::mkconst_int(1, false);
+        break;
+    case vpiAlwaysFF:
+        current_node->attributes[ID::always_ff] = AST::AstNode::mkconst_int(1, false);
+        break;
+    case vpiAlwaysLatch:
+        current_node->attributes[ID::always_latch] = AST::AstNode::mkconst_int(1, false);
+        break;
+    default:
+        break;
+    }
+}
+
+void UhdmAst::process_event_control(const UHDM::BaseClass *object)
+{
+    current_node = make_ast_node(AST::AST_BLOCK);
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            auto process_node = find_ancestor({AST::AST_ALWAYS});
+            if (!process_node) {
+                log_error("%s:%d: Currently supports only event control stmts inside 'always'\n", object->VpiFile().c_str(), object->VpiLineNo());
+            }
+            process_node->children.push_back(node);
+        }
+        // is added inside vpiOperation
+    });
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_initial()
+{
+    current_node = make_ast_node(AST::AST_INITIAL);
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type != AST::AST_BLOCK) {
+                auto block_node = make_ast_node(AST::AST_BLOCK);
+                block_node->children.push_back(node);
+                node = block_node;
+            }
+            current_node->children.push_back(node);
+        } else {
+            current_node->children.push_back(make_ast_node(AST::AST_BLOCK));
+        }
+    });
+}
+
+void UhdmAst::process_begin(bool is_named)
+{
+    current_node = make_ast_node(AST::AST_BLOCK);
+    if (!is_named) {
+        // for unnamed block, reset block name
+        current_node->str = "";
+    }
+    AST::AstNode *hierarchy_node = nullptr;
+    static int unnamed_block_idx = 0;
+    visit_one_to_many({vpiVariables}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (!is_named) {
+                if (!hierarchy_node) {
+                    // Create an implicit hierarchy scope
+                    // simplify checks if sv_mode is set to true when wire is declared inside unnamed block
+                    VERILOG_FRONTEND::sv_mode = true;
+                    hierarchy_node = make_ast_node(AST::AST_BLOCK);
+                    hierarchy_node->str = "$unnamed_block$" + std::to_string(unnamed_block_idx++);
+                }
+                hierarchy_node->children.push_back(node);
+            } else {
+                current_node->children.push_back(node);
+            }
+        }
+    });
+    visit_one_to_many({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if ((node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) && node->children.size() == 1) {
+                auto func_node = find_ancestor({AST::AST_FUNCTION, AST::AST_TASK});
+                if (!func_node)
+                    return;
+                auto wire_node = new AST::AstNode(AST::AST_WIRE);
+                wire_node->type = AST::AST_WIRE;
+                wire_node->str = node->children[0]->str;
+                func_node->children.push_back(wire_node);
+            } else {
+                if (hierarchy_node)
+                    hierarchy_node->children.push_back(node);
+                else
+                    current_node->children.push_back(node);
+            }
+        }
+    });
+    if (hierarchy_node)
+        current_node->children.push_back(hierarchy_node);
+}
+
+void UhdmAst::process_operation(const UHDM::BaseClass *object)
+{
+    auto operation = vpi_get(vpiOpType, obj_h);
+    switch (operation) {
+    case vpiStreamRLOp:
+        process_stream_op();
+        break;
+    case vpiEventOrOp:
+    case vpiListOp:
+        process_list_op();
+        break;
+    case vpiCastOp:
+        process_cast_op();
+        break;
+    case vpiInsideOp:
+        process_inside_op();
+        break;
+    case vpiAssignmentPatternOp:
+        process_assignment_pattern_op();
+        break;
+    case vpiWildEqOp:
+    case vpiWildNeqOp: {
+        report_error("%s:%d: Wildcard operators are not supported yet\n", object->VpiFile().c_str(), object->VpiLineNo());
+        break;
+    }
+    default: {
+        current_node = make_ast_node(AST::AST_NONE);
+        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+            if (node) {
+                current_node->children.push_back(node);
+            }
+        });
+        switch (operation) {
+        case vpiMinusOp:
+            current_node->type = AST::AST_NEG;
+            break;
+        case vpiPlusOp:
+            current_node->type = AST::AST_POS;
+            break;
+        case vpiPosedgeOp:
+            current_node->type = AST::AST_POSEDGE;
+            break;
+        case vpiNegedgeOp:
+            current_node->type = AST::AST_NEGEDGE;
+            break;
+        case vpiUnaryAndOp:
+            current_node->type = AST::AST_REDUCE_AND;
+            break;
+        case vpiUnaryOrOp:
+            current_node->type = AST::AST_REDUCE_OR;
+            break;
+        case vpiUnaryXorOp:
+            current_node->type = AST::AST_REDUCE_XOR;
+            break;
+        case vpiUnaryXNorOp:
+            current_node->type = AST::AST_REDUCE_XNOR;
+            break;
+        case vpiUnaryNandOp: {
+            current_node->type = AST::AST_REDUCE_AND;
+            auto not_node = new AST::AstNode(AST::AST_LOGIC_NOT, current_node);
+            current_node = not_node;
+            break;
+        }
+        case vpiUnaryNorOp: {
+            current_node->type = AST::AST_REDUCE_OR;
+            auto not_node = new AST::AstNode(AST::AST_LOGIC_NOT, current_node);
+            current_node = not_node;
+            break;
+        }
+        case vpiBitNegOp:
+            current_node->type = AST::AST_BIT_NOT;
+            break;
+        case vpiBitAndOp:
+            current_node->type = AST::AST_BIT_AND;
+            break;
+        case vpiBitOrOp:
+            current_node->type = AST::AST_BIT_OR;
+            break;
+        case vpiBitXorOp:
+            current_node->type = AST::AST_BIT_XOR;
+            break;
+        case vpiBitXnorOp:
+            current_node->type = AST::AST_BIT_XNOR;
+            break;
+        case vpiLShiftOp: {
+            current_node->type = AST::AST_SHIFT_LEFT;
+            log_assert(current_node->children.size() == 2);
+            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
+            current_node->children[1] = unsigned_node;
+            break;
+        }
+        case vpiRShiftOp: {
+            current_node->type = AST::AST_SHIFT_RIGHT;
+            log_assert(current_node->children.size() == 2);
+            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
+            current_node->children[1] = unsigned_node;
+            break;
+        }
+        case vpiNotOp:
+            current_node->type = AST::AST_LOGIC_NOT;
+            break;
+        case vpiLogAndOp:
+            current_node->type = AST::AST_LOGIC_AND;
+            break;
+        case vpiLogOrOp:
+            current_node->type = AST::AST_LOGIC_OR;
+            break;
+        case vpiEqOp:
+            current_node->type = AST::AST_EQ;
+            break;
+        case vpiNeqOp:
+            current_node->type = AST::AST_NE;
+            break;
+        case vpiCaseEqOp:
+            current_node->type = AST::AST_EQX;
+            break;
+        case vpiCaseNeqOp:
+            current_node->type = AST::AST_NEX;
+            break;
+        case vpiGtOp:
+            current_node->type = AST::AST_GT;
+            break;
+        case vpiGeOp:
+            current_node->type = AST::AST_GE;
+            break;
+        case vpiLtOp:
+            current_node->type = AST::AST_LT;
+            break;
+        case vpiLeOp:
+            current_node->type = AST::AST_LE;
+            break;
+        case vpiSubOp:
+            current_node->type = AST::AST_SUB;
+            if (!current_node->children.empty() && current_node->children[0]->type == AST::AST_LOCALPARAM) {
+                current_node->children[0]->type = AST::AST_IDENTIFIER;
+            }
+            break;
+        case vpiAddOp:
+            current_node->type = AST::AST_ADD;
+            break;
+        case vpiMultOp:
+            current_node->type = AST::AST_MUL;
+            break;
+        case vpiDivOp:
+            current_node->type = AST::AST_DIV;
+            break;
+        case vpiModOp:
+            current_node->type = AST::AST_MOD;
+            break;
+        case vpiArithLShiftOp: {
+            current_node->type = AST::AST_SHIFT_SLEFT;
+            log_assert(current_node->children.size() == 2);
+            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
+            current_node->children[1] = unsigned_node;
+            break;
+        }
+        case vpiArithRShiftOp: {
+            current_node->type = AST::AST_SHIFT_SRIGHT;
+            log_assert(current_node->children.size() == 2);
+            auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]);
+            current_node->children[1] = unsigned_node;
+            break;
+        }
+        case vpiPowerOp:
+            current_node->type = AST::AST_POW;
+            break;
+        case vpiPostIncOp: {
+            // TODO: Make this an actual post-increment op (currently it's a pre-increment)
+            log_warning("%s:%d: Post-incrementation operations are handled as pre-incrementation.\n", object->VpiFile().c_str(), object->VpiLineNo());
+            [[fallthrough]];
+        }
+        case vpiPreIncOp: {
+            current_node->type = AST::AST_ASSIGN_EQ;
+            auto id = current_node->children[0]->clone();
+            auto add_node = new AST::AstNode(AST::AST_ADD, id, AST::AstNode::mkconst_int(1, true));
+            add_node->filename = current_node->filename;
+            add_node->location = current_node->location;
+            current_node->children.push_back(add_node);
+            break;
+        }
+        case vpiPostDecOp: {
+            // TODO: Make this an actual post-decrement op (currently it's a pre-decrement)
+            log_warning("%s:%d: Post-decrementation operations are handled as pre-decrementation.\n", object->VpiFile().c_str(), object->VpiLineNo());
+            [[fallthrough]];
+        }
+        case vpiPreDecOp: {
+            current_node->type = AST::AST_ASSIGN_EQ;
+            auto id = current_node->children[0]->clone();
+            auto add_node = new AST::AstNode(AST::AST_SUB, id, AST::AstNode::mkconst_int(1, true));
+            add_node->filename = current_node->filename;
+            add_node->location = current_node->location;
+            current_node->children.push_back(add_node);
+            break;
+        }
+        case vpiConditionOp:
+            current_node->type = AST::AST_TERNARY;
+            break;
+        case vpiConcatOp: {
+            current_node->type = AST::AST_CONCAT;
+            std::reverse(current_node->children.begin(), current_node->children.end());
+            break;
+        }
+        case vpiMultiConcatOp:
+        case vpiMultiAssignmentPatternOp:
+            current_node->type = AST::AST_REPLICATE;
+            break;
+        case vpiAssignmentOp:
+            current_node->type = AST::AST_ASSIGN_EQ;
+            break;
+        case vpiStreamLROp: {
+            auto concat_node = current_node->children.back();
+            current_node->children.pop_back();
+            delete current_node;
+            current_node = concat_node;
+            break;
+        }
+        case vpiNullOp: {
+            delete current_node;
+            current_node = nullptr;
+            break;
+        }
+        case vpiMinTypMaxOp: {
+            // ignore min and max and set only typ
+            log_assert(current_node->children.size() == 3);
+            auto tmp = current_node->children[1]->clone();
+            delete current_node;
+            current_node = tmp;
+            break;
+        }
+        default: {
+            delete current_node;
+            current_node = nullptr;
+            report_error("%s:%d: Encountered unhandled operation type %d\n", object->VpiFile().c_str(), object->VpiLineNo(), operation);
+        }
+        }
+    }
+    }
+}
+
+void UhdmAst::process_stream_op()
+{
+    // Create a for loop that does what a streaming operator would do
+    auto block_node = find_ancestor({AST::AST_BLOCK, AST::AST_ALWAYS, AST::AST_INITIAL});
+    auto process_node = find_ancestor({AST::AST_ALWAYS, AST::AST_INITIAL});
+    auto module_node = find_ancestor({AST::AST_MODULE, AST::AST_FUNCTION, AST::AST_PACKAGE});
+    log_assert(module_node);
+    if (!process_node) {
+        if (module_node->type != AST::AST_FUNCTION) {
+            // Create a @* always block
+            process_node = make_ast_node(AST::AST_ALWAYS);
+            module_node->children.push_back(process_node);
+            block_node = make_ast_node(AST::AST_BLOCK);
+            process_node->children.push_back(block_node);
+        } else {
+            // Create only block
+            block_node = make_ast_node(AST::AST_BLOCK);
+            module_node->children.push_back(block_node);
+        }
+    }
+
+    auto loop_id = shared.next_loop_id();
+    auto loop_counter =
+      make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {AST::AstNode::mkconst_int(31, false), AST::AstNode::mkconst_int(0, false)})});
+    loop_counter->is_reg = true;
+    loop_counter->is_signed = true;
+    loop_counter->str = "\\loop" + std::to_string(loop_id) + "::i";
+    module_node->children.insert(module_node->children.end() - 1, loop_counter);
+    auto loop_counter_ident = make_ast_node(AST::AST_IDENTIFIER);
+    loop_counter_ident->str = loop_counter->str;
+
+    auto lhs_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE})->children[0];
+    // Temp var to allow concatenation
+    AST::AstNode *temp_var = nullptr;
+    AST::AstNode *bits_call = nullptr;
+    if (lhs_node->type == AST::AST_WIRE) {
+        module_node->children.insert(module_node->children.begin(), lhs_node->clone());
+        temp_var = lhs_node->clone(); // if we already have wire as lhs, we want to create the same wire for temp_var
+        lhs_node->delete_children();
+        lhs_node->type = AST::AST_IDENTIFIER;
+        bits_call = make_ast_node(AST::AST_FCALL, {lhs_node->clone()});
+        bits_call->str = "\\$bits";
+    } else {
+        // otherwise, we need to calculate size using bits fcall
+        bits_call = make_ast_node(AST::AST_FCALL, {lhs_node->clone()});
+        bits_call->str = "\\$bits";
+        temp_var =
+          make_ast_node(AST::AST_WIRE, {make_ast_node(AST::AST_RANGE, {make_ast_node(AST::AST_SUB, {bits_call, AST::AstNode::mkconst_int(1, false)}),
+                                                                       AST::AstNode::mkconst_int(0, false)})});
+    }
+
+    temp_var->str = "\\loop" + std::to_string(loop_id) + "::temp";
+    module_node->children.insert(module_node->children.end() - 1, temp_var);
+    auto temp_var_ident = make_ast_node(AST::AST_IDENTIFIER);
+    temp_var_ident->str = temp_var->str;
+    auto temp_assign = make_ast_node(AST::AST_ASSIGN_EQ, {temp_var_ident});
+    block_node->children.push_back(temp_assign);
+
+    // Assignment in the loop's block
+    auto assign_node = make_ast_node(AST::AST_ASSIGN_EQ, {lhs_node->clone(), temp_var_ident->clone()});
+    AST::AstNode *slice_size = nullptr; // First argument in streaming op
+    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+        if (!slice_size && node->type == AST::AST_CONSTANT) {
+            slice_size = node;
+        } else {
+            temp_assign->children.push_back(node);
+        }
+    });
+    if (!slice_size) {
+        slice_size = AST::AstNode::mkconst_int(1, true);
+    }
+
+    // Initialization of the loop counter to 0
+    auto init_stmt = make_ast_node(AST::AST_ASSIGN_EQ, {loop_counter_ident, AST::AstNode::mkconst_int(0, true)});
+
+    // Loop condition (loop counter < $bits(RHS))
+    auto cond_stmt =
+      make_ast_node(AST::AST_LE, {loop_counter_ident->clone(), make_ast_node(AST::AST_SUB, {bits_call->clone(), slice_size->clone()})});
+
+    // Increment loop counter
+    auto inc_stmt =
+      make_ast_node(AST::AST_ASSIGN_EQ, {loop_counter_ident->clone(), make_ast_node(AST::AST_ADD, {loop_counter_ident->clone(), slice_size})});
+
+    // Range on the LHS of the assignment
+    auto lhs_range = make_ast_node(AST::AST_RANGE);
+    auto lhs_selfsz = make_ast_node(
+      AST::AST_SELFSZ, {make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_SUB, {bits_call->clone(), AST::AstNode::mkconst_int(1, true)}),
+                                                     loop_counter_ident->clone()})});
+    lhs_range->children.push_back(make_ast_node(AST::AST_ADD, {lhs_selfsz, AST::AstNode::mkconst_int(0, true)}));
+    lhs_range->children.push_back(
+      make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_ADD, {lhs_selfsz->clone(), AST::AstNode::mkconst_int(1, true)}), slice_size->clone()}));
+
+    // Range on the RHS of the assignment
+    auto rhs_range = make_ast_node(AST::AST_RANGE);
+    auto rhs_selfsz = make_ast_node(AST::AST_SELFSZ, {loop_counter_ident->clone()});
+    rhs_range->children.push_back(
+      make_ast_node(AST::AST_SUB, {make_ast_node(AST::AST_ADD, {rhs_selfsz, slice_size->clone()}), AST::AstNode::mkconst_int(1, true)}));
+    rhs_range->children.push_back(make_ast_node(AST::AST_ADD, {rhs_selfsz->clone(), AST::AstNode::mkconst_int(0, true)}));
+
+    // Put ranges on the sides of the assignment
+    assign_node->children[0]->children.push_back(lhs_range);
+    assign_node->children[1]->children.push_back(rhs_range);
+
+    // Putting the loop together
+    auto loop_node = make_ast_node(AST::AST_FOR);
+    loop_node->str = "$loop" + std::to_string(loop_id);
+    loop_node->children.push_back(init_stmt);
+    loop_node->children.push_back(cond_stmt);
+    loop_node->children.push_back(inc_stmt);
+    loop_node->children.push_back(make_ast_node(AST::AST_BLOCK, {assign_node}));
+    loop_node->children[3]->str = "\\stream_op_block" + std::to_string(loop_id);
+
+    block_node->children.push_back(make_ast_node(AST::AST_BLOCK, {loop_node}));
+
+    // Do not create a node
+    shared.report.mark_handled(obj_h);
+}
+
+void UhdmAst::process_list_op()
+{
+    // Add all operands as children of process node
+    if (auto parent_node = find_ancestor({AST::AST_ALWAYS, AST::AST_COND})) {
+        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+            // add directly to process/cond node
+            if (node) {
+                parent_node->children.push_back(node);
+            }
+        });
+    }
+    // Do not create a node
+    shared.report.mark_handled(obj_h);
+}
+
+void UhdmAst::process_cast_op()
+{
+    current_node = make_ast_node(AST::AST_NONE);
+    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+        node->cloneInto(current_node);
+        delete node;
+    });
+    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
+    shared.report.mark_handled(typespec_h);
+    vpi_release_handle(typespec_h);
+}
+
+void UhdmAst::process_inside_op()
+{
+    current_node = make_ast_node(AST::AST_EQ);
+    AST::AstNode *lhs = nullptr;
+    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+        if (!lhs) {
+            lhs = node;
+        }
+        if (current_node->children.size() < 2) {
+            current_node->children.push_back(node);
+        } else {
+            auto or_node = new AST::AstNode(AST::AST_LOGIC_OR);
+            or_node->filename = current_node->filename;
+            or_node->location = current_node->location;
+            auto eq_node = new AST::AstNode(AST::AST_EQ);
+            eq_node->filename = current_node->filename;
+            eq_node->location = current_node->location;
+            or_node->children.push_back(current_node);
+            or_node->children.push_back(eq_node);
+            eq_node->children.push_back(lhs->clone());
+            eq_node->children.push_back(node);
+            current_node = or_node;
+        }
+    });
+}
+
+void UhdmAst::process_assignment_pattern_op()
+{
+    current_node = make_ast_node(AST::AST_CONCAT);
+    if (auto param_node = find_ancestor({AST::AST_PARAMETER, AST::AST_LOCALPARAM})) {
+        std::map<size_t, AST::AstNode *> ordered_children;
+        visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+            if (node->type == AST::AST_ASSIGN || node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) {
+                // Find at what position in the concat should we place this node
+                auto key = node->children[0]->str;
+                key = key.substr(key.find('.') + 1);
+                auto param_type = shared.param_types[param_node->str];
+                if (!param_type) {
+                    log_error("Couldn't find parameter type for node: %s\n", param_node->str.c_str());
+                }
+                size_t pos =
+                  std::find_if(param_type->children.begin(), param_type->children.end(), [key](AST::AstNode *child) { return child->str == key; }) -
+                  param_type->children.begin();
+                ordered_children.insert(std::make_pair(pos, node->children[1]->clone()));
+            } else {
+                current_node->children.push_back(node);
+            }
+        });
+        for (auto p : ordered_children) {
+            current_node->children.push_back(p.second);
+        }
+        std::reverse(current_node->children.begin(), current_node->children.end());
+        return;
+    }
+    auto assign_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE});
+
+    auto proc_node =
+      find_ancestor({AST::AST_BLOCK, AST::AST_GENBLOCK, AST::AST_ALWAYS, AST::AST_INITIAL, AST::AST_MODULE, AST::AST_PACKAGE, AST::AST_CELL});
+    if (proc_node && proc_node->type == AST::AST_CELL && shared.top_nodes.count(proc_node->children[0]->str)) {
+        proc_node = shared.top_nodes[proc_node->children[0]->str];
+    }
+    std::vector<AST::AstNode *> assignments;
+    visit_one_to_many({vpiOperand}, obj_h, [&](AST::AstNode *node) {
+        if (node->type == AST::AST_ASSIGN || node->type == AST::AST_ASSIGN_EQ || node->type == AST::AST_ASSIGN_LE) {
+            assignments.push_back(node);
+        } else {
+            current_node->children.push_back(node);
+        }
+    });
+    std::reverse(current_node->children.begin(), current_node->children.end());
+    if (!assignments.empty()) {
+        if (current_node->children.empty()) {
+            delete assign_node->children[0];
+            assign_node->children[0] = assignments[0]->children[0];
+            current_node = assignments[0]->children[1];
+            assignments[0]->children.clear();
+            delete assignments[0];
+            proc_node->children.insert(proc_node->children.end(), assignments.begin() + 1, assignments.end());
+        } else {
+            proc_node->children.insert(proc_node->children.end(), assignments.begin(), assignments.end());
+        }
+    }
+}
+
+void UhdmAst::process_bit_select()
+{
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    visit_one_to_one({vpiIndex}, obj_h, [&](AST::AstNode *node) {
+        auto range_node = new AST::AstNode(AST::AST_RANGE, node);
+        range_node->filename = current_node->filename;
+        range_node->location = current_node->location;
+        current_node->children.push_back(range_node);
+    });
+}
+
+void UhdmAst::process_part_select()
+{
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    vpiHandle parent_h = vpi_handle(vpiParent, obj_h);
+    current_node->str = get_name(parent_h);
+    vpi_release_handle(parent_h);
+    auto range_node = new AST::AstNode(AST::AST_RANGE);
+    range_node->filename = current_node->filename;
+    range_node->location = current_node->location;
+    visit_one_to_one({vpiLeftRange, vpiRightRange}, obj_h, [&](AST::AstNode *node) { range_node->children.push_back(node); });
+    current_node->children.push_back(range_node);
+}
+
+void UhdmAst::process_indexed_part_select()
+{
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    vpiHandle parent_h = vpi_handle(vpiParent, obj_h);
+    current_node->str = get_name(parent_h);
+    vpi_release_handle(parent_h);
+    // TODO: check if there are other types, for now only handle 1 and 2 (+: and -:)
+    auto indexed_part_select_type = vpi_get(vpiIndexedPartSelectType, obj_h) == 1 ? AST::AST_ADD : AST::AST_SUB;
+    auto range_node = new AST::AstNode(AST::AST_RANGE);
+    range_node->filename = current_node->filename;
+    range_node->location = current_node->location;
+    visit_one_to_one({vpiBaseExpr}, obj_h, [&](AST::AstNode *node) { range_node->children.push_back(node); });
+    visit_one_to_one({vpiWidthExpr}, obj_h, [&](AST::AstNode *node) {
+        auto right_range_node = new AST::AstNode(indexed_part_select_type);
+        right_range_node->children.push_back(range_node->children[0]->clone());
+        right_range_node->children.push_back(node);
+        auto sub = new AST::AstNode(indexed_part_select_type == AST::AST_ADD ? AST::AST_SUB : AST::AST_ADD);
+        sub->children.push_back(right_range_node);
+        sub->children.push_back(AST::AstNode::mkconst_int(1, false, 1));
+        range_node->children.push_back(sub);
+        // range_node->children.push_back(right_range_node);
+    });
+    if (indexed_part_select_type == AST::AST_ADD) {
+        std::reverse(range_node->children.begin(), range_node->children.end());
+    }
+    current_node->children.push_back(range_node);
+}
+
+void UhdmAst::process_if_else()
+{
+    current_node = make_ast_node(AST::AST_CASE);
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) {
+        if (!node) {
+            log_error("Couldn't find node in if stmt. This can happend if unsupported '$value$plusargs' function is used inside if.\n");
+        }
+        auto reduce_node = new AST::AstNode(AST::AST_REDUCE_BOOL, node);
+        current_node->children.push_back(reduce_node);
+    });
+    // If true:
+    auto *condition = new AST::AstNode(AST::AST_COND);
+    auto *constant = AST::AstNode::mkconst_int(1, false, 1);
+    condition->children.push_back(constant);
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        auto *statements = new AST::AstNode(AST::AST_BLOCK);
+        if (node)
+            statements->children.push_back(node);
+        condition->children.push_back(statements);
+    });
+    current_node->children.push_back(condition);
+    // Else:
+    if (vpi_get(vpiType, obj_h) == vpiIfElse) {
+        auto *condition = new AST::AstNode(AST::AST_COND);
+        auto *elseBlock = new AST::AstNode(AST::AST_DEFAULT);
+        condition->children.push_back(elseBlock);
+        visit_one_to_one({vpiElseStmt}, obj_h, [&](AST::AstNode *node) {
+            auto *statements = new AST::AstNode(AST::AST_BLOCK);
+            if (node)
+                statements->children.push_back(node);
+            condition->children.push_back(statements);
+        });
+        current_node->children.push_back(condition);
+    }
+}
+
+void UhdmAst::process_for()
+{
+    current_node = make_ast_node(AST::AST_BLOCK);
+    auto loop_id = shared.next_loop_id();
+    current_node->str = "$fordecl_block" + std::to_string(loop_id);
+    auto loop = make_ast_node(AST::AST_FOR);
+    loop->str = "$loop" + std::to_string(loop_id);
+    current_node->children.push_back(loop);
+    visit_one_to_many({vpiForInitStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node->type == AST::AST_ASSIGN_LE)
+            node->type = AST::AST_ASSIGN_EQ;
+        auto lhs = node->children[0];
+        if (lhs->type == AST::AST_WIRE) {
+            auto *wire = lhs->clone();
+            wire->is_reg = true;
+            current_node->children.push_back(wire);
+            lhs->type = AST::AST_IDENTIFIER;
+            lhs->is_signed = false;
+            lhs->delete_children();
+        }
+        loop->children.push_back(node);
+    });
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
+    visit_one_to_many({vpiForIncStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node->type == AST::AST_ASSIGN_LE)
+            node->type = AST::AST_ASSIGN_EQ;
+        loop->children.push_back(node);
+    });
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node->type != AST::AST_BLOCK) {
+            auto *statements = make_ast_node(AST::AST_BLOCK);
+            statements->str = current_node->str; // Needed in simplify step
+            statements->children.push_back(node);
+            loop->children.push_back(statements);
+        } else {
+            if (node->str == "") {
+                node->str = loop->str;
+            }
+            loop->children.push_back(node);
+        }
+    });
+    transform_breaks_continues(loop, current_node);
+}
+
+void UhdmAst::process_gen_scope()
+{
+    current_node = make_ast_node(AST::AST_GENBLOCK);
+    visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            move_type_to_new_typedef(current_node, node);
+        }
+    });
+
+    visit_one_to_many(
+      {vpiParamAssign, vpiParameter, vpiNet, vpiArrayNet, vpiVariables, vpiContAssign, vpiProcess, vpiModule, vpiGenScopeArray, vpiTaskFunc}, obj_h,
+      [&](AST::AstNode *node) {
+          if (node) {
+              if ((node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) && node->children.empty()) {
+                  delete node; // skip parameters without any children
+              } else {
+                  current_node->children.push_back(node);
+              }
+          }
+      });
+}
+
+void UhdmAst::process_case()
+{
+    current_node = make_ast_node(AST::AST_CASE);
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+    visit_one_to_many({vpiCaseItem}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+}
+
+void UhdmAst::process_case_item()
+{
+    current_node = make_ast_node(AST::AST_COND);
+    vpiHandle itr = vpi_iterate(vpiExpr, obj_h);
+    while (vpiHandle expr_h = vpi_scan(itr)) {
+        // case ... inside statement, the operation is stored in UHDM inside case items
+        // Retrieve just the InsideOp arguments here, we don't add any special handling
+        // TODO: handle inside range (list operations) properly here
+        if (vpi_get(vpiType, expr_h) == vpiOperation && vpi_get(vpiOpType, expr_h) == vpiInsideOp) {
+            visit_one_to_many({vpiOperand}, expr_h, [&](AST::AstNode *node) {
+                if (node) {
+                    current_node->children.push_back(node);
+                }
+            });
+        } else {
+            UhdmAst uhdm_ast(this, shared, indent + "  ");
+            auto *node = uhdm_ast.process_object(expr_h);
+            if (node) {
+                current_node->children.push_back(node);
+            }
+        }
+        // FIXME: If we release the handle here, visiting vpiStmt fails for some reason
+        // vpi_release_handle(expr_h);
+    }
+    vpi_release_handle(itr);
+    if (current_node->children.empty()) {
+        current_node->children.push_back(new AST::AstNode(AST::AST_DEFAULT));
+    }
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type != AST::AST_BLOCK) {
+                auto block_node = new AST::AstNode(AST::AST_BLOCK);
+                block_node->children.push_back(node);
+                node = block_node;
+            }
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_range(const UHDM::BaseClass *object)
+{
+    current_node = make_ast_node(AST::AST_RANGE);
+    visit_one_to_one({vpiLeftRange, vpiRightRange}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+    if (current_node->children.size() > 0) {
+        if (current_node->children[0]->str == "unsized") {
+            log_error("%s:%d: Currently not supported object of type 'unsized range'\n", object->VpiFile().c_str(), object->VpiLineNo());
+        }
+    }
+    if (current_node->children.size() > 1) {
+        if (current_node->children[1]->str == "unsized") {
+            log_error("%s:%d: Currently not supported object of type 'unsized range'\n", object->VpiFile().c_str(), object->VpiLineNo());
+        }
+    }
+}
+
+void UhdmAst::process_return()
+{
+    current_node = make_ast_node(AST::AST_ASSIGN_EQ);
+    auto func_node = find_ancestor({AST::AST_FUNCTION, AST::AST_TASK});
+    if (!func_node->children.empty()) {
+        auto lhs = new AST::AstNode(AST::AST_IDENTIFIER);
+        lhs->str = func_node->children[0]->str;
+        current_node->children.push_back(lhs);
+    }
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+}
+
+void UhdmAst::process_function()
+{
+    current_node = make_ast_node(vpi_get(vpiType, obj_h) == vpiFunction ? AST::AST_FUNCTION : AST::AST_TASK);
+    visit_one_to_one({vpiReturn}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            auto net_type = vpi_get(vpiNetType, obj_h);
+            node->is_reg = net_type == vpiReg;
+            node->str = current_node->str;
+            current_node->children.push_back(node);
+        }
+    });
+    visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            add_or_replace_child(current_node, node);
+        }
+    });
+    visit_one_to_many({vpiIODecl}, obj_h, [&](AST::AstNode *node) {
+        node->type = AST::AST_WIRE;
+        node->port_id = shared.next_port_id();
+        current_node->children.push_back(node);
+    });
+    visit_one_to_many({vpiVariables}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            // Fix for assignments on declaration, e.g.:
+            // logic [63:0] key_out = key_in;
+            // key_out is already declared as vpiVariables, but it is also declared inside vpiStmt
+            const std::unordered_set<AST::AstNodeType> assign_types = {AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE};
+            for (auto c : node->children) {
+                if (assign_types.find(c->type) != assign_types.end() && c->children[0]->type == AST::AST_WIRE) {
+                    c->children[0]->type = AST::AST_IDENTIFIER;
+                    c->children[0]->attributes.erase(UhdmAst::packed_ranges());
+                    c->children[0]->attributes.erase(UhdmAst::unpacked_ranges());
+                }
+            }
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_hier_path()
+{
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    current_node->str = "\\";
+    AST::AstNode *top_node = nullptr;
+    visit_one_to_many({vpiActual}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->str.find('[') != std::string::npos)
+                node->str = node->str.substr(0, node->str.find('['));
+            // for first node, just set correct string and move any children
+            if (!top_node) {
+                current_node->str += node->str.substr(1);
+                current_node->children = std::move(node->children);
+                top_node = current_node;
+                delete node;
+            } else {
+                if (node->str.empty()) {
+                    log_assert(!node->children.empty());
+                    top_node->children.push_back(node->children[0]);
+                } else {
+                    node->type = static_cast<AST::AstNodeType>(AST::AST_DOT);
+                    top_node->children.push_back(node);
+                    top_node = node;
+                }
+            }
+        }
+    });
+}
+
+void UhdmAst::process_gen_scope_array()
+{
+    current_node = make_ast_node(AST::AST_GENBLOCK);
+    visit_one_to_many({vpiGenScope}, obj_h, [&](AST::AstNode *genscope_node) {
+        for (auto *child : genscope_node->children) {
+            if (child->type == AST::AST_PARAMETER || child->type == AST::AST_LOCALPARAM) {
+                auto param_str = child->str.substr(1);
+                auto array_str = "[" + param_str + "]";
+                visitEachDescendant(genscope_node, [&](AST::AstNode *node) {
+                    auto pos = node->str.find(array_str);
+                    if (pos != std::string::npos) {
+                        node->type = AST::AST_PREFIX;
+                        auto *param = new AST::AstNode(AST::AST_IDENTIFIER);
+                        param->str = child->str;
+                        node->children.push_back(param);
+                        auto bracket = node->str.rfind(']');
+                        if (bracket + 2 <= node->str.size()) {
+                            auto *field = new AST::AstNode(AST::AST_IDENTIFIER);
+                            field->str = "\\" + node->str.substr(bracket + 2);
+                            node->children.push_back(field);
+                        }
+                        node->str = node->str.substr(0, node->str.find('['));
+                    }
+                });
+            }
+        }
+        current_node->children.insert(current_node->children.end(), genscope_node->children.begin(), genscope_node->children.end());
+        genscope_node->children.clear();
+        delete genscope_node;
+    });
+}
+
+void UhdmAst::process_tagged_pattern()
+{
+    auto assign_node = find_ancestor({AST::AST_ASSIGN, AST::AST_ASSIGN_EQ, AST::AST_ASSIGN_LE});
+    auto assign_type = AST::AST_ASSIGN;
+    AST::AstNode *lhs_node = nullptr;
+    if (assign_node) {
+        assign_type = assign_node->type;
+        lhs_node = assign_node->children[0];
+    } else {
+        lhs_node = new AST::AstNode(AST::AST_IDENTIFIER);
+        auto ancestor = find_ancestor({AST::AST_WIRE, AST::AST_MEMORY, AST::AST_PARAMETER, AST::AST_LOCALPARAM});
+        if (!ancestor) {
+            log_error("Couldn't find ancestor for tagged pattern!\n");
+        }
+        lhs_node->str = ancestor->str;
+    }
+    current_node = new AST::AstNode(assign_type);
+    current_node->children.push_back(lhs_node->clone());
+    auto typespec_h = vpi_handle(vpiTypespec, obj_h);
+    if (vpi_get(vpiType, typespec_h) == vpiStringTypespec) {
+        std::string field_name = vpi_get_str(vpiName, typespec_h);
+        if (field_name != "default") { // TODO: better support of the default keyword
+            auto field = new AST::AstNode(static_cast<AST::AstNodeType>(AST::AST_DOT));
+            field->str = field_name;
+            current_node->children[0]->children.push_back(field);
+        }
+    } else if (vpi_get(vpiType, typespec_h) == vpiIntegerTypespec) {
+        s_vpi_value val;
+        vpi_get_value(typespec_h, &val);
+        auto range = new AST::AstNode(AST::AST_RANGE);
+        auto index = AST::AstNode::mkconst_int(val.value.integer, false);
+        range->children.push_back(index);
+        current_node->children[0]->children.push_back(range);
+    }
+    vpi_release_handle(typespec_h);
+    visit_one_to_one({vpiPattern}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+}
+
+void UhdmAst::process_logic_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->is_logic = true;
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    // TODO: add const attribute, but it seems it is little more
+    // then just setting boolean value
+    // current_node->is_const = vpi_get(vpiConstantVariable, obj_h);
+    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node->str.empty()) {
+            // anonymous typespec, move the children to variable
+            current_node->type = node->type;
+            current_node->children = std::move(node->children);
+        } else {
+            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+            wiretype_node->str = node->str;
+            current_node->children.push_back(wiretype_node);
+            current_node->is_custom_type = true;
+        }
+        delete node;
+    });
+    // TODO: Handling below seems similar to other typespec accesses for range. Candidate for extraction to a function.
+    if (auto typespec_h = vpi_handle(vpiTypespec, obj_h)) {
+        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        vpi_release_handle(typespec_h);
+    } else {
+        visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+    }
+    visit_default_expr(obj_h);
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_sys_func_call()
+{
+    current_node = make_ast_node(AST::AST_FCALL);
+
+    std::string task_calls[] = {"\\$display", "\\$monitor", "\\$write", "\\$time", "\\$readmemh", "\\$readmemb", "\\$finish", "\\$stop"};
+
+    if (current_node->str == "\\$signed") {
+        current_node->type = AST::AST_TO_SIGNED;
+    } else if (current_node->str == "\\$unsigned") {
+        current_node->type = AST::AST_TO_UNSIGNED;
+    } else if (std::find(std::begin(task_calls), std::end(task_calls), current_node->str) != std::end(task_calls)) {
+        current_node->type = AST::AST_TCALL;
+    }
+
+    visit_one_to_many({vpiArgument}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+
+    if (current_node->str == "\\$display" || current_node->str == "\\$write") {
+        // According to standard, %h and %x mean the same, but %h is currently unsupported by mainline yosys
+        std::string replaced_string = std::regex_replace(current_node->children[0]->str, std::regex("%[h|H]"), "%x");
+        delete current_node->children[0];
+        current_node->children[0] = AST::AstNode::mkconst_str(replaced_string);
+    }
+
+    std::string remove_backslash[] = {"\\$display", "\\$strobe",   "\\$write",    "\\$monitor", "\\$time",    "\\$finish",
+                                      "\\$stop",    "\\$dumpfile", "\\$dumpvars", "\\$dumpon",  "\\$dumpoff", "\\$dumpall"};
+
+    if (std::find(std::begin(remove_backslash), std::end(remove_backslash), current_node->str) != std::end(remove_backslash))
+        current_node->str = current_node->str.substr(1);
+}
+
+void UhdmAst::process_func_call()
+{
+    current_node = make_ast_node(AST::AST_FCALL);
+    visit_one_to_many({vpiArgument}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
+                node->type = AST::AST_IDENTIFIER;
+                node->children.clear();
+            }
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_immediate_assert()
+{
+    current_node = make_ast_node(AST::AST_ASSERT);
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *n) {
+        if (n) {
+            current_node->children.push_back(n);
+        }
+    });
+}
+
+void UhdmAst::process_logic_typespec()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->is_logic = true;
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    if (!current_node->str.empty() && current_node->str.find("::") == std::string::npos) {
+        std::string package_name = "";
+        if (vpiHandle instance_h = vpi_handle(vpiInstance, obj_h)) {
+            if (vpi_get(vpiType, instance_h) == vpiPackage) {
+                package_name = get_object_name(instance_h, {vpiDefName});
+                current_node->str = package_name + "::" + current_node->str.substr(1);
+            }
+            vpi_release_handle(instance_h);
+        }
+    }
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_int_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    current_node = make_ast_node(AST::AST_WIRE);
+    packed_ranges.push_back(make_range(31, 0));
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = true;
+}
+
+void UhdmAst::process_shortint_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    current_node = make_ast_node(AST::AST_WIRE);
+    packed_ranges.push_back(make_range(15, 0));
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = true;
+}
+
+void UhdmAst::process_longint_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    current_node = make_ast_node(AST::AST_WIRE);
+    packed_ranges.push_back(make_range(63, 0));
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = true;
+}
+
+void UhdmAst::process_byte_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    current_node = make_ast_node(AST::AST_WIRE);
+    packed_ranges.push_back(make_range(7, 0));
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = true;
+}
+
+void UhdmAst::process_time_typespec()
+{
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    current_node = make_ast_node(AST::AST_WIRE);
+    packed_ranges.push_back(make_range(63, 0));
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = false;
+}
+
+void UhdmAst::process_string_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->is_string = true;
+    // FIXME:
+    // this is only basic support for strings,
+    // currently yosys doesn't support dynamic resize of wire
+    // based on string size
+    // here we try to get size of string based on provided const string
+    // if it is not available, we are setting size to explicite 64 bits
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *expr_node) {
+        if (expr_node->type == AST::AST_CONSTANT) {
+            auto left_const = AST::AstNode::mkconst_int(expr_node->range_left, true);
+            auto right_const = AST::AstNode::mkconst_int(expr_node->range_right, true);
+            auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
+            current_node->children.push_back(range);
+        }
+    });
+    if (current_node->children.empty()) {
+        auto left_const = AST::AstNode::mkconst_int(64, true);
+        auto right_const = AST::AstNode::mkconst_int(0, true);
+        auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
+        current_node->children.push_back(range);
+    }
+    visit_default_expr(obj_h);
+}
+
+void UhdmAst::process_string_typespec()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->is_string = true;
+    // FIXME:
+    // this is only basic support for strings,
+    // currently yosys doesn't support dynamic resize of wire
+    // based on string size
+    // here, we are setting size to explicite 64 bits
+    auto left_const = AST::AstNode::mkconst_int(64, true);
+    auto right_const = AST::AstNode::mkconst_int(0, true);
+    auto range = make_ast_node(AST::AST_RANGE, {left_const, right_const});
+    current_node->children.push_back(range);
+}
+
+void UhdmAst::process_bit_typespec()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    visit_range(obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_repeat()
+{
+    auto loop_id = shared.next_loop_id();
+    current_node = make_ast_node(AST::AST_BLOCK);
+    current_node->str = "$repeatdecl_block" + std::to_string(loop_id);
+    auto *loop = make_ast_node(AST::AST_REPEAT);
+    loop->str = "$loop" + std::to_string(loop_id);
+    current_node->children.push_back(loop);
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node->type != AST::AST_BLOCK) {
+            node = new AST::AstNode(AST::AST_BLOCK, node);
+        }
+        if (node->str.empty()) {
+            node->str = loop->str; // Needed in simplify step
+        }
+        loop->children.push_back(node);
+    });
+    transform_breaks_continues(loop, current_node);
+}
+
+void UhdmAst::process_var_select()
+{
+    current_node = make_ast_node(AST::AST_IDENTIFIER);
+    visit_one_to_many({vpiIndex}, obj_h, [&](AST::AstNode *node) {
+        if (node->str == current_node->str) {
+            for (auto child : node->children) {
+                current_node->children.push_back(child);
+            }
+            node->children.clear();
+            delete node;
+        } else {
+            auto range_node = new AST::AstNode(AST::AST_RANGE);
+            range_node->filename = current_node->filename;
+            range_node->location = current_node->location;
+            range_node->children.push_back(node);
+            current_node->children.push_back(range_node);
+        }
+    });
+}
+
+void UhdmAst::process_port()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->port_id = shared.next_port_id();
+    vpiHandle lowConn_h = vpi_handle(vpiLowConn, obj_h);
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    if (lowConn_h) {
+        vpiHandle actual_h = vpi_handle(vpiActual, lowConn_h);
+        auto actual_type = vpi_get(vpiType, actual_h);
+        switch (actual_type) {
+        case vpiModport: {
+            vpiHandle iface_h = vpi_handle(vpiInterface, actual_h);
+            if (iface_h) {
+                std::string cellName, ifaceName;
+                if (auto s = vpi_get_str(vpiName, actual_h)) {
+                    cellName = s;
+                    sanitize_symbol_name(cellName);
+                }
+                if (auto s = vpi_get_str(vpiDefName, iface_h)) {
+                    ifaceName = s;
+                    sanitize_symbol_name(ifaceName);
+                }
+                current_node->type = AST::AST_INTERFACEPORT;
+                auto typeNode = new AST::AstNode(AST::AST_INTERFACEPORTTYPE);
+                // Skip '\' in cellName
+                typeNode->str = ifaceName + '.' + cellName.substr(1, cellName.length());
+                current_node->children.push_back(typeNode);
+                shared.report.mark_handled(actual_h);
+                shared.report.mark_handled(iface_h);
+                vpi_release_handle(iface_h);
+            }
+            break;
+        }
+        case vpiInterface: {
+            auto typeNode = new AST::AstNode(AST::AST_INTERFACEPORTTYPE);
+            if (auto s = vpi_get_str(vpiDefName, actual_h)) {
+                typeNode->str = s;
+                sanitize_symbol_name(typeNode->str);
+            }
+            current_node->type = AST::AST_INTERFACEPORT;
+            current_node->children.push_back(typeNode);
+            shared.report.mark_handled(actual_h);
+            break;
+        }
+        case vpiLogicVar:
+        case vpiLogicNet: {
+            current_node->is_logic = true;
+            current_node->is_signed = vpi_get(vpiSigned, actual_h);
+            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+            shared.report.mark_handled(actual_h);
+            break;
+        }
+        case vpiPackedArrayVar:
+            visit_one_to_many({vpiElement}, actual_h, [&](AST::AstNode *node) {
+                if (node && GetSize(node->children) == 1) {
+                    current_node->children.push_back(node->children[0]);
+                    if (node->children[0]->type == AST::AST_WIRETYPE) {
+                        current_node->is_custom_type = true;
+                    }
+                }
+            });
+            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+            shared.report.mark_handled(actual_h);
+            break;
+        case vpiPackedArrayNet:
+            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+            shared.report.mark_handled(actual_h);
+            break;
+        case vpiArrayVar:
+            visit_one_to_many({vpiRange}, actual_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+            shared.report.mark_handled(actual_h);
+            break;
+        case vpiEnumNet:
+        case vpiStructNet:
+        case vpiArrayNet:
+        case vpiStructVar:
+        case vpiUnionVar:
+        case vpiEnumVar:
+        case vpiShortIntVar:
+        case vpiLongIntVar:
+        case vpiIntVar:
+        case vpiIntegerVar:
+            break;
+        default: {
+            const uhdm_handle *const handle = (const uhdm_handle *)actual_h;
+            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+            report_error("%s:%d: Encountered unhandled type in process_port: %s\n", object->VpiFile().c_str(), object->VpiLineNo(),
+                         UHDM::VpiTypeName(actual_h).c_str());
+            break;
+        }
+        }
+        shared.report.mark_handled(lowConn_h);
+        vpi_release_handle(actual_h);
+        vpi_release_handle(lowConn_h);
+    }
+    visit_one_to_one({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            if (!current_node->children.empty() && current_node->children[0]->type != AST::AST_WIRETYPE) {
+                if (!node->str.empty()) {
+                    auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    // wiretype needs to be 1st node (if port have also another range nodes)
+                    current_node->children.insert(current_node->children.begin(), wiretype_node);
+                    current_node->is_custom_type = true;
+                } else {
+                    // anonymous typedef, just move children
+                    current_node->children = std::move(node->children);
+                }
+            }
+            delete node;
+        }
+    });
+    if (const int n = vpi_get(vpiDirection, obj_h)) {
+        if (n == vpiInput) {
+            current_node->is_input = true;
+        } else if (n == vpiOutput) {
+            current_node->is_output = true;
+        } else if (n == vpiInout) {
+            current_node->is_input = true;
+            current_node->is_output = true;
+        }
+    }
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_net()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    auto net_type = vpi_get(vpiNetType, obj_h);
+    current_node->is_reg = net_type == vpiReg;
+    current_node->is_output = net_type == vpiOutput;
+    current_node->is_logic = !current_node->is_reg;
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
+    visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+        if (node && !node->str.empty()) {
+            auto wiretype_node = new AST::AstNode(AST::AST_WIRETYPE);
+            wiretype_node->str = node->str;
+            // wiretype needs to be 1st node
+            current_node->children.insert(current_node->children.begin(), wiretype_node);
+            current_node->is_custom_type = true;
+        }
+    });
+    if (vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h)) {
+        visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        vpi_release_handle(typespec_h);
+    }
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_parameter()
+{
+    auto type = vpi_get(vpiLocalParam, obj_h) == 1 ? AST::AST_LOCALPARAM : AST::AST_PARAMETER;
+    current_node = make_ast_node(type, {}, true);
+    std::vector<AST::AstNode *> packed_ranges;   // comes before wire name
+    std::vector<AST::AstNode *> unpacked_ranges; // comes after wire name
+    // currently unused, but save it for future use
+    if (const char *imported = vpi_get_str(vpiImported, obj_h); imported != nullptr && strlen(imported) > 0) {
+        current_node->attributes[UhdmAst::is_imported()] = AST::AstNode::mkconst_int(1, true);
+    }
+    visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
+    vpiHandle typespec_h = vpi_handle(vpiTypespec, obj_h);
+    if (typespec_h) {
+        int typespec_type = vpi_get(vpiType, typespec_h);
+        switch (typespec_type) {
+        case vpiBitTypespec:
+        case vpiLogicTypespec: {
+            current_node->is_logic = true;
+            visit_one_to_many({vpiRange}, typespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiByteTypespec: {
+            packed_ranges.push_back(make_range(7, 0));
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiEnumTypespec:
+        case vpiRealTypespec:
+        case vpiStringTypespec: {
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiIntTypespec:
+        case vpiIntegerTypespec: {
+            packed_ranges.push_back(make_range(31, 0));
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiShortIntTypespec: {
+            packed_ranges.push_back(make_range(15, 0));
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiTimeTypespec:
+        case vpiLongIntTypespec: {
+            packed_ranges.push_back(make_range(63, 0));
+            shared.report.mark_handled(typespec_h);
+            break;
+        }
+        case vpiStructTypespec: {
+            visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
+                if (node && !node->str.empty()) {
+                    auto wiretype_node = make_ast_node(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                }
+                current_node->is_custom_type = true;
+                auto it = shared.param_types.find(current_node->str);
+                if (it == shared.param_types.end())
+                    shared.param_types.insert(std::make_pair(current_node->str, node));
+            });
+            break;
+        }
+        case vpiPackedArrayTypespec:
+        case vpiArrayTypespec: {
+            shared.report.mark_handled(typespec_h);
+            visit_one_to_one({vpiElemTypespec}, typespec_h, [&](AST::AstNode *node) {
+                if (!node->str.empty()) {
+                    auto wiretype_node = make_ast_node(AST::AST_WIRETYPE);
+                    wiretype_node->str = node->str;
+                    current_node->children.push_back(wiretype_node);
+                    current_node->is_custom_type = true;
+                    auto it = shared.param_types.find(current_node->str);
+                    if (it == shared.param_types.end())
+                        shared.param_types.insert(std::make_pair(current_node->str, node));
+                }
+                if (node && node->attributes.count(UhdmAst::packed_ranges())) {
+                    for (auto r : node->attributes[UhdmAst::packed_ranges()]->children) {
+                        packed_ranges.push_back(r->clone());
+                    }
+                }
+            });
+            break;
+        }
+        default: {
+            const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
+            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+            report_error("%s:%d: Encountered unhandled typespec in process_parameter: '%s' of type '%s'\n", object->VpiFile().c_str(),
+                         object->VpiLineNo(), object->VpiName().c_str(), UHDM::VpiTypeName(typespec_h).c_str());
+            break;
+        }
+        }
+        vpi_release_handle(typespec_h);
+    }
+    AST::AstNode *constant_node = process_value(obj_h);
+    if (constant_node) {
+        constant_node->filename = current_node->filename;
+        constant_node->location = current_node->location;
+        current_node->children.push_back(constant_node);
+    }
+    add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+}
+
+void UhdmAst::process_byte_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->children.push_back(make_range(7, 0));
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
+}
+
+void UhdmAst::process_long_int_var()
+{
+    current_node = make_ast_node(AST::AST_WIRE);
+    current_node->children.push_back(make_range(63, 0));
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
+}
+
+void UhdmAst::process_immediate_cover()
+{
+    current_node = make_ast_node(AST::AST_COVER);
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_immediate_assume()
+{
+    current_node = make_ast_node(AST::AST_ASSUME);
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) {
+        if (node) {
+            current_node->children.push_back(node);
+        }
+    });
+}
+
+void UhdmAst::process_while()
+{
+    auto loop_id = shared.next_loop_id();
+    current_node = make_ast_node(AST::AST_BLOCK);
+    current_node->str = "$whiledecl_block" + std::to_string(loop_id);
+    auto *loop = make_ast_node(AST::AST_WHILE);
+    loop->str = "$loop" + std::to_string(loop_id);
+    current_node->children.push_back(loop);
+    visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { loop->children.push_back(node); });
+    visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
+        if (node->type != AST::AST_BLOCK) {
+            node = make_ast_node(AST::AST_BLOCK, {node});
+        }
+        if (node->str.empty()) {
+            node->str = loop->str; // Needed in simplify step
+        }
+        loop->children.push_back(node);
+    });
+    transform_breaks_continues(loop, current_node);
+}
+
+void UhdmAst::process_gate()
+{
+    current_node = make_ast_node(AST::AST_PRIMITIVE);
+    switch (vpi_get(vpiPrimType, obj_h)) {
+    case vpiAndPrim:
+        current_node->str = "and";
+        break;
+    case vpiNandPrim:
+        current_node->str = "nand";
+        break;
+    case vpiNorPrim:
+        current_node->str = "nor";
+        break;
+    case vpiOrPrim:
+        current_node->str = "or";
+        break;
+    case vpiXorPrim:
+        current_node->str = "xor";
+        break;
+    case vpiXnorPrim:
+        current_node->str = "xnor";
+        break;
+    case vpiBufPrim:
+        current_node->str = "buf";
+        break;
+    case vpiNotPrim:
+        current_node->str = "not";
+        break;
+    default:
+        log_file_error(current_node->filename, current_node->location.first_line, "Encountered unhandled gate type: %s", current_node->str.c_str());
+        break;
+    }
+    visit_one_to_many({vpiPrimTerm}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+}
+
+void UhdmAst::process_primterm()
+{
+    current_node = make_ast_node(AST::AST_ARGUMENT);
+    visit_one_to_one({vpiExpr}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
+}
+
+void UhdmAst::process_unsupported_stmt(const UHDM::BaseClass *object)
+{
+    log_error("%s:%d: Currently not supported object of type '%s'\n", object->VpiFile().c_str(), object->VpiLineNo(),
+              UHDM::VpiTypeName(obj_h).c_str());
+}
+
+AST::AstNode *UhdmAst::process_object(vpiHandle obj_handle)
+{
+    obj_h = obj_handle;
+    const unsigned object_type = vpi_get(vpiType, obj_h);
+    const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
+    const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+    for (auto *obj : shared.nonSynthesizableObjects) {
+        if (!object->Compare(obj)) {
+            log_warning("%s:%d: Skipping non-synthesizable object of type '%s'\n", object->VpiFile().c_str(), object->VpiLineNo(),
+                        UHDM::VpiTypeName(obj_h).c_str());
+            return nullptr;
+        }
+    }
+
+    if (shared.debug_flag) {
+        std::cout << indent << "Object '" << object->VpiName() << "' of type '" << UHDM::VpiTypeName(obj_h) << '\'' << std::endl;
+    }
+
+    switch (object_type) {
+    case vpiDesign:
+        process_design();
+        break;
+    case vpiParameter:
+        process_parameter();
+        break;
+    case vpiPort:
+        process_port();
+        break;
+    case vpiModule:
+        process_module();
+        break;
+    case vpiStructTypespec:
+        process_struct_typespec();
+        break;
+    case vpiUnionTypespec:
+        process_union_typespec();
+        break;
+    case vpiPackedArrayTypespec:
+        process_packed_array_typespec();
+        break;
+    case vpiArrayTypespec:
+        process_array_typespec();
+        break;
+    case vpiTypespecMember:
+        process_typespec_member();
+        break;
+    case vpiEnumTypespec:
+        process_enum_typespec();
+        break;
+    case vpiEnumConst:
+        process_enum_const();
+        break;
+    case vpiEnumVar:
+    case vpiEnumNet:
+    case vpiStructVar:
+    case vpiStructNet:
+    case vpiUnionVar:
+        process_custom_var();
+        break;
+    case vpiShortIntVar:
+    case vpiIntVar:
+    case vpiIntegerVar:
+        process_int_var();
+        break;
+    case vpiShortRealVar:
+    case vpiRealVar:
+        process_real_var();
+        break;
+    case vpiPackedArrayVar:
+        process_packed_array_var();
+        break;
+    case vpiArrayVar:
+        process_array_var();
+        break;
+    case vpiParamAssign:
+        process_param_assign();
+        break;
+    case vpiContAssign:
+        process_cont_assign();
+        break;
+    case vpiAssignStmt:
+    case vpiAssignment:
+        process_assignment();
+        break;
+    case vpiRefVar:
+    case vpiRefObj:
+        current_node = make_ast_node(AST::AST_IDENTIFIER);
+        break;
+    case vpiNet:
+        process_net();
+        break;
+    case vpiArrayNet:
+        process_array_net(object);
+        break;
+    case vpiPackedArrayNet:
+        process_packed_array_net();
+        break;
+    case vpiPackage:
+        process_package();
+        break;
+    case vpiInterface:
+        process_interface();
+        break;
+    case vpiModport:
+        process_modport();
+        break;
+    case vpiIODecl:
+        process_io_decl();
+        break;
+    case vpiAlways:
+        process_always();
+        break;
+    case vpiEventControl:
+        process_event_control(object);
+        break;
+    case vpiInitial:
+        process_initial();
+        break;
+    case vpiNamedBegin:
+        process_begin(true);
+        break;
+    case vpiBegin:
+        process_begin(false);
+        break;
+    case vpiCondition:
+    case vpiOperation:
+        process_operation(object);
+        break;
+    case vpiTaggedPattern:
+        process_tagged_pattern();
+        break;
+    case vpiBitSelect:
+        process_bit_select();
+        break;
+    case vpiPartSelect:
+        process_part_select();
+        break;
+    case vpiIndexedPartSelect:
+        process_indexed_part_select();
+        break;
+    case vpiVarSelect:
+        process_var_select();
+        break;
+    case vpiIf:
+    case vpiIfElse:
+        process_if_else();
+        break;
+    case vpiFor:
+        process_for();
+        break;
+    case vpiBreak:
+        // Will be resolved later by loop processor
+        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::AST_BREAK));
+        break;
+    case vpiContinue:
+        // Will be resolved later by loop processor
+        current_node = make_ast_node(static_cast<AST::AstNodeType>(AST::AST_CONTINUE));
+        break;
+    case vpiGenScopeArray:
+        process_gen_scope_array();
+        break;
+    case vpiGenScope:
+        process_gen_scope();
+        break;
+    case vpiCase:
+        process_case();
+        break;
+    case vpiCaseItem:
+        process_case_item();
+        break;
+    case vpiConstant:
+        current_node = process_value(obj_h);
+        break;
+    case vpiRange:
+        process_range(object);
+        break;
+    case vpiReturn:
+        process_return();
+        break;
+    case vpiFunction:
+    case vpiTask:
+        process_function();
+        break;
+    case vpiBitVar:
+    case vpiLogicVar:
+        process_logic_var();
+        break;
+    case vpiSysFuncCall:
+        process_sys_func_call();
+        break;
+    case vpiFuncCall:
+        process_func_call();
+        break;
+    case vpiTaskCall:
+        current_node = make_ast_node(AST::AST_TCALL);
+        break;
+    case vpiImmediateAssert:
+        if (!shared.no_assert)
+            process_immediate_assert();
+        break;
+    case vpiAssert:
+        if (!shared.no_assert)
+            process_unsupported_stmt(object);
+        break;
+    case vpiHierPath:
+        process_hier_path();
+        break;
+    case UHDM::uhdmimport_typespec:
+        break;
+    case vpiLogicTypespec:
+        process_logic_typespec();
+        break;
+    case vpiIntTypespec:
+    case vpiIntegerTypespec:
+        process_int_typespec();
+        break;
+    case vpiShortIntTypespec:
+        process_shortint_typespec();
+        break;
+    case vpiLongIntTypespec:
+        process_longint_typespec();
+        break;
+    case vpiTimeTypespec:
+        process_time_typespec();
+        break;
+    case vpiBitTypespec:
+        process_bit_typespec();
+        break;
+    case vpiByteTypespec:
+        process_byte_typespec();
+        break;
+    case vpiStringVar:
+        process_string_var();
+        break;
+    case vpiStringTypespec:
+        process_string_typespec();
+        break;
+    case vpiRepeat:
+        process_repeat();
+        break;
+    case vpiByteVar:
+        process_byte_var();
+        break;
+    case vpiLongIntVar:
+        process_long_int_var();
+        break;
+    case vpiImmediateCover:
+        process_immediate_cover();
+        break;
+    case vpiImmediateAssume:
+        process_immediate_assume();
+        break;
+    case vpiAssume:
+        process_unsupported_stmt(object);
+        break;
+    case vpiWhile:
+        process_while();
+        break;
+    case vpiGate:
+        process_gate();
+        break;
+    case vpiPrimTerm:
+        process_primterm();
+        break;
+    case vpiClockingBlock:
+        process_unsupported_stmt(object);
+        break;
+    case vpiProgram:
+    default:
+        report_error("%s:%d: Encountered unhandled object '%s' of type '%s'\n", object->VpiFile().c_str(), object->VpiLineNo(),
+                     object->VpiName().c_str(), UHDM::VpiTypeName(obj_h).c_str());
+        break;
+    }
+
+    // Check if we initialized the node in switch-case
+    if (current_node) {
+        if (current_node->type != AST::AST_NONE) {
+            shared.report.mark_handled(object);
+            return current_node;
+        }
+    }
+    return nullptr;
+}
+
+AST::AstNode *UhdmAst::visit_designs(const std::vector<vpiHandle> &designs)
+{
+    current_node = new AST::AstNode(AST::AST_DESIGN);
+    for (auto design : designs) {
+        UhdmAst ast(this, shared, indent);
+        auto *nodes = ast.process_object(design);
+        // Flatten multiple designs into one
+        for (auto child : nodes->children) {
+            current_node->children.push_back(child);
+        }
+    }
+    return current_node;
+}
+
+void UhdmAst::report_error(const char *format, ...) const
+{
+    va_list args;
+    va_start(args, format);
+    if (shared.stop_on_error) {
+        logv_error(format, args);
+    } else {
+        logv_warning(format, args);
+    }
+}
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/systemverilog/UhdmAst.h b/yosys-plugins/systemverilog/UhdmAst.h
new file mode 100644
index 000000000..b7877a61e
--- /dev/null
+++ b/yosys-plugins/systemverilog/UhdmAst.h
@@ -0,0 +1,182 @@
+#ifndef _UHDM_AST_H_
+#define _UHDM_AST_H_ 1
+
+#include "frontends/ast/ast.h"
+#include <vector>
+#undef cover
+
+#include "uhdmastshared.h"
+#include <uhdm/uhdm.h>
+
+YOSYS_NAMESPACE_BEGIN
+
+class UhdmAst
+{
+  private:
+    // Walks through one-to-many relationships from given parent
+    // node through the VPI interface, visiting child nodes belonging to
+    // ChildrenNodeTypes that are present in the given object.
+    void visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f);
+
+    // Walks through one-to-one relationships from given parent
+    // node through the VPI interface, visiting child nodes belonging to
+    // ChildrenNodeTypes that are present in the given object.
+    void visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(AST::AstNode *)> &f);
+
+    // Visit children of type vpiRange that belong to the given parent node.
+    void visit_range(vpiHandle obj_h, const std::function<void(AST::AstNode *)> &f);
+
+    // Visit the default expression assigned to a variable.
+    void visit_default_expr(vpiHandle obj_h);
+
+    // Create an AstNode of the specified type with metadata extracted from
+    // the given vpiHandle.
+    AST::AstNode *make_ast_node(AST::AstNodeType type, std::vector<AST::AstNode *> children = {}, bool prefer_full_name = false);
+
+    // Create an identifier AstNode
+    AST::AstNode *make_identifier(const std::string &name);
+
+    // Makes the passed node a cell node of the specified type
+    void make_cell(vpiHandle obj_h, AST::AstNode *node, AST::AstNode *type);
+
+    // Moves a type node to the specified node
+    void move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode *type_node);
+
+    // Go up the UhdmAst to find a parent node of the specified type
+    AST::AstNode *find_ancestor(const std::unordered_set<AST::AstNodeType> &types);
+
+    // Reports that something went wrong with reading the UHDM file
+    void report_error(const char *format, ...) const;
+
+    // Processes the value connected to the specified node
+    AST::AstNode *process_value(vpiHandle obj_h);
+
+    // Transforms break and continue nodes into structures accepted by the AST frontend
+    void transform_breaks_continues(AST::AstNode *loop, AST::AstNode *decl_block);
+
+    // The parent UhdmAst
+    UhdmAst *parent;
+
+    // Data shared between all UhdmAst objects
+    UhdmAstShared &shared;
+
+    // The current VPI/UHDM handle
+    vpiHandle obj_h = 0;
+
+    // The current Yosys AST node
+    AST::AstNode *current_node = nullptr;
+
+    // Indentation used for debug printing
+    std::string indent;
+
+    // Mapping of names that should be replaced to new names
+    std::unordered_map<std::string, std::string> node_renames;
+
+    // Functions that process specific types of nodes
+    void process_design();
+    void process_parameter();
+    void process_port();
+    void process_module();
+    void process_struct_typespec();
+    void process_union_typespec();
+    void process_packed_array_typespec();
+    void process_array_typespec();
+    void process_typespec_member();
+    void process_enum_typespec();
+    void process_enum_const();
+    void process_custom_var();
+    void process_int_var();
+    void process_real_var();
+    void process_array_var();
+    void process_packed_array_var();
+    void process_param_assign();
+    void process_cont_assign();
+    void process_cont_assign_net();
+    void process_cont_assign_var_init();
+    void process_assignment();
+    void process_net();
+    void process_packed_array_net();
+    void process_array_net(const UHDM::BaseClass *object);
+    void process_package();
+    void process_interface();
+    void process_modport();
+    void process_io_decl();
+    void process_always();
+    void process_event_control(const UHDM::BaseClass *object);
+    void process_initial();
+    void process_begin(bool is_named);
+    void process_operation(const UHDM::BaseClass *object);
+    void process_stream_op();
+    void process_list_op();
+    void process_cast_op();
+    void process_inside_op();
+    void process_assignment_pattern_op();
+    void process_tagged_pattern();
+    void process_bit_select();
+    void process_part_select();
+    void process_indexed_part_select();
+    void process_var_select();
+    void process_if_else();
+    void process_for();
+    void process_gen_scope_array();
+    void process_gen_scope();
+    void process_case();
+    void process_case_item();
+    void process_range(const UHDM::BaseClass *object);
+    void process_return();
+    void process_function();
+    void process_logic_var();
+    void process_sys_func_call();
+    void process_func_call();
+    void process_immediate_assert();
+    void process_hier_path();
+    void process_logic_typespec();
+    void process_int_typespec();
+    void process_shortint_typespec();
+    void process_longint_typespec();
+    void process_time_typespec();
+    void process_bit_typespec();
+    void process_string_var();
+    void process_string_typespec();
+    void process_repeat();
+    void process_byte_var();
+    void process_byte_typespec();
+    void process_long_int_var();
+    void process_immediate_cover();
+    void process_immediate_assume();
+    void process_while();
+    void process_gate();
+    void process_primterm();
+    void simplify_parameter(AST::AstNode *parameter, AST::AstNode *module_node = nullptr);
+    void process_unsupported_stmt(const UHDM::BaseClass *object);
+
+    UhdmAst(UhdmAst *p, UhdmAstShared &s, const std::string &i) : parent(p), shared(s), indent(i)
+    {
+        if (parent)
+            node_renames = parent->node_renames;
+    }
+
+  public:
+    UhdmAst(UhdmAstShared &s, const std::string &i = "") : UhdmAst(nullptr, s, i) {}
+
+    // Visits single VPI object and creates proper AST node
+    AST::AstNode *process_object(vpiHandle obj_h);
+
+    // Visits all VPI design objects and returns created ASTs
+    AST::AstNode *visit_designs(const std::vector<vpiHandle> &designs);
+
+    static const IdString &partial();
+    static const IdString &packed_ranges();
+    static const IdString &unpacked_ranges();
+    // set this attribute to force conversion of multirange wire to single range. It is useful to force-convert some memories.
+    static const IdString &force_convert();
+    static const IdString &is_imported();
+};
+
+namespace VERILOG_FRONTEND
+{
+extern bool sv_mode;
+}
+YOSYS_NAMESPACE_END
+
+#endif
diff --git a/yosys-plugins/systemverilog/UhdmAstUpstream.cc b/yosys-plugins/systemverilog/UhdmAstUpstream.cc
new file mode 100644
index 000000000..921acf1b0
--- /dev/null
+++ b/yosys-plugins/systemverilog/UhdmAstUpstream.cc
@@ -0,0 +1,216 @@
+namespace AST
+{
+enum AstNodeTypeExtended {
+    AST_DOT = AST::AST_BIND + 1, // here we always want to point to the last element of yosys' AstNodeType
+    AST_BREAK,
+    AST_CONTINUE
+};
+}
+
+static AST::AstNode *mkconst_real(double d)
+{
+    AST::AstNode *node = new AST::AstNode(AST::AST_REALVALUE);
+    node->realvalue = d;
+    return node;
+}
+namespace VERILOG_FRONTEND
+{
+using namespace AST;
+// divide an arbitrary length decimal number by two and return the rest
+static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
+{
+    int carry = 0;
+    for (size_t i = 0; i < digits.size(); i++) {
+        if (digits[i] >= 10)
+            log_file_error(current_filename, get_line_num(), "Invalid use of [a-fxz?] in decimal constant.\n");
+        digits[i] += carry * 10;
+        carry = digits[i] % 2;
+        digits[i] /= 2;
+    }
+    while (!digits.empty() && !digits.front())
+        digits.erase(digits.begin());
+    return carry;
+}
+
+// find the number of significant bits in a binary number (not including the sign bit)
+static int my_ilog2(int x)
+{
+    int ret = 0;
+    while (x != 0 && x != -1) {
+        x = x >> 1;
+        ret++;
+    }
+    return ret;
+}
+
+// parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?')
+static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized)
+{
+    // all digits in string (MSB at index 0)
+    std::vector<uint8_t> digits;
+
+    while (*str) {
+        if ('0' <= *str && *str <= '9')
+            digits.push_back(*str - '0');
+        else if ('a' <= *str && *str <= 'f')
+            digits.push_back(10 + *str - 'a');
+        else if ('A' <= *str && *str <= 'F')
+            digits.push_back(10 + *str - 'A');
+        else if (*str == 'x' || *str == 'X')
+            digits.push_back(0xf0);
+        else if (*str == 'z' || *str == 'Z' || *str == '?')
+            digits.push_back(0xf1);
+        str++;
+    }
+
+    if (base == 10 && GetSize(digits) == 1 && digits.front() >= 0xf0)
+        base = 2;
+
+    data.clear();
+
+    if (base == 10) {
+        while (!digits.empty())
+            data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0);
+    } else {
+        int bits_per_digit = my_ilog2(base - 1);
+        for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) {
+            if (*it > (base - 1) && *it < 0xf0)
+                log_file_error(current_filename, get_line_num(), "Digit larger than %d used in in base-%d constant.\n", base - 1, base);
+            for (int i = 0; i < bits_per_digit; i++) {
+                int bitmask = 1 << i;
+                if (*it == 0xf0)
+                    data.push_back(case_type == 'x' ? RTLIL::Sa : RTLIL::Sx);
+                else if (*it == 0xf1)
+                    data.push_back(case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz);
+                else
+                    data.push_back((*it & bitmask) ? State::S1 : State::S0);
+            }
+        }
+    }
+
+    int len = GetSize(data);
+    RTLIL::State msb = data.empty() ? State::S0 : data.back();
+
+    if (len_in_bits < 0) {
+        if (len < 32)
+            data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb);
+        return;
+    }
+
+    if (is_unsized && (len > len_in_bits))
+        log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len);
+
+    for (len = len - 1; len >= 0; len--)
+        if (data[len] == State::S1)
+            break;
+    if (msb == State::S0 || msb == State::S1) {
+        len += 1;
+        data.resize(len_in_bits, State::S0);
+    } else {
+        len += 2;
+        data.resize(len_in_bits, msb);
+    }
+
+    if (len_in_bits == 0)
+        log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");
+
+    if (len > len_in_bits)
+        log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n", len_in_bits, len, current_filename.c_str(),
+                    get_line_num());
+}
+
+// convert the Verilog code for a constant to an AST node
+static AST::AstNode *const2ast(std::string code, char case_type, bool warn_z)
+{
+    if (warn_z) {
+        AST::AstNode *ret = const2ast(code, case_type, false);
+        if (ret != nullptr && std::find(ret->bits.begin(), ret->bits.end(), RTLIL::State::Sz) != ret->bits.end())
+            log_warning("Yosys has only limited support for tri-state logic at the moment. (%s:%d)\n", current_filename.c_str(), get_line_num());
+        return ret;
+    }
+
+    const char *str = code.c_str();
+
+    // Strings
+    if (*str == '"') {
+        int len = strlen(str) - 2;
+        std::vector<RTLIL::State> data;
+        data.reserve(len * 8);
+        for (int i = 0; i < len; i++) {
+            unsigned char ch = str[len - i];
+            for (int j = 0; j < 8; j++) {
+                data.push_back((ch & 1) ? State::S1 : State::S0);
+                ch = ch >> 1;
+            }
+        }
+        AST::AstNode *ast = AST::AstNode::mkconst_bits(data, false);
+        ast->str = code;
+        return ast;
+    }
+
+    for (size_t i = 0; i < code.size(); i++)
+        if (code[i] == '_' || code[i] == ' ' || code[i] == '\t' || code[i] == '\r' || code[i] == '\n')
+            code.erase(code.begin() + (i--));
+    str = code.c_str();
+
+    char *endptr;
+    long len_in_bits = strtol(str, &endptr, 10);
+
+    // Simple base-10 integer
+    if (*endptr == 0) {
+        std::vector<RTLIL::State> data;
+        my_strtobin(data, str, -1, 10, case_type, false);
+        if (data.back() == State::S1)
+            data.push_back(State::S0);
+        return AST::AstNode::mkconst_bits(data, true);
+    }
+
+    // unsized constant
+    if (str == endptr)
+        len_in_bits = -1;
+
+    // The "<bits>'[sS]?[bodhBODH]<digits>" syntax
+    if (*endptr == '\'') {
+        std::vector<RTLIL::State> data;
+        bool is_signed = false;
+        bool is_unsized = len_in_bits < 0;
+        if (*(endptr + 1) == 's' || *(endptr + 1) == 'S') {
+            is_signed = true;
+            endptr++;
+        }
+        switch (*(endptr + 1)) {
+        case 'b':
+        case 'B':
+            my_strtobin(data, endptr + 2, len_in_bits, 2, case_type, is_unsized);
+            break;
+        case 'o':
+        case 'O':
+            my_strtobin(data, endptr + 2, len_in_bits, 8, case_type, is_unsized);
+            break;
+        case 'd':
+        case 'D':
+            my_strtobin(data, endptr + 2, len_in_bits, 10, case_type, is_unsized);
+            break;
+        case 'h':
+        case 'H':
+            my_strtobin(data, endptr + 2, len_in_bits, 16, case_type, is_unsized);
+            break;
+        default:
+            char next_char = char(tolower(*(endptr + 1)));
+            if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') {
+                is_unsized = true;
+                my_strtobin(data, endptr + 1, 1, 2, case_type, is_unsized);
+            } else {
+                return NULL;
+            }
+        }
+        if (len_in_bits < 0) {
+            if (is_signed && data.back() == State::S1)
+                data.push_back(State::S0);
+        }
+        return AST::AstNode::mkconst_bits(data, is_signed, is_unsized);
+    }
+
+    return NULL;
+}
+} // namespace VERILOG_FRONTEND
diff --git a/yosys-plugins/systemverilog/tests/Makefile b/yosys-plugins/systemverilog/tests/Makefile
new file mode 100644
index 000000000..e078fa75c
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/Makefile
@@ -0,0 +1,25 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+TESTS = counter \
+		break_continue \
+		separate-compilation
+
+include $(shell pwd)/../../Makefile_test.common
+
+counter_verify = true
+break_continue_verify = $(call diff_test,break_continue,out)
+separate-compilation_verify = true
diff --git a/yosys-plugins/systemverilog/tests/break_continue/break_continue.golden.out b/yosys-plugins/systemverilog/tests/break_continue/break_continue.golden.out
new file mode 100644
index 000000000..74a27c291
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/break_continue/break_continue.golden.out
@@ -0,0 +1,2 @@
+top	a	-	-	po	110
+top	b	-	-	po	15
diff --git a/yosys-plugins/systemverilog/tests/break_continue/break_continue.tcl b/yosys-plugins/systemverilog/tests/break_continue/break_continue.tcl
new file mode 100644
index 000000000..166c38e3b
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/break_continue/break_continue.tcl
@@ -0,0 +1,13 @@
+yosys -import
+if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
+yosys -import  ;# ingest plugin commands
+
+set TMP_DIR /tmp
+if { [info exists ::env(TMPDIR) ] } {
+  set TMP_DIR $::env(TMPDIR)
+}
+
+# Testing simple round-trip
+read_systemverilog -o $TMP_DIR/break-continue-test $::env(DESIGN_TOP).v
+prep
+write_table $::env(DESIGN_TOP).out
diff --git a/yosys-plugins/systemverilog/tests/break_continue/break_continue.v b/yosys-plugins/systemverilog/tests/break_continue/break_continue.v
new file mode 100644
index 000000000..d06d60b5f
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/break_continue/break_continue.v
@@ -0,0 +1,30 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module top(output int a, output int b);
+   initial begin
+      a = 0;
+      b = 0;
+      repeat(15) begin
+         if(a > 100) begin
+            if (b > 10)
+               break;
+            b = b + 5;
+            continue;
+         end
+         a = a + 10;
+      end
+   end
+endmodule
diff --git a/yosys-plugins/systemverilog/tests/counter/counter.tcl b/yosys-plugins/systemverilog/tests/counter/counter.tcl
new file mode 100644
index 000000000..56c9c03e3
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/counter/counter.tcl
@@ -0,0 +1,12 @@
+yosys -import
+if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
+yosys -import  ;# ingest plugin commands
+
+set TMP_DIR /tmp
+if { [info exists ::env(TMPDIR) ] } {
+  set TMP_DIR $::env(TMPDIR)
+}
+
+# Testing simple round-trip
+read_systemverilog -o $TMP_DIR/counter-test $::env(DESIGN_TOP).v
+write_verilog
diff --git a/yosys-plugins/systemverilog/tests/counter/counter.v b/yosys-plugins/systemverilog/tests/counter/counter.v
new file mode 100644
index 000000000..3dabd7e7f
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/counter/counter.v
@@ -0,0 +1,33 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module top (
+  input clk,
+  output [3:0] led
+);
+  localparam BITS = 4;
+  localparam LOG2DELAY = 22;
+
+  wire bufg;
+  BUFG bufgctrl (
+      .I(clk),
+      .O(bufg)
+  );
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+  always @(posedge bufg) begin
+    counter <= counter + 1;
+  end
+  assign led[3:0] = counter >> LOG2DELAY;
+endmodule
diff --git a/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-buf.sv b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-buf.sv
new file mode 100644
index 000000000..565946b5d
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-buf.sv
@@ -0,0 +1,21 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module BUF (
+  input I,
+  output O
+);
+  assign O = I;
+endmodule;
diff --git a/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-pkg.sv b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-pkg.sv
new file mode 100644
index 000000000..b0362fcf9
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation-pkg.sv
@@ -0,0 +1,19 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 pkg;
+  parameter BITS = 4;
+  parameter LOG2DELAY = 22;
+endpackage
diff --git a/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.tcl b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.tcl
new file mode 100644
index 000000000..e9eec9258
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.tcl
@@ -0,0 +1,16 @@
+yosys -import
+if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
+yosys -import  ;# ingest plugin commands
+
+set TMP_DIR /tmp
+if { [info exists ::env(TMPDIR) ] } {
+  set TMP_DIR $::env(TMPDIR)
+}
+
+# Testing simple round-trip
+read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP)-pkg.sv
+read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP)-buf.sv
+read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP).v
+read_systemverilog -odir $TMP_DIR/separate-compilation-test -link
+hierarchy
+write_verilog
diff --git a/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.v b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.v
new file mode 100644
index 000000000..5bd294a08
--- /dev/null
+++ b/yosys-plugins/systemverilog/tests/separate-compilation/separate-compilation.v
@@ -0,0 +1,31 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+module top (
+  input clk,
+  output [3:0] led
+);
+
+  wire bufg;
+  BUF bufgctrl (
+      .I(clk),
+      .O(bufg)
+  );
+  reg [pkg::BITS + pkg::LOG2DELAY-1 : 0] counter = 0;
+  always @(posedge bufg) begin
+    counter <= counter + 1;
+  end
+  assign led[3:0] = counter >> pkg::LOG2DELAY;
+endmodule
diff --git a/yosys-plugins/systemverilog/uhdmastfrontend.cc b/yosys-plugins/systemverilog/uhdmastfrontend.cc
new file mode 100644
index 000000000..c09688c90
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmastfrontend.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "uhdmcommonfrontend.h"
+
+namespace UHDM
+{
+extern void visit_object(vpiHandle obj_h, int indent, const char *relation, std::set<const BaseClass *> *visited, std::ostream &out,
+                         bool shallowVisit = false);
+}
+
+YOSYS_NAMESPACE_BEGIN
+
+struct UhdmAstFrontend : public UhdmCommonFrontend {
+    UhdmAstFrontend() : UhdmCommonFrontend("uhdm", "read UHDM file") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    read_uhdm [options] [filename]\n");
+        log("\n");
+        log("Load design from a UHDM file into the current design\n");
+        log("\n");
+        this->print_read_options();
+    }
+    AST::AstNode *parse(std::string filename) override
+    {
+        UHDM::Serializer serializer;
+
+        std::vector<vpiHandle> restoredDesigns = serializer.Restore(filename);
+        UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
+        synthSubset->listenDesigns(restoredDesigns);
+        delete synthSubset;
+        if (this->shared.debug_flag || !this->report_directory.empty()) {
+            for (auto design : restoredDesigns) {
+                std::stringstream strstr;
+                UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : strstr);
+            }
+        }
+        UhdmAst uhdm_ast(this->shared);
+        AST::AstNode *current_ast = uhdm_ast.visit_designs(restoredDesigns);
+        if (!this->report_directory.empty()) {
+            this->shared.report.write(this->report_directory);
+        }
+        for (auto design : restoredDesigns)
+            vpi_release_handle(design);
+
+        serializer.Purge();
+        return current_ast;
+    }
+    void call_log_header(RTLIL::Design *design) override { log_header(design, "Executing UHDM frontend.\n"); }
+} UhdmAstFrontend;
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/systemverilog/uhdmastreport.cc b/yosys-plugins/systemverilog/uhdmastreport.cc
new file mode 100644
index 000000000..9a2832f2d
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmastreport.cc
@@ -0,0 +1,87 @@
+#include "uhdmastreport.h"
+#include "frontends/ast/ast.h"
+#include <fstream>
+#include <sys/stat.h>
+#include <uhdm/BaseClass.h>
+#include <unordered_set>
+
+YOSYS_NAMESPACE_BEGIN
+
+void UhdmAstReport::mark_handled(const UHDM::BaseClass *object)
+{
+    handled_count_per_file.insert(std::make_pair(object->VpiFile(), 0));
+    auto it = unhandled.find(object);
+    if (it != unhandled.end()) {
+        unhandled.erase(it);
+        handled_count_per_file.at(object->VpiFile())++;
+    }
+}
+
+void UhdmAstReport::mark_handled(const vpiHandle obj_h)
+{
+    auto handle = reinterpret_cast<const uhdm_handle *>(obj_h);
+    mark_handled(reinterpret_cast<const UHDM::BaseClass *>(handle->object));
+}
+
+static std::string replace_in_string(std::string str, const std::string &to_find, const std::string &to_replace_with)
+{
+    size_t pos = str.find(to_find);
+    while (pos != std::string::npos) {
+        str.replace(pos, to_find.length(), to_replace_with);
+        pos += to_replace_with.length();
+        pos = str.find(to_find, pos);
+    }
+    return str;
+}
+
+void UhdmAstReport::write(const std::string &directory)
+{
+    std::unordered_map<std::string, std::unordered_set<unsigned>> unhandled_per_file;
+    for (auto object : unhandled) {
+        if (!object->VpiFile().empty() && object->VpiFile() != AST::current_filename) {
+            unhandled_per_file.insert(std::make_pair(object->VpiFile(), std::unordered_set<unsigned>()));
+            unhandled_per_file.at(object->VpiFile()).insert(object->VpiLineNo());
+            handled_count_per_file.insert(std::make_pair(object->VpiFile(), 0));
+        }
+    }
+    unsigned total_handled = 0;
+    for (auto &hc : handled_count_per_file) {
+        if (!hc.first.empty() && hc.first != AST::current_filename) {
+            unhandled_per_file.insert(std::make_pair(hc.first, std::unordered_set<unsigned>()));
+            total_handled += hc.second;
+        }
+    }
+    float coverage = total_handled * 100.f / (total_handled + unhandled.size());
+    mkdir(directory.c_str(), 0777);
+    std::ofstream index_file(directory + "/index.html");
+    index_file << "<!DOCTYPE html>\n<html>\n<head>\n<style>h3{margin:0;padding:10}</style>\n</head><body>" << std::endl;
+    index_file << "<h2>Overall coverage: " << coverage << "%</h2>" << std::endl;
+    for (auto &unhandled_in_file : unhandled_per_file) {
+        // Calculate coverage in file
+        unsigned handled_count = handled_count_per_file.at(unhandled_in_file.first);
+        unsigned unhandled_count = unhandled_in_file.second.size();
+        float coverage = handled_count * 100.f / (handled_count + unhandled_count);
+        // Add to the index file
+        std::string report_filename = replace_in_string(unhandled_in_file.first, "/", ".") + ".html";
+        index_file << "<h3>Cov: " << coverage << "%<a href=\"" << report_filename << "\">" << unhandled_in_file.first << "</a></h3><br>" << std::endl;
+        // Write the report file
+        std::ofstream report_file(directory + '/' + report_filename);
+        report_file << "<!DOCTYPE html>\n<html>\n<head>\n<style>\nbody{font-size:12px;}pre{display:inline}</style>\n</head><body>" << std::endl;
+        report_file << "<h2>" << unhandled_in_file.first << " | Coverage: " << coverage << "%</h2>" << std::endl;
+        std::ifstream source_file(unhandled_in_file.first); // Read the source code
+        unsigned line_number = 1;
+        std::string line;
+        while (std::getline(source_file, line)) {
+            if (unhandled_in_file.second.find(line_number) == unhandled_in_file.second.end()) {
+                report_file << line_number << "<pre> " << line << "</pre><br>" << std::endl;
+            } else {
+                report_file << line_number << "<pre style=\"background-color: #FFB6C1;\"> " << line << "</pre><br>" << std::endl;
+            }
+            ++line_number;
+        }
+        report_file << "</body>\n</html>" << std::endl;
+    }
+    index_file << "</body>\n</html>" << std::endl;
+}
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/systemverilog/uhdmastreport.h b/yosys-plugins/systemverilog/uhdmastreport.h
new file mode 100644
index 000000000..ae16b95f9
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmastreport.h
@@ -0,0 +1,35 @@
+#ifndef _UHDM_AST_REPORT_H_
+#define _UHDM_AST_REPORT_H_ 1
+
+#include "kernel/yosys.h"
+#include <map>
+#include <string>
+#include <unordered_map>
+#undef cover
+#include <uhdm/uhdm.h>
+
+YOSYS_NAMESPACE_BEGIN
+
+class UhdmAstReport
+{
+  private:
+    // Maps a filename to the number of objects being handled by the frontend
+    std::unordered_map<std::string, unsigned> handled_count_per_file;
+
+  public:
+    // Objects not being handled by the frontend
+    std::set<const UHDM::BaseClass *> unhandled;
+
+    // Marks the specified object as being handled by the frontend
+    void mark_handled(const UHDM::BaseClass *object);
+
+    // Marks the object referenced by the specified handle as being handled by the frontend
+    void mark_handled(vpiHandle obj_h);
+
+    // Write the coverage report to the specified path
+    void write(const std::string &directory);
+};
+
+YOSYS_NAMESPACE_END
+
+#endif
diff --git a/yosys-plugins/systemverilog/uhdmastshared.h b/yosys-plugins/systemverilog/uhdmastshared.h
new file mode 100644
index 000000000..a1ad1c6ff
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmastshared.h
@@ -0,0 +1,69 @@
+#ifndef _UHDM_AST_SHARED_H_
+#define _UHDM_AST_SHARED_H_ 1
+
+#include "uhdmastreport.h"
+#include <string>
+#include <unordered_map>
+
+YOSYS_NAMESPACE_BEGIN
+
+class UhdmAstShared
+{
+  private:
+    // Used for generating enum names
+    unsigned enum_count = 0;
+
+    // Used for generating port IDS
+    unsigned port_count = 0;
+
+    // Used for generating loop names
+    unsigned loop_count = 0;
+
+  public:
+    // Generate the next enum ID (starting with 0)
+    unsigned next_enum_id() { return enum_count++; }
+
+    // Generate the next port ID (starting with 1)
+    unsigned next_port_id() { return ++port_count; }
+
+    // Generate the next loop ID (starting with 0)
+    unsigned next_loop_id() { return loop_count++; }
+
+    // Flag that determines whether debug info should be printed
+    bool debug_flag = false;
+
+    // Flag that determines whether we should ignore assert() statements
+    bool no_assert = false;
+
+    // Flag that determines whether errors should be fatal
+    bool stop_on_error = true;
+
+    // Flag that determines whether we should only parse the design
+    // applies only to read_systemverilog command
+    bool parse_only = false;
+
+    // Flag that determines whether we should defer the elaboration
+    // applies only to read_systemverilog command
+    bool defer = false;
+
+    // Flag that determines whether we should perform the elaboration now
+    // applies only to read_systemverilog command
+    bool link = false;
+
+    // Top nodes of the design (modules, interfaces)
+    std::unordered_map<std::string, AST::AstNode *> top_nodes;
+
+    // UHDM node coverage report
+    UhdmAstReport report;
+
+    // Map from AST param nodes to their types (used for params with struct types)
+    std::unordered_map<std::string, AST::AstNode *> param_types;
+
+    AST::AstNode *current_top_node = nullptr;
+    // Set of non-synthesizable objects to skip in current design;
+    std::set<const UHDM::BaseClass *> nonSynthesizableObjects;
+};
+
+YOSYS_NAMESPACE_END
+
+#endif
diff --git a/yosys-plugins/systemverilog/uhdmcommonfrontend.cc b/yosys-plugins/systemverilog/uhdmcommonfrontend.cc
new file mode 100644
index 000000000..651552af6
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmcommonfrontend.cc
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "uhdmcommonfrontend.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+/* Stub for AST::process */
+static void set_line_num(int) {}
+
+/* Stub for AST::process */
+static int get_line_num(void) { return 1; }
+
+void UhdmCommonFrontend::print_read_options()
+{
+    log("    -noassert\n");
+    log("        ignore assert() statements");
+    log("\n");
+    log("    -debug\n");
+    log("        alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2\n");
+    log("\n");
+    log("    -dump_ast1\n");
+    log("        dump abstract syntax tree (before simplification)\n");
+    log("\n");
+    log("    -dump_ast2\n");
+    log("        dump abstract syntax tree (after simplification)\n");
+    log("\n");
+    log("    -no_dump_ptr\n");
+    log("        do not include hex memory addresses in dump (easier to diff dumps)\n");
+    log("\n");
+    log("    -dump_vlog1\n");
+    log("        dump ast as Verilog code (before simplification)\n");
+    log("\n");
+    log("    -dump_vlog2\n");
+    log("        dump ast as Verilog code (after simplification)\n");
+    log("\n");
+    log("    -dump_rtlil\n");
+    log("        dump generated RTLIL netlist\n");
+    log("\n");
+    log("    -report [directory]\n");
+    log("        write a coverage report for the UHDM file\n");
+    log("\n");
+    log("    -defer\n");
+    log("        only read the abstract syntax tree and defer actual compilation\n");
+    log("        to a later 'hierarchy' command. Useful in cases where the default\n");
+    log("        parameters of modules yield invalid or not synthesizable code.\n");
+    log("        Needs to be followed by read_systemverilog -link after reading\n");
+    log("        all files.\n");
+    log("    -link\n");
+    log("        performs linking and elaboration of the files read with -defer\n");
+    log("    -parse-only\n");
+    log("        this parameter only applies to read_systemverilog command,\n");
+    log("        it runs only Surelog to parse design, but doesn't load generated\n");
+    log("        tree into Yosys.\n");
+    log("\n");
+}
+
+void UhdmCommonFrontend::execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+{
+    this->call_log_header(design);
+    this->args = args;
+
+    bool defer = false;
+    bool dump_ast1 = false;
+    bool dump_ast2 = false;
+    bool dump_vlog1 = false;
+    bool dump_vlog2 = false;
+    bool no_dump_ptr = false;
+    bool dump_rtlil = false;
+    std::vector<std::string> unhandled_args;
+
+    for (size_t i = 0; i < args.size(); i++) {
+        if (args[i] == "-debug") {
+            dump_ast1 = true;
+            dump_ast2 = true;
+            dump_vlog1 = true;
+            dump_vlog2 = true;
+            this->shared.debug_flag = true;
+        } else if (args[i] == "-report" && ++i < args.size()) {
+            this->report_directory = args[i];
+            this->shared.stop_on_error = false;
+        } else if (args[i] == "-noassert") {
+            this->shared.no_assert = true;
+        } else if (args[i] == "-defer") {
+            this->shared.defer = true;
+        } else if (args[i] == "-dump_ast1") {
+            dump_ast1 = true;
+        } else if (args[i] == "-dump_ast2") {
+            dump_ast2 = true;
+        } else if (args[i] == "-dump_vlog1") {
+            dump_vlog1 = true;
+        } else if (args[i] == "-dump_vlog2") {
+            dump_vlog2 = true;
+        } else if (args[i] == "-no_dump_ptr") {
+            no_dump_ptr = true;
+        } else if (args[i] == "-dump_rtlil") {
+            dump_rtlil = true;
+        } else if (args[i] == "-parse-only") {
+            this->shared.parse_only = true;
+        } else if (args[i] == "-link") {
+            this->shared.link = true;
+            // Surelog needs it in the command line to link correctly
+            unhandled_args.push_back(args[i]);
+        } else {
+            unhandled_args.push_back(args[i]);
+        }
+    }
+    // Yosys gets confused when extra_args are passed with -link or no option
+    // It's done fully by Surelog, so skip it in this case
+    if (!this->shared.link)
+        extra_args(f, filename, args, args.size() - 1);
+    // pass only unhandled args to Surelog
+    // unhandled args starts with command name,
+    // but Surelog expects args[0] to be program name
+    // and skips it
+    this->args = unhandled_args;
+
+    AST::current_filename = filename;
+    AST::set_line_num = &set_line_num;
+    AST::get_line_num = &get_line_num;
+
+    bool dont_redefine = false;
+    bool default_nettype_wire = true;
+
+    AST::AstNode *current_ast = parse(filename);
+
+    if (current_ast) {
+        AST::process(design, current_ast, dump_ast1, dump_ast2, no_dump_ptr, dump_vlog1, dump_vlog2, dump_rtlil, false, false, false, false, false,
+                     false, false, false, false, false, dont_redefine, false, defer, default_nettype_wire);
+        delete current_ast;
+    }
+}
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/systemverilog/uhdmcommonfrontend.h b/yosys-plugins/systemverilog/uhdmcommonfrontend.h
new file mode 100644
index 000000000..3d5ff169d
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmcommonfrontend.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "UhdmAst.h"
+#include "frontends/ast/ast.h"
+#include "kernel/yosys.h"
+#include "uhdm/SynthSubset.h"
+#include "uhdm/VpiListener.h"
+#include <string>
+#include <vector>
+
+YOSYS_NAMESPACE_BEGIN
+
+struct UhdmCommonFrontend : public Frontend {
+    UhdmAstShared shared;
+    std::string report_directory;
+    std::vector<std::string> args;
+    UhdmCommonFrontend(std::string name, std::string short_help) : Frontend(name, short_help) {}
+    virtual void print_read_options();
+    virtual void help() = 0;
+    virtual AST::AstNode *parse(std::string filename) = 0;
+    virtual void call_log_header(RTLIL::Design *design) = 0;
+    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design);
+};
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/systemverilog/uhdmsurelogastfrontend.cc b/yosys-plugins/systemverilog/uhdmsurelogastfrontend.cc
new file mode 100644
index 000000000..0a72d2634
--- /dev/null
+++ b/yosys-plugins/systemverilog/uhdmsurelogastfrontend.cc
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "UhdmAst.h"
+#include "frontends/ast/ast.h"
+#include "kernel/yosys.h"
+#include "uhdmcommonfrontend.h"
+
+#if defined(_MSC_VER)
+#include <direct.h>
+#include <process.h>
+#else
+#include <sys/param.h>
+#include <unistd.h>
+#endif
+
+#include "Surelog/ErrorReporting/Report.h"
+#include "Surelog/surelog.h"
+
+namespace UHDM
+{
+extern void visit_object(vpiHandle obj_h, int indent, const char *relation, std::set<const BaseClass *> *visited, std::ostream &out,
+                         bool shallowVisit = false);
+}
+
+YOSYS_NAMESPACE_BEGIN
+
+std::vector<vpiHandle> executeCompilation(SURELOG::SymbolTable *symbolTable, SURELOG::ErrorContainer *errors, SURELOG::CommandLineParser *clp,
+                                          SURELOG::scompiler *compiler)
+{
+    bool success = true;
+    bool noFatalErrors = true;
+    unsigned int codedReturn = 0;
+    clp->setWriteUhdm(false);
+    errors->printMessages(clp->muteStdout());
+    std::vector<vpiHandle> the_design;
+    if (success && (!clp->help())) {
+        compiler = SURELOG::start_compiler(clp);
+        if (!compiler)
+            codedReturn |= 1;
+        the_design.push_back(SURELOG::get_uhdm_design(compiler));
+    }
+    SURELOG::ErrorContainer::Stats stats;
+    if (!clp->help()) {
+        stats = errors->getErrorStats();
+        if (stats.nbFatal)
+            codedReturn |= 1;
+        if (stats.nbSyntax)
+            codedReturn |= 2;
+    }
+    bool noFErrors = true;
+    if (!clp->help())
+        noFErrors = errors->printStats(stats, clp->muteStdout());
+    if (noFErrors == false) {
+        noFatalErrors = false;
+    }
+    if ((!noFatalErrors) || (!success) || (errors->getErrorStats().nbError))
+        codedReturn |= 1;
+    if (codedReturn) {
+        log_error("Error when parsing design. Aborting!\n");
+    }
+    return the_design;
+}
+
+struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
+    UhdmSurelogAstFrontend(std::string name, std::string short_help) : UhdmCommonFrontend(name, short_help) {}
+    UhdmSurelogAstFrontend() : UhdmCommonFrontend("verilog_with_uhdm", "generate/read UHDM file") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    read_verilog_with_uhdm [options] [filenames]\n");
+        log("\n");
+        log("Read SystemVerilog files using Surelog into the current design\n");
+        log("\n");
+        this->print_read_options();
+    }
+    AST::AstNode *parse(std::string filename) override
+    {
+        std::vector<const char *> cstrings;
+        cstrings.reserve(this->args.size());
+        for (size_t i = 0; i < this->args.size(); ++i)
+            cstrings.push_back(const_cast<char *>(this->args[i].c_str()));
+
+        SURELOG::SymbolTable *symbolTable = new SURELOG::SymbolTable();
+        SURELOG::ErrorContainer *errors = new SURELOG::ErrorContainer(symbolTable);
+        SURELOG::CommandLineParser *clp = new SURELOG::CommandLineParser(errors, symbolTable, false, false);
+        bool success = clp->parseCommandLine(cstrings.size(), &cstrings[0]);
+        if (!success) {
+            log_error("Error parsing Surelog arguments!\n");
+        }
+        // Force -parse flag settings even if it wasn't specified
+        clp->setwritePpOutput(true);
+        clp->setParse(true);
+        clp->fullSVMode(true);
+        clp->setCacheAllowed(true);
+        if (this->shared.defer) {
+            clp->setCompile(false);
+            clp->setElaborate(false);
+            clp->setSepComp(true);
+        } else {
+            clp->setCompile(true);
+            clp->setElaborate(true);
+        }
+        if (this->shared.link) {
+            clp->setLink(true);
+        }
+
+        SURELOG::scompiler *compiler = nullptr;
+        const std::vector<vpiHandle> uhdm_design = executeCompilation(symbolTable, errors, clp, compiler);
+        if (this->shared.debug_flag || !this->report_directory.empty()) {
+            for (auto design : uhdm_design) {
+                std::stringstream strstr;
+                UHDM::visit_object(design, 1, "", &this->shared.report.unhandled, this->shared.debug_flag ? std::cout : strstr);
+            }
+        }
+
+        SURELOG::shutdown_compiler(compiler);
+        delete clp;
+        delete symbolTable;
+        delete errors;
+        // on parse_only mode, don't try to load design
+        // into yosys
+        if (this->shared.parse_only)
+            return nullptr;
+
+        UhdmAst uhdm_ast(this->shared);
+        if (this->shared.defer && !this->shared.link)
+            return nullptr;
+
+        // FIXME: SynthSubset annotation is incompatible with separate compilation
+        // `-defer` turns elaboration off, so check for it
+        // Should be called 1. for normal flow 2. after finishing with `-link`
+        if (!this->shared.defer) {
+            UHDM::Serializer serializer;
+            UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
+            synthSubset->listenDesigns(uhdm_design);
+            delete synthSubset;
+        }
+
+        AST::AstNode *current_ast = uhdm_ast.visit_designs(uhdm_design);
+        if (!this->report_directory.empty()) {
+            this->shared.report.write(this->report_directory);
+        }
+
+        return current_ast;
+    }
+    void call_log_header(RTLIL::Design *design) override { log_header(design, "Executing Verilog with UHDM frontend.\n"); }
+} UhdmSurelogAstFrontend;
+
+struct UhdmSystemVerilogFrontend : public UhdmSurelogAstFrontend {
+    UhdmSystemVerilogFrontend() : UhdmSurelogAstFrontend("systemverilog", "read SystemVerilog files") {}
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    read_systemverilog [options] [filenames]\n");
+        log("\n");
+        log("Read SystemVerilog files using Surelog into the current design\n");
+        log("\n");
+        this->print_read_options();
+    }
+} UhdmSystemVerilogFrontend;
+
+YOSYS_NAMESPACE_END
diff --git a/yosys-plugins/test-utils.tcl b/yosys-plugins/test-utils.tcl
new file mode 100644
index 000000000..cc215ae88
--- /dev/null
+++ b/yosys-plugins/test-utils.tcl
@@ -0,0 +1,7 @@
+# Utility functions to be used in tests.
+
+# Return path where the test output file "filename"
+# is to be written.
+proc test_output_path { filename } {
+    return "$::env(TEST_OUTPUT_PREFIX)${filename}"
+}
diff --git a/yosys-plugins/uhdm/Makefile b/yosys-plugins/uhdm/Makefile
new file mode 100644
index 000000000..3eea3d43e
--- /dev/null
+++ b/yosys-plugins/uhdm/Makefile
@@ -0,0 +1,19 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = uhdm
+SOURCES = uhdm.cc
+include ../Makefile_plugin.common
diff --git a/yosys-plugins/uhdm/README.md b/yosys-plugins/uhdm/README.md
new file mode 100644
index 000000000..cecd42706
--- /dev/null
+++ b/yosys-plugins/uhdm/README.md
@@ -0,0 +1,6 @@
+# UHDM Plugin
+
+The UHDM plugin has been renamed to [SystemVerilog](../systemverilog-plugin/).
+
+It is kept here for backwards compatibility reasons.
+When loaded, it shows a warning and loads the `SystemVerilog` plugin (if available).
diff --git a/yosys-plugins/uhdm/tests/Makefile b/yosys-plugins/uhdm/tests/Makefile
new file mode 100644
index 000000000..1c6f1d813
--- /dev/null
+++ b/yosys-plugins/uhdm/tests/Makefile
@@ -0,0 +1,17 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 $(shell pwd)/../../Makefile_test.common
diff --git a/yosys-plugins/uhdm/uhdm.cc b/yosys-plugins/uhdm/uhdm.cc
new file mode 100644
index 000000000..9fde149ee
--- /dev/null
+++ b/yosys-plugins/uhdm/uhdm.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+
+PRIVATE_NAMESPACE_BEGIN
+
+struct UhdmDummy {
+    UhdmDummy()
+    {
+        log("\n");
+        log("!! DEPRECATION WARNING !!\n");
+        log("\n");
+        log("The uhdm plugin has been renamed to systemverilog.\n");
+        log("Loading the systemverilog plugin...\n");
+
+        std::vector<std::string> plugin_aliases;
+        load_plugin("systemverilog", plugin_aliases);
+    }
+} UhdmDummy;
+
+PRIVATE_NAMESPACE_END
diff --git a/yosys-plugins/utils.h b/yosys-plugins/utils.h
new file mode 100644
index 000000000..42ad7b158
--- /dev/null
+++ b/yosys-plugins/utils.h
@@ -0,0 +1,19 @@
+#include <algorithm>
+#include <cctype>
+#include <locale>
+
+inline void trim_left(std::string &str)
+{
+    str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](unsigned char ch) { return !std::isspace(ch); }));
+}
+
+inline void trim_right(std::string &str)
+{
+    str.erase(std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), str.end());
+}
+
+inline void trim(std::string &str)
+{
+    trim_left(str);
+    trim_right(str);
+}
diff --git a/yosys-plugins/xdc/BANK.v b/yosys-plugins/xdc/BANK.v
new file mode 100644
index 000000000..dea2a5ed3
--- /dev/null
+++ b/yosys-plugins/xdc/BANK.v
@@ -0,0 +1,21 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module BANK();
+	parameter FASM_EXTRA = "INTERNAL_VREF";
+	parameter NUMBER = 0;
+	parameter INTERNAL_VREF = 600;
+endmodule
diff --git a/yosys-plugins/xdc/Makefile b/yosys-plugins/xdc/Makefile
new file mode 100644
index 000000000..06d61d7a8
--- /dev/null
+++ b/yosys-plugins/xdc/Makefile
@@ -0,0 +1,25 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+NAME = xdc
+SOURCES = xdc.cc
+include ../Makefile_plugin.common
+VERILOG_MODULES = BANK.v
+
+install_modules: $(VERILOG_MODULES)
+	install -D $< $(PLUGINS_DIR)/fasm_extra_modules/$<
+
+install: install_modules
diff --git a/yosys-plugins/xdc/tests/Makefile b/yosys-plugins/xdc/tests/Makefile
new file mode 100644
index 000000000..ce5ac8ce1
--- /dev/null
+++ b/yosys-plugins/xdc/tests/Makefile
@@ -0,0 +1,50 @@
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# counter - basic test for IOSTANDARD, SLEW, DRIVE, IN_TERM properties
+# counter-dict - basic test using XDC -dict for IOSTANDARD, SLEW, DRIVE, IN_TERM properties
+# package_pins-dict-space - basic test for variable whitespace between PACKAGE_PINs and IOSTANDARD
+# port_indexes - like counter but bus port indices are passes without curly braces
+# io_loc_pairs - test for LOC property being set on IOBUFs as the IO_LOC_PAIRS parameter
+# minilitex_ddr_arty - litex design with more types of IOBUFS including differential
+# package_pins - test for PACKAGE_PIN property being set on IOBUFs as the IO_LOC_PAIRS parameter
+# non_zero_port_indexes - testing IO_LOC_PAIRS for design with non-zero indexed ports
+TESTS = counter \
+	counter-dict \
+	package_pins-dict-space \
+	port_indexes \
+	io_loc_pairs \
+	minilitex_ddr_arty \
+	package_pins \
+	non_zero_port_indexes
+
+include $(shell pwd)/../../Makefile_test.common
+
+json_test = python compare_output_json.py --json $(1)/$(1).json --golden $(1)/$(1).golden.json
+
+define json_update =
+$(1)_update_json:
+	python compare_output_json.py --json $(1)/$(1).json --golden $(1)/$(1).golden.json --update
+endef
+
+counter_verify = $(call json_test,counter)
+counter-dict_verify = $(call json_test,counter-dict)
+port_indexes_verify = $(call json_test,port_indexes) && test $$(grep "'unknown' proc command handler" port_indexes/port_indexes.txt | wc -l) -eq 2
+io_loc_pairs_verify = $(call json_test,io_loc_pairs)
+minilitex_ddr_arty_verify = $(call json_test,minilitex_ddr_arty)
+package_pins_verify = $(call json_test,package_pins)
+package_pins-dict-space_verify = $(call json_test,package_pins-dict-space)
+non_zero_port_indexes_verify = $(call json_test,non_zero_port_indexes)
diff --git a/yosys-plugins/xdc/tests/compare_output_json.py b/yosys-plugins/xdc/tests/compare_output_json.py
new file mode 100644
index 000000000..d0440aa6a
--- /dev/null
+++ b/yosys-plugins/xdc/tests/compare_output_json.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2022 F4PGA Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 script extracts the top module cells and their corresponding parameters
+from json files produced by Yosys.
+The return code of this script is used to check if the output is equivalent.
+"""
+
+import sys
+import json
+import argparse
+
+parameters = ["IOSTANDARD", "DRIVE", "SLEW", "IN_TERM", "IO_LOC_PAIRS"]
+
+def read_cells(json_file):
+    with open(json_file) as f:
+        data = json.load(f)
+    f.close()
+    cells = data['modules']['top']['cells']
+    cells_parameters = dict()
+    for cell, opts in cells.items():
+        attributes = opts['parameters']
+        if len(attributes.keys()):
+            if any([x in parameters for x in attributes.keys()]):
+                cells_parameters[cell] = attributes
+    return cells_parameters
+
+
+def main(args):
+    cells = read_cells(args.json)
+    if args.update:
+        with open(args.golden, 'w') as f:
+            json.dump(cells, f, indent=2)
+    else:
+        with open(args.golden) as f:
+            cells_golden = json.load(f)
+            if cells == cells_golden:
+                exit(0)
+            else:
+                print(json.dumps(cells, indent=4))
+                print("VS")
+                print(json.dumps(cells_golden, indent=4))
+                exit(1)
+    f.close()
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--json', help = 'JSON to compare', required = True)
+    parser.add_argument('--golden', help = 'Golden JSON file', required = True)
+    parser.add_argument('--update', action = 'store_true', help = 'Update golden reference')
+    args = parser.parse_args()
+    main(args)
diff --git a/yosys-plugins/xdc/tests/counter-dict/counter-dict.golden.json b/yosys-plugins/xdc/tests/counter-dict/counter-dict.golden.json
new file mode 100644
index 000000000..25e123427
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter-dict/counter-dict.golden.json
@@ -0,0 +1,35 @@
+{
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/counter-dict/counter-dict.tcl b/yosys-plugins/xdc/tests/counter-dict/counter-dict.tcl
new file mode 100644
index 000000000..b6eb5b5cf
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter-dict/counter-dict.tcl
@@ -0,0 +1,19 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json [file dirname $::env(DESIGN_TOP)]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "counter-dict.json"]
diff --git a/yosys-plugins/xdc/tests/counter-dict/counter-dict.v b/yosys-plugins/xdc/tests/counter-dict/counter-dict.v
new file mode 100644
index 000000000..cc8a821db
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter-dict/counter-dict.v
@@ -0,0 +1,111 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/xdc/tests/counter-dict/counter-dict.xdc b/yosys-plugins/xdc/tests/counter-dict/counter-dict.xdc
new file mode 100644
index 000000000..a72cf8905
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter-dict/counter-dict.xdc
@@ -0,0 +1,20 @@
+#set_property LOC R2 [get_ports led]
+#OBUF_6
+set_property DRIVE 12 [get_ports {led[0]}]
+#OBUF_7
+set_property -dict { IN_TERM UNTUNED_SPLIT_40 SLEW FAST IOSTANDARD SSTL135 } [get_ports {led[1]}]
+#OBUF_OUT
+set_property -dict {IN_TERM UNTUNED_SPLIT_50 SLEW FAST IOSTANDARD LVCMOS33} [get_ports {out_a}]
+#bottom_inst.OBUF_10
+set_property -dict { SLEW SLOW IOSTANDARD LVCMOS18 } [get_ports {out_b[0]}]
+#bottom_inst.OBUF_11
+set_property -dict { DRIVE 4 SLEW FAST IOSTANDARD LVCMOS25 } [get_ports {out_b[1]}]
+#bottom_inst.OBUF_9
+set_property -dict { SLEW FAST IOSTANDARD DIFF_SSTL135 } [get_ports {led[2]}]
+#bottom_intermediate_inst.OBUF_8
+set_property -dict { DRIVE 16 IOSTANDARD SSTL135 } [get_ports {led[3]}]
+#set_property INTERNAL_VREF 0.600 [get_iobanks 14]
+#set_property INTERNAL_VREF 0.675 [get_iobanks 15]
+#set_property INTERNAL_VREF 0.750 [get_iobanks 16]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 34]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 35]
diff --git a/yosys-plugins/xdc/tests/counter/counter.golden.json b/yosys-plugins/xdc/tests/counter/counter.golden.json
new file mode 100644
index 000000000..25e123427
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter/counter.golden.json
@@ -0,0 +1,35 @@
+{
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/counter/counter.tcl b/yosys-plugins/xdc/tests/counter/counter.tcl
new file mode 100644
index 000000000..9347071e3
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter/counter.tcl
@@ -0,0 +1,19 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json [file dirname $::env(DESIGN_TOP)]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "counter.json"]
diff --git a/yosys-plugins/xdc/tests/counter/counter.v b/yosys-plugins/xdc/tests/counter/counter.v
new file mode 100644
index 000000000..cc8a821db
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter/counter.v
@@ -0,0 +1,111 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/xdc/tests/counter/counter.xdc b/yosys-plugins/xdc/tests/counter/counter.xdc
new file mode 100644
index 000000000..410ddb377
--- /dev/null
+++ b/yosys-plugins/xdc/tests/counter/counter.xdc
@@ -0,0 +1,30 @@
+#set_property LOC R2 [get_ports led]
+#OBUF_6
+set_property DRIVE 12 [get_ports {led[0]}]
+#OBUF_7
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {led[1]}]
+set_property SLEW FAST [get_ports {led[1]}]
+set_property IOSTANDARD SSTL135 [get_ports {led[1]}]
+#OBUF_OUT
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports {out_a}]
+set_property SLEW FAST [get_ports {out_a}]
+set_property IOSTANDARD LVCMOS33 [get_ports {out_a}]
+#bottom_inst.OBUF_10
+set_property SLEW SLOW [get_ports {out_b[0]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {out_b[0]}]
+#bottom_inst.OBUF_11
+set_property DRIVE 4 [get_ports {out_b[1]}]
+set_property SLEW FAST [get_ports {out_b[1]}]
+set_property IOSTANDARD LVCMOS25 [get_ports {out_b[1]}]
+#bottom_inst.OBUF_9
+set_property SLEW FAST [get_ports {led[2]}]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {led[2]}]
+#bottom_intermediate_inst.OBUF_8
+set_property DRIVE 16 [get_ports {led[3]}]
+set_property IOSTANDARD SSTL135 [get_ports {led[3]}]
+#set_property INTERNAL_VREF 0.600 [get_iobanks 14]
+#set_property INTERNAL_VREF 0.675 [get_iobanks 15]
+#set_property INTERNAL_VREF 0.750 [get_iobanks 16]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 34]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 35]
+
diff --git a/yosys-plugins/xdc/tests/io_loc_pairs/cells_xtra.v b/yosys-plugins/xdc/tests/io_loc_pairs/cells_xtra.v
new file mode 100644
index 000000000..37a334c68
--- /dev/null
+++ b/yosys-plugins/xdc/tests/io_loc_pairs/cells_xtra.v
@@ -0,0 +1,28 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module GTPE2_CHANNEL (
+    (* iopad_external_pin *)
+    output GTPTXN,
+    (* iopad_external_pin *)
+    output GTPTXP,
+    (* iopad_external_pin *)
+    input  GTPRXN,
+    (* iopad_external_pin *)
+    input  GTPRXP
+);
+
+endmodule
diff --git a/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.golden.json b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.golden.json
new file mode 100644
index 000000000..10d3909c7
--- /dev/null
+++ b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.golden.json
@@ -0,0 +1,53 @@
+{
+    "GTPE2_CHANNEL": {
+        "IO_LOC_PAIRS": "rx_p:G1,rx_n:G2,tx_p:G3,tx_n:G4"
+    },
+    "IBUFDS_GTE2": {
+        "IO_LOC_PAIRS": "ibufds_gte2_i:G5,ibufds_gte2_ib:G6"
+    },
+    "OBUFTDS_2": {
+        "IOSTANDARD": "DIFF_SSTL135",
+        "IO_LOC_PAIRS": "signal_p:N2,signal_n:N1",
+        "SLEW": "FAST"
+    },
+    "OBUF_6": {
+        "DRIVE": "12",
+        "IOSTANDARD": "LVCMOS33",
+        "IO_LOC_PAIRS": "led[0]:D10",
+        "SLEW": "SLOW"
+    },
+    "OBUF_7": {
+        "IN_TERM": "UNTUNED_SPLIT_40",
+        "IOSTANDARD": "SSTL135",
+        "IO_LOC_PAIRS": "led[1]:A9",
+        "SLEW": "FAST"
+    },
+    "OBUF_OUT": {
+        "IN_TERM": "UNTUNED_SPLIT_50",
+        "IOSTANDARD": "LVCMOS33",
+        "IO_LOC_PAIRS": "out_a:E3",
+        "SLEW": "FAST"
+    },
+    "bottom_inst.OBUF_10": {
+        "IOSTANDARD": "LVCMOS18",
+        "IO_LOC_PAIRS": "out_b[0]:C2",
+        "SLEW": "SLOW"
+    },
+    "bottom_inst.OBUF_11": {
+        "DRIVE": "4",
+        "IOSTANDARD": "LVCMOS25",
+        "IO_LOC_PAIRS": "out_b[1]:R2",
+        "SLEW": "FAST"
+    },
+    "bottom_inst.OBUF_9": {
+        "IOSTANDARD": "DIFF_SSTL135",
+        "IO_LOC_PAIRS": "led[2]:M6",
+        "SLEW": "FAST"
+    },
+    "bottom_intermediate_inst.OBUF_8": {
+        "DRIVE": "16",
+        "IOSTANDARD": "SSTL135",
+        "IO_LOC_PAIRS": "led[3]:N4",
+        "SLEW": "SLOW"
+    }
+}
diff --git a/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.tcl b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.tcl
new file mode 100644
index 000000000..d7f55064d
--- /dev/null
+++ b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.tcl
@@ -0,0 +1,26 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+read_verilog -lib -specify +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+read_verilog -lib [file dirname $::env(DESIGN_TOP)]/cells_xtra.v
+
+hierarchy -check -top top
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp -run prepare:check
+
+#Read the design constraints
+read_xdc -part_json [file dirname $::env(DESIGN_TOP)]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "io_loc_pairs.json"]
+write_blif -param [test_output_path "io_loc_pairs.eblif"]
diff --git a/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.v b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.v
new file mode 100644
index 000000000..bb08dee5f
--- /dev/null
+++ b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.v
@@ -0,0 +1,148 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n,
+    input rx_n,
+    input rx_p,
+    output tx_n,
+    output tx_p,
+    input ibufds_gte2_i,
+    input ibufds_gte2_ib
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+
+  GTPE2_CHANNEL GTPE2_CHANNEL (
+      .GTPRXP(rx_p),
+      .GTPRXN(rx_n),
+      .GTPTXP(tx_p),
+      .GTPTXN(tx_n)
+  );
+
+  (* keep *)
+  IBUFDS_GTE2 IBUFDS_GTE2 (
+      .I (ibufds_gte2_i),
+      .IB(ibufds_gte2_ib)
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
diff --git a/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.xdc b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.xdc
new file mode 100644
index 000000000..9263df9cf
--- /dev/null
+++ b/yosys-plugins/xdc/tests/io_loc_pairs/io_loc_pairs.xdc
@@ -0,0 +1,52 @@
+# OBUF_6
+set_property LOC D10 [get_ports {led[0]}]
+set_property DRIVE 12 [get_ports {led[0]}]
+
+# OBUF_7
+set_property LOC A9 [get_ports {led[1]}]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports led[1]]
+set_property SLEW FAST [get_ports led[1]]
+set_property IOSTANDARD SSTL135 [get_ports led[1]]
+
+# OBUF_OUT
+set_property LOC E3 [get_ports out_a]
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports out_a]
+set_property SLEW FAST [get_ports out_a]
+set_property IOSTANDARD LVCMOS33 [get_ports out_a]
+
+# bottom_inst.OBUF_10
+set_property LOC C2 [get_ports {out_b[0]}]
+set_property SLEW SLOW [get_ports {out_b[0]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {out_b[0]}]
+
+# bottom_inst.OBUF_11
+set_property LOC R2 [get_ports {out_b[1]}]
+set_property DRIVE 4 [get_ports {out_b[1]}]
+set_property SLEW FAST [get_ports {out_b[1]}]
+set_property IOSTANDARD LVCMOS25 [get_ports {out_b[1]}]
+
+# bottom_inst.OBUF_9
+set_property LOC M6 [get_ports {led[2]}]
+set_property SLEW FAST [get_ports {led[2]}]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {led[2]}]
+
+# bottom_intermediate_inst.OBUF_8
+set_property LOC N4 [get_ports {led[3]}]
+set_property DRIVE 16 [get_ports {led[3]}]
+set_property IOSTANDARD SSTL135 [get_ports {led[3]}]
+
+# OBUFTDS_2
+set_property LOC N2 [get_ports signal_p]
+set_property LOC N1 [get_ports signal_n]
+set_property SLEW FAST [get_ports signal_p]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports signal_p]
+
+# GTPE2_CHANNEL
+set_property LOC G1 [get_ports {rx_p}]
+set_property LOC G2 [get_ports {rx_n}]
+set_property LOC G3 [get_ports {tx_p}]
+set_property LOC G4 [get_ports {tx_n}]
+
+# IBUFDS_GTE2
+set_property LOC G5 [get_ports {ibufds_gte2_i}]
+set_property LOC G6 [get_ports {ibufds_gte2_ib}]
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/VexRiscv_Lite.v b/yosys-plugins/xdc/tests/minilitex_ddr_arty/VexRiscv_Lite.v
new file mode 120000
index 000000000..b77d3e3bf
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/VexRiscv_Lite.v
@@ -0,0 +1 @@
+../../../../third_party/VexRiscv_Lite/VexRiscv_Lite.v
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/mem.init b/yosys-plugins/xdc/tests/minilitex_ddr_arty/mem.init
new file mode 100644
index 000000000..c35c4f858
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/mem.init
@@ -0,0 +1,4795 @@
+b00006f
+13
+13
+13
+13
+13
+13
+13
+fe112e23
+fe512c23
+fe612a23
+fe712823
+fea12623
+feb12423
+fec12223
+fed12023
+fce12e23
+fcf12c23
+fd012a23
+fd112823
+fdc12623
+fdd12423
+fde12223
+fdf12023
+fc010113
+94000ef
+3c12083
+3812283
+3412303
+3012383
+2c12503
+2812583
+2412603
+2012683
+1c12703
+1812783
+1412803
+1012883
+c12e03
+812e83
+412f03
+12f83
+4010113
+30200073
+1001117
+f4c10113
+517
+f6850513
+30551073
+1000517
+f3c50513
+1000597
+6458593
+b50863
+52023
+450513
+ff5ff06f
+1537
+88050513
+30451073
+20c010ef
+6f
+fc002773
+bc0027f3
+e7f7b3
+17f793
+78463
+5b90206f
+8067
+82002737
+2872783
+2c72503
+879793
+a7e7b3
+3072503
+879793
+a7e7b3
+3472503
+879793
+a7e533
+8067
+13
+fff50513
+fe051ce3
+8067
+100713
+820037b7
+a71533
+80a7a623
+80e7a823
+8007a623
+8067
+100713
+820037b7
+a71533
+80a7a623
+80e7aa23
+8007a623
+8067
+793
+400693
+f58633
+64603
+279713
+a70733
+c72023
+178793
+fed794e3
+8067
+793
+400693
+279713
+a70733
+72703
+f58633
+178793
+e60023
+fed794e3
+8067
+f9010113
+6912223
+50493
+3537
+7c850513
+6812423
+5312e23
+5412c23
+5512a23
+5612823
+5712623
+6112623
+7212023
+5812423
+5912223
+5a12023
+3b12e23
+2010413
+3fd020ef
+196a37
+3c6ef9b7
+3010b13
+2a00513
+40a93
+60da0a13
+35f98993
+400b93
+913
+a0593
+52c030ef
+12407b3
+1350533
+a78023
+190913
+ff7914e3
+440413
+fd641ee3
+82004437
+42623
+42823
+900793
+42a23
+f42223
+100913
+1242423
+f00513
+eb1ff0ef
+a8593
+1840513
+eedff0ef
+2410593
+4c40513
+ee1ff0ef
+2810593
+8040513
+ed5ff0ef
+2c10593
+b440513
+ec9ff0ef
+a042423
+a042623
+a042823
+1700793
+af42023
+b242223
+6042a23
+6042c23
+6042e23
+48513
+e65ff0ef
+3010793
+100d13
+409d0b33
+3a37
+40978bb3
+913
+7a8a0a13
+1678c33
+3b8b93
+820047b7
+2500713
+6e7a623
+7a7a823
+f00513
+e19ff0ef
+16a89b3
+413
+100c93
+8a07b3
+7a503
+1c10593
+e6dff0ef
+9c703
+fecc4783
+f71863
+29c703
+fecbc783
+f70463
+c93
+440413
+1000793
+498993
+fcf414e3
+190413
+20c9063
+2000793
+f40a63
+48513
+de5ff0ef
+40913
+f85ff06f
+2000913
+48513
+dd1ff0ef
+3010793
+82004cb7
+40978bb3
+190413
+70c8d13
+100d93
+3b8b93
+2500793
+6fca623
+1bd2023
+f00513
+d75ff0ef
+993
+100793
+13a0733
+72503
+1c10593
+f12623
+dc9ff0ef
+13b0733
+ea8733
+74603
+fecc4703
+c12783
+1000693
+e61c63
+40998733
+ea8733
+374603
+fecbc703
+e60463
+793
+498993
+fad99ae3
+78e63
+140413
+1f00793
+87c863
+48513
+d31ff0ef
+f7dff06f
+8909b3
+2000793
+4019d993
+8f91263
+3537
+7d450513
+1c1020ef
+48513
+cedff0ef
+413
+9344663
+820047b7
+7a623
+7a823
+7aa23
+b00713
+e7a223
+100713
+e7a423
+f00513
+cadff0ef
+6c12083
+6812403
+6412483
+6012903
+5c12983
+5812a03
+5412a83
+5012b03
+4c12b83
+4812c03
+4412c83
+4012d03
+3c12d83
+7010113
+8067
+41240433
+1f45613
+860633
+3537
+40165613
+98593
+7d850513
+12d020ef
+f6dff06f
+48513
+c71ff0ef
+140413
+f69ff06f
+820047b7
+e00713
+3537
+e7a023
+7e450513
+1010206f
+820047b7
+100713
+4537
+e7a023
+80850513
+e90206f
+fd010113
+2112623
+54783
+4079263
+820047b7
+7a623
+7a823
+7aa23
+b00713
+e7a223
+100713
+f00513
+e7a423
+bd5ff0ef
+4537
+82c50513
+a5020ef
+2c12083
+3010113
+8067
+613
+1c10593
+655010ef
+1c12783
+7c783
+78863
+4537
+83850513
+fd1ff06f
+1051713
+1075713
+820047b7
+875713
+e7a623
+1051713
+a12623
+1075713
+e7a823
+7aa23
+900713
+e7a223
+100713
+e7a423
+f00513
+b59ff0ef
+c12583
+4537
+84850513
+25020ef
+f81ff06f
+fd010113
+2112623
+2812423
+2912223
+3212023
+1312e23
+1412c23
+1512a23
+1612823
+8054663
+100493
+40a484b3
+200993
+3437
+7a840413
+1040a13
+4ab7
+300b13
+42503
+c10593
+48913
+b5dff0ef
+c10793
+12787b3
+7c583
+85ca8513
+1390933
+7b0020ef
+ff2b54e3
+440413
+fc8a18e3
+4537
+e450513
+798020ef
+2c12083
+2812403
+2412483
+2012903
+1c12983
+1812a03
+1412a83
+1012b03
+3010113
+8067
+100993
+493
+f7dff06f
+fe010113
+112e23
+812c23
+912a23
+54783
+2079263
+4537
+86450513
+740020ef
+1c12083
+1812403
+1412483
+2010113
+8067
+58493
+613
+c10593
+4e5010ef
+c12783
+50413
+7c783
+78863
+4537
+87850513
+fc1ff06f
+4c783
+2078863
+48513
+613
+c10593
+4b1010ef
+c12783
+50493
+7c783
+78a63
+4537
+88c50513
+f8dff06f
+fff00493
+1041713
+1075713
+820047b7
+875713
+1041413
+6e7aa23
+1045413
+687ac23
+607ae23
+2500713
+6e7a623
+100713
+6e7a823
+f00513
+9b1ff0ef
+48513
+e69ff0ef
+f45ff06f
+f8010113
+6112e23
+6812c23
+6912a23
+7212823
+7312623
+7412423
+7512223
+7612023
+5712e23
+5812c23
+5912a23
+5a12823
+5b12623
+54783
+4079663
+4537
+89c50513
+634020ef
+7c12083
+7812403
+7412483
+7012903
+6c12983
+6812a03
+6412a83
+6012b03
+5c12b83
+5812c03
+5412c83
+5012d03
+4c12d83
+8010113
+8067
+613
+1810593
+3b5010ef
+1812783
+a12423
+7c783
+78863
+4537
+8b050513
+f9dff06f
+3010493
+4010a13
+48793
+78023
+780a3
+78123
+781a3
+478793
+ff4796e3
+82004437
+39b7
+913
+6c40a93
+2500c13
+2500c93
+100b13
+7a898993
+6042a23
+7242c23
+6042e23
+19aa023
+f00513
+7642823
+895ff0ef
+2010593
+2840513
+8f9ff0ef
+2410593
+5c40513
+8edff0ef
+2810593
+9040513
+8e1ff0ef
+2c10593
+c440513
+8d5ff0ef
+b93
+400d13
+1000d93
+812783
+8fbc863
+890913
+8000793
+f8f91ce3
+4937
+400993
+413
+8487b3
+7c583
+85c90513
+140413
+500020ef
+ff3416e3
+448493
+ff4490e3
+4437
+e440513
+4e8020ef
+400913
+44b7
+100593
+8c448513
+4d4020ef
+593
+8c448513
+4c8020ef
+100593
+8c448513
+4bc020ef
+593
+8c448513
+fff90913
+4ac020ef
+fc0916e3
+e440513
+e6dff06f
+18aa023
+7642823
+f00513
+fb4ff0ef
+793
+f98733
+72503
+1c10593
+f12623
+80dff0ef
+c12783
+2010713
+693
+9785b3
+f70633
+1c10713
+d70733
+74503
+64703
+5c883
+a60023
+e54733
+1176733
+e58023
+168693
+158593
+160613
+fda698e3
+478793
+fbb790e3
+1b8b93
+ef1ff06f
+fd010113
+2112623
+2812423
+2912223
+3212023
+1312e23
+54783
+2079663
+4537
+8c850513
+3f4020ef
+2c12083
+2812403
+2412483
+2012903
+1c12983
+3010113
+8067
+613
+810593
+195010ef
+812783
+50913
+7c783
+8079263
+34b7
+7b848493
+413
+4000993
+140793
+f106a3
+4a503
+240793
+810623
+f10723
+340793
+1040413
+c10593
+ff47413
+f107a3
+448493
+ee4ff0ef
+fd3416e3
+1091713
+1075713
+820047b7
+875713
+1091913
+ae7a423
+1095913
+b27a623
+a07a823
+1700713
+ae7a023
+100713
+ae7a223
+f4dff06f
+4537
+87850513
+f3dff06f
+fe010113
+400007b7
+aaaab737
+112e23
+812c23
+912a23
+1212823
+1312623
+1412423
+1512223
+aaa70713
+20078693
+e7a023
+478793
+fed79ce3
+348020ef
+370020ef
+400007b7
+aaaab737
+413
+aaa70713
+20078693
+7a603
+e60463
+140413
+478793
+fed798e3
+400007b7
+55555737
+55570713
+20078693
+e7a023
+478793
+fed79ce3
+2fc020ef
+324020ef
+400007b7
+55555737
+55570713
+20078693
+7a603
+e60463
+140413
+478793
+fed798e3
+40c63
+4537
+10000613
+40593
+8dc50513
+264020ef
+1969b7
+3c6ef937
+400004b7
+513
+60d98993
+35f90913
+40200a37
+98593
+39d020ef
+1250533
+a4a023
+448493
+ff4496e3
+284020ef
+196a37
+2a8020ef
+3c6ef9b7
+40000937
+493
+513
+60da0a13
+35f98993
+40200ab7
+a0593
+35d020ef
+92783
+1350533
+f50463
+148493
+490913
+ff5912e3
+48c63
+4537
+80637
+48593
+90050513
+1d0020ef
+400006b7
+793
+468693
+2637
+279713
+d70733
+f72023
+178793
+fec798e3
+200020ef
+228020ef
+40000737
+106b7
+593
+793
+470713
+fff68693
+2537
+279613
+e60633
+62603
+d67633
+f60463
+158593
+178793
+fea792e3
+4058063
+4537
+2637
+92450513
+154020ef
+593
+1c12083
+1812403
+1412483
+1012903
+c12983
+812a03
+412a83
+58513
+2010113
+8067
+940433
+fc041ae3
+4537
+94850513
+114020ef
+820027b7
+207a023
+7a823
+7aa23
+7ac23
+7ae23
+ff00713
+e7a023
+10737
+fff70713
+e7a223
+1000737
+fff70713
+e7a423
+fff00713
+e7a623
+100713
+2e7a023
+2e7a223
+bb8ff0ef
+50913
+400006b7
+80737
+241793
+d787b3
+87a023
+140413
+fee418e3
+82002437
+100493
+2942223
+b88ff0ef
+40a905b3
+3c000537
+91020ef
+50913
+d8020ef
+100020ef
+2942023
+2942223
+b64ff0ef
+50413
+400007b7
+40200737
+7a683
+478793
+fee79ce3
+820027b7
+100713
+2e7a223
+b3cff0ef
+40a405b3
+3c000537
+45020ef
+50613
+4537
+90593
+95450513
+28020ef
+100593
+ed5ff06f
+f8010113
+6112e23
+6812c23
+6912a23
+7312623
+7612023
+5912a23
+7212823
+7412423
+7512223
+5712e23
+5812c23
+5a12823
+5b12623
+ed0ff0ef
+82003437
+100493
+513
+b08ff0ef
+80942623
+80942c23
+80042623
+100513
+af4ff0ef
+200793
+80f42623
+80942c23
+4537
+80042623
+97c50513
+7a5010ef
+1967b7
+60d78793
+f12823
+37b7
+7a878793
+2c10993
+3110b13
+413
+f12a23
+4cb7
+3c6ef7b7
+100913
+35f78793
+891933
+a93
+c13
+493
+f12623
+2c0006f
+48a93
+a0c13
+700793
+1ef48463
+820037b7
+8127a623
+100713
+80e7ae23
+8007a623
+148493
+3010b93
+4010d93
+2a00513
+b8a13
+d13
+1012583
+71020ef
+c12783
+1ab8733
+1d0d13
+f50533
+a70023
+400793
+fefd10e3
+4b8b93
+fd7d9ae3
+82004bb7
+ba623
+ba823
+900793
+baa23
+fba223
+100d13
+1aba423
+f00513
+9ecff0ef
+a0593
+18b8513
+a28ff0ef
+4cb8513
+3410593
+a1cff0ef
+80b8513
+3810593
+a10ff0ef
+b4b8513
+3c10593
+a04ff0ef
+a0ba423
+a0ba623
+a0ba823
+1700793
+afba023
+baba223
+60baa23
+60bac23
+47b7
+60bae23
+48613
+40593
+98c78513
+661010ef
+40513
+98cff0ef
+2000b93
+a13
+82004d37
+2500793
+6fd2623
+100713
+820047b7
+6e7a823
+f00513
+954ff0ef
+b0693
+713
+100d93
+1412783
+2c10593
+d12e23
+e78633
+62503
+e12c23
+99cff0ef
+1c12683
+19c603
+1812703
+6c583
+c59863
+26c583
+39c603
+c58463
+d93
+470713
+1000793
+468693
+faf71ae3
+47b7
+d8593
+99878513
+5c5010ef
+40513
+fffb8b93
+1ba0a33
+904ff0ef
+f60b94e3
+4537
+99c50513
+5a5010ef
+820047b7
+7a623
+7a823
+7aa23
+b00713
+e7a223
+100713
+e7a423
+f00513
+8a0ff0ef
+40513
+930ff0ef
+e4c8513
+56d010ef
+e14c4ae3
+e19ff06f
+4537
+a8613
+40593
+9a050513
+551010ef
+820037b7
+8127a623
+100713
+80e7ac23
+8007a623
+82003737
+793
+100693
+3579463
+40513
+8e0ff0ef
+e4c8513
+51d010ef
+fff98993
+fffb0b13
+2041063
+100413
+d91ff06f
+81272623
+80d72e23
+80072623
+178793
+fc9ff06f
+7c12083
+7812403
+7412483
+7012903
+6c12983
+6812a03
+6412a83
+6012b03
+5c12b83
+5812c03
+5412c83
+5012d03
+4c12d83
+100513
+8010113
+8067
+ff010113
+4537
+812423
+9b050513
+82004437
+112623
+912223
+1212023
+491010ef
+42623
+42823
+42a23
+c00793
+c537
+f42023
+35050513
+f95fe0ef
+42623
+42823
+42a23
+e00793
+2537
+f42023
+71050513
+f75fe0ef
+200793
+f42623
+20000713
+e42823
+f42a23
+f00793
+f42223
+100493
+942423
+42623
+42823
+300913
+1242a23
+f42223
+942423
+42623
+600713
+e42823
+942a23
+f42223
+942423
+900713
+e42623
+1737
+92070713
+e42823
+42a23
+f42223
+942423
+c800513
+ef9fe0ef
+400793
+f42623
+40000793
+f42823
+42a23
+1242223
+942423
+c800513
+ed5fe0ef
+b91ff0ef
+aacff0ef
+879ff0ef
+c12083
+812403
+412483
+12903
+a03533
+1010113
+8067
+ff010113
+812423
+50413
+52503
+2000593
+112623
+912223
+555000ef
+2051863
+42483
+48513
+6e1000ef
+a48533
+a42023
+c12083
+812403
+48513
+412483
+1010113
+8067
+50023
+42483
+150513
+fd9ff06f
+e7010113
+18112623
+18812423
+18912223
+19212023
+17312e23
+17412c23
+17512a23
+17612823
+17712623
+17812423
+17912223
+17a12023
+15b12e23
+793
+bc079073
+30046073
+44b7
+53d010ef
+e448513
+2d5010ef
+4537
+9c850513
+2c9010ef
+4537
+9f050513
+2bd010ef
+4537
+a1850513
+2b1010ef
+4537
+a3c50513
+2a5010ef
+4537
+a6050513
+299010ef
+e448513
+291010ef
+4537
+a8c50513
+285010ef
+4537
+ab450513
+279010ef
+e448513
+271010ef
+4537
+ad850513
+265010ef
+55b7
+537
+ae85a403
+50793
+ae858593
+40f585b3
+50513
+708010ef
+18a41e63
+4537
+40593
+b0050513
+231010ef
+e448513
+229010ef
+4537
+b7c50513
+21d010ef
+4537
+b9850513
+211010ef
+e448513
+209010ef
+4537
+bb450513
+1fd010ef
+4537
+be850513
+1f1010ef
+4537
+bfc50513
+1e5010ef
+4537
+3c00593
+c0850513
+1d5010ef
+4537
+2000593
+c1450513
+1c5010ef
+4537
+400593
+c3050513
+1b5010ef
+4537
+800593
+c4c50513
+1a5010ef
+4537
+405b7
+c6850513
+195010ef
+e448513
+18d010ef
+4537
+c8450513
+181010ef
+ccdff0ef
+100793
+50413
+f50863
+4537
+cb850513
+165010ef
+e448513
+15d010ef
+2040663
+4537
+cd850513
+14d010ef
+7d4000ef
+50863
+4537
+d0c50513
+139010ef
+e448513
+131010ef
+4537
+d2450513
+125010ef
+4a37
+49b7
+4ab7
+4537
+d5850513
+8d010ef
+413
+40108a3
+1000937
+a00b13
+d00b93
+7f00c13
+700c93
+800d13
+7a0010ef
+94783
+4a10823
+fea78ae3
+90023
+d650e63
+4ab6863
+ff9502e3
+5a50863
+5010513
+41010ef
+5014703
+15010793
+8787b3
+ece78023
+140413
+fc1ff06f
+50613
+4537
+40593
+b1c50513
+95010ef
+4537
+b4850513
+89010ef
+e59ff06f
+1750e63
+fb851ce3
+f80408e3
+d6ca0513
+fff40413
+7ec010ef
+f81ff06f
+1690023
+15010793
+878433
+ec040023
+e448513
+7d0010ef
+1010793
+c10513
+f12623
+cbdff0ef
+45b7
+d7058593
+50413
+2dd000ef
+18051863
+c10513
+ca1ff0ef
+50913
+c10513
+c95ff0ef
+94783
+50413
+2079063
+4537
+d7450513
+1010ef
+ee9ff06f
+d00793
+f90023
+f91ff06f
+613
+5010593
+90513
+5a9000ef
+5012783
+50b13
+7c783
+78863
+4537
+87850513
+fc5ff06f
+44783
+2078663
+613
+5010593
+40513
+575000ef
+5012783
+7c783
+78a63
+4537
+d8c50513
+f95ff06f
+400513
+50413
+4537
+da050513
+b0b93
+6fc010ef
+4cb7
+4d37
+804663
+e448513
+f69ff06f
+1000793
+40913
+87d463
+1000913
+4537
+b0593
+db050513
+748010ef
+c13
+4db7
+18b87b3
+7c583
+dbcd8513
+1c0c13
+72c010ef
+ff8916e3
+90c13
+1000d93
+5bc1a63
+db898513
+714010ef
+c13
+5e00d93
+18b87b3
+7c583
+fe058793
+ff7f793
+4fdf063
+dc4d0513
+6f0010ef
+1c0c13
+ff8910e3
+90c13
+1000d93
+3bc1863
+12b8bb3
+41240433
+12b0b33
+f5dff06f
+bf8c8513
+6c4010ef
+1c0c13
+fa1ff06f
+dc8a8513
+6b4010ef
+fc5ff06f
+db898513
+6a8010ef
+1c0c13
+fc5ff06f
+45b7
+dcc58593
+40513
+13d000ef
+e051063
+c10513
+b01ff0ef
+50b13
+c10513
+af5ff0ef
+50913
+c10513
+ae9ff0ef
+b4783
+50413
+78663
+94783
+79863
+4537
+dd050513
+e4dff06f
+b0513
+613
+5010593
+405000ef
+5012783
+50b13
+7c783
+e60790e3
+90513
+613
+5010593
+3e5000ef
+5012783
+50913
+7c783
+78863
+4537
+df050513
+e01ff06f
+44783
+100513
+2078663
+613
+5010593
+40513
+3ad000ef
+5012783
+7c783
+78863
+4537
+8b050513
+dcdff06f
+793
+279713
+1670733
+caa784e3
+1272023
+178793
+fedff06f
+45b7
+e0458593
+40513
+4d000ef
+e051463
+c10513
+a11ff0ef
+50b13
+c10513
+a05ff0ef
+50913
+c10513
+9f9ff0ef
+b4783
+50413
+78663
+94783
+79863
+4537
+e0850513
+d5dff06f
+b0513
+613
+5010593
+315000ef
+5012783
+50b13
+7c783
+78863
+4537
+e2050513
+d31ff06f
+90513
+613
+5010593
+2e9000ef
+5012783
+50913
+7c783
+78863
+4537
+e4050513
+d05ff06f
+44783
+100513
+2078063
+613
+5010593
+40513
+2b1000ef
+5012783
+7c783
+f00794e3
+793
+279713
+eb06b3
+e90733
+baa78ae3
+72703
+178793
+e6a023
+fe5ff06f
+45b7
+e5c58593
+40513
+754000ef
+8051a63
+c10513
+919ff0ef
+50913
+c10513
+90dff0ef
+94783
+50413
+78663
+54783
+79863
+4537
+e6050513
+c71ff06f
+90513
+613
+5010593
+229000ef
+5012783
+50913
+7c783
+c80792e3
+5010593
+613
+40513
+209000ef
+5012783
+50593
+7c783
+c8079ae3
+90513
+ec010ef
+50593
+4537
+e7850513
+418010ef
+b01ff06f
+45b7
+e8858593
+40513
+6b0000ef
+51e63
+5010513
+494010ef
+4537
+5010593
+e9050513
+fd1ff06f
+45b7
+e9c58593
+40513
+684000ef
+51663
+454010ef
+ab9ff06f
+45b7
+ea458593
+40513
+668000ef
+51a63
+820007b7
+100713
+e7a023
+a95ff06f
+45b7
+eac58593
+40513
+644000ef
+51663
+21c000ef
+a79ff06f
+45b7
+eb858593
+40513
+628000ef
+8051863
+4537
+ec050513
+2ac010ef
+4537
+ee050513
+2a0010ef
+4537
+f0050513
+294010ef
+4537
+f2450513
+4437
+284010ef
+13440513
+27c010ef
+4537
+f4450513
+270010ef
+4537
+f8050513
+264010ef
+13440513
+25c010ef
+4537
+fa050513
+250010ef
+4537
+fc050513
+244010ef
+13440513
+23c010ef
+4537
+fdc50513
+230010ef
+9d9ff06f
+45b7
+ffc58593
+40513
+588000ef
+51a63
+c10513
+f4cff0ef
+9e9fe0ef
+9b5ff06f
+45b7
+458593
+40513
+564000ef
+51663
+99dfe0ef
+999ff06f
+45b7
+c58593
+40513
+548000ef
+51663
+999fe0ef
+97dff06f
+45b7
+1458593
+40513
+52c000ef
+51863
+fff00513
+a59fe0ef
+95dff06f
+45b7
+2058593
+40513
+50c000ef
+2051463
+c10513
+ed0ff0ef
+50413
+c10513
+ec4ff0ef
+50593
+40513
+addfe0ef
+925ff06f
+45b7
+2858593
+40513
+4d4000ef
+51a63
+c10513
+e98ff0ef
+b9dfe0ef
+901ff06f
+45b7
+3458593
+40513
+4b0000ef
+51a63
+c10513
+e74ff0ef
+dd9fe0ef
+8ddff06f
+45b7
+3c58593
+40513
+48c000ef
+51663
+d28ff0ef
+8c1ff06f
+45b7
+4458593
+40513
+470000ef
+51663
+9a0ff0ef
+8a5ff06f
+45b7
+5058593
+40513
+454000ef
+51663
+e75fe0ef
+889ff06f
+45b7
+13458593
+40513
+438000ef
+86050ae3
+4537
+5850513
+97dff06f
+68067
+4537
+ec010113
+a450513
+12112e23
+12812c23
+12912a23
+13212823
+13312623
+13412423
+13512223
+13612023
+11712e23
+11812c23
+140010ef
+4537
+4437
+bc50513
+8440493
+12c010ef
+8440413
+4c503
+8051e63
+820027b7
+207a023
+7a823
+7aa23
+7ac23
+7ae23
+7a023
+e400713
+e7a223
+e737
+4e170713
+e7a423
+e4e737
+1c070713
+e7a623
+100713
+2e7a023
+2e7a223
+b13
+82002ab7
+5100493
+1b00913
+e00993
+100a13
+28aa783
+2caa703
+879793
+e7e7b3
+30aa703
+879793
+e7e7b3
+34aa703
+879793
+e7e7b3
+79e63
+4537
+16c50513
+d80006f
+268010ef
+148493
+f59ff06f
+240010ef
+c050a63
+1e4010ef
+24950263
+25250063
+16407b3
+107c783
+aa79a63
+1b0b13
+b3b1a63
+44b7
+a93
+300993
+100913
+500413
+6c48493
+82000a37
+1a8010ef
+a10623
+1a0010ef
+a106a3
+198010ef
+a10723
+c10b93
+18c010ef
+a107a3
+b8c13
+b13
+c14583
+1c0c13
+6bb4463
+f14783
+d378863
+e14783
+d14703
+158593
+879793
+e7e7b3
+879b13
+87d793
+fb67b3
+1079b13
+f10513
+10b5b13
+43d000ef
+5650463
+1a8a93
+28a9a63
+4537
+e850513
+7b1000ef
+500006f
+f8650513
+153b13
+34aa223
+ee1ff06f
+10c010ef
+ac01a3
+1b0b13
+f85ff06f
+4300513
+168010ef
+f4dff06f
+f14783
+14f46063
+279793
+9787b3
+7a783
+78067
+4b00513
+144010ef
+100513
+13c12083
+13812403
+13412483
+13012903
+12c12983
+12812a03
+12412a83
+12012b03
+11c12b83
+11812c03
+14010113
+8067
+1014783
+1114703
+1879793
+1071713
+e7e7b3
+1314703
+e7e7b3
+1214703
+871713
+e7e7b3
+ffc78793
+400713
+c14683
+e78633
+1b8b93
+d74c63
+f14783
+a93
+4b00513
+eb2794e3
+f55ff06f
+7bc683
+170713
+d60023
+fd1ff06f
+1014403
+1114683
+4b00513
+1841413
+1069693
+d46433
+1314683
+d46433
+1214683
+869693
+d46433
+7c010ef
+4537
+40593
+11050513
+689000ef
+4537
+13850513
+67d000ef
+120010ef
+793
+bc079073
+30047073
+6c1000ef
+6e9000ef
+40693
+613
+593
+513
+cd9ff0ef
+6f
+4b00513
+28010ef
+12a2023
+e09ff06f
+1a8a93
+e68a8ee3
+5500513
+ea9ff06f
+4537
+17850513
+621000ef
+513
+ec1ff06f
+ff5f593
+54783
+b79463
+8067
+78663
+150513
+fedff06f
+513
+8067
+54703
+2071263
+513
+8067
+fee68ee3
+178793
+7c683
+fe069ae3
+150513
+fddff06f
+58793
+fedff06f
+b505b3
+ff67613
+b50663
+54783
+79663
+513
+8067
+fef60ee3
+150513
+fe5ff06f
+50793
+158593
+fff5c703
+178793
+fee78fa3
+fe0718e3
+8067
+c50633
+50793
+c79463
+8067
+5c703
+e78023
+70463
+158593
+178793
+fe5ff06f
+158593
+54703
+fff5c783
+40f707b3
+1879793
+4187d793
+79663
+150513
+fe0710e3
+78513
+8067
+713
+c71863
+793
+78513
+8067
+e507b3
+7c683
+e587b3
+7c783
+40f687b3
+1879793
+4187d793
+fc079ee3
+fc068ce3
+170713
+fc9ff06f
+50793
+7c703
+178693
+71e63
+158593
+fff5c703
+178793
+fee78fa3
+fe0718e3
+8067
+68793
+fd9ff06f
+50793
+61663
+8067
+68793
+7c703
+178693
+fe071ae3
+c78633
+158593
+fff5c703
+178793
+fee78fa3
+fc070ce3
+fec796e3
+78023
+8067
+50793
+7c703
+71663
+40a78533
+8067
+178793
+fedff06f
+fe010113
+812c23
+b12623
+50413
+112e23
+fd1ff0ef
+c12583
+a40533
+ff5f593
+54783
+b78863
+fff50513
+fe857ae3
+513
+1c12083
+1812403
+2010113
+8067
+b505b3
+50793
+b78663
+7c703
+71663
+40a78533
+8067
+178793
+fe9ff06f
+793
+f50733
+74683
+68e63
+58713
+c0006f
+d60c63
+170713
+74603
+fe061ae3
+78513
+8067
+178793
+fd1ff06f
+713
+e61663
+793
+200006f
+e507b3
+e586b3
+7c783
+6c683
+170713
+40d787b3
+fc078ee3
+78513
+8067
+c50633
+50793
+c79463
+8067
+178793
+feb78fa3
+ff1ff06f
+793
+f61463
+8067
+f58733
+74683
+f50733
+178793
+d70023
+fe5ff06f
+2a5fa63
+fff64693
+793
+fff78793
+2f69663
+8067
+f58733
+74683
+f50733
+178793
+d70023
+fef616e3
+8067
+793
+ff5ff06f
+f60733
+e58833
+84803
+e50733
+1070023
+fbdff06f
+fe010113
+812c23
+50413
+58513
+1312623
+112e23
+912a23
+1212823
+1412423
+58993
+e51ff0ef
+4050063
+50913
+40513
+e41ff0ef
+50493
+a40a33
+409a0433
+124f663
+413
+1c0006f
+90613
+98593
+40513
+fff48493
+ed5ff0ef
+fc051ee3
+40513
+1c12083
+1812403
+1412483
+1012903
+c12983
+812a03
+2010113
+8067
+c50633
+ff5f593
+c51663
+513
+8067
+54703
+150793
+feb70ae3
+78513
+fe5ff06f
+fd010113
+2812423
+3212023
+1312e23
+2112623
+2912223
+4937
+50413
+58993
+54783
+18490913
+4061e63
+3000713
+a00613
+4e79463
+154783
+150693
+f90733
+74703
+277713
+70663
+fe078793
+ff7f793
+5800713
+ce79e63
+244783
+f907b3
+7c783
+447f793
+c078463
+240413
+1000613
+513
+5c0006f
+1000713
+fee61ae3
+3000713
+fee796e3
+154783
+f90733
+74703
+277713
+70663
+fe078793
+ff7f793
+5800713
+fce794e3
+240413
+fc1ff06f
+50593
+60513
+c12623
+2c4010ef
+c12603
+950533
+140413
+44783
+f90733
+74703
+4477693
+2068463
+477693
+fd078493
+69c63
+277713
+70663
+fe078793
+ff7f793
+fc978493
+fac4e8e3
+98463
+89a023
+2c12083
+2812403
+2412483
+2012903
+1c12983
+3010113
+8067
+68413
+800613
+f3dff06f
+54683
+2d00713
+e68463
+eadff06f
+ff010113
+150513
+112623
+e9dff0ef
+c12083
+40a00533
+1010113
+8067
+4737
+50613
+18470713
+513
+62683
+6c783
+f707b3
+7c783
+47f793
+79463
+8067
+168793
+f62023
+251793
+a787b3
+6c503
+179793
+a787b3
+fd078513
+fc5ff06f
+f7010113
+7312e23
+68993
+46b7
+8812423
+9212023
+7412c23
+7612823
+60a13
+18468693
+8112623
+8912223
+7512a23
+7712623
+7812423
+7912223
+4087613
+50413
+58913
+12868b13
+60463
+10068b13
+1087693
+68463
+ffe87813
+ffe98693
+2200613
+513
+22d66a63
+187693
+3000c13
+69463
+2000c13
+287693
+a93
+68a63
+80a5863
+41400a33
+fff70713
+2d00a93
+2087c93
+c8863
+1000693
+8d99e63
+ffe70713
+a0a1263
+3000693
+d10e23
+100493
+48693
+f4d463
+78693
+1187793
+40d70733
+10078463
+a8863
+1247463
+1540023
+140413
+c8e63
+800793
+ef99e63
+1247663
+3000793
+f40023
+140413
+1087813
+14080063
+40513
+d406b3
+3000613
+1480006f
+487693
+68863
+fff70713
+2b00a93
+f71ff06f
+887693
+f60684e3
+fff70713
+2000a93
+f5dff06f
+800693
+f6d994e3
+fff70713
+f61ff06f
+1c10b93
+493
+98593
+a0513
+1012623
+f12423
+e12223
+6c5000ef
+ab0533
+54683
+98593
+a0513
+db8023
+6ed000ef
+148493
+1b8b93
+412703
+812783
+c12803
+f33a60e3
+50a13
+fb5ff06f
+127f463
+a78023
+178793
+40f58633
+fec048e3
+70793
+75463
+793
+fff70713
+f40433
+40f70733
+f01ff06f
+40793
+e405b3
+2000513
+fd1ff06f
+1000793
+f0f99ae3
+1247663
+3000793
+f40023
+140793
+127f663
+21b4783
+f400a3
+240413
+ef1ff06f
+127f463
+1878023
+178793
+40f58633
+fec048e3
+70793
+75463
+793
+fff70713
+f40433
+40f70733
+ec9ff06f
+40793
+e405b3
+fd5ff06f
+1257463
+c50023
+150513
+40a687b3
+fef4c8e3
+48793
+50693
+fff00613
+fff78793
+4c79e63
+950533
+50793
+e50633
+2000593
+40f606b3
+6d04063
+75463
+713
+e50533
+8c12083
+8812403
+8412483
+8012903
+7c12983
+7812a03
+7412a83
+7012b03
+6c12b83
+6812c03
+6412c83
+9010113
+8067
+126fa63
+1c10593
+f585b3
+5c583
+b68023
+168693
+f89ff06f
+127f463
+b78023
+178793
+f91ff06f
+ff010113
+812423
+112623
+58413
+1d000ef
+856463
+fff40513
+c12083
+812403
+1010113
+8067
+fc010113
+2d12623
+2c10693
+112e23
+2e12823
+2f12a23
+3012c23
+3112e23
+d12623
+7dc000ef
+1c12083
+4010113
+8067
+fc010113
+2d12623
+2c10693
+812c23
+112e23
+58413
+2e12823
+2f12a23
+3012c23
+3112e23
+d12623
+7a0000ef
+856463
+fff40513
+1c12083
+1812403
+4010113
+8067
+60693
+58613
+800005b7
+fff5c593
+7740006f
+fc010113
+2c12423
+58613
+800005b7
+2d12623
+fff5c593
+2810693
+112e23
+2e12823
+2f12a23
+3012c23
+3112e23
+d12623
+73c000ef
+1c12083
+4010113
+8067
+1000737
+472783
+779513
+f50533
+361967b7
+2e978793
+f50533
+a72223
+8067
+10007b7
+a7a223
+8067
+4537
+ff010113
+2d450513
+112623
+42c000ef
+6f
+1851713
+1855793
+106b7
+e7e7b3
+f0068693
+855713
+d77733
+e7e7b3
+851513
+ff0737
+e57533
+a7e533
+8067
+851793
+855513
+a7e533
+1051513
+1055513
+8067
+1851713
+1855793
+106b7
+e7e7b3
+f0068693
+855713
+d77733
+e7e7b3
+851513
+ff0737
+e57533
+a7e533
+8067
+851793
+855513
+a7e533
+1051513
+1055513
+8067
+46b7
+793
+b505b3
+2e068693
+40a58733
+e04663
+78513
+8067
+150513
+fff54603
+87d713
+879793
+c74733
+271713
+e68733
+75703
+1079793
+107d793
+f747b3
+fc5ff06f
+46b7
+50713
+fff00793
+b508b3
+700813
+6e068693
+40e88633
+4c86a63
+35d713
+371693
+40d585b3
+d50533
+2058c63
+46b7
+b505b3
+6e068693
+150513
+fff54703
+f74733
+ff77713
+271713
+e68733
+72703
+87d793
+f747b3
+fcb51ee3
+fff7c513
+8067
+74603
+870713
+f64633
+ff67613
+261613
+c68633
+62603
+87d793
+f647b3
+ff974603
+f64633
+ff67613
+261613
+c68633
+62603
+87d793
+f64633
+ffa74783
+c7c7b3
+ff7f793
+279793
+f687b3
+7a303
+ffb74783
+865613
+c34333
+67c7b3
+ff7f793
+279793
+f687b3
+7a603
+ffc74783
+835313
+664633
+c7c7b3
+ff7f793
+279793
+f687b3
+7a303
+ffd74783
+865613
+c34333
+67c7b3
+ff7f793
+279793
+f687b3
+7a783
+ffe74603
+835313
+67c7b3
+f64633
+ff67613
+261613
+c68633
+62303
+fff74603
+87d793
+f34333
+664633
+ff67613
+261613
+c68633
+62783
+835313
+67c7b3
+ea5ff06f
+10007b7
+a7a823
+8067
+10007b7
+a7a623
+10007b7
+b7a423
+8067
+ff010113
+912223
+ff57493
+812423
+50413
+48513
+112623
+36c000ef
+10007b7
+107a783
+78663
+48513
+780e7
+a00793
+f41663
+d00513
+fc1ff0ef
+40513
+c12083
+812403
+412483
+1010113
+8067
+ff010113
+812423
+112623
+1000437
+300000ef
+50a63
+812403
+c12083
+1010113
+2980006f
+842783
+fe0782e3
+780e7
+fc050ee3
+812403
+10007b7
+c12083
+c7a303
+1010113
+30067
+ff010113
+112623
+2b8000ef
+2051263
+10007b7
+87a783
+78663
+780e7
+a03533
+c12083
+1010113
+8067
+100513
+ff1ff06f
+ff010113
+812423
+112623
+50413
+44503
+2051063
+a00513
+f01ff0ef
+c12083
+812403
+100513
+1010113
+8067
+ee9ff0ef
+140413
+fd5ff06f
+ff010113
+812423
+112623
+50413
+44503
+51a63
+c12083
+812403
+1010113
+8067
+eb5ff0ef
+140413
+fe1ff06f
+ef010113
+58693
+50613
+10000593
+10513
+10112623
+10812423
+ac5ff0ef
+10010793
+50413
+a787b3
+10513
+f0078023
+f99ff0ef
+40513
+10c12083
+10812403
+11010113
+8067
+fc010113
+2b12223
+2410593
+112e23
+2c12423
+2d12623
+2e12823
+2f12a23
+3012c23
+3112e23
+b12623
+f89ff0ef
+1c12083
+4010113
+8067
+400f
+13
+13
+13
+13
+13
+8067
+cc0027f3
+c79693
+147d713
+c6d693
+793
+d7e463
+8067
+78513
+7005500f
+e787b3
+fedff06f
+400007b7
+40004737
+7a683
+478793
+fee79ce3
+8067
+50023
+8067
+820027b7
+8107a703
+277793
+79863
+177713
+4071e63
+8067
+10007b7
+1c7a803
+10005b7
+820026b7
+1000637
+2458593
+200893
+8086a783
+ff7f793
+fc0798e3
+2062783
+178793
+7f7f793
+f80c63
+2062503
+8006a303
+2f62023
+a58533
+650023
+8116a823
+fcdff06f
+820027b7
+100713
+80e7a823
+10007b7
+187a583
+10006b7
+1000737
+82002637
+2468693
+1472783
+b78863
+80462783
+ff7f793
+78463
+8067
+1472783
+f687b3
+807c783
+80f62023
+1472783
+178793
+7f7f793
+f72a23
+fc9ff06f
+30002673
+1000737
+867613
+1c72783
+70693
+1000737
+2060663
+2072603
+fef60ee3
+1000737
+2470713
+f70733
+178793
+7f7f793
+74503
+f6ae23
+100006f
+2072703
+513
+fcf71ce3
+8067
+1000737
+10007b7
+207a783
+1c72503
+40f50533
+a03533
+8067
+10006b7
+186a603
+160793
+7f7f793
+300025f3
+85f593
+1000737
+4058663
+1472583
+fef58ee3
+bc0025f3
+ffe5f813
+bc081073
+1472703
+e61a63
+82002837
+80482703
+ff77713
+2070663
+1000737
+2470713
+c70733
+8a70023
+f6ac23
+bc059073
+c0006f
+1472583
+faf59ee3
+8067
+80a82023
+fe9ff06f
+10007b7
+207a023
+10007b7
+7ae23
+10007b7
+7ac23
+10007b7
+7aa23
+820027b7
+8107a703
+ff77713
+80e7a823
+300713
+80e7aa23
+bc0027f3
+17e793
+bc079073
+8067
+10007b7
+187a783
+10006b7
+146a703
+fef71ee3
+8067
+fc010113
+2112e23
+2812c23
+2912a23
+3212823
+3312623
+3412423
+3512223
+3612023
+1712e23
+1812c23
+1912a23
+1a12823
+c12623
+4c05c463
+b509b3
+50a13
+58a93
+68493
+a9f663
+fff54a93
+fff00993
+4b37
+5cb7
+a0413
+2500c13
+184b0b13
+2000b93
+ae0c8c93
+2bc0006f
+1878a63
+1347463
+f40023
+140413
+29c0006f
+913
+2b00713
+2d00613
+3000593
+2000513
+2300813
+c12683
+168793
+f12623
+16c783
+14e78063
+12f76263
+14a78063
+15078263
+1678733
+74703
+477713
+12070e63
+c10513
+ba8ff0ef
+50713
+c12683
+2e00613
+fff00793
+6c583
+2c59e63
+168793
+f12623
+16c603
+cb07b3
+7c783
+47f793
+12078663
+c10513
+e12423
+b68ff0ef
+812703
+50793
+55463
+793
+c12683
+6800593
+6c603
+2b60263
+df67593
+4c00513
+a58c63
+5a00513
+a58863
+7400593
+fff00813
+2b61663
+60813
+168613
+c12623
+6c00613
+c81c63
+16c603
+1061863
+268693
+d12623
+4c00813
+c12683
+6c603
+6e00693
+2cd60c63
+ec6e063
+6300693
+14d60c63
+ac6ec63
+2d860c63
+5800693
+2cd60e63
+1347663
+2500793
+f40023
+c12783
+140713
+7c683
+2c068663
+1377463
+d400a3
+240413
+14c0006f
+c78863
+eeb792e3
+196913
+ebdff06f
+1096913
+eb5ff06f
+496913
+eadff06f
+896913
+ea5ff06f
+2096913
+e9dff06f
+2a00613
+fff00713
+ecc796e3
+4a703
+268693
+d12623
+448493
+ea075ce3
+40e00733
+1096913
+eadff06f
+2a00593
+793
+eeb616e3
+268693
+4a503
+d12623
+448493
+ecdff06f
+6400693
+d60663
+6900693
+f4d616e3
+296913
+a00693
+680006f
+7300693
+14d60863
+4c6e463
+6f00693
+22d60063
+7000693
+f2d612e3
+fff00693
+d71663
+196913
+800713
+4a603
+448d13
+90813
+1000693
+40513
+98593
+a18ff0ef
+50413
+1640006f
+7500693
+fad602e3
+7800593
+1000693
+ecb61ee3
+4c00613
+1cc81863
+748493
+ff84f493
+848d13
+4a603
+1f80006f
+1097913
+a090c63
+40793
+448693
+1347663
+4a603
+c40023
+140413
+e78733
+408707b3
+8f04e63
+68493
+c12783
+178793
+f12623
+c12783
+7c783
+d40790e3
+a8663
+1b347c63
+40023
+41440533
+3c12083
+3812403
+3412483
+3012903
+2c12983
+2812a03
+2412a83
+2012b03
+1c12b83
+1812c03
+1412c83
+1012d03
+4010113
+8067
+1347463
+1740023
+140413
+fff78793
+fef048e3
+fff70793
+e04463
+100713
+40e78733
+170713
+f51ff06f
+70793
+fddff06f
+1347463
+1740023
+140413
+f55ff06f
+448d13
+4a483
+49463
+c8493
+78593
+48513
+e12423
+1097913
+d45fe0ef
+812703
+91863
+70793
+fff70713
+2f54863
+793
+2a7cc63
+50793
+55463
+793
+f40433
+e40733
+408707b3
+2f54c63
+d0493
+efdff06f
+1347463
+1740023
+140413
+fbdff06f
+f406b3
+136f863
+f48633
+64603
+c68023
+178793
+fb1ff06f
+1347463
+1740023
+140413
+fb9ff06f
+4a783
+41440733
+448493
+e7a023
+eadff06f
+c13474e3
+1840023
+c01ff06f
+4096913
+1000693
+e49ff06f
+fff78793
+f12623
+70413
+e85ff06f
+800693
+e31ff06f
+6c00613
+448d13
+e2c80ce3
+fdf87613
+5a00593
+e2b606e3
+7400613
+e2c802e3
+6800613
+297593
+e0c81ce3
+4a603
+1061613
+59863
+1065613
+90813
+dc5ff06f
+41065613
+ff5ff06f
+fe098fa3
+e4dff06f
+513
+e49ff06f
+ff010113
+112623
+812423
+912223
+50413
+58493
+28000ef
+50593
+48513
+170000ef
+40a40533
+c12083
+812403
+412483
+1010113
+8067
+fe010113
+112e23
+812c23
+912a23
+a058263
+50413
+8050263
+58513
+b12623
+98000ef
+50493
+40513
+8c000ef
+40a48533
+1f00793
+6a7ec63
+4f50e63
+c12583
+150513
+2000713
+40a70733
+e41733
+793
+a45433
+fff58813
+141413
+1f75613
+866633
+40c806b3
+41f6d693
+171713
+b6f433
+fff50513
+f76733
+40860433
+16f793
+fc051ae3
+171413
+f46433
+40513
+1c12083
+1812403
+1412483
+2010113
+8067
+413
+fe5ff06f
+ffff0737
+e57733
+173693
+469693
+1000793
+40d787b3
+10737
+f557b3
+f0070713
+e7f733
+173713
+371713
+800513
+40e50533
+a7d7b3
+f07f513
+153513
+251513
+d70733
+400693
+40a686b3
+d7d7b3
+e50733
+c7f513
+153513
+200613
+151513
+40a606b3
+d7d7b3
+17d693
+16c693
+16f693
+40d006b3
+40f607b3
+f6f7b3
+e50533
+a78533
+8067
+50793
+513
+79463
+8067
+17f713
+70463
+b50533
+159593
+17d793
+fe5ff06f
+0
+82004028
+8200405c
+82004090
+820040c4
+82004018
+8200404c
+82004080
+820040b4
+616c6564
+203a7379
+0
+2d
+64323025
+30252d2b
+6432
+41524453
+6f6e204d
+6e752077
+20726564
+74666f73
+65726177
+6e6f6320
+6c6f7274
+a
+41524453
+6f6e204d
+6e752077
+20726564
+64726168
+65726177
+6e6f6320
+6c6f7274
+a
+63657250
+67726168
+a6465
+6f636e69
+63657272
+6f722074
+a77
+69746341
+65746176
+6f722064
+64252077
+a
+78323025
+0
+72726473
+613c2064
+65726464
+a3e7373
+0
+6f636e69
+63657272
+64612074
+73657264
+a73
+6f636e69
+63657272
+51442074
+a
+72726473
+72726564
+6f633c20
+3e746e75
+a
+6f636e69
+63657272
+6f632074
+a746e75
+0
+783225
+77726473
+613c2072
+65726464
+a3e7373
+0
+746d654d
+20747365
+20737562
+6c696166
+203a6465
+252f6425
+72652064
+73726f72
+a
+746d654d
+20747365
+61746164
+69616620
+3a64656c
+2f642520
+65206425
+726f7272
+a73
+746d654d
+20747365
+72646461
+69616620
+3a64656c
+2f642520
+65206425
+726f7272
+a73
+746d654d
+20747365
+a4b4f
+736d654d
+64656570
+69725720
+3a736574
+4d642520
+20737062
+64616552
+25203a73
+70624d64
+a73
+64616552
+76656c20
+6e696c65
+a3a67
+2c64256d
+64256220
+7c203a
+6425
+207c
+74736562
+256d203a
+62202c64
+206425
+74696e49
+696c6169
+676e697a
+52445320
+2e2e4d41
+a2e
+6d315b1b
+20202020
+20202020
+20205f5f
+5f205f20
+2020205f
+5f202020
+5f5f2020
+6d305b1b
+a
+6d315b1b
+20202020
+2f202020
+20202f20
+20295f28
+5f5f5f2f
+207c205f
+2f5f2f7c
+6d305b1b
+a
+6d315b1b
+20202020
+202f2020
+2f5f5f2f
+5f202f20
+2d202f5f
+203e295f
+5b1b3c20
+a6d30
+6d315b1b
+20202020
+5f5f2f20
+5f2f5f5f
+5f5f5c2f
+5f5f5c2f
+7c2f5f2f
+5b1b7c5f
+a6d30
+6d315b1b
+42202020
+646c6975
+756f7920
+61682072
+61776472
+202c6572
+69736165
+1b21796c
+a6d305b
+0
+29632820
+706f4320
+67697279
+32207468
+2d323130
+30323032
+6a6e4520
+442d796f
+74696769
+a6c61
+29632820
+706f4320
+67697279
+32207468
+2d373030
+35313032
+4c2d4d20
+a736261
+0
+4f494220
+75622053
+20746c69
+46206e6f
+32206265
+30322035
+31203032
+37343a36
+a32333a
+0
+4f494220
+52432053
+61702043
+64657373
+30252820
+a297838
+0
+4f494220
+52432053
+61662043
+64656c69
+78652820
+74636570
+25206465
+2c783830
+746f6720
+38302520
+a2978
+65685420
+73797320
+206d6574
+6c6c6977
+6e6f6320
+756e6974
+62202c65
+65207475
+63657078
+72702074
+656c626f
+a2e736d
+0
+67694d20
+67206e65
+73207469
+3a316168
+2d2d2d20
+2d2d2d2d
+a2d
+74694c20
+67205865
+73207469
+3a316168
+31623920
+31396531
+a39
+3d3d2d2d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+5b1b203d
+6f536d31
+305b1b43
+3d3d206d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+a2d2d
+6d315b1b
+1b555043
+3a6d305b
+20202020
+202020
+52786556
+76637369
+0
+25204020
+7a484d64
+a
+6d315b1b
+1b4d4f52
+3a6d305b
+20202020
+25202020
+a424b64
+0
+6d315b1b
+4d415253
+6d305b1b
+2020203a
+25202020
+a424b64
+0
+6d315b1b
+5b1b324c
+203a6d30
+20202020
+25202020
+a424b64
+0
+6d315b1b
+4e49414d
+4d41522d
+6d305b1b
+2520203a
+a424b64
+0
+3d3d2d2d
+3d3d3d3d
+3d3d3d3d
+315b1b20
+696e496d
+6c616974
+74617a69
+1b6e6f69
+206d305b
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+a2d2d
+6f6d654d
+69207972
+6974696e
+7a696c61
+6f697461
+6166206e
+64656c69
+a
+3d3d2d2d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+315b1b20
+6f6f426d
+305b1b74
+3d3d206d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+a2d2d
+62206f4e
+20746f6f
+6964656d
+66206d75
+646e756f
+a
+3d3d2d2d
+3d3d3d3d
+3d3d3d3d
+203d3d3d
+6d315b1b
+736e6f43
+1b656c6f
+206d305b
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+a2d2d
+32395b1b
+6c6d313b
+78657469
+6d305b1b
+203e
+82008
+726d
+3c20726d
+72646461
+3e737365
+656c5b20
+6874676e
+a5d
+6f636e69
+63657272
+656c2074
+6874676e
+a
+6f6d654d
+64207972
+3a706d75
+0
+2578300a
+20783830
+20
+78323025
+20
+2e
+6325
+776d
+3c20776d
+72646461
+3e737365
+61763c20
+3e65756c
+6f635b20
+5d746e75
+a
+6f636e69
+63657272
+61762074
+a65756c
+0
+636d
+3c20636d
+3e747364
+72733c20
+5b203e63
+6e756f63
+a5d74
+6f636e69
+63657272
+65642074
+6e697473
+6f697461
+6461206e
+73657264
+a73
+6f636e69
+63657272
+6f732074
+65637275
+64646120
+73736572
+a
+637263
+20637263
+6464613c
+73736572
+6c3c203e
+74676e65
+a3e68
+33435243
+25203a32
+a783830
+0
+6e656469
+74
+6e656449
+25203a74
+a73
+73756c66
+326c68
+6f626572
+746f
+69726573
+6f626c61
+746f
+706c6568
+0
+6574694c
+49422058
+202c534f
+69617661
+6c62616c
+6f632065
+6e616d6d
+3a7364
+2020726d
+20202020
+2d202020
+61657220
+64612064
+73657264
+70732073
+656361
+2020776d
+20202020
+2d202020
+69727720
+61206574
+65726464
+73207373
+65636170
+0
+2020636d
+20202020
+2d202020
+706f6320
+64612079
+73657264
+70732073
+656361
+20637263
+20202020
+2d202020
+6d6f6320
+65747570
+43524320
+6f203233
+20612066
+74726170
+20666f20
+20656874
+72646461
+20737365
+63617073
+65
+6e656469
+20202074
+2d202020
+73696420
+79616c70
+65646920
+6669746e
+726569
+6f626572
+2020746f
+2d202020
+73657220
+70207465
+65636f72
+726f7373
+0
+69726573
+6f626c61
+2d20746f
+6f6f6220
+69762074
+46532061
+4c
+746d656d
+20747365
+2d202020
+6e757220
+6d206120
+726f6d65
+65742079
+7473
+72726473
+776f
+73726473
+77
+68726473
+77
+72726473
+66756264
+0
+72726473
+64
+72726473
+72726564
+0
+77726473
+72
+69726473
+74696e
+6c726473
+6c657665
+0
+746d656d
+747365
+6d6d6f43
+20646e61
+20746f6e
+6e756f66
+a64
+1ebc
+1ef8
+1f5c
+1ef8
+1dec
+1fd8
+44354c73
+6d4d5364
+726b656b
+a6f
+4849367a
+59633747
+36444944
+a6f
+746f6f42
+20676e69
+6d6f7266
+72657320
+2e6c6169
+a2e2e
+73657250
+20512073
+4520726f
+74204353
+6261206f
+2074726f
+746f6f62
+6d6f6320
+74656c70
+2e796c65
+a
+206f6f54
+796e616d
+6e6f6320
+75636573
+65766974
+72726520
+2c73726f
+6f626120
+6e697472
+67
+63657845
+6e697475
+6f622067
+6465746f
+6f727020
+6d617267
+20746120
+30257830
+a0a7838
+0
+3d3d2d2d
+3d3d3d3d
+3d3d3d3d
+203d3d3d
+6d315b1b
+7466694c
+2166666f
+6d305b1b
+3d3d3d20
+3d3d3d3d
+3d3d3d3d
+3d3d3d3d
+a2d2d
+656d6954
+a74756f
+0
+636e6143
+656c6c65
+a64
+8080808
+8080808
+28282808
+8082828
+8080808
+8080808
+8080808
+8080808
+101010a0
+10101010
+10101010
+10101010
+4040404
+4040404
+10100404
+10101010
+41414110
+1414141
+1010101
+1010101
+1010101
+1010101
+10010101
+10101010
+42424210
+2424242
+2020202
+2020202
+2020202
+2020202
+10020202
+8101010
+0
+0
+0
+0
+0
+0
+0
+0
+101010a0
+10101010
+10101010
+10101010
+10101010
+10101010
+10101010
+10101010
+1010101
+1010101
+1010101
+1010101
+1010101
+10010101
+1010101
+2010101
+2020202
+2020202
+2020202
+2020202
+2020202
+10020202
+2020202
+2020202
+33323130
+37363534
+42413938
+46454443
+4a494847
+4e4d4c4b
+5251504f
+56555453
+5a595857
+0
+33323130
+37363534
+62613938
+66656463
+6a696867
+6e6d6c6b
+7271706f
+76757473
+7a797877
+0
+726f6241
+2e646574
+0
+0
+1021
+2042
+3063
+4084
+50a5
+60c6
+70e7
+8108
+9129
+a14a
+b16b
+c18c
+d1ad
+e1ce
+f1ef
+1231
+210
+3273
+2252
+52b5
+4294
+72f7
+62d6
+9339
+8318
+b37b
+a35a
+d3bd
+c39c
+f3ff
+e3de
+2462
+3443
+420
+1401
+64e6
+74c7
+44a4
+5485
+a56a
+b54b
+8528
+9509
+e5ee
+f5cf
+c5ac
+d58d
+3653
+2672
+1611
+630
+76d7
+66f6
+5695
+46b4
+b75b
+a77a
+9719
+8738
+f7df
+e7fe
+d79d
+c7bc
+48c4
+58e5
+6886
+78a7
+840
+1861
+2802
+3823
+c9cc
+d9ed
+e98e
+f9af
+8948
+9969
+a90a
+b92b
+5af5
+4ad4
+7ab7
+6a96
+1a71
+a50
+3a33
+2a12
+dbfd
+cbdc
+fbbf
+eb9e
+9b79
+8b58
+bb3b
+ab1a
+6ca6
+7c87
+4ce4
+5cc5
+2c22
+3c03
+c60
+1c41
+edae
+fd8f
+cdec
+ddcd
+ad2a
+bd0b
+8d68
+9d49
+7e97
+6eb6
+5ed5
+4ef4
+3e13
+2e32
+1e51
+e70
+ff9f
+efbe
+dfdd
+cffc
+bf1b
+af3a
+9f59
+8f78
+9188
+81a9
+b1ca
+a1eb
+d10c
+c12d
+f14e
+e16f
+1080
+a1
+30c2
+20e3
+5004
+4025
+7046
+6067
+83b9
+9398
+a3fb
+b3da
+c33d
+d31c
+e37f
+f35e
+2b1
+1290
+22f3
+32d2
+4235
+5214
+6277
+7256
+b5ea
+a5cb
+95a8
+8589
+f56e
+e54f
+d52c
+c50d
+34e2
+24c3
+14a0
+481
+7466
+6447
+5424
+4405
+a7db
+b7fa
+8799
+97b8
+e75f
+f77e
+c71d
+d73c
+26d3
+36f2
+691
+16b0
+6657
+7676
+4615
+5634
+d94c
+c96d
+f90e
+e92f
+99c8
+89e9
+b98a
+a9ab
+5844
+4865
+7806
+6827
+18c0
+8e1
+3882
+28a3
+cb7d
+db5c
+eb3f
+fb1e
+8bf9
+9bd8
+abbb
+bb9a
+4a75
+5a54
+6a37
+7a16
+af1
+1ad0
+2ab3
+3a92
+fd2e
+ed0f
+dd6c
+cd4d
+bdaa
+ad8b
+9de8
+8dc9
+7c26
+6c07
+5c64
+4c45
+3ca2
+2c83
+1ce0
+cc1
+ef1f
+ff3e
+cf5d
+df7c
+af9b
+bfba
+8fd9
+9ff8
+6e17
+7e36
+4e55
+5e74
+2e93
+3eb2
+ed1
+1ef0
+0
+77073096
+ee0e612c
+990951ba
+76dc419
+706af48f
+e963a535
+9e6495a3
+edb8832
+79dcb8a4
+e0d5e91e
+97d2d988
+9b64c2b
+7eb17cbd
+e7b82d07
+90bf1d91
+1db71064
+6ab020f2
+f3b97148
+84be41de
+1adad47d
+6ddde4eb
+f4d4b551
+83d385c7
+136c9856
+646ba8c0
+fd62f97a
+8a65c9ec
+14015c4f
+63066cd9
+fa0f3d63
+8d080df5
+3b6e20c8
+4c69105e
+d56041e4
+a2677172
+3c03e4d1
+4b04d447
+d20d85fd
+a50ab56b
+35b5a8fa
+42b2986c
+dbbbc9d6
+acbcf940
+32d86ce3
+45df5c75
+dcd60dcf
+abd13d59
+26d930ac
+51de003a
+c8d75180
+bfd06116
+21b4f4b5
+56b3c423
+cfba9599
+b8bda50f
+2802b89e
+5f058808
+c60cd9b2
+b10be924
+2f6f7c87
+58684c11
+c1611dab
+b6662d3d
+76dc4190
+1db7106
+98d220bc
+efd5102a
+71b18589
+6b6b51f
+9fbfe4a5
+e8b8d433
+7807c9a2
+f00f934
+9609a88e
+e10e9818
+7f6a0dbb
+86d3d2d
+91646c97
+e6635c01
+6b6b51f4
+1c6c6162
+856530d8
+f262004e
+6c0695ed
+1b01a57b
+8208f4c1
+f50fc457
+65b0d9c6
+12b7e950
+8bbeb8ea
+fcb9887c
+62dd1ddf
+15da2d49
+8cd37cf3
+fbd44c65
+4db26158
+3ab551ce
+a3bc0074
+d4bb30e2
+4adfa541
+3dd895d7
+a4d1c46d
+d3d6f4fb
+4369e96a
+346ed9fc
+ad678846
+da60b8d0
+44042d73
+33031de5
+aa0a4c5f
+dd0d7cc9
+5005713c
+270241aa
+be0b1010
+c90c2086
+5768b525
+206f85b3
+b966d409
+ce61e49f
+5edef90e
+29d9c998
+b0d09822
+c7d7a8b4
+59b33d17
+2eb40d81
+b7bd5c3b
+c0ba6cad
+edb88320
+9abfb3b6
+3b6e20c
+74b1d29a
+ead54739
+9dd277af
+4db2615
+73dc1683
+e3630b12
+94643b84
+d6d6a3e
+7a6a5aa8
+e40ecf0b
+9309ff9d
+a00ae27
+7d079eb1
+f00f9344
+8708a3d2
+1e01f268
+6906c2fe
+f762575d
+806567cb
+196c3671
+6e6b06e7
+fed41b76
+89d32be0
+10da7a5a
+67dd4acc
+f9b9df6f
+8ebeeff9
+17b7be43
+60b08ed5
+d6d6a3e8
+a1d1937e
+38d8c2c4
+4fdff252
+d1bb67f1
+a6bc5767
+3fb506dd
+48b2364b
+d80d2bda
+af0a1b4c
+36034af6
+41047a60
+df60efc3
+a867df55
+316e8eef
+4669be79
+cb61b38c
+bc66831a
+256fd2a0
+5268e236
+cc0c7795
+bb0b4703
+220216b9
+5505262f
+c5ba3bbe
+b2bd0b28
+2bb45a92
+5cb36a04
+c2d7ffa7
+b5d0cf31
+2cd99e8b
+5bdeae1d
+9b64c2b0
+ec63f226
+756aa39c
+26d930a
+9c0906a9
+eb0e363f
+72076785
+5005713
+95bf4a82
+e2b87a14
+7bb12bae
+cb61b38
+92d28e9b
+e5d5be0d
+7cdcefb7
+bdbdf21
+86d3d2d4
+f1d4e242
+68ddb3f8
+1fda836e
+81be16cd
+f6b9265b
+6fb077e1
+18b74777
+88085ae6
+ff0f6a70
+66063bca
+11010b5c
+8f659eff
+f862ae69
+616bffd3
+166ccf45
+a00ae278
+d70dd2ee
+4e048354
+3903b3c2
+a7672661
+d06016f7
+4969474d
+3e6e77db
+aed16a4a
+d9d65adc
+40df0b66
+37d83bf0
+a9bcae53
+debb9ec5
+47b2cf7f
+30b5ffe9
+bdbdf21c
+cabac28a
+53b39330
+24b4a3a6
+bad03605
+cdd70693
+54de5729
+23d967bf
+b3667a2e
+c4614ab8
+5d681b02
+2a6f2b94
+b40bbe37
+c30c8ea1
+5a05df1b
+2d02ef8d
+4c554e3c
+3e4c
+b18edfe
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/mem_1.init b/yosys-plugins/xdc/tests/minilitex_ddr_arty/mem_1.init
new file mode 100644
index 000000000..e69de29bb
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.golden.json b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.golden.json
new file mode 100644
index 000000000..cb0da138a
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.golden.json
@@ -0,0 +1,259 @@
+{
+  "$iopadmap$top.cpu_reset": {
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "cpu_reset:C2"
+  },
+  "$iopadmap$top.serial_rx": {
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "serial_rx:A9"
+  },
+  "$iopadmap$top.serial_tx": {
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "serial_tx:D10"
+  },
+  "IOBUF": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[0]:K5",
+    "SLEW": "FAST"
+  },
+  "IOBUF_1": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[1]:L3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_10": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[10]:U4",
+    "SLEW": "FAST"
+  },
+  "IOBUF_11": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[11]:V5",
+    "SLEW": "FAST"
+  },
+  "IOBUF_12": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[12]:V1",
+    "SLEW": "FAST"
+  },
+  "IOBUF_13": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[13]:T3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_14": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[14]:U3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_15": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[15]:R3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_2": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[2]:K3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_3": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[3]:L6",
+    "SLEW": "FAST"
+  },
+  "IOBUF_4": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[4]:M3",
+    "SLEW": "FAST"
+  },
+  "IOBUF_5": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[5]:M1",
+    "SLEW": "FAST"
+  },
+  "IOBUF_6": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[6]:L4",
+    "SLEW": "FAST"
+  },
+  "IOBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[7]:M2",
+    "SLEW": "FAST"
+  },
+  "IOBUF_8": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[8]:V4",
+    "SLEW": "FAST"
+  },
+  "IOBUF_9": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dq[9]:T5",
+    "SLEW": "FAST"
+  },
+  "OBUFTDS": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "ddram_dqs_p[0]:N2,ddram_dqs_n[0]:N1",
+    "SLEW": "FAST"
+  },
+  "OBUFTDS_1": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "ddram_dqs_p[1]:U2,ddram_dqs_n[1]:V2",
+    "SLEW": "FAST"
+  },
+  "OBUFTDS_2": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "ddram_clk_p:U9,ddram_clk_n:V9",
+    "SLEW": "FAST"
+  },
+  "clkbuf": {
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "clk100:E3"
+  },
+  "obuf_a0": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[0]:R2",
+    "SLEW": "FAST"
+  },
+  "obuf_a1": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[1]:M6",
+    "SLEW": "FAST"
+  },
+  "obuf_a10": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[10]:R6",
+    "SLEW": "FAST"
+  },
+  "obuf_a11": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[11]:U6",
+    "SLEW": "FAST"
+  },
+  "obuf_a12": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[12]:T6",
+    "SLEW": "FAST"
+  },
+  "obuf_a13": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[13]:T8",
+    "SLEW": "FAST"
+  },
+  "obuf_a2": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[2]:N4",
+    "SLEW": "FAST"
+  },
+  "obuf_a3": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[3]:T1",
+    "SLEW": "FAST"
+  },
+  "obuf_a4": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[4]:N6",
+    "SLEW": "FAST"
+  },
+  "obuf_a5": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[5]:R7",
+    "SLEW": "FAST"
+  },
+  "obuf_a6": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[6]:V6",
+    "SLEW": "FAST"
+  },
+  "obuf_a7": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[7]:U7",
+    "SLEW": "FAST"
+  },
+  "obuf_a8": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[8]:R8",
+    "SLEW": "FAST"
+  },
+  "obuf_a9": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_a[9]:V7",
+    "SLEW": "FAST"
+  },
+  "obuf_ba0": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_ba[0]:R1",
+    "SLEW": "FAST"
+  },
+  "obuf_ba1": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_ba[1]:P4",
+    "SLEW": "FAST"
+  },
+  "obuf_ba2": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_ba[2]:P2",
+    "SLEW": "FAST"
+  },
+  "obuf_cas": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_cas_n:M4",
+    "SLEW": "FAST"
+  },
+  "obuf_cke": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_cke:N5",
+    "SLEW": "FAST"
+  },
+  "obuf_cs": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_cs_n:U8",
+    "SLEW": "FAST"
+  },
+  "obuf_dm0": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dm[0]:L1",
+    "SLEW": "FAST"
+  },
+  "obuf_dm1": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_dm[1]:U1",
+    "SLEW": "FAST"
+  },
+  "obuf_odt": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_odt:R5",
+    "SLEW": "FAST"
+  },
+  "obuf_ras": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_ras_n:P3",
+    "SLEW": "FAST"
+  },
+  "obuf_rst": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_reset_n:K6",
+    "SLEW": "FAST"
+  },
+  "obuf_we": {
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "ddram_we_n:P5",
+    "SLEW": "FAST"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.tcl b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.tcl
new file mode 100644
index 000000000..df2555c13
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.tcl
@@ -0,0 +1,19 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+read_verilog [file dirname [info script]]/VexRiscv_Lite.v
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json [file dirname [info script]]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "minilitex_ddr_arty.json"]
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.v b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.v
new file mode 120000
index 000000000..44966b140
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.v
@@ -0,0 +1 @@
+../../../../third_party/minilitex_ddr_arty/minilitex_ddr_arty.v
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.xdc b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.xdc
new file mode 100644
index 000000000..bb6ded792
--- /dev/null
+++ b/yosys-plugins/xdc/tests/minilitex_ddr_arty/minilitex_ddr_arty.xdc
@@ -0,0 +1,230 @@
+ ## serial:0.tx
+set_property LOC D10 [get_ports serial_tx]
+set_property IOSTANDARD LVCMOS33 [get_ports serial_tx]
+# ## serial:0.rx
+set_property LOC A9 [get_ports serial_rx]
+set_property IOSTANDARD LVCMOS33 [get_ports serial_rx]
+# ## clk100:0
+set_property LOC E3 [get_ports clk100]
+set_property IOSTANDARD LVCMOS33 [get_ports clk100]
+# ## cpu_reset:0
+set_property LOC C2 [get_ports cpu_reset]
+set_property IOSTANDARD LVCMOS33 [get_ports cpu_reset]
+# ## ddram:0.a
+set_property LOC R2 [get_ports {ddram_a[0]} ]
+set_property SLEW FAST [get_ports {ddram_a[0]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[0]} ]
+# ## ddram:0.a
+set_property LOC M6 [get_ports {ddram_a[1]} ]
+set_property SLEW FAST [get_ports {ddram_a[1]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[1]} ]
+# ## ddram:0.a
+set_property LOC N4 [get_ports {ddram_a[2]} ]
+set_property SLEW FAST [get_ports {ddram_a[2]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[2]} ]
+# ## ddram:0.a
+set_property LOC T1 [get_ports {ddram_a[3]} ]
+set_property SLEW FAST [get_ports {ddram_a[3]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[3]} ]
+# ## ddram:0.a
+set_property LOC N6 [get_ports {ddram_a[4]} ]
+set_property SLEW FAST [get_ports {ddram_a[4]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[4]} ]
+# ## ddram:0.a
+set_property LOC R7 [get_ports {ddram_a[5]} ]
+set_property SLEW FAST [get_ports {ddram_a[5]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[5]} ]
+# ## ddram:0.a
+set_property LOC V6 [get_ports {ddram_a[6]} ]
+set_property SLEW FAST [get_ports {ddram_a[6]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[6]} ]
+# ## ddram:0.a
+set_property LOC U7 [get_ports {ddram_a[7]} ]
+set_property SLEW FAST [get_ports {ddram_a[7]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[7]} ]
+# ## ddram:0.a
+set_property LOC R8 [get_ports {ddram_a[8]} ]
+set_property SLEW FAST [get_ports {ddram_a[8]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[8]} ]
+# ## ddram:0.a
+set_property LOC V7 [get_ports {ddram_a[9]} ]
+set_property SLEW FAST [get_ports {ddram_a[9]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[9]} ]
+# ## ddram:0.a
+set_property LOC R6 [get_ports {ddram_a[10]} ]
+set_property SLEW FAST [get_ports {ddram_a[10]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[10]} ]
+# ## ddram:0.a
+set_property LOC U6 [get_ports {ddram_a[11]} ]
+set_property SLEW FAST [get_ports {ddram_a[11]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[11]} ]
+# ## ddram:0.a
+set_property LOC T6 [get_ports {ddram_a[12]} ]
+set_property SLEW FAST [get_ports {ddram_a[12]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[12]} ]
+# ## ddram:0.a
+set_property LOC T8 [get_ports {ddram_a[13]} ]
+set_property SLEW FAST [get_ports {ddram_a[13]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_a[13]} ]
+# ## ddram:0.ba
+set_property LOC R1 [get_ports {ddram_ba[0]} ]
+set_property SLEW FAST [get_ports {ddram_ba[0]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[0]} ]
+# ## ddram:0.ba
+set_property LOC P4 [get_ports {ddram_ba[1]} ]
+set_property SLEW FAST [get_ports {ddram_ba[1]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[1]} ]
+# ## ddram:0.ba
+set_property LOC P2 [get_ports {ddram_ba[2]} ]
+set_property SLEW FAST [get_ports {ddram_ba[2]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[2]} ]
+# ## ddram:0.ras_n
+set_property LOC P3 [get_ports ddram_ras_n]
+set_property SLEW FAST [get_ports ddram_ras_n]
+set_property IOSTANDARD SSTL135 [get_ports ddram_ras_n]
+# ## ddram:0.cas_n
+set_property LOC M4 [get_ports ddram_cas_n]
+set_property SLEW FAST [get_ports ddram_cas_n]
+set_property IOSTANDARD SSTL135 [get_ports ddram_cas_n]
+# ## ddram:0.we_n
+set_property LOC P5 [get_ports ddram_we_n]
+set_property SLEW FAST [get_ports ddram_we_n]
+set_property IOSTANDARD SSTL135 [get_ports ddram_we_n]
+# ## ddram:0.cs_n
+set_property LOC U8 [get_ports ddram_cs_n]
+set_property SLEW FAST [get_ports ddram_cs_n]
+set_property IOSTANDARD SSTL135 [get_ports ddram_cs_n]
+# ## ddram:0.dm
+set_property LOC L1 [get_ports {ddram_dm[0]} ]
+set_property SLEW FAST [get_ports {ddram_dm[0]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[0]} ]
+# ## ddram:0.dm
+set_property LOC U1 [get_ports {ddram_dm[1]} ]
+set_property SLEW FAST [get_ports {ddram_dm[1]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[1]} ]
+# ## ddram:0.dq
+set_property LOC K5 [get_ports {ddram_dq[0]} ]
+set_property SLEW FAST [get_ports {ddram_dq[0]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[0]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[0]} ]
+# ## ddram:0.dq
+set_property LOC L3 [get_ports {ddram_dq[1]} ]
+set_property SLEW FAST [get_ports {ddram_dq[1]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[1]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[1]} ]
+# ## ddram:0.dq
+set_property LOC K3 [get_ports {ddram_dq[2]} ]
+set_property SLEW FAST [get_ports {ddram_dq[2]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[2]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[2]} ]
+# ## ddram:0.dq
+set_property LOC L6 [get_ports {ddram_dq[3]} ]
+set_property SLEW FAST [get_ports {ddram_dq[3]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[3]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[3]} ]
+# ## ddram:0.dq
+set_property LOC M3 [get_ports {ddram_dq[4]} ]
+set_property SLEW FAST [get_ports {ddram_dq[4]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[4]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[4]} ]
+# ## ddram:0.dq
+set_property LOC M1 [get_ports {ddram_dq[5]} ]
+set_property SLEW FAST [get_ports {ddram_dq[5]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[5]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[5]} ]
+# ## ddram:0.dq
+set_property LOC L4 [get_ports {ddram_dq[6]} ]
+set_property SLEW FAST [get_ports {ddram_dq[6]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[6]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[6]} ]
+# ## ddram:0.dq
+set_property LOC M2 [get_ports {ddram_dq[7]} ]
+set_property SLEW FAST [get_ports {ddram_dq[7]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[7]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[7]} ]
+# ## ddram:0.dq
+set_property LOC V4 [get_ports {ddram_dq[8]} ]
+set_property SLEW FAST [get_ports {ddram_dq[8]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[8]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[8]} ]
+# ## ddram:0.dq
+set_property LOC T5 [get_ports {ddram_dq[9]} ]
+set_property SLEW FAST [get_ports {ddram_dq[9]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[9]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[9]} ]
+# ## ddram:0.dq
+set_property LOC U4 [get_ports {ddram_dq[10]} ]
+set_property SLEW FAST [get_ports {ddram_dq[10]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[10]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[10]} ]
+# ## ddram:0.dq
+set_property LOC V5 [get_ports {ddram_dq[11]} ]
+set_property SLEW FAST [get_ports {ddram_dq[11]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[11]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[11]} ]
+# ## ddram:0.dq
+set_property LOC V1 [get_ports {ddram_dq[12]} ]
+set_property SLEW FAST [get_ports {ddram_dq[12]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[12]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[12]} ]
+# ## ddram:0.dq
+set_property LOC T3 [get_ports {ddram_dq[13]} ]
+set_property SLEW FAST [get_ports {ddram_dq[13]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[13]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[13]} ]
+# ## ddram:0.dq
+set_property LOC U3 [get_ports {ddram_dq[14]} ]
+set_property SLEW FAST [get_ports {ddram_dq[14]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[14]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[14]} ]
+# ## ddram:0.dq
+set_property LOC R3 [get_ports {ddram_dq[15]} ]
+set_property SLEW FAST [get_ports {ddram_dq[15]} ]
+set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[15]} ]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[15]} ]
+# ## ddram:0.dqs_p
+set_property LOC N2 [get_ports {ddram_dqs_p[0]} ]
+set_property SLEW FAST [get_ports {ddram_dqs_p[0]} ]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[0]} ]
+# ## ddram:0.dqs_p
+set_property LOC U2 [get_ports {ddram_dqs_p[1]} ]
+set_property SLEW FAST [get_ports {ddram_dqs_p[1]} ]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[1]} ]
+# ## ddram:0.dqs_n
+set_property LOC N1 [get_ports {ddram_dqs_n[0]} ]
+set_property SLEW FAST [get_ports {ddram_dqs_n[0]} ]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[0]} ]
+# ## ddram:0.dqs_n
+set_property LOC V2 [get_ports {ddram_dqs_n[1]} ]
+set_property SLEW FAST [get_ports {ddram_dqs_n[1]} ]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[1]} ]
+# ## ddram:0.clk_p
+set_property LOC U9 [get_ports ddram_clk_p]
+set_property SLEW FAST [get_ports ddram_clk_p]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_clk_p]
+# ## ddram:0.clk_n
+set_property LOC V9 [get_ports ddram_clk_n]
+set_property SLEW FAST [get_ports ddram_clk_n]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports ddram_clk_n]
+# ## ddram:0.cke
+set_property LOC N5 [get_ports ddram_cke]
+set_property SLEW FAST [get_ports ddram_cke]
+set_property IOSTANDARD SSTL135 [get_ports ddram_cke]
+# ## ddram:0.odt
+set_property LOC R5 [get_ports ddram_odt]
+set_property SLEW FAST [get_ports ddram_odt]
+set_property IOSTANDARD SSTL135 [get_ports ddram_odt]
+# ## ddram:0.reset_n
+set_property LOC K6 [get_ports ddram_reset_n]
+set_property SLEW FAST [get_ports ddram_reset_n]
+set_property IOSTANDARD SSTL135 [get_ports ddram_reset_n]
+
+set_property INTERNAL_VREF 0.675 [get_iobanks 34]
+
+#create_clock -name clk100 -period 10.0 [get_nets clk100]
+#
+#set_false_path -quiet -to [get_nets -quiet -filter {mr_ff == TRUE}]
+#
+#set_false_path -quiet -to [get_pins -quiet -filter {REF_PIN_NAME == PRE} -of [get_cells -quiet -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]} ]
+#
+#set_max_delay 2 -quiet -from [get_pins -quiet -filter {REF_PIN_NAME == Q} -of [get_cells -quiet -filter {ars_ff1 == TRUE}]} ] -to [get_pins -quiet -filter {REF_PIN_NAME == D} -of [get_cells -quiet -filter {ars_ff2 == TRUE}]} ]
diff --git a/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.golden.json b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.golden.json
new file mode 100644
index 000000000..980b4cf52
--- /dev/null
+++ b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.golden.json
@@ -0,0 +1,18 @@
+{
+	"$iopadmap$top.LED": {
+		"IOSTANDARD": "LVCMOS33",
+		"IO_LOC_PAIRS": "LED[2]:H5"
+	},
+	"$iopadmap$top.LED_1": {
+		"IOSTANDARD": "LVCMOS33",
+		"IO_LOC_PAIRS": "LED[3]:J5"
+	},
+	"$iopadmap$top.LED_2": {
+		"IOSTANDARD": "LVCMOS33",
+		"IO_LOC_PAIRS": "LED[4]:T9"
+	},
+	"$iopadmap$top.LED_3": {
+		"IOSTANDARD": "LVCMOS33",
+		"IO_LOC_PAIRS": "LED[5]:T10"
+	}
+}
diff --git a/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.tcl b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.tcl
new file mode 100644
index 000000000..50872c005
--- /dev/null
+++ b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.tcl
@@ -0,0 +1,25 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+read_verilog -lib -specify +/xilinx/cells_sim.v
+read_verilog -lib +/xilinx/cells_xtra.v
+
+hierarchy -check -top top
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp -run prepare:check
+
+#Read the design constraints
+read_xdc -part_json [file dirname $::env(DESIGN_TOP)]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "non_zero_port_indexes.json"]
+write_blif -param [test_output_path "non_zero_port_indexes.eblif"]
diff --git a/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.v b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.v
new file mode 100644
index 000000000..f4a409344
--- /dev/null
+++ b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.v
@@ -0,0 +1,23 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top(
+           output [5:2] LED
+           );
+
+   assign LED[5:2] = 4'b1010;
+
+endmodule
diff --git a/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.xdc b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.xdc
new file mode 100644
index 000000000..6a9af2060
--- /dev/null
+++ b/yosys-plugins/xdc/tests/non_zero_port_indexes/non_zero_port_indexes.xdc
@@ -0,0 +1,4 @@
+set_property -dict { PACKAGE_PIN H5   IOSTANDARD LVCMOS33 } [get_ports { LED[2] }];
+set_property -dict { PACKAGE_PIN J5   IOSTANDARD LVCMOS33 } [get_ports { LED[3] }];
+set_property -dict { PACKAGE_PIN T9   IOSTANDARD LVCMOS33 } [get_ports { LED[4] }];
+set_property -dict { PACKAGE_PIN T10   IOSTANDARD LVCMOS33 } [get_ports { LED[5] }];
diff --git a/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.golden.json b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.golden.json
new file mode 100644
index 000000000..2e9102dda
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.golden.json
@@ -0,0 +1,47 @@
+{
+  "OBUFTDS_2": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "signal_p:N2,signal_n:N1",
+    "SLEW": "FAST"
+  },
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "led[0]:D10",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[1]:A9",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "out_a:E3",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "IO_LOC_PAIRS": "out_b[0]:C2",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "IO_LOC_PAIRS": "out_b[1]:R2",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "led[2]:M6",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[3]:N4",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.tcl b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.tcl
new file mode 100644
index 000000000..7625c92c8
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.tcl
@@ -0,0 +1,18 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json [file dirname [info script]]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "package_pins-dict-space.json"]
diff --git a/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.v b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.v
new file mode 100644
index 000000000..23336ed42
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.xdc b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.xdc
new file mode 100644
index 000000000..70453d1cb
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins-dict-space/package_pins-dict-space.xdc
@@ -0,0 +1,29 @@
+#OBUF_6
+set_property PACKAGE_PIN D10 [get_ports {led[0]}]
+set_property DRIVE 12 [get_ports {led[0]}]
+#OBUF_7
+set_property -dict { PACKAGE_PIN A9   IOSTANDARD SSTL135 } [get_ports {led[1]}]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports led[1]]
+set_property SLEW FAST [get_ports led[1]]
+#OBUF_OUT
+set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33} [get_ports out_a]
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports out_a]
+set_property SLEW FAST [get_ports out_a]
+#bottom_inst.OBUF_10
+set_property -dict {PACKAGE_PIN C2  IOSTANDARD LVCMOS18} [get_ports {out_b[0]}]
+set_property SLEW SLOW [get_ports {out_b[0]}]
+#bottom_inst.OBUF_11
+set_property -dict { PACKAGE_PIN R2   IOSTANDARD LVCMOS25 } [get_ports {out_b[1]}]
+set_property DRIVE 4 [get_ports {out_b[1]}]
+set_property SLEW FAST [get_ports {out_b[1]}]
+#bottom_inst.OBUF_9
+set_property -dict {PACKAGE_PIN M6      IOSTANDARD DIFF_SSTL135} [get_ports {led[2]}]
+set_property SLEW FAST [get_ports {led[2]}]
+#bottom_intermediate_inst.OBUF_8
+set_property -dict {PACKAGE_PIN N4    IOSTANDARD SSTL135} [get_ports {led[3]}]
+set_property DRIVE 16 [get_ports {led[3]}]
+#OBUFTDS_2
+set_property -dict {PACKAGE_PIN N2    IOSTANDARD DIFF_SSTL135} [get_ports signal_p]
+set_property PACKAGE_PIN N1 [get_ports signal_n]
+set_property SLEW FAST [get_ports signal_p]
+
diff --git a/yosys-plugins/xdc/tests/package_pins/package_pins.golden.json b/yosys-plugins/xdc/tests/package_pins/package_pins.golden.json
new file mode 100644
index 000000000..2e9102dda
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins/package_pins.golden.json
@@ -0,0 +1,47 @@
+{
+  "OBUFTDS_2": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "signal_p:N2,signal_n:N1",
+    "SLEW": "FAST"
+  },
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "led[0]:D10",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[1]:A9",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "IO_LOC_PAIRS": "out_a:E3",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "IO_LOC_PAIRS": "out_b[0]:C2",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "IO_LOC_PAIRS": "out_b[1]:R2",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "IO_LOC_PAIRS": "led[2]:M6",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "IO_LOC_PAIRS": "led[3]:N4",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/package_pins/package_pins.tcl b/yosys-plugins/xdc/tests/package_pins/package_pins.tcl
new file mode 100644
index 000000000..90298ebbd
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins/package_pins.tcl
@@ -0,0 +1,18 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+#Read the design constraints
+read_xdc -part_json [file dirname [info script]]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "package_pins.json"]
diff --git a/yosys-plugins/xdc/tests/package_pins/package_pins.v b/yosys-plugins/xdc/tests/package_pins/package_pins.v
new file mode 100644
index 000000000..23336ed42
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins/package_pins.v
@@ -0,0 +1,119 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b,
+    output signal_p,
+    output signal_n
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUFTDS OBUFTDS_2 (
+      .I (LD6),
+      .O (signal_p),
+      .OB(signal_n),
+      .T (1'b1)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/xdc/tests/package_pins/package_pins.xdc b/yosys-plugins/xdc/tests/package_pins/package_pins.xdc
new file mode 100644
index 000000000..543edb0d6
--- /dev/null
+++ b/yosys-plugins/xdc/tests/package_pins/package_pins.xdc
@@ -0,0 +1,36 @@
+#OBUF_6
+set_property PACKAGE_PIN D10 [get_ports {led[0]}]
+set_property DRIVE 12 [get_ports {led[0]}]
+#OBUF_7
+set_property PACKAGE_PIN A9 [get_ports {led[1]}]
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports led[1]]
+set_property SLEW FAST [get_ports led[1]]
+set_property IOSTANDARD SSTL135 [get_ports led[1]]
+#OBUF_OUT
+set_property PACKAGE_PIN E3 [get_ports out_a]
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports out_a]
+set_property SLEW FAST [get_ports out_a]
+set_property IOSTANDARD LVCMOS33 [get_ports out_a]
+#bottom_inst.OBUF_10
+set_property PACKAGE_PIN C2 [get_ports {out_b[0]}]
+set_property SLEW SLOW [get_ports {out_b[0]}]
+set_property IOSTANDARD LVCMOS18 [get_ports {out_b[0]}]
+#bottom_inst.OBUF_11
+set_property PACKAGE_PIN R2 [get_ports {out_b[1]}]
+set_property DRIVE 4 [get_ports {out_b[1]}]
+set_property SLEW FAST [get_ports {out_b[1]}]
+set_property IOSTANDARD LVCMOS25 [get_ports {out_b[1]}]
+#bottom_inst.OBUF_9
+set_property PACKAGE_PIN M6 [get_ports {led[2]}]
+set_property SLEW FAST [get_ports {led[2]}]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports {led[2]}]
+#bottom_intermediate_inst.OBUF_8
+set_property PACKAGE_PIN N4 [get_ports {led[3]}]
+set_property DRIVE 16 [get_ports {led[3]}]
+set_property IOSTANDARD SSTL135 [get_ports {led[3]}]
+#OBUFTDS_2
+set_property PACKAGE_PIN N2 [get_ports signal_p]
+set_property PACKAGE_PIN N1 [get_ports signal_n]
+set_property SLEW FAST [get_ports signal_p]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports signal_p]
+
diff --git a/yosys-plugins/xdc/tests/port_indexes/port_indexes.golden.json b/yosys-plugins/xdc/tests/port_indexes/port_indexes.golden.json
new file mode 100644
index 000000000..25e123427
--- /dev/null
+++ b/yosys-plugins/xdc/tests/port_indexes/port_indexes.golden.json
@@ -0,0 +1,35 @@
+{
+  "OBUF_6": {
+    "DRIVE": "12",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "SLOW"
+  },
+  "OBUF_7": {
+    "IN_TERM": "UNTUNED_SPLIT_40",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "FAST"
+  },
+  "OBUF_OUT": {
+    "IN_TERM": "UNTUNED_SPLIT_50",
+    "IOSTANDARD": "LVCMOS33",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_10": {
+    "IOSTANDARD": "LVCMOS18",
+    "SLEW": "SLOW"
+  },
+  "bottom_inst.OBUF_11": {
+    "DRIVE": "4",
+    "IOSTANDARD": "LVCMOS25",
+    "SLEW": "FAST"
+  },
+  "bottom_inst.OBUF_9": {
+    "IOSTANDARD": "DIFF_SSTL135",
+    "SLEW": "FAST"
+  },
+  "bottom_intermediate_inst.OBUF_8": {
+    "DRIVE": "16",
+    "IOSTANDARD": "SSTL135",
+    "SLEW": "SLOW"
+  }
+}
\ No newline at end of file
diff --git a/yosys-plugins/xdc/tests/port_indexes/port_indexes.tcl b/yosys-plugins/xdc/tests/port_indexes/port_indexes.tcl
new file mode 100644
index 000000000..c2c148a84
--- /dev/null
+++ b/yosys-plugins/xdc/tests/port_indexes/port_indexes.tcl
@@ -0,0 +1,38 @@
+yosys -import
+if { [info procs get_ports] == {} } { plugin -i design_introspection }
+if { [info procs read_xdc] == {} } { plugin -i xdc }
+yosys -import  ;# ingest plugin commands
+
+read_verilog $::env(DESIGN_TOP).v
+
+# -flatten is used to ensure that the output eblif has only one module.
+# Some of F4PGA expects eblifs with only one module.
+synth_xilinx -flatten -abc9 -nosrl -noclkbuf -nodsp
+
+if {[info procs unknown] != ""} {
+	rename unknown ""
+}
+proc unknown args {return "'unknown' proc command handler"}
+set fp [open [test_output_path "port_indexes.txt"] "w"]
+if {[catch {invalid command} result]} {
+	close $fp
+	error "Command should be handled by the 'unknown' proc"
+} else {
+	puts $fp $result
+}
+#Read the design constraints
+read_xdc -part_json [file dirname [info script]]/../xc7a35tcsg324-1.json $::env(DESIGN_TOP).xdc
+
+if {[catch {invalid command} result]} {
+	close $fp
+	error "Command should be handled by the 'unknown' proc"
+} else {
+	puts $fp $result
+}
+close $fp
+
+# Clean processes before writing JSON.
+yosys proc
+
+# Write the design in JSON format.
+write_json [test_output_path "port_indexes.json"]
diff --git a/yosys-plugins/xdc/tests/port_indexes/port_indexes.v b/yosys-plugins/xdc/tests/port_indexes/port_indexes.v
new file mode 100644
index 000000000..cc8a821db
--- /dev/null
+++ b/yosys-plugins/xdc/tests/port_indexes/port_indexes.v
@@ -0,0 +1,111 @@
+// Copyright 2020-2022 F4PGA Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+module top (
+    input clk,
+    output [3:0] led,
+    inout out_a,
+    output [1:0] out_b
+);
+
+  wire LD6, LD7, LD8, LD9;
+  wire inter_wire, inter_wire_2;
+  localparam BITS = 1;
+  localparam LOG2DELAY = 25;
+
+  reg [BITS+LOG2DELAY-1:0] counter = 0;
+
+  always @(posedge clk) begin
+    counter <= counter + 1;
+  end
+  assign led[1] = inter_wire;
+  assign inter_wire = inter_wire_2;
+  assign {LD9, LD8, LD7, LD6} = counter >> LOG2DELAY;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_6 (
+      .I(LD6),
+      .O(led[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_7 (
+      .I(LD7),
+      .O(inter_wire_2)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_OUT (
+      .I(LD7),
+      .O(out_a)
+  );
+  bottom bottom_inst (
+      .I (LD8),
+      .O (led[2]),
+      .OB(out_b)
+  );
+  bottom_intermediate bottom_intermediate_inst (
+      .I(LD9),
+      .O(led[3])
+  );
+endmodule
+
+module bottom_intermediate (
+    input  I,
+    output O
+);
+  wire bottom_intermediate_wire;
+  assign O = bottom_intermediate_wire;
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_8 (
+      .I(I),
+      .O(bottom_intermediate_wire)
+  );
+endmodule
+
+module bottom (
+    input I,
+    output [1:0] OB,
+    output O
+);
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_9 (
+      .I(I),
+      .O(O)
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_10 (
+      .I(I),
+      .O(OB[0])
+  );
+  OBUF #(
+      .IOSTANDARD("LVCMOS33"),
+      .SLEW("SLOW")
+  ) OBUF_11 (
+      .I(I),
+      .O(OB[1])
+  );
+endmodule
+
diff --git a/yosys-plugins/xdc/tests/port_indexes/port_indexes.xdc b/yosys-plugins/xdc/tests/port_indexes/port_indexes.xdc
new file mode 100644
index 000000000..48202f52e
--- /dev/null
+++ b/yosys-plugins/xdc/tests/port_indexes/port_indexes.xdc
@@ -0,0 +1,30 @@
+#set_property LOC R2 [get_ports led]
+#OBUF_6
+set_property DRIVE 12 [get_ports led[0]]
+#OBUF_7
+set_property IN_TERM UNTUNED_SPLIT_40 [get_ports led[1]]
+set_property SLEW FAST [get_ports led[1]]
+set_property IOSTANDARD SSTL135 [get_ports led[1]]
+#OBUF_OUT
+set_property IN_TERM UNTUNED_SPLIT_50 [get_ports out_a]
+set_property SLEW FAST [get_ports out_a]
+set_property IOSTANDARD LVCMOS33 [get_ports out_a]
+#bottom_inst.OBUF_10
+set_property SLEW SLOW [get_ports out_b[0]]
+set_property IOSTANDARD LVCMOS18 [get_ports out_b[0]]
+#bottom_inst.OBUF_11
+set_property DRIVE 4 [get_ports out_b[1]]
+set_property SLEW FAST [get_ports out_b[1]]
+set_property IOSTANDARD LVCMOS25 [get_ports out_b[1]]
+#bottom_inst.OBUF_9
+set_property SLEW FAST [get_ports led[2]]
+set_property IOSTANDARD DIFF_SSTL135 [get_ports led[2]]
+#bottom_intermediate_inst.OBUF_8
+set_property DRIVE 16 [get_ports led[3]]
+set_property IOSTANDARD SSTL135 [get_ports led[3]]
+#set_property INTERNAL_VREF 0.600 [get_iobanks 14]
+#set_property INTERNAL_VREF 0.675 [get_iobanks 15]
+#set_property INTERNAL_VREF 0.750 [get_iobanks 16]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 34]
+#set_property INTERNAL_VREF 0.900 [get_iobanks 35]
+
diff --git a/yosys-plugins/xdc/tests/xc7a35tcsg324-1.json b/yosys-plugins/xdc/tests/xc7a35tcsg324-1.json
new file mode 100644
index 000000000..602b949ab
--- /dev/null
+++ b/yosys-plugins/xdc/tests/xc7a35tcsg324-1.json
@@ -0,0 +1,10 @@
+{
+    "iobanks": {
+        "0": "X1Y78",
+        "14": "X1Y26",
+        "15": "X1Y78",
+        "16": "X1Y130",
+        "34": "X113Y26",
+        "35": "X113Y78"
+    }
+}
diff --git a/yosys-plugins/xdc/xdc.cc b/yosys-plugins/xdc/xdc.cc
new file mode 100644
index 000000000..bffdad99a
--- /dev/null
+++ b/yosys-plugins/xdc/xdc.cc
@@ -0,0 +1,458 @@
+/*
+ * Copyright 2020-2022 F4PGA Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ *  ---
+ *
+ *   XDC commands
+ *
+ *   This plugin operates on the existing design and modifies its structure
+ *   based on the content of the XDC (Xilinx Design Constraints) file.
+ *   Since the XDC file consists of Tcl commands it is read using Yosys's
+ *   Tcl interpreter and processed by the new XDC commands imported to the
+ *   Tcl interpreter.
+ */
+#include "../bank_tiles.h"
+#include "../utils.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+#include "libs/json11/json11.hpp"
+#include <cassert>
+
+USING_YOSYS_NAMESPACE
+
+PRIVATE_NAMESPACE_BEGIN
+
+static bool isInputPort(RTLIL::Wire *wire) { return wire->port_input; }
+static bool isOutputPort(RTLIL::Wire *wire) { return wire->port_output; }
+
+enum class SetPropertyOptions { INTERNAL_VREF, IOSTANDARD, SLEW, DRIVE, IN_TERM, IO_LOC_PAIRS };
+
+const std::unordered_map<std::string, SetPropertyOptions> set_property_options_map = {{"INTERNAL_VREF", SetPropertyOptions::INTERNAL_VREF},
+                                                                                      {"IOSTANDARD", SetPropertyOptions::IOSTANDARD},
+                                                                                      {"SLEW", SetPropertyOptions::SLEW},
+                                                                                      {"DRIVE", SetPropertyOptions::DRIVE},
+                                                                                      {"IN_TERM", SetPropertyOptions::IN_TERM},
+                                                                                      {"LOC", SetPropertyOptions::IO_LOC_PAIRS},
+                                                                                      {"PACKAGE_PIN", SetPropertyOptions::IO_LOC_PAIRS}};
+
+// Apart from the common I/OBUFs there is also the GTPE2_CHANNEL primitive which has a total
+// of four IOPADs (2 IPADs and 2 OPADs) which are directly connected to the GTP[RT]X[PN] ports
+// of the BEL. The GTPE2_CHANNEL holds all the placement constraints information of the
+// corresponding PADs
+const std::unordered_map<std::string, std::vector<std::string>> supported_primitive_parameters = {
+  {"OBUF", {"IO_LOC_PAIRS", "IOSTANDARD", "DRIVE", "SLEW", "IN_TERM"}},
+  {"OBUFDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
+  {"OBUFTDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
+  {"IBUF", {"IO_LOC_PAIRS", "IOSTANDARD"}},
+  {"IOBUF", {"IO_LOC_PAIRS", "IOSTANDARD", "DRIVE", "SLEW", "IN_TERM"}},
+  {"IOBUFDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
+  {"IBUFDS_GTE2", {"IO_LOC_PAIRS"}},
+  {"GTPE2_CHANNEL", {"IO_LOC_PAIRS"}}};
+
+void register_in_tcl_interpreter(const std::string &command)
+{
+    Tcl_Interp *interp = yosys_get_tcl_interp();
+    std::string tcl_script = stringf("proc %s args { return [yosys %s {*}$args] }", command.c_str(), command.c_str());
+    Tcl_Eval(interp, tcl_script.c_str());
+}
+
+struct GetIOBanks : public Pass {
+    GetIOBanks(std::function<const BankTilesMap &()> get_bank_tiles) : Pass("get_iobanks", "Set IO Bank number"), get_bank_tiles(get_bank_tiles)
+    {
+        register_in_tcl_interpreter(pass_name);
+    }
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("   get_iobanks <bank_number>\n");
+        log("\n");
+        log("Get IO Bank number\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *) override
+    {
+        if (args.size() < 2) {
+            log_cmd_error("%s: Missing bank number.\n", pass_name.c_str());
+        }
+        auto bank_tiles = get_bank_tiles();
+        if (bank_tiles.count(std::atoi(args[1].c_str())) == 0) {
+            log_cmd_error("%s:Bank number %s is not present in the target device.\n", args[1].c_str(), pass_name.c_str());
+        }
+
+        Tcl_Interp *interp = yosys_get_tcl_interp();
+        Tcl_SetResult(interp, const_cast<char *>(args[1].c_str()), NULL);
+        log("%s\n", args[1].c_str());
+    }
+
+    std::function<const BankTilesMap &()> get_bank_tiles;
+};
+
+struct SetProperty : public Pass {
+    SetProperty(std::function<const BankTilesMap &()> get_bank_tiles) : Pass("set_property", "Set a given property"), get_bank_tiles(get_bank_tiles)
+    {
+        register_in_tcl_interpreter(pass_name);
+    }
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    set_property PROPERTY VALUE OBJECT\n");
+        log("or\n");
+        log("    set_property -dict { PROPERTY VALUE PROPERTY2 VALUE2 } OBJECT\n");
+        log("\n");
+        log("Set the given property to the specified value on an object\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *design) override
+    {
+        if (design->top_module() == nullptr) {
+            log_cmd_error("No top module detected\n");
+        }
+        if (args.at(1) == "-dict") {
+            std::string dict_args = args.at(2);
+            trim(dict_args);
+            std::stringstream args_stream(dict_args);
+            std::vector<std::string> tokens;
+            std::string intermediate;
+            while (getline(args_stream, intermediate, ' ')) {
+                if (intermediate != "\0") {
+                    tokens.push_back(intermediate);
+                }
+            }
+            if (tokens.size() % 2 != 0) {
+                log_cmd_error("Invalid number of dict parameters: %lu.\n", tokens.size());
+            }
+            for (long unsigned int i = 0; i < tokens.size(); i += 2) {
+                std::vector<std::string> new_args(args);
+                new_args.at(1) = tokens[i];
+                new_args.at(2) = tokens[i + 1];
+                read_property(new_args, design);
+            }
+        } else {
+            read_property(args, design);
+        }
+    }
+
+    void read_property(std::vector<std::string> args, RTLIL::Design *design)
+    {
+        std::string option(args[1]);
+        if (set_property_options_map.count(option) == 0) {
+            log_warning("set_property: %s option is currently not supported\n", option.c_str());
+            return;
+        }
+
+        switch (set_property_options_map.at(option)) {
+        case SetPropertyOptions::INTERNAL_VREF:
+            process_vref(std::vector<std::string>(args.begin() + 2, args.end()), design);
+            break;
+        case SetPropertyOptions::IOSTANDARD:
+        case SetPropertyOptions::SLEW:
+        case SetPropertyOptions::DRIVE:
+        case SetPropertyOptions::IN_TERM:
+            process_port_parameter(std::vector<std::string>(args.begin() + 1, args.end()), design);
+            break;
+        case SetPropertyOptions::IO_LOC_PAIRS: {
+            // args "set_property LOC PAD PORT" become "IO_LOC_PAIRS PORT:PAD PORT"
+            std::vector<std::string> new_args(args.begin() + 1, args.end());
+            new_args.at(0) = "IO_LOC_PAIRS";
+            new_args.at(1) = new_args.at(2) + ":" + new_args.at(1);
+            process_port_parameter(new_args, design);
+            break;
+        }
+        default:
+            assert(false);
+        }
+    }
+
+    void process_vref(std::vector<std::string> args, RTLIL::Design *design)
+    {
+        if (args.size() < 2) {
+            log_error("set_property INTERNAL_VREF: Incorrect number of arguments.\n");
+        }
+        int iobank = std::atoi(args[1].c_str());
+        auto bank_tiles = get_bank_tiles();
+        if (bank_tiles.count(iobank) == 0) {
+            log_cmd_error("set_property INTERNAL_VREF: Invalid IO bank.\n");
+        }
+
+        int internal_vref = 1000 * std::atof(args[0].c_str());
+        if (internal_vref != 600 && internal_vref != 675 && internal_vref != 750 && internal_vref != 900) {
+            log("set_property INTERNAL_VREF: Incorrect INTERNAL_VREF value\n");
+            return;
+        }
+
+        // Create a new BANK module if it hasn't been created so far
+        RTLIL::Module *top_module = design->top_module();
+        if (!design->has(ID(BANK))) {
+            std::string fasm_extra_modules_dir(proc_share_dirname() + "/plugins/fasm_extra_modules");
+            Pass::call(design, "read_verilog " + fasm_extra_modules_dir + "/BANK.v");
+        }
+
+        // Set parameters on a new bank instance or update an existing one
+        char bank_cell_name[16];
+        snprintf(bank_cell_name, 16, "\\bank_cell_%d", iobank);
+        RTLIL::Cell *bank_cell = top_module->cell(RTLIL::IdString(bank_cell_name));
+        if (!bank_cell) {
+            bank_cell = top_module->addCell(RTLIL::IdString(bank_cell_name), ID(BANK));
+        }
+        bank_cell->setParam(ID(FASM_EXTRA), RTLIL::Const("INTERNAL_VREF"));
+        bank_cell->setParam(ID(NUMBER), RTLIL::Const(iobank));
+        bank_cell->setParam(ID(INTERNAL_VREF), RTLIL::Const(internal_vref));
+    }
+
+    void process_port_parameter(std::vector<std::string> args, RTLIL::Design *design)
+    {
+        if (args.size() < 1) {
+            log_error("set_property: Incorrect number of arguments.\n");
+        }
+
+        std::string parameter(args.at(0));
+        if (args.size() < 3 || args.at(2).size() == 0) {
+            log_error("set_property %s: Incorrect number of arguments.\n", parameter.c_str());
+        }
+
+        std::string port_name(args.at(2));
+        std::string value(args.at(1));
+
+        auto port_signal = extract_signal(port_name);
+        std::string port(port_signal.first);
+        int port_bit = port_signal.second;
+
+        RTLIL::Wire *wire = design->top_module()->wire(RTLIL::escape_id(port));
+        if (wire == nullptr) {
+            log_error("Couldn't find port %s\n", port_name.c_str());
+        }
+
+        if (!isInputPort(wire) && !isOutputPort(wire)) {
+            log_error("Port %s is not a top port\n", port_name.c_str());
+        }
+
+        if (port_bit < wire->start_offset || port_bit >= wire->start_offset + wire->width) {
+            log_error("Incorrect top port index %d in port %s\n", port_bit, port_name.c_str());
+        }
+
+        // Traverse the port wire
+        traverse_wire(port_name, design->top_module());
+
+        RTLIL::IdString parameter_id(RTLIL::escape_id(parameter));
+        for (auto cell_obj : design->top_module()->cells_) {
+            RTLIL::IdString cell_id = cell_obj.first;
+            RTLIL::Cell *cell = cell_obj.second;
+
+            // Check if the cell is of the type we are looking for
+            auto cell_type_str = RTLIL::unescape_id(cell->type.str());
+            auto primitive_parameters_iter = supported_primitive_parameters.find(cell_type_str);
+            if (primitive_parameters_iter == supported_primitive_parameters.end()) {
+                continue;
+            }
+
+            // Set the parameter on the cell connected to the selected port
+            for (auto connection : cell->connections_) {
+                RTLIL::SigSpec cell_signal = connection.second;
+                if (is_signal_port(cell_signal, port_name)) {
+                    // Check if the attribute is allowed for this module
+                    auto primitive_parameters = primitive_parameters_iter->second;
+                    if (std::find(primitive_parameters.begin(), primitive_parameters.end(), parameter) == primitive_parameters.end()) {
+                        log_error("Cell %s of type %s doesn't support the %s attribute\n", cell->name.c_str(), cell->type.c_str(),
+                                  parameter_id.c_str());
+                    }
+                    if (parameter_id == ID(IO_LOC_PAIRS) and cell->hasParam(parameter_id)) {
+                        std::string cur_value(cell->getParam(parameter_id).decode_string());
+                        value = cur_value + "," + value;
+                    }
+                    cell->setParam(parameter_id, RTLIL::Const(value));
+                    log("Setting parameter %s to value %s on cell %s \n", parameter_id.c_str(), value.c_str(), cell_obj.first.c_str());
+                }
+            }
+        }
+        log("\n");
+    }
+
+    // Search module's connections for the specified destination port
+    // and traverse from the specified destination wire to the source wire
+    void traverse_wire(std::string &port_name, RTLIL::Module *module)
+    {
+        auto port_signal = extract_signal(port_name);
+        std::string signal_name(port_signal.first);
+        auto signal_name_idstr = RTLIL::IdString(RTLIL::escape_id(signal_name));
+        int port_bit = port_signal.second;
+        for (auto connection : module->connections_) {
+            auto dst_sig = connection.first;
+            auto src_sig = connection.second;
+            if (dst_sig.is_chunk()) {
+                auto chunk = dst_sig.as_chunk();
+                if (chunk.wire) {
+                    if (chunk.wire->name != signal_name_idstr) {
+                        continue;
+                    }
+                    if (port_bit < chunk.offset || port_bit >= (chunk.offset + chunk.width)) {
+                        continue;
+                    }
+                    auto src_wires = src_sig.to_sigbit_vector();
+                    auto src_wire_sigbit = src_wires.at(port_bit - chunk.offset);
+                    if (src_wire_sigbit.wire) {
+                        port_name = src_wires.at(port_bit - chunk.offset).wire->name.str();
+                        if (src_wire_sigbit.offset > 0) {
+                            port_name += "[" + std::to_string(src_wire_sigbit.offset) + "]";
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    // Extract signal name and port bit information from port name
+    std::pair<std::string, int> extract_signal(const std::string &port_name)
+    {
+        int port_bit(0);
+        std::string port_str(port_name.size(), '\0');
+        sscanf(port_name.c_str(), "%[^[][%d]", &port_str[0], &port_bit);
+        port_str.resize(strlen(port_str.c_str()));
+        return std::make_pair(port_str, port_bit);
+    }
+
+    // Check if the specified port name is part of the provided connection signal
+    bool is_signal_port(RTLIL::SigSpec signal, const std::string &port_name)
+    {
+        auto port_signal = extract_signal(port_name);
+        std::string port(port_signal.first);
+        int port_bit = port_signal.second;
+        if (signal.is_chunk()) {
+            auto chunk = signal.as_chunk();
+            if (chunk.wire) {
+                // chunk.offset is always indexed from 0. Because of that port_bit must be
+                // corrected with the chunk.wire->start_offset of the port wire in case it is not 0-indexed.
+                // Not doing this would cause lack of some properties (e.g. IO_LOC_PAIRS) for
+                // non-0-indexed ports in final eblif file
+                return (chunk.wire->name == RTLIL::IdString(RTLIL::escape_id(port))) && ((port_bit - chunk.wire->start_offset) == chunk.offset);
+            }
+        }
+        return false;
+    }
+
+    std::function<const BankTilesMap &()> get_bank_tiles;
+};
+
+struct ReadXdc : public Frontend {
+    ReadXdc()
+        : Frontend("xdc", "Read XDC file"), GetIOBanks(std::bind(&ReadXdc::get_bank_tiles, this)),
+          SetProperty(std::bind(&ReadXdc::get_bank_tiles, this))
+    {
+    }
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("    read_xdc -part_json <part_json_filename> <filename>\n");
+        log("\n");
+        log("Read XDC file.\n");
+        log("\n");
+    }
+
+    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *) override
+    {
+        if (args.size() < 2) {
+            log_cmd_error("Missing script file.\n");
+        }
+        size_t argidx = 1;
+        bank_tiles.clear();
+        if (args[argidx] == "-part_json" && argidx + 1 < args.size()) {
+            bank_tiles = ::get_bank_tiles(args[++argidx]);
+            argidx++;
+        }
+        extra_args(f, filename, args, argidx);
+        std::string content{std::istreambuf_iterator<char>(*f), std::istreambuf_iterator<char>()};
+        log("%s\n", content.c_str());
+
+        // According to page 6 of UG903 XDC is tcl, hence quoting of bracketed numbers,
+        // such as bus indexes, is required. For example "signal[5]" would be typically
+        // expanded to the concatenation of the string "signal" and result of the function call "5"
+        // with no arguments. Therefore in TCL the signal indices have to be wrapped in curly braces
+        // e.g "{signal[5]}" in order for the interpreter to not perform any variable substitution
+        // or function calls on the wrapped content.
+        //
+        // Nevertheless, it's quite common for EDA tools to allow for specifying signal indices
+        // (e.g. "signal[5]") without using non-expanding quotes.
+        // Possible TCL implementations of such a feature include registering a TCL command
+        // for each integer which returns itself but surrounded with brackets or using the 'unknown'
+        // command which is invoked by the Tcl interpreter whenever a script tries to invoke a command
+        // that does not exist. In the XDC plugin the latter approach is used, however it's limited to
+        // the 'read_xdc' command, hence the 'unknown' command works solely on the content of the XDC file.
+        //
+        // In this implementation the signal "signal[5]" is expanded in TCL to the concatenation of a string
+        // and function call, however this time the handling of the non-existent command '5' is passed by
+        // the interpreter to the 'unknown' command which returns a string that consists of the indice
+        // integer surrounded by square brackets, i.e. "[5]", effectively expanding the signal to "signal[5]"
+        // string.
+        //
+        Tcl_Interp *interp = yosys_get_tcl_interp();
+        Tcl_Eval(interp, "rename unknown _original_unknown");
+        Tcl_Eval(interp, "proc unknown args { return \\[[lindex $args 0]\\] }");
+        if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
+            log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
+        }
+        Tcl_Eval(interp, "rename unknown \"\"");
+        Tcl_Eval(interp, "rename _original_unknown unknown");
+    }
+    const BankTilesMap &get_bank_tiles() { return bank_tiles; }
+
+    BankTilesMap bank_tiles;
+    struct GetIOBanks GetIOBanks;
+    struct SetProperty SetProperty;
+} ReadXdc;
+
+struct GetBankTiles : public Pass {
+    GetBankTiles() : Pass("get_bank_tiles", "Inspect IO Bank tiles") { register_in_tcl_interpreter(pass_name); }
+
+    void help() override
+    {
+        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+        log("\n");
+        log("   get_bank_tiles <part_json_file>\n");
+        log("\n");
+        log("Inspect IO Bank tiles for the specified part based on the provided JSON file.\n");
+        log("\n");
+    }
+
+    void execute(std::vector<std::string> args, RTLIL::Design *) override
+    {
+        if (args.size() < 2) {
+            log_cmd_error("Missing JSON file.\n");
+        }
+        // Check if the part has the specified bank
+        auto bank_tiles = get_bank_tiles(args[1]);
+        if (bank_tiles.size()) {
+            log("Available bank tiles:\n");
+            for (auto bank : bank_tiles) {
+                log("Bank: %d, Tile: %s\n", bank.first, bank.second.c_str());
+            }
+            log("\n");
+        } else {
+            log("No bank tiles available.\n");
+        }
+    }
+} GetBankTiles;
+
+PRIVATE_NAMESPACE_END