Wiki

This version is outdated by a newer approved version.DiffThis version (04 Aug 2016 21:18) is a draft.
Approvals: 0/1

This is an old revision of the document!


A simple BBP for RF Transceivers

This wiki page is a follow up documentation for the ADI article titled “A Simple Baseband Processor for RF Transceivers”. The article covers the theory and implementation details of a simple BBP using the ZC706 + AD-FMCOMMS3 rapid prototyping platform. This page details the build process of the BBP design and how to run it on the ZC706 + AD-FMCOMMS3 hardware.

Please note that Analog Devices does NOT support this design. It is only meant to illustrate a work flow using the ADI github repositories, creating a frame work to modify the IP cores and to use them in customized projects, building the Linux images and accessing the core using simple software routines. The recommended procedure for BBP design is to model it in Simulink and subsequently implement the design using HDL coder. The radio communication demonstration detailed here may be used as a frame work and implementation flow for such designs. The core of the axi_xcomm2ip is intentionally obfuscated to discourage any use or modification of the IP.

In addition to the BBP design, this document also covers the git repository use, adding AXI interfaces and modifying projects. There fore, it is important that the reader is familiar with the ADI HDL and Linux frame work and the tools needed to build them. Also note that the instructions exclusively use a Linux environment, make system and command line to do things. Please do not seek support or ask questions outside the scope of this document.

Download Source and Run-Time files

Setup the workspace

The ADI reference design repositories are hosted on GitHub. In this section, we show how to setup these repositories in your environment and use your own repository structure and version control along with it. The goal is to leave the ADI repository AS IT IS and do all the customizations outside of it.

[~]> mkdir rfbbp
[~]> cd rfbbp

[~/rfbbp]> git clone git@github.com:analogdevicesinc/hdl.git
[~/rfbbp]> cd hdl
[~/rfbbp/hdl]> git checkout hdl_2016_r1
[~/rfbbp/hdl]> git fetch
[~/rfbbp/hdl]> git rebase origin/hdl_2016_r1
[~/rfbbp/hdl]> cd ..

[~/rfbbp]> git clone git@github.com:analogdevicesinc/linux.git
[~/rfbbp]> cd linux
[~/rfbbp/linux]> git checkout 2016_R1
[~/rfbbp/linux]> git fetch
[~/rfbbp/linux]> git rebase origin/2016_R1
[~/rfbbp/linux]> cd ..

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.

Create the BBP Library

The BBP library is just a directory that needs to contain some specific files. You may place this anywhere in your workspace. In this case, the library is created outside the ADI hdl repository but inside the rfbbp directory.

[~/rfbbp]> mkdir -p ip/axi_xcomm2ip
[~/rfbbp]> touch ip/axi_xcomm2ip/Makefile
[~/rfbbp]> touch ip/axi_xcomm2ip/axi_xcomm2ip.v
[~/rfbbp]> touch ip/axi_xcomm2ip/axi_xcomm2ip_constr.xdc
[~/rfbbp]> touch ip/axi_xcomm2ip/axi_xcomm2ip_ip.tcl

The IP library is “ip” and the IP is named “axi_xcomm2ip”. The minimum set of files an IP needs is the Makefile, a top HDL file, the constraints (if any) and a TCL file to build the IP. The complete IP core files are found in the downloads section at the end of this document. We perhaps need to go through a couple of points about the various files so as to understand the basic frame work and the contents.

Creating a AXI IP core using ADI HDL repository

As mentioned in the article, the IP is an AXI IP core, making it a peripheral that interfaces to the processor so that it can be accessed via software. The ADI reference design repository features a lot of such AXI cores. A quick look reveals that the common module “up_axi” interfaces to the AXI bus. So the first part of the IP core is to instantiate this module. The internal signals mentioned below are then used to infer register or memory space accessible to the processor within the core.

  wire            up_clk;
  wire            up_rstn;
  wire            up_wreq_s;
  wire    [13:0]  up_waddr_s;
  wire    [31:0]  up_wdata_s;
  wire            up_wack_s;
  wire            up_rreq_s;
  wire    [13:0]  up_raddr_s;
  wire    [31:0]  up_rdata_s;
  wire            up_rack_s;

  assign up_clk = s_axi_aclk;
  assign up_rstn = s_axi_aresetn;

  up_axi i_up_axi (
    .up_rstn (up_rstn),
    .up_clk (up_clk),
    .up_axi_awvalid (s_axi_awvalid),
    .up_axi_awaddr (s_axi_awaddr),
    .up_axi_awready (s_axi_awready),
    .up_axi_wvalid (s_axi_wvalid),
    .up_axi_wdata (s_axi_wdata),
    .up_axi_wstrb (s_axi_wstrb),
    .up_axi_wready (s_axi_wready),
    .up_axi_bvalid (s_axi_bvalid),
    .up_axi_bresp (s_axi_bresp),
    .up_axi_bready (s_axi_bready),
    .up_axi_arvalid (s_axi_arvalid),
    .up_axi_araddr (s_axi_araddr),
    .up_axi_arready (s_axi_arready),
    .up_axi_rvalid (s_axi_rvalid),
    .up_axi_rresp (s_axi_rresp),
    .up_axi_rdata (s_axi_rdata),
    .up_axi_rready (s_axi_rready),
    .up_wreq (up_wreq_s),
    .up_waddr (up_waddr_s),
    .up_wdata (up_wdata_s),
    .up_wack (up_wack_s),
    .up_rreq (up_rreq_s),
    .up_raddr (up_raddr_s),
    .up_rdata (up_rdata_s),
    .up_rack (up_rack_s));

Creating an "Insert-able" IP core for the ADI HDL projects

The BBP is implemented as an “insert-able” core. It is placed right in front of the AXI_AD9361 IP core. It is also intended to run at the AD9361 interface clock. So we use the same clock and reset signals as that of the AXI_AD9361 IP.

  input           clk,
  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.

  input           adc_valid_i0,
  input   [15:0]  adc_data_i0,
  input           adc_valid_q0,
  input   [15:0]  adc_data_q0,
  input           adc_valid_i1,
  input   [15:0]  adc_data_i1,
  input           adc_valid_q1,
  input   [15:0]  adc_data_q1,

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.

  input           dac_valid_i0,
  input   [15:0]  dma_data_i0,
  output  [15:0]  dac_data_i0,
  input           dac_valid_q0,
  input   [15:0]  dma_data_q0,
  output  [15:0]  dac_data_q0,
  input           dac_valid_i1,
  input   [15:0]  dma_data_i1,
  output  [15:0]  dac_data_i1,
  input           dac_valid_q1,
  input   [15:0]  dma_data_q1,
  output  [15:0]  dac_data_q1,
  input           dma_dovf,
  input           dma_dunf,
  output          dac_dovf,
  output          dac_dunf,

Then infer a simple data interface multiplexer.

  assign dac_data_i0 = dac_data_i0_int;
  assign dac_data_q0 = dac_data_q0_int;
  assign dac_data_i1 = dac_data_i1_int;
  assign dac_data_q1 = dac_data_q1_int;
  assign dac_dovf = dac_dovf_int;
  assign dac_dunf = dac_dunf_int;

  always @(posedge rst or posedge clk) begin
    if (rst == 1'b1) begin
      dac_enable_m1 <= 1'd0;
      dac_enable <= 1'd0;
      dac_data_i0_int <= 'd0;
      dac_data_q0_int <= 'd0;
      dac_data_i1_int <= 'd0;
      dac_data_q1_int <= 'd0;
      dac_dovf_int <= 'd0;
      dac_dunf_int <= 'd0;
    end else begin
      dac_enable_m1 <= up_dac_enable;
      dac_enable <= dac_enable_m1;
      if (dac_enable == 1'b1) begin
        dac_data_i0_int <= dac_data_i;
        dac_data_q0_int <= dac_data_q;
        dac_data_i1_int <= 16'd0;
        dac_data_q1_int <= 16'd0;
        dac_dovf_int <= 1'd0;
        dac_dunf_int <= 1'd0;
      end else begin
        dac_data_i0_int <= dma_data_i0;
        dac_data_q0_int <= dma_data_q0;
        dac_data_i1_int <= dma_data_i1;
        dac_data_q1_int <= dma_data_q1;
        dac_dovf_int <= dma_dovf;
        dac_dunf_int <= dma_dunf;
      end
    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.

Understanding the IP Register Space

In order to use this IP core all we need now is a definition of the register space.

Creating the IP TCL file for Vivado

The TCL file is quite easy to create and simply makes use of the ADI repository TCL procedures like any other IP core. The only thing to note is the use of the environment variable “AD_HDL_DIR”. This variable is used to point to the ADI HDL repository and use the IP cores, projects and scripts inside of it.

set ad_hdl_dir $::env(ADI_HDL_DIR)
set ad_phdl_dir $::env(ADI_HDL_DIR)

source $ad_hdl_dir/library/scripts/adi_ip.tcl

adi_ip_create axi_xcomm2ip
adi_ip_files axi_xcomm2ip [list \
  "$ad_hdl_dir/library/common/ad_rst.v" \
  "$ad_hdl_dir/library/common/ad_mem.v" \
  "$ad_hdl_dir/library/common/up_axi.v" \
  "axi_xcomm2ip_core.v" \
  "axi_xcomm2ip.v" ]

adi_ip_properties axi_xcomm2ip
adi_ip_constraints axi_xcomm2ip [list \
  "axi_xcomm2ip_constr.xdc" ]

ipx::save_core [ipx::current_core]

Creating The Make file for command-line build

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.

export ADI_HDL_DIR := ../../../hdl
export ADI_PHDL_DIR := ../../../hdl

M_DEPS += $(ADI_HDL_DIR)/library/scripts/adi_env.tcl
M_DEPS += $(ADI_HDL_DIR)/library/scripts/adi_ip.tcl
M_DEPS += $(ADI_HDL_DIR)/library/common/ad_mem.v
M_DEPS += $(ADI_HDL_DIR)/library/common/ad_rst.v
M_DEPS += $(ADI_HDL_DIR)/library/common/up_axi.v
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


clean-all:
	rm -rf $(M_FLIST)


axi_xcomm2ip.xpr: $(M_DEPS)
	rm -rf $(M_FLIST)
	$(M_VIVADO) axi_xcomm2ip_ip.tcl  >> axi_xcomm2ip_ip.log 2>&1

Building the BBP Library

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 “make” inside the directory.

[~/rfbbp]> cd ip
[~/rfbbp/ip]> make
[~/rfbbp/ip]> cd ..
[~/rfbbp]>

resources/fpga/docs/hdl/xcomm2ip.1470338297.txt.gz · Last modified: 04 Aug 2016 21:18 by rejeesh kutty