diff --git a/Makefile b/Makefile
index 2b08ebea37c4946fc529fbf0322851fe5c822235..bf3e6a62c7a556817788542f6881d2f6b40fe9d0 100644
--- a/Makefile
+++ b/Makefile
@@ -288,7 +288,27 @@ 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 get_hs2_id
+
+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)
+
+
+get_hs2_sn:
+	@echo "[FPGA] Get HS2 serial number"
+	cd fpga && make get_hs2_sn 
 
 clean:
 	rm -rf $(riscv-torture-dir)/output/test*
diff --git a/README.md b/README.md
index 1fb75e26d90c46144db76397c9dabbe0ced85d7e..61a277f8903984d1fc74f275f3d33b9e86045895 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,8 @@ https://reference.digilentinc.com/reference/programmable-logic/guides/installati
 
 **be careful about your linux distribution and the supported version of Vitis 2020.1 environment**
 
+
+## Hardware 
 If you have not yet done so, start provisioning the following:
 
 | Reference	                 | URL                                                                             |	List price |	Remark                            |
@@ -73,15 +75,99 @@ If you have not yet done so, start provisioning the following:
 | Connectors                 |	https://store.digilentinc.com/pmod-cable-kit-2x6-pin-and-2x6-pin-to-dual-6-pin-pmod-splitter-cable/ | $5.99 |	At least a 6-pin connector Pmod is necessary; other references may offer it. |
 
 
-## Simulation get started
+## OpenOCD
+
+To be able to run and debug software applications on CVA6, you need to install the OpenOCD tool.
+OpenOCD is a free and open-source software distributed under the GPL-2.0 license.
+It provides on-chip programming and debugging support with a layered architecture of JTAG interface and TAP support.
+
+Global documentation on OpenOCD is available at https://github.com/ThalesGroup/pulpino-compliant-debug/tree/pulpino-dbg/doc/riscv-debug-notes/pdfs
+
+These documents aim at providing help about OpenOCD and RISC-V debug.
+
+Before setting up OpenOCD, other tools are needed:
+- make
+- libtool
+- pkg-congfig > 0.23
+- autoconf > 2.64
+- automake > 1.14
+- texinfo
+
+On Ubuntu, ensure that everything is installed with:
+```
+$ sudo apt install make libtool pkg-config autoconf automake texinfo
+```
+
+Furthermore, you need to set up libusb and libftdi libraries.
+On Ubuntu:
+```
+$ sudo apt install libusb-1.0-0-dev libftdi1-dev
+```
+
+Once all dependencies are installed, OpenOCD can be set up.
+- Download sources:
+```
+$ git clone https://github.com/riscv/riscv-openocd
+$ cd riscv-openocd
+```
+- Prepare a **build** directory:
+```
+$ mkdir build
+```
+- Launch the bootstrap script:
+```
+$ ./bootstrap
+```
+- Launch configure:
+```
+$ ./configure --enable-ftdi --prefix=<absolute path>/build --exec-prefix=<absolute path>/build
+```
+- Compile and install files:
+```
+$ make
+$ make install
+```
+When the installation is achieved, do not forget to add riscv-openocd/build/bin to your PATH.
+```
+$ export PATH=$PATH:<path to riscv-openocd>/build/bin
+```
+
+## HS2 cable
+
+It is necessary to add a udev rule to use the cable.
+OpenOCD provides a file containing the rule we need. Copy it into /etc/udev/rules.d/
+```
+$ sudo cp <path to riscv-openocd>/build/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d
+```
+The file is also available here: https://github.com/riscv/riscv-openocd/blob/riscv/contrib/60-openocd.rules
+The particular entry about the HS2 cable is :
+```
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="660", GROUP="plugdev", TAG+="uaccess"
+```
+Then either reboot your system or reload the udev configuration with :
+```
+$ sudo udevadm control --reload
+```
+
+To check if the cable is recognized, run lsusb. There should be a line like this:
+```
+$ lsusb
+```
+```
+Bus 005 Device 003: ID 0403:6014 Future Technology Devices International, Ltd FT232HSingle HS USB-UART/FIFO IC
+```
+
+
+
+# Simulation get started
 When the development environment is set up, it is now possible to run a simulation.
-Some software applications are available into the sw/app directory. Especially, there are benchmark applications such as Dhrystone and Coremark and other test applications.
+Some software applications are available into the sw/app directory. Especially, there are benchmark applications such as Dhrystone and CoreMark and other test applications.
 
 To simulate a software application on CVA6 processor, run the following command:
 ```
 $ make sim APP=’application to run’
 ```
-For instance, if you want to run Coremark application, you will have to run :
+For instance, if you want to run the CoreMark application, you will have to run :
 ```
 $ make sim APP=coremark
 ```
@@ -136,4 +222,132 @@ $ make cva6_ooc CLK_PERIOD_NS=20 BATCH_MODE=0
 This command generates synthesis and place and route reports in **fpga/reports_cva6_ooc_synth** and **fpga/reports_cva6_ooc_impl**.
 
 
+# FPGA platform
 
+A FPGA platform prototyping **CV32A6** (CVA6 in 32-bit flavor) has been implemented on **Zybo Z7-20** board.
+
+This platform integrates a CV32A6 processor (clocked to 25MHz), a JTAG interface to run and debug software applications and a UART interface to display strings on a hyperterminal.
+
+Below are described steps to run Coremark application on CV32A6 FPGA platform, steps are the same for Dhrystone application and other software applications.
+
+The JTAG-HS2 programming cable is initially a cable that allows programming of Xilinx FPGAs (bitstream loading) from a host PC.
+
+In our case, we use this cable to program software applications on the CV32A6 instantiated in the FPGA through a PMOD connector.
+
+We do not use the HS2 Cable in its original function therfore there is a preliminary step which consists in retrieving the serial number of the HS2 cable.
+
+To do this, connect the HS2 cable to the host PC (Zybo Z7-20 board must be disconnected from the host PC) and run the following command:
+```
+make get_hs2_sn
+```
+you should see:
+```
+[FPGA] Get HS2 serial number
+...............
+###############################
+# TARGEt: localhost:3121/xilinx_tcf/Digilent/<HS2's serial number>
+###############################
+......................
+```
+Replace the **HS2's serial number** in `fpga/scripts/program_cva-fpga.tcl` file by the serial number of your HS2 cable.
+
+## Get started with Coremark application
+
+1. First, make sure the Digilent **JTAG-HS2 debug adapter** is properly connected to the **PMOD JE** connector and that the USBUART adapter is properly connected to the **PMOD JB** connector of the Zybo Z7-20 board.
+![alt text](https://github.com/sjthales/cva6-softcore-contest/blob/master/docs/pictures/20201204_150708.jpg)
+2. Compile Coremark application in `sw/app`. Commands to compile Coremark application are described in `sw/app` directory.
+3. Generate the bitstream of the FPGA platform:
+```
+$ make cva6_fpga
+```
+4. When the bitstream is generated, switch on Zybo board and run:
+```
+$ make program_cva6_fpga
+```
+When the bitstream is loaded, the green LED `done` lights up.
+![alt text](https://github.com/sjthales/cva6-softcore-contest/blob/master/docs/pictures/20201204_160542.jpg)
+
+5. Then, in a terminal, launch **OpenOCD**:
+```
+$ openocd -f fpga/openocd_digilent_hs2.cfg
+```
+If it is successful, you should see:
+```
+Open On-Chip Debugger 0.10.0+dev-00832-gaec5cca (2019-12-10-14:21)
+Licensed under GNU GPL v2
+For bug reports, read
+    http://openocd.org/doc/doxygen/bugs.html
+Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
+Info : clock speed 1000 kHz
+Info : JTAG tap: riscv.cpu tap/device found: 0x249511c3 (mfg: 0x0e1 (Wintec Industries), part: 0x4951, ver: 0x2)
+Info : datacount=2 progbufsize=8
+Info : Examined RISC-V core; found 1 harts
+Info :  hart 0: XLEN=32, misa=0x40141105
+Info : Listening on port 3333 for gdb connections
+Ready for Remote Connections
+Info : Listening on port 6666 for tcl connections
+Info : Listening on port 4444 for telnet connections
+
+```
+6. In separate terminal, launch **gdb**:
+```
+$ riscv32-unknown-elf-gdb sw/app/coremark.riscv
+```
+you must use the gdb from the RISC-V toolchain. If it is successful, you should see:
+```
+GNU gdb (GDB) 9.1
+Copyright (C) 2020 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+Type "show copying" and "show warranty" for details.
+This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv32-unknown-elf".
+Type "show configuration" for configuration details.
+For bug reporting instructions, please see:
+<http://www.gnu.org/software/gdb/bugs/>.
+Find the GDB manual and other documentation resources online at:
+    <http://www.gnu.org/software/gdb/documentation/>.
+
+For help, type "help".
+Type "apropos word" to search for commands related to "word"...
+Reading symbols from sw/app/coremark.riscv...
+(gdb) 
+```
+7. In **gdb**, you need to connect gdb to openocd:
+```
+(gdb) target remote :3333
+```
+if it is successful, you should see the gdb connection in **openocd**:
+```
+Info : accepting 'gdb' connection on tcp/3333
+```
+8. In **gdb**, load **coremark.riscv** to CV32A6 FPGA platform by the **load** command:
+```
+(gdb) load
+Loading section .vectors, size 0x80 lma 0x80000000
+Loading section .init, size 0x60 lma 0x80000080
+Loading section .text, size 0x19010 lma 0x800000e0
+Loading section .rodata, size 0x1520 lma 0x800190f0
+Loading section .eh_frame, size 0x50 lma 0x8001a610
+Loading section .init_array, size 0x4 lma 0x8001a660
+Loading section .data, size 0x9d4 lma 0x8001a668
+Loading section .sdata, size 0x40 lma 0x8001b040
+Start address 0x80000080, load size 110712
+Transfer rate: 63 KB/sec, 7908 bytes/write.
+```
+
+9. At last, in **gdb**, you can run the coremark application by command `c`:
+```
+(gdb) c
+Continuing.
+(gdb) 
+```
+
+10. On the hyperterminal configured on /dev/ttyUSB0 11520-8-N-1, you should see:
+```
+2K performance run parameters for coremark.
+
+....
+
+CoreMark 1.0 : [the CoreMark score
+```
diff --git a/docs/pictures/20201204_150708.jpg b/docs/pictures/20201204_150708.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..261ec08ad9ad66e93212d0660ee9cb1e32196fcf
Binary files /dev/null and b/docs/pictures/20201204_150708.jpg differ
diff --git a/docs/pictures/20201204_160542.jpg b/docs/pictures/20201204_160542.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..f225c0a54d0b28d2e269259b910f267a8be678a6
Binary files /dev/null and b/docs/pictures/20201204_160542.jpg differ
diff --git a/fpga/Makefile b/fpga/Makefile
index 13dbd64dbd39cfd9911c664f071788ecee24389d..7b7a9e623b416b35559545025ce7b5c1bbaf4aed 100644
--- a/fpga/Makefile
+++ b/fpga/Makefile
@@ -29,15 +29,51 @@
 
 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
 
+get_hs2_sn:
+	$(VIVADO) -mode batch -source scripts/get_hs2_sn.tcl
+
+
+
+
+$(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 +81,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 0000000000000000000000000000000000000000..5b30ffc3d76b793cb6dcf86b909f1d1238fc8470
--- /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 0000000000000000000000000000000000000000..502343bcef09f83ed750a24b267752848095fa98
--- /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_digilent_hs2.cfg b/fpga/openocd_digilent_hs2.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7387551c2c489dbbd8fad755bcfb1345a6f6c0aa
--- /dev/null
+++ b/fpga/openocd_digilent_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/get_hs2_sn.tcl b/fpga/scripts/get_hs2_sn.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..e51859355f30fee083bf6fcdf0ee11b777d467e2
--- /dev/null
+++ b/fpga/scripts/get_hs2_sn.tcl
@@ -0,0 +1,8 @@
+open_hw_manager
+connect_hw_server
+foreach TARGET [get_hw_targets] {
+     puts "###############################"
+     puts "# TARGET: $TARGET"
+     puts "###############################"
+}
+
diff --git a/fpga/scripts/program_cva6_fpga.tcl b/fpga/scripts/program_cva6_fpga.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..0fa97ab1eb2ff68e75657957667802d20f2f2918
--- /dev/null
+++ b/fpga/scripts/program_cva6_fpga.tcl
@@ -0,0 +1,13 @@
+open_hw_manager
+connect_hw_server
+current_hw_target [get_hw_targets -filter {NAME!~"localhost:3121/xilinx_tcf/Digilent/<HS2's serial number>"}]
+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 0000000000000000000000000000000000000000..9c5f07d32748f1cca19402db4fa085b183d752b4
--- /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 e551bdab8dfdee0e7b2e752c7a77a34d0c29384e..8eac9f6dfa9df398b85ce1496d4dba7ca0338cf7 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 e8c4d17418e41d42051fbda590776ffb83f6e35b..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..8327a91302bb89754b7e8e50de39fa73f5b99308
--- /dev/null
+++ b/fpga/src/cva6_zybo_z7_20.sv
@@ -0,0 +1,757 @@
+// Copyright (c) 2020 Thales.
+// 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.
+//
+// Author: Sebastien Jacq Thales Research & Technology
+// Date: 07/12/2017
+//
+// Additional contributions by:
+//         Sebastien Jacq - sjthales on github.com
+//
+// Description: Zybo z7-20 FPGA platform top module.
+//
+// =========================================================================== //
+// Revisions  :
+// Date        Version  Author       Description
+// 2020-12-07  0.1      S.Jacq       Top module of Zybo z7-20 FPGA platform
+// =========================================================================== //
+
+module cva6_zybo_z7_20 (
+
+  input  logic     clk_sys   ,
+  input  logic     cpu_reset ,
+
+  // 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 = ~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              ( 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_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].ar_id = dm_axi_m_req.ar.id;
+
+assign master[ariane_soc::Debug].r_user ='0;
+assign master[ariane_soc::Debug].b_user ='0;
+
+
+
+xlnx_axi_dwidth_converter_dm_slave  i_axi_dwidth_converter_dm_slave( 
+    .s_axi_aclk(clk),
+    .s_axi_aresetn(ndmreset_n),
+    .s_axi_awid(master[ariane_soc::Debug].aw_id),
+    .s_axi_awaddr(master[ariane_soc::Debug].aw_addr[31:0]),
+    .s_axi_awlen(master[ariane_soc::Debug].aw_len),
+    .s_axi_awsize(master[ariane_soc::Debug].aw_size),
+    .s_axi_awburst(master[ariane_soc::Debug].aw_burst),
+    .s_axi_awlock(master[ariane_soc::Debug].aw_lock),
+    .s_axi_awcache(master[ariane_soc::Debug].aw_cache),
+    .s_axi_awprot(master[ariane_soc::Debug].aw_prot),
+    .s_axi_awregion(master[ariane_soc::Debug].aw_region),
+    .s_axi_awqos(master[ariane_soc::Debug].aw_qos),
+    .s_axi_awvalid(master[ariane_soc::Debug].aw_valid),
+    .s_axi_awready(master[ariane_soc::Debug].aw_ready),
+    .s_axi_wdata(master[ariane_soc::Debug].w_data),
+    .s_axi_wstrb(master[ariane_soc::Debug].w_strb),
+    .s_axi_wlast(master[ariane_soc::Debug].w_last),
+    .s_axi_wvalid(master[ariane_soc::Debug].w_valid),
+    .s_axi_wready(master[ariane_soc::Debug].w_ready),
+    .s_axi_bid(master[ariane_soc::Debug].b_id),
+    .s_axi_bresp(master[ariane_soc::Debug].b_resp),
+    .s_axi_bvalid(master[ariane_soc::Debug].b_valid),
+    .s_axi_bready(master[ariane_soc::Debug].b_ready),
+    .s_axi_arid(master[ariane_soc::Debug].ar_id),
+    .s_axi_araddr(master[ariane_soc::Debug].ar_addr[31:0]),
+    .s_axi_arlen(master[ariane_soc::Debug].ar_len),
+    .s_axi_arsize(master[ariane_soc::Debug].ar_size),
+    .s_axi_arburst(master[ariane_soc::Debug].ar_burst),
+    .s_axi_arlock(master[ariane_soc::Debug].ar_lock),
+    .s_axi_arcache(master[ariane_soc::Debug].ar_cache),
+    .s_axi_arprot(master[ariane_soc::Debug].ar_prot),
+    .s_axi_arregion(master[ariane_soc::Debug].ar_region),
+    .s_axi_arqos(master[ariane_soc::Debug].ar_qos),
+    .s_axi_arvalid(master[ariane_soc::Debug].ar_valid),
+    .s_axi_arready(master[ariane_soc::Debug].ar_ready),
+    .s_axi_rid(master[ariane_soc::Debug].r_id),
+    .s_axi_rdata(master[ariane_soc::Debug].r_data),
+    .s_axi_rresp(master[ariane_soc::Debug].r_resp),
+    .s_axi_rlast(master[ariane_soc::Debug].r_last),
+    .s_axi_rvalid(master[ariane_soc::Debug].r_valid),
+    .s_axi_rready(master[ariane_soc::Debug].r_ready),
+    .m_axi_awaddr(master_to_dm[0].aw_addr),
+    .m_axi_awlen(master_to_dm[0].aw_len),
+    .m_axi_awsize(master_to_dm[0].aw_size),
+    .m_axi_awburst(master_to_dm[0].aw_burst),
+    .m_axi_awlock(master_to_dm[0].aw_lock),
+    .m_axi_awcache(master_to_dm[0].aw_cache),
+    .m_axi_awprot(master_to_dm[0].aw_prot),
+    .m_axi_awregion(master_to_dm[0].aw_region),
+    .m_axi_awqos(master_to_dm[0].aw_qos),
+    .m_axi_awvalid(master_to_dm[0].aw_valid),
+    .m_axi_awready(master_to_dm[0].aw_ready),
+    .m_axi_wdata(master_to_dm[0].w_data ),
+    .m_axi_wstrb(master_to_dm[0].w_strb),
+    .m_axi_wlast(master_to_dm[0].w_last),
+    .m_axi_wvalid(master_to_dm[0].w_valid),
+    .m_axi_wready(master_to_dm[0].w_ready),
+    .m_axi_bresp(master_to_dm[0].b_resp),
+    .m_axi_bvalid(master_to_dm[0].b_valid),
+    .m_axi_bready(master_to_dm[0].b_ready),
+    .m_axi_araddr(master_to_dm[0].ar_addr),
+    .m_axi_arlen(master_to_dm[0].ar_len),
+    .m_axi_arsize(master_to_dm[0].ar_size),
+    .m_axi_arburst(master_to_dm[0].ar_burst),
+    .m_axi_arlock(master_to_dm[0].ar_lock),
+    .m_axi_arcache(master_to_dm[0].ar_cache),
+    .m_axi_arprot(master_to_dm[0].ar_prot),
+    .m_axi_arregion(master_to_dm[0].ar_region),
+    .m_axi_arqos(master_to_dm[0].ar_qos),
+    .m_axi_arvalid(master_to_dm[0].ar_valid),
+    .m_axi_arready(master_to_dm[0].ar_ready),
+    .m_axi_rdata(master_to_dm[0].r_data),
+    .m_axi_rresp(master_to_dm[0].r_resp),
+    .m_axi_rlast(master_to_dm[0].r_last),
+    .m_axi_rvalid(master_to_dm[0].r_valid),
+    .m_axi_rready(master_to_dm[0].r_ready)
+  );
+
+
+/*****************************************************************/
+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].aw_id = dm_axi_m_req.aw.id;
+assign slave[1].ar_id = dm_axi_m_req.ar.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),
+    .s_axi_aresetn(ndmreset_n),
+    .s_axi_awid(dm_axi_m_req.aw.id),
+    .s_axi_awaddr(dm_axi_m_req.aw.addr[31:0]),
+    .s_axi_awlen(dm_axi_m_req.aw.len),
+    .s_axi_awsize(dm_axi_m_req.aw.size),
+    .s_axi_awburst(dm_axi_m_req.aw.burst),
+    .s_axi_awlock(dm_axi_m_req.aw.lock),
+    .s_axi_awcache(dm_axi_m_req.aw.cache),
+    .s_axi_awprot(dm_axi_m_req.aw.prot),
+    .s_axi_awregion(dm_axi_m_req.aw.region),
+    .s_axi_awqos(dm_axi_m_req.aw.qos),
+    .s_axi_awvalid(dm_axi_m_req.aw_valid),
+    .s_axi_awready(dm_axi_m_resp.aw_ready),
+    .s_axi_wdata(dm_axi_m_req.w.data[31:0]),
+    .s_axi_wstrb(dm_axi_m_req.w.strb[3:0]),
+    .s_axi_wlast(dm_axi_m_req.w.last),
+    .s_axi_wvalid(dm_axi_m_req.w_valid),
+    .s_axi_wready(dm_axi_m_resp.w_ready),
+    .s_axi_bid(dm_axi_m_resp.b.id),
+    .s_axi_bresp(dm_axi_m_resp.b.resp),
+    .s_axi_bvalid(dm_axi_m_resp.b_valid),
+    .s_axi_bready(dm_axi_m_req.b_ready),
+    .s_axi_arid(dm_axi_m_req.ar.id),
+    .s_axi_araddr(dm_axi_m_req.ar.addr[31:0]),
+    .s_axi_arlen(dm_axi_m_req.ar.len),
+    .s_axi_arsize(dm_axi_m_req.ar.size),
+    .s_axi_arburst(dm_axi_m_req.ar.burst),
+    .s_axi_arlock(dm_axi_m_req.ar.lock),
+    .s_axi_arcache(dm_axi_m_req.ar.cache),
+    .s_axi_arprot(dm_axi_m_req.ar.prot),
+    .s_axi_arregion(dm_axi_m_req.ar.region),
+    .s_axi_arqos(dm_axi_m_req.ar.qos),
+    .s_axi_arvalid(dm_axi_m_req.ar_valid),
+    .s_axi_arready(dm_axi_m_resp.ar_ready),
+    .s_axi_rid(dm_axi_m_resp.r.id),
+    .s_axi_rdata(dm_master_s_rdata),
+    .s_axi_rresp(dm_axi_m_resp.r.resp),
+    .s_axi_rlast(dm_axi_m_resp.r.last),
+    .s_axi_rvalid(dm_axi_m_resp.r_valid),
+    .s_axi_rready(dm_axi_m_req.r_ready),
+    .m_axi_awaddr(dm_master_m_awaddr),
+    .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_bresp(slave[1].b_resp),
+    .m_axi_bvalid(slave[1].b_valid),
+    .m_axi_bready(slave[1].b_ready),
+    .m_axi_araddr(dm_master_m_araddr),
+    .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_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)
+  );
+
+
+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_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
+);
+
+
+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 (      ),
+    .rstb_busy (      ),
+    .s_aclk ( clk ),
+    .s_aresetn ( ndmreset_n  ),
+    .s_axi_awid ( dram.aw_id ),
+    .s_axi_awaddr ( saxibram_awaddr ),
+    .s_axi_awlen ( dram.aw_len ),
+    .s_axi_awsize ( dram.aw_size ),
+    .s_axi_awburst ( dram.aw_burst ),
+    .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 ( saxibram_araddr ),
+    .s_axi_arlen ( dram.ar_len ),
+    .s_axi_arsize ( dram.ar_size ),
+    .s_axi_arburst( dram.ar_burst ),
+    .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 )
+  );
+
+endmodule
+
diff --git a/fpga/src/fan_ctrl.sv b/fpga/src/fan_ctrl.sv
deleted file mode 100644
index fb02114360bf8be93c170ab7d815621d30808c81..0000000000000000000000000000000000000000
--- 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 cd350a9355380ea6869c5ef8fad0bdde95d48dc4..0000000000000000000000000000000000000000
--- 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 a66e76383d85d5640aa912b9149b926eb49474e6..0000000000000000000000000000000000000000
--- 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 3886cae984a46903305159d7e182fb220edae747..0000000000000000000000000000000000000000
--- 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 47440a844bd2be1fdf33f6b298f9c184d5ac0e20..0000000000000000000000000000000000000000
--- 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 ab300420488ab5f94c177e8201f928a7def59e97..1ff44584f6f76c20fdf69617b46f5e9c1ae8556e 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 0000000000000000000000000000000000000000..12ef7f9f21283385fcbc0c7800c4d207d78ee32c
--- /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 0000000000000000000000000000000000000000..2b3c0c1e5185e765f4b03eb72ba9566145c47e68
--- /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 0000000000000000000000000000000000000000..60c91008bb2221d174da81da20ef74adccd4e3ff
--- /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 0000000000000000000000000000000000000000..426a7d735e06e6cf10cfd3fcd46b15b196cfa4e4
--- /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 0000000000000000000000000000000000000000..ba0551e7f361e1005d2588464133b688a27b7c7f
--- /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 0000000000000000000000000000000000000000..cdaf8cf96845c36358281750cfd6f600ca5ff258
--- /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 0000000000000000000000000000000000000000..ae2095f04a0a2f173028f056954e2d30c3363fac
--- /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 0000000000000000000000000000000000000000..4f8db458105ccca1395478a950ef8a2133176c53
--- /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 0000000000000000000000000000000000000000..e6dab6376672a87ef93fe95391d88bb4d2e7926e
--- /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 0000000000000000000000000000000000000000..767e364c93dfb16a1f6656b4d08edfec94c914a2
--- /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 0000000000000000000000000000000000000000..6324a5063dd2da019821b1be15ea30c8a249ae64
--- /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 0000000000000000000000000000000000000000..8ce5e6e63e4dfc0884356378e6a85fd093e4fa8a
--- /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 0000000000000000000000000000000000000000..26a329e61a19afe56ff651e9783fe2a07c4a48fc
--- /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 468da6ec35e1d3a8d7142ef67717dcec809a8b98..0868f7ebc8e796880158d0805b074888a2ab30de 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 0000000000000000000000000000000000000000..3669b37a5bccea94c9b7c086916daf3bf935bc9e
--- /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 46587622fcb83c7f72cc002388bd8d21bca2a58a..e92ae1f8c2ad4496004af356809dd3312518d358 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 5bcf0e45bdd692f719b2efcb1e124d1de98d9f00..a9c5c2206a831fadc7adf756cdb99ce5ca0478bb 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 6c11bb82f4c6f110210e86ffebddec173c497391..e0bd0d49ffafaf06db0cbb1b3752f65c5c3ec297 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 fa39710719310a6852a221efefbb71c0555abd24..5856d17abf1e072ae64c013ed2128624d7470310 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 dcec049b9e577ffaef58cd6703f3fc406e6d975f..3ac44d68572be544cd40995ac7014ebbbe9eb536 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 0000000000000000000000000000000000000000..2ebee9230be7c7e9ca9c86b9f20b2601586d95b8
--- /dev/null
+++ b/tb/tb_cva6_zybo_z7_20.sv
@@ -0,0 +1,248 @@
+// Copyright (c) 2020 Thales.
+// 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.
+//
+// Author: Sebastien Jacq Thales Research & Technology
+// Date: 07/12/2020
+//
+// Additional contributions by:
+//         Sebastien Jacq - sjthales on github.com
+//
+// Description: Zybo z7-20 FPGA platform level testbench module.
+//
+// =========================================================================== //
+// Revisions  :
+// Date        Version  Author       Description
+// 2020-12-07  0.1      S.Jacq       Testbench to test Zybo z7-20 FPGA platform
+// =========================================================================== //
+
+
+`timescale 1ns/1ps
+
+
+import ariane_pkg::*;
+import jtag_pkg::*;
+
+
+`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),   
+  
+
+    // jtag
+    .trst_n          (jtag_TRSTn),
+    .tck             (jtag_TCK),
+    .tms             (jtag_TMS),
+    .tdi             (jtag_TDI),
+    .tdo             (jtag_TDO_data),
+  
+    //uart
+    .rx              (rx), 
+    .tx              (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_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);
+
+   
+        // 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