This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
resources:fpga:docs:hdl:xcomm2ip [04 Aug 2016 21:21] – rejeesh kutty | resources:fpga:docs:hdl:xcomm2ip [20 Aug 2016 05:21] (current) – rejeesh kutty | ||
---|---|---|---|
Line 1: | Line 1: | ||
===== A simple BBP for RF Transceivers ===== | ===== A simple BBP for RF Transceivers ===== | ||
- | This wiki page is a follow up documentation | + | This wiki page is a follow up documentation |
- | Please note that Analog Devices does NOT support this design. It is only meant to illustrate a work flow using the ADI github repositories, | + | Please note that Analog Devices does NOT support this design. It is unlikely that we maintain this core or design as we would the reference design. The recommended procedure for a BBP design is to model it in Simulink and subsequently implement the design using HDL coder. The core of the axi_xcomm2ip is intentionally obfuscated to discourage any use or modification of the IP. However, the radio communication demonstration detailed here may be used as a frame work and implementation flow for such designs. It is also meant to illustrate a work flow using the ADI github repositories, |
- | In addition to the BBP design, | + | This document and the design, |
- | ==== Download Source | + | This guide has two sections, the first section covers the hardware demonstration, |
+ | |||
+ | ===== Setup and Running the demo ===== | ||
+ | |||
+ | The demo is a simple chat (as in transmitting and receiving text messages) program between two ZC706 + AD-FMCOMMS3-EBZ platforms. You may place the two boards adjacent to each other within your lab desk space. Please do NOT try to use it with your significant other(s) across the seven seas. The best learning or experimentation setup requires two hardware platforms. This allows one to understand the importance and need for carrier tracking. It is possible for you to run the demo on a single platform in loopback mode. The default setup assumes two independent hardware platforms. So the single platform loopback mode requires some additional LO changes. | ||
+ | |||
+ | ===== Download run-time | ||
<WRAP round download 100%> | <WRAP round download 100%> | ||
{{: | {{: | ||
- | |||
- | {{: | ||
</ | </ | ||
- | ==== Setup the workspace | + | ===== Setup (host Linux desktop) ===== |
- | The ADI reference design repositories | + | The setup assumes that you are familiar with the AD-FMCOMMS3-EBZ user guide and used it to capture some signals or at least done a sanity level testing. You also have the image with the boot and file system partitions in the SD card. |
+ | To begin with, download the RFBBP demo run-time files and extract the contents. | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~]> mkdir rfbbp | ||
+ | [~]> cd rfbbp | ||
+ | |||
+ | [~/ | ||
+ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | Now mount your SD card. You should see two mount points; BOOT and rootfs. The software routines run in user space and we need a directory to keep them. This way, you can blow it away when you don't need it. You may have to be a little mindful of the file permissions as the board user is " | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | Simply copy the the Linux user space files to the " | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | Now unmount the SD card 1, and mount SD card 2 and repeat the same process. After that, unmount SD card 2. If you haven' | ||
+ | |||
+ | ===== Setup SYSTEM-1 (board Linux desktop) ===== | ||
+ | |||
+ | In the desktop, open a terminal and login as root. If the OSC application is already open and running, close it. Then run the shell script with the " | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | System ID [1|2]> 1 | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | <WRAP round note 100%> | ||
+ | If you are running this demo in a single system with loopback, set the receive and transmit LO frequencies to be the same. | ||
+ | </ | ||
+ | |||
+ | ===== Setup SYSTEM-2 (board Linux desktop) ===== | ||
+ | |||
+ | As you may have now guessed, the setup is same as SYSTEM-1 except that you set the ID to 2. This sets the receive LO frequency of SYSTEM-2 same as the transmit LO frequency of SYSTEM-1 and vice-versa. | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | System ID [1|2]> 2 | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | <WRAP round note 100%> | ||
+ | Obviously, though we also mention it, in a single system with loopback, you skip this setup. | ||
+ | </ | ||
+ | |||
+ | ===== Using the chat application ===== | ||
+ | |||
+ | Now you may enter text messages in the " | ||
+ | |||
+ | ===== Building the demo files from source ===== | ||
+ | |||
+ | The main intent behind this design excercise is to illustrate as an example to some of the most frequently asked questions about the HDL repository and how to modify and use it. The following sections may be able to give you some ideas. These sections do a walk through of the build process to generate the demo files above from the source files. As we go through these sections, we cover the above mentioned frequently asked question and reveal (hopefully) our method to madness. | ||
+ | |||
+ | ===== Download Source files ===== | ||
+ | <WRAP round download 100%> | ||
+ | {{: | ||
+ | </ | ||
+ | |||
+ | ===== Setup a workspace ===== | ||
+ | <fc # | ||
+ | |||
+ | The ADI reference design repositories are hosted on GitHub and uses git version control system. However you may use your own repository and/or a different version control system. In any case, try not to download the repository as a zip file. The best strategy is to clone the repository and leave it as it is. Occassionally, | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
[~]> mkdir rfbbp | [~]> mkdir rfbbp | ||
Line 28: | Line 113: | ||
[~/ | [~/ | ||
[~/ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
+ | The build setup assumes you have cloned the " | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
[~/ | [~/ | ||
[~/ | [~/ | ||
Line 36: | Line 126: | ||
[~/ | [~/ | ||
</ | </ | ||
+ | ++++ | ||
- | After the repositories are cloned, the only thing to do is rebase the repository whenever you wish to update it. There is no need to change any files or scripts inside these repositories to use them. | + | ===== Creating |
- | + | <fc # | |
- | ==== Create | + | |
- | + | ||
- | The BBP library | + | |
+ | The RFBBP is developed as an IP core that is part of a different library separate from the ADI library. A Vivado library is just a directory that needs to contain some specific files. In our case, we create a library (named " | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
[~/ | [~/ | ||
Line 50: | Line 140: | ||
[~/ | [~/ | ||
</ | </ | ||
+ | ++++ | ||
- | The IP library | + | This library |
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | set_property ip_repo_paths ip [current_fileset] | ||
+ | </ | ||
+ | ++++ | ||
- | ==== Creating | + | <fc # |
+ | |||
+ | The TCL file is optional. You may create the IP and save the generated files. However, we like the TCL flow because it makes the tool conform to our needs. We do not wish to discuss the reasons (too many), but consider this- so far we were unable to generate the Vivado library files across various versions | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | set ad_hdl_dir $:: | ||
+ | set ad_phdl_dir $:: | ||
+ | |||
+ | source $ad_hdl_dir/ | ||
+ | |||
+ | adi_ip_create axi_xcomm2ip | ||
+ | adi_ip_files axi_xcomm2ip [list \ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | adi_ip_properties axi_xcomm2ip | ||
+ | adi_ip_constraints axi_xcomm2ip [list \ | ||
+ | " | ||
+ | |||
+ | ipx:: | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | Note the use of the environment variable " | ||
+ | |||
+ | <fc # | ||
+ | |||
+ | As with the TCL file, the Makefile is also a choice (watched the Matrix too many times). If you choose to follow our frame work, simply list your dependencies and targets. Again note the export of the environment variable. This variable is set based on the workspace setup we discussed above. | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | export ADI_HDL_DIR := ../ | ||
+ | export ADI_PHDL_DIR := ../ | ||
+ | |||
+ | M_DEPS += $(ADI_HDL_DIR)/ | ||
+ | M_DEPS += $(ADI_HDL_DIR)/ | ||
+ | M_DEPS += $(ADI_HDL_DIR)/ | ||
+ | M_DEPS += $(ADI_HDL_DIR)/ | ||
+ | M_DEPS += $(ADI_HDL_DIR)/ | ||
+ | M_DEPS += axi_xcomm2ip_constr.xdc | ||
+ | M_DEPS += axi_xcomm2ip_ip.tcl | ||
+ | M_DEPS += axi_xcomm2ip.v | ||
+ | |||
+ | M_VIVADO := vivado -mode batch -source | ||
+ | |||
+ | M_FLIST := *.cache | ||
+ | M_FLIST += *.data | ||
+ | M_FLIST += *.xpr | ||
+ | M_FLIST += *.log | ||
+ | M_FLIST += component.xml | ||
+ | M_FLIST += *.jou | ||
+ | M_FLIST += xgui | ||
+ | M_FLIST += .Xil | ||
+ | |||
+ | .PHONY: all clean clean-all | ||
+ | all: axi_xcomm2ip.xpr | ||
+ | |||
+ | |||
+ | clean: | ||
+ | |||
+ | |||
+ | clean-all: | ||
+ | rm -rf $(M_FLIST) | ||
+ | |||
+ | |||
+ | axi_xcomm2ip.xpr: | ||
+ | rm -rf $(M_FLIST) | ||
+ | $(M_VIVADO) axi_xcomm2ip_ip.tcl | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | <fc # | ||
+ | |||
+ | In order for our directory " | ||
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
- | As mentioned in the article, | + | ===== Creating |
+ | <fc # | ||
+ | As mentioned in the article, the RFBBP IP is an AXI core, making it a peripheral that interfaces to the processor so that it can be accessed via software. In order to create an AXI IP core, one could make use of the ADI library common modules. All you need in such a case would be to instantiate the " | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
wire up_clk; | wire up_clk; | ||
Line 101: | Line 283: | ||
.up_rack (up_rack_s)); | .up_rack (up_rack_s)); | ||
</ | </ | ||
+ | ++++ | ||
- | ==== Creating an "Insert-able" | + | <fc # |
- | The BBP is implemented as an " | + | <fc # |
+ | The BBP is implemented as an " | ||
+ | |||
+ | Once the placement has been fixed, match the " | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
input clk, | input clk, | ||
input rst, | input rst, | ||
</ | </ | ||
+ | ++++ | ||
- | In the receive direction it needs to interface to the ADC data ports of the AXI_AD9361 core. This makes it essentially an offline data processing core. | + | In the receive direction it needs to interface to the ADC data ports of the AXI_AD9361 core. This makes it essentially an offline data processing core. So we mirror the " |
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
input | input | ||
Line 123: | Line 311: | ||
input | input | ||
</ | </ | ||
+ | ++++ | ||
Similarly, in the transmit direction it needs to interface to the DAC data ports of the AXI_AD9361 core. However, this breaks the default data path of the ADI design in which the DAC data is sourced from the DMA core. So the BBP IP core needs the DMA signals in order to maintain the default data path unless programmed by the software otherwise. | Similarly, in the transmit direction it needs to interface to the DAC data ports of the AXI_AD9361 core. However, this breaks the default data path of the ADI design in which the DAC data is sourced from the DMA core. So the BBP IP core needs the DMA signals in order to maintain the default data path unless programmed by the software otherwise. | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
input | input | ||
Line 144: | Line 333: | ||
output | output | ||
</ | </ | ||
+ | ++++ | ||
- | Then infer a simple | + | The data path can then be altered by infering |
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
assign dac_data_i0 = dac_data_i0_int; | assign dac_data_i0 = dac_data_i0_int; | ||
Line 186: | Line 376: | ||
end | end | ||
</ | </ | ||
+ | ++++ | ||
- | The rest of the IP core may now generate its own transmit data for the DAC and process the received data from the ADC as it seems fit. This part, though critical, is beyond the scope of this document and is intentionally left out of our discussion. | + | <fc # |
- | ==== Understanding | + | This is NOT something we can answer. It is also a question of " |
- | In order to use this IP core all we need now is a definition | + | As for our RFBBP core, it is suffice to say that the rest of the logic generate its own transmit data for the DAC and process the received data from the ADC as it seems fit. This part, though critical to understanding the workings of a radio design, is beyond the scope of this document and is intentionally left out of our discussion. |
- | ==== Creating the IP TCL file for Vivado | + | ===== Modifying and customizing ADI projects |
+ | <fc # | ||
- | The TCL file is quite easy to create | + | As mentioned above, the RFBBP AXI core is designed for the " |
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | [~/ | ||
+ | </ | ||
+ | ++++ | ||
+ | Lets look at the " | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
set ad_hdl_dir $:: | set ad_hdl_dir $:: | ||
set ad_phdl_dir $:: | set ad_phdl_dir $:: | ||
- | source $ad_hdl_dir/ | + | source $ad_hdl_dir/ |
+ | source $ad_hdl_dir/ | ||
+ | </ | ||
+ | ++++ | ||
- | adi_ip_create axi_xcomm2ip | + | Then we set the "zynq" |
- | adi_ip_files axi_xcomm2ip [list \ | + | ++++ Show/Hide Commands: | |
- | | + | < |
- | " | + | set sys_zynq 1 |
- | " | + | |
- | " | + | |
- | " | + | |
- | adi_ip_properties axi_xcomm2ip | + | create_project zc706 . -part xc7z045ffg900-2 -force |
- | adi_ip_constraints axi_xcomm2ip [list \ | + | |
- | " | + | |
- | ipx::save_core | + | set_property board_part xilinx.com:zc706:part0: |
</ | </ | ||
+ | ++++ | ||
- | ==== Creating | + | Now, pay special attention, we set the ip repository folders. |
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | set_property ip_repo_paths [list $ad_hdl_dir/ | ||
- | The Makefile is also a straight copy of the ADI IP Makefile. However note the export of the environment variable. This variable is set based on the workspace setup we have. This is all that is needed to use the ADI HDL frame work outside of the HDL repository. | + | update_ip_catalog |
+ | </ | ||
+ | ++++ | ||
+ | Once the libraries are read, we can inherit the " | ||
+ | ++++ Show/Hide Commands: | | ||
< | < | ||
- | export ADI_HDL_DIR := ../../../hdl | + | create_bd_design " |
- | export ADI_PHDL_DIR := ../../../hdl | + | source $ad_hdl_dir/projects/common/zc706/zc706_system_bd.tcl |
+ | source $ad_hdl_dir/projects/ | ||
+ | </xterm> | ||
+ | ++++ | ||
- | M_DEPS += $(ADI_HDL_DIR)/ | + | The customization, |
- | M_DEPS | + | ++++ Show/Hide Commands: | |
- | M_DEPS += $(ADI_HDL_DIR)/library/common/ad_mem.v | + | < |
- | M_DEPS += $(ADI_HDL_DIR)/library/common/ad_rst.v | + | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_valid_i0]]] |
- | M_DEPS += $(ADI_HDL_DIR)/library/common/ | + | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_data_i0]]] |
- | M_DEPS | + | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_valid_q0]]] |
- | M_DEPS | + | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_data_q0]]] |
- | M_DEPS | + | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_valid_i1]]] |
+ | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_data_i1]]] | ||
+ | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_valid_q1]]] | ||
+ | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_data_q1]]] | ||
+ | delete_bd_objs [get_bd_nets -of_objects [find_bd_objs -relation connected_to [get_bd_pins axi_ad9361/dac_dunf]]] | ||
+ | </xterm> | ||
+ | ++++ | ||
- | M_VIVADO | + | Add the " |
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | set axi_xcomm2ip [create_bd_cell | ||
+ | set_property -dict [list CONFIG.XCOMM2IP_1T1R_OR_2T2R_N {0}] $axi_xcomm2ip | ||
+ | </ | ||
+ | ++++ | ||
- | M_FLIST := *.cache | + | Connect its slave AXI interface to the " |
- | M_FLIST | + | ++++ Show/Hide Commands: | |
- | M_FLIST | + | < |
- | M_FLIST | + | ad_cpu_interconnect 0x79040000 axi_xcomm2ip |
- | M_FLIST | + | </ |
- | M_FLIST += *.jou | + | ++++ |
- | M_FLIST += xgui | + | |
- | M_FLIST | + | |
- | .PHONY: all clean clean-all | + | And the data path connections; |
- | all: axi_xcomm2ip.xpr | + | ++++ Show/Hide Commands: | |
+ | < | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | ad_connect | ||
+ | </ | ||
+ | ++++ | ||
- | clean:clean-all | + | Some clean-up, saving and validating. |
+ | ++++ Show/Hide Commands: | | ||
+ | < | ||
+ | delete_bd_objs [get_bd_cells ila_adc] | ||
+ | delete_bd_objs [get_bd_nets axi_ad9361_tdd_dbg] [get_bd_cells ila_tdd] | ||
+ | regenerate_bd_layout | ||
+ | save_bd_design | ||
+ | validate_bd_design | ||
+ | </ | ||
+ | ++++ | ||
- | clean-all: | + | Generate |
- | rm -rf $(M_FLIST) | + | ++++ Show/Hide Commands: | |
+ | < | ||
+ | generate_target {synthesis implementation} [get_files zc706.srcs/ | ||
+ | make_wrapper -files [get_files zc706.srcs/ | ||
+ | import_files -force -norecurse | ||
+ | adi_project_files zc706 [list \ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | </ | ||
+ | ++++ | ||
- | axi_xcomm2ip.xpr: $(M_DEPS) | + | Now build the project. |
- | rm -rf $(M_FLIST) | + | ++++ Show/Hide Commands: | |
- | $(M_VIVADO) axi_xcomm2ip_ip.tcl | + | < |
+ | adi_project_run zc706 | ||
</ | </ | ||
+ | ++++ | ||
- | ==== Building the BBP Library | + | ===== Building |
+ | ===== Making | ||
+ | === What do I need to do to access a HDL IP core from Linux? === | ||
+ | |||
+ | ===== Accessing the HDL IP core in Linux ===== | ||
+ | === How do I access a HDL IP core from Linux? | ||
- | The complete IP core files are to be extracted from the downloaded archive. The IP is then built (so that Vivado understands it) by simply running " | ||
- | < | ||
- | [~/ | ||
- | [~/ | ||
- | [~/ | ||
- | [~/ | ||
- | </ | ||