diff --git a/deploy/bit-builder-recipes/xilinx_vc707.yaml b/deploy/bit-builder-recipes/xilinx_vc707.yaml new file mode 100644 index 0000000000..02bd75cc56 --- /dev/null +++ b/deploy/bit-builder-recipes/xilinx_vc707.yaml @@ -0,0 +1,16 @@ +# Build-time bitbuilder design configuration for the FireSim Simulation Manager +# See https://docs.fires.im/en/stable/Advanced-Usage/Manager/Manager-Configuration-Files.html for documentation of all of these params. + +########### +# Schema: +########### +# # Class name of the bitbuilder type. +# # This can be determined from `deploy/buildtools/bitbuilder.py`). +# bitbuilder_type: +# args: +# # Bitbuilder arguments that are passed to the `BitBuilder` +# # object. Determined by looking at `_parse_args` function of class. +# + +bit_builder_type: XilinxVC707BitBuilder +args: null diff --git a/deploy/buildtools/bitbuilder.py b/deploy/buildtools/bitbuilder.py index 1e6e5081c7..7bb332bd8d 100644 --- a/deploy/buildtools/bitbuilder.py +++ b/deploy/buildtools/bitbuilder.py @@ -748,6 +748,13 @@ def __init__(self, build_config: BuildConfig, args: Dict[str, Any]) -> None: super().__init__(build_config, args) self.BOARD_NAME = "au250" +class XilinxVC707BitBuilder(XilinxAlveoBitBuilder): + """Bit builder class that builds + a Xilinx VC707 bitstream from the build config.""" + def __init__(self, build_config: BuildConfig, args: Dict[str, Any]) -> None: + super().__init__(build_config, args) + self.BOARD_NAME = "vc707" + class XilinxVCU118BitBuilder(XilinxAlveoBitBuilder): """Bit builder class that builds a Xilinx VCU118 bitstream from the build config.""" BOARD_NAME: Optional[str] diff --git a/docs/Support-VC707/images/install.png b/docs/Support-VC707/images/install.png new file mode 100644 index 0000000000..1ea7f8634a Binary files /dev/null and b/docs/Support-VC707/images/install.png differ diff --git a/docs/Support-VC707/images/jtag.png b/docs/Support-VC707/images/jtag.png new file mode 100644 index 0000000000..38a8560355 Binary files /dev/null and b/docs/Support-VC707/images/jtag.png differ diff --git a/docs/Support-VC707/images/lspci.png b/docs/Support-VC707/images/lspci.png new file mode 100644 index 0000000000..5df1571c25 Binary files /dev/null and b/docs/Support-VC707/images/lspci.png differ diff --git a/docs/Support-VC707/install-new-fpga.md b/docs/Support-VC707/install-new-fpga.md new file mode 100644 index 0000000000..b918d182b8 --- /dev/null +++ b/docs/Support-VC707/install-new-fpga.md @@ -0,0 +1,40 @@ +## Software and hardware + +为了能运行 firesim,你需要准备如下软硬件环境: +软件环境: +- Ubuntu 20.04 LTS(OS recommended by Xilinx,避免 Xilinx 工具发生一些奇怪的错误) +- clash for linux(加速各种库各种依赖安装速度,否则可能会卡死在某个脚本) +- vivado 2023.1(生成能够烧写到 fpga 板子上的 bitstream) + +硬件环境: +- CPU 11th Gen Intel(R) Core(TM) i5-11500 @ 2.70GHz +- RAM 4*16g(32g、48g 或许也够了) +- VCU128(FPGA board) + - 六孔电源适配器(最好使用厂家自带的) + - micro-usb 用于烧写 bit 流 + - PCIE 延长线(板子太大,无法插进机箱的情况) + +## 安装 FPGA 板子到机箱 + +To install the board in a PC chassis: +1. Power down the host computer and remove the power cord from the PC. +2. 将六孔电源适配器的两端分别插到电源插座和 FPGA 板子上 +3. 将 micro-usb 的两端分别插到主机和 FPGA 板子上 +4. 将 PCIE 延长线插进主板的 PCIE 口,然后将 FPGA 板子插进 PCIE 延长线 +5. 拨动 FPGA 板上的 power on 开关,主机开机 +上述步骤都完成后如下图: +![alt text](./images/install.png) + +以下的步骤用于检测 jtag 和 PCIE 连接是否成功 +打开 vivado,open-Hardware-Manager,open-target,auto-connect,如果如下图所示,说明 jtag 连接成功,可以将 bitstream 烧写进 FPGA board: + +![alt text](./images/jtag.png) + + +因为 Firesim 是利用 XDMA ip 核通过 PCIE 实现主机和 FPGA 板卡的通信,因此我们还需要检查 PCIE 连接是否成功,建议运行 https://github.com/WangXuan95/Xilinx-FPGA-PCIe-XDMA-Tutorial 中的例程一,如果输入 lspci 能够看到 xilinx 设备,说明 PCIE 连接成功: + +![alt text](./images/lspci.png) + + +firesim 官方支持的 FPGA 板卡可以直接烧写官方提供的 bitstream,如果不是官方支持的板卡,就需要执行 firesim buildbitstream 来生成对应的比特流。 +不同的板卡支持不同的 PCIE 接口,并且 fpga 型号也不同,因此需要修改 blockdesign,如果修改后得到的 blockdesign 生成的 bitstream 能提供 firesim 需要的接口,移植最重要的一步就走通了,其余文件的修改就是令生成 rtl、生成 bitstream、跑 workload 等任务自动化。具体需要修改的文件可以参考:support-vc707.md。 \ No newline at end of file diff --git a/docs/Support-VC707/support-vc707.md b/docs/Support-VC707/support-vc707.md new file mode 100644 index 0000000000..500d4e740a --- /dev/null +++ b/docs/Support-VC707/support-vc707.md @@ -0,0 +1,127 @@ +# Adding support for VC707 + +First, you need to create a new folder under `~/firesim/platforms/` to store VC707 related design files and scripts. + +When creating new folders and files, rename `xilinx_alveo_u250` to your specific FPGA name (`xilinx_vc707`). + +```bash +cd ~/firesim/ +git checkout 12e2e0a (release 1.20.1) +git checkout -b vc707 +cd ~/firesim/platforms/ +mkdir xilinx_vc707 +``` + +>FPGAs in FireSim, when first developed, start with implementing/testing the AXI4-Lite interface before moving to add the DMA interface and DRAM. We highly recommend you to follow the same flow when adding an FPGA. + +## Adding a new FireSim `platform` + +In order to make firesim support VC707, we need to get the bitstream that can be programmed into the VC707 board, so we need to first understand how the `firesim buildbitstream` command generates the bitstream for the u250 board. + +Through `which firesim`, we can know that the firesim command actually runs the python program `~/firesim/deploy/firesim`. The specific tasks are defined in the python program. For example, the corresponding code of `firesim buildbitstream` is as follows: + +```python +@register_task +def buildbitstream(build_config_file: BuildConfigFile) -> None: + """ Starting from local Chisel, build a bitstream for all of the specified + hardware configs. """ + + # forced to build locally + for build_config in build_config_file.builds_list: + execute(build_config.bitbuilder.replace_rtl, hosts=['localhost']) + execute(build_config.bitbuilder.build_driver, hosts=['localhost']) + ... +``` + +Before running the `firesim buildbitstream` command, be sure to make some modifications to `./firesim/deploy/config_build.yaml`: modify `default_build_dir` to specify the directory to build in; modify `builds_ro_run` to determine the build object, for example, for u250, build `alveo_u250_firesim_rocket_singlecore_no_nic`. + +In the `buildbitstream` function, `build_config.bitbuilder.replace_rtl` actually executes the following command: + +```bash +cd ~/firesim/sim/ +make PLATFORM=xilinx_alveo_u250 TARGET_PROJECT=firesim DESIGN=FireSim TARGET_CONFIG=FireSimRocketConfig PLATFORM_CONFIG=BaseXilinxAlveoU250Config replace-rtl +``` + +This command actually executes the following content in `~/firesim/sim/make/fpga.mk`: + +```makefile +replace-rtl: $(fpga_delivery_files) $(fpga_sim_delivery_files) + +fpga_delivery_files = $(addprefix $(fpga_delivery_dir)/$(BASE_FILE_NAME), \ + .sv .defines.vh \ + .synthesis.xdc .implementation.xdc) + +fpga_sim_delivery_files = $(fpga_driver_dir)/$(DESIGN)-$(PLATFORM) +``` + +For the u250 board, the above `fpga_delivery_files` corresponds to + +``` +~/firesim/platforms/xilinx_alveo_u250/cl_xilinx_alveo_u250-firesim-FireSim-FireSimRocketConfig-BaseXilinxAlveoU250Config/design +|-- FireSim-generated.sv +|-- FireSim-generated.defines.vh +|-- FireSim-generated.synthesis.xdc +|-- FireSim-generated.implementation.xdc +``` + +The above `fpga_sim_delivery_file` corresponds to `~/firesim/platforms/xilinx_alveo_u250/cl_xilinx_alveo_u250-firesim-FireSim-FireSimRocketConfig-BaseXilinxAlveoU250Config/driver/FireSim-xilinx_alveo_u250` + + + +Before calling vivado to generate bitstream, you first need to automatically generate RTL through firesim, so you need to make some modifications to the files under `platforms/xilinx_alveo_u250/cl_firesim`. + +`platforms/xilinx_alveo_u250/cl_firesim` holds all RTL, TCL, and more needed to build a bitstream for a specific FPGA. + +First, you’ll need to add new Scala configurations to tell Golden Gate there is a new FPGA. + +```scala +class XilinxAlveoU250Config + extends Config(new Config((_, _, _) => { + case F1ShimHasQSFPPorts => true + case HostMemNumChannels => 1 + case PreLinkCircuitPath => Some("firesim_top") + case PostLinkCircuitPath => Some("firesim_top") + }) ++ new F1Config ++ new SimConfig) +``` + +Next, you’ll need to provide a C++ interface that allows FireSim to read/write to the FPGA’s MMIO (AXI4-Lite) and DMA (AXI4) port through XDMA. + +```c +uint32_t simif_xilinx_alveo_u250_t::read(size_t addr) { + uint32_t value; + int rc = fpga_pci_peek(addr, &value); + return value & 0xFFFFFFFF; +} +``` + +Next, you’ll need to add a hook to FireSim’s make system to build the FPGA RTL and also build the C++ driver with the given `simif_*` file. + +At this point you should be able to build the RTL using something like `make -C sim PLATFORM=xilinx_alveo_u250 xilinx_alveo_u250` where you can replace `xilinx_alveo_u250` with your FPGA platform name. This should build both the C++ driver and the RTL associated with it that is copied for synthesis. + + + +## Manager build modifications + +Next, you’ll need to tell the FireSim manager a new platform exists to use it in `firesim buildbitstream`. + +First, we need to add a “bit builder” class that gives the Python code necessary to build and synthesize the RTL on a build farm instance/machine and copy the results back into a FireSim HWDB entry. + +In the Xilinx Alveo U250 case, the `build_bitstream` function builds a bitstream by doing the following in Python: + +1. Creates a copy of the `platform` area previously described on the build farm machine/instance +2. Adds the RTL built with the `make` command from the prior section to that copied area (i.e. `CL_DIR`) +3. Runs the [platforms/xilinx_alveo_u250/build-bitstream.sh](https://www.github.com/firesim/firesim/blob/HEAD/platforms/xilinx_alveo_u250/build-bitstream.sh) script with the copied area. +4. Retrieves the bitstream built and compiles a `*.tar.gz` file with it. Uses that file in a HWDB entry. + +Next, since this class can take arguments from FireSim’s YAML, you’ll need to add a YAML file for a new FPGA in [deploy/bit-builder-recipes](https://www.github.com/firesim/firesim/blob/HEAD/deploy/bit-builder-recipes) (even if it has no args). + +Reference:https://docs.fires.im/en/latest/Advanced-Usage/Adding-FPGAs.html + + + + + + + + + diff --git a/platforms/xilinx_vc707/build-bitstream.sh b/platforms/xilinx_vc707/build-bitstream.sh new file mode 100755 index 0000000000..46ec8f1b67 --- /dev/null +++ b/platforms/xilinx_vc707/build-bitstream.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# This script is called by FireSim's bitbuilder to create a bit file + +# exit script if any command fails +set -e +set -o pipefail + +usage() { + echo "usage: ${0} [OPTIONS]" + echo "" + echo "Options" + echo " --cl_dir : Custom logic directory to build Vivado bitstream from" + echo " --frequency : Frequency in MHz of the desired FPGA host clock." + echo " --strategy : A string to a precanned set of build directives. + See aws-fpga documentation for more info/. + For this platform TIMING and AREA supported." + echo " --board : FPGA board {au200,au250,au280}." + echo " --help : Display this message" + exit "$1" +} + +CL_DIR="" +FREQUENCY="" +STRATEGY="" +BOARD="" + +# getopts does not support long options, and is inflexible +while [ "$1" != "" ]; +do + case $1 in + --help) + usage 1 ;; + --cl_dir ) + shift + CL_DIR=$1 ;; + --strategy ) + shift + STRATEGY=$1 ;; + --frequency ) + shift + FREQUENCY=$1 ;; + --board ) + shift + BOARD=$1 ;; + * ) + echo "invalid option $1" + usage 1 ;; + esac + shift +done + +if [ -z "$CL_DIR" ] ; then + echo "no cl directory specified" + usage 1 +fi + +if [ -z "$FREQUENCY" ] ; then + echo "No --frequency specified" + usage 1 +fi + +if [ -z "$STRATEGY" ] ; then + echo "No --strategy specified" + usage 1 +fi + +if [ -z "$BOARD" ] ; then + echo "No --board specified" + usage 1 +fi + +# run build +cd $CL_DIR +vivado -mode batch -source $CL_DIR/scripts/main.tcl -tclargs $FREQUENCY $STRATEGY $BOARD diff --git a/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_cdc_sync_exdes.v b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_cdc_sync_exdes.v new file mode 100644 index 0000000000..e7a67b0dc4 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_cdc_sync_exdes.v @@ -0,0 +1,658 @@ +/////////////////////////////////////////////////////////////////////////////// +// (c) Copyright 2013 Xilinx, Inc. All rights reserved. +// +// This file contains confidential and proprietary information +// of Xilinx, Inc. and is protected under U.S. and +// international copyright and other intellectual property +// laws. +// +// DISCLAIMER +// This disclaimer is not a license and does not grant any +// rights to the materials distributed herewith. Except as +// otherwise provided in a valid license issued to you by +// Xilinx, and to the maximum extent permitted by applicable +// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +// (2) Xilinx shall not be liable (whether in contract or tort, +// including negligence, or under any other theory of +// liability) for any loss or damage of any kind or nature +// related to, arising under or in connection with these +// materials, including for any direct, or any indirect, +// special, incidental, or consequential loss or damage +// (including loss of data, profits, goodwill, or any type of +// loss or damage suffered as a result of any action brought +// by a third party) even if such damage or loss was +// reasonably foreseeable or Xilinx had been advised of the +// possibility of the same. +// +// CRITICAL APPLICATIONS +// Xilinx products are not designed or intended to be fail- +// safe, or for use in any application requiring fail-safe +// performance, such as life-support or safety devices or +// systems, Class III medical devices, nuclear facilities, +// applications related to the deployment of airbags, or any +// other applications that could lead to death, personal +// injury, or severe property or environmental damage +// (individually and collectively, "Critical +// Applications"). Customer assumes the sole risk and +// liability of any use of Xilinx products in Critical +// Applications, subject only to applicable laws and +// regulations governing limitations on product liability. +// +// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +// PART OF THIS FILE AT ALL TIMES. +// +// +//////////////////////////////////////////////////////////////////////////////// +//Generic Help +//C_CDC_TYPE : Defines the type of CDC needed +// 0 means pulse synchronizer. Used to transfer one clock pulse +// from prmry domain to scndry domain. +// 1 means level synchronizer. Used to transfer level signal. +// 2 means level synchronizer with ack. Used to transfer level +// signal. Input signal should change only when prmry_ack is detected +// +//C_FLOP_INPUT : when set to 1 adds one flop stage to the input prmry_in signal +// Set to 0 when incoming signal is purely floped signal. +// +//C_RESET_STATE : Generally sync flops need not have resets. However, in some cases +// it might be needed. +// 0 means reset not needed for sync flops +// 1 means reset needed for sync flops. i +// In this case prmry_resetn should be in prmry clock, +// while scndry_reset should be in scndry clock. +// +//C_SINGLE_BIT : CDC should normally be done for single bit signals only. +// However, based on design buses can also be CDC'ed. +// 0 means it is a bus. In this case input be connected to prmry_vect_in. +// Output is on scndry_vect_out. +// 1 means it is a single bit. In this case input be connected to prmry_in. +// Output is on scndry_out. +// +//C_VECTOR_WIDTH : defines the size of bus. This is irrelevant when C_SINGLE_BIT = 1 +// +//C_MTBF_STAGES : Defines the number of sync stages needed. Allowed values are 0 to 6. +// Value of 0, 1 is allowed only for level CDC. +// Min value for Pulse CDC is 2 +// +//Whenever this file is used following XDC constraint has to be added + +// set_false_path -to [get_pins -hier *aurora_64b66b_0_cdc_to*/D] + + +//IO Ports +// +// prmry_aclk : clock of originating domain (source domain) +// prmry_resetn : sync reset of originating clock domain (source domain) +// prmry_in : input signal bit. This should be a pure flop output without +// any combi logic. This is source. +// prmry_vect_in : bus signal. From Source domain. +// prmry_ack : Ack signal, valid for one clock period, in prmry_aclk domain. +// Used only when C_CDC_TYPE = 2 +// scndry_aclk : destination clock. +// scndry_resetn : sync reset of destination domain +// scndry_out : sync'ed output in destination domain. Single bit. +// scndry_vect_out : sync'ed output in destination domain. bus. + + + +`timescale 1ps / 1ps + `define DLY #1 +(* DowngradeIPIdentifiedWarnings="yes" *) + +module aurora_64b66b_0_cdc_sync_exdes + # ( + parameter [1:0] c_cdc_type = 1, // 0 Pulse synchronizer, 1 level synchronizer 2 level synchronizer with ACK + parameter [0:0] c_flop_input = 0, // 1 Adds one flop stage to the input prmry_in signal + parameter [0:0] c_reset_state = 0, // 1 Reset needed for sync flops + parameter [0:0] c_single_bit = 1, // 1 single bit input. + parameter [5:0] c_vector_width = 32, // defines the size of bus and irrelevant when C_SINGLE_BIT = 1 + parameter [2:0] c_mtbf_stages = 2 // Number of sync stages needed + ) + ( + input prmry_aclk, + input prmry_rst_n, + input prmry_in, + input [(c_vector_width-1 ):0] prmry_vect_in, + input scndry_aclk, + input scndry_rst_n, + output prmry_ack, + output scndry_out, + output [(c_vector_width-1 ):0] scndry_vect_out + ); + + + // Internal signal declarations + wire s_out_re; + reg p_in_d1_cdc_from; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d1_aurora_64b66b_0_cdc_to; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d2; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d3; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d4; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d5; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d6; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_out_d7; + reg scndry_out_int_d1; + + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d1_aurora_64b66b_0_cdc_to; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d2; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d3; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d4; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d5; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg s_level_out_d6; + + reg p_level_in_d1_cdc_from; + wire p_level_in_int; + + wire [( c_vector_width - 1 ):0]p_level_in_bus_d1_cdc_from; + wire [( c_vector_width - 1 ):0]s_level_out_bus_d1_cdc_tig; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d1_aurora_64b66b_0_cdc_to; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d2; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d3; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d4; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d5; + (* ASYNC_REG = "true" *) (* shift_extract = "{no}" *) reg [( c_vector_width - 1 ):0] s_level_out_bus_d6; + + + wire scndry_out_int; + wire prmry_pulse_ack; + reg prmry_ack_int; + reg p_level_out_d1_aurora_64b66b_0_cdc_to; + reg p_level_out_d2; + reg p_level_out_d3; + reg p_level_out_d4; + reg p_level_out_d5; + reg p_level_out_d6; + reg p_level_out_d7; + + +// Pulse synchronizer Logic +generate if (c_cdc_type == 0) begin + + always @ ( posedge prmry_aclk) + begin : REG_P_IN + if ( ( prmry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + p_in_d1_cdc_from <= 1'b0; + end + else + begin + p_in_d1_cdc_from <= prmry_in ^ p_in_d1_cdc_from; + end + end + + always @ ( posedge scndry_aclk) + begin : P_IN_CROSS2SCNDRY + if ( ( scndry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + s_out_d1_aurora_64b66b_0_cdc_to <= 1'b0; + s_out_d2 <= 1'b0; + s_out_d3 <= 1'b0; + s_out_d4 <= 1'b0; + s_out_d5 <= 1'b0; + s_out_d6 <= 1'b0; + s_out_d7 <= 1'b0; + scndry_out_int_d1 <= 1'b0; + end + else + begin + s_out_d1_aurora_64b66b_0_cdc_to <= p_in_d1_cdc_from; + s_out_d2 <= s_out_d1_aurora_64b66b_0_cdc_to; + s_out_d3 <= s_out_d2; + s_out_d4 <= s_out_d3; + s_out_d5 <= s_out_d4; + s_out_d6 <= s_out_d5; + s_out_d7 <= s_out_d6; + scndry_out_int_d1 <= s_out_re; + end + end + assign scndry_out = scndry_out_int_d1; + assign prmry_ack = 1'b0; + assign scndry_vect_out = 0; +end +endgenerate + + +generate if (c_mtbf_stages == 2 & c_cdc_type == 0) begin + + assign s_out_re = ( s_out_d2 ^ s_out_d3 ); + +end +endgenerate + +generate if (c_mtbf_stages == 3 & c_cdc_type == 0) begin + + assign s_out_re = ( s_out_d3 ^ s_out_d4 ); + +end +endgenerate + +generate if (c_mtbf_stages == 4 & c_cdc_type == 0) begin + + assign s_out_re = ( s_out_d4 ^ s_out_d5 ); + +end +endgenerate + +generate if (c_mtbf_stages == 5 & c_cdc_type == 0) begin + + assign s_out_re = ( s_out_d5 ^ s_out_d6 ); + +end +endgenerate + +generate if (c_mtbf_stages == 6 & c_cdc_type == 0) begin + + assign s_out_re = ( s_out_d6 ^ s_out_d7 ); + +end +endgenerate + + +//Level Synchronizer Logic with out ACK + +generate if (c_flop_input == 1 & c_cdc_type == 1 & c_single_bit == 1) begin + + always @ ( posedge prmry_aclk) + begin : FLOP_IN + if ( ( prmry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + p_level_in_d1_cdc_from <= 1'b0; + end + else + begin + p_level_in_d1_cdc_from <= prmry_in; + end + end + + assign p_level_in_int = p_level_in_d1_cdc_from; + +end +endgenerate + + +generate if (c_flop_input == 0 & c_cdc_type == 1 & c_single_bit == 1) begin + + + assign p_level_in_int = prmry_in; + +end +endgenerate + + +//generate if (c_cdc_type == 1) begin +generate if (c_single_bit == 1 & c_cdc_type == 1) begin + + assign prmry_ack = 1'b0; + assign scndry_vect_out = 0; + + always @ ( posedge scndry_aclk) + begin : CROSS_PLEVEL_IN2SCNDRY + if ( ( scndry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + s_level_out_d1_aurora_64b66b_0_cdc_to <= 1'b0; + s_level_out_d2 <= 1'b0; + s_level_out_d3 <= 1'b0; + s_level_out_d4 <= 1'b0; + s_level_out_d5 <= 1'b0; + s_level_out_d6 <= 1'b0; + end + else + begin + s_level_out_d1_aurora_64b66b_0_cdc_to <= p_level_in_int; + s_level_out_d2 <= s_level_out_d1_aurora_64b66b_0_cdc_to; + s_level_out_d3 <= s_level_out_d2; + s_level_out_d4 <= s_level_out_d3; + s_level_out_d5 <= s_level_out_d4; + s_level_out_d6 <= s_level_out_d5; + end + end +end +endgenerate + + +generate if (c_mtbf_stages == 1 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d1_aurora_64b66b_0_cdc_to; +end +endgenerate + +generate if (c_mtbf_stages == 2 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d2; +end +endgenerate + +generate if (c_mtbf_stages == 3 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d3; +end +endgenerate + +generate if (c_mtbf_stages == 4 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d4; +end +endgenerate + +generate if (c_mtbf_stages == 5 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d5; +end +endgenerate + +generate if (c_mtbf_stages == 6 & c_cdc_type == 1 & c_single_bit == 1) begin + + assign scndry_out = s_level_out_d6; +end +endgenerate + +generate if (c_single_bit == 0 & c_cdc_type == 1) begin + + assign prmry_ack = 1'b0; + assign scndry_out = 1'b0; + + always @ ( posedge scndry_aclk) + begin : CROSS_PLEVEL_IN2SCNDRY + if ( ( scndry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + s_level_out_bus_d1_aurora_64b66b_0_cdc_to <= 0; + s_level_out_bus_d2 <= 0 ; + s_level_out_bus_d3 <= 0 ; + s_level_out_bus_d4 <= 0 ; + s_level_out_bus_d5 <= 0 ; + s_level_out_bus_d6 <= 0 ; + end + else + begin + s_level_out_bus_d1_aurora_64b66b_0_cdc_to <= prmry_vect_in; + s_level_out_bus_d2 <= s_level_out_bus_d1_aurora_64b66b_0_cdc_to; + s_level_out_bus_d3 <= s_level_out_bus_d2; + s_level_out_bus_d4 <= s_level_out_bus_d3; + s_level_out_bus_d5 <= s_level_out_bus_d4; + s_level_out_bus_d6 <= s_level_out_bus_d5; + end + end + +end +endgenerate + +generate if (c_mtbf_stages == 1 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d1_aurora_64b66b_0_cdc_to; +end +endgenerate + +generate if (c_mtbf_stages == 2 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d2; +end +endgenerate + +generate if (c_mtbf_stages == 3 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d3; +end +endgenerate + +generate if (c_mtbf_stages == 4 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d4; +end +endgenerate + +generate if (c_mtbf_stages == 5 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d5; +end +endgenerate + +generate if (c_mtbf_stages == 6 & c_single_bit == 0 & c_cdc_type == 1) begin + + assign scndry_vect_out = s_level_out_bus_d6; +end +endgenerate + + +//Level synchronizer logic with ACK +generate if (c_flop_input == 1 & c_cdc_type == 2) begin + + always @ ( posedge prmry_aclk) + begin : FLOP_IN + if ( ( prmry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + p_level_in_d1_cdc_from <= 1'b0; + end + else + begin + p_level_in_d1_cdc_from <= prmry_in; + end + end + + assign p_level_in_int = p_level_in_d1_cdc_from; + +end +endgenerate + + +generate if (c_flop_input == 0 & c_cdc_type == 2) begin + + assign p_level_in_int = prmry_in; + +end +endgenerate + +generate if (c_cdc_type == 2) begin + always @ ( posedge scndry_aclk) + begin : CROSS_PLEVEL_IN2SCNDRY + if ( ( scndry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + s_level_out_d1_aurora_64b66b_0_cdc_to <= 1'b0; + s_level_out_d2 <= 1'b0; + s_level_out_d3 <= 1'b0; + s_level_out_d4 <= 1'b0; + s_level_out_d5 <= 1'b0; + s_level_out_d6 <= 1'b0; + end + else + begin + s_level_out_d1_aurora_64b66b_0_cdc_to <= p_level_in_int; + s_level_out_d2 <= s_level_out_d1_aurora_64b66b_0_cdc_to; + s_level_out_d3 <= s_level_out_d2; + s_level_out_d4 <= s_level_out_d3; + s_level_out_d5 <= s_level_out_d4; + s_level_out_d6 <= s_level_out_d5; + end + end + + always @ ( posedge prmry_aclk) + begin : CROSS_PLEVEL_SCNDRY2PRMRY + if ( ( prmry_rst_n == 1'b0 ) & ( c_reset_state == 1 ) ) + begin + p_level_out_d1_aurora_64b66b_0_cdc_to <= 1'b0; + p_level_out_d2 <= 1'b0; + p_level_out_d3 <= 1'b0; + p_level_out_d4 <= 1'b0; + p_level_out_d5 <= 1'b0; + p_level_out_d6 <= 1'b0; + p_level_out_d7 <= 1'b0; + prmry_ack_int <= 1'b0; + end + else + begin + p_level_out_d1_aurora_64b66b_0_cdc_to <= scndry_out_int; + p_level_out_d2 <= p_level_out_d1_aurora_64b66b_0_cdc_to; + p_level_out_d3 <= p_level_out_d2; + p_level_out_d4 <= p_level_out_d3; + p_level_out_d5 <= p_level_out_d4; + p_level_out_d6 <= p_level_out_d5; + p_level_out_d7 <= p_level_out_d6; + prmry_ack_int <= prmry_pulse_ack; + end + end + assign prmry_ack = prmry_ack_int; + assign scndry_out = scndry_out_int; + assign scndry_vect_out = 0; +end +endgenerate + + generate if ((c_mtbf_stages == 2 || c_mtbf_stages == 1) & c_cdc_type == 2) begin + + assign scndry_out_int = s_level_out_d2; + assign prmry_pulse_ack = ( p_level_out_d3 ^ p_level_out_d2 ); + end + endgenerate + + generate if (c_mtbf_stages == 3 & c_cdc_type == 2) begin + + assign scndry_out_int = s_level_out_d3; + assign prmry_pulse_ack = ( p_level_out_d4 ^ p_level_out_d3 ); + end + endgenerate + + generate if (c_mtbf_stages == 4 & c_cdc_type == 2) begin + + assign scndry_out_int = s_level_out_d4; + assign prmry_pulse_ack = ( p_level_out_d5 ^ p_level_out_d4 ); + end + endgenerate + + generate if (c_mtbf_stages == 5 & c_cdc_type == 2) begin + + assign scndry_out_int = s_level_out_d5; + assign prmry_pulse_ack = ( p_level_out_d6 ^ p_level_out_d5 ); + end + endgenerate + + generate if (c_mtbf_stages == 6 & c_cdc_type == 2) begin + + assign scndry_out_int = s_level_out_d6; + assign prmry_pulse_ack = ( p_level_out_d7 ^ p_level_out_d6 ); + end + endgenerate + +endmodule + + + +module aurora_64b66b_0_rst_sync_exdes + # ( + parameter c_init_val = 1'b1, + parameter [4:0] c_mtbf_stages = 3 // Number of sync stages needed max value 31 + ) + ( + input prmry_in, + input scndry_aclk, + output scndry_out + ); + +genvar i; + + + +(* ASYNC_REG = "TRUE" *)(* shift_extract = "{no}"*) reg stg1_aurora_64b66b_0_cdc_to = c_init_val; +(* ASYNC_REG = "TRUE" *)(* shift_extract = "{no}"*) reg stg2 = c_init_val; +(* ASYNC_REG = "TRUE" *)(* shift_extract = "{no}"*) reg stg3 = c_init_val; + + (* shift_extract = "{no}"*) reg stg4 = c_init_val; + (* shift_extract = "{no}"*) reg stg5 = c_init_val; + (* shift_extract = "{no}"*) reg stg6 = c_init_val; + (* shift_extract = "{no}"*) reg stg7 = c_init_val; + (* shift_extract = "{no}"*) reg stg8 = c_init_val; + (* shift_extract = "{no}"*) reg stg9 = c_init_val; + (* shift_extract = "{no}"*) reg stg10 = c_init_val; + (* shift_extract = "{no}"*) reg stg11 = c_init_val; + (* shift_extract = "{no}"*) reg stg12 = c_init_val; + (* shift_extract = "{no}"*) reg stg13 = c_init_val; + (* shift_extract = "{no}"*) reg stg14 = c_init_val; + (* shift_extract = "{no}"*) reg stg15 = c_init_val; + (* shift_extract = "{no}"*) reg stg16 = c_init_val; + (* shift_extract = "{no}"*) reg stg17 = c_init_val; + (* shift_extract = "{no}"*) reg stg18 = c_init_val; + (* shift_extract = "{no}"*) reg stg19 = c_init_val; + (* shift_extract = "{no}"*) reg stg20 = c_init_val; + (* shift_extract = "{no}"*) reg stg21 = c_init_val; + (* shift_extract = "{no}"*) reg stg22 = c_init_val; + (* shift_extract = "{no}"*) reg stg23 = c_init_val; + (* shift_extract = "{no}"*) reg stg24 = c_init_val; + (* shift_extract = "{no}"*) reg stg25 = c_init_val; + (* shift_extract = "{no}"*) reg stg26 = c_init_val; + (* shift_extract = "{no}"*) reg stg27 = c_init_val; + (* shift_extract = "{no}"*) reg stg28 = c_init_val; + (* shift_extract = "{no}"*) reg stg29 = c_init_val; + (* shift_extract = "{no}"*) reg stg30 = c_init_val; + (* shift_extract = "{no}"*) reg stg31 = c_init_val; + +generate + +always @(posedge scndry_aclk) +begin + stg1_aurora_64b66b_0_cdc_to <= `DLY prmry_in; + stg2 <= `DLY stg1_aurora_64b66b_0_cdc_to; + stg3 <= `DLY stg2; + stg4 <= `DLY stg3; + stg5 <= `DLY stg4; + stg6 <= `DLY stg5; + stg7 <= `DLY stg6; + stg8 <= `DLY stg7; + stg9 <= `DLY stg8; + stg10 <= `DLY stg9; + stg11 <= `DLY stg10; + stg12 <= `DLY stg11; + stg13 <= `DLY stg12; + stg14 <= `DLY stg13; + stg15 <= `DLY stg14; + stg16 <= `DLY stg15; + stg17 <= `DLY stg16; + stg18 <= `DLY stg17; + stg19 <= `DLY stg18; + stg20 <= `DLY stg19; + stg21 <= `DLY stg20; + stg22 <= `DLY stg21; + stg23 <= `DLY stg22; + stg24 <= `DLY stg23; + stg25 <= `DLY stg24; + stg26 <= `DLY stg25; + stg27 <= `DLY stg26; + stg28 <= `DLY stg27; + stg29 <= `DLY stg28; + stg30 <= `DLY stg29; + stg31 <= `DLY stg30; +end + +if(c_mtbf_stages <= 3) assign scndry_out = stg3; +if(c_mtbf_stages == 4) assign scndry_out = stg4; +if(c_mtbf_stages == 5) assign scndry_out = stg5; +if(c_mtbf_stages == 6) assign scndry_out = stg6; +if(c_mtbf_stages == 7) assign scndry_out = stg7; +if(c_mtbf_stages == 8) assign scndry_out = stg8; +if(c_mtbf_stages == 9) assign scndry_out = stg9; +if(c_mtbf_stages == 10) assign scndry_out = stg10; +if(c_mtbf_stages == 11) assign scndry_out = stg11; +if(c_mtbf_stages == 12) assign scndry_out = stg12; +if(c_mtbf_stages == 13) assign scndry_out = stg13; +if(c_mtbf_stages == 14) assign scndry_out = stg14; +if(c_mtbf_stages == 15) assign scndry_out = stg15; +if(c_mtbf_stages == 16) assign scndry_out = stg16; +if(c_mtbf_stages == 17) assign scndry_out = stg17; +if(c_mtbf_stages == 18) assign scndry_out = stg18; +if(c_mtbf_stages == 19) assign scndry_out = stg19; +if(c_mtbf_stages == 20) assign scndry_out = stg20; +if(c_mtbf_stages == 21) assign scndry_out = stg21; +if(c_mtbf_stages == 22) assign scndry_out = stg22; +if(c_mtbf_stages == 23) assign scndry_out = stg23; +if(c_mtbf_stages == 24) assign scndry_out = stg24; +if(c_mtbf_stages == 25) assign scndry_out = stg25; +if(c_mtbf_stages == 26) assign scndry_out = stg26; +if(c_mtbf_stages == 27) assign scndry_out = stg27; +if(c_mtbf_stages == 28) assign scndry_out = stg28; +if(c_mtbf_stages == 29) assign scndry_out = stg29; +if(c_mtbf_stages == 30) assign scndry_out = stg30; +if(c_mtbf_stages == 31) assign scndry_out = stg31; + +endgenerate + +endmodule diff --git a/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_driver.v b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_driver.v new file mode 100644 index 0000000000..58a921ec1d --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_driver.v @@ -0,0 +1,95 @@ +module aurora_64b66b_0_driver ( +// clk wiz input +input INIT_CLK_IN, +output INIT_CLK_i, +input locked, +// aurora input +input channel_up_i, +input system_reset_i, + + +output reg reset_pb, +output gt_rxcdrovrden_i, +output [2:0] loopback_i, +output power_down_i, +output gt_reset_i, + +input user_clk_i +); + + assign gt_rxcdrovrden_i = 1'b0; + assign loopback_i = 3'b000; + assign power_down_i = 1'b0; + + wire RESET; + assign RESET = ~locked; + + reg [127:0] pma_init_stage = {128{1'b1}}; + reg [23:0] pma_init_pulse_width_cnt = 24'h0; + reg pma_init_assertion = 1'b0; + reg pma_init_assertion_r; + reg gt_reset_i_delayed_r1; + reg gt_reset_i_delayed_r2; + wire gt_reset_i_delayed; + + reg PMA_INIT; + // PMA_INIT is RESET delayed by 1 INIT_CLK cycles + always @(posedge INIT_CLK_i) + begin + PMA_INIT <= RESET; + end + + wire gt_reset_i_tmp; + wire gt_reset_i_tmp2; + + wire reset_i; + + assign gt_reset_i_tmp = PMA_INIT; + assign reset_i = RESET | gt_reset_i_tmp2; + + always @(posedge INIT_CLK_i) + begin + pma_init_stage[127:0] <= {pma_init_stage[126:0], gt_reset_i_tmp}; + end + + assign gt_reset_i_delayed = pma_init_stage[127]; + + always @(posedge INIT_CLK_i) + begin + gt_reset_i_delayed_r1 <= gt_reset_i_delayed; + gt_reset_i_delayed_r2 <= gt_reset_i_delayed_r1; + pma_init_assertion_r <= pma_init_assertion; + if(~gt_reset_i_delayed_r2 & gt_reset_i_delayed_r1 & ~pma_init_assertion & (pma_init_pulse_width_cnt != 24'hFFFFFF)) + pma_init_assertion <= 1'b1; + else if (pma_init_assertion & pma_init_pulse_width_cnt == 24'hFFFFFF) + pma_init_assertion <= 1'b0; + + if(pma_init_assertion) + pma_init_pulse_width_cnt <= pma_init_pulse_width_cnt + 24'h1; + end + + assign gt_reset_i = pma_init_assertion ? 1'b1 : gt_reset_i_delayed; + + aurora_64b66b_0_rst_sync_exdes u_rst_sync_gtrsttmpi + ( + .prmry_in (gt_reset_i_tmp), + .scndry_aclk (user_clk_i), + .scndry_out (gt_reset_i_tmp2) + ); + + // assign gt_reset_i_eff = pma_init_assertion ? 1'b1 : gt_reset_i_delayed; + + BUFG initclk_bufg_i + ( + .I (INIT_CLK_IN), + .O (INIT_CLK_i) + ); + + //*********************************Main Body of Code********************************** + + + + always @(posedge user_clk_i) + reset_pb <= `DLY reset_i; + +endmodule diff --git a/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_utils.v b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_utils.v new file mode 100644 index 0000000000..347c8f3561 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/aurora/aurora_64b66b_0_utils.v @@ -0,0 +1,63 @@ +//aurora_64b66b_0_utils.v + +module aurora_tx_arb( + input [3:0] tx_signal, + + output tx_lane_1, + output tx_lane_2, + output tx_lane_3, + output tx_lane_4 +); + + assign tx_lane_1 = tx_signal[0]; + assign tx_lane_2 = tx_signal[1]; + assign tx_lane_3 = tx_signal[2]; + assign tx_lane_4 = tx_signal[3]; +endmodule + +module aurora_rx_arb( + input rx_lane_1, + input rx_lane_2, + input rx_lane_3, + input rx_lane_4, + + output [3:0] rx_signal +); + + assign rx_signal = {rx_lane_4, rx_lane_3, rx_lane_2, rx_lane_1}; +endmodule + +module aurora_gt_wrapper( + RXP_in, + RXN_in, + + RXP_out, + RXN_out, + + TXP_in, + TXN_in, + + TXP_out, + TXN_out +); + +(* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME QSFP_GT" *) +(* X_INTERFACE_INFO = "xilinx.com:interface:gt_rtl:1.0 QSFP_GT GTX_N" *) output[3:0] TXP_out; +(* X_INTERFACE_INFO = "xilinx.com:interface:gt_rtl:1.0 QSFP_GT GTX_P" *) output[3:0] TXN_out; +(* X_INTERFACE_INFO = "xilinx.com:interface:gt_rtl:1.0 QSFP_GT GRX_N" *) input[3:0] RXN_out; +(* X_INTERFACE_INFO = "xilinx.com:interface:gt_rtl:1.0 QSFP_GT GRX_P" *) input[3:0] RXP_out; + + +output [3:0] RXP_in; +output [3:0] RXN_in; + +input [3:0] TXP_in; +input [3:0] TXN_in; + +assign RXP_in = RXP_out; +assign RXN_in = RXN_out; + +assign TXP_out = TXP_in; +assign TXN_out = TXN_in; + +endmodule \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/design/axi.vh b/platforms/xilinx_vc707/cl_firesim/design/axi.vh new file mode 100644 index 0000000000..0efb44ff86 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/axi.vh @@ -0,0 +1,427 @@ +`ifndef AXI_VH +`define AXI_VH + +//----------------------------------------------------------- +// Must define/override the following... +// i.e. +// `define Otype wire // i/o signal type +// `define Itype wire +// `define AMBA_AXI4 // use AXI4 or AXI4_LITE +// `define AMBA_AXI_CACHE // has *cache +// `define AMBA_AXI_PROT // has *prot +// `define AMBA_AXI_REGION // has *region +// `define AMBA_AXI_QOS // has *qos +// `define AMBA_AXI_ID // has *id +//----------------------------------------------------------- + +// can override +`define Otype wire +`define Itype wire + +`define AMBA_AXI_MASTER_PORT_AW(PNAME, ID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , output `Otype [``ID``-1:0] ``PNAME``_awid \ + `endif \ + `endif \ + , output `Otype [``AD``-1:0] ``PNAME``_awaddr \ + `ifdef AMBA_AXI4 \ + , output `Otype [ 7:0] ``PNAME``_awlen \ + , output `Otype ``PNAME``_awlock \ + , output `Otype [ 2:0] ``PNAME``_awsize \ + , output `Otype [ 1:0] ``PNAME``_awburst \ + `ifdef AMBA_AXI_CACHE \ + , output `Otype [ 3:0] ``PNAME``_awcache \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , output `Otype [ 2:0] ``PNAME``_awprot \ + `endif \ + , output `Otype ``PNAME``_awvalid \ + , input `Itype ``PNAME``_awready \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , output `Otype [ 3:0] ``PNAME``_awqos \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , output `Otype [ 3:0] ``PNAME``_awregion \ + `endif \ + `endif + +`define AMBA_AXI_MASTER_PORT_W(PNAME, ID, DA) \ + , output `Otype [``DA``-1:0] ``PNAME``_wdata \ + , output `Otype [(``DA``/8)-1:0] ``PNAME``_wstrb \ + `ifdef AMBA_AXI4 \ + , output `Otype ``PNAME``_wlast \ + `endif \ + , output `Otype ``PNAME``_wvalid \ + , input `Itype ``PNAME``_wready + +`define AMBA_AXI_MASTER_PORT_B(PNAME, ID) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , input `Itype [``ID``-1:0] ``PNAME``_bid \ + `endif \ + `endif \ + , input `Itype [ 1:0] ``PNAME``_bresp \ + , input `Itype ``PNAME``_bvalid \ + , output `Otype ``PNAME``_bready + +`define AMBA_AXI_MASTER_PORT_AR(PNAME, ID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , output `Otype [``ID``-1:0] ``PNAME``_arid \ + `endif \ + `endif \ + , output `Otype [``AD``-1:0] ``PNAME``_araddr \ + `ifdef AMBA_AXI4 \ + , output `Otype [ 7:0] ``PNAME``_arlen \ + , output `Otype ``PNAME``_arlock \ + , output `Otype [ 2:0] ``PNAME``_arsize \ + , output `Otype [ 1:0] ``PNAME``_arburst \ + `ifdef AMBA_AXI_CACHE \ + , output `Otype [ 3:0] ``PNAME``_arcache \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , output `Otype [ 2:0] ``PNAME``_arprot \ + `endif \ + , output `Otype ``PNAME``_arvalid \ + , input `Itype ``PNAME``_arready \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , output `Otype [ 3:0] ``PNAME``_arqos \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , output `Otype [ 3:0] ``PNAME``_arregion \ + `endif \ + `endif + +`define AMBA_AXI_MASTER_PORT_R(PNAME, ID, DA) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , input `Itype [``ID``-1:0] ``PNAME``_rid \ + `endif \ + `endif \ + , input `Itype [``DA``-1:0] ``PNAME``_rdata \ + , input `Itype [ 1:0] ``PNAME``_rresp \ + `ifdef AMBA_AXI4 \ + , input `Itype ``PNAME``_rlast \ + `endif \ + , input `Itype ``PNAME``_rvalid \ + , output `Otype ``PNAME``_rready + +`define AMBA_AXI_MASTER_PORT(PNAME, ID, AD, DA) \ + `AMBA_AXI_MASTER_PORT_AW(``PNAME``, ``ID``, ``AD``) \ + `AMBA_AXI_MASTER_PORT_W(``PNAME``, ``ID``, ``DA``) \ + `AMBA_AXI_MASTER_PORT_B(``PNAME``, ``ID``) \ + `AMBA_AXI_MASTER_PORT_AR(``PNAME``, ``ID``, ``DA``) \ + `AMBA_AXI_MASTER_PORT_R(``PNAME``, ``ID``, ``DA``) + +//----------------------------------------------------------- + +`define AMBA_AXI_SLAVE_PORT_AW(PNAME, SID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , input `Itype [``SID``-1:0] ``PNAME``_awid \ + `endif \ + `endif \ + , input `Itype [``AD``-1:0] ``PNAME``_awaddr \ + `ifdef AMBA_AXI4 \ + , input `Itype [ 7:0] ``PNAME``_awlen \ + , input `Itype ``PNAME``_awlock \ + , input `Itype [ 2:0] ``PNAME``_awsize \ + , input `Itype [ 1:0] ``PNAME``_awburst \ + `ifdef AMBA_AXI_CACHE \ + , input `Itype [ 3:0] ``PNAME``_awcache \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , input `Itype [ 2:0] ``PNAME``_awprot \ + `endif \ + , input `Itype ``PNAME``_awvalid \ + , output `Otype ``PNAME``_awready \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , input `Itype [ 3:0] ``PNAME``_awqos \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , input `Itype [ 3:0] ``PNAME``_awregion \ + `endif \ + `endif + +`define AMBA_AXI_SLAVE_PORT_W(PNAME, SID, DA) \ + , input `Itype [``DA``-1:0] ``PNAME``_wdata \ + , input `Itype [(``DA``/8)-1:0] ``PNAME``_wstrb \ + `ifdef AMBA_AXI4 \ + , input `Itype ``PNAME``_wlast \ + `endif \ + , input `Itype ``PNAME``_wvalid \ + , output `Otype ``PNAME``_wready + +`define AMBA_AXI_SLAVE_PORT_B(PNAME, SID) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , output `Otype [``SID``-1:0] ``PNAME``_bid \ + `endif \ + `endif \ + , output `Otype [ 1:0] ``PNAME``_bresp \ + , output `Otype ``PNAME``_bvalid \ + , input `Itype ``PNAME``_bready + +`define AMBA_AXI_SLAVE_PORT_AR(PNAME, SID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , input `Itype [``SID``-1:0] ``PNAME``_arid \ + `endif \ + `endif \ + , input `Itype [``AD``-1:0] ``PNAME``_araddr \ + `ifdef AMBA_AXI4 \ + , input `Itype [ 7:0] ``PNAME``_arlen \ + , input `Itype ``PNAME``_arlock \ + , input `Itype [ 2:0] ``PNAME``_arsize \ + , input `Itype [ 1:0] ``PNAME``_arburst \ + `ifdef AMBA_AXI_CACHE \ + , input `Itype [ 3:0] ``PNAME``_arcache \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , input `Itype [ 2:0] ``PNAME``_arprot \ + `endif \ + , input `Itype ``PNAME``_arvalid \ + , output `Otype ``PNAME``_arready \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , input `Itype [ 3:0] ``PNAME``_arqos \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , input `Itype [ 3:0] ``PNAME``_arregion \ + `endif \ + `endif + +`define AMBA_AXI_SLAVE_PORT_R(PNAME, SID, DA) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , output `Otype [``SID``-1:0] ``PNAME``_rid \ + `endif \ + `endif \ + , output `Otype [``DA``-1:0] ``PNAME``_rdata \ + , output `Otype [ 1:0] ``PNAME``_rresp \ + `ifdef AMBA_AXI4 \ + , output `Otype ``PNAME``_rlast \ + `endif \ + , output `Otype ``PNAME``_rvalid \ + , input `Itype ``PNAME``_rready + +`define AMBA_AXI_SLAVE_PORT(PNAME, ID, AD, DA) \ + `AMBA_AXI_SLAVE_PORT_AW(``PNAME``, ``ID``, ``AD``) \ + `AMBA_AXI_SLAVE_PORT_W(``PNAME``, ``ID``, ``DA``) \ + `AMBA_AXI_SLAVE_PORT_B(``PNAME``, ``ID``) \ + `AMBA_AXI_SLAVE_PORT_AR(``PNAME``, ``ID``, ``AD``) \ + `AMBA_AXI_SLAVE_PORT_R(``PNAME``, ``ID``, ``DA``) + +//----------------------------------------------------- + +`define AMBA_AXI_PORT_CONNECTION_AW(PNAME, WNAME) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , .``PNAME``_awid (``WNAME``_awid ) \ + `endif \ + `endif \ + , .``PNAME``_awaddr (``WNAME``_awaddr ) \ + `ifdef AMBA_AXI4 \ + , .``PNAME``_awlen (``WNAME``_awlen ) \ + , .``PNAME``_awlock (``WNAME``_awlock ) \ + , .``PNAME``_awsize (``WNAME``_awsize ) \ + , .``PNAME``_awburst (``WNAME``_awburst ) \ + `ifdef AMBA_AXI_CACHE \ + , .``PNAME``_awcache (``WNAME``_awcache ) \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , .``PNAME``_awprot (``WNAME``_awprot ) \ + `endif \ + , .``PNAME``_awvalid (``WNAME``_awvalid ) \ + , .``PNAME``_awready (``WNAME``_awready ) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , .``PNAME``_awqos (``WNAME``_awqos ) \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , .``PNAME``_awregion (``WNAME``_awregion) \ + `endif \ + `endif + +`define AMBA_AXI_PORT_CONNECTION_W(PNAME, WNAME) \ + , .``PNAME``_wdata (``WNAME``_wdata ) \ + , .``PNAME``_wstrb (``WNAME``_wstrb ) \ + `ifdef AMBA_AXI4 \ + , .``PNAME``_wlast (``WNAME``_wlast ) \ + `endif \ + , .``PNAME``_wvalid (``WNAME``_wvalid ) \ + , .``PNAME``_wready (``WNAME``_wready ) + +`define AMBA_AXI_PORT_CONNECTION_B(PNAME, WNAME) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , .``PNAME``_bid (``WNAME``_bid ) \ + `endif \ + `endif \ + , .``PNAME``_bresp (``WNAME``_bresp ) \ + , .``PNAME``_bvalid (``WNAME``_bvalid ) \ + , .``PNAME``_bready (``WNAME``_bready ) + +`define AMBA_AXI_PORT_CONNECTION_AR(PNAME, WNAME) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , .``PNAME``_arid (``WNAME``_arid ) \ + `endif \ + `endif \ + , .``PNAME``_araddr (``WNAME``_araddr ) \ + `ifdef AMBA_AXI4 \ + , .``PNAME``_arlen (``WNAME``_arlen ) \ + , .``PNAME``_arlock (``WNAME``_arlock ) \ + , .``PNAME``_arsize (``WNAME``_arsize ) \ + , .``PNAME``_arburst (``WNAME``_arburst ) \ + `ifdef AMBA_AXI_CACHE \ + , .``PNAME``_arcache (``WNAME``_arcache ) \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + , .``PNAME``_arprot (``WNAME``_arprot ) \ + `endif \ + , .``PNAME``_arvalid (``WNAME``_arvalid ) \ + , .``PNAME``_arready (``WNAME``_arready ) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + , .``PNAME``_arqos (``WNAME``_arqos ) \ + `endif \ + `ifdef AMBA_AXI_REGION \ + , .``PNAME``_arregion (``WNAME``_arregion) \ + `endif \ + `endif + +`define AMBA_AXI_PORT_CONNECTION_R(PNAME, WNAME) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + , .``PNAME``_rid (``WNAME``_rid ) \ + `endif \ + `endif \ + , .``PNAME``_rdata (``WNAME``_rdata ) \ + , .``PNAME``_rresp (``WNAME``_rresp ) \ + `ifdef AMBA_AXI4 \ + , .``PNAME``_rlast (``WNAME``_rlast ) \ + `endif \ + , .``PNAME``_rvalid (``WNAME``_rvalid ) \ + , .``PNAME``_rready (``WNAME``_rready ) + +`define AMBA_AXI_PORT_CONNECTION(PNAME, WNAME) \ + `AMBA_AXI_PORT_CONNECTION_AW(``PNAME``, ``WNAME``) \ + `AMBA_AXI_PORT_CONNECTION_W(``PNAME``, ``WNAME``) \ + `AMBA_AXI_PORT_CONNECTION_B(``PNAME``, ``WNAME``) \ + `AMBA_AXI_PORT_CONNECTION_AR(``PNAME``, ``WNAME``) \ + `AMBA_AXI_PORT_CONNECTION_R(``PNAME``, ``WNAME``) + +//-------------------------------------------------- + +`define AMBA_AXI_WIRE_AW(PNAME, ID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + wire [``ID``-1:0] ``PNAME``_awid; \ + `endif \ + `endif \ + wire [``AD``-1:0] ``PNAME``_awaddr; \ + `ifdef AMBA_AXI4 \ + wire [ 7:0] ``PNAME``_awlen; \ + wire ``PNAME``_awlock; \ + wire [ 2:0] ``PNAME``_awsize; \ + wire [ 1:0] ``PNAME``_awburst; \ + `ifdef AMBA_AXI_CACHE \ + wire [ 3:0] ``PNAME``_awcache; \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + wire [ 2:0] ``PNAME``_awprot; \ + `endif \ + wire ``PNAME``_awvalid; \ + wire ``PNAME``_awready; \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + wire [ 3:0] ``PNAME``_awqos; \ + `endif \ + `ifdef AMBA_AXI_REGION \ + wire [ 3:0] ``PNAME``_awregion; \ + `endif \ + `endif + +`define AMBA_AXI_WIRE_W(PNAME, ID, DA) \ + wire [``DA``-1:0] ``PNAME``_wdata; \ + wire [(``DA``/8)-1:0] ``PNAME``_wstrb; \ + `ifdef AMBA_AXI4 \ + wire ``PNAME``_wlast; \ + `endif \ + wire ``PNAME``_wvalid; \ + wire ``PNAME``_wready; + +`define AMBA_AXI_WIRE_B(PNAME, ID) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + wire [``ID``-1:0] ``PNAME``_bid; \ + `endif \ + `endif \ + wire [ 1:0] ``PNAME``_bresp; \ + wire ``PNAME``_bvalid; \ + wire ``PNAME``_bready; + +`define AMBA_AXI_WIRE_AR(PNAME, ID, AD) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + wire [``ID``-1:0] ``PNAME``_arid; \ + `endif \ + `endif \ + wire [``AD``-1:0] ``PNAME``_araddr; \ + `ifdef AMBA_AXI4 \ + wire [ 7:0] ``PNAME``_arlen; \ + wire ``PNAME``_arlock; \ + wire [ 2:0] ``PNAME``_arsize; \ + wire [ 1:0] ``PNAME``_arburst; \ + `ifdef AMBA_AXI_CACHE \ + wire [ 3:0] ``PNAME``_arcache; \ + `endif \ + `endif \ + `ifdef AMBA_AXI_PROT \ + wire [ 2:0] ``PNAME``_arprot; \ + `endif \ + wire ``PNAME``_arvalid; \ + wire ``PNAME``_arready; \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_QOS \ + wire [ 3:0] ``PNAME``_arqos; \ + `endif \ + `ifdef AMBA_AXI_REGION \ + wire [ 3:0] ``PNAME``_arregion; \ + `endif \ + `endif + +`define AMBA_AXI_WIRE_R(PNAME, ID, DA) \ + `ifdef AMBA_AXI4 \ + `ifdef AMBA_AXI_ID \ + wire [``ID``-1:0] ``PNAME``_rid; \ + `endif \ + `endif \ + wire [``DA``-1:0] ``PNAME``_rdata; \ + wire [ 1:0] ``PNAME``_rresp; \ + `ifdef AMBA_AXI4 \ + wire ``PNAME``_rlast; \ + `endif \ + wire ``PNAME``_rvalid; \ + wire ``PNAME``_rready; + +`define AMBA_AXI_WIRE(PNAME, ID, AD, DA) \ + `AMBA_AXI_WIRE_AW(``PNAME``, ``ID``, ``AD``) \ + `AMBA_AXI_WIRE_W(``PNAME``, ``ID``, ``DA``) \ + `AMBA_AXI_WIRE_B(``PNAME``, ``ID``) \ + `AMBA_AXI_WIRE_AR(``PNAME``, ``ID``, ``AD``) \ + `AMBA_AXI_WIRE_R(``PNAME``, ``ID``, ``DA``) + +`endif // AXI_VH diff --git a/platforms/xilinx_vc707/cl_firesim/design/axi_tieoff_master.v b/platforms/xilinx_vc707/cl_firesim/design/axi_tieoff_master.v new file mode 100644 index 0000000000..4c0f3acf51 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/axi_tieoff_master.v @@ -0,0 +1,66 @@ +`timescale 1ns/1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 09/10/2021 06:05:42 PM +// Design Name: +// Module Name: axi_tieoff_master +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module axi_tieoff_master( + TIEOFF_M_AXI_CTRL_0_araddr, + TIEOFF_M_AXI_CTRL_0_arready, + TIEOFF_M_AXI_CTRL_0_arvalid, + TIEOFF_M_AXI_CTRL_0_awaddr, + TIEOFF_M_AXI_CTRL_0_awready, + TIEOFF_M_AXI_CTRL_0_awvalid, + TIEOFF_M_AXI_CTRL_0_bready, + TIEOFF_M_AXI_CTRL_0_bresp, + TIEOFF_M_AXI_CTRL_0_bvalid, + TIEOFF_M_AXI_CTRL_0_rdata, + TIEOFF_M_AXI_CTRL_0_rready, + TIEOFF_M_AXI_CTRL_0_rresp, + TIEOFF_M_AXI_CTRL_0_rvalid, + TIEOFF_M_AXI_CTRL_0_wdata, + TIEOFF_M_AXI_CTRL_0_wready, + TIEOFF_M_AXI_CTRL_0_wvalid); + (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME TIEOFF_M_AXI_CTRL_0, ADDR_WIDTH 32, ARUSER_WIDTH 0, AWUSER_WIDTH 0, BUSER_WIDTH 0, DATA_WIDTH 32, HAS_BRESP 1, HAS_BURST 0, HAS_CACHE 0, HAS_LOCK 0, HAS_PROT 0, HAS_QOS 0, HAS_REGION 0, HAS_RRESP 1, HAS_WSTRB 0, ID_WIDTH 0, INSERT_VIP 0, MAX_BURST_LENGTH 1, NUM_READ_OUTSTANDING 1, NUM_READ_THREADS 1, NUM_WRITE_OUTSTANDING 1, NUM_WRITE_THREADS 1, FREQ_HZ 300000000, PHASE 0.0, PROTOCOL AXI4LITE, READ_WRITE_MODE READ_WRITE, RUSER_BITS_PER_BYTE 0, RUSER_WIDTH 0, SUPPORTS_NARROW_BURST 0, WUSER_BITS_PER_BYTE 0, WUSER_WIDTH 0" *) + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 ARADDR" *) output[31:0] TIEOFF_M_AXI_CTRL_0_araddr; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 ARREADY" *) input TIEOFF_M_AXI_CTRL_0_arready; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 ARVALID" *) output TIEOFF_M_AXI_CTRL_0_arvalid; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 AWADDR" *) output[31:0] TIEOFF_M_AXI_CTRL_0_awaddr; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 AWREADY" *) input TIEOFF_M_AXI_CTRL_0_awready; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 AWVALID" *) output TIEOFF_M_AXI_CTRL_0_awvalid; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 BREADY" *) output TIEOFF_M_AXI_CTRL_0_bready; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 BRESP" *) input[1:0] TIEOFF_M_AXI_CTRL_0_bresp; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 BVALID" *) input TIEOFF_M_AXI_CTRL_0_bvalid; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 RDATA" *) input[31:0] TIEOFF_M_AXI_CTRL_0_rdata; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 RREADY" *) output TIEOFF_M_AXI_CTRL_0_rready; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 RRESP" *) input[1:0] TIEOFF_M_AXI_CTRL_0_rresp; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 RVALID" *) input TIEOFF_M_AXI_CTRL_0_rvalid; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 WDATA" *) output[31:0] TIEOFF_M_AXI_CTRL_0_wdata; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 WREADY" *) input TIEOFF_M_AXI_CTRL_0_wready; + (* X_INTERFACE_INFO = "xilinx.com:interface:aximm_rtl:1.0 TIEOFF_M_AXI_CTRL_0 WVALID" *) output TIEOFF_M_AXI_CTRL_0_wvalid; + + assign TIEOFF_M_AXI_CTRL_0_araddr = 32'b0; + assign TIEOFF_M_AXI_CTRL_0_arvalid = 1'b0; + assign TIEOFF_M_AXI_CTRL_0_awaddr = 32'b0; + assign TIEOFF_M_AXI_CTRL_0_awvalid = 1'b0; + assign TIEOFF_M_AXI_CTRL_0_bready = 1'b0; + assign TIEOFF_M_AXI_CTRL_0_rready = 1'b0; + assign TIEOFF_M_AXI_CTRL_0_wdata = 32'b0; + assign TIEOFF_M_AXI_CTRL_0_wvalid = 1'b0; +endmodule diff --git a/platforms/xilinx_vc707/cl_firesim/design/bitstream_config.xdc b/platforms/xilinx_vc707/cl_firesim/design/bitstream_config.xdc new file mode 100644 index 0000000000..99256c8c78 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/bitstream_config.xdc @@ -0,0 +1,11 @@ +# The majority of these constraints are redundant as them come with the u250 given XDC +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property CONFIG_MODE {SPIx4} [current_design] +set_property BITSTREAM.CONFIG.CONFIGFALLBACK Enable [current_design]; # Golden image is the fall back image if new bitstream is corrupted. +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN disable [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR Yes [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design] diff --git a/platforms/xilinx_vc707/cl_firesim/design/helpers.vh b/platforms/xilinx_vc707/cl_firesim/design/helpers.vh new file mode 100644 index 0000000000..6d2769997d --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/helpers.vh @@ -0,0 +1,56 @@ +`ifndef HELPERS_VH +`define HELPERS_VH + +`define DDR4_PDEF(PNAME) \ + output wire ``PNAME``_act_n, \ + output wire [16:0] ``PNAME``_adr, \ + output wire [1:0] ``PNAME``_ba, \ + output wire [1:0] ``PNAME``_bg, \ + output wire ``PNAME``_ck_c, \ + output wire ``PNAME``_ck_t, \ + output wire ``PNAME``_cke, \ + output wire ``PNAME``_cs_n, \ + inout wire [71:0] ``PNAME``_dq, \ + inout wire [17:0] ``PNAME``_dqs_c, \ + inout wire [17:0] ``PNAME``_dqs_t, \ + output wire ``PNAME``_odt, \ + output wire ``PNAME``_par, \ + output wire ``PNAME``_reset_n + +//----------------------------------------------------------- +// Must define/override the following... +// i.e. +// `define DDR4_PAR // use par instead of parity +//----------------------------------------------------------- + +`define DDR4_CONNECT(PNAME, WNAME) \ + , .``PNAME``_act_n(``WNAME``_act_n) \ + , .``PNAME``_adr(``WNAME``_adr) \ + , .``PNAME``_ba(``WNAME``_ba) \ + , .``PNAME``_bg(``WNAME``_bg) \ + , .``PNAME``_ck_c(``WNAME``_ck_c) \ + , .``PNAME``_ck_t(``WNAME``_ck_t) \ + , .``PNAME``_cke(``WNAME``_cke) \ + , .``PNAME``_cs_n(``WNAME``_cs_n) \ + , .``PNAME``_dq(``WNAME``_dq) \ + , .``PNAME``_dqs_c(``WNAME``_dqs_c) \ + , .``PNAME``_dqs_t(``WNAME``_dqs_t) \ + , .``PNAME``_odt(``WNAME``_odt) \ +`ifdef DDR4_PAR \ + , .``PNAME``_par(``WNAME``_par) \ +`else \ + , .``PNAME``_parity(``WNAME``_par) \ +`endif \ + , .``PNAME``_reset_n(``WNAME``_reset_n) + +// ------------------ + +`define DIFF_CLK_PDEF(PNAME) \ + input wire ``PNAME``_clk_n, \ + input wire ``PNAME``_clk_p + +`define DIFF_CLK_CONNECT(PNAME, WNAME) \ + , .``PNAME``_clk_n(``WNAME``_clk_n) \ + , .``PNAME``_clk_p(``WNAME``_clk_p) + +`endif // HELPERS_VH diff --git a/platforms/xilinx_vc707/cl_firesim/design/overall_fpga_top.v b/platforms/xilinx_vc707/cl_firesim/design/overall_fpga_top.v new file mode 100644 index 0000000000..c5ff03d07b --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/design/overall_fpga_top.v @@ -0,0 +1,287 @@ +`timescale 1 ps / 1 ps + +`include "helpers.vh" +`include "axi.vh" + +module overall_fpga_top( + `DDR4_PDEF(ddr4_sdram_c0), + + `DIFF_CLK_PDEF(default_300mhz_clk0), + `DIFF_CLK_PDEF(default_300mhz_clk1), + `DIFF_CLK_PDEF(default_300mhz_clk2), + + input wire [15:0] pci_express_x16_rxn, + input wire [15:0] pci_express_x16_rxp, + output wire [15:0] pci_express_x16_txn, + output wire [15:0] pci_express_x16_txp, + input wire pcie_perstn, + `DIFF_CLK_PDEF(pcie_refclk), + + input wire resetn +); + + wire sys_clk; + wire sys_reset_n; + + `define AMBA_AXI4 + `define AMBA_AXI_CACHE + `define AMBA_AXI_PROT + `define AMBA_AXI_ID + `AMBA_AXI_WIRE(PCIE_M_AXI, 4, 64, 512) + `undef AMBA_AXI4 + `undef AMBA_AXI_CACHE + `undef AMBA_AXI_PROT + `undef AMBA_AXI_ID + + `define AMBA_AXI_PROT + `AMBA_AXI_WIRE(PCIE_M_AXI_LITE, unused, 32, 32) + `undef AMBA_AXI_PROT + + `define AMBA_AXI4 + `define AMBA_AXI_CACHE + `define AMBA_AXI_PROT + `define AMBA_AXI_QOS + `define AMBA_AXI_REGION + `define AMBA_AXI_ID + `AMBA_AXI_WIRE(DDR4_0_S_AXI, 16, 34, 64) + `undef AMBA_AXI4 + `undef AMBA_AXI_CACHE + `undef AMBA_AXI_PROT + `undef AMBA_AXI_QOS + `undef AMBA_AXI_REGION + `undef AMBA_AXI_ID + + design_1 design_1_i ( + .resetn(resetn) + + `define DDR4_PAR + `DDR4_CONNECT(ddr4_sdram_c0, ddr4_sdram_c0) + `undef DDR4_PAR + + `DIFF_CLK_CONNECT(default_300mhz_clk0, default_300mhz_clk0) + `DIFF_CLK_CONNECT(default_300mhz_clk1, default_300mhz_clk1) + `DIFF_CLK_CONNECT(default_300mhz_clk2, default_300mhz_clk2) + + `define AMBA_AXI4 + `define AMBA_AXI_CACHE + `define AMBA_AXI_PROT + `define AMBA_AXI_QOS + `define AMBA_AXI_REGION + `define AMBA_AXI_ID + `AMBA_AXI_PORT_CONNECTION(DDR4_0_S_AXI, DDR4_0_S_AXI) + `undef AMBA_AXI4 + `undef AMBA_AXI_CACHE + `undef AMBA_AXI_PROT + `undef AMBA_AXI_QOS + `undef AMBA_AXI_REGION + `undef AMBA_AXI_ID + + `define AMBA_AXI4 + `define AMBA_AXI_CACHE + `define AMBA_AXI_PROT + `define AMBA_AXI_ID + `AMBA_AXI_PORT_CONNECTION(PCIE_M_AXI, PCIE_M_AXI) + `undef AMBA_AXI4 + `undef AMBA_AXI_CACHE + `undef AMBA_AXI_PROT + `undef AMBA_AXI_ID + + `define AMBA_AXI_PROT + `AMBA_AXI_PORT_CONNECTION(PCIE_M_AXI_LITE, PCIE_M_AXI_LITE) + `undef AMBA_AXI_PROT + + , .pci_express_x16_rxn(pci_express_x16_rxn) + , .pci_express_x16_rxp(pci_express_x16_rxp) + , .pci_express_x16_txn(pci_express_x16_txn) + , .pci_express_x16_txp(pci_express_x16_txp) + , .pcie_perstn(pcie_perstn) + `DIFF_CLK_CONNECT(pcie_refclk, pcie_refclk) + + , .QSFP0_CHANNEL_UP(QSFP0_CHANNEL_UP) + , .TO_QSFP0_DATA(TO_QSFP0_DATA) + , .TO_QSFP0_VALID(TO_QSFP0_VALID) + , .TO_QSFP0_READY(TO_QSFP0_READY) + , .FROM_QSFP0_DATA(FROM_QSFP0_DATA) + , .FROM_QSFP0_VALID(FROM_QSFP0_VALID) + , .FROM_QSFP0_READY(FROM_QSFP0_READY) + , .QSFP1_CHANNEL_UP(QSFP1_CHANNEL_UP) + , .TO_QSFP1_DATA(TO_QSFP1_DATA) + , .TO_QSFP1_VALID(TO_QSFP1_VALID) + , .TO_QSFP1_READY(TO_QSFP1_READY) + , .FROM_QSFP1_DATA(FROM_QSFP1_DATA) + , .FROM_QSFP1_VALID(FROM_QSFP1_VALID) + , .FROM_QSFP1_READY(FROM_QSFP1_READY) + + , .sys_clk(sys_clk) + , .sys_reset_n(sys_reset_n) + ); + + F1Shim firesim_top( + .clock(sys_clk), + .reset(!sys_reset_n), + + .io_master_aw_ready(PCIE_M_AXI_LITE_awready), + .io_master_aw_valid(PCIE_M_AXI_LITE_awvalid), + .io_master_aw_bits_addr(PCIE_M_AXI_LITE_awaddr[24:0]), + .io_master_aw_bits_len(8'h0), + .io_master_aw_bits_size(3'h2), + .io_master_aw_bits_burst(2'h1), + .io_master_aw_bits_lock(1'h0), + .io_master_aw_bits_cache(4'h0), + .io_master_aw_bits_prot(3'h0), //unused? (could connect?) S_AXI_CTRL_awprot + .io_master_aw_bits_qos(4'h0), + .io_master_aw_bits_region(4'h0), + .io_master_aw_bits_id(12'h0), + .io_master_aw_bits_user(1'h0), + + .io_master_w_ready(PCIE_M_AXI_LITE_wready), + .io_master_w_valid(PCIE_M_AXI_LITE_wvalid), + .io_master_w_bits_data(PCIE_M_AXI_LITE_wdata), + .io_master_w_bits_last(1'h1), + .io_master_w_bits_id(12'h0), + .io_master_w_bits_strb(PCIE_M_AXI_LITE_wstrb), //OR 8'hff + .io_master_w_bits_user(1'h0), + + .io_master_b_ready(PCIE_M_AXI_LITE_bready), + .io_master_b_valid(PCIE_M_AXI_LITE_bvalid), + .io_master_b_bits_resp(PCIE_M_AXI_LITE_bresp), + .io_master_b_bits_id(), // UNUSED at top level + .io_master_b_bits_user(), // UNUSED at top level + + .io_master_ar_ready(PCIE_M_AXI_LITE_arready), + .io_master_ar_valid(PCIE_M_AXI_LITE_arvalid), + .io_master_ar_bits_addr(PCIE_M_AXI_LITE_araddr[24:0]), + .io_master_ar_bits_len(8'h0), + .io_master_ar_bits_size(3'h2), + .io_master_ar_bits_burst(2'h1), + .io_master_ar_bits_lock(1'h0), + .io_master_ar_bits_cache(4'h0), + .io_master_ar_bits_prot(3'h0), // S_AXI_CTRL_arprot + .io_master_ar_bits_qos(4'h0), + .io_master_ar_bits_region(4'h0), + .io_master_ar_bits_id(12'h0), + .io_master_ar_bits_user(1'h0), + + .io_master_r_ready(PCIE_M_AXI_LITE_rready), + .io_master_r_valid(PCIE_M_AXI_LITE_rvalid), + .io_master_r_bits_resp(PCIE_M_AXI_LITE_rresp), + .io_master_r_bits_data(PCIE_M_AXI_LITE_rdata), + .io_master_r_bits_last(), //UNUSED at top level + .io_master_r_bits_id(), // UNUSED at top level + .io_master_r_bits_user(), // UNUSED at top level + + // special NIC master interface + .io_pcis_aw_ready(PCIE_M_AXI_awready), + .io_pcis_aw_valid(PCIE_M_AXI_awvalid), + .io_pcis_aw_bits_addr(PCIE_M_AXI_awaddr), + .io_pcis_aw_bits_len(PCIE_M_AXI_awlen), + .io_pcis_aw_bits_size(PCIE_M_AXI_awsize), + .io_pcis_aw_bits_burst(2'h1), // PCIE_M_AXI_awburst + .io_pcis_aw_bits_lock(1'h0), // PCIE_M_AXI_awlock + .io_pcis_aw_bits_cache(4'h0), // PCIE_M_AXI_awcache + .io_pcis_aw_bits_prot(3'h0), //unused? (could connect?) PCIE_M_AXI_awprot + .io_pcis_aw_bits_qos(4'h0), // PCIE_M_AXI_awqos + .io_pcis_aw_bits_region(4'h0), // PCIE_M_AXI_awregion + .io_pcis_aw_bits_id(PCIE_M_AXI_awid), + .io_pcis_aw_bits_user(1'h0), + + .io_pcis_w_ready(PCIE_M_AXI_wready), + .io_pcis_w_valid(PCIE_M_AXI_wvalid), + .io_pcis_w_bits_data(PCIE_M_AXI_wdata), + .io_pcis_w_bits_last(PCIE_M_AXI_wlast), + .io_pcis_w_bits_id(4'h0), + .io_pcis_w_bits_strb(PCIE_M_AXI_wstrb), + .io_pcis_w_bits_user(1'h0), + + .io_pcis_b_ready(PCIE_M_AXI_bready), + .io_pcis_b_valid(PCIE_M_AXI_bvalid), + .io_pcis_b_bits_resp(PCIE_M_AXI_bresp), + .io_pcis_b_bits_id(PCIE_M_AXI_bid), + .io_pcis_b_bits_user(), // UNUSED at top level + + .io_pcis_ar_ready(PCIE_M_AXI_arready), + .io_pcis_ar_valid(PCIE_M_AXI_arvalid), + .io_pcis_ar_bits_addr(PCIE_M_AXI_araddr), + .io_pcis_ar_bits_len(PCIE_M_AXI_arlen), + .io_pcis_ar_bits_size(PCIE_M_AXI_arsize), + .io_pcis_ar_bits_burst(2'h1), // PCIE_M_AXI_arburst + .io_pcis_ar_bits_lock(1'h0), // PCIE_M_AXI_arlock + .io_pcis_ar_bits_cache(4'h0), // PCIE_M_AXI_arcache + .io_pcis_ar_bits_prot(3'h0), // PCIE_M_AXI_arprot + .io_pcis_ar_bits_qos(4'h0), // PCIE_M_AXI_arqos + .io_pcis_ar_bits_region(4'h0), // PCIE_M_AXI_arregion + .io_pcis_ar_bits_id(PCIE_M_AXI_arid), + .io_pcis_ar_bits_user(1'h0), + + .io_pcis_r_ready(PCIE_M_AXI_rready), + .io_pcis_r_valid(PCIE_M_AXI_rvalid), + .io_pcis_r_bits_resp(PCIE_M_AXI_rresp), + .io_pcis_r_bits_data(PCIE_M_AXI_rdata), + .io_pcis_r_bits_last(PCIE_M_AXI_rlast), + .io_pcis_r_bits_id(PCIE_M_AXI_rid), + .io_pcis_r_bits_user(), // UNUSED at top level + + // `include "firesim_ila_insert_ports.v" + + .io_slave_0_aw_ready(DDR4_0_S_AXI_awready), + .io_slave_0_aw_valid(DDR4_0_S_AXI_awvalid), + .io_slave_0_aw_bits_addr(DDR4_0_S_AXI_awaddr), + .io_slave_0_aw_bits_len(DDR4_0_S_AXI_awlen), + .io_slave_0_aw_bits_size(DDR4_0_S_AXI_awsize), + .io_slave_0_aw_bits_burst(DDR4_0_S_AXI_awburst), // not available on DDR IF + .io_slave_0_aw_bits_lock(DDR4_0_S_AXI_awlock), // not available on DDR IF + .io_slave_0_aw_bits_cache(DDR4_0_S_AXI_awcache), // not available on DDR IF + .io_slave_0_aw_bits_prot(DDR4_0_S_AXI_awprot), // not available on DDR IF + .io_slave_0_aw_bits_qos(DDR4_0_S_AXI_awqos), // not available on DDR IF + .io_slave_0_aw_bits_id(DDR4_0_S_AXI_awid), + + .io_slave_0_w_ready(DDR4_0_S_AXI_wready), + .io_slave_0_w_valid(DDR4_0_S_AXI_wvalid), + .io_slave_0_w_bits_data(DDR4_0_S_AXI_wdata), + .io_slave_0_w_bits_last(DDR4_0_S_AXI_wlast), + .io_slave_0_w_bits_strb(DDR4_0_S_AXI_wstrb), + + .io_slave_0_b_ready(DDR4_0_S_AXI_bready), + .io_slave_0_b_valid(DDR4_0_S_AXI_bvalid), + .io_slave_0_b_bits_resp(DDR4_0_S_AXI_bresp), + .io_slave_0_b_bits_id(DDR4_0_S_AXI_bid), + + .io_slave_0_ar_ready(DDR4_0_S_AXI_arready), + .io_slave_0_ar_valid(DDR4_0_S_AXI_arvalid), + .io_slave_0_ar_bits_addr(DDR4_0_S_AXI_araddr), + .io_slave_0_ar_bits_len(DDR4_0_S_AXI_arlen), + .io_slave_0_ar_bits_size(DDR4_0_S_AXI_arsize), + .io_slave_0_ar_bits_burst(DDR4_0_S_AXI_arburst), // not available on DDR IF + .io_slave_0_ar_bits_lock(DDR4_0_S_AXI_arlock), // not available on DDR IF + .io_slave_0_ar_bits_cache(DDR4_0_S_AXI_arcache), // not available on DDR IF + .io_slave_0_ar_bits_prot(DDR4_0_S_AXI_arprot), // not available on DDR IF + .io_slave_0_ar_bits_qos(DDR4_0_S_AXI_arqos), // not available on DDR IF + .io_slave_0_ar_bits_id(DDR4_0_S_AXI_arid), // not available on DDR IF + + .io_slave_0_r_ready(DDR4_0_S_AXI_rready), + .io_slave_0_r_valid(DDR4_0_S_AXI_rvalid), + .io_slave_0_r_bits_resp(DDR4_0_S_AXI_rresp), + .io_slave_0_r_bits_data(DDR4_0_S_AXI_rdata), + .io_slave_0_r_bits_last(DDR4_0_S_AXI_rlast), + .io_slave_0_r_bits_id(DDR4_0_S_AXI_rid), + + .io_qsfp_channel_up_0(QSFP0_CHANNEL_UP), + .io_qsfp_tx_0_ready(TO_QSFP0_READY), + .io_qsfp_tx_0_valid(TO_QSFP0_VALID), + .io_qsfp_tx_0_bits(TO_QSFP0_DATA), + + .io_qsfp_rx_0_ready(FROM_QSFP0_READY), + .io_qsfp_rx_0_valid(FROM_QSFP0_VALID), + .io_qsfp_rx_0_bits(FROM_QSFP0_DATA), + + .io_qsfp_channel_up_1(QSFP1_CHANNEL_UP), + .io_qsfp_tx_1_ready(TO_QSFP1_READY), + .io_qsfp_tx_1_valid(TO_QSFP1_VALID), + .io_qsfp_tx_1_bits(TO_QSFP1_DATA), + + .io_qsfp_rx_1_ready(FROM_QSFP1_READY), + .io_qsfp_rx_1_valid(FROM_QSFP1_VALID), + .io_qsfp_rx_1_bits(FROM_QSFP1_DATA) + ); + +endmodule diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_connections.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_connections.tcl new file mode 120000 index 0000000000..c18ba7c77f --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_connections.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_connections.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_instances.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_instances.tcl new file mode 120000 index 0000000000..b01effe009 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_instances.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_instances.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_interfaces.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_interfaces.tcl new file mode 120000 index 0000000000..c06a174413 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/create_bd_interfaces.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_interfaces.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/ip_mod_list.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/ip_mod_list.tcl new file mode 120000 index 0000000000..00431f6dcc --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.1/ip_mod_list.tcl @@ -0,0 +1 @@ +../2022.1/ip_mod_list.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_connections.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_connections.tcl new file mode 120000 index 0000000000..c18ba7c77f --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_connections.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_connections.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_instances.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_instances.tcl new file mode 120000 index 0000000000..b01effe009 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_instances.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_instances.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_interfaces.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_interfaces.tcl new file mode 120000 index 0000000000..c06a174413 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/create_bd_interfaces.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_interfaces.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/ip_mod_list.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/ip_mod_list.tcl new file mode 120000 index 0000000000..00431f6dcc --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2021.2/ip_mod_list.tcl @@ -0,0 +1 @@ +../2022.1/ip_mod_list.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_connections.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_connections.tcl new file mode 100644 index 0000000000..ac9729808b --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_connections.tcl @@ -0,0 +1,142 @@ +connect_bd_intf_net -intf_net pcie_refclk_net [get_bd_intf_ports pcie_refclk] [get_bd_intf_pins util_ds_buf/CLK_IN_D] +connect_bd_intf_net -intf_net xdma_0_pcie_mgt_net [get_bd_intf_ports pci_express_x16] [get_bd_intf_pins xdma_0/pcie_mgt] +connect_bd_net -net pcie_perstn_net [get_bd_ports pcie_perstn] [get_bd_pins xdma_0/sys_rst_n] + +connect_bd_intf_net -intf_net ddr4_0_C0_DDR4_net [get_bd_intf_ports ddr4_sdram_c0] [get_bd_intf_pins ddr4_0/C0_DDR4] + +connect_bd_net -net resetn_net \ + [get_bd_ports resetn] \ + [get_bd_pins proc_sys_reset_0/ext_reset_in] \ + [get_bd_pins proc_sys_reset_ddr_0/ext_reset_in] \ + [get_bd_pins resetn_inv_0/Op1] + +connect_bd_intf_net -intf_net default_300mhz_clk0_net [get_bd_intf_ports default_300mhz_clk0] [get_bd_intf_pins ddr4_0/C0_SYS_CLK] + +connect_bd_intf_net -intf_net M_AXI_DDR0_net [get_bd_intf_pins axi_dwidth_converter_0/S_AXI] [get_bd_intf_ports DDR4_0_S_AXI] + +connect_bd_intf_net -intf_net axi_clock_converter_0_M_AXI_net [get_bd_intf_pins axi_clock_converter_0/M_AXI] [get_bd_intf_ports PCIE_M_AXI] +connect_bd_intf_net -intf_net axi_clock_converter_1_M_AXI_net [get_bd_intf_pins axi_clock_converter_1/M_AXI] [get_bd_intf_ports PCIE_M_AXI_LITE] + +connect_bd_net -net proc_sys_reset_0_interconnect_aresetn \ + [get_bd_ports sys_reset_n] \ + [get_bd_pins axi_clock_converter_0/m_axi_aresetn] \ + [get_bd_pins axi_clock_converter_1/m_axi_aresetn] \ + [get_bd_pins axi_dwidth_converter_0/s_axi_aresetn] \ + [get_bd_pins axis_clock_converter_0/m_axis_aresetn] \ + [get_bd_pins axis_clock_converter_1/s_axis_aresetn] \ + [get_bd_pins axis_clock_converter_2/m_axis_aresetn] \ + [get_bd_pins axis_clock_converter_3/s_axis_aresetn] \ + [get_bd_pins proc_sys_reset_0/interconnect_aresetn] + +connect_bd_net -net sys_clk_net \ + [get_bd_ports sys_clk] \ + [get_bd_pins axi_clock_converter_0/m_axi_aclk] \ + [get_bd_pins axi_clock_converter_1/m_axi_aclk] \ + [get_bd_pins axi_dwidth_converter_0/s_axi_aclk] \ + [get_bd_pins axis_clock_converter_0/m_axis_aclk] \ + [get_bd_pins axis_clock_converter_1/s_axis_aclk] \ + [get_bd_pins axis_clock_converter_2/m_axis_aclk] \ + [get_bd_pins axis_clock_converter_3/s_axis_aclk] \ + [get_bd_pins clk_wiz_0/clk_out1] \ + [get_bd_pins proc_sys_reset_0/slowest_sync_clk] + +connect_bd_intf_net -intf_net aurora_64b66b_0_USER_DATA_M_AXIS_RX [get_bd_intf_pins aurora_64b66b_0/USER_DATA_M_AXIS_RX] [get_bd_intf_pins axis_data_fifo_0/S_AXIS] +connect_bd_intf_net -intf_net aurora_64b66b_1_USER_DATA_M_AXIS_RX [get_bd_intf_pins aurora_64b66b_1/USER_DATA_M_AXIS_RX] [get_bd_intf_pins axis_data_fifo_2/S_AXIS] +connect_bd_intf_net -intf_net aurora_out_0 [get_bd_intf_ports qsfp0_4x] [get_bd_intf_pins aurora_gt_wrapper_0/QSFP_GT] +connect_bd_intf_net -intf_net aurora_out_1 [get_bd_intf_ports qsfp1_4x] [get_bd_intf_pins aurora_gt_wrapper_1/QSFP_GT] +connect_bd_intf_net -intf_net qsfp0_156mhz_1 [get_bd_intf_ports qsfp0_156mhz] [get_bd_intf_pins aurora_64b66b_0/GT_DIFF_REFCLK1] +connect_bd_intf_net -intf_net qsfp1_156mhz_1 [get_bd_intf_ports qsfp1_156mhz] [get_bd_intf_pins aurora_64b66b_1/GT_DIFF_REFCLK1] +connect_bd_intf_net -intf_net axis_clock_converter_1_M_AXIS [get_bd_intf_pins axis_clock_converter_1/M_AXIS] [get_bd_intf_pins axis_data_fifo_3/S_AXIS] +connect_bd_intf_net -intf_net axis_clock_converter_3_M_AXIS [get_bd_intf_pins axis_clock_converter_3/M_AXIS] [get_bd_intf_pins axis_data_fifo_1/S_AXIS] +connect_bd_intf_net -intf_net axis_data_fifo_0_M_AXIS [get_bd_intf_pins axis_clock_converter_2/S_AXIS] [get_bd_intf_pins axis_data_fifo_0/M_AXIS] +connect_bd_intf_net -intf_net axis_data_fifo_1_M_AXIS [get_bd_intf_pins aurora_64b66b_0/USER_DATA_S_AXIS_TX] [get_bd_intf_pins axis_data_fifo_1/M_AXIS] +connect_bd_intf_net -intf_net axis_data_fifo_2_M_AXIS [get_bd_intf_pins axis_clock_converter_0/S_AXIS] [get_bd_intf_pins axis_data_fifo_2/M_AXIS] +connect_bd_intf_net -intf_net axis_data_fifo_3_M_AXIS [get_bd_intf_pins aurora_64b66b_1/USER_DATA_S_AXIS_TX] [get_bd_intf_pins axis_data_fifo_3/M_AXIS] +connect_bd_intf_net -intf_net default_300mhz_clk1_net [get_bd_intf_ports default_300mhz_clk1] [get_bd_intf_pins clk_wiz_aurora_0/CLK_IN1_D] +connect_bd_intf_net -intf_net default_300mhz_clk2_net [get_bd_intf_ports default_300mhz_clk2] [get_bd_intf_pins clk_wiz_aurora_1/CLK_IN1_D] + +connect_bd_intf_net -intf_net axi_dwidth_converter_0_M_AXI [get_bd_intf_pins axi_dwidth_converter_0/M_AXI] [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI] + +connect_bd_intf_net -intf_net axi_tieoff_master_0_TIEOFF_M_AXI_CTRL_0 \ + [get_bd_intf_pins axi_tieoff_master_0/TIEOFF_M_AXI_CTRL_0] \ + [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI_CTRL] + +connect_bd_intf_net -intf_net xdma_0_M_AXI [get_bd_intf_pins axi_clock_converter_0/S_AXI] [get_bd_intf_pins xdma_0/M_AXI] +connect_bd_intf_net -intf_net xdma_0_M_AXI_LITE [get_bd_intf_pins axi_clock_converter_1/S_AXI] [get_bd_intf_pins xdma_0/M_AXI_LITE] + +# clock for system (clk_wiz_0/clk_in1) comes from DDR0 +connect_bd_net -net ddr4_0_c0_ddr4_ui_clk \ + [get_bd_pins clk_wiz_0/clk_in1] \ + [get_bd_pins proc_sys_reset_ddr_0/slowest_sync_clk] \ + [get_bd_pins axi_dwidth_converter_0/m_axi_aclk] \ + [get_bd_pins ddr4_0/c0_ddr4_ui_clk] + +connect_bd_net -net resetn_inv_0_Res \ + [get_bd_pins clk_wiz_0/reset] \ + [get_bd_pins ddr4_0/sys_rst] \ + [get_bd_pins clk_wiz_aurora_0/reset] \ + [get_bd_pins clk_wiz_aurora_1/reset] \ + [get_bd_pins resetn_inv_0/Res] + +connect_bd_net -net rst_ddr4_0_300M_interconnect_aresetn \ + [get_bd_pins axi_dwidth_converter_0/m_axi_aresetn] \ + [get_bd_pins ddr4_0/c0_ddr4_aresetn] \ + [get_bd_pins proc_sys_reset_ddr_0/interconnect_aresetn] + +connect_bd_net -net util_ds_buf_IBUF_DS_ODIV2 [get_bd_pins util_ds_buf/IBUF_DS_ODIV2] [get_bd_pins xdma_0/sys_clk] + +connect_bd_net -net util_ds_buf_IBUF_OUT [get_bd_pins util_ds_buf/IBUF_OUT] [get_bd_pins xdma_0/sys_clk_gt] + +connect_bd_net -net xdma_0_axi_aclk [get_bd_pins axi_clock_converter_0/s_axi_aclk] [get_bd_pins axi_clock_converter_1/s_axi_aclk] [get_bd_pins xdma_0/axi_aclk] + +connect_bd_net -net xdma_0_axi_aresetn [get_bd_pins axi_clock_converter_0/s_axi_aresetn] [get_bd_pins axi_clock_converter_1/s_axi_aresetn] [get_bd_pins xdma_0/axi_aresetn] + +connect_bd_net -net xlconstant_0_dout [get_bd_pins xdma_0/usr_irq_req] [get_bd_pins xlconstant_0/dout] + +########## + +connect_bd_net -net Net [get_bd_pins aurora_64b66b_1/user_clk_out] [get_bd_pins aurora_64b66b_1_driver/user_clk_i] [get_bd_pins axis_clock_converter_0/s_axis_aclk] [get_bd_pins axis_clock_converter_1/m_axis_aclk] [get_bd_pins axis_data_fifo_2/s_axis_aclk] [get_bd_pins axis_data_fifo_3/s_axis_aclk] +connect_bd_net -net aurora_64b66b_0_channel_up [get_bd_pins aurora_64b66b_0/channel_up] [get_bd_pins aurora_64b66b_0_driver/channel_up_i] [get_bd_ports QSFP0_CHANNEL_UP] +connect_bd_net -net aurora_64b66b_0_driver_INIT_CLK_i [get_bd_pins aurora_64b66b_0/init_clk] [get_bd_pins aurora_64b66b_0_driver/INIT_CLK_i] +connect_bd_net -net aurora_64b66b_0_driver_gt_reset_i [get_bd_pins aurora_64b66b_0/pma_init] [get_bd_pins aurora_64b66b_0_driver/gt_reset_i] +connect_bd_net -net aurora_64b66b_0_driver_gt_rxcdrovrden_i [get_bd_pins aurora_64b66b_0/gt_rxcdrovrden_in] [get_bd_pins aurora_64b66b_0_driver/gt_rxcdrovrden_i] +connect_bd_net -net aurora_64b66b_0_driver_loopback_i [get_bd_pins aurora_64b66b_0/loopback] [get_bd_pins aurora_64b66b_0_driver/loopback_i] +connect_bd_net -net aurora_64b66b_0_driver_power_down_i [get_bd_pins aurora_64b66b_0/power_down] [get_bd_pins aurora_64b66b_0_driver/power_down_i] +connect_bd_net -net aurora_64b66b_0_driver_reset_pb [get_bd_pins aurora_64b66b_0/reset_pb] [get_bd_pins aurora_64b66b_0_driver/reset_pb] +connect_bd_net -net aurora_64b66b_0_sys_reset_out [get_bd_pins aurora_64b66b_0/sys_reset_out] [get_bd_pins aurora_64b66b_0_driver/system_reset_i] [get_bd_pins util_vector_logic_1/Op1] +connect_bd_net -net aurora_64b66b_0_txn [get_bd_pins aurora_64b66b_0/txn] [get_bd_pins aurora_gt_wrapper_0/TXN_in] +connect_bd_net -net aurora_64b66b_0_txp [get_bd_pins aurora_64b66b_0/txp] [get_bd_pins aurora_gt_wrapper_0/TXP_in] +connect_bd_net -net aurora_64b66b_0_user_clk_out [get_bd_pins aurora_64b66b_0/user_clk_out] [get_bd_pins aurora_64b66b_0_driver/user_clk_i] [get_bd_pins axis_clock_converter_2/s_axis_aclk] [get_bd_pins axis_clock_converter_3/m_axis_aclk] [get_bd_pins axis_data_fifo_0/s_axis_aclk] [get_bd_pins axis_data_fifo_1/s_axis_aclk] +connect_bd_net -net aurora_64b66b_1_channel_up [get_bd_pins aurora_64b66b_1/channel_up] [get_bd_pins aurora_64b66b_1_driver/channel_up_i] [get_bd_ports QSFP1_CHANNEL_UP] +connect_bd_net -net aurora_64b66b_1_driver_INIT_CLK_i [get_bd_pins aurora_64b66b_1/init_clk] [get_bd_pins aurora_64b66b_1_driver/INIT_CLK_i] +connect_bd_net -net aurora_64b66b_1_driver_gt_reset_i [get_bd_pins aurora_64b66b_1/pma_init] [get_bd_pins aurora_64b66b_1_driver/gt_reset_i] +connect_bd_net -net aurora_64b66b_1_driver_gt_rxcdrovrden_i [get_bd_pins aurora_64b66b_1/gt_rxcdrovrden_in] [get_bd_pins aurora_64b66b_1_driver/gt_rxcdrovrden_i] +connect_bd_net -net aurora_64b66b_1_driver_loopback_i [get_bd_pins aurora_64b66b_1/loopback] [get_bd_pins aurora_64b66b_1_driver/loopback_i] +connect_bd_net -net aurora_64b66b_1_driver_power_down_i [get_bd_pins aurora_64b66b_1/power_down] [get_bd_pins aurora_64b66b_1_driver/power_down_i] +connect_bd_net -net aurora_64b66b_1_driver_reset_pb [get_bd_pins aurora_64b66b_1/reset_pb] [get_bd_pins aurora_64b66b_1_driver/reset_pb] +connect_bd_net -net aurora_64b66b_1_sys_reset_out [get_bd_pins aurora_64b66b_1/sys_reset_out] [get_bd_pins aurora_64b66b_1_driver/system_reset_i] [get_bd_pins util_vector_logic_0/Op1] +connect_bd_net -net aurora_64b66b_1_txn [get_bd_pins aurora_64b66b_1/txn] [get_bd_pins aurora_gt_wrapper_1/TXN_in] +connect_bd_net -net aurora_64b66b_1_txp [get_bd_pins aurora_64b66b_1/txp] [get_bd_pins aurora_gt_wrapper_1/TXP_in] +connect_bd_net -net aurora_gt_wrapper_0_RXN_in [get_bd_pins aurora_64b66b_0/rxn] [get_bd_pins aurora_gt_wrapper_0/RXN_in] +connect_bd_net -net aurora_gt_wrapper_0_RXP_in [get_bd_pins aurora_64b66b_0/rxp] [get_bd_pins aurora_gt_wrapper_0/RXP_in] +connect_bd_net -net aurora_gt_wrapper_1_RXN_in [get_bd_pins aurora_64b66b_1/rxn] [get_bd_pins aurora_gt_wrapper_1/RXN_in] +connect_bd_net -net aurora_gt_wrapper_1_RXP_in [get_bd_pins aurora_64b66b_1/rxp] [get_bd_pins aurora_gt_wrapper_1/RXP_in] +connect_bd_net -net axis_clock_converter_0_m_axis_tdata [get_bd_pins axis_clock_converter_0/m_axis_tdata] [get_bd_ports FROM_QSFP1_DATA] +connect_bd_net -net axis_clock_converter_0_m_axis_tvalid [get_bd_pins axis_clock_converter_0/m_axis_tvalid] [get_bd_ports FROM_QSFP1_VALID] +connect_bd_net -net axis_clock_converter_1_s_axis_tready [get_bd_pins axis_clock_converter_1/s_axis_tready] [get_bd_ports TO_QSFP1_READY] +connect_bd_net -net axis_clock_converter_2_m_axis_tdata [get_bd_pins axis_clock_converter_2/m_axis_tdata] [get_bd_ports FROM_QSFP0_DATA] +connect_bd_net -net axis_clock_converter_2_m_axis_tvalid [get_bd_pins axis_clock_converter_2/m_axis_tvalid] [get_bd_ports FROM_QSFP0_VALID] +connect_bd_net -net axis_clock_converter_3_s_axis_tready [get_bd_pins axis_clock_converter_3/s_axis_tready] [get_bd_ports TO_QSFP0_READY] +connect_bd_net -net clk_wiz_aurora_0_clk_out1 [get_bd_pins aurora_64b66b_0_driver/INIT_CLK_IN] [get_bd_pins clk_wiz_aurora_0/clk_out1] +connect_bd_net -net clk_wiz_aurora_0_locked [get_bd_pins aurora_64b66b_0_driver/locked] [get_bd_pins clk_wiz_aurora_0/locked] +connect_bd_net -net clk_wiz_aurora_1_clk_out1 [get_bd_pins aurora_64b66b_1_driver/INIT_CLK_IN] [get_bd_pins clk_wiz_aurora_1/clk_out1] +connect_bd_net -net clk_wiz_aurora_1_locked [get_bd_pins aurora_64b66b_1_driver/locked] [get_bd_pins clk_wiz_aurora_1/locked] +connect_bd_net -net util_vector_logic_0_Res [get_bd_pins axis_clock_converter_0/s_axis_aresetn] [get_bd_pins axis_clock_converter_1/m_axis_aresetn] [get_bd_pins axis_data_fifo_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_3/s_axis_aresetn] [get_bd_pins util_vector_logic_0/Res] +connect_bd_net -net util_vector_logic_1_Res [get_bd_pins axis_clock_converter_2/s_axis_aresetn] [get_bd_pins axis_clock_converter_3/m_axis_aresetn] [get_bd_pins axis_data_fifo_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_1/s_axis_aresetn] [get_bd_pins util_vector_logic_1/Res] + +connect_bd_net -net firesim_wrapper_0_FROM_QSFP0_READY [get_bd_pins axis_clock_converter_2/m_axis_tready] [get_bd_ports FROM_QSFP0_READY] +connect_bd_net -net firesim_wrapper_0_FROM_QSFP1_READY [get_bd_pins axis_clock_converter_0/m_axis_tready] [get_bd_ports FROM_QSFP1_READY] +connect_bd_net -net firesim_wrapper_0_TO_QSFP0_DATA [get_bd_pins axis_clock_converter_3/s_axis_tdata] [get_bd_ports TO_QSFP0_DATA] +connect_bd_net -net firesim_wrapper_0_TO_QSFP0_VALID [get_bd_pins axis_clock_converter_3/s_axis_tvalid] [get_bd_ports TO_QSFP0_VALID] +connect_bd_net -net firesim_wrapper_0_TO_QSFP1_DATA [get_bd_pins axis_clock_converter_1/s_axis_tdata] [get_bd_ports TO_QSFP1_DATA] +connect_bd_net -net firesim_wrapper_0_TO_QSFP1_VALID [get_bd_pins axis_clock_converter_1/s_axis_tvalid] [get_bd_ports TO_QSFP1_VALID] diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_instances.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_instances.tcl new file mode 100644 index 0000000000..67cd4628d5 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_instances.tcl @@ -0,0 +1,219 @@ +proc create_axi_clock_converter { name } { + return [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_clock_converter:2.1 $name ] +} +set axi_clock_converter_0 [ create_axi_clock_converter axi_clock_converter_0 ] +set axi_clock_converter_1 [ create_axi_clock_converter axi_clock_converter_1 ] + +proc create_axi_dwidth_converter { name } { + set axi_dwidth_props [list \ + CONFIG.MI_DATA_WIDTH.VALUE_SRC USER \ + CONFIG.ACLK_ASYNC {1} \ + CONFIG.FIFO_MODE {2} \ + CONFIG.MI_DATA_WIDTH {512} \ + CONFIG.SI_DATA_WIDTH {64} \ + CONFIG.SI_ID_WIDTH {16} \ + ] + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dwidth_converter:2.1 $name ] + set_property -dict $axi_dwidth_props $i + return $i +} +set axi_dwidth_converter_0 [ create_axi_dwidth_converter axi_dwidth_converter_0 ] + +proc create_axi_tieoff_master { name } { + set block_name axi_tieoff_master + set block_cell_name $name + if { [catch {set i [create_bd_cell -type module -reference $block_name $block_cell_name] } errmsg] } { + catch {common::send_gid_msg -ssname BD::TCL -id 2095 -severity "ERROR" "Unable to add referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } elseif { $i eq "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2096 -severity "ERROR" "Unable to referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } + return $i +} +set axi_tieoff_master_0 [ create_axi_tieoff_master axi_tieoff_master_0 ] + +set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ] +set_property -dict [list \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ $firesim_freq_mhz \ + CONFIG.USE_LOCKED {false} \ +] $clk_wiz_0 + +proc create_ddr { name clk_intf ddr_intf } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:ddr4:2.2 $name ] + set_property -dict [list \ + CONFIG.C0_CLOCK_BOARD_INTERFACE $clk_intf \ + CONFIG.C0_DDR4_BOARD_INTERFACE $ddr_intf \ + CONFIG.ADDN_UI_CLKOUT1_FREQ_HZ {100} \ + CONFIG.C0.DDR4_AUTO_AP_COL_A3 {true} \ + CONFIG.C0.DDR4_AxiAddressWidth {34} \ + CONFIG.C0.DDR4_EN_PARITY {true} \ + CONFIG.C0.DDR4_MCS_ECC {false} \ + CONFIG.C0.DDR4_Mem_Add_Map {ROW_COLUMN_BANK_INTLV} \ + CONFIG.Debug_Signal {Disable} \ + CONFIG.RESET_BOARD_INTERFACE {resetn} \ + ] $i + return $i +} +set ddr4_0 [ create_ddr ddr4_0 default_300mhz_clk0 ddr4_sdram_c0 ] + +set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] + +proc create_proc_sys_reset_ddr { name } { + return [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 $name ] +} +set proc_sys_reset_ddr_0 [ create_proc_sys_reset_ddr proc_sys_reset_ddr_0 ] + +set resetn_inv_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_vector_logic:2.0 resetn_inv_0 ] +set_property -dict [list \ + CONFIG.C_OPERATION {not} \ + CONFIG.C_SIZE {1} \ +] $resetn_inv_0 + +set util_ds_buf [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_ds_buf:2.2 util_ds_buf ] +set_property -dict [list \ + CONFIG.C_BUF_TYPE {IBUFDSGTE} \ + CONFIG.DIFF_CLK_IN_BOARD_INTERFACE {pcie_refclk} \ + CONFIG.USE_BOARD_FLOW {true} \ +] $util_ds_buf + +set xdma_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xdma:4.1 xdma_0 ] +set_property -dict [list \ + CONFIG.PCIE_BOARD_INTERFACE {pci_express_x16} \ + CONFIG.SYS_RST_N_BOARD_INTERFACE {pcie_perstn} \ + CONFIG.axilite_master_en {true} \ + CONFIG.axilite_master_size {32} \ + CONFIG.xdma_axi_intf_mm {AXI_Memory_Mapped} \ + CONFIG.xdma_rnum_chnl {4} \ + CONFIG.xdma_wnum_chnl {4} \ + CONFIG.pciebar2axibar_axist_bypass {0x0000000000000000} \ + CONFIG.pf0_msix_cap_pba_bir {BAR_1} \ + CONFIG.pf0_msix_cap_table_bir {BAR_1} \ + CONFIG.xdma_axi_intf_mm {AXI_Memory_Mapped} \ +] $xdma_0 + +set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ] +set_property -dict [ list \ + CONFIG.CONST_VAL {0} \ +] $xlconstant_0 + +proc create_generic_aurora_64b66b { name } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:aurora_64b66b:12.0 $name ] + set_property -dict [ list \ + CONFIG.C_AURORA_LANES {4} \ + CONFIG.C_GT_LOC_2 {2} \ + CONFIG.C_GT_LOC_3 {3} \ + CONFIG.C_GT_LOC_4 {4} \ + CONFIG.C_LINE_RATE {15} \ + CONFIG.SupportLevel {1} \ + CONFIG.drp_mode {Disabled} \ + CONFIG.interface_mode {Streaming} \ + ] $i + return $i +} +# X1YN where N=4,5,6,7,10,11 (channel enable is N*4 to N*4+3) +set aurora_64b66b_0 [ create_generic_aurora_64b66b aurora_64b66b_0 ] +set_property -dict [ list \ + CONFIG.CHANNEL_ENABLE {X1Y44 X1Y45 X1Y46 X1Y47} \ + CONFIG.C_REFCLK_SOURCE {MGTREFCLK0_of_Quad_X1Y11} \ + CONFIG.C_START_LANE {X1Y44} \ + CONFIG.C_START_QUAD {Quad_X1Y11} \ +] $aurora_64b66b_0 +set aurora_64b66b_1 [ create_generic_aurora_64b66b aurora_64b66b_1 ] +set_property -dict [ list \ + CONFIG.CHANNEL_ENABLE {X1Y40 X1Y41 X1Y42 X1Y43} \ + CONFIG.C_REFCLK_SOURCE {MGTREFCLK0_of_Quad_X1Y10} \ + CONFIG.C_START_LANE {X1Y40} \ + CONFIG.C_START_QUAD {Quad_X1Y10} \ +] $aurora_64b66b_1 + +proc create_aurora_driver { name } { + set block_name aurora_64b66b_0_driver + set block_cell_name $name + if { [catch {set i [create_bd_cell -type module -reference $block_name $block_cell_name] } errmsg] } { + catch {common::send_gid_msg -ssname BD::TCL -id 2095 -severity "ERROR" "Unable to add referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } elseif { $i eq "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2096 -severity "ERROR" "Unable to referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } + set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_HIGH} \ + ] [get_bd_pins /$name/reset_pb] + return $i +} +set aurora_64b66b_0_driver [ create_aurora_driver aurora_64b66b_0_driver ] +set aurora_64b66b_1_driver [ create_aurora_driver aurora_64b66b_1_driver ] + +proc create_aurora_gt_wrapper { name } { + set block_name aurora_gt_wrapper + set block_cell_name $name + if { [catch {set i [create_bd_cell -type module -reference $block_name $block_cell_name] } errmsg] } { + catch {common::send_gid_msg -ssname BD::TCL -id 2095 -severity "ERROR" "Unable to add referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } elseif { $i eq "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2096 -severity "ERROR" "Unable to referenced block <$block_name>. Please add the files for ${block_name}'s definition into the project."} + exit 1 + } + return $i +} +set aurora_gt_wrapper_0 [ create_aurora_gt_wrapper aurora_gt_wrapper_0 ] +set aurora_gt_wrapper_1 [ create_aurora_gt_wrapper aurora_gt_wrapper_1 ] + +proc create_axis_clock_converter { name } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_clock_converter:1.1 $name ] + set_property -dict [ list \ + CONFIG.SYNCHRONIZATION_STAGES {3} \ + CONFIG.TDATA_NUM_BYTES {32} \ + ] $i + return $i +} +set axis_clock_converter_0 [ create_axis_clock_converter axis_clock_converter_0 ] +set axis_clock_converter_1 [ create_axis_clock_converter axis_clock_converter_1 ] +set axis_clock_converter_2 [ create_axis_clock_converter axis_clock_converter_2 ] +set axis_clock_converter_3 [ create_axis_clock_converter axis_clock_converter_3 ] + +proc create_axis_data_fifo { name } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 $name ] + set_property -dict [ list \ + CONFIG.FIFO_DEPTH {2048} \ + CONFIG.TDATA_NUM_BYTES {32} \ + ] $i + return $i +} +set axis_data_fifo_0 [ create_axis_data_fifo axis_data_fifo_0 ] +set axis_data_fifo_1 [ create_axis_data_fifo axis_data_fifo_1 ] +set axis_data_fifo_2 [ create_axis_data_fifo axis_data_fifo_2 ] +set axis_data_fifo_3 [ create_axis_data_fifo axis_data_fifo_3 ] + +proc create_aurora_clk_wiz { name } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 $name ] + set_property -dict [ list \ + CONFIG.CLKIN1_JITTER_PS {33.330000000000005} \ + CONFIG.CLKOUT1_JITTER {101.475} \ + CONFIG.CLKOUT1_PHASE_ERROR {77.836} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {100} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {4.000} \ + CONFIG.MMCM_CLKIN1_PERIOD {3.333} \ + CONFIG.MMCM_CLKIN2_PERIOD {10.0} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {12.000} \ + CONFIG.MMCM_DIVCLK_DIVIDE {1} \ + CONFIG.PRIM_IN_FREQ {300.000} \ + CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} \ + ] $i + return $i +} +set clk_wiz_aurora_0 [ create_aurora_clk_wiz clk_wiz_aurora_0 ] +set clk_wiz_aurora_1 [ create_aurora_clk_wiz clk_wiz_aurora_1 ] + +proc create_util_vector_logic { name } { + set i [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_vector_logic:2.0 $name ] + set_property -dict [ list \ + CONFIG.C_OPERATION {not} \ + CONFIG.C_SIZE {1} \ + CONFIG.LOGO_FILE {data/sym_notgate.png} \ + ] $i + return $i +} +set util_vector_logic_0 [ create_util_vector_logic util_vector_logic_0 ] +set util_vector_logic_1 [ create_util_vector_logic util_vector_logic_1 ] diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_interfaces.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_interfaces.tcl new file mode 100644 index 0000000000..31960b281d --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/create_bd_interfaces.tcl @@ -0,0 +1,108 @@ +# Create interface ports + +proc create_ddr_sdram_intf_port { name } { + return [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddr4_rtl:1.0 $name ] +} +set ddr4_sdram_c0 [ create_ddr_sdram_intf_port ddr4_sdram_c0 ] + +proc create_300mhz_clk_intf_port { name } { + set shared_clk_props [ list \ + CONFIG.FREQ_HZ {300000000} \ + ] + set i [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 $name ] + set_property -dict $shared_clk_props $i + return $i +} +set default_300mhz_clk0 [ create_300mhz_clk_intf_port default_300mhz_clk0 ] +set default_300mhz_clk1 [ create_300mhz_clk_intf_port default_300mhz_clk1 ] +set default_300mhz_clk2 [ create_300mhz_clk_intf_port default_300mhz_clk2 ] +set default_300mhz_clk3 [ create_300mhz_clk_intf_port default_300mhz_clk3 ] + +set pci_express_x16 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 pci_express_x16 ] + +set pcie_refclk [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 pcie_refclk ] +set_property -dict [ list \ + CONFIG.FREQ_HZ {100000000} \ +] $pcie_refclk + +set PCIE_M_AXI [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 PCIE_M_AXI ] +set_property -dict [ list \ + CONFIG.FREQ_HZ $firesim_freq_hz \ + CONFIG.DATA_WIDTH 512 \ +] $PCIE_M_AXI +set PCIE_M_AXI_LITE [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 PCIE_M_AXI_LITE ] +set_property -dict [ list \ + CONFIG.FREQ_HZ $firesim_freq_hz \ + CONFIG.PROTOCOL AXI4LITE \ +] $PCIE_M_AXI_LITE + +proc create_ddr_intf_port { name firesim_freq_hz } { + set i [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 $name ] + set_property -dict [ list \ + CONFIG.FREQ_HZ $firesim_freq_hz \ + CONFIG.DATA_WIDTH 64 \ + ] $i + return $i +} +set DDR4_0_S_AXI [ create_ddr_intf_port DDR4_0_S_AXI $firesim_freq_hz ] + +proc create_qsfp_clk_intf_port { name } { + set i [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 $name ] + set_property -dict [ list \ + CONFIG.FREQ_HZ {156250000} \ + ] $i + return $i +} +proc create_qsfp_intf_port { name } { + return [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gt_rtl:1.0 $name ] +} +set qsfp0_156mhz [ create_qsfp_clk_intf_port qsfp0_156mhz ] +set qsfp1_156mhz [ create_qsfp_clk_intf_port qsfp1_156mhz ] +set qsfp0_4x [ create_qsfp_intf_port qsfp0_4x ] +set qsfp1_4x [ create_qsfp_intf_port qsfp1_4x ] + +# Create ports + +set pcie_perstn [ create_bd_port -dir I -type rst pcie_perstn ] +set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_LOW} \ +] $pcie_perstn + +set resetn [ create_bd_port -dir I -type rst resetn ] +set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_LOW} \ +] $resetn + +set sys_clk [ create_bd_port -dir O -type clk sys_clk ] +set_property -dict [ list \ + CONFIG.FREQ_HZ $firesim_freq_hz \ +] $sys_clk +set sys_reset_n [ create_bd_port -dir O -type rst sys_reset_n ] + +proc create_bd_port_data_vector { name dir from to } { + set i [ create_bd_port -dir $dir -from $from -to $to $name ] + return $i +} +proc create_bd_port_data_nonvector { name dir } { + set i [ create_bd_port -dir $dir $name ] + return $i +} +# TO/FROM: the perspective of block design to/from the FireSim block +set QSFP0_CHANNEL_UP [ create_bd_port_data_nonvector QSFP0_CHANNEL_UP O ] +set QSFP1_CHANNEL_UP [ create_bd_port_data_nonvector QSFP1_CHANNEL_UP O ] + +set TO_QSFP0_READY [ create_bd_port_data_nonvector TO_QSFP0_READY O ] +set TO_QSFP0_VALID [ create_bd_port_data_nonvector TO_QSFP0_VALID I ] +set TO_QSFP0_DATA [ create_bd_port_data_vector TO_QSFP0_DATA I 255 0 ] + +set TO_QSFP1_READY [ create_bd_port_data_nonvector TO_QSFP1_READY O ] +set TO_QSFP1_VALID [ create_bd_port_data_nonvector TO_QSFP1_VALID I ] +set TO_QSFP1_DATA [ create_bd_port_data_vector TO_QSFP1_DATA I 255 0 ] + +set FROM_QSFP0_READY [ create_bd_port_data_nonvector FROM_QSFP0_READY I ] +set FROM_QSFP0_VALID [ create_bd_port_data_nonvector FROM_QSFP0_VALID O ] +set FROM_QSFP0_DATA [ create_bd_port_data_vector FROM_QSFP0_DATA O 255 0 ] + +set FROM_QSFP1_READY [ create_bd_port_data_nonvector FROM_QSFP1_READY I ] +set FROM_QSFP1_VALID [ create_bd_port_data_nonvector FROM_QSFP1_VALID O ] +set FROM_QSFP1_DATA [ create_bd_port_data_vector FROM_QSFP1_DATA O 255 0 ] diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/ip_mod_list.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/ip_mod_list.tcl new file mode 100644 index 0000000000..dfec2eb7d4 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.1/ip_mod_list.tcl @@ -0,0 +1,20 @@ +set list_check_ips "\ +xilinx.com:ip:aurora_64b66b:12.0\ +xilinx.com:ip:axi_clock_converter:2.1\ +xilinx.com:ip:axi_dwidth_converter:2.1\ +xilinx.com:ip:axis_clock_converter:1.1\ +xilinx.com:ip:axis_data_fifo:2.0\ +xilinx.com:ip:clk_wiz:6.0\ +xilinx.com:ip:ddr4:2.2\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:util_vector_logic:2.0\ +xilinx.com:ip:util_ds_buf:2.2\ +xilinx.com:ip:xdma:4.1\ +xilinx.com:ip:xlconstant:1.1\ +" + +set list_check_mods "\ +aurora_64b66b_0_driver\ +aurora_gt_wrapper\ +axi_tieoff_master\ +" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_connections.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_connections.tcl new file mode 120000 index 0000000000..c18ba7c77f --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_connections.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_connections.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_instances.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_instances.tcl new file mode 120000 index 0000000000..b01effe009 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_instances.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_instances.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_interfaces.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_interfaces.tcl new file mode 120000 index 0000000000..c06a174413 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/create_bd_interfaces.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_interfaces.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/ip_mod_list.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/ip_mod_list.tcl new file mode 120000 index 0000000000..00431f6dcc --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2022.2/ip_mod_list.tcl @@ -0,0 +1 @@ +../2022.1/ip_mod_list.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_connections.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_connections.tcl new file mode 120000 index 0000000000..c18ba7c77f --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_connections.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_connections.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_instances.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_instances.tcl new file mode 120000 index 0000000000..b01effe009 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_instances.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_instances.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_interfaces.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_interfaces.tcl new file mode 120000 index 0000000000..c06a174413 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/create_bd_interfaces.tcl @@ -0,0 +1 @@ +../2022.1/create_bd_interfaces.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/ip_mod_list.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/ip_mod_list.tcl new file mode 120000 index 0000000000..00431f6dcc --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/bd_lib/2023.1/ip_mod_list.tcl @@ -0,0 +1 @@ +../2022.1/ip_mod_list.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/create_bd.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/create_bd.tcl new file mode 100644 index 0000000000..9c07f5d22e --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/create_bd.tcl @@ -0,0 +1,173 @@ +set current_vivado_version [version -short] + +proc get_bd_lib_file { script_folder filename version } { + return $script_folder/bd_lib/$version/$filename +} + +################################################################## +# START (i.e. create block design) +################################################################## + +# block design name (MUST NOT CHANGE) +set design_name design_1 + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..." +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name +} + +common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg} + return $nRet +} + +################################################################## +# CHECK IPs and Modules +################################################################## + +# obtain the 'list_check_ips' and 'list_check_mods' variables +check_file_exists [set sourceFile [get_bd_lib_file $script_folder ip_mod_list.tcl $current_vivado_version]] +source $sourceFile + +set bCheckIPsPassed 1 +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_ips_missing "" + common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } +} + +set bCheckModules 1 +if { $bCheckModules == 1 } { + set list_mods_missing "" + common::send_gid_msg -ssname BD::TCL -id 2020 -severity "INFO" "Checking if the following modules exist in the project's sources: $list_check_mods ." + + foreach mod_vlnv $list_check_mods { + if { [can_resolve_reference $mod_vlnv] == 0 } { + lappend list_mods_missing $mod_vlnv + } + } + + if { $list_mods_missing ne "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2021 -severity "ERROR" "The following module(s) are not found in the project: $list_mods_missing" } + common::send_gid_msg -ssname BD::TCL -id 2022 -severity "INFO" "Please add source files for the missing module(s) above." + set bCheckIPsPassed 0 + } +} + +if { $bCheckIPsPassed != 1 } { + common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { script_folder parentCell firesim_freq_mhz current_vivado_version } { + set firesim_freq_hz [expr $firesim_freq_mhz * 1000000] + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + check_file_exists [set sourceFile [get_bd_lib_file $script_folder create_bd_interfaces.tcl $current_vivado_version]] + source $sourceFile + check_file_exists [set sourceFile [get_bd_lib_file $script_folder create_bd_instances.tcl $current_vivado_version]] + source $sourceFile + check_file_exists [set sourceFile [get_bd_lib_file $script_folder create_bd_connections.tcl $current_vivado_version]] + source $sourceFile + + # Restore current instance + current_bd_instance $oldCurInst + + validate_bd_design + save_bd_design +} +# End of create_root_design() + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design $script_folder "" $desired_host_frequency $current_vivado_version diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation.tcl new file mode 100644 index 0000000000..33d557c0df --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation.tcl @@ -0,0 +1,48 @@ +set impl_run [get_runs impl_1] + +reset_runs ${impl_run} + +set_property -dict [ list \ + STEPS.OPT_DESIGN.IS_ENABLED $opt \ + STEPS.OPT_DESIGN.DIRECTIVE $opt_directive \ + {STEPS.OPT_DESIGN.MORE OPTIONS} "$opt_options" \ + STEPS.PLACE_DESIGN.DIRECTIVE $place_directive \ + {STEPS.PLACE_DESIGN.MORE OPTIONS} "$place_options" \ + STEPS.PHYS_OPT_DESIGN.IS_ENABLED $phys_opt \ + STEPS.PHYS_OPT_DESIGN.DIRECTIVE $phys_directive \ + {STEPS.PHYS_OPT_DESIGN.MORE OPTIONS} "$phys_options" \ + STEPS.ROUTE_DESIGN.DIRECTIVE $route_directive \ + {STEPS.ROUTE_DESIGN.MORE OPTIONS} "$route_options" \ + STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED $route_phys_opt \ + STEPS.POST_ROUTE_PHYS_OPT_DESIGN.DIRECTIVE $post_phys_directive \ + {STEPS.POST_ROUTE_PHYS_OPT_DESIGN.MORE OPTIONS} "$post_phys_options" \ +] ${impl_run} + +if {$route_phys_opt} { + set run_to_step {phys_opt_design (Post-Route)} +} else { + set run_to_step route_design +} +launch_runs ${impl_run} -to_step ${run_to_step} -jobs ${jobs} +wait_on_run ${impl_run} +check_progress ${impl_run} "first normal implementation failed" + +set WNS [get_property STATS.WNS ${impl_run}] +set WHS [get_property STATS.WHS ${impl_run}] + +# run idr or ml flow to close timing +if {$WNS < 0 || $WHS < 0} { + check_file_exists [set sourceFile ${root_dir}/scripts/implementation_idr_ml/${vivado_version}.tcl] + source $sourceFile + # expects that $WHS/WNS is re-set +} + +if {$WNS < 0 || $WHS < 0} { + puts "ERROR: did not meet timing!" + exit 1 +} + +puts "INFO: generate bitstream" +launch_runs ${impl_run} -to_step write_bitstream -jobs ${jobs} +wait_on_run ${impl_run} +check_progress ${impl_run} "bitstream generation failed" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.1.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.1.tcl new file mode 100644 index 0000000000..2fe47512bb --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.1.tcl @@ -0,0 +1,62 @@ +set ml_max_critical_paths 150 +set ml_max_strategies 5 +set ml_qor_suggestions ${root_dir}/vivado_proj/ml_qor_suggestions.rqs +set ml_strategy_dir ${root_dir}/vivado_proj/ml_strategies + +# Cleanup +delete_files [list ${ml_qor_suggestions} ${ml_strategy_dir}] + +set ml_tcls [list] + +open_run ${impl_run} +report_qor_suggestions -max_paths ${ml_max_critical_paths} -max_strategies ${ml_max_strategies} -no_split -quiet +write_qor_suggestions -force -strategy_dir ${ml_strategy_dir} ${ml_qor_suggestions} +close_design + +for {set i 1} {$i <= ${ml_max_strategies}} {incr i} { + set tclFile ${root_dir}/vivado_proj/ml_strategies/impl_1Project_MLStrategyCreateRun${i}.tcl + if {[file exists ${tclFile}]} { + lappend ml_tcls ${tclFile} + } +} + +if {([llength ${ml_tcls}] == 0) && ([file exists ${ml_qor_suggestions}])} { + puts "INFO: no ML strategies were found, using base qor suggestions" + + add_files -force -fileset utils_1 ${ml_qor_suggestions} + + reset_runs ${impl_run} + + set_property RQS_FILES ${ml_qor_suggestions} ${impl_run} + set_property STEPS.OPT_DESIGN.ARGS.DIRECTIVE RQS ${impl_run} + set_property STEPS.PLACE_DESIGN.ARGS.DIRECTIVE RQS ${impl_run} + set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true ${impl_run} + set_property STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE RQS ${impl_run} + set_property STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE RQS ${impl_run} + + launch_runs ${impl_run} -to_step route_design -jobs ${jobs} + wait_on_run ${impl_run} + + check_progress ${impl_run} "implementation failed" + + set WNS [get_property STATS.WNS [get_runs ${impl_run}]] + set WHS [get_property STATS.WHS [get_runs ${impl_run}]] +} else { + foreach tclFile ${ml_tcls} { + puts "INFO: using ML strategy from ${tclFile}" + source ${tclFile} + set impl_run ${ml_strategy_run} + + launch_runs ${impl_run} -to_step route_design -jobs ${jobs} + wait_on_run ${impl_run} + + check_progress ${impl_run} "implementation failed" + + set WNS [get_property STATS.WNS [get_runs ${impl_run}]] + set WHS [get_property STATS.WHS [get_runs ${impl_run}]] + + if {$WNS >= 0 && $WHS >= 0} { + break + } + } +} diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.2.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.2.tcl new file mode 120000 index 0000000000..c43b3cdef3 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2021.2.tcl @@ -0,0 +1 @@ +2021.1.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.1.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.1.tcl new file mode 120000 index 0000000000..f31ad8df1d --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.1.tcl @@ -0,0 +1 @@ +2022.2.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.2.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.2.tcl new file mode 100644 index 0000000000..d182cc55bc --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2022.2.tcl @@ -0,0 +1,21 @@ +# Intelligent Design Runs (IDR) Flow +create_run -flow "Vivado IDR Flow $vivado_version_major" -parent_run synth_1 idr_impl_1 +set_property REFERENCE_RUN ${impl_run} [get_runs idr_impl_1] +set impl_run [get_runs idr_impl_1] + +launch_runs ${impl_run} -jobs ${jobs} +wait_on_run ${impl_run} + +check_progress ${impl_run} "idr implementation failed" + +# We need to figure out which IDR implementation run was successful +foreach sub_impl_run [get_runs ${impl_run}*] { + if {[get_property PROGRESS ${sub_impl_run}] == "100%"} { + set WNS [get_property STATS.WNS ${sub_impl_run}] + set WHS [get_property STATS.WHS ${sub_impl_run}] + if {$WNS >= 0 && $WHS >= 0} { + puts "INFO: timing met in idr run ${sub_impl_run}" + break + } + } +} diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2023.1.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2023.1.tcl new file mode 120000 index 0000000000..f31ad8df1d --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/implementation_idr_ml/2023.1.tcl @@ -0,0 +1 @@ +2022.2.tcl \ No newline at end of file diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/main.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/main.tcl new file mode 100644 index 0000000000..b75dca09b0 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/main.tcl @@ -0,0 +1,135 @@ +set root_dir [pwd] +set vivado_version [version -short] +set vivado_version_major [string range $vivado_version 0 3] + +set ifrequency [lindex $argv 0] +set istrategy [lindex $argv 1] +set iboard [lindex $argv 2] + +proc retrieveVersionedFile { filename version } { + set first [file rootname $filename] + set last [file extension $filename] + if {[file exists ${first}_${version}${last}]} { + return ${first}_${version}${last} + } + return $filename +} + +# get utilities +source $root_dir/scripts/utils.tcl + +puts "Running with Vivado $vivado_version (Major Version: $vivado_version_major)" + +check_file_exists [set sourceFile [retrieveVersionedFile ${root_dir}/scripts/platform_env.tcl $vivado_version]] +source $sourceFile + +check_file_exists [set sourceFile [retrieveVersionedFile ${root_dir}/scripts/${iboard}.tcl $vivado_version]] +source $sourceFile + +# Cleanup +delete_files [list ${root_dir}/vivado_proj/firesim.bit] + +create_project -force firesim ${root_dir}/vivado_proj -part $part +set_property board_part $board_part [current_project] + +# Loading all the verilog files +foreach addFile [list \ + ${root_dir}/design/axi_tieoff_master.v \ + ${root_dir}/design/axi.vh \ + ${root_dir}/design/helpers.vh \ + ${root_dir}/design/overall_fpga_top.v \ + ${root_dir}/design/FireSim-generated.sv \ + ${root_dir}/design/FireSim-generated.defines.vh \ + ${root_dir}/design/aurora/aurora_64b66b_0_driver.v \ + ${root_dir}/design/aurora/aurora_64b66b_0_cdc_sync_exdes.v \ + ${root_dir}/design/aurora/aurora_64b66b_0_utils.v \ +] { + set addFile [retrieveVersionedFile $addFile $vivado_version] + check_file_exists $addFile + add_files $addFile + if {[file extension $addFile] == ".vh"} { + set_property IS_GLOBAL_INCLUDE 1 [get_files $addFile] + } +} + +set desired_host_frequency $ifrequency +set strategy $istrategy + +# Loading create_bd.tcl +check_file_exists [set sourceFile ${root_dir}/scripts/create_bd.tcl] +source $sourceFile + +# Making wrapper around bd +generate_target all [get_files ${root_dir}/vivado_proj/firesim.srcs/sources_1/bd/design_1/design_1.bd] +update_compile_order -fileset sources_1 + +# Mark top-level name for future steps/cmds +set top_level_name overall_fpga_top + +# Report if any IPs need to be updated +report_ip_status + +# Adding additional constraint sets +create_fileset -constrset synth_fileset +create_fileset -constrset impl_fileset + +if {[file exists [set constrFile [retrieveVersionedFile ${root_dir}/design/FireSim-generated.synthesis.xdc $vivado_version]]]} { + # map L2 banks to URAMs if possible (might warn if cells not present) + add_line_to_file 1 $constrFile "set_property RAM_STYLE ULTRA \[get_cells -hierarchical -regexp {.*firesim_top.*cc_banks_.*_reg.*}\]" + add_files -fileset synth_fileset -norecurse $constrFile +} + +if {[file exists [set constrFile [retrieveVersionedFile ${root_dir}/design/FireSim-generated.implementation.xdc $vivado_version]]]} { + # add impl clock to top of xdc + add_line_to_file 1 $constrFile "create_generated_clock -name host_clock \[get_pins design_1_i/clk_wiz_0/inst/mmcme4_adv_inst/CLKOUT0\]" + add_files -fileset impl_fileset -norecurse $constrFile +} + + +if {[file exists [set constrFile [retrieveVersionedFile ${root_dir}/design/bitstream_config.xdc $vivado_version]]]} { + add_files -fileset impl_fileset -norecurse $constrFile +} + +update_compile_order -fileset sources_1 +set_property top $top_level_name [current_fileset] +update_compile_order -fileset sources_1 + +foreach f [get_files -of [get_filesets synth_fileset]] { + set_property USED_IN {synthesis} $f + set_property USED_IN_IMPLEMENTATION 0 $f + set_property USED_IN_SYNTHESIS 1 $f +} + +foreach f [get_files -of [get_filesets impl_fileset]] { + set_property USED_IN {implementation} $f + set_property USED_IN_IMPLEMENTATION 1 $f + set_property USED_IN_SYNTHESIS 0 $f + set_property PROCESSING_ORDER LATE $f +} + +proc set_fileset_for_run_or_delete { fsname runname } { + if {[llength [get_filesets -quiet $fsname]]} { + set_property constrset $fsname [get_runs $runname] + } else { + delete_fileset $fsname + } +} +set_fileset_for_run_or_delete synth_fileset synth_1 +set_fileset_for_run_or_delete impl_fileset impl_1 + +set rpt_dir ${root_dir}/vivado_proj/reports +file mkdir ${rpt_dir} + +# Set synth/impl strategy vars +check_file_exists [set sourceFile ${root_dir}/scripts/strategies/strategy_${strategy}.tcl] +source $sourceFile + +# Run synth/impl and generate collateral +foreach sourceFile [list ${root_dir}/scripts/synthesis.tcl ${root_dir}/scripts/post_synth.tcl ${root_dir}/scripts/implementation.tcl ${root_dir}/scripts/post_impl.tcl] { + set sourceFile [retrieveVersionedFile $sourceFile $vivado_version] + check_file_exists $sourceFile + source $sourceFile +} + +puts "Done!" +exit 0 diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/platform_env.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/platform_env.tcl new file mode 100644 index 0000000000..84ef64eaa4 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/platform_env.tcl @@ -0,0 +1 @@ +set jobs 8 diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/post_impl.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/post_impl.tcl new file mode 100644 index 0000000000..8f0908bbb5 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/post_impl.tcl @@ -0,0 +1,25 @@ +# write reports + +open_run impl_1 + +# Report final timing +report_timing_summary -file ${rpt_dir}/final_timing_summary.rpt + +# Report utilization +report_utilization -hierarchical -hierarchical_percentages -file ${rpt_dir}/final_utilization.rpt + +# Report RAM utilization +report_ram_utilization -include_lutram -file ${rpt_dir}/final_ram_utilization.rpt -csv ${rpt_dir}/final_ram_utilization.csv + +# Report clock utilization +report_clock_utilization -file ${rpt_dir}/final_clock_utilization.rpt + +close_design + +# write bit/mcs + +set firesim_bit_path ${root_dir}/vivado_proj/firesim.bit + +file copy -force ${root_dir}/vivado_proj/firesim.runs/${impl_run}/${top_level_name}.bit ${firesim_bit_path} + +write_cfgmem -force -format mcs -interface SPIx4 -size 1024 -loadbit "up 0x01002000 ${firesim_bit_path}" -verbose ${root_dir}/vivado_proj/firesim.mcs diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/post_synth.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/post_synth.tcl new file mode 100644 index 0000000000..20666618aa --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/post_synth.tcl @@ -0,0 +1,11 @@ +# write reports + +open_run synth_1 + +# Report utilization +report_utilization -hierarchical -hierarchical_percentages -file ${rpt_dir}/post_synth_utilization.rpt + +# Report control sets +report_control_sets -verbose -file ${rpt_dir}/post_synth_control_sets.rpt + +close_design diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_AREA.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_AREA.tcl new file mode 100644 index 0000000000..29f4a1f343 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_AREA.tcl @@ -0,0 +1,25 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-retiming" +set synth_directive "AreaOptimized_high" + +# Everything after this point is identical to the Timing strategy and should be +# explored for future area savings. + +set opt 1 +set opt_options "" +set opt_directive "Explore" + +set place_options "" +set place_directive "ExtraNetDelay_high" + +set phys_opt 1 +set phys_options "" +set phys_directive "AggressiveExplore" + +set route_options "-tns_cleanup" +set route_directive "Explore" + +set route_phys_opt 1 +set post_phys_options "" +set post_phys_directive "AggressiveExplore" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_BASIC.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_BASIC.tcl new file mode 100644 index 0000000000..97a237bba4 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_BASIC.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-keep_equivalent_registers -retiming" +set synth_directive "default" + +set opt 1 +set opt_options "" +set opt_directive "ExploreWithRemap" + +set place_options "" +set place_directive "Explore" + +set phys_opt 1 +set phys_options "" +set phys_directive "AggressiveExplore" + +set route_options "" +set route_directive "Explore" + +set route_phys_opt 1 +set post_phys_options "" +set post_phys_directive "AggressiveExplore" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_CONGESTION.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_CONGESTION.tcl new file mode 100644 index 0000000000..66bbe88881 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_CONGESTION.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-no_lc -shreg_min_size 10 -control_set_opt_threshold 16 -retiming" +set synth_directive "AlternateRoutability" + +set opt 1 +set opt_options "-bufg_opt -control_set_merge -hier_fanout_limit 512 -muxf_remap -propconst -retarget -sweep" +set opt_directive "" + +set place_options "" +set place_directive "AltSpreadLogic_medium" + +set phys_opt 1 +set phys_options "" +set phys_directive "AggressiveExplore" + +set route_options "" +set route_directive "Explore" + +set route_phys_opt 0 +set post_phys_options "" +set post_phys_directive "" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_DEFAULT.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_DEFAULT.tcl new file mode 100644 index 0000000000..1f8c731b29 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_DEFAULT.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-keep_equivalent_registers -flatten_hierarchy rebuilt -retiming" +set synth_directive "default" + +set opt 1 +set opt_options "" +set opt_directive "" + +set place_options "" +set place_directive "" + +set phys_opt 0 +set phys_options "" +set phys_directive "" + +set route_options "" +set route_directive "" + +set route_phys_opt 0 +set post_phys_options "" +set post_phys_directive "" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_EXPLORE.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_EXPLORE.tcl new file mode 100644 index 0000000000..9876fdf9ca --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_EXPLORE.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-keep_equivalent_registers -flatten_hierarchy rebuilt -retiming" +set synth_directive "default" + +set opt 1 +set opt_options "" +set opt_directive "Explore" + +set place_options "" +set place_directive "Explore" + +set phys_opt 1 +set phys_options "" +set phys_directive "Explore" + +set route_options "" +set route_directive "Explore" + +set route_phys_opt 0 +set post_phys_options "" +set post_phys_directive "Explore" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_NORETIMING.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_NORETIMING.tcl new file mode 100644 index 0000000000..2f09f40e2c --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_NORETIMING.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-no_lc -shreg_min_size 5 -fsm_extraction one_hot -resource_sharing auto" +set synth_directive "default" + +set opt 1 +set opt_options "" +set opt_directive "Explore" + +set place_options "" +set place_directive "ExtraNetDelay_high" + +set phys_opt 1 +set phys_options "" +set phys_directive "AggressiveExplore" + +set route_options "-tns_cleanup" +set route_directive "Explore" + +set route_phys_opt 1 +set post_phys_options "" +set post_phys_directive "AggressiveExplore" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_TIMING.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_TIMING.tcl new file mode 100644 index 0000000000..dc1e5b3641 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/strategies/strategy_TIMING.tcl @@ -0,0 +1,22 @@ +# adapted from aws-fpga's strategies (minus the extra params + hook tcl) + +set synth_options "-no_lc -shreg_min_size 5 -fsm_extraction one_hot -resource_sharing auto -retiming" +set synth_directive "default" + +set opt 1 +set opt_options "" +set opt_directive "Explore" + +set place_options "" +set place_directive "ExtraNetDelay_high" + +set phys_opt 1 +set phys_options "" +set phys_directive "AggressiveExplore" + +set route_options "-tns_cleanup" +set route_directive "Explore" + +set route_phys_opt 1 +set post_phys_options "" +set post_phys_directive "AggressiveExplore" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/synthesis.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/synthesis.tcl new file mode 100644 index 0000000000..d3b9703c6c --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/synthesis.tcl @@ -0,0 +1,13 @@ +variable synth_run [get_runs synth_1] + +reset_runs ${synth_run} + +set_property -dict [ list \ + STEPS.SYNTH_DESIGN.ARGS.DIRECTIVE ${synth_directive} \ + {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} "${synth_options}" \ +] ${synth_run} + +launch_runs ${synth_run} -jobs ${jobs} +wait_on_run ${synth_run} + +check_progress ${synth_run} "synthesis failed" diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/utils.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/utils.tcl new file mode 100644 index 0000000000..a536d103f0 --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/utils.tcl @@ -0,0 +1,38 @@ +proc delete_files { file_list } { + foreach path $file_list { + if {[file exists ${path}]} { + file delete -force -- ${path} + } + } +} + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +set script_folder [_tcl::get_script_folder] + +proc check_file_exists { inFile } { + if {![file exists $inFile]} { + puts "ERROR: Could not find $inFile" + exit 1 + } +} + +proc check_progress { run errmsg } { + set progress [get_property PROGRESS ${run}] + if {$progress != "100%"} { + puts "ERROR: $errmsg (progress at $progress/%100)" + exit 1 + } +} + +proc add_line_to_file { lineno ifile istr } { + if {[catch {exec sed -i "${lineno}i ${istr}\\n" ${ifile}}]} { + puts "ERROR: Updating ${ifile} failed ($result)" + exit 1 + } +} diff --git a/platforms/xilinx_vc707/cl_firesim/scripts/vc707.tcl b/platforms/xilinx_vc707/cl_firesim/scripts/vc707.tcl new file mode 100644 index 0000000000..92c8299d3a --- /dev/null +++ b/platforms/xilinx_vc707/cl_firesim/scripts/vc707.tcl @@ -0,0 +1,23 @@ +# ************************************************************************* +# +# Copyright 2020 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ************************************************************************* + +# Adapted from https://github.com/Xilinx/open-nic-shell + +set part XC7VX485T-2FFG1761C +set board_part xilinx.com:au250:part0:1.3 +set zynq_family 0 diff --git a/platforms/xilinx_vc707/scripts/berkeley-setup-fpgas.sh b/platforms/xilinx_vc707/scripts/berkeley-setup-fpgas.sh new file mode 100755 index 0000000000..b9fc2bbfdb --- /dev/null +++ b/platforms/xilinx_vc707/scripts/berkeley-setup-fpgas.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -ex + +BITSTREAM=$SCRATCH_HOME/firesim-private/deploy/results-build/2023-05-12--07-11-08-alveou250_firesim_rocket_singlecore_no_nic_w_pres/cl_xilinx_alveo_u250-firesim-FireSim-FireSimRocketConfig-BaseXilinxAlveoConfig/xilinx_alveo_u250/firesim.bit + +./fpga-util.py --bdf 04:00.0 --disconnect-bdf +./fpga-util.py --bdf 83:00.0 --disconnect-bdf + +if lspci | grep -i xilinx; then + echo "Something went wrong" + exit 1 +else + echo "Missing them" +fi + +./fpga-util.py --serial Xilinx/21320733400EA --bitstream $BITSTREAM +./fpga-util.py --serial Xilinx/213207334001A --bitstream $BITSTREAM + +if lspci | grep -i xilinx; then + echo "Something went wrong" + exit 1 +else + echo "Missing them" +fi + +./fpga-util.py --bdf 04:00.0 --reconnect-bdf +./fpga-util.py --bdf 83:00.0 --reconnect-bdf + +if lspci | grep -i xilinx; then + echo "Found them" +else + echo "Something went wrong" + exit 1 +fi + +## from scratch +# +#./fpga-util.py --bdf 04:00.0 --disconnect-bdf +#./fpga-util.py --bdf 04:00.1 --disconnect-bdf +#./fpga-util.py --bdf 83:00.0 --disconnect-bdf +#./fpga-util.py --bdf 83:00.1 --disconnect-bdf +# +#./fpga-util.py --serial Xilinx/21320733400EA --bitstream $BITSTREAM +#./fpga-util.py --serial Xilinx/213207334001A --bitstream $BITSTREAM +# +##./fpga-util.py --bdf 04:00.0 --reconnect-bdf +##./fpga-util.py --bdf 04:00.1 --reconnect-bdf +##./fpga-util.py --bdf 83:00.0 --reconnect-bdf +##./fpga-util.py --bdf 83:00.1 --reconnect-bdf diff --git a/platforms/xilinx_vc707/scripts/firesim-fpga-util.py b/platforms/xilinx_vc707/scripts/firesim-fpga-util.py new file mode 100755 index 0000000000..96f9be4a25 --- /dev/null +++ b/platforms/xilinx_vc707/scripts/firesim-fpga-util.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 + +import argparse +import os +import subprocess +import sys +import shutil +import json +from pathlib import Path +import pcielib +import util + +from typing import Dict, Any, List + +scriptPath = Path(__file__).resolve().parent +# firesim specific location of where to read/write database file +dbPath = Path() # must be overridden by cmdline + +def program_fpga(vivado: Path, serial: str, bitstream: str) -> None: + progTcl = scriptPath / 'program_fpga.tcl' + assert progTcl.exists(), f"Unable to find {progTcl}" + rc, stdout, stderr = util.call_vivado( + vivado, + [ + '-source', str(progTcl), + '-tclargs', + '-serial', serial, + '-bitstream_path', bitstream, + ] + ) + if rc != 0: + sys.exit(f":ERROR: Unable to flash FPGA {serial} with {bitstream}.\nstdout:\n{stdout}\nstderr:\n{stderr}") + +# mapping functions + +def set_fpga_db(db: Path) -> None: + global dbPath + dbPath = db + +def get_fpga_db() -> Dict[Any, Any]: + global dbPath + if dbPath.exists(): + with open(dbPath, 'r') as f: + return json.load(f) + else: + print(f":ERROR: Unable to open {dbPath}. Does it exist? Did you run 'firesim enumeratefpgas'?", file=sys.stderr) + sys.exit(f":ERROR: Unable to create FPGA database from {dbPath}") + +def get_serial_from_bus_id(id: str) -> str: + deviceBDF = pcielib.get_bdf_from_extended_bdf(pcielib.get_singular_device_extended_bdf(id)) + for e in get_fpga_db(): + if deviceBDF == e['bdf']: + return e['uid'] + sys.exit(":ERROR: Unable to get serial number from bus id") + +def get_serials() -> List[str]: + serials = [] + for e in get_fpga_db(): + serials.append(e['uid']) + return serials + +def get_extended_bdfs() -> List[str]: + bdfs = [] + for e in get_fpga_db(): + bdfs.append(pcielib.get_extended_bdf_from_bdf(e['bdfs'])) + return bdfs + +# main + +def main(args: List[str]) -> int: + parser = argparse.ArgumentParser(description="Program/manipulate a Xilinx XDMA-enabled FPGA device") + megroup = parser.add_mutually_exclusive_group(required=True) + megroup.add_argument("--bus_id", help="Bus number of FPGA (i.e. ****::**.*)") + megroup.add_argument("--bdf", help="BDF of FPGA (i.e. ****:)") + megroup.add_argument("--extended-bdf", help="Extended BDF of FPGA (i.e. all of this - ****:**:**.*)") + megroup.add_argument("--serial", help="Serial number of FPGA (i.e. what 'get_hw_target' shows in Vivado)") + megroup.add_argument("--all-serials", help="Use all serial numbers (no PCI-E manipulation)", action="store_true") + megroup.add_argument("--all-bdfs", help="Use all BDFs (PCI-E manipulation)", action="store_true") + parser.add_argument("--vivado-bin", help="Explicit path to 'vivado'", type=Path) + parser.add_argument("--hw-server-bin", help="Explicit path to 'hw_server'", type=Path) + parser.add_argument("--fpga-db", help="Explicit path to FPGA DB file (used to resolve BDFs to serial numbers or obtain all serial numbers of FPGAs)", type=Path, required=True) + megroup2 = parser.add_mutually_exclusive_group(required=True) + megroup2.add_argument("--bitstream", help="The bitstream to flash onto FPGA(s)", type=Path) + megroup2.add_argument("--disconnect-bdf", help="Disconnect BDF(s)", action="store_true") + megroup2.add_argument("--reconnect-bdf", help="Reconnect BDF(s)", action="store_true") + parsed_args = parser.parse_args(args) + + if parsed_args.hw_server_bin is None: + parsed_args.hw_server_bin = shutil.which('hw_server') + if parsed_args.vivado_bin is None: + parsed_args.vivado_bin = shutil.which('vivado') + if parsed_args.vivado_bin is None: + parsed_args.vivado_bin = shutil.which('vivado_lab') + + if parsed_args.hw_server_bin is None: + print(':ERROR: Could not find Xilinx Hardware Server!', file=sys.stderr) + exit(1) + if parsed_args.vivado_bin is None: + print(':ERROR: Could not find Xilinx Vivado (or Vivado Lab)!', file=sys.stderr) + exit(1) + + parsed_args.vivado_bin = Path(parsed_args.vivado_bin).absolute() + parsed_args.hw_server_bin = Path(parsed_args.hw_server_bin).absolute() + + eUserId = os.geteuid() + sudoUserId = os.getenv('SUDO_UID') + isAdmin = (eUserId == 0) and (sudoUserId is None) + userId = eUserId if sudoUserId is None else int(sudoUserId) + + # if not sudoer, spawn w/ sudo + if eUserId != 0: + execvArgs = ['/usr/bin/sudo', str(Path(__file__).absolute())] + sys.argv[1:] + execvArgs += ['--vivado-bin', str(parsed_args.vivado_bin), '--hw-server-bin', str(parsed_args.hw_server_bin)] + print(f":INFO: Running: {execvArgs}") + os.execv(execvArgs[0], execvArgs) + + # use cmdline db file + set_fpga_db(parsed_args.fpga_db) + + def is_bdf_arg(parsed_args) -> bool: + return parsed_args.bus_id or parsed_args.bdf or parsed_args.extended_bdf or parsed_args.all_bdfs + + def get_bus_ids_from_args(parsed_args) -> List[str]: + bus_ids = [] + if parsed_args.bus_id: + bus_ids.append(parsed_args.bus_id) + if parsed_args.bdf: + bus_ids.append(pcielib.get_bus_id_from_extended_bdf(pcielib.get_extended_bdf_from_bdf(parsed_args.bdf))) + if parsed_args.extended_bdf: + bus_ids.append(pcielib.get_bus_id_from_extended_bdf(parsed_args.extended_bdf)) + if parsed_args.all_bdfs: + bus_ids.extend([pcielib.get_bus_id_from_extended_bdf(bdf) for bdf in get_extended_bdfs()]) + return bus_ids + + def disconnect_bus_id(bus_id: str) -> None: + pcielib.clear_serr_bits(bus_id) + pcielib.clear_fatal_error_reporting_bits(bus_id) + pcielib.remove(bus_id) + assert not pcielib.any_device_exists(bus_id), f"{bus_id} still visible. Check for proper removal." + + def reconnect_bus_id(bus_id: str) -> None: + pcielib.rescan(bus_id) + pcielib.enable_memmapped_transfers(bus_id) + assert pcielib.any_device_exists(bus_id), f"{bus_id} not visible. Check for proper rescan." + + # program based on bitstream + if parsed_args.bitstream is not None: + if not parsed_args.bitstream.is_file() or not parsed_args.bitstream.exists(): + sys.exit(f":ERROR: Invalid bitstream: {parsed_args.bitstream}") + else: + parsed_args.bitstream = parsed_args.bitstream.absolute() + + if is_bdf_arg(parsed_args): + bus_ids = get_bus_ids_from_args(parsed_args) + + # must be called before the remove otherwise it will not find a serial number + serialNums = [] + for bus_id in bus_ids: + serialNums.append(get_serial_from_bus_id(bus_id)) + + for bus_id in bus_ids: + disconnect_bus_id(bus_id) + + # program fpga(s) separately if doing multiple bdfs + for i, bus_id in enumerate(bus_ids): + serialNumber = serialNums[i] + program_fpga(parsed_args.vivado_bin, serialNumber, parsed_args.bitstream) + print(f":INFO: Successfully programmed FPGA {bus_id} with {parsed_args.bitstream}") + + for bus_id in bus_ids: + reconnect_bus_id(bus_id) + + if parsed_args.serial or parsed_args.all_serials: + serials = [] + if parsed_args.serial: + serials.append(parsed_args.serial) + if parsed_args.all_serials: + serials.extend(get_serials()) + + for serial in serials: + program_fpga(parsed_args.vivado_bin, serial, parsed_args.bitstream) + print(f":INFO: Successfully programmed FPGA {serial} with {parsed_args.bitstream}") + print(":WARNING: Please warm reboot the machine") + + # disconnect bdfs + if parsed_args.disconnect_bdf: + if is_bdf_arg(parsed_args): + bus_ids = get_bus_ids_from_args(parsed_args) + for bus_id in bus_ids: + disconnect_bus_id(bus_id) + else: + sys.exit("Must provide a BDF-like argument to disconnect") + + # reconnect bdfs + if parsed_args.reconnect_bdf: + if is_bdf_arg(parsed_args): + bus_ids = get_bus_ids_from_args(parsed_args) + for bus_id in bus_ids: + reconnect_bus_id(bus_id) + else: + sys.exit("Must provide a BDF-like argument to disconnect") + + return 0 + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/platforms/xilinx_vc707/scripts/firesim-generate-fpga-db.py b/platforms/xilinx_vc707/scripts/firesim-generate-fpga-db.py new file mode 100755 index 0000000000..8db666e421 --- /dev/null +++ b/platforms/xilinx_vc707/scripts/firesim-generate-fpga-db.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 + +import argparse +import os +import subprocess +import sys +import pwd +import re +import shutil +import signal +import json +from pathlib import Path +import pcielib +import util + +from typing import Optional, Dict, Any, List + +scriptPath = Path(__file__).resolve().parent +defaultDbPath = Path("/opt/firesim-db.json") + +def get_bdfs() -> List[str]: + pLspci= subprocess.Popen(['lspci'], stdout=subprocess.PIPE) + pGrep = subprocess.Popen(['grep', '-i', 'xilinx'], stdin=pLspci.stdout, stdout=subprocess.PIPE) + if pLspci.stdout is not None: + pLspci.stdout.close() + + sout, serr = pGrep.communicate() + + eSout = sout.decode('utf-8') if sout is not None else "" + eSerr = serr.decode('utf-8') if serr is not None else "" + + if pGrep.returncode != 0: + sys.exit(f":ERROR: It failed with stdout: {eSout} stderr: {eSerr}") + + outputLines = eSout.splitlines() + bdfs = [ i[:7] for i in outputLines if len(i.strip()) >= 0] + return bdfs + +def call_fpga_util(args: List[str]) -> None: + progScript = Path('/usr/local/bin/firesim-fpga-util.py') + assert progScript.exists(), f"Unable to find {progScript}" + pProg = subprocess.Popen( + [str(progScript.resolve().absolute())] + args, + stdout=subprocess.PIPE + ) + + sout, serr = pProg.communicate() + + eSout = sout.decode('utf-8') if sout is not None else "" + eSerr = serr.decode('utf-8') if serr is not None else "" + + if pProg.returncode != 0: + sys.exit(f":ERROR: It failed with stdout: {eSout} stderr: {eSerr}") + +def disconnect_bdf(bdf: str, vivado: str, hw_server: str) -> None: + print(f":INFO: Disconnecting BDF: {bdf}") + global defaultDbPath + call_fpga_util([ + "--fpga-db", defaultDbPath, + "--bdf", bdf, + "--disconnect-bdf", + "--vivado-bin", vivado, + "--hw-server-bin", hw_server, + ]) + +def reconnect_bdf(bdf: str, vivado: str, hw_server: str) -> None: + print(f":INFO: Reconnecting BDF: {bdf}") + global defaultDbPath + call_fpga_util([ + "--fpga-db", defaultDbPath, + "--bdf", bdf, + "--reconnect-bdf", + "--vivado-bin", vivado, + "--hw-server-bin", hw_server, + ]) + +def program_fpga(serial: str, bitstream: str, vivado: str, hw_server: str) -> None: + print(f":INFO: Programming {serial} with {bitstream}") + global defaultDbPath + call_fpga_util([ + "--fpga-db", defaultDbPath, + "--serial", serial, + "--bitstream", bitstream, + "--vivado-bin", vivado, + "--hw-server-bin", hw_server, + ]) + +def get_serial_numbers_and_fpga_types(vivado: Path) -> Dict[str, str]: + global scriptPath + tclScript = scriptPath / 'get_serial_dev_for_fpgas.tcl' + assert tclScript.exists(), f"Unable to find {tclScript}" + rc, stdout, stderr = util.call_vivado(vivado, ['-source', str(tclScript)]) + if rc != 0: + sys.exit(f":ERROR: It failed with:\nstdout:\n{stdout}\nstderr:\n{stderr}") + + outputLines = stdout.splitlines() + relevantLines= [s for s in outputLines if ("hw_dev" in s) or ("hw_uid" in s)] + devs = [] + uids = [] + + for line in relevantLines: + m = re.match(r"^hw_dev: (.*)$", line) + if m: + devs.append(m.group(1)) + + m = re.match(r"^hw_uid: (.*)$", line) + if m: + uids.append(m.group(1)) + + uid2dev = {} + for uid, dev in zip(uids, devs): + uid2dev[uid] = dev + + return uid2dev + +def call_driver(bdf: str, driver: Path, args: List[str]) -> int: + bus_id = pcielib.get_bus_id_from_extended_bdf(pcielib.get_extended_bdf_from_bdf(bdf)) + + driverPath = driver.resolve().absolute() + assert driverPath.exists(), f"Unable to find {driverPath}" + + pProg = subprocess.Popen( + [ + str(driverPath), + "+permissive", + f"+bus={bus_id}", + ] + args + [ + "+permissive-off", + "+prog0=none", + ], + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + + try: + sout, serr = pProg.communicate(timeout=5) + except: + # spam any amount of flush signals + pProg.send_signal(signal.SIGPIPE) + pProg.send_signal(signal.SIGUSR1) + pProg.send_signal(signal.SIGUSR2) + + # spam any amount of kill signals + pProg.kill() + pProg.send_signal(signal.SIGINT) + pProg.send_signal(signal.SIGTERM) + + # retrieve flushed output + sout, serr = pProg.communicate() + + eSout = sout.decode('utf-8') if sout is not None else "" + eSerr = serr.decode('utf-8') if serr is not None else "" + + if pProg.returncode == 124 or pProg.returncode is None: + sys.exit(":ERROR: Timed out...") + elif pProg.returncode != 0: + print(f":WARNING: Running the driver failed...", file=sys.stderr) + + print(f":DEBUG: bdf: {bdf} bus_id: {bus_id}\nstdout:\n{eSout}\nstderr:\n{eSerr}") + return pProg.returncode + +def run_driver_check_fingerprint(bdf: str, driver: Path) -> int: + print(f":INFO: Running check fingerprint driver call with {bdf}") + return call_driver(bdf, driver, ["+check-fingerprint"]) + +def run_driver_write_fingerprint(bdf: str, driver: Path, write_val: int) -> int: + print(f":INFO: Running write fingerprint driver call with {bdf}") + # TODO: maybe confirm write went through in the stdout/err? + return call_driver(bdf, driver, [f"+write-fingerprint={write_val}"]) + +def main(args: List[str]) -> int: + parser = argparse.ArgumentParser(description="Generate a FireSim json database file") + parser.add_argument("--bitstream", help="Bitstream to flash on all Xilinx XDMA-enabled FPGAs (must align with --driver)", type=Path, required=True) + parser.add_argument("--driver", help="FireSim driver to test bitstream with (must align with --bitstream)", type=Path, required=True) + parser.add_argument("--out-db-json", help="Path to output FireSim database", type=Path, required=True) + parser.add_argument("--vivado-bin", help="Explicit path to 'vivado'", type=Path) + parser.add_argument("--hw-server-bin", help="Explicit path to 'hw_server'", type=Path) + parsed_args = parser.parse_args(args) + + if parsed_args.hw_server_bin is None: + parsed_args.hw_server_bin = shutil.which('hw_server') + if parsed_args.vivado_bin is None: + parsed_args.vivado_bin = shutil.which('vivado') + if parsed_args.vivado_bin is None: + parsed_args.vivado_bin = shutil.which('vivado_lab') + + if parsed_args.hw_server_bin is None: + print(':ERROR: Could not find Xilinx Hardware Server!', file=sys.stderr) + exit(1) + if parsed_args.vivado_bin is None: + print(':ERROR: Could not find Xilinx Vivado!', file=sys.stderr) + exit(1) + + parsed_args.vivado_bin = Path(parsed_args.vivado_bin).absolute() + parsed_args.hw_server_bin = Path(parsed_args.hw_server_bin).absolute() + + eUserId = os.geteuid() + sudoUserId = os.getenv('SUDO_UID') + isAdmin = (eUserId == 0) and (sudoUserId is None) + userId = eUserId if sudoUserId is None else int(sudoUserId) + + if eUserId != 0: + execvArgs = ['/usr/bin/sudo', str(Path(__file__).absolute())] + sys.argv[1:] + execvArgs += ['--vivado-bin', str(parsed_args.vivado_bin), '--hw-server-bin', str(parsed_args.hw_server_bin)] + print(f":INFO: Running: {execvArgs}") + os.execv(execvArgs[0], execvArgs) + + print(":INFO: This script expects that all Xilinx XDMA-enabled FPGAs are programmed with the same --bitstream arg. by default (through an MCS file for bistream file)") + + # 1. get all serial numbers for all fpgas on the system + + sno2fpga = get_serial_numbers_and_fpga_types(parsed_args.vivado_bin) + serials = sno2fpga.keys() + bdfs = get_bdfs() + + # 2. program all fpgas so that they are in a known state + + # disconnect all + for bdf in bdfs: + disconnect_bdf(bdf, str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + for serial in serials: + program_fpga(serial, str(parsed_args.bitstream.resolve().absolute()), str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + # reconnect all + for bdf in bdfs: + reconnect_bdf(bdf, str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + serial2BDF: Dict[str, str] = {} + + write_val = 0xDEADBEEF + + # 3. write to all fingerprints based on bdfs + + for bdf in bdfs: + run_driver_write_fingerprint(bdf, parsed_args.driver, write_val) + + # 4. create mapping by checking if fingerprint was overridden + + for serial in serials: + # disconnect all + for bdf in bdfs: + disconnect_bdf(bdf, str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + program_fpga(serial, str(parsed_args.bitstream.resolve().absolute()), str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + # reconnect all + for bdf in bdfs: + reconnect_bdf(bdf, str(parsed_args.vivado_bin), str(parsed_args.hw_server_bin)) + + # read all fingerprints to find the good one + for bdf in bdfs: + if not (bdf in serial2BDF.values()): + rc = run_driver_check_fingerprint(bdf, parsed_args.driver) + if rc == 0: + serial2BDF[serial] = bdf + break + + if not (serial in serial2BDF): + print(f":ERROR: Unable to determine BDF for {serial} FPGA. Something went wrong", file=sys.stderr) + sys.exit(1) + + print(f":INFO: Mapping: {serial2BDF}") + + finalMap = [] + for s, b in serial2BDF.items(): + finalMap.append({ + "uid" : s, + "device" : sno2fpga[s], + "bdf" : b + }) + + with open(parsed_args.out_db_json, 'w') as f: + json.dump(finalMap, f, indent=2) + + print(f":INFO: Successfully wrote to {parsed_args.out_db_json}") + + return 0 + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/platforms/xilinx_vc707/scripts/get_serial_dev_for_fpgas.tcl b/platforms/xilinx_vc707/scripts/get_serial_dev_for_fpgas.tcl new file mode 100644 index 0000000000..c6da6024a5 --- /dev/null +++ b/platforms/xilinx_vc707/scripts/get_serial_dev_for_fpgas.tcl @@ -0,0 +1,23 @@ +# Directory variables +set script_path [file normalize [info script]] +set script_dir [file dirname $script_path] +set root_dir [file dirname $script_dir] + +set_param labtools.enable_cs_server false + +open_hw_manager +connect_hw_server -allow_non_jtag + +# by default vivado opens a default hw target +close_hw_target + +foreach {hw_target} [get_hw_targets] { + open_hw_target $hw_target + set hw_dev [get_hw_device] + set hw_uid [get_property UID $hw_target] + puts "hw_dev: $hw_dev" + puts "hw_uid: $hw_uid" + close_hw_target +} + +exit diff --git a/platforms/xilinx_vc707/scripts/pcielib.py b/platforms/xilinx_vc707/scripts/pcielib.py new file mode 100644 index 0000000000..1d9ac44f5d --- /dev/null +++ b/platforms/xilinx_vc707/scripts/pcielib.py @@ -0,0 +1,159 @@ +import subprocess +import sys +import re +import time +from pathlib import Path + +from typing import Dict, List + +pciDevicesPath = Path('/sys/bus/pci/devices') + +def get_device_paths(bus_id: str) -> List[Path]: + result = [] + for entry in pciDevicesPath.iterdir(): + if re.match('^0000:' + re.escape(bus_id) + ':[a-fA-F0-9]{2}\.[0-7]$', entry.name): + result.append(entry) + return result + +def get_device_extended_bdfs(bus_id: str) -> List[str]: + return [e.name for e in get_device_paths(bus_id)] + +def get_singular_device_path(bus_id: str) -> Path: + devicePaths = get_device_paths(bus_id) + if len(devicePaths) == 0: + sys.exit(f":ERROR: Unable to obtain Extended Device BDF path for {bus_id}") + if len(devicePaths) != 1: + sys.exit(f":ERROR: Unable to obtain Extended Device BDF path for {bus_id} since too many Extended Device BDFs match: {devicePaths}") + return devicePaths[0] + +def get_singular_device_extended_bdf(bus_id: str) -> str: + deviceBDFs = get_device_extended_bdfs(bus_id) + if len(deviceBDFs) == 0: + sys.exit(f":ERROR: Unable to obtain Extended Device BDF for {bus_id}") + if len(deviceBDFs) != 1: + sys.exit(f":ERROR: Unable to obtain Extended Device BDF for {bus_id} since too many Extended Device BDFs match: {deviceBDFs}") + return deviceBDFs[0] + +# obtain bridge paths/bdfs + +def get_bridge_paths(bus_id: str) -> List[Path]: + return [e.resolve().absolute().parent for e in get_device_paths(bus_id)] + +def get_bridge_extended_bdfs(bus_id: str) -> List[str]: + return [e.name for e in get_bridge_paths(bus_id)] + +def get_singular_bridge_path(bus_id: str) -> Path: + bridgePaths = get_bridge_paths(bus_id) + if len(bridgePaths) == 0: + sys.exit(f":ERROR: Unable to obtain Extended Bridge BDF path for {bus_id}") + if len(bridgePaths) != 1: + sys.exit(f":ERROR: Unable to obtain Extended Bridge BDF path for {bus_id} since too many Extended Bridge BDFs match: {bridgePaths}") + return bridgePaths[0] + +def get_singular_bridge_extended_bdf(bus_id: str) -> str: + bridgeBDFs = get_bridge_extended_bdfs(bus_id) + if len(bridgeBDFs) == 0: + sys.exit(f":ERROR: Unable to obtain Extended Bridge BDF for {bus_id}") + if len(bridgeBDFs) != 1: + sys.exit(f":ERROR: Unable to obtain Extended Bridge BDF for {bus_id} since too many Extended Bridge BDFs match: {bridgeBDFs}") + return bridgeBDFs[0] + +# misc + +def get_fpga_devs(bus_id) -> List[Path]: + def readUevent(path: Path) -> Dict[str, str]: + if not (path / 'uevent').exists(): + return {} + return { entry[0]: entry[1] for entry in [line.strip('\n\r ').split('=') for line in open(f'{path}/uevent', 'r').readlines()] if len(entry) >= 2 } + + def xdmaResolver(path: Path) -> List[Path]: + xdmaDevs = [] + for f in ['resource', 'resource0', 'resource1']: + rsrcPath = (path / f) + if rsrcPath.exists(): + xdmaDevs.append(rsrcPath) + xdmaPath = (path / 'xdma') + if xdmaPath.is_dir(): + ueventEntries = [readUevent(xdmaPath / entry.name) for entry in xdmaPath.iterdir() if (xdmaPath / entry.name).is_dir()] + xdmaDevs.extend([Path('/dev') / uevent['DEVNAME'] for uevent in ueventEntries if 'DEVNAME' in uevent and (Path('/dev') / uevent['DEVNAME']).exists()]) + return xdmaDevs + + resolvers = { + 'xdma' : xdmaResolver + } + + returnDevs = [] + fpgaDevices = get_device_extended_bdfs(bus_id) + for fpgaDev in fpgaDevices: + path = pciDevicesPath / fpgaDev + fpgaDevUevent = readUevent(path) + if 'DRIVER' not in fpgaDevUevent: + print(":WARNING: Verify that 'xdma' driver is loaded") + continue + if fpgaDevUevent['DRIVER'] not in resolvers: + continue + returnDevs.extend(resolvers[fpgaDevUevent['DRIVER']](path.resolve())) + + return returnDevs + +# clear SERR bit in command register +# https://support.xilinx.com/s/question/0D52E00006hpjPHSAY/dell-r720-poweredge-server-reboots-on-fpga-reprogramming?language=en_US +def clear_serr_bits(bus_id: str) -> None: + for bridgeBDF in get_bridge_extended_bdfs(bus_id): + run = subprocess.run(['setpci', '-s', bridgeBDF, 'COMMAND=0000:0100']) + if run.returncode != 0: + sys.exit(f":ERROR: Unable to clear SERR bit for {bridgeBDF}") + time.sleep(1) + +# clear fatal error reporting enable bit in the device control register +# https://support.xilinx.com/s/question/0D52E00006hpjPHSAY/dell-r720-poweredge-server-reboots-on-fpga-reprogramming?language=en_US +def clear_fatal_error_reporting_bits(bus_id: str) -> None: + for bridgeBDF in get_bridge_extended_bdfs(bus_id): + run = subprocess.run(['setpci', '-s', bridgeBDF, 'CAP_EXP+8.w=0000:0004']) + if run.returncode != 0: + sys.exit(f":ERROR: Unable to clear error reporting bit for {bridgeBDF}") + time.sleep(1) + +def write_to_linux_device_path(path: Path, data: str = '1\n') -> None: + try: + print(f":INFO: Writing to {path}: {data.strip()}") + open(path, 'w').write(data) + except: + sys.exit(f":ERROR: Cannot write to {path} value: {data}") + time.sleep(1) + +def remove(bus_id: str) -> None: + for devicePaths in get_device_paths(bus_id): + removePath = devicePaths.resolve().absolute() / 'remove' + if removePath.exists(): + write_to_linux_device_path(removePath) + +def rescan(bus_id: str) -> None: + for bridgePath in get_bridge_paths(bus_id): + rescanPath = bridgePath / 'rescan' + if rescanPath.exists(): + write_to_linux_device_path(rescanPath) + write_to_linux_device_path(Path('/sys/bus/pci/rescan')) + +# enable memory mapped transfers for the fpga +# https://support.xilinx.com/s/question/0D52E00006iHlNoSAK/lspci-reports-bar-0-disabled?language=en_US +def enable_memmapped_transfers(bus_id: str) -> None: + for deviceBDF in get_device_extended_bdfs(bus_id): + run = subprocess.run(['setpci', '-s', deviceBDF, 'COMMAND=0x02']) + if run.returncode != 0: + sys.exit(f":ERROR: Unable to enable memmapped transfers on {deviceBDF}") + time.sleep(1) + +def any_device_exists(bus_id: str) -> bool: + return len(get_device_paths(bus_id)) > 0 + +# converter funcs + +def get_extended_bdf_from_bdf(bdf: str) -> str: + return '0000:' + bdf + +def get_bus_id_from_extended_bdf(extended_bdf: str) -> str: + return extended_bdf[5:7] + +def get_bdf_from_extended_bdf(extended_bdf: str) -> str: + return extended_bdf[5:] diff --git a/platforms/xilinx_vc707/scripts/program_fpga.tcl b/platforms/xilinx_vc707/scripts/program_fpga.tcl new file mode 100644 index 0000000000..53b7a95f7a --- /dev/null +++ b/platforms/xilinx_vc707/scripts/program_fpga.tcl @@ -0,0 +1,69 @@ +# Adapted from https://github.com/Xilinx/open-nic-shell + +# Directory variables +set script_path [file normalize [info script]] +set script_dir [file dirname $script_path] +set root_dir [file dirname $script_dir] + +# Loading options +# bitstream_path Path to the bitstream +# serial Serial number of FPGA board (without trailing A) +array set options { + -bitstream_path "" + -probes_path "" + -serial "" +} + +# Expect arguments in the form of `-argument value` +for {set i 0} {$i < $argc} {incr i 2} { + set arg [lindex $argv $i] + set val [lindex $argv [expr $i+1]] + if {[info exists options($arg)]} { + set options($arg) $val + puts "Set option $arg to $val" + } else { + puts "Skip unknown argument $arg and its value $val" + } +} + +# Settings based on defaults or passed in values +foreach {key value} [array get options] { + set [string range $key 1 end] $value +} + +puts "Program file: $options(-bitstream_path)" +puts "Probes file: $options(-probes_path)" +puts "Serial Number: $options(-serial)" + +set_param labtools.enable_cs_server false + +open_hw_manager +connect_hw_server -allow_non_jtag + +# by default vivado opens a default hw target +close_hw_target + +# check if serial is in hw targets +set final_hw_target "" +foreach {hw_target} [get_hw_targets] { + if {[string first $serial $hw_target] != -1} { + set final_hw_target $hw_target + } +} + +if {$final_hw_target == ""} { + puts "Unable to find $serial in available HW targets. See available HW targets below:" + get_hw_targets + exit 1 +} + +puts "Programming $final_hw_target with ${options(-bitstream_path)}" +open_hw_target $final_hw_target +set_property PROBES.FILE ${options(-probes_path)} [get_hw_device] +set_property FULL_PROBES.FILE ${options(-probes_path)} [get_hw_device] +set_property PROGRAM.FILE ${options(-bitstream_path)} [get_hw_device] +program_hw_devices [get_hw_device] +refresh_hw_device [get_hw_device] +close_hw_target + +exit diff --git a/platforms/xilinx_vc707/scripts/util.py b/platforms/xilinx_vc707/scripts/util.py new file mode 100644 index 0000000000..190eedfcd0 --- /dev/null +++ b/platforms/xilinx_vc707/scripts/util.py @@ -0,0 +1,22 @@ +from pathlib import Path +import subprocess + +from typing import List, Tuple + +def call_vivado(vivado: Path, args: List[str]) -> Tuple[int, str, str]: + pVivado = subprocess.Popen( + [ + str(vivado), + '-mode', 'tcl', + ] + args, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + + sout, serr = pVivado.communicate() + + eSout = sout.decode('utf-8') if sout is not None else "" + eSerr = serr.decode('utf-8') if serr is not None else "" + + return (pVivado.returncode, eSout, eSerr) diff --git a/sim/make/driver.mk b/sim/make/driver.mk index b625f16d07..5ed0d6e313 100644 --- a/sim/make/driver.mk +++ b/sim/make/driver.mk @@ -54,6 +54,7 @@ $(eval $(call built_within_conda_only_driver_compilation_rules,xilinx_alveo_u280 $(eval $(call built_within_conda_only_driver_compilation_rules,xilinx_alveo_u200)) $(eval $(call built_within_conda_only_driver_compilation_rules,xilinx_vcu118)) $(eval $(call built_within_conda_only_driver_compilation_rules,rhsresearch_nitefury_ii)) +$(eval $(call built_within_conda_only_driver_compilation_rules,xilinx_vc707)) # these compilation flags are only guaranteed to work for ubuntu 20.04/18.04 (other OS's are not supported since vitis is experimental) $(vitis): export CXXFLAGS := $(CXXFLAGS) $(common_cxx_flags) $(DRIVER_CXXOPTS) \ diff --git a/sim/make/fpga.mk b/sim/make/fpga.mk index fbcf732982..2c6503c719 100644 --- a/sim/make/fpga.mk +++ b/sim/make/fpga.mk @@ -6,6 +6,15 @@ platforms_dir := $(abspath $(firesim_base_dir)/../platforms) +$(info firesim_base_dir is: $(firesim_base_dir)) +$(info platforms_dir is: $(platforms_dir)) +$(info PLATFORM is: $(PLATFORM)) + +.PHONY: xy_test +xy_test: + $(info hello guy!) + + ifeq ($(PLATFORM), vitis) board_dir := $(platforms_dir)/vitis else ifeq ($(PLATFORM), xilinx_alveo_u250) @@ -20,6 +29,8 @@ else ifeq ($(PLATFORM), rhsresearch_nitefury_ii) board_dir := $(platforms_dir)/rhsresearch_nitefury_ii/NiteFury-and-LiteFury-firesim/Sample-Projects/Project-0 else ifeq ($(PLATFORM), f1) board_dir := $(platforms_dir)/f1/aws-fpga/hdk/cl/developer_designs +else ifeq ($(PLATFORM), vc707) +board_dir := $(platforms_dir)/xilinx_vc707 else $(error Invalid PLATFORM used: $(PLATFORM)) endif diff --git a/sim/midas/src/main/cc/simif_xilinx_vc707.cc b/sim/midas/src/main/cc/simif_xilinx_vc707.cc new file mode 100644 index 0000000000..86e914c037 --- /dev/null +++ b/sim/midas/src/main/cc/simif_xilinx_vc707.cc @@ -0,0 +1,335 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bridges/cpu_managed_stream.h" +#include "core/simif.h" + +#define PCI_DEV_FMT "%04x:%02x:%02x.%d" + +class simif_xilinx_alveo_u250_t final : public simif_t, + public CPUManagedStreamIO { +public: + simif_xilinx_alveo_u250_t(const TargetConfig &config, + const std::vector &args); + ~simif_xilinx_alveo_u250_t(); + + void write(size_t addr, uint32_t data) override; + uint32_t read(size_t addr) override; + + uint32_t is_write_ready(); + void check_rc(int rc, char *infostr); + void fpga_shutdown(); + void fpga_setup(uint16_t domain_id, + uint8_t bus_id, + uint8_t device_id, + uint8_t pf_id, + uint8_t bar_id, + uint16_t pci_vendor_id, + uint16_t pci_device_id); + + CPUManagedStreamIO &get_cpu_managed_stream_io() override { return *this; } + +private: + uint32_t mmio_read(size_t addr) override { return read(addr); } + size_t + cpu_managed_axi4_write(size_t addr, const char *data, size_t size) override; + size_t cpu_managed_axi4_read(size_t addr, char *data, size_t size) override; + uint64_t get_beat_bytes() const override { + return config.cpu_managed->beat_bytes(); + } + + void *fpga_pci_bar_get_mem_at_offset(uint64_t offset); + int fpga_pci_poke(uint64_t offset, uint32_t value); + int fpga_pci_peek(uint64_t offset, uint32_t *value); + + int edma_write_fd; + int edma_read_fd; + void *bar0_base; + uint32_t bar0_size = 0x2000000; // 32 MB (TODO: Make configurable?) +}; + +static int fpga_pci_check_file_id(char *path, uint16_t id) { + if (path) { + fprintf(stdout, "Opening %s\n", path); + } else { + assert(path); + } + int ret = 0; + FILE *fp = fopen(path, "r"); + assert(fp); + uint32_t tmp_id; + ret = fscanf(fp, "%x", &tmp_id); + assert(ret >= 0); + assert(tmp_id == id); + fclose(fp); + return 0; +} + +simif_xilinx_alveo_u250_t::simif_xilinx_alveo_u250_t( + const TargetConfig &config, const std::vector &args) + : simif_t(config) { + + std::optional domain_id; + std::optional bus_id; + std::optional device_id; + std::optional pf_id; + std::optional bar_id; + std::optional pci_vendor_id; + std::optional pci_device_id; + + for (auto &arg : args) { + if (arg.find("+domain=") == 0) { + printf("+domain found: %s\n", arg.c_str() + 8); + domain_id = strtoul(arg.c_str() + 8, NULL, 16); + continue; + } + if (arg.find("+bus=") == 0) { + printf("+bus found: %s\n", arg.c_str() + 5); + bus_id = strtoul(arg.c_str() + 5, NULL, 16); + continue; + } + if (arg.find("+device=") == 0) { + printf("+device found: %s\n", arg.c_str() + 8); + device_id = strtoul(arg.c_str() + 8, NULL, 16); + continue; + } + if (arg.find("+function=") == 0) { + printf("+function found: %s\n", arg.c_str() + 10); + pf_id = strtoul(arg.c_str() + 10, NULL, 16); + continue; + } + if (arg.find("+bar=") == 0) { + printf("+bar found: %s\n", arg.c_str() + 5); + bar_id = strtoul(arg.c_str() + 5, NULL, 16); + continue; + } + if (arg.find("+pci-vendor=") == 0) { + pci_vendor_id = strtoul(arg.c_str() + 12, NULL, 16); + continue; + } + if (arg.find("+pci-device=") == 0) { + pci_device_id = strtoul(arg.c_str() + 12, NULL, 16); + continue; + } + } + + if (!domain_id) { + fprintf(stderr, "Domain ID not specified. Assuming Domain ID 0\n"); + domain_id = 0; + } + if (!bus_id) { + fprintf(stderr, "Bus ID not specified. Assuming Bus ID 0\n"); + bus_id = 0; + } + if (!device_id) { + fprintf(stderr, "Device ID not specified. Assuming Device ID 0\n"); + device_id = 0; + } + if (!pf_id) { + fprintf(stderr, "Function ID not specified. Assuming Function ID 0\n"); + pf_id = 0; + } + if (!bar_id) { + fprintf(stderr, "BAR ID not specified. Assuming BAR ID 0\n"); + bar_id = 0; + } + if (!pci_vendor_id) { + fprintf(stderr, + "PCI Vendor ID not specified. Assuming PCI Vendor ID 0x10ee\n"); + pci_vendor_id = 0x10ee; + } + if (!pci_device_id) { + fprintf(stderr, + "PCI Device ID not specified. Assuming PCI Device ID 0x903f\n"); + pci_device_id = 0x903f; + } + + printf("Using: " PCI_DEV_FMT + ", BAR ID: %u, PCI Vendor ID: 0x%04x, PCI Device ID: 0x%04x\n", + *domain_id, + *bus_id, + *device_id, + *pf_id, + *bar_id, + *pci_vendor_id, + *pci_device_id); + + fpga_setup(*domain_id, + *bus_id, + *device_id, + *pf_id, + *bar_id, + *pci_vendor_id, + *pci_device_id); +} + +void * +simif_xilinx_alveo_u250_t::fpga_pci_bar_get_mem_at_offset(uint64_t offset) { + assert(!(((uint64_t)(offset + 4)) > bar0_size)); + return (uint8_t *)bar0_base + offset; +} + +int simif_xilinx_alveo_u250_t::fpga_pci_poke(uint64_t offset, uint32_t value) { + uint32_t *reg_ptr = (uint32_t *)fpga_pci_bar_get_mem_at_offset(offset); + *reg_ptr = value; + return 0; +} + +int simif_xilinx_alveo_u250_t::fpga_pci_peek(uint64_t offset, uint32_t *value) { + uint32_t *reg_ptr = (uint32_t *)fpga_pci_bar_get_mem_at_offset(offset); + *value = *reg_ptr; + return 0; +} + +void simif_xilinx_alveo_u250_t::check_rc(int rc, char *infostr) { + if (rc) { + if (infostr) { + fprintf(stderr, "%s\n", infostr); + } + fprintf(stderr, "INVALID RETCODE: %d\n", rc); + fpga_shutdown(); + exit(1); + } +} + +void simif_xilinx_alveo_u250_t::fpga_shutdown() { + if (bar0_base) { + int ret = munmap(bar0_base, bar0_size); + assert(ret == 0); + } + close(edma_write_fd); + close(edma_read_fd); +} + +void simif_xilinx_alveo_u250_t::fpga_setup(uint16_t domain_id, + uint8_t bus_id, + uint8_t device_id, + uint8_t pf_id, + uint8_t bar_id, + uint16_t pci_vendor_id, + uint16_t pci_device_id) { + + int fd = -1; + char sysfs_name[256]; + int ret; + + // check vendor id + ret = snprintf(sysfs_name, + sizeof(sysfs_name), + "/sys/bus/pci/devices/" PCI_DEV_FMT "/vendor", + domain_id, + bus_id, + device_id, + pf_id); + assert(ret >= 0); + fpga_pci_check_file_id(sysfs_name, pci_vendor_id); + + // check device id + ret = snprintf(sysfs_name, + sizeof(sysfs_name), + "/sys/bus/pci/devices/" PCI_DEV_FMT "/device", + domain_id, + bus_id, + device_id, + pf_id); + assert(ret >= 0); + fpga_pci_check_file_id(sysfs_name, pci_device_id); + + // XDMA setup + char device_file_name[256]; + char device_file_name2[256]; + char user_file_name[256]; + + ret = snprintf(sysfs_name, + sizeof(sysfs_name), + "/sys/bus/pci/devices/" PCI_DEV_FMT "/xdma", + domain_id, + bus_id, + device_id, + pf_id); + assert(ret >= 0); + DIR *d; + struct dirent *dir; + int xdma_id = -1; + + d = opendir(sysfs_name); + if (d) { + while ((dir = readdir(d)) != NULL) { + printf("examining xdma/%s\n", dir->d_name); + if (strstr(dir->d_name, "xdma") && strstr(dir->d_name, "_h2c_0")) { + xdma_id = strtol(dir->d_name + 4, NULL, 10); + break; + } + } + closedir(d); + } + + assert(xdma_id != -1); + + // open and memory map + sprintf(user_file_name, "/dev/xdma%d_user", xdma_id); + + fd = open(user_file_name, O_RDWR | O_SYNC); + assert(fd != -1); + + bar0_base = mmap(0, bar0_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + assert(bar0_base != MAP_FAILED); + close(fd); + fd = -1; + + sprintf(device_file_name, "/dev/xdma%d_h2c_0", xdma_id); + printf("Using xdma write queue: %s\n", device_file_name); + sprintf(device_file_name2, "/dev/xdma%d_c2h_0", xdma_id); + printf("Using xdma read queue: %s\n", device_file_name2); + + edma_write_fd = open(device_file_name, O_WRONLY); + edma_read_fd = open(device_file_name2, O_RDONLY); + assert(edma_write_fd >= 0); + assert(edma_read_fd >= 0); +} + +simif_xilinx_alveo_u250_t::~simif_xilinx_alveo_u250_t() { fpga_shutdown(); } + +void simif_xilinx_alveo_u250_t::write(size_t addr, uint32_t data) { + int rc = fpga_pci_poke(addr, data); + check_rc(rc, NULL); +} + +uint32_t simif_xilinx_alveo_u250_t::read(size_t addr) { + uint32_t value; + int rc = fpga_pci_peek(addr, &value); + return value & 0xFFFFFFFF; +} + +size_t simif_xilinx_alveo_u250_t::cpu_managed_axi4_read(size_t addr, + char *data, + size_t size) { + return ::pread(edma_read_fd, data, size, addr); +} + +size_t simif_xilinx_alveo_u250_t::cpu_managed_axi4_write(size_t addr, + const char *data, + size_t size) { + return ::pwrite(edma_write_fd, data, size, addr); +} + +uint32_t simif_xilinx_alveo_u250_t::is_write_ready() { + uint64_t addr = 0x4; + uint32_t value; + int rc = fpga_pci_peek(addr, &value); + check_rc(rc, NULL); + return value & 0xFFFFFFFF; +} + +std::unique_ptr +create_simif(const TargetConfig &config, int argc, char **argv) { + std::vector args(argv + 1, argv + argc); + return std::make_unique(config, args); +} diff --git a/sim/midas/src/main/scala/midas/Config.scala b/sim/midas/src/main/scala/midas/Config.scala index f0b97633ec..74bcba5fba 100644 --- a/sim/midas/src/main/scala/midas/Config.scala +++ b/sim/midas/src/main/scala/midas/Config.scala @@ -179,6 +179,26 @@ class XilinxVCU118Config extends Config(new Config((site, here, up) => { case PostLinkCircuitPath => Some("partition_wrapper/partition/firesim_top") }) ++ new SimConfig) +class XilinxVC707Config extends Config(new Config((site, here, up) => { + case Platform => (p: Parameters) => new F1Shim()(p) + case HasDMAChannel => true + case StreamEngineInstantiatorKey => (e: StreamEngineParameters, p: Parameters) => new CPUManagedStreamEngine(p, e) + case CPUManagedAXI4Key => Some(CPUManagedAXI4Params( + addrBits = 64, + dataBits = 512, + idBits = 4, + )) + case FPGAManagedAXI4Key => None + case CtrlNastiKey => NastiParameters(32, 25, 12) + case HostMemChannelKey => HostMemChannelParams( + size = 0x40000000L, // 1 GiB + beatBytes = 8, + idBits = 6) + case HostMemNumChannels => 2 + case PreLinkCircuitPath => Some("partition/firesim_top") + case PostLinkCircuitPath => Some("partition_wrapper/partition/firesim_top") +}) ++ new SimConfig) + class VitisConfig extends Config(new Config((site, here, up) => { case Platform => (p: Parameters) => new VitisShim()(p) case CPUManagedAXI4Key => None