http://other.dreamrunner.org/2012/02/usrp2-hdl-primer/#more-351
Documentation for the USRP2′s Verilog implementation is essentially non-existent. I am writing this primer as both a reference for the reader and an aid in my learning and understanding of the FPGA’s architecture and functionality.
To get started, the code is located in a git repository. Check out a copy by entering the following:
git clone git://code.ettus.com/ettus/uhd.git
The USRP2′s architecture is a little confusing, so I will start off with a brief overview. Configuration data for the FPGA is stored on a supplied 2GB SD card. On startup, the FPGA is programmed with this configuration data. If there is no SD card or an invalid configuration is present, the FPGA will not program properly. Successful configuration is verified by the two lower-left LEDs turning on after a few seconds post power-on.
Internal to the FPGA, there is a 32-bit open-source soft-core RISC processor. This core is referred to as ‘ZPU’, and is supported through by an open-source toolchain by Zylin. Program data for the ZPU is stored in a separate location on the installed SD card.
Data is transferred to and from the USRP2 over a Gigabit Ethernet port using UDP. The FPGA has direct access to a PHYceiver, so all protocol translation is done in the FPGA fabric.
Lastly, the FPGA’s main clock is provided at 100MHz. Both the ADCs and DACs also interface at this 100MHz rate.
The FPGA HDL code is located under <uhd_repo>/fpga/usrp2
. First we’ll look at the top-level design file, which is located under <uhd_repo>/fpga/usrp2/top/USRP2/u2_core.v
. u2_rev3.v
is technically the top-level design, but mostly contains the DCM instantiations and various basic logic signals.
Ignoring the various wire declarations at the top, the first module we run into is wb_1master
Location: <uhd_repo>/fpga/usrp2/control_lib/wb_1master.v
This ‘wishbone single master interconnect’ provides a simple bus interface to the ZPU core. It segments the address space to provide access to the instantiated Block RAM, Packet Router, SPI, I2C devices, etc.
Location: <uhd_repo>/fpga/usrp2/control_lib/system_control.v
This is a simple POR controller for sytem-wide reset and SD card arbitration. ZPU code is loaded into RAM after a POR from the SD card, so a delayed signal is necessary in order for the processor to take control of the SD card. Note: it appears as if the ZPU does not have access to the SD card, as that module is commented out of the top-level code
Location: <uhd_repo>/fpga/usrp2/control_lib/ram_loader.v
As mentioned earlier, the ZPU program is loaded from the SD card onto on-board Block RAM after POR. This device serves no other purpose during the rest of the time.
Location: <uhd_repo>/fpga/usrp2/opencores/zpu/zpu_wb_top.vhd
The main ZPU top-level instantiation. Very basic RISC core, with wishbone interface and interrupt inputs. This ZPU core does not handle any of the raw data, but is used to set up peripherals and provide an interface for the computer to modify register settings, etc.
Location: <uhd_repo>/fpga/usrp2/control_lib/ram_harvard.v
Main Block RAM instantiation. Currently this limits program sizes to 16kB. This device (RAM) is accessible as device #0 on the wishbone interconnect, and has an associated address range of 8′b0000 0000 – 8′b0011 1111.
Location: <uhd_repo>/fpga/usrp2/fifo/packet_router.v
TODO: Figure out what this module does… Unfortunately the next page or so was done last night but I forgot to save….
Location: <uhd_repo>/fpga/usrp2/opencores/spi/rtl/verilog/spi_top.v
This is an Opencores core which acts as an SPI bus master for the ZPU. There are various devices on the SPI bus, including ADCs/DACs, and random peripherals on installed daughterboards.
Location: <uhd_repo>/fpga/usrp2/opencores/i2c/rtl/verilog/i2c_master_top.v
This is another Opencores core which acts as an I2C bus master for the ZPU. I2C only seems to be used for various daughterboard configuration functions. It does not seem to be connected to anything on the main motherboard.
Location: <uhd_repo>/fpga/usrp2/control_lib/nsgpio.v
This module provides full tri-state access to all 32 gpio lines which go to the daughterboard(s). Only controlled by the ZPU. I am pretty sure all access to these GPIOs is performed solely through commands from the host computer.
Location: <uhd_repo>/fpga/usrp2/control_lib/wb_readback_mux.v
TODO: Figure out what this module does….
Location: <uhd_repo>/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
TODO: This is obviously the interface to the GigE, but I need to figure out what exactly it does….
Location: <uhd_repo>/fpga/usrp2/control_lib/settings_bus.v
TODO: Figure out what this module does….
Location: <uhd_repo>/fpga/usrp2/control_lib/settings_bus_crossclock.v
This module just provides a cross-clock-domain interface using a FIFO.
Location: <uhd_repo>/fpga/usrp2/control_lib/setting_reg.v
These modules provide addressable settings registers whose value can be changed by the ZPU through the settings_bus.
Location: <uhd_repo>/fpga/usrp2/control_lib/oneshot_2clk.v
Used to retime a signal between clock domains. Upon a positive edge of the incoming signal on clock domain 1, a one-shot pulse is output on the second clock domain.
Location: <uhd_repo>/fpga/usrp2/control_lib/pic.v
(Programmable?) Interrupt Controller. TODO: Figure out exactly hos this interrupt controller works….
Location: <uhd_repo>/fpga/usrp2/control_lib/simple_uart.v
This module gives the ZPU a debugging UART output. TODO: Figure out where this is physically!. I believe the UART rate is 230400 8N1.
Location: <uhd_repo>/fpga/usrp2/sdr_lib/rx_frontend.v
This module contains the first stage of filtering for the incoming ADC samples. I & Q samples enter and are modified to account for any DC ADC offset along with any apparent I/Q mismatch as long as the IQCOMP_EN parameter is set to one (which it is by default). Since these transformations are applied, a higher-precision 24-bit I & Q sample are output to the next stage of data handling.
Location: <uhd_repo>/fpga/usrp2/sdr_lib/dsp_core_rx.v
This module performs all the main DSP functions to incoming ADC samples after they have made their way through the rx_frontend
module.
First in the path is a CORDIC filter with an associated incrementing phase register to implement a NCO. This first filter is necessary to mix the signal to the correct baseband frequency since the daughterboard may not be able to tune the exactly-correct frequency.
Second, the samples pass through a cascaded integrator-comb filter (CIC) which decimates the signal by a parameter set by the user, which is actually a ZPU settings register.
Two additional half-band decimators are used to reduce harmonics from the CIC. The half-band decimators are used in case the desired decimation is a multiple of 2 (one half-band decimator used) or 4 (two half-band decimators used).
The total decimation is CIC_DECIM*(hb1_en+1)*(hb2_en+1) assuming hb1_en, hb2_en := {0,1}
The samples are finally output using the ‘sample’ bus in packed {I,Q} form and only valid when strobe == 1.
Location: <uhd_repo>/fpga/usrp2/vrt/vita_rx_chain.v
TODO: I don’t know exactly what this does, but it looks as if it packetizes everything up to be sent off to the packet_router module…. which i assume eventually makes its way out to the GigE interface….
Location: <uhd_repo>/fpga/usrp2/extramfifo/ext_fifo.v
This FIFO controller utilizes the off-chip SRAM present on the USRP2 motherboard. It provides a buffer for incoming TX samples before they are sent out to the corresponding DAC
Location: <uhd_repo>/fpga/usrp2/vrt/vita_tx_chain.v
Interestingly enough, this time this vita component seems to contain the whole chain of modules for streaming data to the DAC. It contains packet deframing, transmit control, and dsp_core_tx, which takes care of halfband interpolation filters and again in this instance a CIC interpolator”. Pretty much backwards from the dsp_core_rx module described earlier.
Location: <uhd_repo>/fpga/usrp2/sdr_lib/tx_frontend.v
Pretty much the same as rx_frontend, just doing I/Q balancing and DC offset correction. This case all of these parameters are settable by the user (ZPU) interface.
Location: <uhd_repo>/fpga/usrp2/serdes/serdes.v
SERDES stands for serializer/deserializer, and is a common tool used to serialize data going over a serial data link. In this case, it is communicating digital data over the MIMO cable link that’s communicating raw data to/from another connected radio. Not really of much concern for independent single-radio setups. Also only allows for 2 (maybe 3?) radios to be connected together.
Location: <uhd_repo>/fpga/usrp2/timing/time_64bit.v
All of the samples are eventually time-tagged with a 64-bit incrementing time tag. This time is modified both by the incoming PPS and phase-locked 100MHz system (DSP) clock. TODO: Don’t quite know at this point if the time is actually used anywhere or not…
http://novelflash.com/wiki/index.php?title=USRP2_HDL_Primer
聯(lián)系客服