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. + +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. + + +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