From 64bda94d6bfd2d447f0133954550df8c10f06899 Mon Sep 17 00:00:00 2001
From: sjthales <sebastien.jacq@thalesgroup.com>
Date: Fri, 4 Dec 2020 11:46:48 +0100
Subject: [PATCH] update to implement cv32a6 on zybo z7-20 board

---
 Makefile                                      |   17 +-
 fpga/Makefile                                 |   45 +-
 fpga/constraints/cva6_fpga.xdc                |   53 +
 fpga/constraints/zybo_z7_20.xdc               |   32 +
 fpga/openocd_diligent_hs2.cfg                 |   41 +
 fpga/scripts/program_cva6_fpga.tcl            |   13 +
 fpga/scripts/run_cva6_fpga.tcl                |  111 ++
 fpga/src/ariane_peripherals_xilinx.sv         |    2 +-
 fpga/src/ariane_xilinx.sv                     | 1459 -----------------
 fpga/src/cva6_zybo_z7_20.sv                   |  950 +++++++++++
 fpga/src/fan_ctrl.sv                          |   59 -
 fpga/src/genesysii.svh                        |   27 -
 fpga/src/kc705.svh                            |   27 -
 fpga/src/vc707.svh                            |   25 -
 fpga/src/vcu118.svh                           |   14 -
 fpga/src/zybo-z7-20.svh                       |    3 +
 fpga/xilinx/.gitignore                        |    5 +
 fpga/xilinx/ariane_xlnx_ip.yml                |   92 ++
 fpga/xilinx/common.mk                         |   19 +
 fpga/xilinx/xlnx_axi_clock_converter/Makefile |    2 +
 .../xlnx_axi_clock_converter/tcl/run.tcl      |   17 +
 .../Makefile                                  |    2 +
 .../tcl/run.tcl                               |   17 +
 .../Makefile                                  |    2 +
 .../tcl/run.tcl                               |   17 +
 fpga/xilinx/xlnx_blk_mem_gen/Makefile         |    2 +
 fpga/xilinx/xlnx_blk_mem_gen/tcl/run.tcl      |   37 +
 fpga/xilinx/xlnx_clk_gen/Makefile             |    2 +
 fpga/xilinx/xlnx_clk_gen/tcl/run.tcl          |   28 +
 src/ariane.sv                                 |   10 +-
 src/axi_adapter_32.sv                         |  348 ++++
 src/csr_regfile.sv                            |    1 +
 src/frontend/frontend.sv                      |    2 +-
 sw/bsp/config/fpga_platform_config.h          |    2 +-
 sw/bsp/config/link.ld                         |    2 +-
 tb/jtag_pkg.sv                                |  124 +-
 tb/tb_cva6_zybo_z7_20.sv                      |  236 +++
 37 files changed, 2209 insertions(+), 1636 deletions(-)
 create mode 100644 fpga/constraints/cva6_fpga.xdc
 create mode 100644 fpga/constraints/zybo_z7_20.xdc
 create mode 100644 fpga/openocd_diligent_hs2.cfg
 create mode 100644 fpga/scripts/program_cva6_fpga.tcl
 create mode 100644 fpga/scripts/run_cva6_fpga.tcl
 delete mode 100644 fpga/src/ariane_xilinx.sv
 create mode 100644 fpga/src/cva6_zybo_z7_20.sv
 delete mode 100644 fpga/src/fan_ctrl.sv
 delete mode 100644 fpga/src/genesysii.svh
 delete mode 100644 fpga/src/kc705.svh
 delete mode 100644 fpga/src/vc707.svh
 delete mode 100644 fpga/src/vcu118.svh
 create mode 100644 fpga/xilinx/.gitignore
 create mode 100644 fpga/xilinx/ariane_xlnx_ip.yml
 create mode 100644 fpga/xilinx/common.mk
 create mode 100644 fpga/xilinx/xlnx_axi_clock_converter/Makefile
 create mode 100644 fpga/xilinx/xlnx_axi_clock_converter/tcl/run.tcl
 create mode 100644 fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/Makefile
 create mode 100644 fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/tcl/run.tcl
 create mode 100644 fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/Makefile
 create mode 100644 fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/tcl/run.tcl
 create mode 100644 fpga/xilinx/xlnx_blk_mem_gen/Makefile
 create mode 100644 fpga/xilinx/xlnx_blk_mem_gen/tcl/run.tcl
 create mode 100644 fpga/xilinx/xlnx_clk_gen/Makefile
 create mode 100644 fpga/xilinx/xlnx_clk_gen/tcl/run.tcl
 create mode 100644 src/axi_adapter_32.sv
 create mode 100644 tb/tb_cva6_zybo_z7_20.sv

diff --git a/Makefile b/Makefile
index 2b08ebea..867b1fdd 100644
--- a/Makefile
+++ b/Makefile
@@ -288,7 +288,22 @@ cva6_ooc: $(ariane_pkg) $(util) $(src) $(fpga_src)
 	@echo read_verilog -sv {$(fpga_src)}   >> fpga/scripts/add_sources.tcl
 	cd fpga && make cva6_ooc BOARD=$(BOARD) XILINX_PART=$(XILINX_PART) XILINX_BOARD=$(XILINX_BOARD) CLK_PERIOD_NS=$(CLK_PERIOD_NS) BATCH_MODE=$(BATCH_MODE)
 
-.PHONY:  cva6_ooc
+.PHONY:  cva6_ooc cva6_fpga program_cva6_fpga
+
+cva6_fpga: $(ariane_pkg) $(util) $(src) $(fpga_src) $(uart_src)
+	@echo "[FPGA] Generate sources"
+	@echo read_vhdl        {$(uart_src)}    > fpga/scripts/add_sources.tcl
+	@echo read_verilog -sv {$(ariane_pkg)} >> fpga/scripts/add_sources.tcl
+	@echo read_verilog -sv {$(filter-out $(fpga_filter), $(util))}     >> fpga/scripts/add_sources.tcl
+	@echo read_verilog -sv {$(filter-out $(fpga_filter), $(src))} 	   >> fpga/scripts/add_sources.tcl
+	@echo read_verilog -sv {$(fpga_src)}   >> fpga/scripts/add_sources.tcl
+	@echo "[FPGA] Generate Bitstream"
+	cd fpga && make cva6_fpga BOARD=$(BOARD) XILINX_PART=$(XILINX_PART) XILINX_BOARD=$(XILINX_BOARD) CLK_PERIOD_NS=$(CLK_PERIOD_NS) BATCH_MODE=$(BATCH_MODE)
+
+
+program_cva6_fpga: 
+	@echo "[FPGA] Program FPGA"
+	cd fpga && make program_cva6_fpga BOARD=$(BOARD) XILINX_PART=$(XILINX_PART) XILINX_BOARD=$(XILINX_BOARD) CLK_PERIOD_NS=$(CLK_PERIOD_NS) BATCH_MODE=$(BATCH_MODE)
 
 clean:
 	rm -rf $(riscv-torture-dir)/output/test*
diff --git a/fpga/Makefile b/fpga/Makefile
index 13dbd64d..250952f4 100644
--- a/fpga/Makefile
+++ b/fpga/Makefile
@@ -29,15 +29,46 @@
 
 VIVADO ?= vivado
 
+work-dir := work-fpga
+bit := $(work-dir)/cva6_fpga.bit
+
+ip-dir := xilinx
+ips := xlnx_blk_mem_gen.xci  \
+       xlnx_axi_clock_converter.xci  \
+       xlnx_axi_dwidth_converter_dm_master.xci \
+       xlnx_axi_dwidth_converter_dm_slave.xci \
+       xlnx_clk_gen.xci             
+
 all: $(cva6_ooc)
 
 cva6_ooc: 
 ifeq ($(BATCH_MODE), 1)
 	$(VIVADO) -mode batch -source  scripts/run_cva6_ooc.tcl
 else
-	$(VIVADO) -source  scripts/run_cva6_ooc.tcl	
+	$(VIVADO) -source scripts/run_cva6_ooc.tcl	
+endif
+
+cva6_fpga: $(ips)
+ifeq ($(BATCH_MODE), 1)
+	mkdir -p $(work-dir)
+	$(VIVADO) -mode batch -source scripts/run_cva6_fpga.tcl
+else
+	$(VIVADO) -source scripts/run_cva6_fpga.tcl	
 endif
 
+program_cva6_fpga:
+ifeq ($(BATCH_MODE), 1)
+	$(VIVADO) -mode batch -source scripts/program_cva6_fpga.tcl
+else
+	$(VIVADO) -source scripts/program_cva6_fpga.tcl	
+endif
+
+
+$(ips): %.xci :
+	mkdir -p $(work-dir)
+	@echo Generating $(@F)
+	@cd $(ip-dir)/$(basename $(@F)) && make clean && make
+	@cp $(ip-dir)/$(basename $(@F))/ip/$(@F) $@
 
 clean:
 	rm -rf 	*.log \
@@ -45,15 +76,25 @@ clean:
 		*.str \
 		*.mif \
 		*.xpr \
+		*.xci \
 		cva6_ooc.cache \
 		cva6_ooc.hw \
 		cva6_ooc.ip_user_files \
 		cva6_ooc.sim \
 		cva6_ooc.runs \
 		cva6_ooc.hbs \
+		cva6_fpga.cache \
+		cva6_fpga.hw \
+		cva6_fpga.ip_user_files \
+		cva6_fpga.sim \
+		cva6_fpga.runs \
+		cva6_fpga.hbs \
 		.Xil \
 		reports_cva6_ooc_synth \
-		reports_cva6_ooc_impl 
+		reports_cva6_ooc_impl \
+		reports_cva6_fpga_synth \
+		reports_cva6_fpga_impl \
+		$(work-dir)
 
 
 .PHONY:
diff --git a/fpga/constraints/cva6_fpga.xdc b/fpga/constraints/cva6_fpga.xdc
new file mode 100644
index 00000000..5b30ffc3
--- /dev/null
+++ b/fpga/constraints/cva6_fpga.xdc
@@ -0,0 +1,53 @@
+## Common Ariane XDCs
+
+create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports tck]
+set_input_jitter tck 1.000
+set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_IBUF]
+
+# minimize routing delay
+set_input_delay -clock tck -clock_fall 5.000 [get_ports tdi]
+set_input_delay -clock tck -clock_fall 5.000 [get_ports tms]
+set_output_delay -clock tck 5.000 [get_ports tdo]
+set_false_path -from [get_ports trst_n]
+
+
+set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 20.000
+set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 20.000
+set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_src/ack_src_q_reg/D] 20.000
+
+# set multicycle path on reset, on the FPGA we do not care about the reset anyway
+set_multicycle_path -from [get_pins {i_rstgen_main/i_rstgen_bypass/synch_regs_q_reg[3]/C}] 4
+set_multicycle_path -hold -from [get_pins {i_rstgen_main/i_rstgen_bypass/synch_regs_q_reg[3]/C}] 3
+
+set_property MARK_DEBUG false [get_nets {debug_req[data][7]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][4]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][0]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][1]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][2]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][3]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][5]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][6]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][8]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][11]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][13]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][15]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][17]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][19]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][21]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][23]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][25]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][27]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][29]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][31]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][30]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][28]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][26]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][24]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][22]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][20]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][18]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][16]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][14]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][12]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][9]}]
+set_property MARK_DEBUG false [get_nets {debug_req[data][10]}]
diff --git a/fpga/constraints/zybo_z7_20.xdc b/fpga/constraints/zybo_z7_20.xdc
new file mode 100644
index 00000000..502343bc
--- /dev/null
+++ b/fpga/constraints/zybo_z7_20.xdc
@@ -0,0 +1,32 @@
+set_property PACKAGE_PIN K17 [get_ports clk_sys]
+set_property IOSTANDARD LVCMOS33 [get_ports clk_sys]
+
+## Buttons
+set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports cpu_reset]
+
+## To use FTDI FT2232 JTAG
+set_property -dict {PACKAGE_PIN V13 IOSTANDARD LVCMOS33} [get_ports trst_n]
+set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports tck]
+set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports tdi]
+set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports tdo]
+set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports tms]
+
+## UART
+set_property -dict {PACKAGE_PIN W8 IOSTANDARD LVCMOS33} [get_ports tx]
+set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS33} [get_ports rx]
+
+
+
+
+## JTAG
+# minimize routing delay
+
+set_max_delay -to [get_ports tdo] 20.000
+set_max_delay -from [get_ports tms] 20.000
+set_max_delay -from [get_ports tdi] 20.000
+set_max_delay -from [get_ports trst_n] 20.000
+
+# reset signal
+set_false_path -from [get_ports trst_n]
+
+
diff --git a/fpga/openocd_diligent_hs2.cfg b/fpga/openocd_diligent_hs2.cfg
new file mode 100644
index 00000000..be360d4b
--- /dev/null
+++ b/fpga/openocd_diligent_hs2.cfg
@@ -0,0 +1,41 @@
+
+
+# Digilent JTAG-HS2
+
+
+interface ftdi
+ftdi_device_desc "Digilent USB Device"
+ftdi_vid_pid 0x0403 0x6014
+ftdi_serial 210249A85F9B
+ftdi_channel 0						
+ftdi_layout_init 0x00e8 0x60eb
+
+reset_config none
+
+
+adapter_khz     1000
+
+
+# TAP declaration
+set _CHIPNAME riscv
+jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0
+
+gdb_report_data_abort enable
+gdb_report_register_access_error enable
+
+riscv set_reset_timeout_sec 120
+riscv set_command_timeout_sec 120
+
+# prefer to use sba for system bus access
+riscv set_prefer_sba on
+
+# dump jtag chain
+scan_chain
+bindto 0.0.0.0
+
+init
+halt
+echo "Ready for Remote Connections"
diff --git a/fpga/scripts/program_cva6_fpga.tcl b/fpga/scripts/program_cva6_fpga.tcl
new file mode 100644
index 00000000..4f1b3ed3
--- /dev/null
+++ b/fpga/scripts/program_cva6_fpga.tcl
@@ -0,0 +1,13 @@
+open_hw
+connect_hw_server
+current_hw_target [get_hw_targets -filter {NAME!~"localhost:3121/xilinx_tcf/Digilent/210249A85F9B"}]
+open_hw_target
+set_property PROGRAM.FILE {cva6_fpga.runs/impl_1/cva6_zybo_z7_20.bit} [get_hw_devices xc7z020_1]
+current_hw_device [get_hw_devices xc7z020_1]
+refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7z020_1] 0]
+set_property PROBES.FILE {} [get_hw_devices xc7z020_1]
+set_property FULL_PROBES.FILE {} [get_hw_devices xc7z020_1]
+set_property PROGRAM.FILE {cva6_fpga.runs/impl_1/cva6_zybo_z7_20.bit} [get_hw_devices xc7z020_1]
+program_hw_devices [get_hw_devices xc7z020_1]
+refresh_hw_device [lindex [get_hw_devices xc7z020_1] 0]
+
diff --git a/fpga/scripts/run_cva6_fpga.tcl b/fpga/scripts/run_cva6_fpga.tcl
new file mode 100644
index 00000000..9c5f07d3
--- /dev/null
+++ b/fpga/scripts/run_cva6_fpga.tcl
@@ -0,0 +1,111 @@
+# Copyright (c) 2020 Thales.
+# 
+# Copyright and related rights are licensed under the Solderpad
+# License, Version 2.0 (the "License"); you may not use this file except in
+# compliance with the License.  You may obtain a copy of the License at
+# http://solderpad.org/licenses/SHL-2.0/ Unless required by applicable law
+# or agreed to in writing, software, hardware and materials distributed under
+# this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+# Author:         Sebastien Jacq - sjthales on github.com
+
+#
+# Additional contributions by:
+#
+#
+# script Name:    run_cva6_fpga
+# Project Name:   CVA6 softcore
+# Language:       tcl
+#
+# Description:    Script to generate bitstream of CVA6 architecture
+#                 in Zybo 7-20 board
+#
+# =========================================================================== #
+# Revisions  :
+# Date        Version  Author       Description
+# 2020-11-06  0.1      S.Jacq       Created
+# =========================================================================== #
+set project cva6_fpga
+
+create_project $project . -force -part $::env(XILINX_PART)
+set_property board_part $::env(XILINX_BOARD) [current_project]
+
+
+
+# set number of threads to 8 (maximum, unfortunately)
+set_param general.maxThreads 8
+
+set_msg_config -id {[Synth 8-5858]} -new_severity "info"
+
+set_msg_config -id {[Synth 8-4480]} -limit 1000
+
+add_files -fileset constrs_1 -norecurse constraints/zybo_z7_20.xdc
+
+read_ip xilinx/xlnx_blk_mem_gen/ip/xlnx_blk_mem_gen.xci
+read_ip xilinx/xlnx_axi_clock_converter/ip/xlnx_axi_clock_converter.xci
+read_ip xilinx/xlnx_axi_dwidth_converter_dm_slave/ip/xlnx_axi_dwidth_converter_dm_slave.xci
+read_ip xilinx/xlnx_axi_dwidth_converter_dm_master/ip/xlnx_axi_dwidth_converter_dm_master.xci
+
+read_ip xilinx/xlnx_clk_gen/ip/xlnx_clk_gen.xci
+
+set_property include_dirs { "src/axi_sd_bridge/include" "../src/common_cells/include" } [current_fileset]
+
+source scripts/add_sources.tcl
+
+set_property top cva6_zybo_z7_20 [current_fileset]
+
+read_verilog -sv {src/zybo-z7-20.svh ../src/common_cells/include/common_cells/registers.svh}
+set file "src/zybo-z7-20.svh"
+set registers "../src/common_cells/include/common_cells/registers.svh"
+
+set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file" "$registers"]]
+set_property -dict { file_type {Verilog Header} is_global_include 1} -objects $file_obj
+
+update_compile_order -fileset sources_1
+
+add_files -fileset constrs_1 -norecurse constraints/$project.xdc
+
+synth_design -rtl -name rtl_1
+
+
+set_property STEPS.SYNTH_DESIGN.ARGS.RETIMING true [get_runs synth_1]
+
+launch_runs synth_1
+wait_on_run synth_1
+open_run synth_1
+
+exec mkdir -p reports_cva6_fpga_synth/
+exec rm -rf reports_cva6_fpga_synth/*
+
+
+check_timing -verbose                                                   -file reports_cva6_fpga_synth/$project.check_timing.rpt
+report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports_cva6_fpga_synth/$project.timing_WORST_100.rpt
+report_timing -nworst 1 -delay_type max -sort_by group                  -file reports_cva6_fpga_synth/$project.timing.rpt
+report_utilization -hierarchical                                        -file reports_cva6_fpga_synth/$project.utilization.rpt
+report_cdc                                                              -file reports_cva6_fpga_synth/$project.cdc.rpt
+report_clock_interaction                                                -file reports_cva6_fpga_synth/$project.clock_interaction.rpt
+
+# set for RuntimeOptimized implementation
+set_property "steps.place_design.args.directive" "RuntimeOptimized" [get_runs impl_1]
+set_property "steps.route_design.args.directive" "RuntimeOptimized" [get_runs impl_1]
+
+##create_clock -period $::env(CLK_PERIOD_NS) -name clk_i   [get_ports clk_i]
+
+#set_property HD.CLK_SRC BUFGCTRL_X1Y2 [get_ports clk_i]
+
+
+launch_runs impl_1
+wait_on_run impl_1
+launch_runs impl_1 -to_step write_bitstream
+wait_on_run impl_1
+open_run impl_1
+
+# reports
+exec mkdir -p reports_cva6_fpga_impl/
+exec rm -rf reports_cva6_fpga_impl/*
+check_timing                                                              -file reports_cva6_fpga_impl/${project}.check_timing.rpt
+report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack   -file reports_cva6_fpga_impl/${project}.timing_WORST_100.rpt
+report_timing -nworst 1 -delay_type max -sort_by group                    -file reports_cva6_fpga_impl/${project}.timing.rpt
+report_utilization -hierarchical                                          -file reports_cva6_fpga_impl/${project}.utilization.rpt
diff --git a/fpga/src/ariane_peripherals_xilinx.sv b/fpga/src/ariane_peripherals_xilinx.sv
index e551bdab..8eac9f6d 100644
--- a/fpga/src/ariane_peripherals_xilinx.sv
+++ b/fpga/src/ariane_peripherals_xilinx.sv
@@ -308,7 +308,7 @@ module ariane_peripherals #(
     // ---------------
     // 3. SPI
     // ---------------
-    assign spi.b_user = 1'b0;
+    //assign spi.b_user = 1'b0;
     assign spi.r_user = 1'b0;
 
     if (InclSPI) begin : gen_spi
diff --git a/fpga/src/ariane_xilinx.sv b/fpga/src/ariane_xilinx.sv
deleted file mode 100644
index e8c4d174..00000000
--- a/fpga/src/ariane_xilinx.sv
+++ /dev/null
@@ -1,1459 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: Xilinx FPGA top-level
-// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-
-module ariane_xilinx (
-`ifdef GENESYSII
-  input  logic         sys_clk_p   ,
-  input  logic         sys_clk_n   ,
-  input  logic         cpu_resetn  ,
-  inout  wire  [31:0]  ddr3_dq     ,
-  inout  wire  [ 3:0]  ddr3_dqs_n  ,
-  inout  wire  [ 3:0]  ddr3_dqs_p  ,
-  output logic [14:0]  ddr3_addr   ,
-  output logic [ 2:0]  ddr3_ba     ,
-  output logic         ddr3_ras_n  ,
-  output logic         ddr3_cas_n  ,
-  output logic         ddr3_we_n   ,
-  output logic         ddr3_reset_n,
-  output logic [ 0:0]  ddr3_ck_p   ,
-  output logic [ 0:0]  ddr3_ck_n   ,
-  output logic [ 0:0]  ddr3_cke    ,
-  output logic [ 0:0]  ddr3_cs_n   ,
-  output logic [ 3:0]  ddr3_dm     ,
-  output logic [ 0:0]  ddr3_odt    ,
-
-  output wire          eth_rst_n   ,
-  input  wire          eth_rxck    ,
-  input  wire          eth_rxctl   ,
-  input  wire [3:0]    eth_rxd     ,
-  output wire          eth_txck    ,
-  output wire          eth_txctl   ,
-  output wire [3:0]    eth_txd     ,
-  inout  wire          eth_mdio    ,
-  output logic         eth_mdc     ,
-  output logic [ 7:0]  led         ,
-  input  logic [ 7:0]  sw          ,
-  output logic         fan_pwm     ,
-  input  logic         trst_n      ,
-`elsif KC705
-  input  logic         sys_clk_p   ,
-  input  logic         sys_clk_n   ,
-
-  input  logic         cpu_reset   ,
-  inout  logic [63:0]  ddr3_dq     ,
-  inout  logic [ 7:0]  ddr3_dqs_n  ,
-  inout  logic [ 7:0]  ddr3_dqs_p  ,
-  output logic [13:0]  ddr3_addr   ,
-  output logic [ 2:0]  ddr3_ba     ,
-  output logic         ddr3_ras_n  ,
-  output logic         ddr3_cas_n  ,
-  output logic         ddr3_we_n   ,
-  output logic         ddr3_reset_n,
-  output logic [ 0:0]  ddr3_ck_p   ,
-  output logic [ 0:0]  ddr3_ck_n   ,
-  output logic [ 0:0]  ddr3_cke    ,
-  output logic [ 0:0]  ddr3_cs_n   ,
-  output logic [ 7:0]  ddr3_dm     ,
-  output logic [ 0:0]  ddr3_odt    ,
-
-  output wire          eth_rst_n   ,
-  input  wire          eth_rxck    ,
-  input  wire          eth_rxctl   ,
-  input  wire [3:0]    eth_rxd     ,
-  output wire          eth_txck    ,
-  output wire          eth_txctl   ,
-  output wire [3:0]    eth_txd     ,
-  inout  wire          eth_mdio    ,
-  output logic         eth_mdc     ,
-  output logic [ 3:0]  led         ,
-  input  logic [ 3:0]  sw          ,
-  output logic         fan_pwm     ,
-  input  logic         trst_n      ,
-`elsif VC707
-  input  logic         sys_clk_p   ,
-  input  logic         sys_clk_n   ,
-  input  logic         cpu_reset   ,
-  inout  wire  [63:0]  ddr3_dq     ,
-  inout  wire  [ 7:0]  ddr3_dqs_n  ,
-  inout  wire  [ 7:0]  ddr3_dqs_p  ,
-  output logic [13:0]  ddr3_addr   ,
-  output logic [ 2:0]  ddr3_ba     ,
-  output logic         ddr3_ras_n  ,
-  output logic         ddr3_cas_n  ,
-  output logic         ddr3_we_n   ,
-  output logic         ddr3_reset_n,
-  output logic [ 0:0]  ddr3_ck_p   ,
-  output logic [ 0:0]  ddr3_ck_n   ,
-  output logic [ 0:0]  ddr3_cke    ,
-  output logic [ 0:0]  ddr3_cs_n   ,
-  output logic [ 7:0]  ddr3_dm     ,
-  output logic [ 0:0]  ddr3_odt    ,
-  output wire          eth_rst_n   ,
-  input  wire          eth_rxck    ,
-  input  wire          eth_rxctl   ,
-  input  wire [3:0]    eth_rxd     ,
-  output wire          eth_txck    ,
-  output wire          eth_txctl   ,
-  output wire [3:0]    eth_txd     ,
-  inout  wire          eth_mdio    ,
-  output logic         eth_mdc     ,
-  output logic [ 7:0]  led         ,
-  input  logic [ 7:0]  sw          ,
-  output logic         fan_pwm     ,
-  input  logic         trst        ,
-`elsif VCU118
-  input  wire          c0_sys_clk_p    ,  // 250 MHz Clock for DDR
-  input  wire          c0_sys_clk_n    ,  // 250 MHz Clock for DDR
-  input  wire          sys_clk_p       ,  // 100 MHz Clock for PCIe
-  input  wire          sys_clk_n       ,  // 100 MHz Clock for PCIE
-  input  wire          sys_rst_n       ,  // PCIe Reset
-  input  logic         cpu_reset       ,  // CPU subsystem reset
-  output wire [16:0]   c0_ddr4_adr     ,
-  output wire [1:0]    c0_ddr4_ba      ,
-  output wire [0:0]    c0_ddr4_cke     ,
-  output wire [0:0]    c0_ddr4_cs_n    ,
-  inout  wire [7:0]    c0_ddr4_dm_dbi_n,
-  inout  wire [63:0]   c0_ddr4_dq      ,
-  inout  wire [7:0]    c0_ddr4_dqs_c   ,
-  inout  wire [7:0]    c0_ddr4_dqs_t   ,
-  output wire [0:0]    c0_ddr4_odt     ,
-  output wire [0:0]    c0_ddr4_bg      ,
-  output wire          c0_ddr4_reset_n ,
-  output wire          c0_ddr4_act_n   ,
-  output wire [0:0]    c0_ddr4_ck_c    ,
-  output wire [0:0]    c0_ddr4_ck_t    ,
-  output wire [7:0]    pci_exp_txp     ,
-  output wire [7:0]    pci_exp_txn     ,
-  input  wire [7:0]    pci_exp_rxp     ,
-  input  wire [7:0]    pci_exp_rxn     ,
-  input  logic         trst_n          ,
-`endif
-  // SPI
-  output logic        spi_mosi    ,
-  input  logic        spi_miso    ,
-  output logic        spi_ss      ,
-  output logic        spi_clk_o   ,
-  // common part
-  // input logic      trst_n      ,
-  input  logic        tck         ,
-  input  logic        tms         ,
-  input  logic        tdi         ,
-  output wire         tdo         ,
-  input  logic        rx          ,
-  output logic        tx
-);
-// 24 MByte in 8 byte words
-localparam NumWords = (24 * 1024 * 1024) / 8;
-localparam NBSlave = 2; // debug, ariane
-localparam AxiAddrWidth = 64;
-localparam AxiDataWidth = 64;
-localparam AxiIdWidthMaster = 4;
-localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
-localparam AxiUserWidth = 1;
-
-AXI_BUS #(
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_ID_WIDTH   ( AxiIdWidthMaster ),
-    .AXI_USER_WIDTH ( AxiUserWidth     )
-) slave[NBSlave-1:0]();
-
-AXI_BUS #(
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
-    .AXI_USER_WIDTH ( AxiUserWidth     )
-) master[ariane_soc::NB_PERIPHERALS-1:0]();
-
-// disable test-enable
-logic test_en;
-logic ndmreset;
-logic ndmreset_n;
-logic debug_req_irq;
-logic timer_irq;
-logic ipi;
-
-logic clk;
-logic eth_clk;
-logic spi_clk_i;
-logic phy_tx_clk;
-logic sd_clk_sys;
-
-logic ddr_sync_reset;
-logic ddr_clock_out;
-
-logic rst_n, rst;
-logic rtc;
-
-// we need to switch reset polarity
-`ifdef VCU118
-logic cpu_resetn;
-assign cpu_resetn = ~cpu_reset;
-`elsif GENESYSII
-logic cpu_reset;
-assign cpu_reset  = ~cpu_resetn;
-`elsif KC705
-assign cpu_resetn = ~cpu_reset;
-`elsif VC707
-assign cpu_resetn = ~cpu_reset;
-assign trst_n = ~trst;
-`endif
-
-logic pll_locked;
-
-// ROM
-logic                    rom_req;
-logic [AxiAddrWidth-1:0] rom_addr;
-logic [AxiDataWidth-1:0] rom_rdata;
-
-// Debug
-logic          debug_req_valid;
-logic          debug_req_ready;
-dm::dmi_req_t  debug_req;
-logic          debug_resp_valid;
-logic          debug_resp_ready;
-dm::dmi_resp_t debug_resp;
-
-logic dmactive;
-
-// IRQ
-logic [1:0] irq;
-assign test_en    = 1'b0;
-
-logic [NBSlave-1:0] pc_asserted;
-
-rstgen i_rstgen_main (
-    .clk_i        ( clk                      ),
-    .rst_ni       ( pll_locked & (~ndmreset) ),
-    .test_mode_i  ( test_en                  ),
-    .rst_no       ( ndmreset_n               ),
-    .init_no      (                          ) // keep open
-);
-
-assign rst_n = ~ddr_sync_reset;
-assign rst = ddr_sync_reset;
-
-// ---------------
-// AXI Xbar
-// ---------------
-axi_node_wrap_with_slices #(
-    // three ports from Ariane (instruction, data and bypass)
-    .NB_SLAVE           ( NBSlave                    ),
-    .NB_MASTER          ( ariane_soc::NB_PERIPHERALS ),
-    .NB_REGION          ( ariane_soc::NrRegion       ),
-    .AXI_ADDR_WIDTH     ( AxiAddrWidth               ),
-    .AXI_DATA_WIDTH     ( AxiDataWidth               ),
-    .AXI_USER_WIDTH     ( AxiUserWidth               ),
-    .AXI_ID_WIDTH       ( AxiIdWidthMaster           ),
-    .MASTER_SLICE_DEPTH ( 2                          ),
-    .SLAVE_SLICE_DEPTH  ( 2                          )
-) i_axi_xbar (
-    .clk          ( clk        ),
-    .rst_n        ( ndmreset_n ),
-    .test_en_i    ( test_en    ),
-    .slave        ( slave      ),
-    .master       ( master     ),
-    .start_addr_i ({
-        ariane_soc::DebugBase,
-        ariane_soc::ROMBase,
-        ariane_soc::CLINTBase,
-        ariane_soc::PLICBase,
-        ariane_soc::UARTBase,
-        ariane_soc::TimerBase,
-        ariane_soc::SPIBase,
-        ariane_soc::EthernetBase,
-        ariane_soc::GPIOBase,
-        ariane_soc::DRAMBase
-    }),
-    .end_addr_i   ({
-        ariane_soc::DebugBase    + ariane_soc::DebugLength - 1,
-        ariane_soc::ROMBase      + ariane_soc::ROMLength - 1,
-        ariane_soc::CLINTBase    + ariane_soc::CLINTLength - 1,
-        ariane_soc::PLICBase     + ariane_soc::PLICLength - 1,
-        ariane_soc::UARTBase     + ariane_soc::UARTLength - 1,
-        ariane_soc::TimerBase    + ariane_soc::TimerLength - 1,
-        ariane_soc::SPIBase      + ariane_soc::SPILength - 1,
-        ariane_soc::EthernetBase + ariane_soc::EthernetLength -1,
-        ariane_soc::GPIOBase     + ariane_soc::GPIOLength - 1,
-        ariane_soc::DRAMBase     + ariane_soc::DRAMLength - 1
-    }),
-    .valid_rule_i (ariane_soc::ValidRule)
-);
-
-// ---------------
-// Debug Module
-// ---------------
-dmi_jtag i_dmi_jtag (
-    .clk_i                ( clk                  ),
-    .rst_ni               ( rst_n                ),
-    .dmi_rst_no           (                      ), // keep open
-    .testmode_i           ( test_en              ),
-    .dmi_req_valid_o      ( debug_req_valid      ),
-    .dmi_req_ready_i      ( debug_req_ready      ),
-    .dmi_req_o            ( debug_req            ),
-    .dmi_resp_valid_i     ( debug_resp_valid     ),
-    .dmi_resp_ready_o     ( debug_resp_ready     ),
-    .dmi_resp_i           ( debug_resp           ),
-    .tck_i                ( tck    ),
-    .tms_i                ( tms    ),
-    .trst_ni              ( trst_n ),
-    .td_i                 ( tdi    ),
-    .td_o                 ( tdo    ),
-    .tdo_oe_o             (        )
-);
-
-ariane_axi::req_t    dm_axi_m_req;
-ariane_axi::resp_t   dm_axi_m_resp;
-
-logic                dm_slave_req;
-logic                dm_slave_we;
-logic [64-1:0]       dm_slave_addr;
-logic [64/8-1:0]     dm_slave_be;
-logic [64-1:0]       dm_slave_wdata;
-logic [64-1:0]       dm_slave_rdata;
-
-logic                dm_master_req;
-logic [64-1:0]       dm_master_add;
-logic                dm_master_we;
-logic [64-1:0]       dm_master_wdata;
-logic [64/8-1:0]     dm_master_be;
-logic                dm_master_gnt;
-logic                dm_master_r_valid;
-logic [64-1:0]       dm_master_r_rdata;
-
-// debug module
-dm_top #(
-    .NrHarts          ( 1                 ),
-    .BusWidth         ( AxiDataWidth      ),
-    .SelectableHarts  ( 1'b1              )
-) i_dm_top (
-    .clk_i            ( clk               ),
-    .rst_ni           ( rst_n             ), // PoR
-    .testmode_i       ( test_en           ),
-    .ndmreset_o       ( ndmreset          ),
-    .dmactive_o       ( dmactive          ), // active debug session
-    .debug_req_o      ( debug_req_irq     ),
-    .unavailable_i    ( '0                ),
-    .hartinfo_i       ( {ariane_pkg::DebugHartInfo} ),
-    .slave_req_i      ( dm_slave_req      ),
-    .slave_we_i       ( dm_slave_we       ),
-    .slave_addr_i     ( dm_slave_addr     ),
-    .slave_be_i       ( dm_slave_be       ),
-    .slave_wdata_i    ( dm_slave_wdata    ),
-    .slave_rdata_o    ( dm_slave_rdata    ),
-    .master_req_o     ( dm_master_req     ),
-    .master_add_o     ( dm_master_add     ),
-    .master_we_o      ( dm_master_we      ),
-    .master_wdata_o   ( dm_master_wdata   ),
-    .master_be_o      ( dm_master_be      ),
-    .master_gnt_i     ( dm_master_gnt     ),
-    .master_r_valid_i ( dm_master_r_valid ),
-    .master_r_rdata_i ( dm_master_r_rdata ),
-    .dmi_rst_ni       ( rst_n             ),
-    .dmi_req_valid_i  ( debug_req_valid   ),
-    .dmi_req_ready_o  ( debug_req_ready   ),
-    .dmi_req_i        ( debug_req         ),
-    .dmi_resp_valid_o ( debug_resp_valid  ),
-    .dmi_resp_ready_i ( debug_resp_ready  ),
-    .dmi_resp_o       ( debug_resp        )
-);
-
-axi2mem #(
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves    ),
-    .AXI_ADDR_WIDTH ( AxiAddrWidth        ),
-    .AXI_DATA_WIDTH ( AxiDataWidth        ),
-    .AXI_USER_WIDTH ( AxiUserWidth        )
-) i_dm_axi2mem (
-    .clk_i      ( clk                       ),
-    .rst_ni     ( rst_n                     ),
-    .slave      ( master[ariane_soc::Debug] ),
-    .req_o      ( dm_slave_req              ),
-    .we_o       ( dm_slave_we               ),
-    .addr_o     ( dm_slave_addr             ),
-    .be_o       ( dm_slave_be               ),
-    .data_o     ( dm_slave_wdata            ),
-    .data_i     ( dm_slave_rdata            )
-);
-
-axi_master_connect i_dm_axi_master_connect (
-  .axi_req_i(dm_axi_m_req),
-  .axi_resp_o(dm_axi_m_resp),
-  .master(slave[1])
-);
-
-axi_adapter #(
-    .DATA_WIDTH            ( AxiDataWidth              )
-) i_dm_axi_master (
-    .clk_i                 ( clk                       ),
-    .rst_ni                ( rst_n                     ),
-    .req_i                 ( dm_master_req             ),
-    .type_i                ( ariane_axi::SINGLE_REQ    ),
-    .gnt_o                 ( dm_master_gnt             ),
-    .gnt_id_o              (                           ),
-    .addr_i                ( dm_master_add             ),
-    .we_i                  ( dm_master_we              ),
-    .wdata_i               ( dm_master_wdata           ),
-    .be_i                  ( dm_master_be              ),
-    .size_i                ( 2'b11                     ), // always do 64bit here and use byte enables to gate
-    .id_i                  ( '0                        ),
-    .valid_o               ( dm_master_r_valid         ),
-    .rdata_o               ( dm_master_r_rdata         ),
-    .id_o                  (                           ),
-    .critical_word_o       (                           ),
-    .critical_word_valid_o (                           ),
-    .axi_req_o             ( dm_axi_m_req              ),
-    .axi_resp_i            ( dm_axi_m_resp             )
-);
-
-// ---------------
-// Core
-// ---------------
-ariane_axi::req_t    axi_ariane_req;
-ariane_axi::resp_t   axi_ariane_resp;
-
-ariane #(
-    .ArianeCfg ( ariane_soc::ArianeSocCfg )
-) i_ariane (
-    .clk_i        ( clk                 ),
-    .rst_ni       ( ndmreset_n          ),
-    .boot_addr_i  ( ariane_soc::ROMBase ), // start fetching from ROM
-    .hart_id_i    ( '0                  ),
-    .irq_i        ( irq                 ),
-    .ipi_i        ( ipi                 ),
-    .time_irq_i   ( timer_irq           ),
-    .debug_req_i  ( debug_req_irq       ),
-    .axi_req_o    ( axi_ariane_req      ),
-    .axi_resp_i   ( axi_ariane_resp     )
-);
-
-axi_master_connect i_axi_master_connect_ariane (.axi_req_i(axi_ariane_req), .axi_resp_o(axi_ariane_resp), .master(slave[0]));
-
-// ---------------
-// CLINT
-// ---------------
-// divide clock by two
-always_ff @(posedge clk or negedge ndmreset_n) begin
-  if (~ndmreset_n) begin
-    rtc <= 0;
-  end else begin
-    rtc <= rtc ^ 1'b1;
-  end
-end
-
-ariane_axi::req_t    axi_clint_req;
-ariane_axi::resp_t   axi_clint_resp;
-
-clint #(
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
-    .NR_CORES       ( 1                )
-) i_clint (
-    .clk_i       ( clk            ),
-    .rst_ni      ( ndmreset_n     ),
-    .testmode_i  ( test_en        ),
-    .axi_req_i   ( axi_clint_req  ),
-    .axi_resp_o  ( axi_clint_resp ),
-    .rtc_i       ( rtc            ),
-    .timer_irq_o ( timer_irq      ),
-    .ipi_o       ( ipi            )
-);
-
-axi_slave_connect i_axi_slave_connect_clint (.axi_req_o(axi_clint_req), .axi_resp_i(axi_clint_resp), .slave(master[ariane_soc::CLINT]));
-
-// ---------------
-// ROM
-// ---------------
-axi2mem #(
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_USER_WIDTH ( AxiUserWidth     )
-) i_axi2rom (
-    .clk_i  ( clk                     ),
-    .rst_ni ( ndmreset_n              ),
-    .slave  ( master[ariane_soc::ROM] ),
-    .req_o  ( rom_req                 ),
-    .we_o   (                         ),
-    .addr_o ( rom_addr                ),
-    .be_o   (                         ),
-    .data_o (                         ),
-    .data_i ( rom_rdata               )
-);
-
-bootrom i_bootrom (
-    .clk_i   ( clk       ),
-    .req_i   ( rom_req   ),
-    .addr_i  ( rom_addr  ),
-    .rdata_o ( rom_rdata )
-);
-
-// ---------------
-// Peripherals
-// ---------------
-`ifdef KC705
-  logic [7:0] unused_led;
-  logic [3:0] unused_switches = 4'b0000;
-`endif
-
-ariane_peripherals #(
-    .AxiAddrWidth ( AxiAddrWidth     ),
-    .AxiDataWidth ( AxiDataWidth     ),
-    .AxiIdWidth   ( AxiIdWidthSlaves ),
-    .AxiUserWidth ( AxiUserWidth     ),
-    .InclUART     ( 1'b1             ),
-    .InclGPIO     ( 1'b1             ),
-    `ifdef KINTEX7
-    .InclSPI      ( 1'b1         ),
-    .InclEthernet ( 1'b1         )
-    `elsif KC705
-    .InclSPI      ( 1'b1         ),
-    .InclEthernet ( 1'b0         ) // Ethernet requires RAMB16 fpga/src/ariane-ethernet/dualmem_widen8.sv to be defined
-    `elsif VC707
-    .InclSPI      ( 1'b1         ),
-    .InclEthernet ( 1'b0         )
-    `elsif VCU118
-    .InclSPI      ( 1'b0         ),
-    .InclEthernet ( 1'b0         )
-    `endif
-) i_ariane_peripherals (
-    .clk_i        ( clk                          ),
-    .clk_200MHz_i ( ddr_clock_out                ),
-    .rst_ni       ( ndmreset_n                   ),
-    .plic         ( master[ariane_soc::PLIC]     ),
-    .uart         ( master[ariane_soc::UART]     ),
-    .spi          ( master[ariane_soc::SPI]      ),
-    .gpio         ( master[ariane_soc::GPIO]     ),
-    .eth_clk_i    ( eth_clk                      ),
-    .ethernet     ( master[ariane_soc::Ethernet] ),
-    .timer        ( master[ariane_soc::Timer]    ),
-    .irq_o        ( irq                          ),
-    .rx_i         ( rx                           ),
-    .tx_o         ( tx                           ),
-    .eth_txck,
-    .eth_rxck,
-    .eth_rxctl,
-    .eth_rxd,
-    .eth_rst_n,
-    .eth_txctl,
-    .eth_txd,
-    .eth_mdio,
-    .eth_mdc,
-    .phy_tx_clk_i   ( phy_tx_clk                  ),
-    .sd_clk_i       ( sd_clk_sys                  ),
-    .spi_clk_o      ( spi_clk_o                   ),
-    .spi_mosi       ( spi_mosi                    ),
-    .spi_miso       ( spi_miso                    ),
-    .spi_ss         ( spi_ss                      ),
-    `ifdef KC705
-      .leds_o         ( {led[3:0], unused_led[7:4]}),
-      .dip_switches_i ( {sw, unused_switches}     )
-    `else
-      .leds_o         ( led                       ),
-      .dip_switches_i ( sw                        )
-    `endif
-);
-
-
-// ---------------------
-// Board peripherals
-// ---------------------
-// ---------------
-// DDR
-// ---------------
-logic [AxiIdWidthSlaves-1:0] s_axi_awid;
-logic [AxiAddrWidth-1:0]     s_axi_awaddr;
-logic [7:0]                  s_axi_awlen;
-logic [2:0]                  s_axi_awsize;
-logic [1:0]                  s_axi_awburst;
-logic [0:0]                  s_axi_awlock;
-logic [3:0]                  s_axi_awcache;
-logic [2:0]                  s_axi_awprot;
-logic [3:0]                  s_axi_awregion;
-logic [3:0]                  s_axi_awqos;
-logic                        s_axi_awvalid;
-logic                        s_axi_awready;
-logic [AxiDataWidth-1:0]     s_axi_wdata;
-logic [AxiDataWidth/8-1:0]   s_axi_wstrb;
-logic                        s_axi_wlast;
-logic                        s_axi_wvalid;
-logic                        s_axi_wready;
-logic [AxiIdWidthSlaves-1:0] s_axi_bid;
-logic [1:0]                  s_axi_bresp;
-logic                        s_axi_bvalid;
-logic                        s_axi_bready;
-logic [AxiIdWidthSlaves-1:0] s_axi_arid;
-logic [AxiAddrWidth-1:0]     s_axi_araddr;
-logic [7:0]                  s_axi_arlen;
-logic [2:0]                  s_axi_arsize;
-logic [1:0]                  s_axi_arburst;
-logic [0:0]                  s_axi_arlock;
-logic [3:0]                  s_axi_arcache;
-logic [2:0]                  s_axi_arprot;
-logic [3:0]                  s_axi_arregion;
-logic [3:0]                  s_axi_arqos;
-logic                        s_axi_arvalid;
-logic                        s_axi_arready;
-logic [AxiIdWidthSlaves-1:0] s_axi_rid;
-logic [AxiDataWidth-1:0]     s_axi_rdata;
-logic [1:0]                  s_axi_rresp;
-logic                        s_axi_rlast;
-logic                        s_axi_rvalid;
-logic                        s_axi_rready;
-
-AXI_BUS #(
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
-    .AXI_USER_WIDTH ( AxiUserWidth     )
-) dram();
-
-axi_riscv_atomics_wrap #(
-    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
-    .AXI_DATA_WIDTH ( AxiDataWidth     ),
-    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
-    .AXI_USER_WIDTH ( AxiUserWidth     ),
-    .AXI_MAX_WRITE_TXNS ( 1  ),
-    .RISCV_WORD_WIDTH   ( 64 )
-) i_axi_riscv_atomics (
-    .clk_i  ( clk                      ),
-    .rst_ni ( ndmreset_n               ),
-    .slv    ( master[ariane_soc::DRAM] ),
-    .mst    ( dram                     )
-);
-
-`ifdef PROTOCOL_CHECKER
-logic pc_status;
-
-xlnx_protocol_checker i_xlnx_protocol_checker (
-  .pc_status(),
-  .pc_asserted(pc_status),
-  .aclk(clk),
-  .aresetn(ndmreset_n),
-  .pc_axi_awid     (dram.aw_id),
-  .pc_axi_awaddr   (dram.aw_addr),
-  .pc_axi_awlen    (dram.aw_len),
-  .pc_axi_awsize   (dram.aw_size),
-  .pc_axi_awburst  (dram.aw_burst),
-  .pc_axi_awlock   (dram.aw_lock),
-  .pc_axi_awcache  (dram.aw_cache),
-  .pc_axi_awprot   (dram.aw_prot),
-  .pc_axi_awqos    (dram.aw_qos),
-  .pc_axi_awregion (dram.aw_region),
-  .pc_axi_awuser   (dram.aw_user),
-  .pc_axi_awvalid  (dram.aw_valid),
-  .pc_axi_awready  (dram.aw_ready),
-  .pc_axi_wlast    (dram.w_last),
-  .pc_axi_wdata    (dram.w_data),
-  .pc_axi_wstrb    (dram.w_strb),
-  .pc_axi_wuser    (dram.w_user),
-  .pc_axi_wvalid   (dram.w_valid),
-  .pc_axi_wready   (dram.w_ready),
-  .pc_axi_bid      (dram.b_id),
-  .pc_axi_bresp    (dram.b_resp),
-  .pc_axi_buser    (dram.b_user),
-  .pc_axi_bvalid   (dram.b_valid),
-  .pc_axi_bready   (dram.b_ready),
-  .pc_axi_arid     (dram.ar_id),
-  .pc_axi_araddr   (dram.ar_addr),
-  .pc_axi_arlen    (dram.ar_len),
-  .pc_axi_arsize   (dram.ar_size),
-  .pc_axi_arburst  (dram.ar_burst),
-  .pc_axi_arlock   (dram.ar_lock),
-  .pc_axi_arcache  (dram.ar_cache),
-  .pc_axi_arprot   (dram.ar_prot),
-  .pc_axi_arqos    (dram.ar_qos),
-  .pc_axi_arregion (dram.ar_region),
-  .pc_axi_aruser   (dram.ar_user),
-  .pc_axi_arvalid  (dram.ar_valid),
-  .pc_axi_arready  (dram.ar_ready),
-  .pc_axi_rid      (dram.r_id),
-  .pc_axi_rlast    (dram.r_last),
-  .pc_axi_rdata    (dram.r_data),
-  .pc_axi_rresp    (dram.r_resp),
-  .pc_axi_ruser    (dram.r_user),
-  .pc_axi_rvalid   (dram.r_valid),
-  .pc_axi_rready   (dram.r_ready)
-);
-`endif
-
-assign dram.r_user = '0;
-assign dram.b_user = '0;
-
-xlnx_axi_clock_converter i_xlnx_axi_clock_converter_ddr (
-  .s_axi_aclk     ( clk              ),
-  .s_axi_aresetn  ( ndmreset_n       ),
-  .s_axi_awid     ( dram.aw_id       ),
-  .s_axi_awaddr   ( dram.aw_addr     ),
-  .s_axi_awlen    ( dram.aw_len      ),
-  .s_axi_awsize   ( dram.aw_size     ),
-  .s_axi_awburst  ( dram.aw_burst    ),
-  .s_axi_awlock   ( dram.aw_lock     ),
-  .s_axi_awcache  ( dram.aw_cache    ),
-  .s_axi_awprot   ( dram.aw_prot     ),
-  .s_axi_awregion ( dram.aw_region   ),
-  .s_axi_awqos    ( dram.aw_qos      ),
-  .s_axi_awvalid  ( dram.aw_valid    ),
-  .s_axi_awready  ( dram.aw_ready    ),
-  .s_axi_wdata    ( dram.w_data      ),
-  .s_axi_wstrb    ( dram.w_strb      ),
-  .s_axi_wlast    ( dram.w_last      ),
-  .s_axi_wvalid   ( dram.w_valid     ),
-  .s_axi_wready   ( dram.w_ready     ),
-  .s_axi_bid      ( dram.b_id        ),
-  .s_axi_bresp    ( dram.b_resp      ),
-  .s_axi_bvalid   ( dram.b_valid     ),
-  .s_axi_bready   ( dram.b_ready     ),
-  .s_axi_arid     ( dram.ar_id       ),
-  .s_axi_araddr   ( dram.ar_addr     ),
-  .s_axi_arlen    ( dram.ar_len      ),
-  .s_axi_arsize   ( dram.ar_size     ),
-  .s_axi_arburst  ( dram.ar_burst    ),
-  .s_axi_arlock   ( dram.ar_lock     ),
-  .s_axi_arcache  ( dram.ar_cache    ),
-  .s_axi_arprot   ( dram.ar_prot     ),
-  .s_axi_arregion ( dram.ar_region   ),
-  .s_axi_arqos    ( dram.ar_qos      ),
-  .s_axi_arvalid  ( dram.ar_valid    ),
-  .s_axi_arready  ( dram.ar_ready    ),
-  .s_axi_rid      ( dram.r_id        ),
-  .s_axi_rdata    ( dram.r_data      ),
-  .s_axi_rresp    ( dram.r_resp      ),
-  .s_axi_rlast    ( dram.r_last      ),
-  .s_axi_rvalid   ( dram.r_valid     ),
-  .s_axi_rready   ( dram.r_ready     ),
-  // to size converter
-  .m_axi_aclk     ( ddr_clock_out    ),
-  .m_axi_aresetn  ( ndmreset_n       ),
-  .m_axi_awid     ( s_axi_awid       ),
-  .m_axi_awaddr   ( s_axi_awaddr     ),
-  .m_axi_awlen    ( s_axi_awlen      ),
-  .m_axi_awsize   ( s_axi_awsize     ),
-  .m_axi_awburst  ( s_axi_awburst    ),
-  .m_axi_awlock   ( s_axi_awlock     ),
-  .m_axi_awcache  ( s_axi_awcache    ),
-  .m_axi_awprot   ( s_axi_awprot     ),
-  .m_axi_awregion ( s_axi_awregion   ),
-  .m_axi_awqos    ( s_axi_awqos      ),
-  .m_axi_awvalid  ( s_axi_awvalid    ),
-  .m_axi_awready  ( s_axi_awready    ),
-  .m_axi_wdata    ( s_axi_wdata      ),
-  .m_axi_wstrb    ( s_axi_wstrb      ),
-  .m_axi_wlast    ( s_axi_wlast      ),
-  .m_axi_wvalid   ( s_axi_wvalid     ),
-  .m_axi_wready   ( s_axi_wready     ),
-  .m_axi_bid      ( s_axi_bid        ),
-  .m_axi_bresp    ( s_axi_bresp      ),
-  .m_axi_bvalid   ( s_axi_bvalid     ),
-  .m_axi_bready   ( s_axi_bready     ),
-  .m_axi_arid     ( s_axi_arid       ),
-  .m_axi_araddr   ( s_axi_araddr     ),
-  .m_axi_arlen    ( s_axi_arlen      ),
-  .m_axi_arsize   ( s_axi_arsize     ),
-  .m_axi_arburst  ( s_axi_arburst    ),
-  .m_axi_arlock   ( s_axi_arlock     ),
-  .m_axi_arcache  ( s_axi_arcache    ),
-  .m_axi_arprot   ( s_axi_arprot     ),
-  .m_axi_arregion ( s_axi_arregion   ),
-  .m_axi_arqos    ( s_axi_arqos      ),
-  .m_axi_arvalid  ( s_axi_arvalid    ),
-  .m_axi_arready  ( s_axi_arready    ),
-  .m_axi_rid      ( s_axi_rid        ),
-  .m_axi_rdata    ( s_axi_rdata      ),
-  .m_axi_rresp    ( s_axi_rresp      ),
-  .m_axi_rlast    ( s_axi_rlast      ),
-  .m_axi_rvalid   ( s_axi_rvalid     ),
-  .m_axi_rready   ( s_axi_rready     )
-);
-
-xlnx_clk_gen i_xlnx_clk_gen (
-  .clk_out1 ( clk           ), // 50 MHz
-  .clk_out2 ( phy_tx_clk    ), // 125 MHz (for RGMII PHY)
-  .clk_out3 ( eth_clk       ), // 125 MHz quadrature (90 deg phase shift)
-  .clk_out4 ( sd_clk_sys    ), // 50 MHz clock
-  .reset    ( cpu_reset     ),
-  .locked   ( pll_locked    ),
-  .clk_in1  ( ddr_clock_out )
-);
-
-`ifdef KINTEX7
-fan_ctrl i_fan_ctrl (
-    .clk_i         ( clk        ),
-    .rst_ni        ( ndmreset_n ),
-    .pwm_setting_i ( '1         ),
-    .fan_pwm_o     ( fan_pwm    )
-);
-
-xlnx_mig_7_ddr3 i_ddr (
-    .sys_clk_p,
-    .sys_clk_n,
-    .ddr3_dq,
-    .ddr3_dqs_n,
-    .ddr3_dqs_p,
-    .ddr3_addr,
-    .ddr3_ba,
-    .ddr3_ras_n,
-    .ddr3_cas_n,
-    .ddr3_we_n,
-    .ddr3_reset_n,
-    .ddr3_ck_p,
-    .ddr3_ck_n,
-    .ddr3_cke,
-    .ddr3_cs_n,
-    .ddr3_dm,
-    .ddr3_odt,
-    .mmcm_locked     (                ), // keep open
-    .app_sr_req      ( '0             ),
-    .app_ref_req     ( '0             ),
-    .app_zq_req      ( '0             ),
-    .app_sr_active   (                ), // keep open
-    .app_ref_ack     (                ), // keep open
-    .app_zq_ack      (                ), // keep open
-    .ui_clk          ( ddr_clock_out  ),
-    .ui_clk_sync_rst ( ddr_sync_reset ),
-    .aresetn         ( ndmreset_n     ),
-    .s_axi_awid,
-    .s_axi_awaddr    ( s_axi_awaddr[29:0] ),
-    .s_axi_awlen,
-    .s_axi_awsize,
-    .s_axi_awburst,
-    .s_axi_awlock,
-    .s_axi_awcache,
-    .s_axi_awprot,
-    .s_axi_awqos,
-    .s_axi_awvalid,
-    .s_axi_awready,
-    .s_axi_wdata,
-    .s_axi_wstrb,
-    .s_axi_wlast,
-    .s_axi_wvalid,
-    .s_axi_wready,
-    .s_axi_bready,
-    .s_axi_bid,
-    .s_axi_bresp,
-    .s_axi_bvalid,
-    .s_axi_arid,
-    .s_axi_araddr     ( s_axi_araddr[29:0] ),
-    .s_axi_arlen,
-    .s_axi_arsize,
-    .s_axi_arburst,
-    .s_axi_arlock,
-    .s_axi_arcache,
-    .s_axi_arprot,
-    .s_axi_arqos,
-    .s_axi_arvalid,
-    .s_axi_arready,
-    .s_axi_rready,
-    .s_axi_rid,
-    .s_axi_rdata,
-    .s_axi_rresp,
-    .s_axi_rlast,
-    .s_axi_rvalid,
-    .init_calib_complete (            ), // keep open
-    .device_temp         (            ), // keep open
-    .sys_rst             ( cpu_resetn )
-);
-`elsif VC707
-fan_ctrl i_fan_ctrl (
-    .clk_i         ( clk        ),
-    .rst_ni        ( ndmreset_n ),
-    .pwm_setting_i ( '1         ),
-    .fan_pwm_o     ( fan_pwm    )
-);
-
-xlnx_mig_7_ddr3 i_ddr (
-    .sys_clk_p,
-    .sys_clk_n,
-    .ddr3_dq,
-    .ddr3_dqs_n,
-    .ddr3_dqs_p,
-    .ddr3_addr,
-    .ddr3_ba,
-    .ddr3_ras_n,
-    .ddr3_cas_n,
-    .ddr3_we_n,
-    .ddr3_reset_n,
-    .ddr3_ck_p,
-    .ddr3_ck_n,
-    .ddr3_cke,
-    .ddr3_cs_n,
-    .ddr3_dm,
-    .ddr3_odt,
-    .mmcm_locked     (                ), // keep open
-    .app_sr_req      ( '0             ),
-    .app_ref_req     ( '0             ),
-    .app_zq_req      ( '0             ),
-    .app_sr_active   (                ), // keep open
-    .app_ref_ack     (                ), // keep open
-    .app_zq_ack      (                ), // keep open
-    .ui_clk          ( ddr_clock_out  ),
-    .ui_clk_sync_rst ( ddr_sync_reset ),
-    .aresetn         ( ndmreset_n     ),
-    .s_axi_awid,
-    .s_axi_awaddr    ( s_axi_awaddr[29:0] ),
-    .s_axi_awlen,
-    .s_axi_awsize,
-    .s_axi_awburst,
-    .s_axi_awlock,
-    .s_axi_awcache,
-    .s_axi_awprot,
-    .s_axi_awqos,
-    .s_axi_awvalid,
-    .s_axi_awready,
-    .s_axi_wdata,
-    .s_axi_wstrb,
-    .s_axi_wlast,
-    .s_axi_wvalid,
-    .s_axi_wready,
-    .s_axi_bready,
-    .s_axi_bid,
-    .s_axi_bresp,
-    .s_axi_bvalid,
-    .s_axi_arid,
-    .s_axi_araddr     ( s_axi_araddr[29:0] ),
-    .s_axi_arlen,
-    .s_axi_arsize,
-    .s_axi_arburst,
-    .s_axi_arlock,
-    .s_axi_arcache,
-    .s_axi_arprot,
-    .s_axi_arqos,
-    .s_axi_arvalid,
-    .s_axi_arready,
-    .s_axi_rready,
-    .s_axi_rid,
-    .s_axi_rdata,
-    .s_axi_rresp,
-    .s_axi_rlast,
-    .s_axi_rvalid,
-    .init_calib_complete (            ), // keep open
-    .device_temp         (            ), // keep open
-    .sys_rst             ( cpu_resetn )
-);
-`elsif VCU118
-
-  logic [63:0]  dram_dwidth_axi_awaddr;
-  logic [7:0]   dram_dwidth_axi_awlen;
-  logic [2:0]   dram_dwidth_axi_awsize;
-  logic [1:0]   dram_dwidth_axi_awburst;
-  logic [0:0]   dram_dwidth_axi_awlock;
-  logic [3:0]   dram_dwidth_axi_awcache;
-  logic [2:0]   dram_dwidth_axi_awprot;
-  logic [3:0]   dram_dwidth_axi_awqos;
-  logic         dram_dwidth_axi_awvalid;
-  logic         dram_dwidth_axi_awready;
-  logic [511:0] dram_dwidth_axi_wdata;
-  logic [63:0]  dram_dwidth_axi_wstrb;
-  logic         dram_dwidth_axi_wlast;
-  logic         dram_dwidth_axi_wvalid;
-  logic         dram_dwidth_axi_wready;
-  logic         dram_dwidth_axi_bready;
-  logic [1:0]   dram_dwidth_axi_bresp;
-  logic         dram_dwidth_axi_bvalid;
-  logic [63:0]  dram_dwidth_axi_araddr;
-  logic [7:0]   dram_dwidth_axi_arlen;
-  logic [2:0]   dram_dwidth_axi_arsize;
-  logic [1:0]   dram_dwidth_axi_arburst;
-  logic [0:0]   dram_dwidth_axi_arlock;
-  logic [3:0]   dram_dwidth_axi_arcache;
-  logic [2:0]   dram_dwidth_axi_arprot;
-  logic [3:0]   dram_dwidth_axi_arqos;
-  logic         dram_dwidth_axi_arvalid;
-  logic         dram_dwidth_axi_arready;
-  logic         dram_dwidth_axi_rready;
-  logic         dram_dwidth_axi_rlast;
-  logic         dram_dwidth_axi_rvalid;
-  logic [1:0]   dram_dwidth_axi_rresp;
-  logic [511:0] dram_dwidth_axi_rdata;
-
-axi_dwidth_converter_512_64 i_axi_dwidth_converter_512_64 (
-  .s_axi_aclk     ( ddr_clock_out            ),
-  .s_axi_aresetn  ( ndmreset_n               ),
-
-  .s_axi_awid     ( s_axi_awid               ),
-  .s_axi_awaddr   ( s_axi_awaddr             ),
-  .s_axi_awlen    ( s_axi_awlen              ),
-  .s_axi_awsize   ( s_axi_awsize             ),
-  .s_axi_awburst  ( s_axi_awburst            ),
-  .s_axi_awlock   ( s_axi_awlock             ),
-  .s_axi_awcache  ( s_axi_awcache            ),
-  .s_axi_awprot   ( s_axi_awprot             ),
-  .s_axi_awregion ( '0                       ),
-  .s_axi_awqos    ( s_axi_awqos              ),
-  .s_axi_awvalid  ( s_axi_awvalid            ),
-  .s_axi_awready  ( s_axi_awready            ),
-  .s_axi_wdata    ( s_axi_wdata              ),
-  .s_axi_wstrb    ( s_axi_wstrb              ),
-  .s_axi_wlast    ( s_axi_wlast              ),
-  .s_axi_wvalid   ( s_axi_wvalid             ),
-  .s_axi_wready   ( s_axi_wready             ),
-  .s_axi_bid      ( s_axi_bid                ),
-  .s_axi_bresp    ( s_axi_bresp              ),
-  .s_axi_bvalid   ( s_axi_bvalid             ),
-  .s_axi_bready   ( s_axi_bready             ),
-  .s_axi_arid     ( s_axi_arid               ),
-  .s_axi_araddr   ( s_axi_araddr             ),
-  .s_axi_arlen    ( s_axi_arlen              ),
-  .s_axi_arsize   ( s_axi_arsize             ),
-  .s_axi_arburst  ( s_axi_arburst            ),
-  .s_axi_arlock   ( s_axi_arlock             ),
-  .s_axi_arcache  ( s_axi_arcache            ),
-  .s_axi_arprot   ( s_axi_arprot             ),
-  .s_axi_arregion ( '0                       ),
-  .s_axi_arqos    ( s_axi_arqos              ),
-  .s_axi_arvalid  ( s_axi_arvalid            ),
-  .s_axi_arready  ( s_axi_arready            ),
-  .s_axi_rid      ( s_axi_rid                ),
-  .s_axi_rdata    ( s_axi_rdata              ),
-  .s_axi_rresp    ( s_axi_rresp              ),
-  .s_axi_rlast    ( s_axi_rlast              ),
-  .s_axi_rvalid   ( s_axi_rvalid             ),
-  .s_axi_rready   ( s_axi_rready             ),
-
-  .m_axi_awaddr   ( dram_dwidth_axi_awaddr   ),
-  .m_axi_awlen    ( dram_dwidth_axi_awlen    ),
-  .m_axi_awsize   ( dram_dwidth_axi_awsize   ),
-  .m_axi_awburst  ( dram_dwidth_axi_awburst  ),
-  .m_axi_awlock   ( dram_dwidth_axi_awlock   ),
-  .m_axi_awcache  ( dram_dwidth_axi_awcache  ),
-  .m_axi_awprot   ( dram_dwidth_axi_awprot   ),
-  .m_axi_awregion (                          ), // left open
-  .m_axi_awqos    ( dram_dwidth_axi_awqos    ),
-  .m_axi_awvalid  ( dram_dwidth_axi_awvalid  ),
-  .m_axi_awready  ( dram_dwidth_axi_awready  ),
-  .m_axi_wdata    ( dram_dwidth_axi_wdata    ),
-  .m_axi_wstrb    ( dram_dwidth_axi_wstrb    ),
-  .m_axi_wlast    ( dram_dwidth_axi_wlast    ),
-  .m_axi_wvalid   ( dram_dwidth_axi_wvalid   ),
-  .m_axi_wready   ( dram_dwidth_axi_wready   ),
-  .m_axi_bresp    ( dram_dwidth_axi_bresp    ),
-  .m_axi_bvalid   ( dram_dwidth_axi_bvalid   ),
-  .m_axi_bready   ( dram_dwidth_axi_bready   ),
-  .m_axi_araddr   ( dram_dwidth_axi_araddr   ),
-  .m_axi_arlen    ( dram_dwidth_axi_arlen    ),
-  .m_axi_arsize   ( dram_dwidth_axi_arsize   ),
-  .m_axi_arburst  ( dram_dwidth_axi_arburst  ),
-  .m_axi_arlock   ( dram_dwidth_axi_arlock   ),
-  .m_axi_arcache  ( dram_dwidth_axi_arcache  ),
-  .m_axi_arprot   ( dram_dwidth_axi_arprot   ),
-  .m_axi_arregion (                          ),
-  .m_axi_arqos    ( dram_dwidth_axi_arqos    ),
-  .m_axi_arvalid  ( dram_dwidth_axi_arvalid  ),
-  .m_axi_arready  ( dram_dwidth_axi_arready  ),
-  .m_axi_rdata    ( dram_dwidth_axi_rdata    ),
-  .m_axi_rresp    ( dram_dwidth_axi_rresp    ),
-  .m_axi_rlast    ( dram_dwidth_axi_rlast    ),
-  .m_axi_rvalid   ( dram_dwidth_axi_rvalid   ),
-  .m_axi_rready   ( dram_dwidth_axi_rready   )
-);
-
-  ddr4_0 i_ddr (
-    .c0_init_calib_complete (                              ),
-    .dbg_clk                (                              ),
-    .c0_sys_clk_p           ( c0_sys_clk_p                 ),
-    .c0_sys_clk_n           ( c0_sys_clk_n                 ),
-    .dbg_bus                (                              ),
-    .c0_ddr4_adr            ( c0_ddr4_adr                  ),
-    .c0_ddr4_ba             ( c0_ddr4_ba                   ),
-    .c0_ddr4_cke            ( c0_ddr4_cke                  ),
-    .c0_ddr4_cs_n           ( c0_ddr4_cs_n                 ),
-    .c0_ddr4_dm_dbi_n       ( c0_ddr4_dm_dbi_n             ),
-    .c0_ddr4_dq             ( c0_ddr4_dq                   ),
-    .c0_ddr4_dqs_c          ( c0_ddr4_dqs_c                ),
-    .c0_ddr4_dqs_t          ( c0_ddr4_dqs_t                ),
-    .c0_ddr4_odt            ( c0_ddr4_odt                  ),
-    .c0_ddr4_bg             ( c0_ddr4_bg                   ),
-    .c0_ddr4_reset_n        ( c0_ddr4_reset_n              ),
-    .c0_ddr4_act_n          ( c0_ddr4_act_n                ),
-    .c0_ddr4_ck_c           ( c0_ddr4_ck_c                 ),
-    .c0_ddr4_ck_t           ( c0_ddr4_ck_t                 ),
-    .c0_ddr4_ui_clk         ( ddr_clock_out                ),
-    .c0_ddr4_ui_clk_sync_rst( ddr_sync_reset               ),
-    .c0_ddr4_aresetn        ( ndmreset_n                   ),
-    .c0_ddr4_s_axi_awid     ( '0                           ),
-    .c0_ddr4_s_axi_awaddr   ( dram_dwidth_axi_awaddr[30:0] ),
-    .c0_ddr4_s_axi_awlen    ( dram_dwidth_axi_awlen        ),
-    .c0_ddr4_s_axi_awsize   ( dram_dwidth_axi_awsize       ),
-    .c0_ddr4_s_axi_awburst  ( dram_dwidth_axi_awburst      ),
-    .c0_ddr4_s_axi_awlock   ( dram_dwidth_axi_awlock       ),
-    .c0_ddr4_s_axi_awcache  ( dram_dwidth_axi_awcache      ),
-    .c0_ddr4_s_axi_awprot   ( dram_dwidth_axi_awprot       ),
-    .c0_ddr4_s_axi_awqos    ( dram_dwidth_axi_awqos        ),
-    .c0_ddr4_s_axi_awvalid  ( dram_dwidth_axi_awvalid      ),
-    .c0_ddr4_s_axi_awready  ( dram_dwidth_axi_awready      ),
-    .c0_ddr4_s_axi_wdata    ( dram_dwidth_axi_wdata        ),
-    .c0_ddr4_s_axi_wstrb    ( dram_dwidth_axi_wstrb        ),
-    .c0_ddr4_s_axi_wlast    ( dram_dwidth_axi_wlast        ),
-    .c0_ddr4_s_axi_wvalid   ( dram_dwidth_axi_wvalid       ),
-    .c0_ddr4_s_axi_wready   ( dram_dwidth_axi_wready       ),
-    .c0_ddr4_s_axi_bready   ( dram_dwidth_axi_bready       ),
-    .c0_ddr4_s_axi_bid      (                              ),
-    .c0_ddr4_s_axi_bresp    ( dram_dwidth_axi_bresp        ),
-    .c0_ddr4_s_axi_bvalid   ( dram_dwidth_axi_bvalid       ),
-    .c0_ddr4_s_axi_arid     ( '0                           ),
-    .c0_ddr4_s_axi_araddr   ( dram_dwidth_axi_araddr[30:0] ),
-    .c0_ddr4_s_axi_arlen    ( dram_dwidth_axi_arlen        ),
-    .c0_ddr4_s_axi_arsize   ( dram_dwidth_axi_arsize       ),
-    .c0_ddr4_s_axi_arburst  ( dram_dwidth_axi_arburst      ),
-    .c0_ddr4_s_axi_arlock   ( dram_dwidth_axi_arlock       ),
-    .c0_ddr4_s_axi_arcache  ( dram_dwidth_axi_arcache      ),
-    .c0_ddr4_s_axi_arprot   ( dram_dwidth_axi_arprot       ),
-    .c0_ddr4_s_axi_arqos    ( dram_dwidth_axi_arqos        ),
-    .c0_ddr4_s_axi_arvalid  ( dram_dwidth_axi_arvalid      ),
-    .c0_ddr4_s_axi_arready  ( dram_dwidth_axi_arready      ),
-    .c0_ddr4_s_axi_rready   ( dram_dwidth_axi_rready       ),
-    .c0_ddr4_s_axi_rlast    ( dram_dwidth_axi_rlast        ),
-    .c0_ddr4_s_axi_rvalid   ( dram_dwidth_axi_rvalid       ),
-    .c0_ddr4_s_axi_rresp    ( dram_dwidth_axi_rresp        ),
-    .c0_ddr4_s_axi_rid      (                              ),
-    .c0_ddr4_s_axi_rdata    ( dram_dwidth_axi_rdata        ),
-    .sys_rst                ( cpu_reset                    )
-  );
-
-
-  logic pcie_ref_clk;
-  logic pcie_ref_clk_gt;
-
-  logic pcie_axi_clk;
-  logic pcie_axi_rstn;
-
-  logic         pcie_axi_awready;
-  logic         pcie_axi_wready;
-  logic [3:0]   pcie_axi_bid;
-  logic [1:0]   pcie_axi_bresp;
-  logic         pcie_axi_bvalid;
-  logic         pcie_axi_arready;
-  logic [3:0]   pcie_axi_rid;
-  logic [255:0] pcie_axi_rdata;
-  logic [1:0]   pcie_axi_rresp;
-  logic         pcie_axi_rlast;
-  logic         pcie_axi_rvalid;
-  logic [3:0]   pcie_axi_awid;
-  logic [63:0]  pcie_axi_awaddr;
-  logic [7:0]   pcie_axi_awlen;
-  logic [2:0]   pcie_axi_awsize;
-  logic [1:0]   pcie_axi_awburst;
-  logic [2:0]   pcie_axi_awprot;
-  logic         pcie_axi_awvalid;
-  logic         pcie_axi_awlock;
-  logic [3:0]   pcie_axi_awcache;
-  logic [255:0] pcie_axi_wdata;
-  logic [31:0]  pcie_axi_wstrb;
-  logic         pcie_axi_wlast;
-  logic         pcie_axi_wvalid;
-  logic         pcie_axi_bready;
-  logic [3:0]   pcie_axi_arid;
-  logic [63:0]  pcie_axi_araddr;
-  logic [7:0]   pcie_axi_arlen;
-  logic [2:0]   pcie_axi_arsize;
-  logic [1:0]   pcie_axi_arburst;
-  logic [2:0]   pcie_axi_arprot;
-  logic         pcie_axi_arvalid;
-  logic         pcie_axi_arlock;
-  logic [3:0]   pcie_axi_arcache;
-  logic         pcie_axi_rready;
-
-  logic [63:0]  pcie_dwidth_axi_awaddr;
-  logic [7:0]   pcie_dwidth_axi_awlen;
-  logic [2:0]   pcie_dwidth_axi_awsize;
-  logic [1:0]   pcie_dwidth_axi_awburst;
-  logic [0:0]   pcie_dwidth_axi_awlock;
-  logic [3:0]   pcie_dwidth_axi_awcache;
-  logic [2:0]   pcie_dwidth_axi_awprot;
-  logic [3:0]   pcie_dwidth_axi_awregion;
-  logic [3:0]   pcie_dwidth_axi_awqos;
-  logic         pcie_dwidth_axi_awvalid;
-  logic         pcie_dwidth_axi_awready;
-  logic [63:0]  pcie_dwidth_axi_wdata;
-  logic [7:0]   pcie_dwidth_axi_wstrb;
-  logic         pcie_dwidth_axi_wlast;
-  logic         pcie_dwidth_axi_wvalid;
-  logic         pcie_dwidth_axi_wready;
-  logic [1:0]   pcie_dwidth_axi_bresp;
-  logic         pcie_dwidth_axi_bvalid;
-  logic         pcie_dwidth_axi_bready;
-  logic [63:0]  pcie_dwidth_axi_araddr;
-  logic [7:0]   pcie_dwidth_axi_arlen;
-  logic [2:0]   pcie_dwidth_axi_arsize;
-  logic [1:0]   pcie_dwidth_axi_arburst;
-  logic [0:0]   pcie_dwidth_axi_arlock;
-  logic [3:0]   pcie_dwidth_axi_arcache;
-  logic [2:0]   pcie_dwidth_axi_arprot;
-  logic [3:0]   pcie_dwidth_axi_arregion;
-  logic [3:0]   pcie_dwidth_axi_arqos;
-  logic         pcie_dwidth_axi_arvalid;
-  logic         pcie_dwidth_axi_arready;
-  logic [63:0]  pcie_dwidth_axi_rdata;
-  logic [1:0]   pcie_dwidth_axi_rresp;
-  logic         pcie_dwidth_axi_rlast;
-  logic         pcie_dwidth_axi_rvalid;
-  logic         pcie_dwidth_axi_rready;
-
-  // PCIe Reset
-  logic sys_rst_n_c;
-  IBUF sys_reset_n_ibuf (.O(sys_rst_n_c), .I(sys_rst_n));
-
-  IBUFDS_GTE4 #(
-    .REFCLK_HROW_CK_SEL ( 2'b00 )
-  ) IBUFDS_GTE4_inst (
-    .O     ( pcie_ref_clk_gt ),
-    .ODIV2 ( pcie_ref_clk    ),
-    .CEB   ( 1'b0            ),
-    .I     ( sys_clk_p       ),
-    .IB    ( sys_clk_n       )
-  );
-
-  // 250 MHz AXI
-  xdma_0 i_xdma (
-    .sys_clk                  ( pcie_ref_clk     ),
-    .sys_clk_gt               ( pcie_ref_clk_gt  ),
-    .sys_rst_n                ( sys_rst_n_c      ),
-    .user_lnk_up              (                  ),
-
-    // Tx
-    .pci_exp_txp              ( pci_exp_txp      ),
-    .pci_exp_txn              ( pci_exp_txn      ),
-    // Rx
-    .pci_exp_rxp              ( pci_exp_rxp      ),
-    .pci_exp_rxn              ( pci_exp_rxn      ),
-    .usr_irq_req              ( 1'b0             ),
-    .usr_irq_ack              (                  ),
-    .msi_enable               (                  ),
-    .msi_vector_width         (                  ),
-    .axi_aclk                 ( pcie_axi_clk     ),
-    .axi_aresetn              ( pcie_axi_rstn    ),
-    .m_axi_awready            ( pcie_axi_awready ),
-    .m_axi_wready             ( pcie_axi_wready  ),
-    .m_axi_bid                ( pcie_axi_bid     ),
-    .m_axi_bresp              ( pcie_axi_bresp   ),
-    .m_axi_bvalid             ( pcie_axi_bvalid  ),
-    .m_axi_arready            ( pcie_axi_arready ),
-    .m_axi_rid                ( pcie_axi_rid     ),
-    .m_axi_rdata              ( pcie_axi_rdata   ),
-    .m_axi_rresp              ( pcie_axi_rresp   ),
-    .m_axi_rlast              ( pcie_axi_rlast   ),
-    .m_axi_rvalid             ( pcie_axi_rvalid  ),
-    .m_axi_awid               ( pcie_axi_awid    ),
-    .m_axi_awaddr             ( pcie_axi_awaddr  ),
-    .m_axi_awlen              ( pcie_axi_awlen   ),
-    .m_axi_awsize             ( pcie_axi_awsize  ),
-    .m_axi_awburst            ( pcie_axi_awburst ),
-    .m_axi_awprot             ( pcie_axi_awprot  ),
-    .m_axi_awvalid            ( pcie_axi_awvalid ),
-    .m_axi_awlock             ( pcie_axi_awlock  ),
-    .m_axi_awcache            ( pcie_axi_awcache ),
-    .m_axi_wdata              ( pcie_axi_wdata   ),
-    .m_axi_wstrb              ( pcie_axi_wstrb   ),
-    .m_axi_wlast              ( pcie_axi_wlast   ),
-    .m_axi_wvalid             ( pcie_axi_wvalid  ),
-    .m_axi_bready             ( pcie_axi_bready  ),
-    .m_axi_arid               ( pcie_axi_arid    ),
-    .m_axi_araddr             ( pcie_axi_araddr  ),
-    .m_axi_arlen              ( pcie_axi_arlen   ),
-    .m_axi_arsize             ( pcie_axi_arsize  ),
-    .m_axi_arburst            ( pcie_axi_arburst ),
-    .m_axi_arprot             ( pcie_axi_arprot  ),
-    .m_axi_arvalid            ( pcie_axi_arvalid ),
-    .m_axi_arlock             ( pcie_axi_arlock  ),
-    .m_axi_arcache            ( pcie_axi_arcache ),
-    .m_axi_rready             ( pcie_axi_rready  ),
-
-    .cfg_mgmt_addr            ( '0               ),
-    .cfg_mgmt_write           ( '0               ),
-    .cfg_mgmt_write_data      ( '0               ),
-    .cfg_mgmt_byte_enable     ( '0               ),
-    .cfg_mgmt_read            ( '0               ),
-    .cfg_mgmt_read_data       (                  ),
-    .cfg_mgmt_read_write_done (                  )
-  );
-
-  axi_dwidth_converter_256_64 i_axi_dwidth_converter_256_64 (
-    .s_axi_aclk     ( pcie_axi_clk             ),
-    .s_axi_aresetn  ( pcie_axi_rstn            ),
-    .s_axi_awid     ( pcie_axi_awid            ),
-    .s_axi_awaddr   ( pcie_axi_awaddr          ),
-    .s_axi_awlen    ( pcie_axi_awlen           ),
-    .s_axi_awsize   ( pcie_axi_awsize          ),
-    .s_axi_awburst  ( pcie_axi_awburst         ),
-    .s_axi_awlock   ( pcie_axi_awlock          ),
-    .s_axi_awcache  ( pcie_axi_awcache         ),
-    .s_axi_awprot   ( pcie_axi_awprot          ),
-    .s_axi_awregion ( '0                       ),
-    .s_axi_awqos    ( '0                       ),
-    .s_axi_awvalid  ( pcie_axi_awvalid         ),
-    .s_axi_awready  ( pcie_axi_awready         ),
-    .s_axi_wdata    ( pcie_axi_wdata           ),
-    .s_axi_wstrb    ( pcie_axi_wstrb           ),
-    .s_axi_wlast    ( pcie_axi_wlast           ),
-    .s_axi_wvalid   ( pcie_axi_wvalid          ),
-    .s_axi_wready   ( pcie_axi_wready          ),
-    .s_axi_bid      ( pcie_axi_bid             ),
-    .s_axi_bresp    ( pcie_axi_rresp           ),
-    .s_axi_bvalid   ( pcie_axi_bvalid          ),
-    .s_axi_bready   ( pcie_axi_bready          ),
-    .s_axi_arid     ( pcie_axi_arid            ),
-    .s_axi_araddr   ( pcie_axi_araddr          ),
-    .s_axi_arlen    ( pcie_axi_arlen           ),
-    .s_axi_arsize   ( pcie_axi_arsize          ),
-    .s_axi_arburst  ( pcie_axi_arburst         ),
-    .s_axi_arlock   ( pcie_axi_arlock          ),
-    .s_axi_arcache  ( pcie_axi_arcache         ),
-    .s_axi_arprot   ( pcie_axi_arprot          ),
-    .s_axi_arregion ( '0                       ),
-    .s_axi_arqos    ( '0                       ),
-    .s_axi_arvalid  ( pcie_axi_arvalid         ),
-    .s_axi_arready  ( pcie_axi_arready         ),
-    .s_axi_rid      ( pcie_axi_rid             ),
-    .s_axi_rdata    ( pcie_axi_rdata           ),
-    .s_axi_rresp    ( pcie_axi_bresp           ),
-    .s_axi_rlast    ( pcie_axi_rlast           ),
-    .s_axi_rvalid   ( pcie_axi_rvalid          ),
-    .s_axi_rready   ( pcie_axi_rready          ),
-
-    .m_axi_awaddr   ( pcie_dwidth_axi_awaddr   ),
-    .m_axi_awlen    ( pcie_dwidth_axi_awlen    ),
-    .m_axi_awsize   ( pcie_dwidth_axi_awsize   ),
-    .m_axi_awburst  ( pcie_dwidth_axi_awburst  ),
-    .m_axi_awlock   ( pcie_dwidth_axi_awlock   ),
-    .m_axi_awcache  ( pcie_dwidth_axi_awcache  ),
-    .m_axi_awprot   ( pcie_dwidth_axi_awprot   ),
-    .m_axi_awregion ( pcie_dwidth_axi_awregion ),
-    .m_axi_awqos    ( pcie_dwidth_axi_awqos    ),
-    .m_axi_awvalid  ( pcie_dwidth_axi_awvalid  ),
-    .m_axi_awready  ( pcie_dwidth_axi_awready  ),
-    .m_axi_wdata    ( pcie_dwidth_axi_wdata    ),
-    .m_axi_wstrb    ( pcie_dwidth_axi_wstrb    ),
-    .m_axi_wlast    ( pcie_dwidth_axi_wlast    ),
-    .m_axi_wvalid   ( pcie_dwidth_axi_wvalid   ),
-    .m_axi_wready   ( pcie_dwidth_axi_wready   ),
-    .m_axi_bresp    ( pcie_dwidth_axi_bresp    ),
-    .m_axi_bvalid   ( pcie_dwidth_axi_bvalid   ),
-    .m_axi_bready   ( pcie_dwidth_axi_bready   ),
-    .m_axi_araddr   ( pcie_dwidth_axi_araddr   ),
-    .m_axi_arlen    ( pcie_dwidth_axi_arlen    ),
-    .m_axi_arsize   ( pcie_dwidth_axi_arsize   ),
-    .m_axi_arburst  ( pcie_dwidth_axi_arburst  ),
-    .m_axi_arlock   ( pcie_dwidth_axi_arlock   ),
-    .m_axi_arcache  ( pcie_dwidth_axi_arcache  ),
-    .m_axi_arprot   ( pcie_dwidth_axi_arprot   ),
-    .m_axi_arregion ( pcie_dwidth_axi_arregion ),
-    .m_axi_arqos    ( pcie_dwidth_axi_arqos    ),
-    .m_axi_arvalid  ( pcie_dwidth_axi_arvalid  ),
-    .m_axi_arready  ( pcie_dwidth_axi_arready  ),
-    .m_axi_rdata    ( pcie_dwidth_axi_rdata    ),
-    .m_axi_rresp    ( pcie_dwidth_axi_rresp    ),
-    .m_axi_rlast    ( pcie_dwidth_axi_rlast    ),
-    .m_axi_rvalid   ( pcie_dwidth_axi_rvalid   ),
-    .m_axi_rready   ( pcie_dwidth_axi_rready   )
-  );
-
-
-assign slave[1].aw_user = '0;
-assign slave[1].ar_user = '0;
-assign slave[1].w_user = '0;
-
-logic [3:0] slave_b_id;
-logic [3:0] slave_r_id;
-
-assign slave[1].b_id = slave_b_id[1:0];
-assign slave[1].r_id = slave_r_id[1:0];
-
-// PCIe Clock Converter
-axi_clock_converter_0 pcie_axi_clock_converter (
-  .m_axi_aclk     ( clk                      ),
-  .m_axi_aresetn  ( ndmreset_n               ),
-  .m_axi_awid     ( {2'b0, slave[1].aw_id} ),
-  .m_axi_awaddr   ( slave[1].aw_addr   ),
-  .m_axi_awlen    ( slave[1].aw_len    ),
-  .m_axi_awsize   ( slave[1].aw_size   ),
-  .m_axi_awburst  ( slave[1].aw_burst  ),
-  .m_axi_awlock   ( slave[1].aw_lock   ),
-  .m_axi_awcache  ( slave[1].aw_cache  ),
-  .m_axi_awprot   ( slave[1].aw_prot   ),
-  .m_axi_awregion ( slave[1].aw_region ),
-  .m_axi_awqos    ( slave[1].aw_qos    ),
-  .m_axi_awvalid  ( slave[1].aw_valid  ),
-  .m_axi_awready  ( slave[1].aw_ready  ),
-  .m_axi_wdata    ( slave[1].w_data    ),
-  .m_axi_wstrb    ( slave[1].w_strb    ),
-  .m_axi_wlast    ( slave[1].w_last    ),
-  .m_axi_wvalid   ( slave[1].w_valid   ),
-  .m_axi_wready   ( slave[1].w_ready   ),
-  .m_axi_bid      ( slave_b_id         ),
-  .m_axi_bresp    ( slave[1].b_resp    ),
-  .m_axi_bvalid   ( slave[1].b_valid   ),
-  .m_axi_bready   ( slave[1].b_ready   ),
-  .m_axi_arid     ( {2'b0, slave[1].ar_id} ),
-  .m_axi_araddr   ( slave[1].ar_addr   ),
-  .m_axi_arlen    ( slave[1].ar_len    ),
-  .m_axi_arsize   ( slave[1].ar_size   ),
-  .m_axi_arburst  ( slave[1].ar_burst  ),
-  .m_axi_arlock   ( slave[1].ar_lock   ),
-  .m_axi_arcache  ( slave[1].ar_cache  ),
-  .m_axi_arprot   ( slave[1].ar_prot   ),
-  .m_axi_arregion ( slave[1].ar_region ),
-  .m_axi_arqos    ( slave[1].ar_qos    ),
-  .m_axi_arvalid  ( slave[1].ar_valid  ),
-  .m_axi_arready  ( slave[1].ar_ready  ),
-  .m_axi_rid      ( slave_r_id         ),
-  .m_axi_rdata    ( slave[1].r_data    ),
-  .m_axi_rresp    ( slave[1].r_resp    ),
-  .m_axi_rlast    ( slave[1].r_last    ),
-  .m_axi_rvalid   ( slave[1].r_valid   ),
-  .m_axi_rready   ( slave[1].r_ready   ),
-  // from size converter
-  .s_axi_aclk     ( pcie_axi_clk             ),
-  .s_axi_aresetn  ( ndmreset_n               ),
-  .s_axi_awid     ( '0                       ),
-  .s_axi_awaddr   ( pcie_dwidth_axi_awaddr   ),
-  .s_axi_awlen    ( pcie_dwidth_axi_awlen    ),
-  .s_axi_awsize   ( pcie_dwidth_axi_awsize   ),
-  .s_axi_awburst  ( pcie_dwidth_axi_awburst  ),
-  .s_axi_awlock   ( pcie_dwidth_axi_awlock   ),
-  .s_axi_awcache  ( pcie_dwidth_axi_awcache  ),
-  .s_axi_awprot   ( pcie_dwidth_axi_awprot   ),
-  .s_axi_awregion ( pcie_dwidth_axi_awregion ),
-  .s_axi_awqos    ( pcie_dwidth_axi_awqos    ),
-  .s_axi_awvalid  ( pcie_dwidth_axi_awvalid  ),
-  .s_axi_awready  ( pcie_dwidth_axi_awready  ),
-  .s_axi_wdata    ( pcie_dwidth_axi_wdata    ),
-  .s_axi_wstrb    ( pcie_dwidth_axi_wstrb    ),
-  .s_axi_wlast    ( pcie_dwidth_axi_wlast    ),
-  .s_axi_wvalid   ( pcie_dwidth_axi_wvalid   ),
-  .s_axi_wready   ( pcie_dwidth_axi_wready   ),
-  .s_axi_bid      (                          ),
-  .s_axi_bresp    ( pcie_dwidth_axi_bresp    ),
-  .s_axi_bvalid   ( pcie_dwidth_axi_bvalid   ),
-  .s_axi_bready   ( pcie_dwidth_axi_bready   ),
-  .s_axi_arid     ( '0                       ),
-  .s_axi_araddr   ( pcie_dwidth_axi_araddr   ),
-  .s_axi_arlen    ( pcie_dwidth_axi_arlen    ),
-  .s_axi_arsize   ( pcie_dwidth_axi_arsize   ),
-  .s_axi_arburst  ( pcie_dwidth_axi_arburst  ),
-  .s_axi_arlock   ( pcie_dwidth_axi_arlock   ),
-  .s_axi_arcache  ( pcie_dwidth_axi_arcache  ),
-  .s_axi_arprot   ( pcie_dwidth_axi_arprot   ),
-  .s_axi_arregion ( pcie_dwidth_axi_arregion ),
-  .s_axi_arqos    ( pcie_dwidth_axi_arqos    ),
-  .s_axi_arvalid  ( pcie_dwidth_axi_arvalid  ),
-  .s_axi_arready  ( pcie_dwidth_axi_arready  ),
-  .s_axi_rid      (                          ),
-  .s_axi_rdata    ( pcie_dwidth_axi_rdata    ),
-  .s_axi_rresp    ( pcie_dwidth_axi_rresp    ),
-  .s_axi_rlast    ( pcie_dwidth_axi_rlast    ),
-  .s_axi_rvalid   ( pcie_dwidth_axi_rvalid   ),
-  .s_axi_rready   ( pcie_dwidth_axi_rready   )
-);
-`endif
-
-endmodule
diff --git a/fpga/src/cva6_zybo_z7_20.sv b/fpga/src/cva6_zybo_z7_20.sv
new file mode 100644
index 00000000..66c4c0c6
--- /dev/null
+++ b/fpga/src/cva6_zybo_z7_20.sv
@@ -0,0 +1,950 @@
+
+
+module cva6_zybo_z7_20 (
+
+//  input  logic          USER_SI570_P,
+//  input  logic          USER_SI570_N,
+
+input  logic          clk_sys,
+
+  input  logic         cpu_reset   ,
+//  output logic [ 7:0]  led         ,
+//  input  logic [ 7:0]  sw          ,
+
+
+
+  // common part
+   input logic      trst_n      ,
+  input  logic        tck         ,
+  input  logic        tms         ,
+  input  logic        tdi         ,
+  output wire         tdo         ,
+  input  logic        rx          ,
+  output logic        tx
+);
+// 24 MByte in 8 byte words
+localparam NumWords = (24 * 1024 * 1024) / 8;
+localparam NBSlave = 2; // debug, ariane
+localparam AxiAddrWidth = 64;
+localparam AxiDataWidth = 64;
+localparam AxiIdWidthMaster = 4;
+localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 5
+localparam AxiUserWidth = 1;
+
+AXI_BUS #(
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthMaster ),
+    .AXI_USER_WIDTH ( AxiUserWidth     )
+) slave[NBSlave-1:0]();
+
+AXI_BUS #(
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .AXI_USER_WIDTH ( AxiUserWidth     )
+) master[ariane_soc::NB_PERIPHERALS-1:0]();
+
+AXI_BUS #(
+    .AXI_ADDR_WIDTH ( 32     ),
+    .AXI_DATA_WIDTH ( 32     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .AXI_USER_WIDTH ( AxiUserWidth     )
+) master_to_dm[0:0]();
+
+// disable test-enable
+logic test_en;
+logic ndmreset;
+logic ndmreset_n;
+logic debug_req_irq;
+logic time_irq;
+logic ipi;
+
+logic clk;
+logic eth_clk;
+logic spi_clk_i;
+logic phy_tx_clk;
+logic sd_clk_sys;
+
+
+logic ps_clock_out;
+
+logic rst_n, rst;
+logic rtc;
+
+
+//assign trst_n = 1'b1;
+//assign trst_n = ndmreset_n;
+
+logic pll_locked;
+
+// ROM
+logic                    rom_req;
+logic [AxiAddrWidth-1:0] rom_addr;
+logic [AxiDataWidth-1:0] rom_rdata;
+
+// Debug
+logic          debug_req_valid;
+logic          debug_req_ready;
+dm::dmi_req_t  debug_req;
+logic          debug_resp_valid;
+logic          debug_resp_ready;
+dm::dmi_resp_t debug_resp;
+
+logic dmactive;
+
+// IRQ
+logic [1:0] irq;
+assign test_en    = 1'b0;
+
+logic [NBSlave-1:0] pc_asserted;
+
+logic dmi_trst_n;
+
+rstgen i_rstgen_main (
+    .clk_i        ( clk                      ),
+    .rst_ni       ( pll_locked & (~ndmreset) ),
+    .test_mode_i  ( test_en                  ),
+    .rst_no       ( ndmreset_n               ),
+    .init_no      (                          ) // keep open
+);
+
+
+
+//assign rst_n = ndmreset_n;
+//assign rst = ~ndmreset_n;
+
+assign rst_n = ~cpu_reset;
+assign rst = cpu_reset;
+
+// ---------------
+// AXI Xbar
+// ---------------
+axi_node_wrap_with_slices #(
+    // three ports from Ariane (instruction, data and bypass)
+    .NB_SLAVE           ( NBSlave                    ),
+    .NB_MASTER          ( ariane_soc::NB_PERIPHERALS ),
+    .NB_REGION          ( ariane_soc::NrRegion       ),
+    .AXI_ADDR_WIDTH     ( AxiAddrWidth               ),
+    .AXI_DATA_WIDTH     ( AxiDataWidth               ),
+    .AXI_USER_WIDTH     ( AxiUserWidth               ),
+    .AXI_ID_WIDTH       ( AxiIdWidthMaster           ),
+    .MASTER_SLICE_DEPTH ( 2                          ),
+    .SLAVE_SLICE_DEPTH  ( 2                          )
+) i_axi_xbar (
+    .clk          ( clk        ),
+    .rst_n        ( ndmreset_n ),
+    .test_en_i    ( test_en    ),
+    .slave        ( slave      ),
+    .master       ( master     ),
+    .start_addr_i ({
+        ariane_soc::DebugBase,
+        ariane_soc::ROMBase,
+        ariane_soc::CLINTBase,
+        ariane_soc::PLICBase,
+        ariane_soc::UARTBase,
+        ariane_soc::TimerBase,
+        ariane_soc::SPIBase,
+        ariane_soc::EthernetBase,
+        ariane_soc::GPIOBase,
+        ariane_soc::DRAMBase
+    }),
+    .end_addr_i   ({
+        ariane_soc::DebugBase    + ariane_soc::DebugLength - 1,
+        ariane_soc::ROMBase      + ariane_soc::ROMLength - 1,
+        ariane_soc::CLINTBase    + ariane_soc::CLINTLength - 1,
+        ariane_soc::PLICBase     + ariane_soc::PLICLength - 1,
+        ariane_soc::UARTBase     + ariane_soc::UARTLength - 1,
+        ariane_soc::TimerBase    + ariane_soc::TimerLength - 1,
+        ariane_soc::SPIBase      + ariane_soc::SPILength - 1,
+        ariane_soc::EthernetBase + ariane_soc::EthernetLength -1,
+        ariane_soc::GPIOBase     + ariane_soc::GPIOLength - 1,
+        ariane_soc::DRAMBase     + ariane_soc::DRAMLength - 1
+    }),
+    .valid_rule_i (ariane_soc::ValidRule)
+);
+
+`ifdef LAUTERBACH_DEBUG_PROBE
+  assign dmi_trst_n = trst_n;
+`else
+  assign dmi_trst_n = 1'b1;
+`endif
+
+// ---------------
+// Debug Module
+// ---------------
+dmi_jtag  #(
+        .IdcodeValue          ( 32'h249511C3    )
+    )i_dmi_jtag (
+    .clk_i                ( clk                  ),
+    .rst_ni               ( rst_n                ),
+    .dmi_rst_no           (                      ), // keep open
+    .testmode_i           ( test_en              ),
+    .dmi_req_valid_o      ( debug_req_valid      ),
+    .dmi_req_ready_i      ( debug_req_ready      ),
+    .dmi_req_o            ( debug_req            ),
+    .dmi_resp_valid_i     ( debug_resp_valid     ),
+    .dmi_resp_ready_o     ( debug_resp_ready     ),
+    .dmi_resp_i           ( debug_resp           ),
+    .tck_i                ( tck    ),
+    .tms_i                ( tms    ),
+    //.trst_ni              ( trst_n ),
+    .trst_ni              ( dmi_trst_n ),
+    .td_i                 ( tdi    ),
+    .td_o                 ( tdo    ),
+    .tdo_oe_o             (        )
+);
+
+ariane_axi::req_t    dm_axi_m_req;
+ariane_axi::resp_t   dm_axi_m_resp;
+
+logic                dm_slave_req;
+logic                dm_slave_we;
+logic [32-1:0]       dm_slave_addr;
+logic [32/8-1:0]     dm_slave_be;
+logic [32-1:0]       dm_slave_wdata;
+logic [32-1:0]       dm_slave_rdata;
+
+logic                dm_master_req;
+logic [32-1:0]       dm_master_add;
+logic                dm_master_we;
+logic [32-1:0]       dm_master_wdata;
+logic [32/8-1:0]     dm_master_be;
+logic                dm_master_gnt;
+logic                dm_master_r_valid;
+logic [32-1:0]       dm_master_r_rdata;
+
+// debug module
+dm_top #(
+    .NrHarts          ( 1                 ),
+    .BusWidth         ( 32      ),
+    .SelectableHarts  ( 1'b1              )
+) i_dm_top (
+    .clk_i            ( clk               ),
+    .rst_ni           ( rst_n             ), // PoR
+    .testmode_i       ( test_en           ),
+    .ndmreset_o       ( ndmreset          ),
+    .dmactive_o       ( dmactive          ), // active debug session
+    .debug_req_o      ( debug_req_irq     ),
+    .unavailable_i    ( '0                ),
+    .hartinfo_i       ( {ariane_pkg::DebugHartInfo} ),
+    .slave_req_i      ( dm_slave_req      ),
+    .slave_we_i       ( dm_slave_we       ),
+    .slave_addr_i     ( dm_slave_addr     ),
+    .slave_be_i       ( dm_slave_be       ),
+    .slave_wdata_i    ( dm_slave_wdata    ),
+    .slave_rdata_o    ( dm_slave_rdata    ),
+    .master_req_o     ( dm_master_req     ),
+    .master_add_o     ( dm_master_add     ),
+    .master_we_o      ( dm_master_we      ),
+    .master_wdata_o   ( dm_master_wdata   ),
+    .master_be_o      ( dm_master_be      ),
+    .master_gnt_i     ( dm_master_gnt     ),
+    .master_r_valid_i ( dm_master_r_valid ),
+    .master_r_rdata_i ( dm_master_r_rdata ),
+    .dmi_rst_ni       ( rst_n             ),
+    .dmi_req_valid_i  ( debug_req_valid   ),
+    .dmi_req_ready_o  ( debug_req_ready   ),
+    .dmi_req_i        ( debug_req         ),
+    .dmi_resp_valid_o ( debug_resp_valid  ),
+    .dmi_resp_ready_i ( debug_resp_ready  ),
+    .dmi_resp_o       ( debug_resp        )
+);
+/********************************************************/
+axi2mem #(
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves    ),
+    .AXI_ADDR_WIDTH ( 32        ),
+    .AXI_DATA_WIDTH ( 32        ),
+    .AXI_USER_WIDTH ( AxiUserWidth        )
+) i_dm_axi2mem (
+    .clk_i      ( clk                       ),
+    .rst_ni     ( rst_n                     ),
+//    .slave      ( master[ariane_soc::Debug] ),
+    .slave      ( master_to_dm[0] ),
+    .req_o      ( dm_slave_req              ),
+    .we_o       ( dm_slave_we               ),
+    .addr_o     ( dm_slave_addr             ),
+    .be_o       ( dm_slave_be               ),
+    .data_o     ( dm_slave_wdata            ),
+    .data_i     ( dm_slave_rdata            )
+);
+
+
+
+assign master_to_dm[0].aw_user = '0;
+assign master_to_dm[0].w_user = '0;
+assign master_to_dm[0].ar_user = '0;
+
+assign master_to_dm[0].aw_id = dm_axi_m_req.aw.id;
+//assign master_to_dm[0].b_id = dm_axi_m_resp.b.id;
+//assign dm_axi_m_resp.b.id = master_to_dm[0].b_id;
+assign master_to_dm[0].ar_id = dm_axi_m_req.ar.id;
+//assign master_to_dm[0].r_id = dm_axi_m_resp.r.id;
+//assign dm_axi_m_resp.r.id = master_to_dm[0].r_id;
+
+assign master[ariane_soc::Debug].r_user ='0;
+assign master[ariane_soc::Debug].b_user ='0;
+
+//assign master[ariane_soc::Debug].b_id = master_to_dm[0].b_id;
+//assign master[ariane_soc::Debug].r_id = master_to_dm[0].r_id;
+
+
+
+xlnx_axi_dwidth_converter_dm_slave  i_axi_dwidth_converter_dm_slave( 
+    .s_axi_aclk(clk),// : in STD_LOGIC;
+    .s_axi_aresetn(ndmreset_n),// : in STD_LOGIC;
+    .s_axi_awid(master[ariane_soc::Debug].aw_id),// : in STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_awaddr(master[ariane_soc::Debug].aw_addr[31:0]),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_awlen(master[ariane_soc::Debug].aw_len),// : in STD_LOGIC_VECTOR ( 7 downto 0 );
+    .s_axi_awsize(master[ariane_soc::Debug].aw_size),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_awburst(master[ariane_soc::Debug].aw_burst),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_awlock(master[ariane_soc::Debug].aw_lock),// : in STD_LOGIC_VECTOR ( 0 to 0 );
+    .s_axi_awcache(master[ariane_soc::Debug].aw_cache),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awprot(master[ariane_soc::Debug].aw_prot),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_awregion(master[ariane_soc::Debug].aw_region),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awqos(master[ariane_soc::Debug].aw_qos),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awvalid(master[ariane_soc::Debug].aw_valid),// : in STD_LOGIC;
+    .s_axi_awready(master[ariane_soc::Debug].aw_ready),// : out STD_LOGIC;
+    .s_axi_wdata(master[ariane_soc::Debug].w_data),// : in STD_LOGIC_VECTOR ( 63 downto 0 );
+    .s_axi_wstrb(master[ariane_soc::Debug].w_strb),// : in STD_LOGIC_VECTOR ( 7 downto 0 );
+    .s_axi_wlast(master[ariane_soc::Debug].w_last),// : in STD_LOGIC;
+    .s_axi_wvalid(master[ariane_soc::Debug].w_valid),// : in STD_LOGIC;
+    .s_axi_wready(master[ariane_soc::Debug].w_ready),// : out STD_LOGIC;
+    .s_axi_bid(master[ariane_soc::Debug].b_id),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    //.s_axi_bid(),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_bresp(master[ariane_soc::Debug].b_resp),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_bvalid(master[ariane_soc::Debug].b_valid),// : out STD_LOGIC;
+    .s_axi_bready(master[ariane_soc::Debug].b_ready),// : in STD_LOGIC;
+    .s_axi_arid(master[ariane_soc::Debug].ar_id),// : in STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_araddr(master[ariane_soc::Debug].ar_addr[31:0]),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_arlen(master[ariane_soc::Debug].ar_len),// : in STD_LOGIC_VECTOR ( 7 downto 0 );
+    .s_axi_arsize(master[ariane_soc::Debug].ar_size),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_arburst(master[ariane_soc::Debug].ar_burst),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_arlock(master[ariane_soc::Debug].ar_lock),// : in STD_LOGIC_VECTOR ( 0 to 0 );
+    .s_axi_arcache(master[ariane_soc::Debug].ar_cache),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arprot(master[ariane_soc::Debug].ar_prot),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_arregion(master[ariane_soc::Debug].ar_region),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arqos(master[ariane_soc::Debug].ar_qos),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arvalid(master[ariane_soc::Debug].ar_valid),// : in STD_LOGIC;
+    .s_axi_arready(master[ariane_soc::Debug].ar_ready),// : out STD_LOGIC;
+    .s_axi_rid(master[ariane_soc::Debug].r_id),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    //.s_axi_rid(),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_rdata(master[ariane_soc::Debug].r_data),// : out STD_LOGIC_VECTOR ( 63 downto 0 );
+    .s_axi_rresp(master[ariane_soc::Debug].r_resp),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_rlast(master[ariane_soc::Debug].r_last),// : out STD_LOGIC;
+    .s_axi_rvalid(master[ariane_soc::Debug].r_valid),// : out STD_LOGIC;
+    .s_axi_rready(master[ariane_soc::Debug].r_ready),// : in STD_LOGIC;
+    .m_axi_awaddr(master_to_dm[0].aw_addr),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_awlen(master_to_dm[0].aw_len),// : out STD_LOGIC_VECTOR ( 7 downto 0 );
+    .m_axi_awsize(master_to_dm[0].aw_size),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_awburst(master_to_dm[0].aw_burst),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_awlock(master_to_dm[0].aw_lock),// : out STD_LOGIC_VECTOR ( 0 to 0 );
+    .m_axi_awcache(master_to_dm[0].aw_cache),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awprot(master_to_dm[0].aw_prot),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_awregion(master_to_dm[0].aw_region),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awqos(master_to_dm[0].aw_qos),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awvalid(master_to_dm[0].aw_valid),// : out STD_LOGIC;
+    .m_axi_awready(master_to_dm[0].aw_ready),// : in STD_LOGIC;
+    .m_axi_wdata(master_to_dm[0].w_data ),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_wstrb(master_to_dm[0].w_strb),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_wlast(master_to_dm[0].w_last),// : out STD_LOGIC;
+    .m_axi_wvalid(master_to_dm[0].w_valid),// : out STD_LOGIC;
+    .m_axi_wready(master_to_dm[0].w_ready),// : in STD_LOGIC;
+    .m_axi_bresp(master_to_dm[0].b_resp),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_bvalid(master_to_dm[0].b_valid),// : in STD_LOGIC;
+    .m_axi_bready(master_to_dm[0].b_ready),// : out STD_LOGIC;
+    .m_axi_araddr(master_to_dm[0].ar_addr),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_arlen(master_to_dm[0].ar_len),// : out STD_LOGIC_VECTOR ( 7 downto 0 );
+    .m_axi_arsize(master_to_dm[0].ar_size),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_arburst(master_to_dm[0].ar_burst),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_arlock(master_to_dm[0].ar_lock),// : out STD_LOGIC_VECTOR ( 0 to 0 );
+    .m_axi_arcache(master_to_dm[0].ar_cache),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arprot(master_to_dm[0].ar_prot),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_arregion(master_to_dm[0].ar_region),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arqos(master_to_dm[0].ar_qos),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arvalid(master_to_dm[0].ar_valid),// : out STD_LOGIC;
+    .m_axi_arready(master_to_dm[0].ar_ready),// : in STD_LOGIC;
+    .m_axi_rdata(master_to_dm[0].r_data),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_rresp(master_to_dm[0].r_resp),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_rlast(master_to_dm[0].r_last),// : in STD_LOGIC;
+    .m_axi_rvalid(master_to_dm[0].r_valid),// : in STD_LOGIC;
+    .m_axi_rready(master_to_dm[0].r_ready)// : out STD_LOGIC
+  );
+
+
+
+/*axi_master_connect i_dm_axi_master_connect (
+  .axi_req_i(dm_axi_m_req),
+  .axi_resp_o(dm_axi_m_resp),
+  .master(slave[1])
+);*/
+/*****************************************************************/
+logic [31 : 0] dm_master_m_awaddr;
+logic [31 : 0] dm_master_m_araddr;
+
+assign slave[1].aw_addr = {32'h0000_0000, dm_master_m_awaddr};
+assign slave[1].ar_addr = {32'h0000_0000, dm_master_m_araddr};
+
+logic [31 : 0] dm_master_s_rdata;
+
+assign dm_axi_m_resp.r.data = {32'h0000_0000, dm_master_s_rdata}; 
+
+assign slave[1].aw_user = '0;
+assign slave[1].w_user = '0;
+assign slave[1].ar_user = '0;
+//assign slave[1].b_user = '0;
+
+assign slave[1].aw_id = dm_axi_m_req.aw.id;
+//assign slave[1].b_id = dm_axi_m_resp.b.id;
+///assign dm_axi_m_resp.b.id = slave[1].b_id;
+assign slave[1].ar_id = dm_axi_m_req.ar.id;
+//assign slave[1].r_id = dm_axi_m_resp.r.id;
+//assign dm_axi_m_resp.r.id = slave[1].r_id;
+assign slave[1].aw_atop = dm_axi_m_req.aw.atop;
+
+
+
+xlnx_axi_dwidth_converter_dm_master  i_axi_dwidth_converter_dm_master( 
+    .s_axi_aclk(clk),// : in STD_LOGIC;
+    .s_axi_aresetn(ndmreset_n),// : in STD_LOGIC;
+    .s_axi_awid(dm_axi_m_req.aw.id),// : in STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_awaddr(dm_axi_m_req.aw.addr[31:0]),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_awlen(dm_axi_m_req.aw.len),// : in STD_LOGIC_VECTOR ( 7 downto 0 );
+    .s_axi_awsize(dm_axi_m_req.aw.size),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_awburst(dm_axi_m_req.aw.burst),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_awlock(dm_axi_m_req.aw.lock),// : in STD_LOGIC_VECTOR ( 0 to 0 );
+    .s_axi_awcache(dm_axi_m_req.aw.cache),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awprot(dm_axi_m_req.aw.prot),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_awregion(dm_axi_m_req.aw.region),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awqos(dm_axi_m_req.aw.qos),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_awvalid(dm_axi_m_req.aw_valid),// : in STD_LOGIC;
+    .s_axi_awready(dm_axi_m_resp.aw_ready),// : out STD_LOGIC;
+    .s_axi_wdata(dm_axi_m_req.w.data[31:0]),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_wstrb(dm_axi_m_req.w.strb[3:0]),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_wlast(dm_axi_m_req.w.last),// : in STD_LOGIC;
+    .s_axi_wvalid(dm_axi_m_req.w_valid),// : in STD_LOGIC;
+    .s_axi_wready(dm_axi_m_resp.w_ready),// : out STD_LOGIC;
+    .s_axi_bid(dm_axi_m_resp.b.id),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_bresp(dm_axi_m_resp.b.resp),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_bvalid(dm_axi_m_resp.b_valid),// : out STD_LOGIC;
+    .s_axi_bready(dm_axi_m_req.b_ready),// : in STD_LOGIC;
+    .s_axi_arid(dm_axi_m_req.ar.id),// : in STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_araddr(dm_axi_m_req.ar.addr[31:0]),// : in STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_arlen(dm_axi_m_req.ar.len),// : in STD_LOGIC_VECTOR ( 7 downto 0 );
+    .s_axi_arsize(dm_axi_m_req.ar.size),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_arburst(dm_axi_m_req.ar.burst),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_arlock(dm_axi_m_req.ar.lock),// : in STD_LOGIC_VECTOR ( 0 to 0 );
+    .s_axi_arcache(dm_axi_m_req.ar.cache),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arprot(dm_axi_m_req.ar.prot),// : in STD_LOGIC_VECTOR ( 2 downto 0 );
+    .s_axi_arregion(dm_axi_m_req.ar.region),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arqos(dm_axi_m_req.ar.qos),// : in STD_LOGIC_VECTOR ( 3 downto 0 );
+    .s_axi_arvalid(dm_axi_m_req.ar_valid),// : in STD_LOGIC;
+    .s_axi_arready(dm_axi_m_resp.ar_ready),// : out STD_LOGIC;
+    .s_axi_rid(dm_axi_m_resp.r.id),// : out STD_LOGIC_VECTOR ( 4 downto 0 );
+    .s_axi_rdata(dm_master_s_rdata),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .s_axi_rresp(dm_axi_m_resp.r.resp),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .s_axi_rlast(dm_axi_m_resp.r.last),// : out STD_LOGIC;
+    .s_axi_rvalid(dm_axi_m_resp.r_valid),// : out STD_LOGIC;
+    .s_axi_rready(dm_axi_m_req.r_ready),// : in STD_LOGIC;
+    .m_axi_awaddr(dm_master_m_awaddr),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_awlen(slave[1].aw_len),// : out STD_LOGIC_VECTOR ( 7 downto 0 );
+    .m_axi_awsize(slave[1].aw_size),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_awburst(slave[1].aw_burst),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_awlock(slave[1].aw_lock),// : out STD_LOGIC_VECTOR ( 0 to 0 );
+    .m_axi_awcache(slave[1].aw_cache),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awprot(slave[1].aw_prot),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_awregion(slave[1].aw_region),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awqos(slave[1].aw_qos),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_awvalid(slave[1].aw_valid),// : out STD_LOGIC;
+    .m_axi_awready(slave[1].aw_ready),// : in STD_LOGIC;
+    .m_axi_wdata(slave[1].w_data ),// : out STD_LOGIC_VECTOR ( 63 downto 0 );
+    .m_axi_wstrb(slave[1].w_strb),// : out STD_LOGIC_VECTOR ( 7 downto 0 );
+    .m_axi_wlast(slave[1].w_last),// : out STD_LOGIC;
+    .m_axi_wvalid(slave[1].w_valid),// : out STD_LOGIC;
+    .m_axi_wready(slave[1].w_ready),// : in STD_LOGIC;
+    .m_axi_bresp(slave[1].b_resp),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_bvalid(slave[1].b_valid),// : in STD_LOGIC;
+    .m_axi_bready(slave[1].b_ready),// : out STD_LOGIC;
+    .m_axi_araddr(dm_master_m_araddr),// : out STD_LOGIC_VECTOR ( 31 downto 0 );
+    .m_axi_arlen(slave[1].ar_len),// : out STD_LOGIC_VECTOR ( 7 downto 0 );
+    .m_axi_arsize(slave[1].ar_size),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_arburst(slave[1].ar_burst),// : out STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_arlock(slave[1].ar_lock),// : out STD_LOGIC_VECTOR ( 0 to 0 );
+    .m_axi_arcache(slave[1].ar_cache),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arprot(slave[1].ar_prot),// : out STD_LOGIC_VECTOR ( 2 downto 0 );
+    .m_axi_arregion(slave[1].ar_region),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arqos(slave[1].ar_qos),// : out STD_LOGIC_VECTOR ( 3 downto 0 );
+    .m_axi_arvalid(slave[1].ar_valid),// : out STD_LOGIC;
+    .m_axi_arready(slave[1].ar_ready),// : in STD_LOGIC;
+    .m_axi_rdata(slave[1].r_data),// : in STD_LOGIC_VECTOR ( 63 downto 0 );
+    .m_axi_rresp(slave[1].r_resp),// : in STD_LOGIC_VECTOR ( 1 downto 0 );
+    .m_axi_rlast(slave[1].r_last),// : in STD_LOGIC;
+    .m_axi_rvalid(slave[1].r_valid),// : in STD_LOGIC;
+    .m_axi_rready(slave[1].r_ready)// : out STD_LOGIC
+  );
+
+
+/*axi_adapter #(
+    .DATA_WIDTH            ( 32              )
+) i_dm_axi_master (
+    .clk_i                 ( clk                       ),
+    .rst_ni                ( rst_n                     ),
+    .req_i                 ( dm_master_req             ),
+    .type_i                ( ariane_axi::SINGLE_REQ    ),
+    .gnt_o                 ( dm_master_gnt             ),
+    .gnt_id_o              (                           ),
+    .addr_i                ( {32'h00000000, dm_master_add}             ),
+    .we_i                  ( dm_master_we              ),
+    .wdata_i               ( dm_master_wdata           ),
+    .be_i                  ( dm_master_be              ),
+    .size_i                ( 2'b11                     ), // always do 64bit here and use byte enables to gate
+    .id_i                  ( '0                        ),
+    .valid_o               ( dm_master_r_valid         ),
+    .rdata_o               ( dm_master_r_rdata         ),
+    .id_o                  (                           ),
+    .critical_word_o       (                           ),
+    .critical_word_valid_o (                           ),
+    .axi_req_o             ( dm_axi_m_req              ),
+    .axi_resp_i            ( dm_axi_m_resp             )
+);*/
+
+axi_adapter_32 #(
+    .DATA_WIDTH            ( 32              )
+) i_dm_axi_master (
+    .clk_i                 ( clk                       ),
+    .rst_ni                ( rst_n                     ),
+    .req_i                 ( dm_master_req             ),
+    .type_i                ( ariane_axi::SINGLE_REQ    ),
+    .gnt_o                 ( dm_master_gnt             ),
+    .gnt_id_o              (                           ),
+    .addr_i                (  dm_master_add             ),
+    .we_i                  ( dm_master_we              ),
+    .wdata_i               ( dm_master_wdata           ),
+    .be_i                  ( dm_master_be              ),
+    .size_i                ( 2'b10                     ), // always do 32bit here and use byte enables to gate
+    .id_i                  ( '0                        ),
+    .valid_o               ( dm_master_r_valid         ),
+    .rdata_o               ( dm_master_r_rdata         ),
+    .id_o                  (                           ),
+    .critical_word_o       (                           ),
+    .critical_word_valid_o (                           ),
+    .axi_req_o             ( dm_axi_m_req              ),
+    .axi_resp_i            ( dm_axi_m_resp             )
+);
+
+// ---------------
+// Core
+// ---------------
+ariane_axi::req_t    axi_ariane_req;
+ariane_axi::resp_t   axi_ariane_resp;
+
+ariane #(
+    .ArianeCfg ( ariane_soc::ArianeSocCfg )
+) i_ariane (
+    .clk_i        ( clk                 ),
+    .rst_ni       ( ndmreset_n          ),
+    .boot_addr_i  ( ariane_soc::ROMBase[riscv::XLEN-1:0] ), // start fetching from ROM
+    .hart_id_i    ( '0                  ),
+    .irq_i        ( irq                 ),
+    .ipi_i        ( ipi                 ),
+    .time_irq_i   ( timer_irq           ),
+    .debug_req_i  ( debug_req_irq       ),
+    .axi_req_o    ( axi_ariane_req      ),
+    .axi_resp_i   ( axi_ariane_resp     )
+);
+
+axi_master_connect i_axi_master_connect_ariane (.axi_req_i(axi_ariane_req), .axi_resp_o(axi_ariane_resp), .master(slave[0]));
+
+// ---------------
+// CLINT
+// ---------------
+// divide clock by two
+always_ff @(posedge clk or negedge ndmreset_n) begin
+  if (~ndmreset_n) begin
+    rtc <= 0;
+  end else begin
+    rtc <= rtc ^ 1'b1;
+  end
+end
+
+ariane_axi::req_t    axi_clint_req;
+ariane_axi::resp_t   axi_clint_resp;
+
+clint #(
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .NR_CORES       ( 1                )
+) i_clint (
+    .clk_i       ( clk            ),
+    .rst_ni      ( ndmreset_n     ),
+    .testmode_i  ( test_en        ),
+    .axi_req_i   ( axi_clint_req  ),
+    .axi_resp_o  ( axi_clint_resp ),
+    .rtc_i       ( rtc            ),
+    .timer_irq_o ( timer_irq      ),
+    .ipi_o       ( ipi            )
+);
+
+axi_slave_connect i_axi_slave_connect_clint (.axi_req_o(axi_clint_req), .axi_resp_i(axi_clint_resp), .slave(master[ariane_soc::CLINT]));
+
+// ---------------
+// ROM
+// ---------------
+axi2mem #(
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_USER_WIDTH ( AxiUserWidth     )
+) i_axi2rom (
+    .clk_i  ( clk                     ),
+    .rst_ni ( ndmreset_n              ),
+    .slave  ( master[ariane_soc::ROM] ),
+    .req_o  ( rom_req                 ),
+    .we_o   (                         ),
+    .addr_o ( rom_addr                ),
+    .be_o   (                         ),
+    .data_o (                         ),
+    .data_i ( rom_rdata               )
+);
+
+bootrom i_bootrom (
+    .clk_i   ( clk       ),
+    .req_i   ( rom_req   ),
+    .addr_i  ( rom_addr  ),
+    .rdata_o ( rom_rdata )
+);
+
+
+
+ariane_peripherals #(
+    .AxiAddrWidth ( AxiAddrWidth     ),
+    .AxiDataWidth ( AxiDataWidth     ),
+    .AxiIdWidth   ( AxiIdWidthSlaves ),
+    .AxiUserWidth ( AxiUserWidth     ),
+    .InclUART     ( 1'b1             ),
+    .InclGPIO     ( 1'b0             ),
+    .InclSPI      ( 1'b0         ),
+    .InclEthernet ( 1'b0         )
+
+) i_ariane_peripherals (
+    .clk_i        ( clk                          ),
+    .clk_200MHz_i ( 1'b0               ),
+    .rst_ni       ( ndmreset_n                   ),
+    .plic         ( master[ariane_soc::PLIC]     ),
+    .uart         ( master[ariane_soc::UART]     ),
+    .spi          ( master[ariane_soc::SPI]      ),
+    .gpio         ( master[ariane_soc::GPIO]     ),
+    .eth_clk_i    ( eth_clk                      ),
+    .ethernet     ( master[ariane_soc::Ethernet] ),
+    .timer        ( master[ariane_soc::Timer]    ),
+    .irq_o        ( irq                          ),
+    .rx_i         ( rx                           ),
+    .tx_o         ( tx                           ),
+    .eth_txck (),
+    .eth_rxck (1'b0),
+    .eth_rxctl (1'b0),
+    .eth_rxd (4'b0000),
+    .eth_rst_n (),
+    .eth_txctl (),
+    .eth_txd (),
+    .eth_mdio (),
+    .eth_mdc (),
+    .phy_tx_clk_i   ( phy_tx_clk                  ),
+    .sd_clk_i       ( sd_clk_sys                  ),
+    .spi_clk_o      ( spi_clk_o                   ),
+    .spi_mosi       ( spi_mosi                    ),
+    .spi_miso       ( spi_miso                    ),
+    .spi_ss         ( spi_ss                      ),
+
+      .leds_o         (                        ),
+      .dip_switches_i (                        )
+
+);
+
+
+// ---------------------
+// Board peripherals
+// ---------------------
+// ---------------
+// DDR
+// ---------------
+logic [AxiIdWidthSlaves-1:0] s_axi_awid;
+logic [AxiAddrWidth-1:0]     s_axi_awaddr;
+logic [7:0]                  s_axi_awlen;
+logic [2:0]                  s_axi_awsize;
+logic [1:0]                  s_axi_awburst;
+logic [0:0]                  s_axi_awlock;
+logic [3:0]                  s_axi_awcache;
+logic [2:0]                  s_axi_awprot;
+logic [3:0]                  s_axi_awregion;
+logic [3:0]                  s_axi_awqos;
+logic                        s_axi_awvalid;
+logic                        s_axi_awready;
+logic [AxiDataWidth-1:0]     s_axi_wdata;
+logic [AxiDataWidth/8-1:0]   s_axi_wstrb;
+logic                        s_axi_wlast;
+logic                        s_axi_wvalid;
+logic                        s_axi_wready;
+logic [AxiIdWidthSlaves-1:0] s_axi_bid;
+logic [1:0]                  s_axi_bresp;
+logic                        s_axi_bvalid;
+logic                        s_axi_bready;
+logic [AxiIdWidthSlaves-1:0] s_axi_arid;
+logic [AxiAddrWidth-1:0]     s_axi_araddr;
+logic [7:0]                  s_axi_arlen;
+logic [2:0]                  s_axi_arsize;
+logic [1:0]                  s_axi_arburst;
+logic [0:0]                  s_axi_arlock;
+logic [3:0]                  s_axi_arcache;
+logic [2:0]                  s_axi_arprot;
+logic [3:0]                  s_axi_arregion;
+logic [3:0]                  s_axi_arqos;
+logic                        s_axi_arvalid;
+logic                        s_axi_arready;
+logic [AxiIdWidthSlaves-1:0] s_axi_rid;
+logic [AxiDataWidth-1:0]     s_axi_rdata;
+logic [1:0]                  s_axi_rresp;
+logic                        s_axi_rlast;
+logic                        s_axi_rvalid;
+logic                        s_axi_rready;
+
+AXI_BUS #(
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .AXI_USER_WIDTH ( AxiUserWidth     )
+) dram();
+
+axi_riscv_atomics_wrap #(
+    .AXI_ADDR_WIDTH ( AxiAddrWidth     ),
+    .AXI_DATA_WIDTH ( AxiDataWidth     ),
+    .AXI_ID_WIDTH   ( AxiIdWidthSlaves ),
+    .AXI_USER_WIDTH ( AxiUserWidth     ),
+    .AXI_MAX_WRITE_TXNS ( 1  ),
+    .RISCV_WORD_WIDTH   ( 64 )
+) i_axi_riscv_atomics (
+    .clk_i  ( clk                      ),
+    .rst_ni ( ndmreset_n               ),
+    .slv    ( master[ariane_soc::DRAM] ),
+    .mst    ( dram                     )
+);
+
+
+assign dram.r_user = '0;
+assign dram.b_user = '0;
+
+//xlnx_axi_clock_converter i_xlnx_axi_clock_converter_ddr (
+//  .s_axi_aclk     ( clk              ),
+//  .s_axi_aresetn  ( ndmreset_n       ),
+//  .s_axi_awid     ( dram.aw_id       ),
+//  .s_axi_awaddr   ( dram.aw_addr     ),
+//  .s_axi_awlen    ( dram.aw_len      ),
+//  .s_axi_awsize   ( dram.aw_size     ),
+//  .s_axi_awburst  ( dram.aw_burst    ),
+//  .s_axi_awlock   ( dram.aw_lock     ),
+//  .s_axi_awcache  ( dram.aw_cache    ),
+//  .s_axi_awprot   ( dram.aw_prot     ),
+//  .s_axi_awregion ( dram.aw_region   ),
+//  .s_axi_awqos    ( dram.aw_qos      ),
+//  .s_axi_awvalid  ( dram.aw_valid    ),
+//  .s_axi_awready  ( dram.aw_ready    ),
+//  .s_axi_wdata    ( dram.w_data      ),
+//  .s_axi_wstrb    ( dram.w_strb      ),
+//  .s_axi_wlast    ( dram.w_last      ),
+//  .s_axi_wvalid   ( dram.w_valid     ),
+//  .s_axi_wready   ( dram.w_ready     ),
+//  .s_axi_bid      ( dram.b_id        ),
+//  .s_axi_bresp    ( dram.b_resp      ),
+//  .s_axi_bvalid   ( dram.b_valid     ),
+//  .s_axi_bready   ( dram.b_ready     ),
+//  .s_axi_arid     ( dram.ar_id       ),
+//  .s_axi_araddr   ( dram.ar_addr     ),
+//  .s_axi_arlen    ( dram.ar_len      ),
+//  .s_axi_arsize   ( dram.ar_size     ),
+//  .s_axi_arburst  ( dram.ar_burst    ),
+//  .s_axi_arlock   ( dram.ar_lock     ),
+//  .s_axi_arcache  ( dram.ar_cache    ),
+//  .s_axi_arprot   ( dram.ar_prot     ),
+//  .s_axi_arregion ( dram.ar_region   ),
+//  .s_axi_arqos    ( dram.ar_qos      ),
+//  .s_axi_arvalid  ( dram.ar_valid    ),
+//  .s_axi_arready  ( dram.ar_ready    ),
+//  .s_axi_rid      ( dram.r_id        ),
+//  .s_axi_rdata    ( dram.r_data      ),
+//  .s_axi_rresp    ( dram.r_resp      ),
+//  .s_axi_rlast    ( dram.r_last      ),
+//  .s_axi_rvalid   ( dram.r_valid     ),
+//  .s_axi_rready   ( dram.r_ready     ),
+//  // to size converter
+//  .m_axi_aclk     ( ps_clock_out    ),
+//  .m_axi_aresetn  ( ndmreset_n       ),
+//  .m_axi_awid     ( s_axi_awid       ),
+//  .m_axi_awaddr   ( s_axi_awaddr     ),
+//  .m_axi_awlen    ( s_axi_awlen      ),
+//  .m_axi_awsize   ( s_axi_awsize     ),
+//  .m_axi_awburst  ( s_axi_awburst    ),
+//  .m_axi_awlock   ( s_axi_awlock     ),
+//  .m_axi_awcache  ( s_axi_awcache    ),
+//  .m_axi_awprot   ( s_axi_awprot     ),
+//  .m_axi_awregion ( s_axi_awregion   ),
+//  .m_axi_awqos    ( s_axi_awqos      ),
+//  .m_axi_awvalid  ( s_axi_awvalid    ),
+//  .m_axi_awready  ( s_axi_awready    ),
+//  .m_axi_wdata    ( s_axi_wdata      ),
+//  .m_axi_wstrb    ( s_axi_wstrb      ),
+//  .m_axi_wlast    ( s_axi_wlast      ),
+//  .m_axi_wvalid   ( s_axi_wvalid     ),
+//  .m_axi_wready   ( s_axi_wready     ),
+//  .m_axi_bid      ( s_axi_bid        ),
+//  .m_axi_bresp    ( s_axi_bresp      ),
+//  .m_axi_bvalid   ( s_axi_bvalid     ),
+//  .m_axi_bready   ( s_axi_bready     ),
+//  .m_axi_arid     ( s_axi_arid       ),
+//  .m_axi_araddr   ( s_axi_araddr     ),
+//  .m_axi_arlen    ( s_axi_arlen      ),
+//  .m_axi_arsize   ( s_axi_arsize     ),
+//  .m_axi_arburst  ( s_axi_arburst    ),
+//  .m_axi_arlock   ( s_axi_arlock     ),
+//  .m_axi_arcache  ( s_axi_arcache    ),
+//  .m_axi_arprot   ( s_axi_arprot     ),
+//  .m_axi_arregion ( s_axi_arregion   ),
+//  .m_axi_arqos    ( s_axi_arqos      ),
+//  .m_axi_arvalid  ( s_axi_arvalid    ),
+//  .m_axi_arready  ( s_axi_arready    ),
+//  .m_axi_rid      ( s_axi_rid        ),
+//  .m_axi_rdata    ( s_axi_rdata      ),
+//  .m_axi_rresp    ( s_axi_rresp      ),
+//  .m_axi_rlast    ( s_axi_rlast      ),
+//  .m_axi_rvalid   ( s_axi_rvalid     ),
+//  .m_axi_rready   ( s_axi_rready     )
+//);
+
+xlnx_clk_gen i_xlnx_clk_gen (
+  .clk_out1 ( clk           ), // 25 MHz
+  .clk_out2 ( phy_tx_clk    ), // 125 MHz (for RGMII PHY)
+  .clk_out3 ( eth_clk       ), // 125 MHz quadrature (90 deg phase shift)
+  .clk_out4 ( sd_clk_sys    ), // 50 MHz clock
+  .reset    ( cpu_reset     ),
+  .locked   ( pll_locked    ),
+  .clk_in1  ( clk_sys )  //125 MHz
+  //.clk_in1_p( USER_SI570_P    ),
+  //.clk_in1_n( USER_SI570_N    )
+);
+
+
+
+//logic          eth_rst_n ;
+//logic          eth_rxck  ;
+//logic          eth_rxctl ;
+//logic [3:0]    eth_rxd   ;
+//logic          eth_txck  ;
+//logic          eth_txctl ;
+//logic [3:0]    eth_txd   ;
+//logic          eth_mdio  ;
+//logic          eth_mdc   ;
+
+
+
+//logic [48 : 0] saxigp0_awaddr;
+//logic [48 : 0] saxigp0_araddr;
+
+
+//assign saxigp0_awaddr = s_axi_awaddr[48:0] & 48'h7fff_ffff;
+//assign saxigp0_araddr = s_axi_araddr[48:0] & 48'h7fff_ffff;
+
+//xlnx_zynq_ultra_ps i_xlnx_zynq_ultra_ps (
+//  .saxihpc0_fpd_aclk ( ps_clock_out     ),//: in STD_LOGIC;
+//  .saxigp0_aruser    (s_axi_aruser       ),//: in STD_LOGIC;
+//  .saxigp0_awuser    (s_axi_awuser       ),//: in STD_LOGIC;
+//  .saxigp0_awid      ('0                 ),//: in STD_LOGIC_VECTOR ( 5 downto 0 );
+//  //.saxigp0_awaddr    (s_axi_awaddr[47:0] ),//: in STD_LOGIC_VECTOR ( 48 downto 0 );
+//  .saxigp0_awaddr    (saxigp0_awaddr     ),//: in STD_LOGIC_VECTOR ( 48 downto 0 );
+//  .saxigp0_awlen     (s_axi_awlen        ),//: in STD_LOGIC_VECTOR ( 7 downto 0 );
+//  .saxigp0_awsize    (s_axi_awsize       ),//: in STD_LOGIC_VECTOR ( 2 downto 0 );
+//  .saxigp0_awburst   (s_axi_awburst      ),//: in STD_LOGIC_VECTOR ( 1 downto 0 );
+//  .saxigp0_awlock    (s_axi_awlock       ),//: in STD_LOGIC;
+//  .saxigp0_awcache   (s_axi_awcache      ),//: in STD_LOGIC_VECTOR ( 3 downto 0 );
+//  .saxigp0_awprot    (s_axi_awprot       ),//: in STD_LOGIC_VECTOR ( 2 downto 0 );
+//  .saxigp0_awvalid   (s_axi_awvalid      ),//: in STD_LOGIC;
+//  .saxigp0_awready   (s_axi_awready      ),//: out STD_LOGIC;
+//  .saxigp0_wdata     (s_axi_wdata        ),//: in STD_LOGIC_VECTOR ( 63 downto 0 );
+//  .saxigp0_wstrb     (s_axi_wstrb        ),//: in STD_LOGIC_VECTOR ( 7 downto 0 );
+//  .saxigp0_wlast     (s_axi_wlast        ),//: in STD_LOGIC;
+//  .saxigp0_wvalid    (s_axi_wvalid       ),//: in STD_LOGIC;
+//  .saxigp0_wready    (s_axi_wready       ),//: out STD_LOGIC;
+//  .saxigp0_bid       (                   ),//: out STD_LOGIC_VECTOR ( 5 downto 0 );
+//  .saxigp0_bresp     (s_axi_bresp        ),//: out STD_LOGIC_VECTOR ( 1 downto 0 );
+//  .saxigp0_bvalid    (s_axi_bvalid       ),//: out STD_LOGIC;
+//  .saxigp0_bready    (s_axi_bready       ),//: in STD_LOGIC;
+//  .saxigp0_arid      ('0                 ),//: in STD_LOGIC_VECTOR ( 5 downto 0 );
+//  //.saxigp0_araddr    (s_axi_araddr[47:0] ),//: in STD_LOGIC_VECTOR ( 48 downto 0 );
+//  .saxigp0_araddr    (saxigp0_araddr ),//: in STD_LOGIC_VECTOR ( 48 downto 0 );
+//  .saxigp0_arlen     (s_axi_arlen        ),//: in STD_LOGIC_VECTOR ( 7 downto 0 );
+//  .saxigp0_arsize    (s_axi_arsize       ),//: in STD_LOGIC_VECTOR ( 2 downto 0 );
+//  .saxigp0_arburst   (s_axi_arburst      ),//: in STD_LOGIC_VECTOR ( 1 downto 0 );
+//  .saxigp0_arlock    (s_axi_arlock       ),//: in STD_LOGIC;
+//  .saxigp0_arcache   (s_axi_arcache      ),//: in STD_LOGIC_VECTOR ( 3 downto 0 );
+//  .saxigp0_arprot    (s_axi_arprot       ),//: in STD_LOGIC_VECTOR ( 2 downto 0 );
+//  .saxigp0_arvalid   (s_axi_arvalid      ),//: in STD_LOGIC;
+//  .saxigp0_arready   (s_axi_arready      ),//: out STD_LOGIC;
+//  .saxigp0_rid       (                   ),//: out STD_LOGIC_VECTOR ( 5 downto 0 );
+//  .saxigp0_rdata     (s_axi_rdata        ),//: out STD_LOGIC_VECTOR ( 63 downto 0 );
+//  .saxigp0_rresp     (s_axi_rresp        ),//: out STD_LOGIC_VECTOR ( 1 downto 0 );
+//  .saxigp0_rlast     (s_axi_rlast        ),//: out STD_LOGIC;
+//  .saxigp0_rvalid    (s_axi_rvalid       ),//: out STD_LOGIC;
+//  .saxigp0_rready    (s_axi_rready       ),//: in STD_LOGIC;
+//  .saxigp0_awqos     (s_axi_awqos        ),//: in STD_LOGIC_VECTOR ( 3 downto 0 );
+//  .saxigp0_arqos     (s_axi_arqos        ),//: in STD_LOGIC_VECTOR ( 3 downto 0 );
+//  //.pl_clk0           ( ps_clock_out     )//: out STD_LOGIC
+//  .pl_clk0           (      )//: out STD_LOGIC
+//  );
+
+logic [31 : 0] saxibram_awaddr;
+logic [31 : 0] saxibram_araddr;
+
+
+assign saxibram_awaddr = dram.aw_addr & 32'h7fff_ffff;
+assign saxibram_araddr = dram.ar_addr & 32'h7fff_ffff;
+
+xlnx_blk_mem_gen i_xlnx_blk_mem_gen (
+
+    .rsta_busy (      ),//: OUT STD_LOGIC;
+    .rstb_busy (      ),//: OUT STD_LOGIC;
+    .s_aclk ( clk     ),//: IN STD_LOGIC;
+    .s_aresetn (    ndmreset_n  ),//: IN STD_LOGIC;
+    .s_axi_awid ( dram.aw_id       ),//: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
+//    .s_axi_awaddr ( dram.aw_addr     ),//: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+    .s_axi_awaddr ( saxibram_awaddr     ),//: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+    .s_axi_awlen ( dram.aw_len      ),//: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+    .s_axi_awsize ( dram.aw_size     ),//: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
+    .s_axi_awburst ( dram.aw_burst    ),//: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
+    .s_axi_awvalid ( dram.aw_valid    ),//: IN STD_LOGIC;
+    .s_axi_awready ( dram.aw_ready    ),//: OUT STD_LOGIC;
+    .s_axi_wdata ( dram.w_data      ),//: IN STD_LOGIC_VECTOR(63 DOWNTO 0);
+    .s_axi_wstrb ( dram.w_strb      ),//: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+    .s_axi_wlast ( dram.w_last      ),//: IN STD_LOGIC;
+    .s_axi_wvalid ( dram.w_valid     ),//: IN STD_LOGIC;
+    .s_axi_wready ( dram.w_ready     ),//: OUT STD_LOGIC;
+    .s_axi_bid ( dram.b_id        ),//: OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
+    .s_axi_bresp ( dram.b_resp      ),//: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
+    .s_axi_bvalid ( dram.b_valid     ),//: OUT STD_LOGIC;
+    .s_axi_bready ( dram.b_ready     ),//: IN STD_LOGIC;
+    .s_axi_arid ( dram.ar_id       ),//: IN STD_LOGIC_VECTOR(5 DOWNTO 0);
+//    .s_axi_araddr ( dram.ar_addr     ),//: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+    .s_axi_araddr ( saxibram_araddr     ),//: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
+    .s_axi_arlen ( dram.ar_len      ),//: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+    .s_axi_arsize ( dram.ar_size     ),//: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
+    .s_axi_arburst( dram.ar_burst    ),//: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
+    .s_axi_arvalid ( dram.ar_valid    ),//: IN STD_LOGIC;
+    .s_axi_arready ( dram.ar_ready    ),//: OUT STD_LOGIC;
+    .s_axi_rid ( dram.r_id        ),//: OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
+    .s_axi_rdata ( dram.r_data      ),//: OUT STD_LOGIC_VECTOR(63 DOWNTO 0);
+    .s_axi_rresp ( dram.r_resp      ),//: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
+    .s_axi_rlast ( dram.r_last      ),//: OUT STD_LOGIC;
+    .s_axi_rvalid ( dram.r_valid     ),//: OUT STD_LOGIC;
+    .s_axi_rready ( dram.r_ready     )//: IN STD_LOGIC
+  );
+
+endmodule
+
diff --git a/fpga/src/fan_ctrl.sv b/fpga/src/fan_ctrl.sv
deleted file mode 100644
index fb021143..00000000
--- a/fpga/src/fan_ctrl.sv
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: PWM Fan Control for Genesys II board
-// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch
-
-module fan_ctrl (
-    input  logic       clk_i,
-    input  logic       rst_ni,
-    input  logic [3:0] pwm_setting_i,
-    output logic       fan_pwm_o
-);
-    logic [3:0]  ms_clock_d, ms_clock_q;
-    logic [19:0] cycle_counter_d, cycle_counter_q;
-
-    // clock divider
-    always_comb begin
-        cycle_counter_d = cycle_counter_q;
-        ms_clock_d = ms_clock_q;
-
-        // divide clock by 499999
-        if (cycle_counter_q == 499_999) begin
-            cycle_counter_d = 0;
-            ms_clock_d = ms_clock_q + 1;
-        end else begin
-            cycle_counter_d = cycle_counter_q + 1;
-        end
-
-        if (ms_clock_q == 15) begin
-            ms_clock_d = 0;
-        end
-    end
-
-    // duty cycle
-    always_comb begin
-        if (ms_clock_q < pwm_setting_i) begin
-            fan_pwm_o = 1'b1;
-        end else begin
-            fan_pwm_o = 1'b0;
-        end
-    end
-
-    always_ff @(posedge clk_i or negedge rst_ni) begin
-        if (~rst_ni) begin
-            ms_clock_q      <= '0;
-            cycle_counter_q <= '0;
-        end else begin
-            ms_clock_q      <= ms_clock_d;
-            cycle_counter_q <= cycle_counter_d;
-        end
-    end
-endmodule
diff --git a/fpga/src/genesysii.svh b/fpga/src/genesysii.svh
deleted file mode 100644
index cd350a93..00000000
--- a/fpga/src/genesysii.svh
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: Set global FPGA degines
-// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-
-`define GENESYSII
-// include KINTEX7 specific code (relevant for KC705, GENESYSII,...)
-`define KINTEX7
-
-`define ARIANE_DATA_WIDTH 64
-
-// Instantiate protocl checker
-// `define PROTOCOL_CHECKER
-
-// write-back cache
-// `define WB_DCACHE
-
-// write-through cache
-`define WT_DCACHE
diff --git a/fpga/src/kc705.svh b/fpga/src/kc705.svh
deleted file mode 100644
index a66e7638..00000000
--- a/fpga/src/kc705.svh
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: Set global FPGA degines
-// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-
-`define KC705
-// include KINTEX7 specific code (relevant for KC705, GENESYSII,...)
-`define KINTEX7
-
-`define ARIANE_DATA_WIDTH 64
-
-// Instantiate protocl checker
-// `define PROTOCOL_CHECKER
-
-// write-back cache
-// `define WB_DCACHE
-
-// write-through cache
-`define WT_DCACHE
diff --git a/fpga/src/vc707.svh b/fpga/src/vc707.svh
deleted file mode 100644
index 3886cae9..00000000
--- a/fpga/src/vc707.svh
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: Set global FPGA degines
-// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-
-`define VC707
-
-`define ARIANE_DATA_WIDTH 64
-
-// Instantiate protocl checker
-// `define PROTOCOL_CHECKER
-
-// write-back cache
-// `define WB_DCACHE
-
-// write-through cache
-`define WT_DCACHE
diff --git a/fpga/src/vcu118.svh b/fpga/src/vcu118.svh
deleted file mode 100644
index 47440a84..00000000
--- a/fpga/src/vcu118.svh
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 ETH Zurich and University of Bologna.
-// Copyright and related rights are licensed under the Solderpad Hardware
-// License, Version 0.51 (the "License"); you may not use this file except in
-// compliance with the License.  You may obtain a copy of the License at
-// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-// or agreed to in writing, software, hardware and materials distributed under
-// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// Description: Set global FPGA degines
-// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-
-`define VCU118
diff --git a/fpga/src/zybo-z7-20.svh b/fpga/src/zybo-z7-20.svh
index ab300420..1ff44584 100644
--- a/fpga/src/zybo-z7-20.svh
+++ b/fpga/src/zybo-z7-20.svh
@@ -9,3 +9,6 @@
 
 // write-through cache
 `define WT_DCACHE
+
+// debug probe
+//`define LAUTERBACH_DEBUG_PROBE
diff --git a/fpga/xilinx/.gitignore b/fpga/xilinx/.gitignore
new file mode 100644
index 00000000..12ef7f9f
--- /dev/null
+++ b/fpga/xilinx/.gitignore
@@ -0,0 +1,5 @@
+xlnx*/*
+!xlnx*/tcl
+!Makefile
+!common.mk
+!*.prj
\ No newline at end of file
diff --git a/fpga/xilinx/ariane_xlnx_ip.yml b/fpga/xilinx/ariane_xlnx_ip.yml
new file mode 100644
index 00000000..2b3c0c1e
--- /dev/null
+++ b/fpga/xilinx/ariane_xlnx_ip.yml
@@ -0,0 +1,92 @@
+xlnx_axi_dwidth_converter:
+  ip: axi_dwidth_converter
+  vendor: xilinx.com
+  config:
+    si_data_width: 64
+    si_id_width: 5
+    mi_data_width: 32
+
+xlnx_axi_clock_converter:
+  ip: axi_clock_converter
+  vendor: xilinx.com
+  config:
+    width: 64
+    data_width: 64
+    id_width: 5
+
+xlnx_axi_gpio:
+  ip: axi_gpio
+  vendor: xilinx.com
+  config:
+    c_gpio_width: 8
+    c_gpio2_width:  8
+    c_is_dual: 1
+    c_all_inputs_2: 1
+    c_interrupt_present: 0
+
+xlnx_axi_quad_spi:
+  ip: axi_quad_spi
+  vendor: xilinx.com
+  config:
+    c_use_startup: 0
+    c_sck_ratio: 4
+    c_fifo_depth: 256
+    c_type_of_axi4_interface: 1
+    c_s_axi4_id_width: 0
+
+xlnx_clk_gen:
+  ip: clk_wiz
+  vendor: xilinx.com
+  config:
+    prim_in_freq: 200
+    num_out_clks: 4
+    clkout2_used: true
+    clkout3_used: true
+    clkout4_used: true
+    clkout1_requested_out_freq: 50
+    clkout2_requested_out_freq: 125
+    clkout3_requested_out_freq: 125
+    clkout3_requested_phase: 90
+    clkout4_requested_out_freq: 50
+    clkin1_jitter_ps: 50
+
+xlnx_ila:
+  ip: ila
+  vendor: xilinx.com
+  config:
+    c_num_of_probes: 8
+    c_probe3_width: 4
+    c_probe6_width: 4
+    c_data_depth: 16384
+    c_input_pipe_stages: 1
+
+xlnx_mig_7_ddr3:
+  ip: mig_7series
+  vendor: xilinx.com
+  config:
+    xml_input_file: mig_a.prj
+    reset_board_interface: Custom
+    mig_dont_touch_param: Custom
+    board_mig_param: Custom
+
+xlnx_ila:
+  ip: xlnx_ila
+  vendor: xilinx.com
+  config:
+    addr_width: 64
+    data_width: 64
+    id_width: 5
+    awuser_width: 1
+    aruser_width: 1
+    ruser_width: 1
+    wuser_width: 1
+    buser_width: 1
+    max_aw_waits: 1024
+    max_ar_waits: 1024
+    max_w_waits: 1024
+    max_r_waits: 1024
+    max_b_waits: 1024
+    max_continuous_wtransfers_waits: 1024
+    max_wlast_to_awvalid_waits: 1024
+    max_write_to_bvalid_waits: 1024
+    max_continuous_rtransfers_waits: 1024
\ No newline at end of file
diff --git a/fpga/xilinx/common.mk b/fpga/xilinx/common.mk
new file mode 100644
index 00000000..60c91008
--- /dev/null
+++ b/fpga/xilinx/common.mk
@@ -0,0 +1,19 @@
+all:
+	vivado -mode batch -source tcl/run.tcl
+	mkdir -p ip
+	cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/.
+	cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/.
+
+gui:
+	vivado -mode gui -source tcl/run.tcl &
+
+clean:
+	rm -rf ip/*
+	mkdir -p ip
+	rm -rf ${PROJECT}.*
+	rm -rf component.xml
+	rm -rf vivado*.jou
+	rm -rf vivado*.log
+	rm -rf vivado*.str
+	rm -rf xgui
+	rm -rf .Xil
\ No newline at end of file
diff --git a/fpga/xilinx/xlnx_axi_clock_converter/Makefile b/fpga/xilinx/xlnx_axi_clock_converter/Makefile
new file mode 100644
index 00000000..426a7d73
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_clock_converter/Makefile
@@ -0,0 +1,2 @@
+PROJECT:=xlnx_axi_clock_converter
+include ../common.mk
\ No newline at end of file
diff --git a/fpga/xilinx/xlnx_axi_clock_converter/tcl/run.tcl b/fpga/xilinx/xlnx_axi_clock_converter/tcl/run.tcl
new file mode 100644
index 00000000..ba0551e7
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_clock_converter/tcl/run.tcl
@@ -0,0 +1,17 @@
+set partNumber $::env(XILINX_PART)
+set boardName  $::env(XILINX_BOARD)
+
+set ipName xlnx_axi_clock_converter
+
+create_project $ipName . -force -part $partNumber
+set_property board_part $boardName [current_project]
+
+create_ip -name axi_clock_converter -vendor xilinx.com -library ip -module_name $ipName
+
+set_property -dict [list CONFIG.ADDR_WIDTH {64} CONFIG.DATA_WIDTH {64} CONFIG.ID_WIDTH {5}] [get_ips $ipName]
+
+generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+generate_target all [get_files  ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+launch_run -jobs 8 ${ipName}_synth_1
+wait_on_run ${ipName}_synth_1
\ No newline at end of file
diff --git a/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/Makefile b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/Makefile
new file mode 100644
index 00000000..cdaf8cf9
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/Makefile
@@ -0,0 +1,2 @@
+PROJECT:=xlnx_axi_dwidth_converter_dm_master
+include ../common.mk
diff --git a/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/tcl/run.tcl b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/tcl/run.tcl
new file mode 100644
index 00000000..ae2095f0
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_master/tcl/run.tcl
@@ -0,0 +1,17 @@
+set partNumber $::env(XILINX_PART)
+set boardName  $::env(XILINX_BOARD)
+
+set ipName xlnx_axi_dwidth_converter_dm_master
+
+create_project $ipName . -force -part $partNumber
+set_property board_part $boardName [current_project]
+
+create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -module_name $ipName
+
+set_property -dict [list CONFIG.SI_DATA_WIDTH {32} CONFIG.SI_ID_WIDTH {4} CONFIG.MI_DATA_WIDTH {64}] [get_ips $ipName]
+
+generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+generate_target all [get_files  ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+launch_run -jobs 8 ${ipName}_synth_1
+wait_on_run ${ipName}_synth_1
diff --git a/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/Makefile b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/Makefile
new file mode 100644
index 00000000..4f8db458
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/Makefile
@@ -0,0 +1,2 @@
+PROJECT:=xlnx_axi_dwidth_converter_dm_slave
+include ../common.mk
diff --git a/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/tcl/run.tcl b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/tcl/run.tcl
new file mode 100644
index 00000000..e6dab637
--- /dev/null
+++ b/fpga/xilinx/xlnx_axi_dwidth_converter_dm_slave/tcl/run.tcl
@@ -0,0 +1,17 @@
+set partNumber $::env(XILINX_PART)
+set boardName  $::env(XILINX_BOARD)
+
+set ipName xlnx_axi_dwidth_converter_dm_slave
+
+create_project $ipName . -force -part $partNumber
+set_property board_part $boardName [current_project]
+
+create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -module_name $ipName
+
+set_property -dict [list CONFIG.SI_DATA_WIDTH {64} CONFIG.SI_ID_WIDTH {5} CONFIG.MI_DATA_WIDTH {32}] [get_ips $ipName]
+
+generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+generate_target all [get_files  ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+launch_run -jobs 8 ${ipName}_synth_1
+wait_on_run ${ipName}_synth_1
diff --git a/fpga/xilinx/xlnx_blk_mem_gen/Makefile b/fpga/xilinx/xlnx_blk_mem_gen/Makefile
new file mode 100644
index 00000000..767e364c
--- /dev/null
+++ b/fpga/xilinx/xlnx_blk_mem_gen/Makefile
@@ -0,0 +1,2 @@
+PROJECT:=xlnx_blk_mem_gen
+include ../common.mk
diff --git a/fpga/xilinx/xlnx_blk_mem_gen/tcl/run.tcl b/fpga/xilinx/xlnx_blk_mem_gen/tcl/run.tcl
new file mode 100644
index 00000000..6324a506
--- /dev/null
+++ b/fpga/xilinx/xlnx_blk_mem_gen/tcl/run.tcl
@@ -0,0 +1,37 @@
+set partNumber $::env(XILINX_PART)
+set boardName  $::env(XILINX_BOARD)
+
+set ipName xlnx_blk_mem_gen
+
+create_project $ipName . -force -part $partNumber
+set_property board_part $boardName [current_project]
+
+create_ip -name blk_mem_gen -vendor xilinx.com -library ip -module_name $ipName
+
+set_property -dict [list CONFIG.AXI_ID_Width {5} \
+                         CONFIG.Assume_Synchronous_Clk {true} \
+                         CONFIG.Byte_Size {8} \
+                         CONFIG.EN_SAFETY_CKT {true} \
+                         CONFIG.Enable_B {Use_ENB_Pin} \
+                         CONFIG.Interface_Type {AXI4} \
+                         CONFIG.Memory_Type {Simple_Dual_Port_RAM} \
+                         CONFIG.Operating_Mode_A {READ_FIRST} \
+                         CONFIG.Operating_Mode_B {READ_FIRST} \
+                         CONFIG.Port_B_Clock {100} \
+                         CONFIG.Port_B_Enable_Rate {100} \
+                         CONFIG.Read_Width_A {64} \
+                         CONFIG.Read_Width_B {64} \
+                         CONFIG.Register_PortA_Output_of_Memory_Primitives {false} \
+                         CONFIG.Reset_Type {ASYNC} \
+                         CONFIG.Use_AXI_ID {true} \
+                         CONFIG.Use_Byte_Write_Enable {true} \
+                         CONFIG.Use_RSTB_Pin {true} \
+                         CONFIG.Write_Depth_A {16834} \
+                         CONFIG.Write_Width_A {64} \
+                         CONFIG.Write_Width_B {64} ] [get_ips $ipName]
+
+generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+generate_target all [get_files  ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+launch_run -jobs 8 ${ipName}_synth_1
+wait_on_run ${ipName}_synth_1
diff --git a/fpga/xilinx/xlnx_clk_gen/Makefile b/fpga/xilinx/xlnx_clk_gen/Makefile
new file mode 100644
index 00000000..8ce5e6e6
--- /dev/null
+++ b/fpga/xilinx/xlnx_clk_gen/Makefile
@@ -0,0 +1,2 @@
+PROJECT:=xlnx_clk_gen
+include ../common.mk
\ No newline at end of file
diff --git a/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl b/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl
new file mode 100644
index 00000000..26a329e6
--- /dev/null
+++ b/fpga/xilinx/xlnx_clk_gen/tcl/run.tcl
@@ -0,0 +1,28 @@
+set partNumber $::env(XILINX_PART)
+set boardName  $::env(XILINX_BOARD)
+
+set ipName xlnx_clk_gen
+
+create_project $ipName . -force -part $partNumber
+set_property board_part $boardName [current_project]
+
+create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName
+
+set_property -dict [list CONFIG.PRIM_IN_FREQ {125.000} \
+                        CONFIG.NUM_OUT_CLKS {4} \
+                        CONFIG.CLKOUT2_USED {true} \
+                        CONFIG.CLKOUT3_USED {true} \
+                        CONFIG.CLKOUT4_USED {true} \
+                        CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {25} \
+                        CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {125} \
+                        CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {125} \
+                        CONFIG.CLKOUT3_REQUESTED_PHASE {90.000} \
+                        CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {50} \
+                        CONFIG.CLKIN1_JITTER_PS {50.0} \
+                       ] [get_ips $ipName]
+
+generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+generate_target all [get_files  ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
+launch_run -jobs 8 ${ipName}_synth_1
+wait_on_run ${ipName}_synth_1
diff --git a/src/ariane.sv b/src/ariane.sv
index 468da6ec..0868f7eb 100644
--- a/src/ariane.sv
+++ b/src/ariane.sv
@@ -29,8 +29,8 @@ module ariane import ariane_pkg::*; #(
   input  logic                         clk_i,
   input  logic                         rst_ni,
   // Core ID, Cluster ID and boot address are considered more or less static
-  input  logic [63:0]                  boot_addr_i,  // reset boot address
-  input  logic [63:0]                  hart_id_i,    // hart id in a multicore environment (reflected in a CSR)
+  input  logic [riscv::XLEN-1:0]                  boot_addr_i,  // reset boot address
+  input  logic [riscv::XLEN-1:0]                  hart_id_i,    // hart id in a multicore environment (reflected in a CSR)
 
   // Interrupt inputs
   input  logic [1:0]                   irq_i,        // level sensitive IR lines, mip & sip (async)
@@ -87,8 +87,10 @@ module ariane import ariane_pkg::*; #(
   // --------------
   // ISSUE <-> EX
   // --------------
-   logic [63:0] rs1_forwarding_id_ex; // unregistered version of fu_data_o.operanda
-   logic [63:0] rs2_forwarding_id_ex; // unregistered version of fu_data_o.operandb
+
+
+  logic [riscv::VLEN-1:0] rs1_forwarding_id_ex; // unregistered version of fu_data_o.operanda
+  logic [riscv::VLEN-1:0] rs2_forwarding_id_ex; // unregistered version of fu_data_o.operandb
 
   fu_data_t                 fu_data_id_ex;
   logic [riscv::VLEN-1:0]   pc_id_ex;
diff --git a/src/axi_adapter_32.sv b/src/axi_adapter_32.sv
new file mode 100644
index 00000000..3669b37a
--- /dev/null
+++ b/src/axi_adapter_32.sv
@@ -0,0 +1,348 @@
+/* Copyright 2018 ETH Zurich and University of Bologna.
+ * Copyright and related rights are licensed under the Solderpad Hardware
+ * License, Version 0.51 (the “License”); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+ * or agreed to in writing, software, hardware and materials distributed under
+ * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * File:  axi_adapter.sv
+ * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
+ * Date:   1.8.2018
+ *
+ * Description: Manages communication with the AXI Bus
+ */
+//import std_cache_pkg::*;
+
+module axi_adapter_32 #(
+    parameter int unsigned DATA_WIDTH            = 256,
+    parameter logic        CRITICAL_WORD_FIRST   = 0, // the AXI subsystem needs to support wrapping reads for this feature
+    parameter int unsigned AXI_ID_WIDTH          = 10,
+    parameter int unsigned CACHELINE_BYTE_OFFSET = 8
+)(
+    input  logic                                        clk_i,  // Clock
+    input  logic                                        rst_ni, // Asynchronous reset active low
+
+    input  logic                                        req_i,
+    input  ariane_axi::ad_req_t                         type_i,
+    output logic                                        gnt_o,
+    output logic [AXI_ID_WIDTH-1:0]                     gnt_id_o,
+    input  logic [31:0]                                 addr_i,
+    input  logic                                        we_i,
+    input  logic [(DATA_WIDTH/32)-1:0][31:0]            wdata_i,
+    input  logic [(DATA_WIDTH/32)-1:0][3:0]             be_i,
+    input  logic [1:0]                                  size_i,
+    input  logic [AXI_ID_WIDTH-1:0]                     id_i,
+    // read port
+    output logic                                        valid_o,
+    output logic [(DATA_WIDTH/32)-1:0][31:0]            rdata_o,
+    output logic [AXI_ID_WIDTH-1:0]                     id_o,
+    // critical word - read port
+    output logic [31:0]                                 critical_word_o,
+    output logic                                        critical_word_valid_o,
+    // AXI port
+    output ariane_axi::req_t                            axi_req_o,
+    input  ariane_axi::resp_t                           axi_resp_i
+);
+    localparam BURST_SIZE = DATA_WIDTH/32-1;
+    localparam ADDR_INDEX = ($clog2(DATA_WIDTH/32) > 0) ? $clog2(DATA_WIDTH/32) : 1;
+
+    enum logic [3:0] {
+        IDLE, WAIT_B_VALID, WAIT_AW_READY, WAIT_LAST_W_READY, WAIT_LAST_W_READY_AW_READY, WAIT_AW_READY_BURST,
+        WAIT_R_VALID, WAIT_R_VALID_MULTIPLE, COMPLETE_READ
+    } state_q, state_d;
+
+    // counter for AXI transfers
+    logic [ADDR_INDEX-1:0] cnt_d, cnt_q;
+    logic [(DATA_WIDTH/32)-1:0][32:0] cache_line_d, cache_line_q;
+    // save the address for a read, as we allow for non-cacheline aligned accesses
+    logic [(DATA_WIDTH/32)-1:0] addr_offset_d, addr_offset_q;
+    logic [AXI_ID_WIDTH-1:0]    id_d, id_q;
+    logic [ADDR_INDEX-1:0]      index;
+
+    always_comb begin : axi_fsm
+        // Default assignments
+        axi_req_o.aw_valid  = 1'b0;
+        axi_req_o.aw.addr   = addr_i;
+        axi_req_o.aw.prot   = 3'b0;
+        axi_req_o.aw.region = 4'b0;
+        axi_req_o.aw.len    = 8'b0;
+        axi_req_o.aw.size   = {1'b0, size_i};
+        axi_req_o.aw.burst  = (type_i == ariane_axi::SINGLE_REQ) ? 2'b00 :  2'b01;  // fixed size for single request and incremental transfer for everything else
+        axi_req_o.aw.lock   = 1'b0;
+        axi_req_o.aw.cache  = 4'b0;
+        axi_req_o.aw.qos    = 4'b0;
+        axi_req_o.aw.id     = id_i;
+        axi_req_o.aw.atop   = '0; // currently not used
+        //axi_req_o.aw.user   = '0;
+
+        axi_req_o.ar_valid  = 1'b0;
+        // in case of a single request or wrapping transfer we can simply begin at the address, if we want to request a cache-line
+        // with an incremental transfer we need to output the corresponding base address of the cache line
+        axi_req_o.ar.addr   = (CRITICAL_WORD_FIRST || type_i == ariane_axi::SINGLE_REQ) ? addr_i : { addr_i[31:CACHELINE_BYTE_OFFSET], {{CACHELINE_BYTE_OFFSET}{1'b0}}};
+        axi_req_o.ar.prot   = 3'b0;
+        axi_req_o.ar.region = 4'b0;
+        axi_req_o.ar.len    = 8'b0;
+        axi_req_o.ar.size   = {1'b0, size_i}; // 8 bytes
+        axi_req_o.ar.burst  = (type_i == ariane_axi::SINGLE_REQ) ? 2'b00 : (CRITICAL_WORD_FIRST ? 2'b10 : 2'b01);  // wrapping transfer in case of a critical word first strategy
+        axi_req_o.ar.lock   = 1'b0;
+        axi_req_o.ar.cache  = 4'b0;
+        axi_req_o.ar.qos    = 4'b0;
+        axi_req_o.ar.id     = id_i;
+       // axi_req_o.ar.user   = '0;
+
+        axi_req_o.w_valid   = 1'b0;
+        axi_req_o.w.data    = wdata_i[0];
+        axi_req_o.w.strb    = be_i[0];
+        axi_req_o.w.last    = 1'b0;
+        //axi_req_o.w.user    = '0;
+
+        axi_req_o.b_ready   = 1'b0;
+        axi_req_o.r_ready   = 1'b0;
+
+        gnt_o         = 1'b0;
+        gnt_id_o      = id_i;
+        valid_o       = 1'b0;
+        id_o          = axi_resp_i.r.id;
+
+        critical_word_o         = axi_resp_i.r.data;
+        critical_word_valid_o   = 1'b0;
+        rdata_o                 = cache_line_q;
+
+        state_d                 = state_q;
+        cnt_d                   = cnt_q;
+        cache_line_d            = cache_line_q;
+        addr_offset_d           = addr_offset_q;
+        id_d                    = id_q;
+        index                   = '0;
+
+        case (state_q)
+
+            IDLE: begin
+                cnt_d = '0;
+                // we have an incoming request
+                if (req_i) begin
+                    // is this a read or write?
+                    // write
+                    if (we_i) begin
+                        // the data is valid
+                        axi_req_o.aw_valid = 1'b1;
+                        axi_req_o.w_valid  = 1'b1;
+                        // its a single write
+                        if (type_i == ariane_axi::SINGLE_REQ) begin
+                            // only a single write so the data is already the last one
+                            axi_req_o.w.last   = 1'b1;
+                            // single req can be granted here
+                            gnt_o = axi_resp_i.aw_ready & axi_resp_i.w_ready;
+                            case ({axi_resp_i.aw_ready, axi_resp_i.w_ready})
+                                2'b11: state_d = WAIT_B_VALID;
+                                2'b01: state_d = WAIT_AW_READY;
+                                2'b10: state_d = WAIT_LAST_W_READY;
+                                default: state_d = IDLE;
+                            endcase
+
+                        // its a request for the whole cache line
+                        end else begin
+                            axi_req_o.aw.len = BURST_SIZE; // number of bursts to do
+                            axi_req_o.w.data = wdata_i[0];
+                            axi_req_o.w.strb = be_i[0];
+
+                            if (axi_resp_i.w_ready)
+                                cnt_d = BURST_SIZE - 1;
+                            else
+                                cnt_d = BURST_SIZE;
+
+                            case ({axi_resp_i.aw_ready, axi_resp_i.w_ready})
+                                2'b11: state_d = WAIT_LAST_W_READY;
+                                2'b01: state_d = WAIT_LAST_W_READY_AW_READY;
+                                2'b10: state_d = WAIT_LAST_W_READY;
+                                default:;
+                            endcase
+                        end
+                    // read
+                    end else begin
+
+                        axi_req_o.ar_valid = 1'b1;
+                        gnt_o = axi_resp_i.ar_ready;
+                        if (type_i != ariane_axi::SINGLE_REQ) begin
+                            axi_req_o.ar.len = BURST_SIZE;
+                            cnt_d = BURST_SIZE;
+                        end
+
+                        if (axi_resp_i.ar_ready) begin
+                            state_d = (type_i == ariane_axi::SINGLE_REQ) ? WAIT_R_VALID : WAIT_R_VALID_MULTIPLE;
+                            addr_offset_d = addr_i[ADDR_INDEX-1+3:3];
+                        end
+                    end
+                end
+            end
+
+            // ~> from single write
+            WAIT_AW_READY: begin
+                axi_req_o.aw_valid = 1'b1;
+
+                if (axi_resp_i.aw_ready) begin
+                    gnt_o   = 1'b1;
+                    state_d = WAIT_B_VALID;
+                end
+            end
+
+            // ~> we need to wait for an aw_ready and there is at least one outstanding write
+            WAIT_LAST_W_READY_AW_READY: begin
+                axi_req_o.w_valid  = 1'b1;
+                axi_req_o.w.last   = (cnt_q == '0);
+                if (type_i == ariane_axi::SINGLE_REQ) begin
+                    axi_req_o.w.data   = wdata_i[0];
+                    axi_req_o.w.strb   = be_i[0];
+                end else begin
+                    axi_req_o.w.data   = wdata_i[BURST_SIZE-cnt_q];
+                    axi_req_o.w.strb   = be_i[BURST_SIZE-cnt_q];
+                end
+                axi_req_o.aw_valid = 1'b1;
+                // we are here because we want to write a cache line
+                axi_req_o.aw.len   = BURST_SIZE;
+                // we got an aw_ready
+                case ({axi_resp_i.aw_ready, axi_resp_i.w_ready})
+                    // we got an aw ready
+                    2'b01: begin
+                        // are there any outstanding transactions?
+                        if (cnt_q == 0)
+                            state_d = WAIT_AW_READY_BURST;
+                        else // yes, so reduce the count and stay here
+                            cnt_d = cnt_q - 1;
+                    end
+                    2'b10: state_d = WAIT_LAST_W_READY;
+                    2'b11: begin
+                        // we are finished
+                        if (cnt_q == 0) begin
+                            state_d  = WAIT_B_VALID;
+                            gnt_o    = 1'b1;
+                        // there are outstanding transactions
+                        end else begin
+                            state_d = WAIT_LAST_W_READY;
+                            cnt_d = cnt_q - 1;
+                        end
+                    end
+                    default:;
+               endcase
+
+            end
+
+            // ~> all data has already been sent, we are only waiting for the aw_ready
+            WAIT_AW_READY_BURST: begin
+                axi_req_o.aw_valid = 1'b1;
+                axi_req_o.aw.len   = BURST_SIZE;
+
+                if (axi_resp_i.aw_ready) begin
+                    state_d  = WAIT_B_VALID;
+                    gnt_o    = 1'b1;
+                end
+            end
+
+            // ~> from write, there is an outstanding write
+            WAIT_LAST_W_READY: begin
+                axi_req_o.w_valid = 1'b1;
+
+                if (type_i != ariane_axi::SINGLE_REQ) begin
+                    axi_req_o.w.data   = wdata_i[BURST_SIZE-cnt_q];
+                    axi_req_o.w.strb   = be_i[BURST_SIZE-cnt_q];
+                end
+
+                // this is the last write
+                if (cnt_q == '0) begin
+                    axi_req_o.w.last = 1'b1;
+                    if (axi_resp_i.w_ready) begin
+                        state_d  = WAIT_B_VALID;
+                        gnt_o    = 1'b1;
+                    end
+                end else if (axi_resp_i.w_ready) begin
+                    cnt_d = cnt_q - 1;
+                end
+            end
+
+            // ~> finish write transaction
+            WAIT_B_VALID: begin
+                axi_req_o.b_ready = 1'b1;
+                id_o = axi_resp_i.b.id;
+
+                // Write is valid
+                if (axi_resp_i.b_valid) begin
+                    state_d = IDLE;
+                    valid_o = 1'b1;
+                end
+            end
+
+            // ~> cacheline read, single read
+            WAIT_R_VALID_MULTIPLE, WAIT_R_VALID: begin
+                if (CRITICAL_WORD_FIRST)
+                    index = addr_offset_q + (BURST_SIZE-cnt_q);
+                else
+                    index = BURST_SIZE-cnt_q;
+
+                // reads are always wrapping here
+                axi_req_o.r_ready = 1'b1;
+                // this is the first read a.k.a the critical word
+                if (axi_resp_i.r_valid) begin
+                    if (CRITICAL_WORD_FIRST) begin
+                        // this is the first word of a cacheline read, e.g.: the word which was causing the miss
+                        if (state_q == WAIT_R_VALID_MULTIPLE && cnt_q == BURST_SIZE) begin
+                            critical_word_valid_o = 1'b1;
+                            critical_word_o       = axi_resp_i.r.data;
+                        end
+                    end else begin
+                        // check if the address offset matches - then we are getting the critical word
+                        if (index == addr_offset_q) begin
+                            critical_word_valid_o = 1'b1;
+                            critical_word_o       = axi_resp_i.r.data;
+                        end
+                    end
+
+                    // this is the last read
+                    if (axi_resp_i.r.last) begin
+                        id_d    = axi_resp_i.r.id;
+                        state_d = COMPLETE_READ;
+                    end
+
+                    // save the word
+                    if (state_q == WAIT_R_VALID_MULTIPLE) begin
+                        cache_line_d[index] = axi_resp_i.r.data;
+
+                    end else
+                        cache_line_d[0] = axi_resp_i.r.data;
+
+                    // Decrease the counter
+                    cnt_d = cnt_q - 1;
+                end
+            end
+            // ~> read is complete
+            COMPLETE_READ: begin
+                valid_o = 1'b1;
+                state_d = IDLE;
+                id_o    = id_q;
+            end
+        endcase
+    end
+
+    // ----------------
+    // Registers
+    // ----------------
+    always_ff @(posedge clk_i or negedge rst_ni) begin
+        if (~rst_ni) begin
+            // start in flushing state and initialize the memory
+            state_q       <= IDLE;
+            cnt_q         <= '0;
+            cache_line_q  <= '0;
+            addr_offset_q <= '0;
+            id_q          <= '0;
+        end else begin
+            state_q       <= state_d;
+            cnt_q         <= cnt_d;
+            cache_line_q  <= cache_line_d;
+            addr_offset_q <= addr_offset_d;
+            id_q          <= id_d;
+        end
+    end
+
+endmodule
diff --git a/src/csr_regfile.sv b/src/csr_regfile.sv
index 46587622..e92ae1f8 100644
--- a/src/csr_regfile.sv
+++ b/src/csr_regfile.sv
@@ -1089,6 +1089,7 @@ module csr_regfile import ariane_pkg::*; #(
 `endif
             dcsr_q                 <= '0;
             dcsr_q.prv             <= riscv::PRIV_LVL_M;
+            dcsr_q.xdebugver       <= 4'h4;
             dpc_q                  <= '0;
             dscratch0_q            <= {riscv::XLEN{1'b0}};
             dscratch1_q            <= {riscv::XLEN{1'b0}};
diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv
index 5bcf0e45..a9c5c220 100644
--- a/src/frontend/frontend.sv
+++ b/src/frontend/frontend.sv
@@ -24,7 +24,7 @@ module frontend import ariane_pkg::*; #(
   input  logic               flush_bp_i,         // flush branch prediction
   input  logic               debug_mode_i,
   // global input
-  input  logic [63:0]        boot_addr_i,
+  input  logic [riscv::XLEN-1:0]        boot_addr_i,
   // Set a new PC
   // mispredict
   input  bp_resolve_t        resolved_branch_i,  // from controller signaling a branch_predict -> update BTB
diff --git a/sw/bsp/config/fpga_platform_config.h b/sw/bsp/config/fpga_platform_config.h
index 6c11bb82..e0bd0d49 100644
--- a/sw/bsp/config/fpga_platform_config.h
+++ b/sw/bsp/config/fpga_platform_config.h
@@ -35,7 +35,7 @@
  * Platform frequency
  */
 
-#define FPGA_UART_0_FREQUENCY 50000000
+#define FPGA_UART_0_FREQUENCY 25000000
 
 
 /***************************************************************************//**
diff --git a/sw/bsp/config/link.ld b/sw/bsp/config/link.ld
index fa397107..5856d17a 100644
--- a/sw/bsp/config/link.ld
+++ b/sw/bsp/config/link.ld
@@ -32,7 +32,7 @@ MEMORY
 	   allowing initialized sections to be placed there). Infact we dump all
 	   sections to ram. */
 
-	ram (rwxai) : ORIGIN = 0x80000000, LENGTH = 0x40000
+	ram (rwxai) : ORIGIN = 0x80000000, LENGTH = 0x20000
 	dbg (rwxai) : ORIGIN = 0x1A110800, LENGTH = 0x1000
 }
 
diff --git a/tb/jtag_pkg.sv b/tb/jtag_pkg.sv
index dcec049b..3ac44d68 100644
--- a/tb/jtag_pkg.sv
+++ b/tb/jtag_pkg.sv
@@ -53,7 +53,7 @@ package jtag_pkg;
 
    task automatic jtag_wait_halfperiod(input int cycles);
       //#(50000*cycles);
-      #(100*cycles);
+      #(5*cycles);
    endtask
 
    task automatic jtag_clock(
@@ -461,7 +461,7 @@ package jtag_pkg;
          ref logic s_trstn,
          ref logic s_tdi
       );
-         JTAG_reg #(.size(32+1), .instr({JTAG_SOC_DMIACCESS, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
+         JTAG_reg #(.size(32), .instr({JTAG_SOC_DMIACCESS, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
          jtag_soc_dbg.setIR(s_tck, s_tms, s_trstn, s_tdi);
 
       endtask
@@ -473,7 +473,7 @@ package jtag_pkg;
          ref logic s_tdi
       );
 
-         JTAG_reg #(.size(32+1), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
+         JTAG_reg #(.size(32), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
          jtag_soc_dbg.setIR(s_tck, s_tms, s_trstn, s_tdi);
 
       endtask
@@ -841,12 +841,12 @@ package jtag_pkg;
          ref logic s_tdi,
          ref logic s_tdo
       );
-         logic [31+1:0] dataout;
-         JTAG_reg #(.size(32+1), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
+         logic [31:0] dataout;
+         JTAG_reg #(.size(32), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
          jtag_soc_dbg.start_shift(s_tck, s_tms, s_trstn, s_tdi);
-         jtag_soc_dbg.shift_nbits(32+1, '0, dataout, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+         jtag_soc_dbg.shift_nbits(32, '0, dataout, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
          jtag_soc_dbg.idle(s_tck, s_tms, s_trstn, s_tdi);
-         dtmcs = dataout[32:1];
+         dtmcs = dataout[31:0];
       endtask
 
       task write_dtmcs(
@@ -857,10 +857,10 @@ package jtag_pkg;
          ref logic s_tdi,
          ref logic s_tdo
       );
-         logic [31+1:0] dataout;
-         JTAG_reg #(.size(32+1), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
+         logic [31:0] dataout;
+         JTAG_reg #(.size(32), .instr({JTAG_SOC_DTMCSR, JTAG_SOC_BYPASS})) jtag_soc_dbg = new;
          jtag_soc_dbg.start_shift(s_tck, s_tms, s_trstn, s_tdi);
-         jtag_soc_dbg.shift_nbits(32+1, {dtmcs, 1'b0}, dataout, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+         jtag_soc_dbg.shift_nbits(32, {dtmcs, 1'b0}, dataout, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
          jtag_soc_dbg.idle(s_tck, s_tms, s_trstn, s_tdi);
 
       endtask
@@ -1153,12 +1153,12 @@ package jtag_pkg;
                    s_tdo
              );
              if (dmi_op == 2'h2) begin
-                 $display("[TB] %t dmi previous operation failed, not handled", $realtime);
+                 $display("[TB] %t read_debug_reg dmi previous operation failed, not handled", $realtime);
                  dmi_op = 2'h0; // TODO: for now we just force completion
              end
 
              if (dmi_op == 2'h3) begin
-                 $display("[TB] %t retrying debug reg access", $realtime);
+                 $display("[TB] %t read_debug_reg retrying debug reg access", $realtime);
                  this.dmi_reset(s_tck,s_tms,s_trstn,s_tdi,s_tdo);
                  this.init_dmi_access(s_tck,s_tms,s_trstn,s_tdi);
              end
@@ -1220,12 +1220,12 @@ package jtag_pkg;
                    s_tdo
              );
              if (dmi_op == 2'h2) begin
-                 $display("[TB] %t dmi previous operation failed, not handled", $realtime);
+                 $display("[TB] %t write_debug_reg dmi previous operation failed, not handled", $realtime);
                  dmi_op = 2'h0; // TODO: for now we just force completion
              end
 
              if (dmi_op == 2'h3) begin
-                 $display("[TB] %t retrying debug reg access", $realtime);
+                 $display("[TB] %t write_debug_reg retrying debug reg access", $realtime);
                  this.dmi_reset(s_tck,s_tms,s_trstn,s_tdi,s_tdo);
                  this.init_dmi_access(s_tck,s_tms,s_trstn,s_tdi);
              end
@@ -1684,6 +1684,102 @@ package jtag_pkg;
       
             endtask
 
+	task load_L2_ariane(
+               input int   num_stim,
+               ref   logic [95:0] stimuli [100000:0],
+               ref   logic s_tck,
+               ref   logic s_tms,
+               ref   logic s_trstn,
+               ref   logic s_tdi,
+               ref   logic s_tdo
+            );
+      
+               logic [1:0][31:0]   jtag_data;
+               logic [31:0]        jtag_addr;
+               logic [31:0]        spi_addr;
+               logic [31:0]        spi_addr_old;
+               logic               more_stim = 1;
+               logic [1:0]         dm_op;
+               logic [31:0]        dm_data;
+               logic [6:0]         dm_addr;
+      
+               spi_addr        = stimuli[num_stim][95:64]; // assign address
+               jtag_data[0]    = stimuli[num_stim][63:0];  // assign data
+      
+               this.set_sbreadonaddr(1'b0, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+               this.set_sbautoincrement(1'b0, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+      
+               $display("[JTAG] Loading L2 with debug module jtag interface");
+      
+               spi_addr_old = spi_addr - 32'h8;
+      
+               while (more_stim) begin // loop until we have no more stimuli
+      
+                  jtag_addr = stimuli[num_stim][95:64];
+                  for (int i=0;i<256;i=i+2) begin
+                     spi_addr       = stimuli[num_stim][95:64]; // assign address
+                     jtag_data[0]   = stimuli[num_stim][31:0];  // assign data
+                     jtag_data[1]   = stimuli[num_stim][63:32]; // assign data
+      
+                     if (spi_addr != (spi_addr_old + 32'h8))
+                        begin
+                           spi_addr_old = spi_addr - 32'h8;
+                           break;
+                        end
+                     else begin
+                        num_stim = num_stim + 1;
+                     end
+                     if (num_stim > $size(stimuli) || stimuli[num_stim]===96'bx ) begin // make sure we have more stimuli
+                        more_stim = 0;                    // if not set variable to 0, will prevent additional stimuli to be applied
+                        break;
+                     end
+                     spi_addr_old = spi_addr;
+      
+                     this.set_dmi(
+                        2'b10,           //write
+                        7'h3D,           //sbdata1,
+                        jtag_data[1],    //data
+                        {dm_addr, dm_data, dm_op},
+                        s_tck,
+                        s_tms,
+                        s_trstn,
+                        s_tdi,
+                        s_tdo
+                     );
+
+                      this.set_dmi(
+                        2'b10,           //write
+                        7'h39,           //sbaddress0,
+                        spi_addr[31:0], //bootaddress
+                        {dm_addr, dm_data, dm_op},
+                        s_tck,
+                        s_tms,
+                        s_trstn,
+                        s_tdi,
+                        s_tdo
+                     );
+      
+                     this.set_dmi(
+                        2'b10,           //write
+                        7'h3C,           //sbdata0,
+                        jtag_data[0],    //data
+                        {dm_addr, dm_data, dm_op},
+                        s_tck,
+                        s_tms,
+                        s_trstn,
+                        s_tdi,
+                        s_tdo
+                     );
+      
+                     
+                  end
+                 // $display("[JTAG] Loading L2 - Written up to %x (%t)", spi_addr[31:0]+4, $realtime);
+      
+               end
+               this.set_sbreadonaddr(1'b1, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+               this.set_sbautoincrement(1'b0, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+      
+            endtask
       // discover harts by writting all ones to hartsel and reading it back
       task test_discover_harts(
          output logic        error,
diff --git a/tb/tb_cva6_zybo_z7_20.sv b/tb/tb_cva6_zybo_z7_20.sv
new file mode 100644
index 00000000..c3c2bb9c
--- /dev/null
+++ b/tb/tb_cva6_zybo_z7_20.sv
@@ -0,0 +1,236 @@
+`timescale 1ns/1ps
+
+
+import ariane_pkg::*;
+//import uvm_pkg::*;
+import jtag_pkg::*;
+//import pulp_tap_pkg::*;
+
+//`include "uvm_macros.svh"
+
+//`define MAIN_MEM(P) dut.i_sram.genblk1[0].i_ram.Mem_DP[(``P``)]
+
+//import "DPI-C" function read_elf(input string filename);
+//import "DPI-C" function byte get_section(output longint address, output longint len);
+//import "DPI-C" context function byte read_section(input longint address, inout byte buffer[]);
+
+
+`define EXIT_SUCCESS  0
+`define EXIT_FAIL     1
+`define EXIT_ERROR   -1
+
+
+module tb_cva6_zybo_z7_20;
+
+
+// enable Debug Module Tests
+parameter ENABLE_DM_TESTS = 0;
+
+
+
+// contains the program code
+string stimuli_file;
+
+/* simulation variables & flags */
+
+
+int                   num_stim;
+logic [95:0]          stimuli  [100000:0];                // array for the stimulus vectors
+
+logic                 dev_dpi_en = 0;
+logic [255:0][31:0]   jtag_data;
+
+
+
+//jtag_pkg::test_mode_if_t   test_mode_if = new;
+jtag_pkg::debug_mode_if_t  debug_mode_if = new;
+//pulp_tap_pkg::pulp_tap_if_soc_t pulp_tap = new;
+
+logic [8:0] jtag_conf_reg, jtag_conf_rego; //22bits but actually only the last 9bits are used
+localparam BEGIN_MEM_INSTR = 32'h80000080;
+
+int                   exit_status = `EXIT_ERROR;
+
+
+//    static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
+
+    localparam int unsigned CLOCK_PERIOD = 8ns;
+    // toggle with RTC period
+//    localparam int unsigned RTC_CLOCK_PERIOD = 30.517us;
+
+    localparam NUM_WORDS = 2**25;
+    logic clk_i;
+    logic rx;
+    logic tx;
+    logic rst_i;
+
+    logic        jtag_TCK;
+    logic        jtag_TMS;
+    logic        jtag_TDI;
+    logic        jtag_TRSTn;
+    logic        jtag_TDO_data;
+    logic        jtag_TDO_driven;
+
+    logic        s_trstn = 1'b0;
+    logic        s_tck   = 1'b0;
+    logic        s_tdi   = 1'b0;
+    logic        s_tms   = 1'b0;
+    logic        s_tdo;
+
+    longint unsigned cycles;
+    longint unsigned max_cycles;
+
+    logic [31:0]   gpr;
+
+    string binary = "";
+
+
+
+  cva6_zybo_z7_20 DUT(
+    .clk_sys(clk_i),
+    .cpu_reset       (rst_i),             //input  logic         cpu_reset   ,
+  
+
+    // jtag
+    .trst_n          (jtag_TRSTn),   //input logic      trst_n      ,
+    .tck             (jtag_TCK),     //input  logic        tck         ,
+    .tms             (jtag_TMS),     //input  logic        tms         ,
+    .tdi             (jtag_TDI),     //input  logic        tdi         ,
+    .tdo             (jtag_TDO_data),//output wire         tdo         ,
+  
+    //uart
+    .rx              (rx),         //input  logic        rx          ,
+    .tx              (tx)             //output logic        tx
+); 
+
+
+uart_bus
+  #(
+    .BAUD_RATE ( 115200),
+    .PARITY_EN ( 0)
+    ) i_uart_bus
+  (
+   
+    .rx              (tx),
+    .tx              (rx),  
+    .rx_en (1'b1)
+  );
+
+    assign jtag_TCK = s_tck;
+    assign jtag_TRSTn = s_trstn;
+    assign jtag_TMS = s_tms;
+    assign jtag_TDI = s_tdi;
+    
+    assign s_tdo = jtag_TDO_data;
+
+    initial begin
+        clk_i = 1'b0;
+
+        forever begin
+            #(CLOCK_PERIOD/2) clk_i = 1'b1;
+            #(CLOCK_PERIOD/2) clk_i = 1'b0;
+
+        end
+    end
+
+
+
+    // testbench driver process
+    initial
+    begin
+
+        logic [1:0]  dm_op;
+        logic [31:0] dm_data;
+        logic [6:0]  dm_addr;
+        logic        error;
+        automatic logic [9:0]  FC_CORE_ID = {5'd0,5'd0};
+
+        $display("[TB] %t - Asserting hard reset", $realtime);
+        //rst_ni = 1'b0;
+        rst_i = 1'b1;
+        
+        #200ns
+       
+        // read in the stimuli vectors  == address_value
+        if ($value$plusargs("stimuli=%s", stimuli_file)) begin
+            $display("Loading custom stimuli from %s", stimuli_file);
+	    $readmemh(stimuli_file, stimuli);
+        end else begin
+	    $display("Loading default stimuli");
+	    //$readmemh("/home/sjacq/Work_dir/USE_CASE/2020/ohg/test_ariane/bug_performance_cva6/sw/app/dhrystone.stim.txt", stimuli);
+	    $readmemh("/home/sjacq/Work_dir/USE_CASE/2020/contest_softcore_cva6/cva6-softcore-contest_zybo/fpga/sw_debug/app/helloworld.stim.txt", stimuli);
+        end
+
+        // before starting the actual boot procedure we do some light
+        // testing on the jtag link
+        jtag_pkg::jtag_reset(s_tck, s_tms, s_trstn, s_tdi);
+        jtag_pkg::jtag_softreset(s_tck, s_tms, s_trstn, s_tdi);
+        #5us;
+    
+        jtag_pkg::jtag_bypass_test(s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+        #5us;
+    
+        jtag_pkg::jtag_get_idcode(s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+        #5us;
+
+        rst_i = 1'b0;
+        #100us;
+        debug_mode_if.init_dmi_access(s_tck, s_tms, s_trstn, s_tdi);
+
+        debug_mode_if.set_dmactive(1'b1, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+    
+        debug_mode_if.set_hartsel(FC_CORE_ID, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+   $display("[TB] %t - Halting the Core", $realtime);
+    debug_mode_if.halt_harts(s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+    
+   $display("[TB] %t - reading gpr 0x1000 ", $realtime);
+    debug_mode_if.read_reg_abstract_cmd(16'h1000, gpr, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+   $display("[TB] %t - reading gpr 0x1001 ", $realtime);
+    debug_mode_if.read_reg_abstract_cmd(16'h1001, gpr, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+
+       debug_mode_if.test_read_sbcs(s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+    
+        $display("[TB] %t - Loading L2", $realtime);
+
+        // use debug module to load binary
+        debug_mode_if.load_L2_ini(num_stim, stimuli, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+        //debug_mode_if.load_L2_ariane(num_stim, stimuli, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+    
+        // write dpc to addr_i so that we know where we resume
+         debug_mode_if.write_reg_abstract_cmd(riscv::CSR_DPC,  BEGIN_MEM_INSTR,
+                                     s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+    
+        // we have set dpc and loaded the binary, we can go now
+        $display("[TB] %t - Resuming the CORE", $realtime);
+        debug_mode_if.resume_harts(s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+
+        #50000us;
+        // enable sb access for subsequent readMem calls
+        debug_mode_if.set_sbreadonaddr(1'b1, s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+    
+        // wait for end of computation signal
+        $display("[TB] %t - Waiting for end of computation", $realtime);
+    
+        jtag_data[0] = 0;
+        while(jtag_data[0][31] == 0) begin
+            debug_mode_if.readMem(32'h1A1040A0, jtag_data[0], s_tck, s_tms, s_trstn, s_tdi, s_tdo);
+            #50us;
+        end
+    
+        if (jtag_data[0][30:0] == 0)
+            exit_status = `EXIT_SUCCESS;
+        else
+            exit_status = `EXIT_FAIL;
+
+        $display("[TB] %t - Received status core: 0x%h", $realtime, jtag_data[0][30:0]);
+    
+        $stop;
+
+    end
+
+endmodule
-- 
GitLab