diff options
author | Wade Fife <wade.fife@ettus.com> | 2021-03-04 16:27:24 -0600 |
---|---|---|
committer | Wade Fife <wade.fife@ettus.com> | 2021-03-17 17:46:06 -0500 |
commit | ada6a4e46770d22d528b2b6fbc2bdd71e5e3064d (patch) | |
tree | 21ba4229fb195da6fc1da4907ec00aed85a07c6c /host/examples/rfnoc-example | |
parent | 866df135adb91299d1009c1b1d2053dd3112acda (diff) | |
download | uhd-ada6a4e46770d22d528b2b6fbc2bdd71e5e3064d.tar.gz uhd-ada6a4e46770d22d528b2b6fbc2bdd71e5e3064d.tar.bz2 uhd-ada6a4e46770d22d528b2b6fbc2bdd71e5e3064d.zip |
examples: Add IP to OOT RFNoC gain example
This updates the gain example to show how to use RFNoC IP, in-tree
Xilinx IP, and out-of-tree Xilinx IP in a custom RFNoC block.
Diffstat (limited to 'host/examples/rfnoc-example')
5 files changed, 335 insertions, 39 deletions
diff --git a/host/examples/rfnoc-example/fpga/Makefile.srcs b/host/examples/rfnoc-example/fpga/Makefile.srcs index f95dab6ea..88a729c97 100644 --- a/host/examples/rfnoc-example/fpga/Makefile.srcs +++ b/host/examples/rfnoc-example/fpga/Makefile.srcs @@ -6,16 +6,18 @@ # We first need to figure out our own path, in case this file is being included # from somewhere else (e.g., from a fpgadev/top/$device directory) -RFNOC_EXAMPLE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +OOT_FPGA_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) # One include statement for every RFNoC block with its own subdirectory, which # itself will contain a Makefile.srcs -include $(RFNOC_EXAMPLE_DIR)/rfnoc_block_gain/Makefile.srcs +include $(OOT_FPGA_DIR)/rfnoc_block_gain/Makefile.srcs + +include $(OOT_FPGA_DIR)/ip/cmplx_mul/Makefile.inc +LIB_IP_XCI_SRCS += $(LIB_IP_CMPLX_MUL_SRCS) # If there are additional modules or IP (other than what is in the RFNoC block # subdirectories) that needs to get installed in order to synthesize blocks from # this module, list them here: -#RFNOC_OOT_SRCS += $(abspath $(addprefix ${RFNOC_EXAMPLE_DIR}, -#my_other_module.v \ -#ip/my_ip_core/my_ip_core.xci \ +#RFNOC_OOT_SRCS += $(abspath $(addprefix ${OOT_FPGA_DIR}, \ +#$(IP_BUILD_DIR)/cmplx_mul/cmplx_mul.xci \ #)) diff --git a/host/examples/rfnoc-example/fpga/ip/cmplx_mul/Makefile.inc b/host/examples/rfnoc-example/fpga/ip/cmplx_mul/Makefile.inc new file mode 100644 index 000000000..14d456146 --- /dev/null +++ b/host/examples/rfnoc-example/fpga/ip/cmplx_mul/Makefile.inc @@ -0,0 +1,17 @@ +# +# Copyright 2021 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# + +include $(TOOLS_DIR)/make/viv_ip_builder.mak + +LIB_IP_CMPLX_MUL_SRCS = $(IP_BUILD_DIR)/cmplx_mul/cmplx_mul.xci + +LIB_IP_CMPLX_MUL_OUTS = $(addprefix $(IP_BUILD_DIR)/cmplx_mul/, \ +cmplx_mul.xci.out \ +synth/cmplx_mul.vhd \ +) + +$(LIB_IP_CMPLX_MUL_SRCS) $(LIB_IP_CMPLX_MUL_OUTS) : $(OOT_FPGA_DIR)/ip/cmplx_mul/cmplx_mul.xci + $(call BUILD_VIVADO_IP,cmplx_mul,$(ARCH),$(PART_ID),$(OOT_FPGA_DIR)/ip,$(IP_BUILD_DIR),0) diff --git a/host/examples/rfnoc-example/fpga/ip/cmplx_mul/cmplx_mul.xci b/host/examples/rfnoc-example/fpga/ip/cmplx_mul/cmplx_mul.xci new file mode 100644 index 000000000..9ba4231db --- /dev/null +++ b/host/examples/rfnoc-example/fpga/ip/cmplx_mul/cmplx_mul.xci @@ -0,0 +1,187 @@ +<?xml version="1.0" encoding="UTF-8"?> +<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <spirit:vendor>xilinx.com</spirit:vendor> + <spirit:library>xci</spirit:library> + <spirit:name>unknown</spirit:name> + <spirit:version>1.0</spirit:version> + <spirit:componentInstances> + <spirit:componentInstance> + <spirit:instanceName>cmplx_mul</spirit:instanceName> + <spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="cmpy" spirit:version="6.0"/> + <spirit:configurableElementValues> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ACLKEN_INTF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ACLK_INTF.CLK_DOMAIN"/> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ACLK_INTF.FREQ_HZ">10000000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ACLK_INTF.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ACLK_INTF.PHASE">0.000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.ARESETN_INTF.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.CLK_DOMAIN"/> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.FREQ_HZ">100000000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TKEEP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TLAST">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TREADY">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TSTRB">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.LAYERED_METADATA">undef</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.PHASE">0.000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TDATA_NUM_BYTES">10</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TDEST_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TID_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TUSER_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.CLK_DOMAIN"/> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.FREQ_HZ">100000000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TKEEP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TLAST">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TREADY">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TSTRB">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.LAYERED_METADATA">undef</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.PHASE">0.000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TDATA_NUM_BYTES">4</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TDEST_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TID_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TUSER_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.CLK_DOMAIN"/> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.FREQ_HZ">100000000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TKEEP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TLAST">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TREADY">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TSTRB">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.LAYERED_METADATA">undef</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.PHASE">0.000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TDATA_NUM_BYTES">4</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TDEST_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TID_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TUSER_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.CLK_DOMAIN"/> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.FREQ_HZ">100000000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TKEEP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TLAST">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TREADY">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TSTRB">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.INSERT_VIP">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.LAYERED_METADATA">undef</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.PHASE">0.000</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TDATA_NUM_BYTES">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TDEST_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TID_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TUSER_WIDTH">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_A_WIDTH">16</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_B_WIDTH">16</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ACLKEN">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_ARESETN">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_A_TLAST">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_A_TUSER">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_B_TLAST">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_B_TUSER">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_CTRL_TLAST">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_HAS_S_AXIS_CTRL_TUSER">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_LATENCY">7</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_MULT_TYPE">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_AXIS_DOUT_TDATA_WIDTH">80</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_M_AXIS_DOUT_TUSER_WIDTH">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OPTIMIZE_GOAL">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_OUT_WIDTH">33</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_A_TDATA_WIDTH">32</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_A_TUSER_WIDTH">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_B_TDATA_WIDTH">32</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_B_TUSER_WIDTH">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_CTRL_TDATA_WIDTH">8</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_S_AXIS_CTRL_TUSER_WIDTH">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_THROTTLE_SCHEME">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_TLAST_RESOLUTION">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_VERBOSITY">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_XDEVICE">xc7k410t</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_XDEVICEFAMILY">kintex7</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.HAS_NEGATE">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.ROUND">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.SINGLE_OUTPUT">0</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.USE_DSP_CASCADES">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ACLKEN">false</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.APortWidth">16</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ARESETN">true</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ATUSERWidth">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.BPortWidth">16</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.BTUSERWidth">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.CTRLTUSERWidth">1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">testerific</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FlowControl">Blocking</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasATLAST">true</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasATUSER">false</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasBTLAST">true</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasBTUSER">false</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasCTRLTLAST">false</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HasCTRLTUSER">false</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.LatencyConfig">Automatic</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.MinimumLatency">7</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.MultType">Use_Mults</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.OptimizeGoal">Performance</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.OutTLASTBehv">Pass_A_TLAST</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.OutputWidth">33</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.RoundMode">Truncate</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">kintex7</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BASE_BOARD_PART"/> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD_CONNECTIONS"/> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xc7k410t</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">fbg900</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VERILOG</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-1</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.STATIC_POWER"/> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE"/> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPCONTEXT">IP_Flow</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">17</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SELECTEDSIMMODEL"/> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SHAREDDIR">.</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2019.1.1_AR73068</spirit:configurableElementValue> + <spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">OUT_OF_CONTEXT</spirit:configurableElementValue> + </spirit:configurableElementValues> + <spirit:vendorExtensions> + <xilinx:componentInstanceExtensions> + <xilinx:configElementInfos> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TKEEP" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TLAST" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TREADY" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.HAS_TSTRB" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TDATA_NUM_BYTES" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TDEST_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS_DOUT.TID_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TKEEP" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TLAST" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TREADY" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.HAS_TSTRB" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TDATA_NUM_BYTES" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TDEST_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_A.TID_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TKEEP" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TLAST" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TREADY" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.HAS_TSTRB" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TDATA_NUM_BYTES" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TDEST_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_B.TID_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TKEEP" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TREADY" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.HAS_TSTRB" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TDATA_NUM_BYTES" xilinx:valueSource="auto"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TDEST_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS_CTRL.TID_WIDTH" xilinx:valueSource="constant"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.ARESETN" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.FlowControl" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HasATLAST" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HasBTLAST" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.MinimumLatency" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.OptimizeGoal" xilinx:valueSource="user"/> + <xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.OutTLASTBehv" xilinx:valueSource="user"/> + </xilinx:configElementInfos> + </xilinx:componentInstanceExtensions> + </spirit:vendorExtensions> + </spirit:componentInstance> + </spirit:componentInstances> +</spirit:design> diff --git a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/Makefile b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/Makefile index 1ff3046ee..0239041b9 100644 --- a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/Makefile +++ b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/Makefile @@ -19,24 +19,40 @@ include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak #------------------------------------------------- # Design Specific #------------------------------------------------- + +# In-tree IP +LIB_IP_DIR = $(BASE_DIR)/../lib/ip +include $(LIB_IP_DIR)/complex_multiplier/Makefile.inc + +# Out-of-tree IP +OOT_FPGA_DIR = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/../ +include $(OOT_FPGA_DIR)/ip/cmplx_mul/Makefile.inc + # Include makefiles and sources for the DUT and its # dependencies. +include $(BASE_DIR)/../lib/rfnoc/Makefile.srcs include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs include Makefile.srcs -DESIGN_SRCS += $(abspath \ -$(RFNOC_CORE_SRCS) \ -$(RFNOC_UTIL_SRCS) \ -$(RFNOC_OOT_SRCS) \ +DESIGN_SRCS += $(abspath \ +$(RFNOC_SRCS) \ +$(RFNOC_CORE_SRCS) \ +$(RFNOC_UTIL_SRCS) \ +$(RFNOC_OOT_SRCS) \ +$(LIB_IP_CMPLX_MUL_SRCS) \ +$(LIB_IP_COMPLEX_MULTIPLIER_SRCS) \ ) #------------------------------------------------- # Testbench Specific #------------------------------------------------- -SIM_TOP = rfnoc_block_gain_tb +SIM_TOP = rfnoc_block_gain_tb glbl SIM_SRCS = \ +$(abspath $(IP_BUILD_DIR)/cmplx_mul/sim/cmplx_mul.vhd) \ +$(abspath $(IP_BUILD_DIR)/complex_multiplier/sim/complex_multiplier.vhd) \ $(abspath rfnoc_block_gain_tb.sv) \ +$(VIVADO_PATH)/data/verilog/src/glbl.v \ #------------------------------------------------- # Bottom-of-Makefile diff --git a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v index 929439a52..6f050e8bc 100644 --- a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v +++ b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v @@ -17,6 +17,11 @@ // CHDR_W : AXIS-CHDR data bus width // MTU : Maximum transmission unit (i.e., maximum packet size in // CHDR words is 2**MTU). +// IP_OPTION : Select which IP to use for the complex multiply. Use one of +// the following options: +// HDL_IP = In-tree RFNoC HDL, with a DSP48E1 primitive +// IN_TREE_IP = In-tree "complex_multiplier" (Xilinx IP) +// OUT_OF_TREE_IP = Out-of-tree "cmplx_mul" (Xilinx IP) // `default_nettype none @@ -25,7 +30,8 @@ module rfnoc_block_gain #( parameter [9:0] THIS_PORTID = 10'd0, parameter CHDR_W = 64, - parameter [5:0] MTU = 10 + parameter [5:0] MTU = 10, + parameter IP_OPTION = "HDL_IP" )( // RFNoC Framework Clocks and Resets input wire rfnoc_chdr_clk, @@ -250,36 +256,104 @@ module rfnoc_block_gain #( wire mult_tvalid; wire mult_tready; - // Multiply complex sample by a real-valued gain. Only input the gain - // (real_tvalid) when we have payload data to go in (cplx_tdata). That way - // the current gain value always applies to the current sample. This assumes - // that real_tready and cplx_tready have identical behavior. + // Multiply each complex sample by a real-valued gain. Only input the gain + // when we have payload data to go in (m_in_payload_tdata). That way the + // current gain value always applies to the current sample. This assumes that + // the tready of both inputs have identical behavior. // // Note that we receive the data with I on bits [31:16] and Q on bits [15:0], - // but this does not matter to our multiplier. - // - mult_rc #( - .WIDTH_REAL (16), - .WIDTH_CPLX (16), - .WIDTH_P (32), - .DROP_TOP_P (5), // Must be 5 for a normal multiply in DSP48E1 - .LATENCY (4) // Turn on all pipeline registers in the DSP48E1 - ) mult_rc_i ( - .clk (axis_data_clk), - .reset (axis_data_rst), - .real_tdata (reg_gain), - .real_tlast (m_in_payload_tlast), - .real_tvalid (m_in_payload_tvalid), - .real_tready (), - .cplx_tdata (m_in_payload_tdata), - .cplx_tlast (m_in_payload_tlast), - .cplx_tvalid (m_in_payload_tvalid), - .cplx_tready (m_in_payload_tready), - .p_tdata (mult_tdata), - .p_tlast (mult_tlast), - .p_tvalid (mult_tvalid), - .p_tready (mult_tready) - ); + // but the I/Q order does not matter to our complex multiplier. + + generate + // Use a generate statement to choose which IP to use for the multiply. + // These all do the same thing and we only have multiple options to show + // how you can use IP from different locations. + + if (IP_OPTION == "HDL_IP") begin : gen_rfnoc_ip + // Use the RFNoC mult_rc Verilog module, which uses a DSP48E1 primitive + mult_rc #( + .WIDTH_REAL (16), + .WIDTH_CPLX (16), + .WIDTH_P (32), + .DROP_TOP_P (5), // Must be 5 for a normal multiply in DSP48E1 + .LATENCY (4) // Turn on all pipeline registers in the DSP48E1 + ) mult_rc_i ( + .clk (axis_data_clk), + .reset (axis_data_rst), + .real_tdata (reg_gain), + .real_tlast (m_in_payload_tlast), + .real_tvalid (m_in_payload_tvalid), + .real_tready (), + .cplx_tdata (m_in_payload_tdata), + .cplx_tlast (m_in_payload_tlast), + .cplx_tvalid (m_in_payload_tvalid), + .cplx_tready (m_in_payload_tready), + .p_tdata (mult_tdata), + .p_tlast (mult_tlast), + .p_tvalid (mult_tvalid), + .p_tready (mult_tready) + ); + + end else if (IP_OPTION == "IN_TREE_IP") begin : gen_in_tree_ip + // Use the in-tree "complex_multiplier" IP, which is a Xilinx Complex + // Multiplier LogiCORE IP located in the UHD repository in + // fpga/usrp3/lib/ip/. + + // The LSB of the output is clipped in this IP, so double the gain to + // compensate. This limits the maximum gain in this version. + wire [15:0] gain = 2*reg_gain; + + complex_multiplier complex_multiplier ( + .aclk (axis_data_clk), + .aresetn (~axis_data_rst), + .s_axis_a_tdata ({16'b0, gain}), + .s_axis_a_tlast (m_in_payload_tlast), + .s_axis_a_tvalid (m_in_payload_tvalid), + .s_axis_a_tready (), + .s_axis_b_tdata (m_in_payload_tdata), + .s_axis_b_tlast (m_in_payload_tlast), + .s_axis_b_tvalid (m_in_payload_tvalid), + .s_axis_b_tready (m_in_payload_tready), + .s_axis_ctrl_tdata (8'd0), + .s_axis_ctrl_tvalid (1'b1), + .s_axis_ctrl_tready (), + .m_axis_dout_tdata (mult_tdata), + .m_axis_dout_tlast (mult_tlast), + .m_axis_dout_tvalid (mult_tvalid), + .m_axis_dout_tready (mult_tready) + ); + + end else if (IP_OPTION == "OUT_OF_TREE_IP") begin : gen_oot_ip + // Use the out-of-tree "cmplx_mul" IP, which is a Xilinx Complex + // Multiplier LogiCORE IP located in the IP directory of this example. + + // This IP has a 33-bit output, but because it's AXI-Stream, each + // component is placed in a 5-byte word. Since our gain is real only, + // we'll never need all 33-bits. + wire [79:0] m_axis_dout_tdata; + + cmplx_mul cmplx_mul_i ( + .aclk (axis_data_clk), + .aresetn (~axis_data_rst), + .s_axis_a_tdata ({16'd0, reg_gain}), + .s_axis_a_tlast (m_in_payload_tlast), + .s_axis_a_tvalid (m_in_payload_tvalid), + .s_axis_a_tready (), + .s_axis_b_tdata (m_in_payload_tdata), + .s_axis_b_tlast (m_in_payload_tlast), + .s_axis_b_tvalid (m_in_payload_tvalid), + .s_axis_b_tready (m_in_payload_tready), + .m_axis_dout_tdata (m_axis_dout_tdata), + .m_axis_dout_tlast (mult_tlast), + .m_axis_dout_tvalid (mult_tvalid), + .m_axis_dout_tready (mult_tready) + ); + + assign mult_tdata[31: 0] = m_axis_dout_tdata[31: 0]; + assign mult_tdata[63:32] = m_axis_dout_tdata[71:40]; + + end + endgenerate // Clip the results axi_clip_complex #( |