USRP FPGA HDL Source

repository·UHD-3.15.LTS·Indexed 43 days ago

https://github.com/ettusresearch/fpga

Open-source Hardware Description Language (HDL) source code for Ettus Research Universal Software Radio Peripheral (USRP) SDR platforms. Includes build instructions and coding guidelines for Generation 1 (Altera Quartus), Generation 2 (Xilinx ISE), and Generation 3 (Xilinx Vivado/ISE) hardware.

Tokens
12.5K
Snippets
45
Records
64
Agent score
55%

What's inside USRP FPGA

  1. Understand the licensing for USRP3 FPGA code

    UHD-3.15.LTS

    All code written by Ettus Research within the usrp3 subdirectory of this repository is licensed under the LGPLv3 (GNU Lesser General Public License version 3).

    Note that the repository may contain code from other sources which is marked appropriately and may be subject to different licenses.

    If you require an alternative license for components owned by Ettus Research or National Instruments, you must contact info@ettus.com.

  2. Identify the correct FPGA source directory by USRP generation

    UHD-3.15.LTS

    The FPGA HDL source is organized into directories based on the USRP product generation. Use the following mapping to locate the source code for your device:

    • Generation 1: Located in the __usrp1__ directory. Supports USRP Classic devices only. Requires Altera Quartus.
    • Generation 2: Located in the __usrp2__ directory. Supports USRP N2X0, B100, E1X0, and USRP2. Requires Xilinx ISE and GNU make.
    • Generation 3: Located in the __usrp3__ directory. Supports USRP B2X0, X Series, and E3X0. Requires Xilinx ISE and GNU make.
  3. Understand the 10GE MAC Core directory structure

    UHD-3.15.LTS

    The 10GE MAC Core project is organized into the following directory structure:

    • doc: Documentation files.
    • rtl/include: Verilog defines and utility files.
    • rtl/verilog: Verilog source files for the xge_mac.
    • sim/systemc: SystemC simulation directory.
    • sim/verilog: Verilog simulation directory.
    • tbench/systemc: SystemC test-bench source files.
    • tbench/verilog: Verilog test-bench source files.
  4. Identify USRP FPGA source by product generation

    UHD-3.15.LTS

    The repository is organized into directories based on the USRP hardware generation. Locate the appropriate directory to find the HDL source for your specific device:

    • Generation 1: Located in __usrp1__. Supports USRP Classic devices only. Requires Altera Quartus.
    • Generation 2: Located in __usrp2__. Supports USRP N2X0, B100, E1X0, and USRP2. Requires Xilinx ISE and GNU make.
    • Generation 3: Located in __usrp3__. Supports USRP B2X0, X Series, E3X0, and N3xx. Requires Xilinx Vivado or ISE and GNU make.
  5. Requirements for an FPGA unit test

    UHD-3.15.LTS

    To implement a unit test or system-level test using the Vivado makefile infrastructure, every executable FPGA unit test must consist of two primary components:

    1. A Makefile: This tells the build tools what to build, where to build it, dependency information, and runtime information. The infrastructure handles the specific implementation details for different supported simulation tools.
    2. A Testbench top-level module: The SystemVerilog/Verilog module that serves as the entry point for the simulation.
  6. Where to insert custom DSP logic in Generation 2 products

    UHD-3.15.LTS

    The USRP FPGA build-framework provides specific insertion points within the transmit (TX) and receive (RX) chains. You can add custom DSP modules at the following locations:

    Receive (RX) Chain:

    • Before the DDC (Digital Down Converter) module
    • After the DDC module
    • Replacing the DDC module
    • As an RX packet engine

    Transmit (TX) Chain:

    • Before the DUC (Digital Up Converter) module
    • After the DUC module
    • Replacing the DUC module
    • As a TX packet engine
  7. Implement test cases with START, DONE, and ASSERT macros

    UHD-3.15.LTS

    Test cases should be independent entities that validate specific DUT behaviors. They are managed using a lifecycle of start, assertion, and completion macros within the tb_main block.

    Test Case Lifecycle

    1. Start: Wrap the test logic with `TEST_CASE_START("test_name").
    2. Validate: Use assertion macros to check conditions. If an assertion fails, it affects the test case status.
    3. End: Wrap the end of the logic with `TEST_CASE_DONE(test_result), where test_result is the user-specified outcome.

    Assertion Macros

    Assertions are wrappers around SystemVerilog asserts that integrate with the reporting framework:

    • `ASSERT_FATAL(cond, msg): Throws an error and halts the simulator if cond is false.
    • `ASSERT_ERROR(cond, msg): Throws an error and fails the current test case, but the simulator continues.
    • `ASSERT_WARNING(cond, msg): Throws a warning but does not fail the test case.
    `TEST_CASE_START("My Test Case");
      // ... test logic ...
      `ASSERT_ERROR(data == expected_data, "Data mismatch!");
    `TEST_CASE_DONE(1);
  8. AXI Bus Naming and Implementation Best Practices

    UHD-3.15.LTS

    Since AXI buses are heavily used, follow these specific naming conventions to simplify connections:

    Module Port Naming (Master/Slave Convention)

    When defining ports for a module, use the s_ (slave) and m_ (master) prefixes. This ensures that a master always connects to a slave correctly.

    // Slave interface ports
    input  wire [63:0] s_axis_tdata,
    input  wire        s_axis_tlast,
    input  wire        s_axis_tvalid,
    output wire        s_axis_tready,
    
    // Master interface ports
    output reg  [63:0] m_axis_tdata,
    output reg         m_axis_tlast,
    output reg         m_axis_tvalid,
    input  wire        m_axis_tready,

    Inter-module Connection Naming

    Do not use the master/slave convention for the wires that connect two modules. Instead, name the wire based on its function or the data it carries.

    • Functional Naming: axis_eth2xbar_tdata
    • Data-centric Naming: If the 'axis' prefix is obvious, you may drop it (e.g., samp_tdata).
    // Module ports use master/slave convention
    input  wire [63:0] s_axis_tdata,
    output reg  [63:0] m_axis_tdata,
    
    // Connections between modules use functional/data names
    wire [63:0] axis_eth2xbar_tdata,
    wire [63:0] samp_tdata,
  9. Module Definition and Port Declaration Standards

    UHD-3.15.LTS

    Follow these rules when defining and instantiating modules:

    • File Structure: Define each module in its own separate file.
    • Port Declarations: Use Verilog 2001 ANSI-C style port declarations.
    • Port Organization:
      • Declare inputs and outputs one per line.
      • Be explicit about wire vs reg types.
      • Group signals logically (e.g., keep AXI-Stream components together) rather than strictly by direction.
      • Add inline comments to ports to describe their behavior.
    • Instantiation:
      • Always instantiate all ports, even if they are unconnected or tied off.
      • Use explicit connections (e.g., .status(/* unused */)) instead of letting the compiler insert default values.
      • Never use positional arguments for instantiation.
    // ANSI-C style port declaration
    module my_module (
      input  wire [63:0] s_axis_tdata, // Description of data
      input  wire        s_axis_tlast,
      output reg  [63:0] m_axis_tdata,
      output reg         m_axis_tvalid
    );
    
    // Explicit instantiation
    dummy_module inst (
      .clk(clk), 
      .rst(rst), 
      .status(/* unused */)
    );
  10. Install build dependencies on Ubuntu, Fedora, or Windows

    UHD-3.15.LTS

    Before building, ensure your environment has the necessary system dependencies.

    Ubuntu

    sudo apt-get install python bash build-essential doxygen

    Fedora

    sudo yum -y install python bash make doxygen

    Windows (using Cygwin)

    Windows is only supported with Vivado. Use Cygwin (64-bit preferred) and install the following packages via the GUI installer:

    python patch patchutils bash make doxygen
  11. Build the FPGA documentation locally

    UHD-3.15.LTS

    To view documentation for custom or unstable branches that are not available on the web, you must build the documentation locally using Doxygen.

    1. Install Doxygen on your system.
    2. Navigate to the docs directory.
    3. Run make to generate the HTML documentation.
    4. Open html/index.html in a web browser.
    $ cd docs
    $ make
    $ sensible-browser html/index.html
  12. Set up the Xilinx build environment

    UHD-3.15.LTS

    Before building, you must add xtclsh to your PATH and initialize the Xilinx environment by sourcing the appropriate settings script. Replace <install_dir> with your actual Xilinx installation path.

    • For 64-bit platforms: source <install_dir>/Xilinx/12.2/ISE_DS/settings64.sh
    • For 32-bit platforms: source <install_dir>/Xilinx/12.2/ISE_DS/settings32.sh
    source <install_dir>/Xilinx/12.2/ISE_DS/settings64.sh