<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://kb.ettus.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WadeFife</id>
		<title>Ettus Knowledge Base - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://kb.ettus.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WadeFife"/>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/Special:Contributions/WadeFife"/>
		<updated>2026-07-08T14:07:50Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6219</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6219"/>
				<updated>2025-10-01T15:06:40Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Reorder questions and remove redundant questions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 4.7, you can add clock generation modules that create new clocks based on the existing clocks. Note that you must create such a module as an HDL module: Describing clocks in the YAML files will not cause them to be generated for you.&lt;br /&gt;
&lt;br /&gt;
Assuming you have such a module, describe the clocks in the module's YAML files as such:&lt;br /&gt;
&lt;br /&gt;
 clocks:&lt;br /&gt;
    - name: ce&lt;br /&gt;
      direction: in&lt;br /&gt;
    - name: my_clk&lt;br /&gt;
      direction: out&lt;br /&gt;
&lt;br /&gt;
Now you will have a new clock called &amp;lt;code&amp;gt;my_clk&amp;lt;/code&amp;gt;, which is derived from the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock.&lt;br /&gt;
&lt;br /&gt;
In older versions of UHD, adding custom clocks is not directly supported. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado should I install? ===&lt;br /&gt;
&lt;br /&gt;
You should always use the Vivado version specified in the UHD documentation for your UHD release, including any required patches. See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements.&lt;br /&gt;
&lt;br /&gt;
The exact version string can be found in the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script for the FPGA target you intend to build (e.g., &amp;lt;code&amp;gt;fpga/usrp3/top/x400/setupenv.sh&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
=== How do I get Vivado 2021.1 to work on Ubuntu 22.04 and later? ===&lt;br /&gt;
&lt;br /&gt;
Vivado needs the &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;libtinfo5&amp;lt;/code&amp;gt;, which are no longer included by default in recent Ubuntu installations. To install them, run the following commands:&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version? ===&lt;br /&gt;
&lt;br /&gt;
While it is technically possible to use a different Vivado version, doing so comes with significant risks. Vivado versions are not fully compatible with each other, and changing the version usually leads to FPGA build failures. Furthermore, the shipping FPGA images for each UHD release are tested and validated using the specified Vivado version. Other versions are untested. For these reasons, the build process checks the Vivado version and will raise an error if you run &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; with an unsupported version installed.&lt;br /&gt;
&lt;br /&gt;
Because alternative versions are untested, using a different Vivado version is strongly discouraged. If you choose to proceed anyway, you must:&lt;br /&gt;
&lt;br /&gt;
* Update the Vivado version string in the setupenv.sh script for your FPGA target.&lt;br /&gt;
* Update all IP blocks to versions compatible with the new Vivado release, and modify any connections in the USRP code to match the updated IP interfaces. Failure to update the IP blocks will result in errors about the IP being locked. Incorrect or incomplete updates to IP connections may cause build failures or result in a non-functional FPGA image.&lt;br /&gt;
* Additional changes may be required depending on the Vivado version and the specific USRP target you are building. Unfortunately, it's not possible to predict these changes in advance.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI. In UHD 4.7 and later, this can be done by adding the &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; argument to the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; command. In UHD 4.6 and earlier, this can be done by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example: &amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In some cases, it may also be necessary to reset the output products for some of the IP. If you get an error message about a BD sub-design being not generated for the synthesis target, then navigate to the &amp;quot;IP Sources&amp;quot; tab in the Project Manager Sources window, then right-click on affected IP and select &amp;quot;Reset Output Products...&amp;quot;, then click &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== When I start an FPGA build or use rfnoc_image_builder, I get an error &amp;quot;setupenv.sh: source: not found&amp;quot; and the build fails. What happened? ===&lt;br /&gt;
&lt;br /&gt;
In some Linux distributions (e.g. Ubuntu) &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; is set as default shell which can cause FPGA builds to fail.&lt;br /&gt;
&lt;br /&gt;
Below is an example of the error. Note, that your message may look somewhat different depending on UHD version and USRP target but the important lines are marked in bold.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y e320_rfnoc_image_core_fft.yml -t E320_1G&lt;br /&gt;
    Using FPGA directory /home/someuser/uhd/fpga&lt;br /&gt;
    Selected device: e320&lt;br /&gt;
    Build artifacts directory already exists (contents will be overwritten).&lt;br /&gt;
    Launching build with the following settings:&lt;br /&gt;
     * FPGA Directory: /home/someuser/uhd/fpga/usrp3/top/e320&lt;br /&gt;
     * Build Artifacts Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G&lt;br /&gt;
     * Build Output Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build&lt;br /&gt;
     * Build IP Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-ip&lt;br /&gt;
    Executing the following command: . ./setupenv.sh &amp;amp;&amp;amp; make E320_1G BUILD_DIR=/home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G IMAGE_CORE_NAME=usrp_e320_fpga_1G&lt;br /&gt;
    '''/bin/sh: 6: ./setupenv.sh: Bad substitution'''&lt;br /&gt;
    '''/bin/sh: 8: ./setupenv.sh: declare: not found'''&lt;br /&gt;
    /bin/sh: 9: ./setupenv.sh: PRODUCT_ID_MAP[E320]=zynq/xc7z045/ffg900/-3: not found&lt;br /&gt;
    '''/bin/sh: 15: ./setupenv.sh: source: not found'''&lt;br /&gt;
    Build finished with return code 127.&lt;br /&gt;
&lt;br /&gt;
It is recommended to set the default shell to &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt; by running the following command in the terminal. When asked &amp;lt;code&amp;gt;Use dash as the default system shell (/bin/sh)?&amp;lt;/code&amp;gt; choose &amp;lt;code&amp;gt;&amp;lt;No&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ sudo dpkg-reconfigure dash&lt;br /&gt;
&lt;br /&gt;
Confirm your default shell was changed to bash by running this command:&lt;br /&gt;
&lt;br /&gt;
    $ ll /bin/sh&lt;br /&gt;
&lt;br /&gt;
You should see output similar to this:&lt;br /&gt;
&lt;br /&gt;
    lrwxrwxrwx 1 root root 4 Oct 10  2020 /bin/sh -&amp;gt; bash*&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6218</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6218"/>
				<updated>2025-10-01T14:41:27Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add which Vivado version to use, and using different Vivado version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 4.7, you can add clock generation modules that create new clocks based on the existing clocks. Note that you must create such a module as an HDL module: Describing clocks in the YAML files will not cause them to be generated for you.&lt;br /&gt;
&lt;br /&gt;
Assuming you have such a module, describe the clocks in the module's YAML files as such:&lt;br /&gt;
&lt;br /&gt;
 clocks:&lt;br /&gt;
    - name: ce&lt;br /&gt;
      direction: in&lt;br /&gt;
    - name: my_clk&lt;br /&gt;
      direction: out&lt;br /&gt;
&lt;br /&gt;
Now you will have a new clock called &amp;lt;code&amp;gt;my_clk&amp;lt;/code&amp;gt;, which is derived from the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock.&lt;br /&gt;
&lt;br /&gt;
In older versions of UHD, adding custom clocks is not directly supported. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
=== Why does the Vivado 2021.1 installer get stuck or not start on Ubuntu? ===&lt;br /&gt;
&lt;br /&gt;
The Vivado installer needs the libncurses5 and libtinfo5 libraries to run correctly. They can be installed by running the following commands:&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI. In UHD 4.7 and later, this can be done by adding the &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; argument to the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; command. In UHD 4.6 and earlier, this can be done by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example: &amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In some cases, it may also be necessary to reset the output products for some of the IP. If you get an error message about a BD sub-design being not generated for the synthesis target, then navigate to the &amp;quot;IP Sources&amp;quot; tab in the Project Manager Sources window, then right-click on affected IP and select &amp;quot;Reset Output Products...&amp;quot;, then click &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== When I start an FPGA build or use rfnoc_image_builder, I get an error &amp;quot;setupenv.sh: source: not found&amp;quot; and the build fails. What happened? ===&lt;br /&gt;
&lt;br /&gt;
In some Linux distributions (e.g. Ubuntu) &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; is set as default shell which can cause FPGA builds to fail.&lt;br /&gt;
&lt;br /&gt;
Below is an example of the error. Note, that your message may look somewhat different depending on UHD version and USRP target but the important lines are marked in bold.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y e320_rfnoc_image_core_fft.yml -t E320_1G&lt;br /&gt;
    Using FPGA directory /home/someuser/uhd/fpga&lt;br /&gt;
    Selected device: e320&lt;br /&gt;
    Build artifacts directory already exists (contents will be overwritten).&lt;br /&gt;
    Launching build with the following settings:&lt;br /&gt;
     * FPGA Directory: /home/someuser/uhd/fpga/usrp3/top/e320&lt;br /&gt;
     * Build Artifacts Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G&lt;br /&gt;
     * Build Output Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build&lt;br /&gt;
     * Build IP Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-ip&lt;br /&gt;
    Executing the following command: . ./setupenv.sh &amp;amp;&amp;amp; make E320_1G BUILD_DIR=/home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G IMAGE_CORE_NAME=usrp_e320_fpga_1G&lt;br /&gt;
    '''/bin/sh: 6: ./setupenv.sh: Bad substitution'''&lt;br /&gt;
    '''/bin/sh: 8: ./setupenv.sh: declare: not found'''&lt;br /&gt;
    /bin/sh: 9: ./setupenv.sh: PRODUCT_ID_MAP[E320]=zynq/xc7z045/ffg900/-3: not found&lt;br /&gt;
    '''/bin/sh: 15: ./setupenv.sh: source: not found'''&lt;br /&gt;
    Build finished with return code 127.&lt;br /&gt;
&lt;br /&gt;
It is recommended to set the default shell to &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt; by running the following command in the terminal. When asked &amp;lt;code&amp;gt;Use dash as the default system shell (/bin/sh)?&amp;lt;/code&amp;gt; choose &amp;lt;code&amp;gt;&amp;lt;No&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ sudo dpkg-reconfigure dash&lt;br /&gt;
&lt;br /&gt;
Confirm your default shell was changed to bash by running this command:&lt;br /&gt;
&lt;br /&gt;
    $ ll /bin/sh&lt;br /&gt;
&lt;br /&gt;
You should see output similar to this:&lt;br /&gt;
&lt;br /&gt;
    lrwxrwxrwx 1 root root 4 Oct 10  2020 /bin/sh -&amp;gt; bash*&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;br /&gt;
&lt;br /&gt;
=== How do I get Vivado 2021.1 to work with Ubuntu 22.04 and later? ===&lt;br /&gt;
&lt;br /&gt;
Vivado 2021.1 requires the &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; library, which is no longer included by default in recent Ubuntu installations.&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 22.04 ====&lt;br /&gt;
&lt;br /&gt;
You can install &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; by running the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt update&lt;br /&gt;
    $ sudo apt install libncurses5&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24.04 ====&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 24.04, &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; is no longer available in the default repositories. To install it, you need to add a repository that includes the required package.&lt;br /&gt;
&lt;br /&gt;
First, create or edit the file:&lt;br /&gt;
&lt;br /&gt;
    /etc/apt/sources.list.d/ubuntu-focal-sources.list&lt;br /&gt;
&lt;br /&gt;
Then add the following line to the file:&lt;br /&gt;
&lt;br /&gt;
    deb http://security.ubuntu.com/ubuntu focal-security main universe&lt;br /&gt;
&lt;br /&gt;
Next, update your package list and install the library:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt update&lt;br /&gt;
    $ sudo apt install libncurses5&lt;br /&gt;
&lt;br /&gt;
=== Which Vivado version should I install? ===&lt;br /&gt;
&lt;br /&gt;
You should always use the Vivado version specified in the UHD documentation for your UHD release, including any required patches. The exact version string can be found in the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script for the FPGA target you intend to build (e.g., &amp;lt;code&amp;gt;fpga/usrp3/top/x400/setupenv.sh&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version? ===&lt;br /&gt;
&lt;br /&gt;
While it is technically possible to use a different Vivado version, doing so comes with significant risks. Vivado versions are not fully compatible with each other, and changing the version usually leads to FPGA build failures. Furthermore, the shipping FPGA images for each UHD release are tested and validated using the specified Vivado version. Other versions are untested. For these reasons, the build process checks the Vivado version and will raise an error if you run &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; with an unsupported version installed.&lt;br /&gt;
&lt;br /&gt;
Because alternative versions are untested, using a different Vivado version is strongly discouraged. If you choose to proceed anyway, you must:&lt;br /&gt;
&lt;br /&gt;
* Update the Vivado version string in the setupenv.sh script for your FPGA target.&lt;br /&gt;
* Update all IP blocks to versions compatible with the new Vivado release, and modify any connections in the USRP code to match the updated IP interfaces. Failure to update the IP blocks will result in errors about the IP being locked. Incorrect or incomplete updates to IP connections may cause build failures or result in a non-functional FPGA image.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6217</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6217"/>
				<updated>2025-10-01T14:35:45Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add how to install libncurses on Ubuntu 22 and later&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 4.7, you can add clock generation modules that create new clocks based on the existing clocks. Note that you must create such a module as an HDL module: Describing clocks in the YAML files will not cause them to be generated for you.&lt;br /&gt;
&lt;br /&gt;
Assuming you have such a module, describe the clocks in the module's YAML files as such:&lt;br /&gt;
&lt;br /&gt;
 clocks:&lt;br /&gt;
    - name: ce&lt;br /&gt;
      direction: in&lt;br /&gt;
    - name: my_clk&lt;br /&gt;
      direction: out&lt;br /&gt;
&lt;br /&gt;
Now you will have a new clock called &amp;lt;code&amp;gt;my_clk&amp;lt;/code&amp;gt;, which is derived from the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock.&lt;br /&gt;
&lt;br /&gt;
In older versions of UHD, adding custom clocks is not directly supported. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
=== Why does the Vivado 2021.1 installer get stuck or not start on Ubuntu? ===&lt;br /&gt;
&lt;br /&gt;
The Vivado installer needs the libncurses5 and libtinfo5 libraries to run correctly. They can be installed by running the following commands:&lt;br /&gt;
&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
 sudo apt install ./libncurses5_6.3-2ubuntu0.1_amd64.deb&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI. In UHD 4.7 and later, this can be done by adding the &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; argument to the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; command. In UHD 4.6 and earlier, this can be done by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example: &amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In some cases, it may also be necessary to reset the output products for some of the IP. If you get an error message about a BD sub-design being not generated for the synthesis target, then navigate to the &amp;quot;IP Sources&amp;quot; tab in the Project Manager Sources window, then right-click on affected IP and select &amp;quot;Reset Output Products...&amp;quot;, then click &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== When I start an FPGA build or use rfnoc_image_builder, I get an error &amp;quot;setupenv.sh: source: not found&amp;quot; and the build fails. What happened? ===&lt;br /&gt;
&lt;br /&gt;
In some Linux distributions (e.g. Ubuntu) &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; is set as default shell which can cause FPGA builds to fail.&lt;br /&gt;
&lt;br /&gt;
Below is an example of the error. Note, that your message may look somewhat different depending on UHD version and USRP target but the important lines are marked in bold.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y e320_rfnoc_image_core_fft.yml -t E320_1G&lt;br /&gt;
    Using FPGA directory /home/someuser/uhd/fpga&lt;br /&gt;
    Selected device: e320&lt;br /&gt;
    Build artifacts directory already exists (contents will be overwritten).&lt;br /&gt;
    Launching build with the following settings:&lt;br /&gt;
     * FPGA Directory: /home/someuser/uhd/fpga/usrp3/top/e320&lt;br /&gt;
     * Build Artifacts Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G&lt;br /&gt;
     * Build Output Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build&lt;br /&gt;
     * Build IP Directory: /home/someuser/uhd/fpga/usrp3/top/e320/build-ip&lt;br /&gt;
    Executing the following command: . ./setupenv.sh &amp;amp;&amp;amp; make E320_1G BUILD_DIR=/home/someuser/uhd/fpga/usrp3/top/e320/build-usrp_e320_fpga_1G IMAGE_CORE_NAME=usrp_e320_fpga_1G&lt;br /&gt;
    '''/bin/sh: 6: ./setupenv.sh: Bad substitution'''&lt;br /&gt;
    '''/bin/sh: 8: ./setupenv.sh: declare: not found'''&lt;br /&gt;
    /bin/sh: 9: ./setupenv.sh: PRODUCT_ID_MAP[E320]=zynq/xc7z045/ffg900/-3: not found&lt;br /&gt;
    '''/bin/sh: 15: ./setupenv.sh: source: not found'''&lt;br /&gt;
    Build finished with return code 127.&lt;br /&gt;
&lt;br /&gt;
It is recommended to set the default shell to &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt; by running the following command in the terminal. When asked &amp;lt;code&amp;gt;Use dash as the default system shell (/bin/sh)?&amp;lt;/code&amp;gt; choose &amp;lt;code&amp;gt;&amp;lt;No&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ sudo dpkg-reconfigure dash&lt;br /&gt;
&lt;br /&gt;
Confirm your default shell was changed to bash by running this command:&lt;br /&gt;
&lt;br /&gt;
    $ ll /bin/sh&lt;br /&gt;
&lt;br /&gt;
You should see output similar to this:&lt;br /&gt;
&lt;br /&gt;
    lrwxrwxrwx 1 root root 4 Oct 10  2020 /bin/sh -&amp;gt; bash*&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;br /&gt;
&lt;br /&gt;
=== How do I get Vivado 2021.1 to work with Ubuntu 22.04 and later? ===&lt;br /&gt;
&lt;br /&gt;
Vivado 2021.1 requires the &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; library, which is no longer included by default in recent Ubuntu installations.&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 22.04 ====&lt;br /&gt;
&lt;br /&gt;
You can install &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; by running the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt update&lt;br /&gt;
    $ sudo apt install libncurses5&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu 24.04 ====&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 24.04, &amp;lt;code&amp;gt;libncurses5&amp;lt;/code&amp;gt; is no longer available in the default repositories. To install it, you need to add a repository that includes the required package.&lt;br /&gt;
&lt;br /&gt;
First, create or edit the file:&lt;br /&gt;
&lt;br /&gt;
    /etc/apt/sources.list.d/ubuntu-focal-sources.list&lt;br /&gt;
&lt;br /&gt;
Then add the following line to the file:&lt;br /&gt;
&lt;br /&gt;
    deb http://security.ubuntu.com/ubuntu focal-security main universe&lt;br /&gt;
&lt;br /&gt;
Next, update your package list and install the library:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt update&lt;br /&gt;
    $ sudo apt install libncurses5&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6113</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6113"/>
				<updated>2025-01-29T22:13:35Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added workaround for the BD sub-design not being generated after converting to project mode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 4.7, you can add clock generation modules that create new clocks based on the existing clocks. Note that you must create such a module as an HDL module: Describing clocks in the YAML files will not cause them to be generated for you.&lt;br /&gt;
&lt;br /&gt;
Assuming you have such a module, describe the clocks in the module's YAML files as such:&lt;br /&gt;
&lt;br /&gt;
 clocks:&lt;br /&gt;
    - name: ce&lt;br /&gt;
      direction: in&lt;br /&gt;
    - name: my_clk&lt;br /&gt;
      direction: out&lt;br /&gt;
&lt;br /&gt;
Now you will have a new clock called &amp;lt;code&amp;gt;my_clk&amp;lt;/code&amp;gt;, which is derived from the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock.&lt;br /&gt;
&lt;br /&gt;
In older versions of UHD, adding custom clocks is not directly supported. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI. In UHD 4.7 and later, this can be done by adding the &amp;lt;code&amp;gt;-g&amp;lt;/code&amp;gt; argument to the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; command. In UHD 4.6 and earlier, this can be done by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example: &amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In some cases, it may also be necessary to reset the output products for some of the IP. If you get an error message about a BD sub-design being not generated for the synthesis target, then navigate to the &amp;quot;IP Sources&amp;quot; tab in the Project Manager Sources window, then right-click on affected IP and select &amp;quot;Reset Output Products...&amp;quot;, then click &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6040</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6040"/>
				<updated>2024-06-26T13:53:27Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add CE clocks to N3xx and X4xx, which were added in UHD 4.6&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 266.667 MHz (available in UHD 4.6 and later)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 4.7, you can add clock generation modules that create new clocks based on the existing clocks. Note that you must create such a module as an HDL module: Describing clocks in the YAML files will not cause them to be generated for you.&lt;br /&gt;
&lt;br /&gt;
Assuming you have such a module, describe the clocks in the module's YAML files as such:&lt;br /&gt;
&lt;br /&gt;
 clocks:&lt;br /&gt;
    - name: ce&lt;br /&gt;
      direction: in&lt;br /&gt;
    - name: my_clk&lt;br /&gt;
      direction: out&lt;br /&gt;
&lt;br /&gt;
Now you will have a new clock called &amp;lt;code&amp;gt;my_clk&amp;lt;/code&amp;gt;, which is derived from the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock.&lt;br /&gt;
&lt;br /&gt;
In older versions of UHD, adding custom clocks is not directly supported. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6017</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6017"/>
				<updated>2024-02-12T16:06:44Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added additional explanation of the build.log file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
When you build an FPGA target, a build directory is created in the FPGA's top directory that contains all the build outputs. Here you'll find the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file as well as report files and checkpoints. Not all log information is printed to the console during build, so make sure you check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; file for details. It may contain a useful error message that was not printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6005</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=6005"/>
				<updated>2024-01-17T03:18:42Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add FAQ about &amp;quot;critical warnings&amp;quot; during the build process, which is expected.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;br /&gt;
&lt;br /&gt;
=== I see a &amp;quot;CRITICAL WARNING&amp;quot; in the build log. Is this expected? ===&lt;br /&gt;
&lt;br /&gt;
There are many critical warnings that appear during the build process that can be safely ignored. For example, you may see the following:&lt;br /&gt;
&lt;br /&gt;
    CRITICAL WARNING: [Vivado 12-1790] Evaluation License Warning: This design contains one or more IP cores that use separately licensed features. If the design has been configured to make use of evaluation features, please note that these features will cease to function after a certain period of time. Please consult the core datasheet to determine whether the core which you have configured will be affected. Evaluation features should NOT be used in production systems.&lt;br /&gt;
&lt;br /&gt;
The FPGA builds include IP for which the licenses are included with Vivado, but Vivado prints the warnings anyway. As long as you have a Vivado license and a bitstream was successfully generated, the IP should work as expected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5890</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5890"/>
				<updated>2023-10-20T19:19:04Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Adding clocks for X440&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X440====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 0 || Daughterboard 0 master clock rate divided by 8 (e.g., 62.5 MHz if master clock rate is 500 MHz)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt; || Radio interface clock for daughterboard 1 || Daughterboard 1 master clock rate divided by 8&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio0_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 0 || Twice the frequency of &amp;lt;code&amp;gt;radio0&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio1_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x for daughterboard 1 || Twice the frequency of &amp;lt;code&amp;gt;radio1&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5889</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5889"/>
				<updated>2023-10-14T21:29:08Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Fix N32x rfnoc_chdr clock frequency&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5888</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5888"/>
				<updated>2023-10-14T21:27:49Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add RFNoC control clock&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 93.75 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; || RFNoC Control clock || 40 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5887</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5887"/>
				<updated>2023-10-14T21:16:15Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Fixed N300/N310 DRAM clock rate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5842</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5842"/>
				<updated>2023-08-18T21:45:24Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add X440 memory performance numbers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 3360 || 798 || 784 || 616 || 461&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 8118 || 2007 || 2007 || N/A || N/A&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# X410 with 400 MHz bandwidth uses two independent memory banks, with channels 0-1 on Bank 0, and channels 2-3 on Bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 4-channel configuration has the same performance as a 2-channel configuration.&lt;br /&gt;
# X440 uses two independent memory banks. For 400 MHz, channels 0-3 are on Bank 0 and channels 4-7 are on Bank 1 by default. For 1600 MHz, channel 0 is on Bank 0 and channel 1 is on bank 1 by default. The traffic flows on Bank 0 and Bank 1 are independent and do not affect each other. Therefore, a 2-channel configuration has the same performance as a 1-channel configuration.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5841</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5841"/>
				<updated>2023-08-17T22:00:36Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add X440 memory parameters&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 8 x 128-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.4 GT/s (19.2 GB/s) per bank&amp;lt;br&amp;gt;(38.4 GB/s total) || 2 x 512-bit @ 300 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The default DRAM configuration used for X410 and X440 changes depending on the configured bandwidth. The default parameters to use for each image type is shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || 128 || 32 || 8&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || 512 || 32 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (400 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000, 32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X440 (1600 MHz BW) || &amp;quot;300e6&amp;quot; || &amp;quot;{32'h00000000, 32'h00000000}&amp;quot; || &amp;quot;{32'hFFFFFFFF, 32'hFFFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5827</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5827"/>
				<updated>2023-08-04T15:15:01Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add FAQ section related to building FPGA images&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Can I use a different Vivado version from the one required by my UHD version? ===&lt;br /&gt;
&lt;br /&gt;
This is technically possible, but it can be a lot of work to convert and adapt all of the IP to a new Vivado version, and your custom combination of UHD and Vivado versions will not have been tested or validated by Ettus Research. Therefore, this is not recommended or supported.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;br /&gt;
&lt;br /&gt;
== Building FPGA Images ==&lt;br /&gt;
&lt;br /&gt;
=== Why did my FPGA build fail to meet timing constraints? ===&lt;br /&gt;
&lt;br /&gt;
FPGAs have clocks that trigger the transfer of data between internal registers. The Vivado tool does a timing check near the end of the build to ensure that the paths from each driving register or port to each receiving register or port are not too long for the specified clock period or delay constraints. When it says &amp;quot;The design did not satisfy timing constraints&amp;quot; it means that Vivado couldn't arrange the logic on the chip in a way that meets all requirements. There are several reasons this might happen:&lt;br /&gt;
&lt;br /&gt;
* You added new logic to the design with too much logic between registers. In this case, you should modify your design to make meeting timing easier.&lt;br /&gt;
* You added new logic, but made a mistake in which you're trying to use the wrong clock or reset, which makes it difficult to meet timing. In this case you need to correct the mistake in your design.&lt;br /&gt;
* The design has become too crowded, making it difficult for the tools to meet the timing requirements. In this case you need to remove something to make more room.&lt;br /&gt;
* Bad luck. The tools use pseudorandom algorithms to find solutions to really hard problems, and sometimes it doesn't find a good solution even when one is possible. In this case you can make a minor change to the design and build again to see if it does better the second time. If you don't change anything, Vivado will normally give you identical results for each build. In UHD 4.4 and later you can add the &amp;lt;code&amp;gt;BUILD_SEED=1&amp;lt;/code&amp;gt; option to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments to change a build seed that will affect the build results. Using a different seed number for each build will ensure that you get a unique build result each time. 0 is the default seed if not specified. Random build failures occur occasionally for some FPGA targets, in which case you should retry the build with a different seed.&lt;br /&gt;
&lt;br /&gt;
The FPGA tools produce a timing report that says exactly which path failed to meet timing. Sometimes that can point you in the right direction. But sometimes the path indicated only failed because of another path that's even more difficult. Open &amp;lt;code&amp;gt;post_route_timing_summary.rpt&amp;lt;/code&amp;gt; in the build output folder and search for &amp;quot;(VIOLATED)&amp;quot; to find the path(s) that failed.&lt;br /&gt;
&lt;br /&gt;
=== My design doesn't fit in the FPGA. What can I do to reduce the size? ===&lt;br /&gt;
&lt;br /&gt;
Read the &amp;lt;code&amp;gt;post_synth_util.rpt&amp;lt;/code&amp;gt; to determine what resource(s) you are running out of in order to know what kinds of changes are needed. Below are several easy ways to reduce the resource utilization of the FPGA.&lt;br /&gt;
&lt;br /&gt;
* If you are not using all RF channels of your device, modify the FPGA YAML file to remove the DDC, DUC, and Radio blocks for the unused channels, then regenerate the FPGA code using &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt;. Note that you may need at least one Radio block for RFNoC to work properly. You may also remove the DDC and/or the DUC if your application uses full bandwidth for one or more channels and therefore doesn't require up or down conversion.&lt;br /&gt;
* If you are not using DRAM, remove the Replay or DMA FIFO blocks. Also, on X4xx, change the &amp;lt;code&amp;gt;DRAM_CH&amp;lt;/code&amp;gt; variable to 0 in the Makefile for the FPGA target you are building.&lt;br /&gt;
* If you do not need all SFP ports, use a build target that matches your needs. For example, on X4xx, the &amp;quot;X1&amp;quot; option (one 10 Gbps lane) uses the least resources whereas &amp;quot;X4&amp;quot; (four 10 Gbps lanes) uses a lot more, and the &amp;quot;CG&amp;quot; option (four 25 Gbps lanes) uses the most.&lt;br /&gt;
* If you do not need the full bandwidth of the device, use a smaller bandwidth option. For example, on X410, the &amp;quot;_100&amp;quot; option (100 MHz bandwidth) uses less resources than the &amp;quot;_200&amp;quot; option (200 MHz bandwidth).&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;crossbar_routes&amp;lt;/code&amp;gt; definition to the FPGA YAML file to include only the crossbar paths required for your application. This is an advanced feature in UHD 4.5 and later. This must be done carefully to avoid removing essential paths. See the X440 YAML files for examples.&lt;br /&gt;
&lt;br /&gt;
Other reductions are possible but require advanced knowledge of UHD and/or RFNoC to avoid breaking key functionality of the device.&lt;br /&gt;
&lt;br /&gt;
=== How do I create a Vivado project for my FPGA build? ===&lt;br /&gt;
&lt;br /&gt;
Vivado supports two modes of operation known as &amp;quot;project mode&amp;quot; and &amp;quot;non-project mode&amp;quot;. Project mode is more user-friendly because it creates a project file that is managed by Vivado and works natively in the Vivado GUI. Non-project mode is generally used by more advanced users who want full control over the Vivado build process and is typically used in fully scripted or automated build flows. The USRP build flow in UHD uses non-project mode. As a result, there is no Vivado project file by default.&lt;br /&gt;
&lt;br /&gt;
It is possible to create a project file from the USRP build flow with the following steps:&lt;br /&gt;
&lt;br /&gt;
# Start the USRP FPGA build in the GUI by adding &amp;lt;code&amp;gt;GUI=1&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; arguments. Example:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;make X410_X4_200 GUI=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# After the build completes, run the following command in the TCL Console of Vivado to create the project file and switch to project mode:&amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;save_project_as project_name project_dir&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;In this example, &amp;quot;project_name&amp;quot; is the name you want to give the project file and &amp;quot;project_dir&amp;quot; is the directory in which you want to put the project.&lt;br /&gt;
# Set the compile order to automatic: &amp;lt;br/&amp;gt;&amp;lt;code&amp;gt;set_property source_mgmt_mode All [current_project]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This project file can now be used independently of the normal FPGA build flow in UHD. It is up to the user to update this project file as the design changes since it will not be managed by the normal build flow in UHD.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA takes a long time to build. What can I do to make builds faster? ===&lt;br /&gt;
&lt;br /&gt;
High-performance computers are recommended for FPGA builds since an FPGA build can take several hours.&lt;br /&gt;
&lt;br /&gt;
The build process is divided into two steps, IP generation and the FPGA build.&lt;br /&gt;
&lt;br /&gt;
==== IP Generation ====&lt;br /&gt;
&lt;br /&gt;
This process can take several hours by default and is run automatically, if needed, when you build an FPGA target. Fortunately, this only needs to be done once for each USRP type and won't run again unless IP is changed.&lt;br /&gt;
&lt;br /&gt;
You can speed up the IP generation by running this step with multiple jobs. For example:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 4 X410_IP&lt;br /&gt;
&lt;br /&gt;
This example will build four IP cores at a time. Note that this generally requires 4 times as much memory and needs at least 4 CPU cores. You can adjust the number of parallel jobs based on the amount of system memory and/or CPU cores you have available.&lt;br /&gt;
&lt;br /&gt;
==== FPGA Build ====&lt;br /&gt;
&lt;br /&gt;
Unfortunately, increasing the number of jobs does not speed up FPGA performance because there is only one Vivado instance for the FPGA build. Vivado, by default, will use multiple CPU cores, where possible, but this does not significantly improve build performance since many parts of the build are not easily parallelizable.&lt;br /&gt;
&lt;br /&gt;
One way to shorten the build time is to reduce the size of the design. See above on how to reduce the size of your design.&lt;br /&gt;
&lt;br /&gt;
In the case where you need to build multiple FPGA types, you can use the jobs option with &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; to build multiple FPGAs simultaneously, which can dramatically reduce the time required per build. Note that this requires a significant amount of memory and CPU cores and therefore is only recommended for systems that can handle such loads. An example is shown below for building two FPGA images in parallel:&lt;br /&gt;
&lt;br /&gt;
    $ make -j 2 X410_X4_200 X410_CG_400&lt;br /&gt;
&lt;br /&gt;
It is also possible to open separate terminal instances and run one build in each instance to get the same effect. Do not build the same FPGA target in multiple instances, since multiple builds for the same target would conflict as they try to access and update the same files.&lt;br /&gt;
&lt;br /&gt;
=== My FPGA build failed with a cryptic message or no message at all. How do I debug this? ===&lt;br /&gt;
&lt;br /&gt;
Check the &amp;lt;code&amp;gt;build.log&amp;lt;/code&amp;gt; in the FPGA build folder for clues that may not have been printed to the console.&lt;br /&gt;
&lt;br /&gt;
Builds often fail when Vivado encounters an internal error or runs out of memory. For internal errors, the error message is typically not very helpful and is often due to a bug in Vivado. When Vivado runs out of memory, it may immediately terminate without giving any error message at all. Consider monitoring the memory usage during the FPGA build to see if you are approaching your system's limit.&lt;br /&gt;
&lt;br /&gt;
If you have made changes to the design, try building an unmodified FPGA image from scratch to ensure the build process is working properly on your system. If this works, try adding your changes incrementally until the section of code causing the problem is identified.&lt;br /&gt;
&lt;br /&gt;
Note that such errors are often beyond the control of Ettus Research and reaching out to Xilinx support is a better option if it is truly a Vivado issue.&lt;br /&gt;
&lt;br /&gt;
=== I get a warning saying that an IP is locked, which results in errors later in the IP generation process. How do I resolve this? ===&lt;br /&gt;
&lt;br /&gt;
Vivado &amp;quot;locks&amp;quot; IP, for example, when it needs to be updated for the running version of Vivado or FPGA device type. This is intended to force the user to fix the issue and to avoid building incompatible IP. Build failures related to IP being locked should never occur during a normal build. The IP version in the UHD repo always matches the Vivado version required for that release of UHD.&lt;br /&gt;
&lt;br /&gt;
This can happen if you have used the wrong version of Vivado or do not have the correct Vivado patches installed. Refer to the &amp;lt;code&amp;gt;Generation 3 USRP Build Documentation&amp;lt;/code&amp;gt; section of the [[UHD and USRP User Manual|UHD Manual] for the required version and patches. When you run the `source setenv.sh` step to setup your environment, the script will check to make sure you are using the correct version.&lt;br /&gt;
&lt;br /&gt;
In some cases, reinstalling Vivado might be required.&lt;br /&gt;
&lt;br /&gt;
Once the correct Vivado version and patches are installed, you will need to remove all build products (to remove any locked IP that was generated) and retry the build. For example:&lt;br /&gt;
&lt;br /&gt;
    $ source setupenv.sh     # Setup environment and check the Vivado version&lt;br /&gt;
    $ make cleanall          # Remove any bad IP that was generated&lt;br /&gt;
    $ make X410_X4_200       # Start the build process again&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=UHD_and_USRP_User_Manual&amp;diff=5826</id>
		<title>UHD and USRP User Manual</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=UHD_and_USRP_User_Manual&amp;diff=5826"/>
				<updated>2023-08-03T21:51:31Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added link to the manual archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Software'''&lt;br /&gt;
* [https://files.ettus.com/manual/ UHD Manual (master)]&lt;br /&gt;
* [https://files.ettus.com/manual_archive/ UHD Manual Archive (previous releases)]&lt;br /&gt;
&lt;br /&gt;
'''Motherboards'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_b200.html  B200/B210/B200mini/B205mini]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_x3x0.html X300/X310]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp2.html N200/N210]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_e3x0.html E310/E312]&lt;br /&gt;
&lt;br /&gt;
'''Daughterboards'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_basictx BasicRX/LFRX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_basicrx BasicTX/LFTX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_cbx CBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_sbx SBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_wbx WBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_wbx UBX]&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_octoclock.html OctoClock]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5813</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5813"/>
				<updated>2023-06-12T22:16:21Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (Per Channel)&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_Development&amp;diff=5801</id>
		<title>Getting Started with RFNoC Development</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_Development&amp;diff=5801"/>
				<updated>2023-04-19T13:40:12Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Fix link to mailing list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
&lt;br /&gt;
'''AN-823'''&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2016-07-12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Martin Braun&amp;lt;br&amp;gt; Nicolas Cuervo&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-01-10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Team&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added “Digital Gain” example&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-05-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Updated example code. Update to Testbench section.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-08-26&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Updated following sections: '''Abstract'''(This AN is specific to USRP X300/X310), '''Using a graphical interface'''(updated GUI image with newest version and the explanation section), '''Testing out the custom block'''(Updated GRC image that has correct Sampling Rate for RFNoC:Radio block).&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-09-07&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added link to Video that follows this App Note in the Resources section. Also [https://youtube.com/watch?v=j-EfyPVpaJ8 here]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2019-10-24&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Fixed list of USRPs that this AN is applicable to: all current 3rd generation USRP hardware.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
'''Note:''' This application note applies to UHD 3.x and does not cover UHD 4.x. For UHD 4.x, see [[Getting Started with RFNoC in UHD 4.0]].&lt;br /&gt;
&lt;br /&gt;
This application note guides a user through basic information on the RFNoC architecture, installing necessary software to develop custom RFNoC blocks, also called Computation Engines (CE), and walks through the steps of creating a custom RFNoC block using an example. RFNoC is currently supported on any 3rd generation USRP hardware, currently: E310/E312, E320, N300/N310/N320/N321, and X300/X310.  '''However''', this document primarily covers using RFNoC for the USRP X300/X310 and E310/E312. Using RFNoC with the other USRPs is similar to that documented herein.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
First sections deal with installing tools and validating correct tool installation in order to do RFNoC development. Later sections deal with creating a custom RFNoC block, using the built-in testbench architecture, building an FPGA image with the custom block and finally testing out the new block within GNU Radio.&lt;br /&gt;
&lt;br /&gt;
==Licensing==&lt;br /&gt;
The RFNoC code base is open source, including code that executes on the host, as well as code targeted to the USRP hardware (FPGA and microcontroller firmware). RFNoC is available under the open-source GNU Lesser General Public License (LGPL). For more information on our licensing policy, please contact [mailto:info@ettus.com info@ettus.com].&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
RFNoC is only supported on 3rd generation USRP hardware as noted in the Abstract.&lt;br /&gt;
&lt;br /&gt;
In order to build custom USRP FPGA images and RFNoC blocks the following hardware and software are needed.&lt;br /&gt;
&lt;br /&gt;
* '''Ubuntu 14.04.5 or 16.04.1 (preferred):''' Currently PyBOMBS (which can be used to install the ''Software build tools''), works most reliably in Ubuntu, and thus, we recommend using this distribution. Also, a majority of the scripts used during the build process are Linux (Ubuntu) specific. A PC with multiple cores and 8GB+ of RAM is recommended.&lt;br /&gt;
&lt;br /&gt;
* '''Xilinx Vivado tools (version 2017.4):''' The specific version depends on the branch and state of the FPGA code. The default install location is &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;. Once all of the Software build tools are installed the specific version for the downloaded code can be found in the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{DEVICE}&amp;lt;/code&amp;gt; directory. Further information can be found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here].&lt;br /&gt;
&lt;br /&gt;
* '''Software build tools:''' If UHD can be or has been compiled from source on the development PC then all the necessary software build components are present (PyBOMBS can be used to set all this up and instructions on how to do so are given in a following step).&lt;br /&gt;
&lt;br /&gt;
* Any 3rd generation USRP hardware as noted in the Abstract.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:'''&lt;br /&gt;
* The edition of Xilinx Vivado that is required will depend on which USRP device is being used.&lt;br /&gt;
** X3xx series devices: Design Edition or System Edition.&lt;br /&gt;
** E3xx series devices: Design Edition, System Edition, or the free WebPack Edition.&lt;br /&gt;
* Other operating systems can be used, but the exact steps on how to proceed are not given in this Application Note.&lt;br /&gt;
* In some Linux distributions (e.g. Ubuntu) &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; is set as default shell, which may cause some issues. It is recommended to set the shell to &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt; by running the following commands in the terminal. Choose &amp;lt;code&amp;gt;&amp;lt;No&amp;gt;&amp;lt;/code&amp;gt; when prompted by the first command and the second command will validate the that bash will be used.&lt;br /&gt;
&lt;br /&gt;
    $ sudo dpkg-reconfigure dash&lt;br /&gt;
    $ ll /bin/sh&lt;br /&gt;
&lt;br /&gt;
==Creating a development environment==&lt;br /&gt;
While this Application Note goes through the process of integrating GNU Radio into the RFNoC development flow, it is by no means required to use or develop within the RFNoC framework, but it makes it a great deal easier to use a framework on top of RFNoC for aspects such as visualization and other features. GNU Radio is freely available and more information about it can be found [http://gnuradio.org/ here].&lt;br /&gt;
&lt;br /&gt;
The following software packages are required in order to setup a development environment/sandbox:&lt;br /&gt;
&lt;br /&gt;
* UHD&lt;br /&gt;
* GNU Radio &lt;br /&gt;
* gr-ettus&lt;br /&gt;
&lt;br /&gt;
===Create development environment using PyBOMBS===&lt;br /&gt;
The cleanest way to set this up is to install everything into a dedicated directory. [https://github.com/gnuradio/pybombs PyBOMBS] is the simplest way to do this. If not already installed, PyBOMBS can be setup with the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt-get install git&lt;br /&gt;
    $ sudo apt-get install python-setuptools python-dev python-pip build-essential &lt;br /&gt;
    &lt;br /&gt;
    $ sudo pip install git+https://github.com/gnuradio/pybombs.git&lt;br /&gt;
    $ pybombs recipes add gr-recipes git+https://github.com/gnuradio/gr-recipes.git&lt;br /&gt;
    $ pybombs recipes add ettus git+https://github.com/EttusResearch/ettus-pybombs.git&lt;br /&gt;
&lt;br /&gt;
These commands will do the following:&lt;br /&gt;
* Install &amp;lt;code&amp;gt;Git&amp;lt;/code&amp;gt;&lt;br /&gt;
* Install &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; and other Python dependencies&lt;br /&gt;
* Install the latest &amp;lt;code&amp;gt;PyBOMBS&amp;lt;/code&amp;gt; from its Git repository&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;gr-recipes&amp;lt;/code&amp;gt; recipes which are used to install GNU Radio specific software&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;ettus&amp;lt;/code&amp;gt; recipes which are used to install Ettus Research specific software&lt;br /&gt;
&lt;br /&gt;
From here, PyBOMBS can be used to setup and install the development environment/sandbox by running the following command:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs prefix init ~/rfnoc -R rfnoc -a rfnoc&lt;br /&gt;
&lt;br /&gt;
This will do the following:&lt;br /&gt;
&lt;br /&gt;
* Create a directory in the user’s home directory called &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; (any valid directory name will work)&lt;br /&gt;
&lt;br /&gt;
* Give the prefix an alias of &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; ( &amp;lt;code&amp;gt;[-a alias]&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;–a rfnoc&amp;lt;/code&amp;gt; ), which would be the name given to this path. This name will be used in further steps that use PyBOMBS. When creating the first prefix and omitting the alias, the prefix will be setup as the default.&lt;br /&gt;
&lt;br /&gt;
* Use the &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; prefix recipe ( as opposed to a package recipe like &amp;lt;code&amp;gt;gqrx&amp;lt;/code&amp;gt; ) to clone UHD, FPGA, GNU Radio, and gr-ettus sources into the &amp;lt;code&amp;gt;~/rfnoc&amp;lt;/code&amp;gt; directory as well as compile and install all the software&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' A user can specify how many cores are used by builds when using PyBOMBS. The default is set to 4. For example, this will set the number of cores used to 3:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs config makewidth 3&lt;br /&gt;
&lt;br /&gt;
The value will be written into a configuration file and then applied to subsequent PyBOMBS commands. This value can temporarily be overridden for a specific build by specifying the &amp;lt;code&amp;gt;--config makewidth=X&amp;lt;/code&amp;gt; argument, where “&amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;” is an integer number. If the user only has 4 cores it is recommend to use this argument in the pybombs command to limit the number of cores to &amp;lt;4 (e.g. 3) so that the computer stays responsive. Following are 2 examples, one using less cores and the other using more cores:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs --config makewidth=3 prefix init ~/rfnoc -R rfnoc -a rfnoc &lt;br /&gt;
    $ pybombs --config makewidth=7 prefix init ~/rfnoc -R rfnoc -a rfnoc&lt;br /&gt;
&lt;br /&gt;
Then, it is necessary to setup the PyBOMBS environment, so that the system/terminal session will have the environmental variables pointing to this newly created prefix, which is done with the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ cd ~/rfnoc&lt;br /&gt;
    $ source ./setup_env.sh&lt;br /&gt;
&lt;br /&gt;
Once the previous command is run, this terminal session will have access to the environmental variables that allow the complete use of the set of software that was just installed with PyBOMBS. If access to the software is needed in other terminals the same command must be run within them.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Throughout the rest of this document the term &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; will used at the beginning of different directories. For example, &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&amp;lt;/code&amp;gt; is a directory that contains useful scripts for compiling. The term &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; is used to denote the folders that precede the &amp;lt;code&amp;gt;/src&amp;lt;/code&amp;gt; directory. Examples of what &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; could be: &amp;lt;code&amp;gt;/home/user/rfnoc&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;/home/user/myDevfolder/&amp;lt;/code&amp;gt;. On many Linux environments using &amp;lt;code&amp;gt;~/&amp;lt;/code&amp;gt; at the beginning of the target directory path is equivalent to the user’s home directory.( i.e &amp;lt;code&amp;gt;~/&amp;lt;/code&amp;gt; is equal to &amp;lt;code&amp;gt;/home/user/&amp;lt;/code&amp;gt;). So &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; could also look like &amp;lt;code&amp;gt;~/rfnoc&amp;lt;/code&amp;gt;  or &amp;lt;code&amp;gt;~/myDevfolder/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Create the development environment manually===&lt;br /&gt;
As an alternative to using PyBOMBS, manually installing and configuring the software is done by following the individual install notes for [http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGRFromSource GNU Radio], [https://files.ettus.com/manual/page_build_guide.html UHD] and [https://github.com/EttusResearch/gr-ettus gr-ettus] and by making sure they are reachable by linkers and compilers.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The Application Note found [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux here] goes through the process of manually installing UHD and GNU Radio on Linux platforms.&lt;br /&gt;
&lt;br /&gt;
To manually download the software, use these &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; commands, which will select the correct branches:&lt;br /&gt;
&lt;br /&gt;
    $ git clone --recursive -b rfnoc-devel https://github.com/EttusResearch/uhd.git &lt;br /&gt;
    $ git clone --recursive -b maint https://github.com/gnuradio/gnuradio.git # master branch is also fine instead of maint&lt;br /&gt;
    $ git clone -b master https://github.com/EttusResearch/gr-ettus.git &lt;br /&gt;
    $ git clone -b rfnoc-devel https://github.com/EttusResearch/fpga.git&lt;br /&gt;
&lt;br /&gt;
If UHD, GNU Radio and/or gr-ettus are already installed, it would be sufficient to checkout the branches mentioned and update them them (&amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;). Thereafter, rebuild each of the repositories (rebuild order: UHD, GNU Radio, gr-ettus).&lt;br /&gt;
&lt;br /&gt;
===Verify Environment===&lt;br /&gt;
Running the command “&amp;lt;code&amp;gt;uhd_config_info&amp;lt;/code&amp;gt;” with the “&amp;lt;code&amp;gt;--version&amp;lt;/code&amp;gt;” flag will verify that the installation has been completed successfully.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The version string output from this command may differ, however it should be similar to the output below.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_config_info --version&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-161- g83150fdd&lt;br /&gt;
    &lt;br /&gt;
    4.0.0.rfnoc-devel-161-g83150fdd&lt;br /&gt;
&lt;br /&gt;
===Testing the default FPGA image and building from existing blocks===&lt;br /&gt;
&lt;br /&gt;
It is recommended to spend a moment looking at the Ettus Research default image, which is pre-built with a set of RFNoC blocks, as well as building a custom image with a unique set of pre-built RFNoC blocks. To get the default image(s), run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_images_downloader&lt;br /&gt;
&lt;br /&gt;
Ettus Research will be updating the default image(s) occasionally, and &amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt; can be run anytime after running &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt; and re-installing to pull the most current images. Images are stored in the &amp;lt;code&amp;gt;{USER_PREFIX}/share/uhd/images&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
The following images have the corresponding RFNoC blocks (Computation Engines):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Image Name&lt;br /&gt;
!Included Blocks&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x300_fpga_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x300_fpga_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;2x DDC, 2x DUC&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x300_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x300_fpga_RFNOC_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;DUC, DDC (one channel), fosphor, window, fft, 2x AXI FIFOs&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;DUC, DDC (one channel), fosphor, window, fft, 2x AXI FIFOs, Keep One in N, FIR, Siggen&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_e310_fpga.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_e310_fpga_sg3.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;1x DDC, 1x DUC&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_e310_fpga_RFNOC.bit (sg1 version)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_e310_fpga_RFNOC_sg3.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;fosphor, window, fft, 2x AXI FIFOs, FIR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Instructions on flashing the image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
  &lt;br /&gt;
'''NOTE:''' FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device.&lt;br /&gt;
&lt;br /&gt;
By following the steps above the following should now be available:&lt;br /&gt;
* UHD/RFNoC code downloaded and installed&lt;br /&gt;
* FPGA code available&lt;br /&gt;
* A valid RFNoC image on your X3xx or E3xx series device&lt;br /&gt;
&lt;br /&gt;
====Inspect default images====&lt;br /&gt;
Run the following command, with a USRP connected to your PC, to verify current image on the USRP.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe&lt;br /&gt;
&lt;br /&gt;
If an RFNoC image was successfully loaded onto the USRP, there will be a lot of output text (RFNoC code is currently very verbose). The final lines of the output should be similar to the following for an USRP X310 ( e.g. &amp;lt;code&amp;gt;usrp_x310_fpga_HG&amp;lt;/code&amp;gt; ):&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * DDC_1&lt;br /&gt;
    |   |   |   * DUC_0&lt;br /&gt;
    |   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Final output for &amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt; image:&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * DUC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * Window_0&lt;br /&gt;
    |   |   |   * FIR_0&lt;br /&gt;
    |   |   |   * SigGen_0&lt;br /&gt;
    |   |   |   * KeepOneInN_0&lt;br /&gt;
    |   |   |   * fosphor_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The actual names and number of blocks can differ. The list of blocks should start with the &amp;lt;code&amp;gt;DmaFIFO_x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Radio_x&amp;lt;/code&amp;gt;, and then a couple more lines of block IDs should follow.&lt;br /&gt;
&lt;br /&gt;
====Build custom image with pre-built RFNoC blocks====&lt;br /&gt;
Because of the growing number of RFNoC blocks, the user has the option to build an FPGA image with a set of pre-built RFNoC blocks of their choosing. The following steps describe the process for doing this and by so doing will also validate proper tool installation. Because compilation can take a couple of hours, it is recommended the user begin this process while continuing the rest of this guide.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' FPGA compilations can run in the background, however they are very resource intensive. If the user intents to use the same computer that is compiling to walk through the rest of this Application Note, it is recommended that the computer has plenty of resources.&lt;br /&gt;
&lt;br /&gt;
The script to initiate a compile is called &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt;, and is located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&amp;lt;/code&amp;gt; directory. Run the help menu by typing:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts &lt;br /&gt;
    $ ./uhd_image_builder.py --help&lt;br /&gt;
&lt;br /&gt;
A more detailed discussion of this script is given in an upcoming section. For now, compiling an FPGA image that has 2 RFNoC blocks (&amp;lt;code&amp;gt;window&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fft&amp;lt;/code&amp;gt;) and some &amp;lt;code&amp;gt;FIFOs&amp;lt;/code&amp;gt;, is done by running the script with the following arguments.&lt;br /&gt;
&lt;br /&gt;
Example for an X310 USRP:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py window fft -d x310 -t X310_RFNOC_HG -m 5 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
Example for an E310 USRP with Speed Grade 3 (sg3) FPGA:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py window fft -d e310 -t E310_RFNOC_sg3 -m 5 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
At the end of a successful compilation process, write the new image to a USRP. If the image was compiled for a USRP X310, the following command will load the new image. Update the &amp;lt;code&amp;gt;{IP_Address}&amp;lt;/code&amp;gt; of the USRP and &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; to the appropriate values for your configuration before running the command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=x300,addr={IP_ADDRESS}&amp;quot; --fpga-path {USER_PREFIX}/src/uhd-fpga/usrp3/top/x300/build/usrp_x310_fpga_RFNOC_HG.bit&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. Additional instructions on flashing a custom image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
&lt;br /&gt;
After the image has been successfully written to the USRP, power-cycle it and run the “&amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;” utility to view the newly compiled blocks.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe&lt;br /&gt;
&lt;br /&gt;
The final lines of output for the image built for the X310 is as follows:&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * Window_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
===Getting started with UHD + RFNoC===&lt;br /&gt;
The following new examples included within the &amp;lt;code&amp;gt;rfnoc-devel&amp;lt;/code&amp;gt; branch of UHD, are a good reference on how to use RFNoC from UHD.&lt;br /&gt;
&lt;br /&gt;
The following example is based off of &amp;lt;code&amp;gt;rx_samples_to_file.cpp&amp;lt;/code&amp;gt;. The example can be configured to place an RFNoC block in between the radio and host.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_rx_to_file.cpp&lt;br /&gt;
&lt;br /&gt;
This next example chains a null source to another block and streams the data to the host.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_nullsource_ce_rx.cpp&lt;br /&gt;
&lt;br /&gt;
These examples demonstrate the core features and flexibility of RFNoC.&lt;br /&gt;
&lt;br /&gt;
For more information on UHD and UHD development please refer to the [https://kb.ettus.com/UHD UHD Software Resource page], [https://kb.ettus.com/Getting_Started_with_UHD_and_C%2B%2B Getting Started with UHD and C++ Application Note] or directly to the [http://files.ettus.com/manual/ UHD user manual].&lt;br /&gt;
&lt;br /&gt;
===Getting started with GNU Radio + RFNoC===&lt;br /&gt;
A good way of getting started with RFNoC in a more visual way is to use GNU Radio. The &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; out-of-tree module (OOT) allows a user to use RFNoC blocks in their local GNU Radio / GNU Radio Companion (GRC) installation. This GNU Radio OOT contains blocks that allow you to configure your FPGA through GRC.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' As blocks in the &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; OOT mature, they will be upstreamed to &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt;. Also, &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; is a container used by Ettus Research to disseminate experimental or under-development features for &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt;. It is not a replacement for &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt; (in fact, the latter is a requirement for &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;).&lt;br /&gt;
    &lt;br /&gt;
Examples can be run from &amp;lt;code&amp;gt;gr-ettus/examples/rfnoc&amp;lt;/code&amp;gt;, provided that the appropriate RFNoC blocks are compiled into the FPGA image currently running on the USRP.&lt;br /&gt;
&lt;br /&gt;
A couple of rules for building GNU Radio flowgraphs with RFNoC blocks:&lt;br /&gt;
&lt;br /&gt;
* You always need a &amp;lt;code&amp;gt;Device3&amp;lt;/code&amp;gt; object in your flow graph (it does not get connected, see screenshot below).&lt;br /&gt;
* You should have at least two RFNoC blocks connected together. Going &amp;lt;code&amp;gt;GNU Radio Block&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;RFNoC Block&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;GNU Radio Block&amp;lt;/code&amp;gt; is not recommended (it will work, but with suboptimal performance).&lt;br /&gt;
&lt;br /&gt;
The GNU Radio flowgraph &amp;lt;code&amp;gt;rfnoc_ddc.grc&amp;lt;/code&amp;gt; is an example that can be run using the default RFNoC image. Below are screenshots of the flowgraph and what it produces.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 1.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Copy Block: In the RFNoC domain, streams of data can not be split as easily as they are in the GNU Radio domain. The “copy” block depicted in the screenshot above serves the function as a stream splitter. Its main purpose, when “enabled”, is to copy the samples it is getting at its input and put them into the output, but here it is also serving as a boundary between a RFNoC-domain and a GNURadio-domain. In the flowgraph above, after this boundary is passed, the data stream can easily be split into the two sinks to have them run simultaneously (standard GNU Radio functionality). It is possible to connect the GNU Radio blocks directly to RFNoC blocks without a “copy” block, but only one would work at a time (the other ones would have to be disabled). Another way to split data streams from the RFNoC-domain is to use the ”RFNoC: split stream” block, which would split the streams in the RFNoC domain, but this is not very useful here as we are, in any case, moving into the GNURadio-domain.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 2.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
For more information on GNURadio development please refer to the [http://gnuradio.org/doc/doxygen/ GNURadio user's manual and API].&lt;br /&gt;
&lt;br /&gt;
==Starting a custom RFNoC block using RFNoC Modtool==&lt;br /&gt;
The figure below shows the basic structure of the RFNoC Stack. Corresponding code is needed in each of the three sections in order to build a custom RFNoC block with GNU Radio integration. A tool called RFNoC Modtool was created in order to minimize the effort needed to implement a new RFNoC block. RFNoC Modtool creates a custom GNU Radio OOT module with the basic structure and the necessary files for each of these sections. RFNoC Modtool is currently a part of the GNU Radio OOT module &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 3.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
===RFNoC Modtool Utilization===&lt;br /&gt;
'''NOTE:''' Console outputs may vary depending on the version of UHD the user is running. However, functionality should be the same or similar.&lt;br /&gt;
&lt;br /&gt;
Because the RFNoC Modtool has similar functionality to the &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt; [ [http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules gr_modtool] ] provided by GNU Radio, those that have worked with &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt; in the past will find the RFNoC Modtool familiar.&lt;br /&gt;
&lt;br /&gt;
To check the usage of the tool, run the following:&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool help&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    Usage:&lt;br /&gt;
    rfnocmodtool &amp;lt;command&amp;gt; [options] -- Run &amp;lt;command&amp;gt; with the given options.&lt;br /&gt;
    rfnocmodtool help -- Show a list of commands.&lt;br /&gt;
    rfnocmodtool help &amp;lt;command&amp;gt; -- Shows the help for a given command. &lt;br /&gt;
    &lt;br /&gt;
    List of possible commands:&lt;br /&gt;
    &lt;br /&gt;
    Name      Aliases          Description&lt;br /&gt;
    =====================================================================&lt;br /&gt;
    disable   dis              Disable block (comments out CMake entries for files) &lt;br /&gt;
    info      getinfo,inf      Return information about a given module &lt;br /&gt;
    remove    rm,del           Remove block (delete files and remove Makefile entries) &lt;br /&gt;
    makexml   mx               Make XML file for GRC block bindings &lt;br /&gt;
    add       insert           Add block to the out-of-tree module. &lt;br /&gt;
    newmod    nm,create        Create a new out-of-tree module &lt;br /&gt;
    rename    mv               Rename a block in the out-of-tree module.&lt;br /&gt;
&lt;br /&gt;
===Creating an RFNoC OOT Module===&lt;br /&gt;
&lt;br /&gt;
To start generating an RFNoC OOT module navigate to the source location ( i.e. &amp;lt;code&amp;gt;cd ~/{USER_PREFIX}/src&amp;lt;/code&amp;gt; ) and type:&lt;br /&gt;
    $ rfnocmodtool newmod [NAME OF THE MODULE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;[NAME OF THE MODULE]&amp;lt;/code&amp;gt; is a name the user gives the new module. In the following, a module is created with the name “&amp;lt;code&amp;gt;tutorial&amp;lt;/code&amp;gt;”. If the user does not write the name of the module following the &amp;lt;code&amp;gt;newmod&amp;lt;/code&amp;gt; command the tool will ask for it interactively. Running this command will create a folder containing the basic folders that you may need for a functional module.&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool newmod tutorial&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    Creating out-of-tree module in ./rfnoc-tutorial... Done.&lt;br /&gt;
    Use 'rfnocmodtool add' to add a new block to this currently empty module.&lt;br /&gt;
&lt;br /&gt;
To see what files and directories were created run:&lt;br /&gt;
&lt;br /&gt;
    $ ls rfnoc-tutorial/&lt;br /&gt;
    apps  cmake  CMakeLists.txt  docs  examples  grc  include  lib  MANIFEST.md  python  README.md  rfnoc  swig&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In contrast with &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt;, this includes a folder called &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt;, which is where the UHD/FPGA files are located.&lt;br /&gt;
&lt;br /&gt;
===Adding custom blocks to OOT Module===&lt;br /&gt;
In order to add blocks to a module, navigate to the folder just created and use the &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; command of &amp;lt;code&amp;gt;rfnocmodtool&amp;lt;/code&amp;gt;. Continuing with the example above, run the following:&lt;br /&gt;
&lt;br /&gt;
    $ cd rfnoc-tutorial&lt;br /&gt;
    $ rfnocmodtool add [NAME OF THE BLOCK]&lt;br /&gt;
&lt;br /&gt;
For demonstrative purposes, a block named &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; will be created. The &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block will multiply samples that pass through it by a constant. As before, if the name is not given, the tool will ask the user for the name. There are several arguments that can be passed to the tool, but running the tool without any of these arguments will give the following interactive parsing output:&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool add gain&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    RFNoC module name identified: tutorial&lt;br /&gt;
    Block/code identifier: gain&lt;br /&gt;
    Enter valid argument list, including default arguments: &lt;br /&gt;
    Block NoC ID (Hexadecimal): 1111222233334444&lt;br /&gt;
    Skip Block Controllers Generation? [UHD block ctrl files] [y/N] N&lt;br /&gt;
    Skip Block interface files Generation? [GRC block ctrl files] [y/N] N&lt;br /&gt;
&lt;br /&gt;
Hitting &amp;lt;code&amp;gt;enter&amp;lt;/code&amp;gt; on each one of the options will take the default values.&lt;br /&gt;
&lt;br /&gt;
The following is a description of the valid argument list items:&lt;br /&gt;
&lt;br /&gt;
* '''NoC ID:''' This ID is a Hexadecimal number which serves as identification between the hardware part and the software part of the design. It can be as long as 16 0-9 A-F digits. If a NoC ID is not provided, it will be set to a random number.&lt;br /&gt;
&lt;br /&gt;
* '''Block Controllers Generation:''' The block controllers are the C++ control that the user can apply to the UHD-part of the design. In these files, the user can add more control over this layer of the design. Depending on the complexity of the block it may be possible to add all necessary control using NoCScript (more details on NoCScript can be found in the section labeled UHD Integration). In this case the cpp/hpp block control files generation are not needed. Default is to generate as their existence will be ignored if not edited.&lt;br /&gt;
&lt;br /&gt;
* '''Block Interface:''' Add more design specific functionality to the design at the GNU Radio interface by generating these block-interface files and adding necessary logic.  Depending on the complexity of the block it may be possible to add all necessary control using NoC-Script. In this case the block-interface files are not needed. Default is to generate as their existence will be ignored if not edited.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' If the user does not intend to use the block controllers or is not sure if they are needed, the presence of them in the design will do no harm. It is recommended to add them. This leaves the possibility to add more functions inside them in a future stage of development. &lt;br /&gt;
&lt;br /&gt;
After finishing the parsing, the following files will be generated/edited:&lt;br /&gt;
&lt;br /&gt;
    Adding file 'lib/gain_impl.h'...&lt;br /&gt;
    Adding file 'lib/gain_impl.cc'...&lt;br /&gt;
    Adding file 'include/tutorial/gain.h'...&lt;br /&gt;
    Adding file 'include/tutorial/gain_block_ctrl.hpp'...&lt;br /&gt;
    Adding file 'lib/gain_block_ctrl_impl.cpp'...&lt;br /&gt;
    Editing swig/tutorial_swig.i...&lt;br /&gt;
    Adding file 'python/qa_gain.py'...&lt;br /&gt;
    Editing python/CMakeLists.txt...&lt;br /&gt;
    Adding file 'grc/tutorial_gain.xml'...&lt;br /&gt;
    Adding file 'rfnoc/blocks/gain.xml'...&lt;br /&gt;
    Adding file 'rfnoc/fpga-src/noc_block_gain.v'...&lt;br /&gt;
    rfnoc/testbenches/noc_block_gain_tb folder created&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/Makefile'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/CMakeLists.txt'...&lt;br /&gt;
&lt;br /&gt;
==Creating FPGA portion of custom RFNoC Block==&lt;br /&gt;
===RFNoC FPGA User Interface (API)===&lt;br /&gt;
RFNoC blocks or Computation Engines (CEs) in the FPGA use a NoC Shell instance to interface with the rest of RFNoC. NoC Shell implements RFNoC's core functionality: packet muxing and demuxing, flow control, and the settings register bus (i.e. write/read control/status registers). The NoC Shell has an interface to the RFNoC AXI stream crossbar and a user interface. NoC Shell AXI stream interfaces expect CHDR packets with a proper header. See the manual for information on [https://files.ettus.com/manual/page_rtp.html CHDR and SID].&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' AXI Stream is an ARM AMBA standard interface. Xilinx has an [http://www.xilinx.com/support/documentation/ip_documentation/ug761_axi_reference_guide.pdf AXI Reference Guide] with more details on this standard.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 4.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Many designs will want to use an AXI Stream interface with only sample data. However, as stated earlier, the NoC Shell block expects CHDR packets. To ease interfacing user code, the AXI Wrapper block provides the necessary logic to strip and insert the CHDR header, effectively converting packetized sample data into streaming sample data and vice versa. The example RFNoC blocks &amp;lt;code&amp;gt;noc_block_fft.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;noc_block_fir.v&amp;lt;/code&amp;gt; show how AXI Wrapper is used to implement existing Xilinx AXI Stream based IP within a computation engine.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' AXI Wrapper also supports AXI Stream buses for configuration. These buses are driven via the setting register bus and do not have back pressure. They also consume two user register addresses per bus.&lt;br /&gt;
&lt;br /&gt;
The primary user interface consists of four AXI stream interfaces ( &amp;lt;code&amp;gt;tready, tvalid, tlast, tdata&amp;lt;/code&amp;gt; ) and a settings register bus ( 8-bit, valid user register addresses: &amp;lt;code&amp;gt;128-255&amp;lt;/code&amp;gt; ).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
AXI Stream signals:&lt;br /&gt;
* '''m_axis_data_tdata:''' Input sample data packets &lt;br /&gt;
** Data coming from host or another CE&lt;br /&gt;
* '''s_axis_data_tdata:''' Output sample data packets &lt;br /&gt;
** Data going to another CE or host&lt;br /&gt;
* '''m_axis_data_tready:''' Input signal to CE&lt;br /&gt;
** Used to notify CE that downstream CE is ready for data &lt;br /&gt;
* '''s_axis_data_tready:''' Output signal to CE&lt;br /&gt;
** Used to notify upstream CE that CE is ready for data &lt;br /&gt;
* '''m_axis_data_tvalid:''' Input signal to CE&lt;br /&gt;
** Used to indicate upstream CE has valid data &lt;br /&gt;
* '''s_axis_data_tvalid:''' Output signal to CE&lt;br /&gt;
** Used to indicate to downstream CE that CE has valid data &lt;br /&gt;
* '''m_axis_data_tlast:''' Input signal to CE&lt;br /&gt;
** Used to delimit packets from upstream CE &lt;br /&gt;
* '''s_axis_data_tlast:''' Output signal to CE&lt;br /&gt;
** Used to delimit packets to downstream CE&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |[[File:rfnoc gsg an 5.png|right|500px|]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 6.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
Settings Bus signals:&lt;br /&gt;
* '''set_stb:''' Assert to write '''set_data''' to register at '''set_addr'''ess&lt;br /&gt;
* '''set_addr:''' Register address to set&lt;br /&gt;
* '''set_data:''' Data to set&lt;br /&gt;
* '''rb_data:''' Data to read back&lt;br /&gt;
* '''rb_strobe:''' Assert to read '''rb_data''' from register at '''set_addr'''ess&lt;br /&gt;
&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |[[File:rfnoc gsg an 7.png|right|500px|]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
For the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; example block the following architecture is desired:&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 8.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Open the file &amp;lt;code&amp;gt;rfnoc-tutorial/rfnoc/fpga-src/noc_block_gain.v&amp;lt;/code&amp;gt; that contains the RFNoC block skeleton code that was created when the &amp;lt;code&amp;gt;$ rfnocmodtool add gain&amp;lt;/code&amp;gt; command was run and modify the following ('''BOLD''' indicates changes to the skeleton code).&lt;br /&gt;
&lt;br /&gt;
    '''localparam [7:0] SR_GAIN = SR_USER_REG_BASE;'''&lt;br /&gt;
    localparam [7:0] SR_TEST_REG_1 = SR_USER_REG_BASE + 8'd1;&lt;br /&gt;
    &lt;br /&gt;
    '''wire [15:0] gain;'''&lt;br /&gt;
    '''setting_reg #('''&lt;br /&gt;
      '''.my_addr(SR_GAIN), .awidth(8), .width(16))'''&lt;br /&gt;
    '''sr_gain ('''&lt;br /&gt;
      '''.clk(ce_clk), .rst(ce_rst),'''&lt;br /&gt;
      '''.strobe(set_stb), .addr(set_addr), .in(set_data), .out(gain), .changed());'''&lt;br /&gt;
    &lt;br /&gt;
     always @(posedge ce_clk) begin&lt;br /&gt;
        case(rb_addr)&lt;br /&gt;
          '''8'd0 : rb_data &amp;lt;= {48'd0, gain};'''&lt;br /&gt;
          8'd1 : rb_data &amp;lt;= {32'd0, test_reg_1};&lt;br /&gt;
          default : rb_data &amp;lt;= 64'h0BADC0DE0BADC0DE;&lt;br /&gt;
        endcase&lt;br /&gt;
     end&lt;br /&gt;
     &lt;br /&gt;
     '''wire [31:0] pipe_in_tdata;'''&lt;br /&gt;
     '''wire pipe_in_tvalid, pipe_in_tlast;'''&lt;br /&gt;
     '''wire pipe_in_tready;'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] pipe_out_tdata;'''&lt;br /&gt;
     '''wire pipe_out_tvalid, pipe_out_tlast;'''&lt;br /&gt;
     '''wire pipe_out_tready;'''&lt;br /&gt;
 &lt;br /&gt;
     '''// Adding FIFO to ensure Pipeline'''&lt;br /&gt;
     '''axi_fifo_flop #(.WIDTH(32+1))'''&lt;br /&gt;
     '''pipeline0_axi_fifo_flop ('''&lt;br /&gt;
       '''.clk(ce_clk),'''&lt;br /&gt;
       '''.reset(ce_rst),'''&lt;br /&gt;
       '''.clear(clear_tx_seqnum),'''&lt;br /&gt;
       '''.i_tdata({m_axis_data_tlast,m_axis_data_tdata}),'''&lt;br /&gt;
       '''.i_tvalid(m_axis_data_tvalid),'''&lt;br /&gt;
       '''.i_tready(m_axis_data_tready),'''&lt;br /&gt;
       '''.o_tdata({pipe_in_tlast,pipe_in_tdata}),'''&lt;br /&gt;
       '''.o_tvalid(pipe_in_tvalid),'''&lt;br /&gt;
       '''.o_tready(pipe_in_tready));'''  &lt;br /&gt;
 &lt;br /&gt;
     '''wire [15:0] i = pipe_in_tdata[31:16];'''&lt;br /&gt;
     '''wire [15:0] q = pipe_in_tdata[15:0];'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] i_mult_gain = i*gain;'''&lt;br /&gt;
     '''wire [31:0] q_mult_gain = q*gain;'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] mult_gain = {i_mult_gain[15:0], q_mult_gain[15:0]};'''&lt;br /&gt;
     '''axi_fifo_flop #(.WIDTH(32+1))'''&lt;br /&gt;
     '''pipeline1_axi_fifo_flop ('''&lt;br /&gt;
       '''.clk(ce_clk),'''&lt;br /&gt;
       '''.reset(ce_rst),'''&lt;br /&gt;
       '''.clear(clear_tx_seqnum),'''&lt;br /&gt;
       '''.i_tdata({pipe_in_tlast,mult_gain}),'''&lt;br /&gt;
       '''.i_tvalid(pipe_in_tvalid),'''&lt;br /&gt;
       '''.i_tready(pipe_in_tready),'''&lt;br /&gt;
       '''.o_tdata({pipe_out_tlast,pipe_out_tdata}),'''&lt;br /&gt;
       '''.o_tvalid(pipe_out_tvalid),'''&lt;br /&gt;
       '''.o_tready(pipe_out_tready));'''&lt;br /&gt;
 &lt;br /&gt;
     '''/* Output Signals */'''&lt;br /&gt;
     '''assign pipe_out_tready = s_axis_data_tready;'''&lt;br /&gt;
     '''assign s_axis_data_tvalid = pipe_out_tvalid;'''&lt;br /&gt;
     '''assign s_axis_data_tlast  = pipe_out_tlast;'''&lt;br /&gt;
     '''assign s_axis_data_tdata  = pipe_out_tdata;'''&lt;br /&gt;
&lt;br /&gt;
The following is a block diagram of the code created by the above Verilog:&lt;br /&gt;
&lt;br /&gt;
[[File:gain_block_diagram_v01.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:'''  In order to meet timing, FIFO blocks were added to either side of the Multiplication process.&lt;br /&gt;
&lt;br /&gt;
===Creating and running HDL testbenches===&lt;br /&gt;
In order to make the coding iteration process more efficient, it is recommended to create testbenches for all RFNoC blocks before compiling them into the FPGA image. This allows for flaw and/or bug detection early in the design. RFNoC Modtool provides the structure and files ( e.g. noc_block_{USER_BLOCK_NAME}_tb ) for the testbenches of each of the OOT blocks that are added with the &amp;lt;code&amp;gt;$ rfnocmodtool add&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
Below is a figure that shows the general testbench architecture  that is created by the RFNoC Modtool. This architecture allows a user to test their custom block in the exact same environment it will be placed in when it is built into the RFNoC architecture. Other benefits of the testbench architecture include:&lt;br /&gt;
* Testing through multiple blocks (e.g. FILTER -&amp;gt; FFT -&amp;gt; AVE) &lt;br /&gt;
* Testing with multiple streams (e.g. RFNoC block ADD/SUB takes 2 streams, one that will have a constant added to it and one that will have a constant subtracted from it)&lt;br /&gt;
* Data transfer abstraction (e.g. RFNoC Sim Lib API calls to &amp;lt;code&amp;gt;tb_streamer.send&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;tb_streamer.recv&amp;lt;/code&amp;gt; which take care of all the AXI stream signaling)&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 9.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The &amp;lt;code&amp;gt;noc_block_tb&amp;lt;/code&amp;gt; block is an instantiation of the &amp;lt;code&amp;gt;noc_block_export_io&amp;lt;/code&amp;gt; that is used in testbenches to communicate to the RFNoC architecture. This makes it possible to talk “RFNoC” to the user’s custom block and as such the custom block has a complete RFNoC experience (signaling, flowcontrol, addressing, etc)&lt;br /&gt;
&lt;br /&gt;
From the [[Getting Started with RFNoC Development#Adding_custom_blocks_to_OOT_Module|Adding custom blocks to OOT Module section]] where the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block was initially created, the last files generated were:&lt;br /&gt;
&lt;br /&gt;
    rfnoc/testbenches/noc_block_gain_tb folder created&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/Makefile'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/CMakeLists.txt'...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;noc_block_gain_tb&amp;lt;/code&amp;gt; is a folder generated to contain all the files related to the test bench of the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block. Each time a new OOT block is created, a new folder will be generated as well. &lt;br /&gt;
&lt;br /&gt;
Inside of this folder are the following three files:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;CMakeLists.txt:&amp;lt;/code&amp;gt; this is an empty file used, so far, only to increase the scope of the compilers.&lt;br /&gt;
* &amp;lt;code&amp;gt;noc_block_gain_tb.sv:&amp;lt;/code&amp;gt; this is a ''System Verilog'' file, in which user custom tests are to be located.  This is the '''only''' file that needs to be modified.&lt;br /&gt;
* &amp;lt;code&amp;gt;Makefile:&amp;lt;/code&amp;gt; This file determines the directives that run the simulation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;noc_block_gain_tb.sv&amp;lt;/code&amp;gt; testbench skeleton code creates the following architecture:&lt;br /&gt;
&lt;br /&gt;
[[File:testbench_arch_gain_v01.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Open the file &amp;lt;code&amp;gt;rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv&amp;lt;/code&amp;gt; and modify the following lines:&lt;br /&gt;
&lt;br /&gt;
Right under the “Verification” section:&lt;br /&gt;
&lt;br /&gt;
    initial begin : tb_main&lt;br /&gt;
      string s;&lt;br /&gt;
      logic [31:0] random_word;&lt;br /&gt;
      logic [63:0] readback;&lt;br /&gt;
      '''logic [15:0] gain;'''&lt;br /&gt;
&lt;br /&gt;
In the “Test 4 -- Write / readback user registers” section:&lt;br /&gt;
    &lt;br /&gt;
    `TEST_CASE_START(&amp;quot;Write / readback user registers&amp;quot;);&lt;br /&gt;
    random_word = $random();&lt;br /&gt;
    '''tb_streamer.write_user_reg(sid_noc_block_gain, noc_block_gain.SR_GAIN, random_word[15:0]);'''&lt;br /&gt;
    '''tb_streamer.read_user_reg(sid_noc_block_gain, 0, readback);'''&lt;br /&gt;
    '''$sformat(s, &amp;quot;User register 0 incorrect readback! Expected: %0d, Actual %0d&amp;quot;, readback[15:0], random_word[15:0]);'''&lt;br /&gt;
    '''`ASSERT_ERROR(readback[15:0] == random_word[15:0], s);'''&lt;br /&gt;
    &lt;br /&gt;
In the “Test 5 -- Test sequence” section:&lt;br /&gt;
&lt;br /&gt;
    `TEST_CASE_START(&amp;quot;Test sequence&amp;quot;);&lt;br /&gt;
    '''gain = 100;'''&lt;br /&gt;
    '''tb_streamer.write_user_reg(sid_noc_block_gain, noc_block_gain.SR_GAIN, gain);'''&lt;br /&gt;
    fork&lt;br /&gt;
      begin&lt;br /&gt;
        cvita_payload_t send_payload;&lt;br /&gt;
        for (int i = 0; i &amp;lt; SPP/2; i++) begin&lt;br /&gt;
          send_payload.push_back(64'(i));&lt;br /&gt;
        end&lt;br /&gt;
        tb_streamer.send(send_payload);&lt;br /&gt;
      end&lt;br /&gt;
      begin&lt;br /&gt;
        cvita_payload_t recv_payload;&lt;br /&gt;
        cvita_metadata_t md;&lt;br /&gt;
        logic [63:0] expected_value;&lt;br /&gt;
        tb_streamer.recv(recv_payload,md);&lt;br /&gt;
        for (int i = 0; i &amp;lt; SPP/2; i++) begin&lt;br /&gt;
          '''expected_value = i*gain;'''&lt;br /&gt;
&lt;br /&gt;
Test #4 verifies that we can write and readback the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; value. Test #5 writes to the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; register, sends a sample set in the form of a ramp (1, 2, 3, 4, etc) to the RFNoC gain block and finally reads the values from the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block and compares them to expected values. The followings steps will allow the user to run this testbench.&lt;br /&gt;
&lt;br /&gt;
From within the &amp;lt;code&amp;gt;rfnoc-tutorial&amp;lt;/code&amp;gt; directory, create a &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; directory and enter it by running:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build &amp;amp;&amp;amp; cd build/&lt;br /&gt;
&lt;br /&gt;
The next step is to run &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;. If PyBOMBS was used to create the development sandbox, &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt; will automatically detect the location of the &amp;lt;code&amp;gt;fpga&amp;lt;/code&amp;gt; repository. If PyBOMBS was not used, the user must provide the location of where the &amp;lt;code&amp;gt;fpga&amp;lt;/code&amp;gt; repository is installed.&lt;br /&gt;
&lt;br /&gt;
If PyBOMBS used, run:&lt;br /&gt;
&lt;br /&gt;
    $ cmake ../&lt;br /&gt;
&lt;br /&gt;
If PyBOMBS not used, run:&lt;br /&gt;
&lt;br /&gt;
    $ cmake [-DUHD_FPGA_DIR=/PATH/TO/FPGA/REPOSITORY] ../&lt;br /&gt;
&lt;br /&gt;
Final output from the &amp;lt;code&amp;gt;$ cmake ../&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /home/widow/rfnoc/src/rfnoc-tutorial/build&lt;br /&gt;
&lt;br /&gt;
The following command will modify the necessary files and set the correct path to the simulation tools. From now on, every time a new block is added, this command will be run automatically. Remember, only run the following command once for each OOT module (not RFNoC block, but OOT module) created:&lt;br /&gt;
&lt;br /&gt;
    $ make test_tb&lt;br /&gt;
    Scanning dependencies of target test_tb&lt;br /&gt;
    Built target test_tb&lt;br /&gt;
&lt;br /&gt;
Testbenches can be executed by running the command:&lt;br /&gt;
&lt;br /&gt;
    $ make noc_block_[name_of_your_block]_tb &lt;br /&gt;
&lt;br /&gt;
The gain block testbench can be run by running the following command:&lt;br /&gt;
&lt;br /&gt;
    $ make noc_block_gain_tb&lt;br /&gt;
&lt;br /&gt;
The simulation will start.  Final output should look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ========================================================&lt;br /&gt;
    TESTBENCH STARTED: noc_block_gain&lt;br /&gt;
    ========================================================&lt;br /&gt;
    [TEST CASE   1] (t=000000000) BEGIN: Wait for Reset...&lt;br /&gt;
    [TEST CASE   1] (t=000001002) DONE... Passed&lt;br /&gt;
    [TEST CASE   2] (t=000001002) BEGIN: Check NoC ID...&lt;br /&gt;
    Read GAIN NOC ID: 1111222233334444&lt;br /&gt;
    [TEST CASE   2] (t=000001238) DONE... Passed&lt;br /&gt;
    [TEST CASE   3] (t=000001238) BEGIN: Connect RFNoC blocks...&lt;br /&gt;
    Connecting noc_block_tb (SID: 1:0) to noc_block_gain (SID: 0:0)&lt;br /&gt;
    Connecting noc_block_gain (SID: 0:0) to noc_block_tb (SID: 1:0)&lt;br /&gt;
    [TEST CASE   3] (t=000005457) DONE... Passed&lt;br /&gt;
    [TEST CASE   4] (t=000005457) BEGIN: Write / readback user registers...&lt;br /&gt;
    [TEST CASE   4] (t=000006888) DONE... Passed&lt;br /&gt;
    [TEST CASE   5] (t=000006888) BEGIN: Test sequence...&lt;br /&gt;
    [TEST CASE   5] (t=000007633) DONE... Passed&lt;br /&gt;
    ========================================================&lt;br /&gt;
    '''TESTBENCH FINISHED: noc_block_gain'''&lt;br /&gt;
    ''' - Time elapsed:   7700 ns'''             &lt;br /&gt;
    ''' - Tests Expected: 5'''&lt;br /&gt;
    ''' - Tests Run:      5'''&lt;br /&gt;
    ''' - Tests Passed:   5'''&lt;br /&gt;
    '''Result: PASSED'''   &lt;br /&gt;
    ========================================================&lt;br /&gt;
    $finish called at time : 7700 ns : File &amp;quot;/home/widow/rfnoc/src/rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv&amp;quot; Line 10&lt;br /&gt;
    INFO: [USF-XSim-96] XSim completed. Design snapshot 'noc_block_gain_tb_behav' loaded.&lt;br /&gt;
    INFO: [USF-XSim-97] XSim simulation ran for 1000000000us&lt;br /&gt;
    launch_simulation: Time (s): cpu = 00:00:10 ; elapsed = 00:00:12 . Memory (MB): peak = 966.387 ; gain = 54.848 ; free physical = 3080 ; free virtual = 29888&lt;br /&gt;
    # if [string equal $vivado_mode &amp;quot;batch&amp;quot;] {&lt;br /&gt;
    #     puts &amp;quot;BUILDER: Closing project&amp;quot;&lt;br /&gt;
    #     close_project&lt;br /&gt;
    # } else {&lt;br /&gt;
    #     puts &amp;quot;BUILDER: In GUI mode. Leaving project open.&amp;quot;&lt;br /&gt;
    # }&lt;br /&gt;
    BUILDER: Closing project&lt;br /&gt;
    ****** Webtalk v2015.4 (64-bit)&lt;br /&gt;
      **** SW Build 1412921 on Wed Nov 18 09:44:32 MST 2015&lt;br /&gt;
      **** IP Build 1412160 on Tue Nov 17 13:47:24 MST 2015&lt;br /&gt;
        ** Copyright 1986-2015 Xilinx, Inc. All Rights Reserved.&lt;br /&gt;
    &lt;br /&gt;
    source /home/widow/rfnoc/src/rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/xsim_proj/xsim_proj.hw/webtalk/labtool_webtalk.tcl -notrace&lt;br /&gt;
    INFO: [Common 17-206] Exiting Webtalk at Tue Jan 10 23:26:20 2017...&lt;br /&gt;
    INFO: [Common 17-206] Exiting Vivado at Tue Jan 10 23:26:22 2017...&lt;br /&gt;
    Built target noc_block_gain_tb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With every custom block created, a &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; directive will be available to run the simulation from the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
===Building the FPGA image with a custom user block===&lt;br /&gt;
In this section steps are given on how to initiate an FPGA build while incorporating the user’s custom RFNoC block. The first sections give general information on building RFNoC images. The remaining two sections show how to initiate FPGA builds using a command line interface and using a graphical interface (coming out soon), respectively.&lt;br /&gt;
&lt;br /&gt;
====Discussion on number of blocks in an FPGA image====&lt;br /&gt;
There is a maximum number of blocks that can be added for each device. The maximum amount of computation engines (CEs/RFNoC blocks) that each device can use is 16, but the amount of custom blocks that can be added depends on the device. &lt;br /&gt;
&lt;br /&gt;
If using a device from the X3xx series, from the 16 CEs, there are 6 that will be always added and are not subject to direct customization: 1 CE for the AXI bus, 1 CE for the Ethernet Interface, 2 Radios and 2 Dma FIFOS. Because of this, the application will only allow a number of 10 custom blocks on the X3xx series. &lt;br /&gt;
&lt;br /&gt;
If using a device from the E3xx series, 2 CE engines are always added and are not subject to direct customization: 1 CE for the AXI bus and 1 Radio. This would virtually allow 14 slots for custom blocks. However, given the size of the FPGA on the E3xx series of devices, the application only allows a number of 6 custom blocks. &lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Blocks with higher resource utilization may fill up the FPGA and force the user to include less blocks.&lt;br /&gt;
&lt;br /&gt;
Verify the current maximum values by running the &amp;lt;code&amp;gt;uhd_images_builder.py&amp;lt;/code&amp;gt; utility from the scripts directory.&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&lt;br /&gt;
    $ uhd_image_builder.py --help&lt;br /&gt;
&lt;br /&gt;
====Discussion on FPGA image targets====&lt;br /&gt;
RFNoC target names follow the pattern &amp;lt;code&amp;gt;{DEVICE}_RFNOC_{BUILD_TYPE}&amp;lt;/code&amp;gt; with the following build types: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;HG:&amp;lt;/code&amp;gt; 1GigE on SFP+ Port0, 10Gig on SFP+ Port&lt;br /&gt;
* &amp;lt;code&amp;gt;XG:&amp;lt;/code&amp;gt; 10GigE on both SFP+ ports&lt;br /&gt;
* &amp;lt;code&amp;gt;HLS:&amp;lt;/code&amp;gt; Vivado High Level Synthesis enabled&lt;br /&gt;
* &amp;lt;code&amp;gt;sgX:&amp;lt;/code&amp;gt; Speed grade for E300 devices (1 or 3)&lt;br /&gt;
&lt;br /&gt;
Some examples are:&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_XG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_XG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_HLS_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_HLS_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;E310_RFNOC&amp;lt;/code&amp;gt; (this is for the speed grade 1 FPGA version of E310, append &amp;lt;code&amp;gt;_sg3&amp;lt;/code&amp;gt; for speed grade 3)&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' E310, E312 and E313 all have the same FPGA hardware and therefore will use the &amp;lt;code&amp;gt;E310_RFNOC_{BUILD_TYPE}&amp;lt;/code&amp;gt; target. USRP E3xx devices have either &amp;lt;code&amp;gt;sg1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sg3&amp;lt;/code&amp;gt; hardware, please visit [http://files.ettus.com/e3xx_images/README here] to find out how to differentiate.&lt;br /&gt;
&lt;br /&gt;
Additional information about the build targets can be found at the build instructions for USRP3, found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here].&lt;br /&gt;
&lt;br /&gt;
====Image building using the command line====&lt;br /&gt;
The script &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; is used to generate the NoC block instantiation file and build the FPGA image. Run the help menu by typing:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&lt;br /&gt;
    $ ./uhd_image_builder.py --help&lt;br /&gt;
         &lt;br /&gt;
    usage: uhd_image_builder.py [-h] [-I INCLUDE_DIR [INCLUDE_DIR ...]]&lt;br /&gt;
                                [-m MAX_NUM_BLOCKS] [--fill-with-fifos]&lt;br /&gt;
                                [-o OUTFILE] [-d DEVICE] [-t TARGET] [-g] [-c]&lt;br /&gt;
                                [blocks [blocks ...]]&lt;br /&gt;
    &lt;br /&gt;
    Generate the NoC block instantiation file&lt;br /&gt;
    &lt;br /&gt;
    positional arguments:&lt;br /&gt;
      blocks                List block names to instantiate.&lt;br /&gt;
    &lt;br /&gt;
    optional arguments:&lt;br /&gt;
      -h, --help            show this help message and exit&lt;br /&gt;
      -I INCLUDE_DIR [INCLUDE_DIR ...], --include-dir INCLUDE_DIR [INCLUDE_DIR ...]&lt;br /&gt;
                            Path directory of the RFNoC Out-of-Tree module&lt;br /&gt;
      -m MAX_NUM_BLOCKS, --max-num-blocks MAX_NUM_BLOCKS&lt;br /&gt;
                            Maximum number of blocks (Max. Allowed for x310|x300:&lt;br /&gt;
                            10, for e300: 6)&lt;br /&gt;
      --fill-with-fifos     If the number of blocks provided was smaller than the&lt;br /&gt;
                            max number, fill the rest with FIFOs&lt;br /&gt;
      -o OUTFILE, --outfile OUTFILE&lt;br /&gt;
                            Output /path/filename - By running this directive, you&lt;br /&gt;
                            won't build your IP&lt;br /&gt;
      -d DEVICE, --device DEVICE&lt;br /&gt;
                            Device to be programmed [x300, x310, e310]&lt;br /&gt;
      -t TARGET, --target TARGET&lt;br /&gt;
                            Build target - image type [X3X0_RFNOC_HG,&lt;br /&gt;
                            X3X0_RFNOC_XG, E310_RFNOC_sg3...]&lt;br /&gt;
      -g, --GUI             Open Vivado GUI during the FPGA building process&lt;br /&gt;
      -c, --clean-all       Cleans the IP before a new build&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are details on the usage of the script which is followed by an example:&lt;br /&gt;
&lt;br /&gt;
'''Blocks:''' The first arguments are the names of RFNoC blocks that the user wants to have compiled into the new image which are separated by a space. They can be custom blocks from the user’s OOT module or from the ones that are provided from Ettus, or a combination. Blocks provided by Ettus Research are listed (among other sources necessary for the FPGA build) in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/lib/rfnoc/Makefile.srcs&amp;lt;/code&amp;gt; file. &lt;br /&gt;
&lt;br /&gt;
These blocks can be identified by the following pattern: &lt;br /&gt;
&lt;br /&gt;
    noc_block_{NAME}.v&lt;br /&gt;
&lt;br /&gt;
However, as all the RFNoC blocks have the same &amp;lt;code&amp;gt;noc_block_&amp;lt;/code&amp;gt; prefix, for simplicity this prefix is omitted when listing the blocks in the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; utility. As an example of the incorrect and correct way of adding blocks, consider the following examples when adding the &amp;lt;code&amp;gt;noc_block_null_source_sink&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;noc_block_siggen&amp;lt;/code&amp;gt; blocks:&lt;br /&gt;
&lt;br /&gt;
Incorrect method:  &lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py noc_block_null_source_sink noc_block_siggen ...&lt;br /&gt;
&lt;br /&gt;
Correct method:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py null_source_sink siggen ...&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Blocks generated by the RFNoC Modtool follow the same naming convention.&lt;br /&gt;
&lt;br /&gt;
There is an increasing list of pre-built blocks. Here is a sample:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;axi_fifo_loopback&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;axi_dma_fifo&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fir_filter&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fft&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;null_source_sink&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;schmidl_cox&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;packet_resizer&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;split_stream&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;vector_iir&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;addsub&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;window&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;keep_one_in_n&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;pfb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;export_io&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;conv_encoder_qpsk&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;siggen&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;logpwr&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fosphor&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;moving_avg&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ddc&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;duc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
RFNoC related blocks generally reside in &amp;lt;code&amp;gt;fpga/usrp3/lib/rfnoc/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
!Block&lt;br /&gt;
!Filename&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FIFO&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_axi_fifo_loopback.v noc_block_axi_fifo_loopback.v]&lt;br /&gt;
|Simple FIFO loopback / passthrough block.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FFT&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_fft.v noc_block_fft.v]&lt;br /&gt;
|Xilinx coregen based Fast Fourier Transform up to length 4096.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FIR&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_fir_filter.v noc_block_fir_filter.v]&lt;br /&gt;
|Xilinx coregen based Finite Impulse Response Filter, 41 taps, reconfigurable tap coefficients.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|Window&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_window.v noc_block_window.v]&lt;br /&gt;
|Windowing block for use with FFT block.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Vector IIR&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_vector_iir.v noc_block_vector_iir.v]&lt;br /&gt;
|Single pole IIR with configurable coefficients that filters data along vectors (i.e. parallel streams of samples). Useful with FFT output.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Keep One in N&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_keep_one_in_n.v noc_block_keep_one_in_n.v]&lt;br /&gt;
|Keeps one packet every N packets.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|AddSub&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_addsub.v noc_block_addsub.v]&lt;br /&gt;
|Example of using multiple block ports in a single RFNoC block to add and subtract streams.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Null Source Sink&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_null_source_sink.v noc_block_null_source_sink.v]&lt;br /&gt;
|Generates dummy packets and can consume packets at a configurable rate. Useful for testing.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Packet Resizer&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_packet_resizer.v noc_block_packet_resizer.v]&lt;br /&gt;
|Resizes input packets to a configurable size (larger or smaller than source packets).&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Split Stream&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_split_stream.v noc_block_split_stream.v]&lt;br /&gt;
|Replicates an input stream to a configurable number of output streams.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' There is a restriction on the amount of blocks that can added into the FPGA image, see the section in this Application Note labeled [[Getting_Started_with_RFNoC_Development#Discussion_on_number_of_blocks_in_an_FPGA_image|Discussion on number of blocks in an FPGA image]] for more information. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-I INCLUDE_DIR:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt; directive provides the path to top OOT directory, which contains the users &amp;lt;code&amp;gt;rfnoc/fpga-src&amp;lt;/code&amp;gt; directory which contains the custom blocks. This path is needed by the Xilinx Vivado tool. Inside the &amp;lt;code&amp;gt;fpga-src&amp;lt;/code&amp;gt; directory there is a file called &amp;lt;code&amp;gt;Makefile.srcs&amp;lt;/code&amp;gt; that contains the path of the OOT module and a list of all the custom OOT blocks. This is an auto generated file, which is amended every time a new block is added to the OOT module. Manually modifying this file is not recommended. If there are multiple OOT modules with various custom blocks that reside in different directories the way to include them all is by separating the different paths by a space (e.g. &amp;lt;code&amp;gt;-I /first/OOT/path/ /second/OOT/path/&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''IMPORTANT:''' Please be sure to terminate the path of your OOT with the &amp;quot;/&amp;quot; character. Otherwise the path might not be recognized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-d DEVICE:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;-d&amp;lt;/code&amp;gt; directive directs the script on which USRP device the build is for. If no &amp;lt;code&amp;gt;–d&amp;lt;/code&amp;gt; is included the default is &amp;lt;code&amp;gt;–d x310&amp;lt;/code&amp;gt;. Generation-3 USRPs and above all support RFNoC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-t TARGET:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;–t&amp;lt;/code&amp;gt; directive directs the script on which type of image to build for the chosen device. With each USRP device there are several build options to choose from. Detailed information about the build targets can be found at the build instructions for USRP3, found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here]. If &amp;lt;code&amp;gt;-t&amp;lt;/code&amp;gt; is not included, a default target will be chosen for the given device. For example, the default &amp;lt;code&amp;gt;X310_RFNOC_HG&amp;lt;/code&amp;gt; target builds for the &amp;lt;code&amp;gt;–d x310&amp;lt;/code&amp;gt; device. More details on targets can be found in the section of this Application Note labeled [[Getting Started with RFNoC Development#Discussion_on_FPGA_image_targets|Discussion on FPGA image targets]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-m MAX_NUM_BLOCKS:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;–m&amp;lt;/code&amp;gt; directive specifies the max number of RFNoC blocks to build on the FPGA image. An RFNoC image does not need to fill all available slots with RFNoC blocks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--fill-with-fifos:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;--fill-with-fifos&amp;lt;/code&amp;gt; directive will fill the empty RFNoC block slots with FIFOS. As an example, if a user indicates three RFNoC blocks by name and also specifies &amp;lt;code&amp;gt;–m 5&amp;lt;/code&amp;gt; then the other two slots will be filed with FIFOs. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-o OUTFILE:&amp;lt;/code&amp;gt; With the &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; directive, the RFNoC blocks instantiation file is generated and saved at the desired path with the given name for the user to inspect. The FPGA image will NOT build if this directive is provided. The purpose of the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script is to auto generate an instantiation file and populate the source files needed for the Xilinx Vivado tool to build the FPGA image, however, it may be desirable to only see the effect of adding a custom OOT module in the &amp;lt;code&amp;gt;fpga/&amp;lt;/code&amp;gt; directory, or for inspecting the instantiation file. When the directive is not provided the &amp;lt;code&amp;gt;rfnoc_ce_auto_inst_x3x0.v&amp;lt;/code&amp;gt; file is overwritten and the FPGA image build process will start automatically (standard use).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-g, --GUI:&amp;lt;/code&amp;gt; Open Vivado GUI during the FPGA building process&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-c, --clean-all:&amp;lt;/code&amp;gt; Cleans the IP before a new build&lt;br /&gt;
&lt;br /&gt;
Here is how to create an X310 FPGA image incorporating the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block that was created earlier in this Application Note:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts     &lt;br /&gt;
    $ ./uhd_image_builder.py gain ddc fft -I {USER_PREFIX}/src/rfnoc-tutorial/ -d x310 -t X310_RFNOC_HG -m 6 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At the end of a successful compilation process, write the new image to a USRP. The following command will load the new image. Update the &amp;lt;code&amp;gt;{IP_Address}&amp;lt;/code&amp;gt; of the USRP and &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; to the appropriate values for your configuration before running the command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=x300,addr={IP_ADDRESS}&amp;quot; --fpga-path {USER_PREFIX}/src/uhd-fpga/usrp3/top/x300/build/usrp_x310_fpga_RFNOC_HG.bit&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' &lt;br /&gt;
* The FPGA image building process may take over an hour.&lt;br /&gt;
&lt;br /&gt;
* FPGA images are specific to the USRP device NOT the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. Additional instructions on flashing a custom image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
&lt;br /&gt;
* [Environment setup] - The &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script will also set up the Xilinx Vivado environment by automatically running the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{device}&amp;lt;/code&amp;gt; directory. The &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script assumes that Xilinx Vivado is installed in the default location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;.  If the installation is in a different directory the &amp;lt;code&amp;gt;setupenv_base.sh&amp;lt;/code&amp;gt; script will need to be modified. The script is located at: &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts/setupenv_base.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besides the custom &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block, a &amp;lt;code&amp;gt;DDC&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FFT&amp;lt;/code&amp;gt; block are also being added along with three &amp;lt;code&amp;gt;FIFOs&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;DDC&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FFT&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FIFO&amp;lt;/code&amp;gt; blocks are already in the script's path and therefore do not need their path specified (they ship with the Ettus Research FPGA code). The reason three FIFOs are added is because the max number of blocks was specified to be 6 ( &amp;lt;code&amp;gt;-m 6&amp;lt;/code&amp;gt; ) and since only 3 blocks were specifically named the other three slots are filled with FIFOs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 10.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Instructions on flashing the image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series. FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. &lt;br /&gt;
&lt;br /&gt;
Once the newly compiled image is loaded onto a USRP X3xx running the following command will show what RFNoC blocks are available on the FPGA:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * '''Block_0'''&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The reason the custom block is called &amp;lt;code&amp;gt;Block_0&amp;lt;/code&amp;gt; and not &amp;lt;code&amp;gt;gain_0&amp;lt;/code&amp;gt; is because there is still host side software/files that need updated in order for this block to populate it’s proper name. A following section (UHD Integration) will step through the process of updating those host side files.&lt;br /&gt;
&lt;br /&gt;
====Using a graphical interface====&lt;br /&gt;
A graphical user interface for FPGA generation and building is shipped along with the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script. This intuitive application aids in setting up a custom FPGA build. &lt;br /&gt;
&lt;br /&gt;
This utility is located in the same &amp;lt;code&amp;gt;scripts&amp;lt;/code&amp;gt; directory as &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
To run it, enter the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts/&lt;br /&gt;
    $ ./uhd_image_builder_gui&lt;br /&gt;
&lt;br /&gt;
The application will then be launched:&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 11.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''1. Select build target:''' In this panel the available build targets are listed. This list may vary depending on which branch of the FPGA repository this user is using. Only RFNoC targets are listed. The build type descriptions are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;HG:&amp;lt;/code&amp;gt; 1GigE on SFP+ Port0, 10Gig on SFP+ Port1&lt;br /&gt;
* &amp;lt;code&amp;gt;XG:&amp;lt;/code&amp;gt; 10GigE on both SFP+ ports&lt;br /&gt;
* &amp;lt;code&amp;gt;HLS:&amp;lt;/code&amp;gt; Vivado High Level Synthesis enabled&lt;br /&gt;
* &amp;lt;code&amp;gt;sgX:&amp;lt;/code&amp;gt; Speed grade for E300 devices (1 or 3)&lt;br /&gt;
&lt;br /&gt;
'''2. List of blocks available:''' In this panel the available blocks are listed that can be included into a custom design. This list separates the RFNoC blocks provided by Ettus Research and the OOT modules and corresponding blocks that the user adds. Given the hardware differences between the X3xx and E3xx devices, this list will dynamically change when a different device is selected from the panel on the left. This implies that it is necessary to add the OOT modules for each device independently. This is accomplished by using the &amp;lt;code&amp;gt;Add OOT Blocks&amp;lt;/code&amp;gt; feature of the application, details of which are explained at #7 (&amp;lt;code&amp;gt;Add OOT Blocks&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''3. Blocks in current design:''' This section gives information on the MAX number of blocks for a given USRP (based on the target selection). There is a maximum number of blocks that can be added for each device. See the section in this App Note labeled &amp;quot;Discussion on number of blocks in an FPGA image&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
'''4. Blocks in current design:''' This panel will be populated by adding elements from the available blocks. All the blocks listed in here will be compiled into the FPGA custom image. There is a maximum number of blocks that can be added for each device. See the section in this App Note labeled &amp;quot;Discussion on number of blocks in an FPGA image&amp;quot; for more information. &lt;br /&gt;
&lt;br /&gt;
'''5. Add button (&amp;gt;&amp;gt;):''' Manually add the blocks from the central panel into your design.&lt;br /&gt;
&lt;br /&gt;
'''6. Remove button (&amp;lt;&amp;lt;):''' Remove blocks from the current design (far-left panel)&lt;br /&gt;
&lt;br /&gt;
'''7. Fill with FIFOs:''' By checking this box, the design will fill any available/unspecified block slots with FIFOs. The number of FIFO blocks that will be instantiated is based on the rules of amount of blocks explained at #3. When less than the max amount of blocks are needed for certain implementation, many users choose to fill their design with FIFO blocks. &lt;br /&gt;
&lt;br /&gt;
'''8. Open Vivado GUI:''' Open Vivado GUI during the FPGA building process. This allows the user to save a Vivado project with all IP and work within the Vivado GUI for development.&lt;br /&gt;
&lt;br /&gt;
'''9. Clean IP:''' Cleans the IP before a new build (recompiles all IP).&lt;br /&gt;
&lt;br /&gt;
'''10. Add OOT blocks:''' Manually add RFNoC Modtool-generated OOT modules by pointing the application to the &amp;lt;code&amp;gt;Makefile.srcs&amp;lt;/code&amp;gt; file, which is located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/{USER-OOT-moddir}/rfnoc/fpga-srcs/&amp;lt;/code&amp;gt; directory. After adding this file, blocks will appear under “&amp;lt;code&amp;gt;OOT blocks for XXXX devices&amp;lt;/code&amp;gt;”&lt;br /&gt;
&lt;br /&gt;
'''11. Show Instantiation File:''' The application auto-generates the instantiation file that is going to be used by Vivado to build the FPGA image. This instantiation file can be viewed and edited before starting the build by clicking this button. &lt;br /&gt;
&lt;br /&gt;
'''12. Import from GRC:''' If the user has a GNU Radio flowgraph with RFNoC blocks already in it, this application can read what RFNoC blocks are in the flowgraph and populate the &amp;lt;code&amp;gt;Blocks in current design&amp;lt;/code&amp;gt; section of the application with the necessary RFNoC blocks. '''NOTE:''' All RFNoC blocks pulled from a &amp;lt;code&amp;gt;.grc&amp;lt;/code&amp;gt; file must be in the of &amp;lt;code&amp;gt;List of blocks available&amp;lt;/code&amp;gt; before beginning the build.&lt;br /&gt;
&lt;br /&gt;
'''13. Generate .bit file:''' Start the build by clicking this button. &lt;br /&gt;
&lt;br /&gt;
'''14. uhd_image_builder command:''' The command line command with arguments is dynamically build here as the user selects different options. The user could save this command to use next time they build/compile an FPGA image to avoid having to select all options again. &lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' See the latter end of the previous section for additional information on what to expect once the compile has started as well as final output.&lt;br /&gt;
&lt;br /&gt;
==Creating Software/Host portion of custom RFNoC Block==&lt;br /&gt;
Now that the FPGA portion is complete the next step is to add software integration to UHD and GNU Radio as depicted in the RFNoC Stack below.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 12.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
===UHD integration===&lt;br /&gt;
Despite the data processing happening on the FPGA, the host software still has a lot of responsibilities in order for an RFNoC application to function. For example, it needs to know which settings registers are available within an RFNoC block, or what kind of input and output a block has. All of this information goes into the &amp;lt;code&amp;gt;Block Declaration&amp;lt;/code&amp;gt;, which is an XML file that is readable by UHD. Often, some simple logic needs to be embedded in the XML file, which we can do by using a simple scripting language called Noc-Script. Changes to the block declaration file are immediately imported into UHD every time an application is executed, and therefore, no software development toolchain needs to be set up.&lt;br /&gt;
&lt;br /&gt;
The list of things declared by the block declaration file includes:&lt;br /&gt;
&lt;br /&gt;
* Block name and Noc-ID&lt;br /&gt;
* Registers&lt;br /&gt;
* Inputs and outputs (including types)&lt;br /&gt;
&lt;br /&gt;
In some cases, additional C++ code is required to properly control a block from software. In this case, a &amp;lt;code&amp;gt;Block Controller&amp;lt;/code&amp;gt; file is required as well as the declaration file. In most cases, the default block controller provided by UHD is sufficient, so no C++ code needs to be written. Writing custom block controllers requires more effort, and means having to set up a programming toolchain. A common reason to write custom C++ block controllers is if setting a register requires a lot of computation, which is not feasible to do within a block declaration file (e.g., using Noc-Script).&lt;br /&gt;
&lt;br /&gt;
Skeleton code for both the block declaration and the block controller (if required) can be generated through RFNoC Modtool.&lt;br /&gt;
&lt;br /&gt;
Because the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block does not require anything other than simply reading and writing to a single register the default block controller will suffice for this example. However, we will need to add information about the register.&lt;br /&gt;
&lt;br /&gt;
Open the &amp;lt;code&amp;gt;gain.xml&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;/rfnoc-tutorial/rfnoc/blocks&amp;lt;/code&amp;gt; directory and add the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;&amp;lt;!--Default XML file--&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;nocblock&amp;gt;&lt;br /&gt;
      &amp;lt;name&amp;gt;gain&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;blockname&amp;gt;gain&amp;lt;/blockname&amp;gt;&lt;br /&gt;
      &amp;lt;ids&amp;gt;&lt;br /&gt;
        &amp;lt;id revision=&amp;quot;0&amp;quot;&amp;gt;1111222233334444&amp;lt;/id&amp;gt;&lt;br /&gt;
      &amp;lt;/ids&amp;gt;&lt;br /&gt;
      '''&amp;lt;nowiki&amp;gt;&amp;lt;!-- Registers --&amp;gt;&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;registers&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;setreg&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;name&amp;gt;GAIN&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;address&amp;gt;128&amp;lt;/address&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;/setreg&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;/registers&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;nowiki&amp;gt;&amp;lt;!-- Args --&amp;gt;&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;args&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;arg&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;name&amp;gt;gain&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;double&amp;lt;/type&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;value&amp;gt;1.0&amp;lt;/value&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;check&amp;gt;GE($gain, 0.0) AND LE($gain, 32767.0)&amp;lt;/check&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;check_message&amp;gt;Invalid gain.&amp;lt;/check_message&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;action&amp;gt;'''&lt;br /&gt;
            '''SR_WRITE(&amp;quot;GAIN&amp;quot;, IROUND($gain))'''&lt;br /&gt;
          '''&amp;lt;/action&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;/arg&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;/args&amp;gt;'''&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!--One input, one output. If this is used, better have all the info the C++ file.--&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;ports&amp;gt;&lt;br /&gt;
        &amp;lt;sink&amp;gt;&lt;br /&gt;
          '''&amp;lt;name&amp;gt;in0&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;sc16&amp;lt;/type&amp;gt;'''&lt;br /&gt;
        &amp;lt;/sink&amp;gt;&lt;br /&gt;
        &amp;lt;nowiki&amp;gt;&amp;lt;source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
          '''&amp;lt;name&amp;gt;out0&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;sc16&amp;lt;/type&amp;gt;'''&lt;br /&gt;
        &amp;lt;nowiki&amp;gt;&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;/ports&amp;gt;&lt;br /&gt;
    &amp;lt;/nocblock&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GNU Radio Integration===&lt;br /&gt;
GNU Radio is built around the concept of blocks, similarly to RFNoC. When mapping RFNoC into an application, the simple constraint is made that every RFNoC block maps to a single GNU Radio block. Thus, when creating mixed GNU Radio/RFNoC applications, there is a very clear 1:1 mapping between what’s happening in RFNoC and GNU Radio.&lt;br /&gt;
&lt;br /&gt;
Since most RFNoC blocks behave very similar to one another from GNU Radio’s perspective, it is generally not required to write C++ code for another block. Rather, a default block provided by RFNoC can be used with appropriate configuration. However, in some cases it may be desirable or even necessary to write a custom GNU Radio block for more specific controlling of the underlying RFNoC block. GNU Radio allows writing blocks in either C++ or Python, but since UHD and RFNoC do not have a Python API, a custom wrapper for an RFNoC block needs to be written in C++. RFNoC Modtool will create skeleton files for this purpose.&lt;br /&gt;
&lt;br /&gt;
The most popular and effective way to use GNU Radio is through the graphical interface, the GNU Radio Companion (GRC). GRC requires a separate description of every GNU Radio block in order to become available in the graphical UI, and the same is true for an RFNoC block that is wrapped in a GNU Radio block (even if the generic RFNoC block wrapper is used). For GNU Radio 3.7 and earlier, GRC bindings for blocks are written as XML files with interspersed Cheetah or Python statements. For a more detailed tutorial on how to write these files, refer to the [http://gnuradio.org/redmine/projects/gnuradio/wiki GNU Radio Documentation] and associated [http://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorials tutorials].&lt;br /&gt;
&lt;br /&gt;
====GNU Radio Block Code====&lt;br /&gt;
&lt;br /&gt;
* C++ or Python, although RFNoC blocks need to be written in C++ (if at all)&lt;br /&gt;
* How does GNU Radio interface to RFNoC?&lt;br /&gt;
** via C++ infrastructure code in &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; provides a base RFNoC block class&lt;br /&gt;
** Users extend base class for their RFNoC blocks&lt;br /&gt;
** Many blocks can use base class “as is”&lt;br /&gt;
** No C++ or Python code!&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-tutorial/lib/gain_impl.cc&amp;lt;/code&amp;gt;&lt;br /&gt;
** The gain block does not need anything additional&lt;br /&gt;
&lt;br /&gt;
====GNU Radio Companion Bindings====&lt;br /&gt;
* XML&lt;br /&gt;
* Describes GNU Radio blocks to GRC&lt;br /&gt;
* No recompilation&lt;br /&gt;
* Requirement of GNU Radio Companion&lt;br /&gt;
* Not strictly necessary for GNU Radio&lt;br /&gt;
* Tutorial on how to write them:&lt;br /&gt;
** [http://gnuradio.org/redmine/projects/gnuradio/wiki/GNURadioCompanion http://gnuradio.org/redmine/projects/gnuradio/wiki/GNURadioCompanion ]&lt;br /&gt;
* Skeleton file generated by RFNoC Modtool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Open the &amp;lt;code&amp;gt;tutorial-gain.xml&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;rfnoc-tutorial/grc&amp;lt;/code&amp;gt; directory and edit as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;block&amp;gt;&lt;br /&gt;
      &amp;lt;name&amp;gt;RFNoC: gain&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;key&amp;gt;tutorial_gain&amp;lt;/key&amp;gt;&lt;br /&gt;
      &amp;lt;category&amp;gt;tutorial&amp;lt;/category&amp;gt;&lt;br /&gt;
      &amp;lt;import&amp;gt;import tutorial&amp;lt;/import&amp;gt;&lt;br /&gt;
      &amp;lt;make&amp;gt;tutorial.gain(&lt;br /&gt;
        self.device3,&lt;br /&gt;
        uhd.stream_args( \# TX Stream Args&lt;br /&gt;
            cpu_format=&amp;quot;'''fc32'''&amp;quot;,&lt;br /&gt;
            otw_format=&amp;quot;'''sc16'''&amp;quot;,&lt;br /&gt;
            args=&amp;quot;gr_vlen={0},{1}&amp;quot;.format(${grvlen}, &amp;quot;&amp;quot; if $grvlen == 1 else &amp;quot;spp={0}&amp;quot;.format($grvlen)),&lt;br /&gt;
        ),&lt;br /&gt;
        uhd.stream_args( \# RX Stream Args&lt;br /&gt;
            cpu_format=&amp;quot;'''fc32'''&amp;quot;,&lt;br /&gt;
            otw_format=&amp;quot;'''sc16'''&amp;quot;,&lt;br /&gt;
            args=&amp;quot;gr_vlen={0},{1}&amp;quot;.format(${grvlen}, &amp;quot;&amp;quot; if $grvlen == 1 else &amp;quot;spp={0}&amp;quot;.format($grvlen)),&lt;br /&gt;
        ),&lt;br /&gt;
        $block_index, $device_index,&lt;br /&gt;
      )&lt;br /&gt;
    '''self.$(id).set_arg(&amp;quot;gain&amp;quot;, $gain)'''&lt;br /&gt;
      '''&amp;lt;/make&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;callback&amp;gt;set_arg(&amp;quot;gain&amp;quot;, $gain)&amp;lt;/callback&amp;gt;'''&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'param' node for every Parameter you want settable from the GUI.&lt;br /&gt;
           Sub-nodes:&lt;br /&gt;
           * name&lt;br /&gt;
           * key (makes the value accessible as $keyname, e.g. in the make node)&lt;br /&gt;
           * type --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
         .  &lt;br /&gt;
         .&lt;br /&gt;
         .&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;option&amp;gt;&lt;br /&gt;
          &amp;lt;name&amp;gt;Byte&amp;lt;/name&amp;gt;&lt;br /&gt;
          &amp;lt;key&amp;gt;u8&amp;lt;/key&amp;gt;&lt;br /&gt;
        &amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;/param&amp;gt;&lt;br /&gt;
      &amp;lt;param&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;'''Gain'''&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;key&amp;gt;'''gain'''&amp;lt;/key&amp;gt;&lt;br /&gt;
        '''&amp;lt;value&amp;gt;1.0&amp;lt;/value&amp;gt;'''&lt;br /&gt;
        &amp;lt;type&amp;gt;'''real'''&amp;lt;/type&amp;gt;&lt;br /&gt;
      &amp;lt;/param&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'sink' node per input. Sub-nodes:&lt;br /&gt;
           * name (an identifier for the GUI)&lt;br /&gt;
           * type&lt;br /&gt;
           * vlen&lt;br /&gt;
           * optional (set to 1 for optional inputs) --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;sink&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;in&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;'''complex'''&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;vlen&amp;gt;$grvlen&amp;lt;/vlen&amp;gt;&lt;br /&gt;
        &amp;lt;domain&amp;gt;rfnoc&amp;lt;/domain&amp;gt;&lt;br /&gt;
      &amp;lt;/sink&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'source' node per output. Sub-nodes:&lt;br /&gt;
           * name (an identifier for the GUI)&lt;br /&gt;
           * type&lt;br /&gt;
           * vlen&lt;br /&gt;
           * optional (set to 1 for optional inputs) --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;out&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;'''complex'''&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;vlen&amp;gt;$grvlen&amp;lt;/vlen&amp;gt;&lt;br /&gt;
        &amp;lt;domain&amp;gt;rfnoc&amp;lt;/domain&amp;gt;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;/block&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Indentation spacing is important in the &amp;lt;code&amp;gt;&amp;lt;make&amp;gt;&amp;lt;/code&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
===Compile, Install and Verify===&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/rfnoc-tutorial/build&lt;br /&gt;
    $ make install&lt;br /&gt;
    &lt;br /&gt;
    $ uhd_usrp_probe &lt;br /&gt;
    &lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * '''gain_0'''&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' In the case where the &amp;lt;code&amp;gt;gain_0&amp;lt;/code&amp;gt; does not appear but &amp;lt;code&amp;gt;Block_0&amp;lt;/code&amp;gt; does: Most likely, the XML block declaration file (see [[Getting_Started_with_RFNoC_Development#UHD_integration|UHD Integration]] section) for the block contains a NoC-ID that does not match with any NoC-ID defined in the hardware part of the design. The user has to be certain that the description files are up-to-date and that the NoC-ID matches in the SW and HW side. See the [[Getting_Started_with_RFNoC_Development#UHD_integration|UHD Integration]] section to update those host side files.&lt;br /&gt;
&lt;br /&gt;
==Testing out the custom block==&lt;br /&gt;
At this point the custom &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; RFNoc Block (Computation Engine) can be used within a GNU Radio flowgraph. Below is an example GRC flowgraph using our new block as well as the output application it produces. &lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 13.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Copy Block: In the RFNoC domain, streams of data can not be split as easily as they are in the GNU Radio domain. The “copy” block depicted in the screenshot above serves the function as a stream splitter . It’s main purpose, when “enabled”, is to copy the samples it is getting at its input and putting then into the output, but here it is also serving as a boundary between a RFNoC-domain and a GNURadio-domain. In the flowgraph above. after this boundary is passed, the data stream can easily be split into the two sinks to have them run simultaneously (standard GNU Radio functionality). It is possible to connect the GNU Radio blocks directly to RFNoC blocks without a “copy” block, but only one would work at a time (the other ones would have to be disabled). Another way to split data streams from the RFNoC-domain is to use the ”RFNoC: split stream” block, which would split the streams in the RFNoC domain, but this is not very useful here as we are, in any case, moving into the GNURadio-domain.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 14.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Xilinx Vivado===&lt;br /&gt;
====Compile issues====&lt;br /&gt;
=====Synthesis is failing=====&lt;br /&gt;
Verify all the correct Xilinx [[Getting Started with RFNoC Development#Prerequisites|prerequisite software]] is installed.&lt;br /&gt;
&lt;br /&gt;
Additional helpful information can be found in the following Xilinx forum posts:&lt;br /&gt;
* https://forums.xilinx.com/t5/Synthesis/Synthesis-failed-without-reporting-any-error/td-p/686000&lt;br /&gt;
* https://forums.xilinx.com/t5/Installation-and-Licensing/Vivado-on-Linux-synthesis-fails-with-no-error-message/td-p/732143&lt;br /&gt;
&lt;br /&gt;
====Environment Setup====&lt;br /&gt;
The &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script will also set up the Xilinx Vivado environment by automatically running the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{device}&amp;lt;/code&amp;gt; directory. The &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script assumes that Xilinx Vivado is installed in the default location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;. If the installation is in a different directory, then the &amp;lt;code&amp;gt;setupenv_base.sh&amp;lt;/code&amp;gt; script will need to be modified. The script is located at: &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3_rfnoc/tools/scripts/setupenv_base.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reference Files==&lt;br /&gt;
The following reference files are included within the gain_src.tar.gz archive linked below:&lt;br /&gt;
&lt;br /&gt;
* gain.xml		&lt;br /&gt;
* noc_block_gain.v	&lt;br /&gt;
* noc_block_gain_tb.sv	&lt;br /&gt;
* tutorial_gain.xml&lt;br /&gt;
* rfnoc_gain.grc&lt;br /&gt;
&lt;br /&gt;
[[Media:gain src.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
==Links and Additional Resources==&lt;br /&gt;
===RFNoC additional resources===&lt;br /&gt;
* [https://youtube.com/watch?v=j-EfyPVpaJ8 Video: RFNoC Getting Started Video Tutorial]&lt;br /&gt;
* [https://kb.ettus.com/Mailing_Lists USRP Mailing List]&lt;br /&gt;
* [https://kb.ettus.com/RFNoC RFNoC Software Resources Page]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_Intro.pdf RFNoC Introduction]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_FPGA.pdf RFNoC Deep Dive: FPGA]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_Host.pdf RFNoC Deep Dive: Host side]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8cPd3t88djE Video: RFNoC presented at Wireless @ Virginia Tech, 2015 ]&lt;br /&gt;
** Explaining the slides of Intro, FPGA and Host presentations above (in that order).&lt;br /&gt;
* [https://www.youtube.com/watch?v=51rpjJ2W0Qs Video: It's the RFNoC Life for Us by Martin Braun at GRCon16, 2016]&lt;br /&gt;
&lt;br /&gt;
===GNU Radio resources===&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules GNU Radio OutOfTree Modules tutorial]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGRFromSource GNU Radio Installation]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/Tutorials GNU Radio Tutorials]&lt;br /&gt;
&lt;br /&gt;
===UHD resources===&lt;br /&gt;
* [http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com USRP Mailing List]&lt;br /&gt;
* [https://kb.ettus.com/UHD UHD Software Resources Page]&lt;br /&gt;
* [http://files.ettus.com/manual/md_usrp3_build_instructions.html USRP3 build instructions]&lt;br /&gt;
* [http://files.ettus.com/manual/ UHD Manual]&lt;br /&gt;
&lt;br /&gt;
===Other resources===&lt;br /&gt;
* [https://www.xilinx.com/support/documentation/ip_documentation/ug761_axi_reference_guide.pdf Xilinx - AXI reference guide]&lt;br /&gt;
* [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD + GNU Radio Application Note (Linux)]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/pybombs/wiki PyBOMBS]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5551</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5551"/>
				<updated>2022-12-24T19:02:54Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Updated DRAM performance numbers for X3xx and E320 due to bug fix for those USRPs.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 299 || 191 || 148&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 274 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# E31x, N3xx, and X410 were tested using UHD 4.2. E320 and X3xx were tested using UHD 4.3.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5506</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5506"/>
				<updated>2022-10-26T15:00:50Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added example connections for FIFO and Replay YAML examples.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# This was tested using UHD 4.2.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the replay block to a stream endpoint&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining Replay port&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect each port of the DMA FIFO block to a stream endpoint, or insert it&lt;br /&gt;
  # into the data path where desired. This examples uses stream endpoints.&lt;br /&gt;
  - { srcblk: &amp;lt;epN&amp;gt;,   srcport: out0,  dstblk: fifo0,   dstport: in_0 }&lt;br /&gt;
  - { srcblk: replay0, srcport: out_0, dstblk: &amp;lt;epN&amp;gt;,   dstport: in0  }&lt;br /&gt;
  - { srcblk: &amp;lt;epN+1&amp;gt;, srcport: out0,  dstblk: fifo0,   dstport: in_1 }&lt;br /&gt;
  - { srcblk: fifo0,   srcport: out_1, dstblk: &amp;lt;epN+1&amp;gt;, dstport: in0  }&lt;br /&gt;
  ... repeat for each remaining FIFO port&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_N300/N310/N320/N321_Getting_Started_Guide&amp;diff=5423</id>
		<title>USRP N300/N310/N320/N321 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_N300/N310/N320/N321_Getting_Started_Guide&amp;diff=5423"/>
				<updated>2022-07-15T18:01:31Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Fix old location for network config&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
===N300===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP N300&lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 RJ45 – SFP+ Adapter&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
||[[File:n300 kit.png|450px|center]]&lt;br /&gt;
|}&lt;br /&gt;
===N310===&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP N310&lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 RJ45 – SFP+ Adapter&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
||[[File:n310 kit.png|500px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===N320===&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP N320&lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 RJ45 – SFP+ Adapter&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
|[[File:n320 kit.png|500px|center]] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===N321===&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP N321&lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 RJ45 – SFP+ Adapter&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
||[[File:n321 kit.png|500px|center]] &lt;br /&gt;
|}&lt;br /&gt;
==Verify the Contents of Your Kit==&lt;br /&gt;
Ensure that your kit contains all the items listed above. If any items are missing, please contact sales@ettus.com​ immediately.&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
* microSD Card Writer&lt;br /&gt;
&lt;br /&gt;
* For Network Mode: A host computer with an available 1 or 10 Gigabit Ethernet interface for sample streaming. In addition to the Ethernet interface used for sampling streaming, your host computer will require a separate 1 Gigabit Ethernet interface for command and control streaming.&lt;br /&gt;
 &lt;br /&gt;
* For Stand-Alone Embedded Mode: A host computer with an available 1 Gigabit Ethernet port or a USB 2.0 port to remotely access the embedded Linux operating system running on ARM CPU.&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow metal objects to touch the circuit board while powered.&lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than -15 dBm of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
In order to use your Universal Software Radio Peripheral (USRP™), you must have the software tools correctly installed and configured on your host computer. A step-by-step guide for doing this is available at the Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]] Application Notes.&lt;br /&gt;
&lt;br /&gt;
To find the latest release of UHD, see the UHD repository at https://github.com/EttusResearch/uhd.&lt;br /&gt;
&lt;br /&gt;
The USRP N310 requires UHD version 3.11.0.0 or later. &lt;br /&gt;
&lt;br /&gt;
The USRP N300 requires UHD version 3.12.0.0 or later.&lt;br /&gt;
&lt;br /&gt;
The USRP N320/N321 requires UHD version 3.14.0.0 or later. &lt;br /&gt;
&lt;br /&gt;
White Rabbit Ethernet-Based Synchronization of the N3xx USRP requires UHD version 3.12.0.0 or later. For additional details on White Rabbit Ethernet-Based Synchronization, please see the application note, [[Using Ethernet-Based Synchronization on the USRP™ N3xx Devices]].&lt;br /&gt;
&lt;br /&gt;
'''When you receive a brand-new device, it is strongly recommended that you download the most recent filesystem image from the Ettus Research website and write it to the SD card that comes with the unit. It is not recommended that you use the SD card from the factory as-is. Instructions on downloading the latest filesystem image and writing it to the SD card are listed below.'''&lt;br /&gt;
&lt;br /&gt;
'''Note that if you are operating the device in Network Mode, the version of UHD running on the host computer and the USRP N3xx must match.'''&lt;br /&gt;
&lt;br /&gt;
==Connecting the Device==&lt;br /&gt;
===Interfaces Overview===&lt;br /&gt;
Listed below are the interfaces to connect to the USRP N3xx. Each interface has specific functionality, limitations and purpose. &lt;br /&gt;
&lt;br /&gt;
'''Serial Console'''&lt;br /&gt;
&lt;br /&gt;
The Serial Console provides a low level interface to the device typically used for debugging.&lt;br /&gt;
&lt;br /&gt;
'''1 Gigabit RJ45 Connection'''&lt;br /&gt;
&lt;br /&gt;
The 1 Gigabit RJ45 Connection interfaces with the on-board ARM CPU. When operated in &amp;quot;Network mode&amp;quot;, this interface can optionally be used for UHD management traffic. Regardless of the operation mode (Network vs Embedded) this interface can be used to connect to the ARM via SSH. By default, the 1Gb RJ45 connection is configured to use a DHCP assigned IP address.&lt;br /&gt;
&lt;br /&gt;
'''Dual SFP+ Connections'''&lt;br /&gt;
&lt;br /&gt;
The Dual SFP+ Connections support multiple configurations for streaming high-speed, low-latency data, depending upon the FPGA image which is loaded.&lt;br /&gt;
&lt;br /&gt;
'''QSFP+ Connection (N320/ N321 Only)'''&lt;br /&gt;
&lt;br /&gt;
The QSFP+ Connection supports 2 x 10Gb lanes for streaming high-speed, low-latency data, while the onboard SFP0 connection is used for White Rabbit Ethernet-Based Synchronization.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Serial Console Connection===&lt;br /&gt;
It is possible to gain shell access to the device using a serial terminal emulator via the Serial Console port. Most Linux, OSX, or other Unix based operating systems have a tool called &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; which can be used for this purpose. &lt;br /&gt;
&lt;br /&gt;
If you do not have &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; installed, it can be installed via your package manager. For Ubuntu/Debian based operating systems it can be installed with &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; such as:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install screen&lt;br /&gt;
&lt;br /&gt;
The default Baud Rate for the Serial Console is: &amp;lt;code&amp;gt;115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact device node you should attach to depends on your operating system's driver and other USB devices that might already be connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under &amp;lt;code&amp;gt;/dev/serial/by-id&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ ls /dev/serial/by-id&lt;br /&gt;
    usb-Digilent_Digilent_USB_Device_25163511FE00-if00-port0&lt;br /&gt;
    usb-Digilent_Digilent_USB_Device_25163511FE00-if01-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if01-port0&lt;br /&gt;
&lt;br /&gt;
NOTE: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
Every N3XX series device connected to USB will by default show up as four different devices. The devices labeled &amp;lt;code&amp;gt;&amp;quot;USB_to_UART_Bridge_Controller&amp;quot;&amp;lt;/code&amp;gt; are the devices that offer a serial prompt. The first (with the &amp;lt;code&amp;gt;if00&amp;lt;/code&amp;gt; suffix) connects to the &amp;lt;code&amp;gt;ARM CPU&amp;lt;/code&amp;gt;, whereas the second connects to the &amp;lt;code&amp;gt;STM32 Microcontroller&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
If you have multiple N3xx Serial Consoles connected to a single host, you may have to empirically test nodes. &lt;br /&gt;
&lt;br /&gt;
Connecting to the ARM CPU can be performed with the command:&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if00-port0 115200&lt;br /&gt;
&lt;br /&gt;
Upon starting the USRP N3xx, boot messages will appear and rapidly update. Once the boot process successfully completes, a login prompt like the following should appear:&lt;br /&gt;
&lt;br /&gt;
    OpenEmbedded test ni-n3xx-313ABDA ttyPS0&lt;br /&gt;
    &lt;br /&gt;
    ni-n3xx-313ABDA login: &lt;br /&gt;
&lt;br /&gt;
Enter the username: ​&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;​ &lt;br /&gt;
&lt;br /&gt;
By default, the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user's password is left blank. Press the &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; key when prompted for a password.&lt;br /&gt;
&lt;br /&gt;
You should now be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-n3xx-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
Using the default configuration, the serial console will show all kernel log messages (which are not available when using SSH), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or boot-loader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
====Connecting to the microcontroller====&lt;br /&gt;
&lt;br /&gt;
Using the Serial Console interface, it is possible to connect to the STM32 microcontroller with the command below. The STM32 controls the power sequencing and several other low level device operations.&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6CB5-if01-port0 115200&lt;br /&gt;
&lt;br /&gt;
The STM32 interface provides a very simple prompt. The command &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt; will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it (i.e., emulating a power button press) and other low-level diagnostics.&lt;br /&gt;
&lt;br /&gt;
===Connecting to the ARM via SSH===&lt;br /&gt;
By default, the RJ45 1Gb management interface is configured to be assigned a DHCP IP address. &lt;br /&gt;
&lt;br /&gt;
If you have access to a network which provides a DHCP server (such as a common router's LAN), attach the RJ45 1Gb port to this network. Details vary by vendor, however, most router management interfaces will provide a list of attached devices to the LAN including their IP address.&lt;br /&gt;
&lt;br /&gt;
Without access to a router management interface, you can identify the IP address by connecting to the ARM CPU via Serial Console as detailed in the section above and running the command &amp;lt;code&amp;gt;ip a&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ip a&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.1.151/24 brd 192.168.1.255 scope global dynamic eth0&lt;br /&gt;
       valid_lft 42865sec preferred_lft 42865sec&lt;br /&gt;
3: sfp0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 9000 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.10.2/24 brd 192.168.10.255 scope global sfp0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
4: sfp1: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 9000 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do not have access to a network with a DHCP server, you can create one using the Linux utility &amp;lt;code&amp;gt;dnsmasq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ sudo dnsmasq -i &amp;lt;ETHERNET_ADAPTER_NAME&amp;gt; --dhcp-range=192.168.1.151,192.168.1.254 --except-interface=lo --bind-dynamic --no-daemon&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the value &amp;lt;code&amp;gt;&amp;lt;ETHERNET_ADAPTER_NAME&amp;gt;&amp;lt;/code&amp;gt; to match the interface you would like to create a DHCP server on.&lt;br /&gt;
&lt;br /&gt;
After the device has obtained an IP address, you can remotely log into it from a Linux or macOS system with SSH, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ssh root@192.168.1.151&lt;br /&gt;
&lt;br /&gt;
NOTE: The IP address may vary depending on your network setup.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password default password is empty/blank.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the SSH connection can be established using the third-party program ​Putty​. &lt;br /&gt;
&lt;br /&gt;
After logging in, you should be presented with a shell like the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-n3xx-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
==Updating the Linux File System==&lt;br /&gt;
Before operating the device, it is​ ​strongly​ recommended to update to the latest version of the Embedded Linux file system. If you are operating the device in Network Mode, the version of UHD running on the host machine and N3xx USRP must match. &lt;br /&gt;
&lt;br /&gt;
There is two ways to update the file system for the N3xx USRP: &lt;br /&gt;
&lt;br /&gt;
1. Mender&lt;br /&gt;
&lt;br /&gt;
2. Physically remove microSD card from device and write a new file system to the microSD card. &lt;br /&gt;
&lt;br /&gt;
===File System Partition Layout===&lt;br /&gt;
The SD Card is divided into four partitions. There is two root file system partitions, a boot partition and a data partition. &lt;br /&gt;
&lt;br /&gt;
Any data you would like to preserve through Mender updates should be saved to the &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; partition, which is mounted at &amp;lt;code&amp;gt;/data&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Updating the file system with Mender===&lt;br /&gt;
Mender is third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website https://mender.io). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Users can host their own local Mender server, or use servers hosted by Mender as a paid service; contact Mender for more information. &lt;br /&gt;
&lt;br /&gt;
====Mender Update Process====&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted. Any data stored in the root partitions will be permanently lost with a Mender update.&lt;br /&gt;
&lt;br /&gt;
After updating a partition with Mender, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched, which presumably is in a working state. Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To obtain the file system Mender image (these are files with a &amp;lt;code&amp;gt;.mender&amp;lt;/code&amp;gt; suffix), run the following command on the host computer with Internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader -t mender -t n3xx --yes&lt;br /&gt;
&lt;br /&gt;
Example Output:    &lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    451639 kB / 451639 kB (100%) n3xx_common_mender_default-v3.14.0.0.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
NOTE: In the output of the command, the folder destination where the images are saved is printed out.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to copy this Mender file system image to the USRP N3xx. This can be done with the Linux utility &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ scp /usr/local/share/uhd/images/usrp_n3xx_fs.mender root@192.168.1.51:~/. &lt;br /&gt;
&lt;br /&gt;
Note: The path and IP may different for your configuration, the command above assumes you're using the default installation path of &amp;lt;code&amp;gt;/usr/local&amp;lt;/code&amp;gt; and that the N3xx's IP is &amp;lt;code&amp;gt;192.168.1.51&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
After copying the Mender file system image to the N3xx, connect to the N3xx using either the Serial Console, or via SSH to gain shell access.&lt;br /&gt;
&lt;br /&gt;
On the N3xx, run &amp;lt;code&amp;gt;mender install /path/to/latest.mender&amp;lt;/code&amp;gt; to update the file system:&lt;br /&gt;
&lt;br /&gt;
    $ mender install /home/root/usrp_n3xx_fs.mender&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
    $ mender install &amp;lt;nowiki&amp;gt;http://server.name/path/to/latest.mender&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a few minutes to complete. After mender has logged a successful update, reboot the device:&lt;br /&gt;
    $ reboot&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so that the boot loader knows to permanently boot into this partition:&lt;br /&gt;
    $ mender -commit&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried on the N3xx:&lt;br /&gt;
    $ cat /etc/mender/artifact_info&lt;br /&gt;
&lt;br /&gt;
If you are using a Mender server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and you can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
For more information on updating the file-system, refer to the UHD Manual at ​https://uhd.ettus.com​.&lt;br /&gt;
&lt;br /&gt;
===Updating the files system by writing the disk image===&lt;br /&gt;
Please see the separate application note, [[Writing the USRP File System Disk Image to a SD Card]], for step-by-step instructions on writing the file system image to the SD card.&lt;br /&gt;
&lt;br /&gt;
==Updating the Network Configurations==&lt;br /&gt;
The USRP N3xx systemd network configuration files are located at: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    # ls /data/network/&lt;br /&gt;
    eth0.network  int0.network  sfp0.network  sfp1.network&lt;br /&gt;
&lt;br /&gt;
or for older versions of the file system: &amp;lt;code&amp;gt;/etc/systemd/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    # ls /etc/systemd/network/&lt;br /&gt;
    eth0.network  sfp0.network  sfp1.network&lt;br /&gt;
&lt;br /&gt;
For details on configuration please refer to the [https://www.freedesktop.org/software/systemd/man/systemd.network.html systemd-networkd manual pages].&lt;br /&gt;
&lt;br /&gt;
The factory settings are as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
eth0 (DHCP):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=eth0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    DHCP=ipv4&lt;br /&gt;
&lt;br /&gt;
    [DHCP]&lt;br /&gt;
    UseHostname=false&lt;br /&gt;
&lt;br /&gt;
sfp0 (static):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=sfp0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    Address=192.168.10.2/24&lt;br /&gt;
&lt;br /&gt;
    [Link]&lt;br /&gt;
    MTUBytes=9000&lt;br /&gt;
&lt;br /&gt;
sfp1 (static):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=sfp1&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    Address=192.168.20.2/24&lt;br /&gt;
&lt;br /&gt;
    [Link]&lt;br /&gt;
    MTUBytes=9000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional notes on networking:&lt;br /&gt;
&lt;br /&gt;
* Care needs to be taken when editing these files on the device, since &amp;lt;code&amp;gt;vi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;vim&amp;lt;/code&amp;gt; sometimes generates undo files (e.g. &amp;lt;code&amp;gt;/etc/systemd/network/sfp0.network~&amp;lt;/code&amp;gt;), that &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; might accidentally pick up.&lt;br /&gt;
* Temporarily setting the IP addresses or MTU sizes via &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; or other command line tools will only change the value until the next reboot or reload of the FPGA image.&lt;br /&gt;
* If the MTU of the device and host computers differ, streaming issues can occur.&lt;br /&gt;
* Streaming via SFP0 at 1 Gb rates requires a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;&lt;br /&gt;
* Streaming via SFP0 at 10 Gb rates requires a MTU of &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For addition details on network configuration here: https://files.ettus.com/manual/page_usrp_n3xx.html#n3xx_network_configuration&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA Image==&lt;br /&gt;
&lt;br /&gt;
===Network Mode FPGA Image Update===&lt;br /&gt;
The FPGA image should match the version of UHD installed on the host computer, when operated in Network mode. Connect the device to the host computer using either the RJ45 or SFP+ port, refer to the section above for detailed instructions. &lt;br /&gt;
&lt;br /&gt;
To obtain all the FPGA images for a specific version of UHD, run the following command on the host computer with internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader&lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    00006 kB / 00006 kB (100%) usrp1_b100_fw_default-g6bea23d.zip&lt;br /&gt;
    19810 kB / 19810 kB (100%) x3xx_x310_fpga_default-gf1ba32fe.zip&lt;br /&gt;
    02757 kB / 02757 kB (100%) usrp2_n210_fpga_default-g6bea23d.zip&lt;br /&gt;
    02123 kB / 02123 kB (100%) n230_n230_fpga_default-ge57dfe0.zip&lt;br /&gt;
    00522 kB / 00522 kB (100%) usrp1_b100_fpga_default-g6bea23d.zip&lt;br /&gt;
    00491 kB / 00491 kB (100%) b2xx_b200_fpga_default-ge57dfe0.zip&lt;br /&gt;
    02415 kB / 02415 kB (100%) usrp2_n200_fpga_default-g6bea23d.zip&lt;br /&gt;
    08988 kB / 08988 kB (100%) e3xx_e320_fpga_default-g3de8954a.zip&lt;br /&gt;
    23045 kB / 23045 kB (100%) n3xx_n310_fpga_default-g3de8954a.zip&lt;br /&gt;
    00523 kB / 00523 kB (100%) b2xx_b205mini_fpga_default-ge57dfe0.zip&lt;br /&gt;
    18937 kB / 18937 kB (100%) x3xx_x300_fpga_default-gf1ba32fe.zip&lt;br /&gt;
    00017 kB / 00017 kB (100%) octoclock_octoclock_fw_default-g14000041.zip&lt;br /&gt;
    00007 kB / 00007 kB (100%) usrp2_usrp2_fw_default-g6bea23d.zip&lt;br /&gt;
    00009 kB / 00009 kB (100%) usrp2_n200_fw_default-g6bea23d.zip&lt;br /&gt;
    00450 kB / 00450 kB (100%) usrp2_usrp2_fpga_default-g6bea23d.zip&lt;br /&gt;
    00144 kB / 00144 kB (100%) b2xx_common_fw_default-ga69ab0c.zip&lt;br /&gt;
    25107 kB / 25107 kB (100%) n3xx_n320_fpga_default-g3de8954a.zip&lt;br /&gt;
    00464 kB / 00464 kB (100%) b2xx_b200mini_fpga_default-ge57dfe0.zip&lt;br /&gt;
    00319 kB / 00319 kB (100%) usrp1_usrp1_fpga_default-g6bea23d.zip&lt;br /&gt;
    04839 kB / 04839 kB (100%) usb_common_windrv_default-g14000041.zip&lt;br /&gt;
    00009 kB / 00009 kB (100%) usrp2_n210_fw_default-g6bea23d.zip&lt;br /&gt;
    16065 kB / 16065 kB (100%) n3xx_n300_fpga_default-g3de8954a.zip&lt;br /&gt;
    05578 kB / 05578 kB (100%) e3xx_e310_fpga_default-g4bc2c6f.zip&lt;br /&gt;
    00885 kB / 00885 kB (100%) b2xx_b210_fpga_default-ge57dfe0.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE: In the above example output, the Images Destination folder is printed:&lt;br /&gt;
&lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
&lt;br /&gt;
To list the N3xx FPGA images with a full path, run the command:&lt;br /&gt;
&lt;br /&gt;
    $ ls -w 1 /usr/local/share/uhd/images/usrp_n3*.bit&lt;br /&gt;
    &lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n300_fpga_AA.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n300_fpga_HG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n300_fpga_WX.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n300_fpga_XG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n310_fpga_AA.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n310_fpga_HG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n310_fpga_WX.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n310_fpga_XG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n320_fpga_AQ.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n320_fpga_HG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n320_fpga_WX.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n320_fpga_XG.bit&lt;br /&gt;
    /usr/local/share/uhd/images/usrp_n320_fpga_XQ.bit&lt;br /&gt;
&lt;br /&gt;
To update the default &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; variant of FPGA image, run the command:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=n3xx,addr=&amp;lt;N3xx_IP_ADDR&amp;gt;,fpga=HG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    uhd_image_loader --args &amp;quot;type=n3xx,addr=192.168.1.151,fpga=HG&amp;quot;&lt;br /&gt;
    [INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.11.1.HEAD-0-gad6b0935&lt;br /&gt;
    [INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.1.151,type=n3xx,product=n310,serial=313ABDA,claimed=False,skip_init=1&lt;br /&gt;
    [INFO] [MPM.main] Launching USRP/MPM, version: 3.11.1.0-gunknown&lt;br /&gt;
    [INFO] [MPM.main] Spawning RPC process...&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Device serial number: 313ABDA&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Found 2 daughterboard(s).&lt;br /&gt;
    [INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
    [INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
    [INFO] [MPM.RPCServer] RPC server ready!&lt;br /&gt;
    [INFO] [MPM.RPCServer] Spawning watchdog task...&lt;br /&gt;
    [INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
    [INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
    [INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Device serial number: 313ABDA&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Found 2 daughterboard(s).&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To load a different default FPGA image (i.e. &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WG&amp;lt;/code&amp;gt;), modify the device argument &amp;lt;code&amp;gt;fpga=&amp;lt;/code&amp;gt; to a value of &amp;lt;code&amp;gt;fpga=XG&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;fpga=WG&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To specify the path to a custom FPGA image, use the ​&amp;lt;code&amp;gt;--fpga-path&amp;lt;/code&amp;gt;​ argument. &lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=n3xx,addr=&amp;lt;N3xx_IP_ADDR&amp;gt;&amp;quot; --fpga-path=/path/to/custom/fpga.bit&lt;br /&gt;
&lt;br /&gt;
The Verilog code for the FPGA in the USRP N3xx is open-source, and users are free to modify and customize it for their needs. However, certain modifications may result in either bricking the device, or even in physical damage to the unit. Please note that modifications to the FPGA are made at the risk of the user, and may not be covered by the warranty of the device.&lt;br /&gt;
&lt;br /&gt;
===Embedded Mode FPGA Image Update===&lt;br /&gt;
&lt;br /&gt;
It is possible to update the FPGA image when operated in Embedded mode. Connect to the ARM CPU via Serial Console or SSH as detailed in the section above. &lt;br /&gt;
&lt;br /&gt;
Updating the FPGA image from the ARM CPU is the same as detailed above for a Network mode update, except it is not required to provide an &amp;lt;code&amp;gt;addr&amp;lt;/code&amp;gt; device argument. &lt;br /&gt;
&lt;br /&gt;
    uhd_image_loader --args &amp;quot;type=n3xx,fpga=HG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-n3xx-313ABDA:~# uhd_image_loader --args &amp;quot;type=n3xx,fpga=HG&amp;quot;&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.2.0; Boost_106400; UHD_3.11.1.0-0-unknown&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=127.0.0.1,type=n3xx,product=n310,serial=313ABDA,claimed=False,skip_init=1&lt;br /&gt;
[INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
[INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 313ABDA&lt;br /&gt;
[INFO] [MPM.PeriphManager] Found 2 daughterboard(s).&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on updating the FPGA image, refer to the UHD Manual at http://uhd.ettus.com​ .&lt;br /&gt;
&lt;br /&gt;
==Setting Up a Streaming Connection==&lt;br /&gt;
The device supports multiple, high-speed, low-latency interfaces on the SFP+ ports for streaming samples to the host computer. &lt;br /&gt;
&lt;br /&gt;
===1Gb Streaming SFP Port 0===&lt;br /&gt;
Complete the steps below to set up a streaming connection over the 1 Gigabit Ethernet interface on &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When streaming via SFP Port 0 at 1 Gb speeds, it is important that the connection is direct between the Host and USRP. Placing a switch or other network gear between the Host and USRP can reduce throughput of the transport link. It is also generally recommended to avoid using USB to Ethernet Adapters for the high speed streaming interface, as they may limit performance or cause periodic flow control errors. &lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; FPGA image must be loaded for &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt; to operate at 1Gb speeds. If the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 1Gb speeds. &lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's Ethernet adapter as shown below. This interface should be separate from the 1Gb NIC/network which is connected to the 1Gb RJ45 management interface.&lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 1500&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt; at 1Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Insert the ​ RJ45 – SFP+ adapter ​into​ &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt;​ .&lt;br /&gt;
&lt;br /&gt;
3. Connect the adapter to a host computer using the Ethernet cable to SFP0.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above ​&amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown&lt;br /&gt;
below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
    PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.&lt;br /&gt;
    64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=1.06 ms&lt;br /&gt;
    ^C&lt;br /&gt;
    --- 192.168.10.2 ping statistics ---&lt;br /&gt;
    1 packets transmitted, 1 received, 0% packet loss, time 0ms&lt;br /&gt;
    rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms&lt;br /&gt;
    &lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program. &lt;br /&gt;
&lt;br /&gt;
Proceed to the next section &amp;quot;Verifying Device Operation&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===10Gb Streaming SFP Port 1===&lt;br /&gt;
Complete the steps below to set up a streaming connection over the 10 Gigabit Ethernet interface on &amp;lt;code&amp;gt;SFP Port 1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE: Both the &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA images support 10Gb speeds over SFP Port 1. &lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's 10Gb Ethernet adapter as shown below. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.20.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 9000&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating at 10Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Connect the USRP to a host computer using either a 10Gb SFP or Fiber cable to &amp;lt;code&amp;gt;SFP Port 1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above ​&amp;lt;code&amp;gt;SFP Port 1&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
3. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.20.2​&amp;lt;/code&amp;gt; from the host, as shown&lt;br /&gt;
below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.20.2&lt;br /&gt;
&lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program. &lt;br /&gt;
&lt;br /&gt;
Proceed to the next section &amp;quot;Verifying Device Operation&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Dual 10Gb Streaming SFP Ports 0/1===&lt;br /&gt;
Complete the steps below to set up a streaming connections over the Dual 10 Gigabit Ethernet interface on &amp;lt;code&amp;gt;SFP Ports 0/1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image must be loaded for &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt; to operate at 10 Gb speeds. If the &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 10 Gb speeds. &lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's #1 10Gb Ethernet adapter as shown below. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 9000&lt;br /&gt;
&lt;br /&gt;
2. Configure your Host's #2 10Gb Ethernet adapter as shown below. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.20.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 9000&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating at 10Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;9000&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Connect the USRP to a host computer using either a 10Gb SFP or Fiber cables to &amp;lt;code&amp;gt;SFP Ports 0/1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The ​Green LEDs​ above ​&amp;lt;code&amp;gt;SFP Ports 0/1&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the &amp;lt;code&amp;gt;SFP Port 0&amp;lt;/code&amp;gt; connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
&lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program. &lt;br /&gt;
&lt;br /&gt;
5. To test the &amp;lt;code&amp;gt;SFP Port 1&amp;lt;/code&amp;gt; connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.20.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.20.2&lt;br /&gt;
&lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program. &lt;br /&gt;
&lt;br /&gt;
Proceed to the next section &amp;quot;Verifying Device Operation&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For more details on Network Setup and Configuration, please see the “Interfaces and Connectivity” section on the [[N300/N310]] or [[N320/N321]] hardware resources pages.&lt;br /&gt;
&lt;br /&gt;
==Verifying Device Operation==&lt;br /&gt;
Once you have successfully setup a management interface and streaming interface, you can now verify the devices operation using the included UHD utilities.&lt;br /&gt;
&lt;br /&gt;
===Subdevice Specification Mapping===&lt;br /&gt;
====N300====&lt;br /&gt;
The USRP N300 contains 2 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF0-1&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
* RF0 = A:0&lt;br /&gt;
* RF1 = A:1&lt;br /&gt;
&lt;br /&gt;
====N310====&lt;br /&gt;
The USRP N310 contains 4 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF0-3&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
=====UHD 3.11.x.x - 3.12.x.x=====&lt;br /&gt;
* RF0 = A:0&lt;br /&gt;
* RF1 = B:0&lt;br /&gt;
* RF2 = C:0&lt;br /&gt;
* RF3 = D:0&lt;br /&gt;
&lt;br /&gt;
=====UHD 3.13.x.x+=====&lt;br /&gt;
* RF0 = A:0&lt;br /&gt;
* RF1 = A:1&lt;br /&gt;
* RF2 = B:0&lt;br /&gt;
* RF3 = B:1&lt;br /&gt;
&lt;br /&gt;
====N320====&lt;br /&gt;
The USRP N320 contains 2 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF0-1&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
* RF0 = A:0&lt;br /&gt;
* RF1 = B:0&lt;br /&gt;
&lt;br /&gt;
====N321====&lt;br /&gt;
The USRP N321 contains 2 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF0-1&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
* RF0 = A:0&lt;br /&gt;
* RF1 = B:0&lt;br /&gt;
&lt;br /&gt;
Additional details of UHD Subdevice Specifications can be found here in the UHD Manual: http://files.ettus.com/manual/page_configuration.html#config_subdev&lt;br /&gt;
&lt;br /&gt;
===Supported Sample Rates===&lt;br /&gt;
&lt;br /&gt;
The USRP N300/N310 supports the three fixed Master Clock Rates listed below. &lt;br /&gt;
&lt;br /&gt;
* 122.88 MHz&lt;br /&gt;
* 125.00 MHz&lt;br /&gt;
* 153.60 MHz&lt;br /&gt;
&lt;br /&gt;
The USRP N320/N321 supports the three fixed Master Clock Rates listed below. &lt;br /&gt;
&lt;br /&gt;
* 200.00 MHz&lt;br /&gt;
* 245.76 MHz&lt;br /&gt;
* 250.00 MHz&lt;br /&gt;
&lt;br /&gt;
Sample rates as delivered to/from the host computer for USRP devices are constrained to follow several important rules.&lt;br /&gt;
&lt;br /&gt;
It is important to understand that strictly-integer decimation and interpolation are used within USRP hardware to meet the requested sample rate requirements of the application at hand. That means that the desired sample rate must meet the requirement that master-clock-rate/desired-sample-rate be an integer ratio. Further, it is strongly desirable for that ratio to be even. This ratio is the decimation (down-conversion) or interpolation (up-conversion) factor. The decimation or interpolation factor may be between 1 and 1024. There are further constraints on the decimation or interpolation factor. If the decimation or interpolation factor exceeds 128, then it must be evenly divisible by 2. If the decimation or interpolation factor exceeds 256, then it must be evenly divisible by 4.&lt;br /&gt;
&lt;br /&gt;
====Example Sample Rates====&lt;br /&gt;
Listed below are common sample rates for the given master clock rates. This is not a complete listing of the supported sample rates.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Master Clock Rate&lt;br /&gt;
!colspan=&amp;quot;20&amp;quot;|Decimation / Interpolation Rate &amp;lt;br&amp;gt; Host Sample Rate [Msps]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 14&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 16&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 18&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 32&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 64&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 100&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 128&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 200&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 256&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 512&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1024&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 122.88e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 61.44e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 30.72e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20.48e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 15.36e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.288e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10.24e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8.7771e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 7.68e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.8267e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.144e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4.096e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 3.84e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.92e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.2288e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 960e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 614.4e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 480e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 240e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 120e3&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 62.5e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 31.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20.833e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 15.625e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.5e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10.417e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8.9286e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 7.8125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.9444e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4.1667e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 3.90625e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.953125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 976.5625e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 625e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 488.28125e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 244.14e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 122.07e3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 153.6e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 76.8e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 38.4e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 25.6e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 19.2e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 15.36e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.8e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10.971e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 9.6e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8.5333e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 7.68e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 5.12e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4.8e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2.4e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.536e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.2e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 768e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 600e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 300e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 150e3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====N320/N321 Example Sample Rates====&lt;br /&gt;
Listed below are common sample rates for the given master clock rates. This is not a complete listing of the supported sample rates.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Master Clock Rate&lt;br /&gt;
!colspan=&amp;quot;20&amp;quot;|Decimation / Interpolation Rate &amp;lt;br&amp;gt; Host Sample Rate [Msps]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 14&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 16&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 18&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 30&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 32&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 64&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 100&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 128&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 200&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 256&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 512&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1024&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 200e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 100e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 50e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 33.33e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 16.66e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 14.2857e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.5e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 11.11e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.667e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 3.125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.5625e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 781.25e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 390.625e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 195.3125e3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 245.76e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 122.88e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 61.44e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 30.72e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20.48e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 15.36e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.288e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10.24e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8.7771e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 7.68e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.8267e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.144e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4.096e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 3.84e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.92e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.2288e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 960e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 614.4e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 480e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 240e3&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 250e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 62.5e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 31.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 20.833e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 15.625e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 12.5e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 10.417e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 8.9286e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 7.8125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.9444e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 6.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 4.1667e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 3.90625e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.953125e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 1.25e6&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 976.5625e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 625e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 488.28125e3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 244.14e3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Additional information on Sample Rates can be found here in the UHD Manual: http://files.ettus.com/manual/page_general.html#general_sampleratenotes&lt;br /&gt;
&lt;br /&gt;
===Probe the USRP===&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
The UHD utility &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt; provides detailed information of the USRP device.&lt;br /&gt;
&lt;br /&gt;
From your host computer, run the command &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$  uhd_usrp_probe &lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.HEAD-0-ga0a71d10&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.10.2,type=n3xx,product=n310,serial=313ABDA,claimed=False,addr=192.168.10.2&lt;br /&gt;
[INFO] [MPM.main] Launching USRP/MPM, version: 3.13.1.0-gd3b7e90a&lt;br /&gt;
[INFO] [MPM.main] Spawning RPC process...&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 313ABDA&lt;br /&gt;
[INFO] [MPM.PeriphManager] Initialized 2 daughterboard(s).&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `time_source=internal,clock_source=internal'.&lt;br /&gt;
[INFO] [MPM.RPCServer] RPC server ready!&lt;br /&gt;
[INFO] [MPM.RPCServer] Spawning watchdog task...&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1355 MB/s)&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `mgmt_addr=192.168.10.2,clock_source=internal,time_source=internal,product=n310'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1358 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1355 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1345 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000011312)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: N300-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: ni-n3xx-313ABDA&lt;br /&gt;
|   |   eeprom_version: 1&lt;br /&gt;
|   |   mpm_version: 3.13.1.0-gd3b7e90a&lt;br /&gt;
|   |   pid: 16962&lt;br /&gt;
|   |   product: n310&lt;br /&gt;
|   |   rev: 3&lt;br /&gt;
|   |   rpc_connection: remote&lt;br /&gt;
|   |   serial: 313ABDA&lt;br /&gt;
|   |   type: n3xx&lt;br /&gt;
|   |   MPM Version: 1.2&lt;br /&gt;
|   |   FPGA Version: 5.2&lt;br /&gt;
|   |   RFNoC capable: Yes&lt;br /&gt;
|   |   &lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo, sfp0&lt;br /&gt;
|   |   Clock sources: external, internal, gpsdo&lt;br /&gt;
|   |   Sensors: gps_tpv, ref_locked, gps_time, gps_locked, temp, gps_sky, fan&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, LOCAL&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 75.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, LOCAL&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 75.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9371 Dual ADC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: B&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, LOCAL&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 75.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, LOCAL&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 75.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: B&lt;br /&gt;
|   |   |   |   Name: AD9371 Dual ADC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 65.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 65.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9371 Dual DAC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: B&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 65.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Magnesium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9371_lo_locked, lowband_lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 65.0 step 0.5 dB&lt;br /&gt;
|   |   |   |   Gain range rfic: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range dsa: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Gain range amp: 0.0 to 0.0 step 0.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 100000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: B&lt;br /&gt;
|   |   |   |   Name: AD9371 Dual DAC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RFNoC blocks on this device:&lt;br /&gt;
|   |   |   &lt;br /&gt;
|   |   |   * DmaFIFO_0&lt;br /&gt;
|   |   |   * Radio_0&lt;br /&gt;
|   |   |   * Radio_1&lt;br /&gt;
|   |   |   * DDC_0&lt;br /&gt;
|   |   |   * DDC_1&lt;br /&gt;
|   |   |   * DUC_0&lt;br /&gt;
|   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====N320====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$ uhd_usrp_probe &lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106600; UHD_3.14.0.0-0-g6875d061&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=127.0.0.1,type=n3xx,product=n320,serial=3181FFA,claimed=False&lt;br /&gt;
[INFO] [MPM.main] Launching USRP/MPM, version: 3.14.0.0-g6875d061&lt;br /&gt;
[INFO] [MPM.main] Spawning RPC process...&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 3181FFA&lt;br /&gt;
[INFO] [MPM.Rhodium-0] Successfully loaded all peripherals!&lt;br /&gt;
[INFO] [MPM.Rhodium-1] Successfully loaded all peripherals!&lt;br /&gt;
[INFO] [MPM.PeriphManager] Initialized 2 daughterboard(s).&lt;br /&gt;
[INFO] [MPM.PeriphManager] No QSFP board detected: Assuming it is disabled in the device tree overlay (e.g., HG, XG images).&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `time_source=internal,clock_source=internal'.&lt;br /&gt;
[INFO] [MPM.Rhodium-0] init() called with args `time_source=internal,clock_source=internal'&lt;br /&gt;
[INFO] [MPM.Rhodium-1] init() called with args `time_source=internal,clock_source=internal'&lt;br /&gt;
[INFO] [MPM.Rhodium-0.init.LMK04828] LMK initialized and locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-1.init.LMK04828] LMK initialized and locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-1.DAC37J82] DAC PLL Locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-1.AD9695] ADC PLL Locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-1.init] JESD204B Link Initialization &amp;amp; Training Complete&lt;br /&gt;
[INFO] [MPM.Rhodium-0.DAC37J82] DAC PLL Locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-0.AD9695] ADC PLL Locked!&lt;br /&gt;
[INFO] [MPM.Rhodium-0.init] JESD204B Link Initialization &amp;amp; Training Complete&lt;br /&gt;
[INFO] [MPM.RPCServer] RPC server ready!&lt;br /&gt;
[INFO] [MPM.RPCServer] Spawning watchdog task...&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `mgmt_addr=127.0.0.1,clock_source=internal,time_source=internal,product=n320'.&lt;br /&gt;
[INFO] [MPM.Rhodium-0] init() called with args `mgmt_addr=127.0.0.1,clock_source=internal,time_source=internal,product=n320'&lt;br /&gt;
[INFO] [MPM.Rhodium-1] init() called with args `mgmt_addr=127.0.0.1,clock_source=internal,time_source=internal,product=n320'&lt;br /&gt;
[INFO] [0/Replay_0] Initializing block control (NOC ID: 0x4E91A00000000004)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000000320)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000000320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/FIFO_0] Initializing block control (NOC ID: 0xF1F0000000000000)&lt;br /&gt;
[INFO] [0/FIFO_1] Initializing block control (NOC ID: 0xF1F0000000000000)&lt;br /&gt;
  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: N300-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: ni-n3xx-3181FFA&lt;br /&gt;
|   |   eeprom_version: 2&lt;br /&gt;
|   |   mpm_version: 3.14.0.0-g6875d061&lt;br /&gt;
|   |   pid: 16962&lt;br /&gt;
|   |   product: n320&lt;br /&gt;
|   |   rev: 6&lt;br /&gt;
|   |   rpc_connection: local&lt;br /&gt;
|   |   serial: 3181FFA&lt;br /&gt;
|   |   type: n3xx&lt;br /&gt;
|   |   MPM Version: 1.2&lt;br /&gt;
|   |   FPGA Version: 5.3&lt;br /&gt;
|   |   FPGA git hash: 3de8954.clean&lt;br /&gt;
|   |   RFNoC capable: Yes&lt;br /&gt;
|   |   &lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo, sfp0&lt;br /&gt;
|   |   Clock sources: external, internal, gpsdo&lt;br /&gt;
|   |   Sensors: gps_tpv, temp, gps_sky, fan, gps_time, gps_locked, ref_locked, gps_gpgga&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: A&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 3175A79&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: A&lt;br /&gt;
|   |   |   |   Name: ad9695-625&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: B&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 3175A67&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: B&lt;br /&gt;
|   |   |   |   Name: ad9695-625&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: A&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 3175A79&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: A&lt;br /&gt;
|   |   |   |   Name: dac37j82&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: B&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 3175A67&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: B&lt;br /&gt;
|   |   |   |   Name: dac37j82&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RFNoC blocks on this device:&lt;br /&gt;
|   |   |   &lt;br /&gt;
|   |   |   * Replay_0&lt;br /&gt;
|   |   |   * Radio_0&lt;br /&gt;
|   |   |   * Radio_1&lt;br /&gt;
|   |   |   * DDC_0&lt;br /&gt;
|   |   |   * DDC_1&lt;br /&gt;
|   |   |   * DUC_0&lt;br /&gt;
|   |   |   * DUC_1&lt;br /&gt;
|   |   |   * FIFO_0&lt;br /&gt;
|   |   |   * FIFO_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====N321====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ uhd_usrp_probe&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.1 20180712 (Red Hat 7.3.1-6); Boost_106400; UHD_3.14.0.0-0-g6875d061&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.20.2,type=n3xx,product=n320,serial=3166646,claimed=False,addr=192.168.20.2&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `time_source=internal,clock_source=internal,product=n320,mgmt_addr=192.168.20.2'.&lt;br /&gt;
[INFO] [MPM.Rhodium-0] init() called with args `time_source=internal,clock_source=internal,product=n320,mgmt_addr=192.168.20.2'&lt;br /&gt;
[INFO] [MPM.Rhodium-1] init() called with args `time_source=internal,clock_source=internal,product=n320,mgmt_addr=192.168.20.2'&lt;br /&gt;
[INFO] [0/Replay_0] Initializing block control (NOC ID: 0x4E91A00000000004)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000000320)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000000320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/FIFO_0] Initializing block control (NOC ID: 0xF1F0000000000000)&lt;br /&gt;
[INFO] [0/FIFO_1] Initializing block control (NOC ID: 0xF1F0000000000000)&lt;br /&gt;
  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: N300-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: ni-n3xx-3166646&lt;br /&gt;
|   |   eeprom_version: 2&lt;br /&gt;
|   |   mpm_version: 3.14.0.0-g6875d061&lt;br /&gt;
|   |   pid: 16962&lt;br /&gt;
|   |   product: n320&lt;br /&gt;
|   |   rev: 6&lt;br /&gt;
|   |   rpc_connection: remote&lt;br /&gt;
|   |   serial: 3166646&lt;br /&gt;
|   |   type: n3xx&lt;br /&gt;
|   |   MPM Version: 1.2&lt;br /&gt;
|   |   FPGA Version: 5.3&lt;br /&gt;
|   |   FPGA git hash: 3de8954.clean&lt;br /&gt;
|   |   RFNoC capable: Yes&lt;br /&gt;
|   |   &lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo, sfp0&lt;br /&gt;
|   |   Clock sources: external, internal, gpsdo&lt;br /&gt;
|   |   Sensors: gps_sky, gps_time, gps_gpgga, gps_locked, fan, gps_tpv, ref_locked, temp&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: B&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 316D814&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: B&lt;br /&gt;
|   |   |   |   Name: ad9695-625&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: A&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 316D810&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, RX2, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: A&lt;br /&gt;
|   |   |   |   Name: ad9695-625&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: B&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 316D814&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: B&lt;br /&gt;
|   |   |   |   Name: dac37j82&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: A&lt;br /&gt;
|   |   |   ID: Unknown (0x0152)&lt;br /&gt;
|   |   |   Serial: 316D810&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Rhodium&lt;br /&gt;
|   |   |   |   Antennas: TX/RX, CAL, TERM&lt;br /&gt;
|   |   |   |   Sensors: lo_locked&lt;br /&gt;
|   |   |   |   Freq range: 1.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range all: 0.0 to 60.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 250000000.0 to 250000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: &lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: A&lt;br /&gt;
|   |   |   |   Name: dac37j82&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RFNoC blocks on this device:&lt;br /&gt;
|   |   |   &lt;br /&gt;
|   |   |   * Replay_0&lt;br /&gt;
|   |   |   * Radio_0&lt;br /&gt;
|   |   |   * Radio_1&lt;br /&gt;
|   |   |   * DDC_0&lt;br /&gt;
|   |   |   * DDC_1&lt;br /&gt;
|   |   |   * DUC_0&lt;br /&gt;
|   |   |   * DUC_1&lt;br /&gt;
|   |   |   * FIFO_0&lt;br /&gt;
|   |   |   * FIFO_1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you see warnings such as:&lt;br /&gt;
&lt;br /&gt;
    [WARNING] [UDP] The recv buffer could not be resized sufficiently.&lt;br /&gt;
&lt;br /&gt;
You need to resize the socket buffers for your network interface card:&lt;br /&gt;
&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=288000&lt;br /&gt;
    sudo sysctl -w net.core.wmem_max=288000&lt;br /&gt;
    sudo sysctl -w net.core.rmem_max=33554432&lt;br /&gt;
&lt;br /&gt;
===ASCII Art Example===&lt;br /&gt;
The UHD driver includes several example programs, which may serve as test programs or the basis for your application program. The source code can be obtained from the UHD repository on github at: https://github.com/EttusResearch/uhd/tree/master/host/examples&lt;br /&gt;
&lt;br /&gt;
You can quickly verify the operation of your USRP N3xx by running the &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; UHD example program. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; utility is a simple console ­based, real-time FFT display tool. It is not graphical in nature, so it can be easily run over an SSH connection within a terminal window, and does not need any graphical capability, such as X Windows, to be installed. It can also be run over a serial console connection, although this is not recommended, as the formatting may not render correctly.&lt;br /&gt;
&lt;br /&gt;
You can run a simple test of the N3xx USRP by connecting an antenna and observing the spectrum of a commercial FM radio station in real-time, following the steps below:&lt;br /&gt;
&lt;br /&gt;
1. Attach an antenna to the &amp;lt;code&amp;gt;Ch0/RX2&amp;lt;/code&amp;gt;­ antenna port of the N3xx.&lt;br /&gt;
&lt;br /&gt;
2. From your host computer, run the command:&lt;br /&gt;
&lt;br /&gt;
'''N300/N310'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /usr/local/lib/uhd/examples/rx_ascii_art_dft --args &amp;quot;master_clock_rate=125e6,mgmt_addr=192.168.1.151,addr=192.168.10.2&amp;quot; --freq 98.5e6 --rate 2.5e6 --gain 50 --ref-lvl=&amp;quot;-50&amp;quot; --dyn-rng 90 --ant &amp;quot;RX2&amp;quot; --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''N320/N321'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /usr/local/lib/uhd/examples/rx_ascii_art_dft --args &amp;quot;master_clock_rate=250e6,mgmt_addr=192.168.1.151,addr=192.168.10.2&amp;quot; --freq 98.5e6 --rate 2.5e6 --gain 50 --ref-lvl=&amp;quot;-50&amp;quot; --dyn-rng 90 --ant &amp;quot;RX2&amp;quot; --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the command­ line argument &amp;lt;code&amp;gt;freq&amp;lt;/code&amp;gt; ​above to specify a tuning frequency for a strong local FM radio station. You will also need to update the IP Address to match your device IP.&lt;br /&gt;
&lt;br /&gt;
3. You should see a real-time FFT display of 2.5 MHz of spectrum, centered at the specified tuning frequency.&lt;br /&gt;
&lt;br /&gt;
4. Type &amp;quot;&amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;&amp;quot; or &amp;lt;code&amp;gt;Ctrl­-C&amp;lt;/code&amp;gt; to stop the program and to return to the Linux command line.&lt;br /&gt;
&lt;br /&gt;
5. You can run with the &amp;lt;code&amp;gt;​­­--help&amp;lt;/code&amp;gt; ​argument to see a description of all available command-line options.&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ /usr/local/lib/uhd/examples/rx_ascii_art_dft --args &amp;quot;master_clock_rate=125e6,mgmt_addr=192.168.1.151,addr=192.168.10.2&amp;quot; --freq 98.5e6 --rate 2.5e6 --gain 50 --ref-lvl=&amp;quot;-50&amp;quot; --dyn-rng 90 --ant &amp;quot;RX2&amp;quot; --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Creating the usrp device with: master_clock_rate=125e6,mgmt_addr=192.168.1.151,addr=192.168.10.2...&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.11.1.HEAD-0-gad6b0935&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.1.151,type=n3xx,product=n310,serial=313ABDA,claimed=False,master_clock_rate=125e6,addr=192.168.10.2&lt;br /&gt;
[INFO] [MPM.main] Launching USRP/MPM, version: 3.11.1.0-gunknown&lt;br /&gt;
[INFO] [MPM.main] Spawning RPC process...&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 313ABDA&lt;br /&gt;
[INFO] [MPM.PeriphManager] Found 2 daughterboard(s).&lt;br /&gt;
[INFO] [MPM.RPCServer] RPC server ready!&lt;br /&gt;
[INFO] [MPM.RPCServer] Spawning watchdog task...&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `mgmt_addr=192.168.1.151,product=n310,master_clock_rate=125e6'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000004)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1336 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1338 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1346 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1350 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000000310)&lt;br /&gt;
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000000310)&lt;br /&gt;
[INFO] [0/Radio_2] Initializing block control (NOC ID: 0x12AD100000000310)&lt;br /&gt;
[INFO] [0/Radio_3] Initializing block control (NOC ID: 0x12AD100000000310)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DDC_2] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DDC_3] Initializing block control (NOC ID: 0xDDC0000000000001)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/DUC_2] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
[INFO] [0/DUC_3] Initializing block control (NOC ID: 0xD0C0000000000000)&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: N300-Series Device&lt;br /&gt;
  Mboard 0: ni-n3xx-313ABDA&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: B&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 2&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: C&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
  TX Channel: 3&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: D&lt;br /&gt;
    TX Subdev: Magnesium&lt;br /&gt;
&lt;br /&gt;
Setting RX Rate: 2.500000 Msps...&lt;br /&gt;
Actual RX Rate: 2.500000 Msps...&lt;br /&gt;
&lt;br /&gt;
Setting RX Freq: 98.500000 MHz...&lt;br /&gt;
Actual RX Freq: 98.500000 MHz...&lt;br /&gt;
&lt;br /&gt;
Setting RX Gain: 50.000000 dB...&lt;br /&gt;
Actual RX Gain: 50.000000 dB...&lt;br /&gt;
&lt;br /&gt;
Checking RX: all_los: locked ...&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Benchmarking your system===&lt;br /&gt;
Included with the UHD driver example programs is a utility, &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; to benchmark the transport link of the system. &lt;br /&gt;
&lt;br /&gt;
A system's maximum performance is dependent upon many factors. &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; will exercise the transport link and CPU of the system. &lt;br /&gt;
&lt;br /&gt;
====1 Gb Interface====&lt;br /&gt;
NOTE: This example requires the &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
'''N300/N310'''&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RF0/A:0&amp;quot;, at a rate of 3.84 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.10.2,master_clock_rate=122.88e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 3.84e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 3.84e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''N310'''&lt;br /&gt;
&lt;br /&gt;
This example will test four full-duplex streams at 1.25 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.10.2,master_clock_rate=125e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1,2,3&amp;quot; \&lt;br /&gt;
    --rx_rate 1.25e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot; \&lt;br /&gt;
    --tx_rate 1.25e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''N320/N321'''&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RF0/A:0&amp;quot;, at a rate of 3.84 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.10.2,master_clock_rate=245.76e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 3.84e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 3.84e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When streaming samples over a 1 Gb transport link, the maximum accumulative rate for all channels is 25 MS/s with a &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; OTW format. To achieve higher streaming rates, it is recommended to use the 10 Gb interfaces.&lt;br /&gt;
&lt;br /&gt;
====10 Gb Interface SFP 1====&lt;br /&gt;
NOTE: This example will work with either the &amp;lt;code&amp;gt;HG&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image.&lt;br /&gt;
&lt;br /&gt;
'''N300/N310'''&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RF0/A:0&amp;quot;, at a rate of 31.25 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.20.2,master_clock_rate=125e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 31.25e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 31.25e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
'''N320/N321'''&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RF0/A:0&amp;quot;, at a rate of 31.25 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.20.2,master_clock_rate=250e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 31.25e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 31.25e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
'''N310'''&lt;br /&gt;
&lt;br /&gt;
This example will test four full-duplex streams at 30.72 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.20.2,master_clock_rate=122.88e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1,2,3&amp;quot; \&lt;br /&gt;
    --rx_rate 30.72e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot; \&lt;br /&gt;
    --tx_rate 30.72e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''N320/N321'''&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 30.72 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.20.2,master_clock_rate=245.76e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1,2,3&amp;quot; \&lt;br /&gt;
    --rx_rate 30.72e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 B:0&amp;quot; \&lt;br /&gt;
    --tx_rate 30.72e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 B:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Dual 10 Gb Interface====&lt;br /&gt;
NOTE: This example requires the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
'''N310'''&lt;br /&gt;
&lt;br /&gt;
This example will test four full-duplex streams at 62.5 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=125e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1,2,3&amp;quot; \&lt;br /&gt;
    --rx_rate 62.5e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot; \&lt;br /&gt;
    --tx_rate 62.5e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1 B:0 B:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''N320/N321'''&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 62.5 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;type=n3xx,mgmt_addr=192.168.1.151,addr=192.168.10.2,second_addr=192.168.20.2,master_clock_rate=250e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1,2,3&amp;quot; \&lt;br /&gt;
    --rx_rate 62.5e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 B:0&amp;quot; \&lt;br /&gt;
    --tx_rate 62.5e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 B:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==USRP N3xx Device Specific Operations==&lt;br /&gt;
&lt;br /&gt;
===White Rabbit Ethernet-Based Synchronization===&lt;br /&gt;
* [[Using Ethernet-Based Synchronization on the USRP™ N3xx Devices]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===N320/N321===&lt;br /&gt;
* [[USRP N320/N321 LO Distribution]]&lt;br /&gt;
* [[5G NR EVM Measurements with the USRP N320/N321]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Turning the Device Off/On===&lt;br /&gt;
To avoid damaging the file system and causing any corruption, do not turn the device off with the power button without first shutting down the system. Use this command to cleanly and properly shut the system down:&lt;br /&gt;
&lt;br /&gt;
    shutdown ­-h now&lt;br /&gt;
&lt;br /&gt;
===Enable Auto Booting===&lt;br /&gt;
Auto booting of the N3xx when power is applied can be configured by enabling the flag on the device's EEPROM with the following command:&lt;br /&gt;
&lt;br /&gt;
    eeprom-set-flags 0x1&lt;br /&gt;
&lt;br /&gt;
===Default Password===&lt;br /&gt;
The default user is &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; and the password is empty (no password).&lt;br /&gt;
&lt;br /&gt;
It is recommended to update the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password, which can be done with the command &amp;lt;code&amp;gt;passwd&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    root@ni-n3xx-serial:~# passwd&lt;br /&gt;
    Changing password for root&lt;br /&gt;
    New password: &lt;br /&gt;
    Re-enter new password: &lt;br /&gt;
    passwd: password changed.&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:N300]]&lt;br /&gt;
[[Category:N310]]&lt;br /&gt;
&lt;br /&gt;
[[Category:N320]]&lt;br /&gt;
&lt;br /&gt;
[[Category:N321]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5422</id>
		<title>Using the RFNoC Replay Block in UHD 4</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5422"/>
				<updated>2022-07-15T17:10:24Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add notes specific to E31x devices.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642b'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
This application note guides a user through basic use of the RFNoC Replay block&lt;br /&gt;
in UHD 4.x and explains how to run the UHD Replay example. This example covers&lt;br /&gt;
the USRP X410, X310/X300, N300/N310/N320 and E320 devices. For UHD 3.x, please&lt;br /&gt;
refer to [[Using_the_RFNoC_Replay_Block|the UHD 3.x replay block Application Note]].&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The FPGA size on E31x devices is limited, so it is not recommended&lt;br /&gt;
for use with the Replay block. In order to fit the Replay block on the FPGA,&lt;br /&gt;
use the E320 or a larger USRP instead.&lt;br /&gt;
&lt;br /&gt;
An introduction to RFNoC with UHD 4.0 and above can be found [[Getting_Started_with_RFNoC_in_UHD_4.0|here]].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of&lt;br /&gt;
arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay&lt;br /&gt;
block, it must be instantiated in the design and connected to the DRAM interface.&lt;br /&gt;
&lt;br /&gt;
The replay block is a standard feature of UHD and RFNoC, and a custom compile of&lt;br /&gt;
UHD is not required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs, so when using these images,&lt;br /&gt;
the following examples can be run without any manual builds of UHD or FPGA images.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
To follow this application note, you need a device with a replay block instantiated,&lt;br /&gt;
and a UHD version recent enough to have the full support for the replay block&lt;br /&gt;
(UHD 4.2 and beyond). To test for the replay block capabilities, connect and&lt;br /&gt;
enable your USRP device, and run the following command:&lt;br /&gt;
&lt;br /&gt;
    uhd_usrp_probe --args &amp;lt;device args&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Insert the appropriate device args for your device, e.g.&lt;br /&gt;
&lt;br /&gt;
    uhd_usrp_probe --args type=x4xx,addr=192.168.30.2&lt;br /&gt;
&lt;br /&gt;
Depending on your device, the output could look like this (truncated):&lt;br /&gt;
&lt;br /&gt;
     _____________________________________________________&lt;br /&gt;
    /&lt;br /&gt;
    |       Device: X400-Series Device&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Mboard: ni-x4xx-&amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   pid: 1040&lt;br /&gt;
    |   |   rev: 4&lt;br /&gt;
    |   |   rev_compat: 4&lt;br /&gt;
    |   |   serial: &amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   MPM Version: 4.0&lt;br /&gt;
    |   |   FPGA Version: 7.6&lt;br /&gt;
    |   |   FPGA git hash: &amp;lt;hash&amp;gt;.clean&lt;br /&gt;
    |   |   RFNoC capable: Yes&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   Time sources:  internal, external, qsfp0, gpsdo&lt;br /&gt;
    |   |   Clock sources: mboard, internal, external, nsync, gpsdo&lt;br /&gt;
    |   |   Sensors: ...&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/DDC#0&lt;br /&gt;
    |   |   * 0/DDC#1&lt;br /&gt;
    |   |   * 0/DUC#0&lt;br /&gt;
    |   |   * 0/DUC#1&lt;br /&gt;
    |   |   * 0/Radio#0&lt;br /&gt;
    |   |   * 0/Radio#1&lt;br /&gt;
    |   |   * 0/Replay#0&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Static connections on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/SEP#0:0==&amp;gt;0/DUC#0:0&lt;br /&gt;
    |   |   * 0/DUC#0:0==&amp;gt;0/Radio#0:0&lt;br /&gt;
    |   |   * 0/Radio#0:0==&amp;gt;0/DDC#0:0&lt;br /&gt;
    |   |   * 0/DDC#0:0==&amp;gt;0/SEP#0:0&lt;br /&gt;
    |   |   * 0/SEP#1:0==&amp;gt;0/DUC#0:1&lt;br /&gt;
    |   |   * 0/DUC#0:1==&amp;gt;0/Radio#0:1&lt;br /&gt;
    |   |   * 0/Radio#0:1==&amp;gt;0/DDC#0:1&lt;br /&gt;
    |   |   * 0/DDC#0:1==&amp;gt;0/SEP#1:0&lt;br /&gt;
    |   |   * 0/SEP#2:0==&amp;gt;0/DUC#1:0&lt;br /&gt;
    |   |   * 0/DUC#1:0==&amp;gt;0/Radio#1:0&lt;br /&gt;
    |   |   * 0/Radio#1:0==&amp;gt;0/DDC#1:0&lt;br /&gt;
    |   |   * 0/DDC#1:0==&amp;gt;0/SEP#2:0&lt;br /&gt;
    |   |   * 0/SEP#3:0==&amp;gt;0/DUC#1:1&lt;br /&gt;
    |   |   * 0/DUC#1:1==&amp;gt;0/Radio#1:1&lt;br /&gt;
    |   |   * 0/Radio#1:1==&amp;gt;0/DDC#1:1&lt;br /&gt;
    |   |   * 0/DDC#1:1==&amp;gt;0/SEP#3:0&lt;br /&gt;
    |   |   * 0/SEP#4:0==&amp;gt;0/Replay#0:0&lt;br /&gt;
    |   |   * 0/Replay#0:0==&amp;gt;0/SEP#4:0&lt;br /&gt;
    |   |   * 0/SEP#5:0==&amp;gt;0/Replay#0:1&lt;br /&gt;
    |   |   * 0/Replay#0:1==&amp;gt;0/SEP#5:0&lt;br /&gt;
    |   |   * 0/SEP#6:0==&amp;gt;0/Replay#0:2&lt;br /&gt;
    |   |   * 0/Replay#0:2==&amp;gt;0/SEP#6:0&lt;br /&gt;
    |   |   * 0/SEP#7:0==&amp;gt;0/Replay#0:3&lt;br /&gt;
    |   |   * 0/Replay#0:3==&amp;gt;0/SEP#7:0&lt;br /&gt;
&lt;br /&gt;
The output tells us that this USRP has a Replay block instantiated (&amp;lt;code&amp;gt;0/Replay#0&amp;lt;/code&amp;gt;).&lt;br /&gt;
It has four static connections to stream endpoints, which also tells us that&lt;br /&gt;
this is a four-port replay block.&lt;br /&gt;
&lt;br /&gt;
If your device does not report a replay block, then you need to load&lt;br /&gt;
an FPGA image which includes this block. See [[#building_fpga|this section]] for instructions on how to do&lt;br /&gt;
this before you proceed. If it does report a block, you can move to the next&lt;br /&gt;
section.&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a&lt;br /&gt;
file containing the samples you wish to replay. This could be generated in&lt;br /&gt;
advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For&lt;br /&gt;
this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;)&lt;br /&gt;
to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000&lt;br /&gt;
samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz.&lt;br /&gt;
Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real&lt;br /&gt;
and 16-bit imaginary components). We can run the program by invoking python from&lt;br /&gt;
the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, enter a command like the following (the path to&lt;br /&gt;
the examples depends on your installation method, for a normal installation via&lt;br /&gt;
apt-get, examples will be located in &amp;lt;code&amp;gt;/usr/lib/uhd/examples&amp;lt;/code&amp;gt; or&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/lib/uhd/examples&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
    $ cd /path/to/examples&lt;br /&gt;
    $ ./replay_samples_from_file --args &amp;lt;device args&amp;gt; --freq 915e6 --gain 10 --file samples.dat --rate 200e6&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the&lt;br /&gt;
FPGA, where they are recorded into the USRP's on-board DRAM. Then, the Replay block&lt;br /&gt;
will play the samples to the radio continuously with a base frequency of 915 MHz,&lt;br /&gt;
creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
Alternatively, use the &amp;lt;code&amp;gt;--nsamps&amp;lt;/code&amp;gt; command line argument to transmit&lt;br /&gt;
a certain number of samples before returning to the command line. Use the&lt;br /&gt;
&amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; argument to see a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
The advantage of this example compared to directly streaming the file to the&lt;br /&gt;
device is twofold:&lt;br /&gt;
&lt;br /&gt;
* The initial upload to DRAM can happen at any link rate. Even when using 1 GbE, this example will work.&lt;br /&gt;
* Once uploaded, the host computer is basically idle. The FPGA will handle the streaming to the radio front-end.&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp source code]&lt;br /&gt;
for &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; may be considered an example&lt;br /&gt;
for best practices on how to use the replay block.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
This block works like a record and playback buffer that uses DRAM on the USRP to&lt;br /&gt;
store samples.&lt;br /&gt;
Data can be streamed to the block, like to any other RFNoC block.&lt;br /&gt;
&lt;br /&gt;
Refer the [https://files.ettus.com/manual/classuhd_1_1rfnoc_1_1replay__block__control.html manual of the replay block controller]&lt;br /&gt;
for a comprehensive description of its features and API calls.&lt;br /&gt;
&lt;br /&gt;
In the following, we shall use the C++ API to demonstrate the most important&lt;br /&gt;
API calls. We will assume there is a replay block controller called&lt;br /&gt;
&amp;lt;code&amp;gt;replay_ctrl&amp;lt;/code&amp;gt; available in the current context, and it is of type&lt;br /&gt;
&amp;lt;code&amp;gt;uhd::rfnoc::replay_block_control::sptr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Recording Data===&lt;br /&gt;
&lt;br /&gt;
Before streaming data to the replay block, it needs to be configured for recording:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives&lt;br /&gt;
on port &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt; into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt;&lt;br /&gt;
and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is&lt;br /&gt;
filled, recording automatically stops. Care should be taken to configure the&lt;br /&gt;
memory buffers so that they do not overlap if more than one Replay block or&lt;br /&gt;
buffer is being used simultaneously.&lt;br /&gt;
&lt;br /&gt;
Call this once for every port that you expect to stream data into.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block&lt;br /&gt;
than the size of the record buffer. Additional data is not accepted or dropped&lt;br /&gt;
by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the&lt;br /&gt;
size of the DRAM on the USRP and how the memory interface is configured on the USRP.&lt;br /&gt;
By default, we expose the entire memory of the device, but it is possible to modify&lt;br /&gt;
&amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; if less memory should be made accessible.&lt;br /&gt;
&lt;br /&gt;
Devices have the following amount of memory:&lt;br /&gt;
{|&lt;br /&gt;
|E310&lt;br /&gt;
|512 MiB&lt;br /&gt;
|-&lt;br /&gt;
|E320&lt;br /&gt;
|2 GiB&lt;br /&gt;
|-&lt;br /&gt;
|N3xx&lt;br /&gt;
|2 GiB&lt;br /&gt;
|-&lt;br /&gt;
|X310&lt;br /&gt;
|1 GiB&lt;br /&gt;
|-&lt;br /&gt;
|X410&lt;br /&gt;
|4 GiB per bank (note: not all banks may be connected)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The currently available memory can be queried using the block controller and the &lt;br /&gt;
&amp;lt;code&amp;gt;get_mem_size()&amp;lt;/code&amp;gt; API call.&lt;br /&gt;
&lt;br /&gt;
To restart recording from the same offset, the following API call can be used:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and&lt;br /&gt;
it resets the internal counters that track how much data has been recorded. If&lt;br /&gt;
a previous recording has taken place then it is a good idea to ensure that&lt;br /&gt;
stale data was not queued up in the RF network on the FPGA from a previous run.&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling&lt;br /&gt;
&amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up&lt;br /&gt;
unexpectedly in the record buffer. If so, it restarts recording then waits&lt;br /&gt;
again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the&lt;br /&gt;
record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected)&lt;br /&gt;
        std::this_thread::sleep_for(100ms);&lt;br /&gt;
&lt;br /&gt;
===Playing Back Data===&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base&lt;br /&gt;
address and size of the playback buffer. To play back previously recorded data,&lt;br /&gt;
set the start address to the same address that was used for the record buffer&lt;br /&gt;
and set the size of the playback buffer to the match the amount of data that&lt;br /&gt;
was recorded. Note that the record and playback buffers do not need to be the&lt;br /&gt;
same, allowing a single Replay block to both record and playback to different&lt;br /&gt;
regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command.&lt;br /&gt;
Playback automatically wraps around to the start of the buffer if more data is&lt;br /&gt;
requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely&lt;br /&gt;
until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only&lt;br /&gt;
the specified number of samples to be played once. Playback can be stopped by issuing&lt;br /&gt;
 a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is&lt;br /&gt;
received (DRAM reads are not aborted mid-transaction). As a result, some data&lt;br /&gt;
will continue to stream from the Replay block after the stop command is issued&lt;br /&gt;
while waiting for the DRAM read to complete and for all the internal buffers to&lt;br /&gt;
empty.&lt;br /&gt;
&lt;br /&gt;
When using the C++ API, the &amp;lt;code&amp;gt;play()&amp;lt;/code&amp;gt; API call is a useful shorthand&lt;br /&gt;
for configuring playback and submitting the stream command at the same time:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;play(buffer_start_byte_address, num_bytes_to_play, replay_chan, start_time, repeat);&lt;br /&gt;
&lt;br /&gt;
In either case, the start time is optional. When given, the first sample to leave&lt;br /&gt;
the block on playback is tagged with this timestamp.&lt;br /&gt;
&lt;br /&gt;
===Memory Alignment and Word Sizes===&lt;br /&gt;
&lt;br /&gt;
There are two memory alignment values that need to be considered when dealing&lt;br /&gt;
with the replay block. The first is the word size, which is the minimum number of&lt;br /&gt;
bytes per DRAM transaction. For most configurations, the word size is 64 bits,&lt;br /&gt;
which means that only even numbers of samples can be recorded or played back&lt;br /&gt;
when using 16-bit complex samples (at 4 bytes per sample). Use the &amp;lt;code&amp;gt;get_word_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
API call to identify the correct word size. The word size can go up to 512 bits.&lt;br /&gt;
&lt;br /&gt;
The second alignment value is the memory's page boundaries. The start addresses&lt;br /&gt;
for record and replay should fall onto a 4 kiB memory boundary to ensure correct&lt;br /&gt;
alignment of data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;building_fpga&amp;quot;&amp;gt;&lt;br /&gt;
==Building Custom FPGA Images with a Replay Block==&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Note: Cloning the repository is only required when building custom FPGA images.&lt;br /&gt;
If the replay block is already built into the USRP's bit file, this is not&lt;br /&gt;
required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs.&lt;br /&gt;
&lt;br /&gt;
If you do require access to the source code, e.g. to build an FPGA image with a&lt;br /&gt;
custom replay block configuration, run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ git clone https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
For the rest of the Application Note, we assume the repository was cloned into&lt;br /&gt;
the location &amp;lt;code&amp;gt;~/src/uhd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need&lt;br /&gt;
to have the Xilinx development tools installed. The specific version required&lt;br /&gt;
depends on the UHD version. Refer to the&lt;br /&gt;
[https://files.ettus.com/manual/md_usrp3_build_instructions.html manual] for the&lt;br /&gt;
correct version for your UHD version, and the installation instructions for&lt;br /&gt;
Vivado in order to install these tools. It is recommended that you use the&lt;br /&gt;
default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Building the FPGA===&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Most bitfiles already include the replay block! This section is&lt;br /&gt;
only relevant if you want to build your own bitfile, or the bitfile you're using&lt;br /&gt;
does not contain the replay block already.&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the&lt;br /&gt;
USRP you plan to use. This is currently a manual step. The instructions below&lt;br /&gt;
are for the X310, but similar instructions apply to other RFNoC-capable&lt;br /&gt;
devices.&lt;br /&gt;
&lt;br /&gt;
To create a custom FPGA image with a replay, you need to create an image core file.&lt;br /&gt;
The following lines are the relevant lines from the&lt;br /&gt;
[https://github.com/EttusResearch/uhd/blob/master/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml X310 default image core file]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      # ... all the other stream endpoints...&lt;br /&gt;
      ep4:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
      ep5:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
    &lt;br /&gt;
    noc_blocks:&lt;br /&gt;
      # ... all the other blocks...&lt;br /&gt;
      replay0:&lt;br /&gt;
        block_desc: 'replay.yml'&lt;br /&gt;
        parameters:&lt;br /&gt;
          NUM_PORTS: 2&lt;br /&gt;
          MEM_ADDR_W: 30&lt;br /&gt;
    &lt;br /&gt;
    connections:&lt;br /&gt;
      # ...connections for all the other blocks...&lt;br /&gt;
      # ep4 to replay0(0)&lt;br /&gt;
      - { srcblk: ep4,     srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
      # replay0(0) to ep4&lt;br /&gt;
      - { srcblk: replay0, srcport: out_0, dstblk: ep4,     dstport: in0  }&lt;br /&gt;
      # ep5 to replay0(1)&lt;br /&gt;
      - { srcblk: ep5,     srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
      # replay0(1) to ep5&lt;br /&gt;
      - { srcblk: replay0, srcport: out_1, dstblk: ep5,     dstport: in0  }&lt;br /&gt;
      # BSP Connections&lt;br /&gt;
      - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      # ...all other clock domains...&lt;br /&gt;
      - { srcblk: _device_, srcport: dram,  dstblk: replay0, dstport: mem  }&lt;br /&gt;
&lt;br /&gt;
As you can see, the replay block requires configuration in up to four sections:&lt;br /&gt;
* For maximum flexibility, every port of the replay block will receive its own stream endpoint. This is not a requirement of the replay block, but allows its flexible use.&lt;br /&gt;
* Of course, the block needs to be declared in the &amp;lt;code&amp;gt;noc_blocks&amp;lt;/code&amp;gt; section. The blocks contain two parameters, NUM_PORTS, and MEM_ADDR_W. The former is the number of ports this RFNoC block may have. The latter is the width of the memory address word, i.e., it is log2(memory_size).&lt;br /&gt;
* It must be connected to the stream endpoints in the &amp;lt;code&amp;gt;connections&amp;lt;/code&amp;gt; section, as well as to the DRAM banks (BSP connection).&lt;br /&gt;
* Finally, the clock domain needs to be connected.&lt;br /&gt;
&lt;br /&gt;
All devices have limits regarding the number of ports and the memory size. The following values may not be exceeded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
E310:&lt;br /&gt;
    NUM_PORTS: 2&lt;br /&gt;
    MEM_ADDR_W: 29&lt;br /&gt;
E320:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 31&lt;br /&gt;
N3xx:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 31&lt;br /&gt;
X310:&lt;br /&gt;
    NUM_PORTS: 2&lt;br /&gt;
    MEM_ADDR_W: 30&lt;br /&gt;
X410:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When the YAML image core file is complete, save it, e.g., as x310_replay_image_core.yml,&lt;br /&gt;
and pass it to the image builder:&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y x310_replay_image_core.yml [ --fpga-dir ~/usr/uhd/fpga ]&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Because the DRAM does not fit by default on the E31x devices, it is&lt;br /&gt;
not included in the build by default. To include the DRAM on E31x builds, set&lt;br /&gt;
the environment variable &amp;lt;code&amp;gt;DRAM=1&amp;lt;/code&amp;gt; before building (e.g.,&lt;br /&gt;
&amp;lt;code&amp;gt;DRAM=1 rfnoc_image_builder ...&amp;lt;/code&amp;gt;). The E320 is the recommended E-series&lt;br /&gt;
device for use with the Replay block.&lt;br /&gt;
&lt;br /&gt;
This will create a bitfile that contains the replay block. It can be loaded onto&lt;br /&gt;
the device using the &amp;lt;code&amp;gt;uhd_image_loader&amp;lt;/code&amp;gt; tool:&lt;br /&gt;
&lt;br /&gt;
    uhd_image_loader --args type=x300,addr=&amp;lt;ip address&amp;gt; --fpga-path=/path/to/usrp_x310_fpga_HG.bit&lt;br /&gt;
&lt;br /&gt;
When this is complete, the replay block is ready to use.&lt;br /&gt;
&lt;br /&gt;
==Source files==&lt;br /&gt;
&lt;br /&gt;
For reference, the following files implement the replay block:&lt;br /&gt;
&lt;br /&gt;
* Verilog/HDL sources: https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_replay&lt;br /&gt;
* C++ Block controller sources (header, block controller, Python bindings, unit tests):&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/include/uhd/rfnoc/replay_block_control.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control.cpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control_python.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/tests/rfnoc_block_tests/replay_block_test.cpp&lt;br /&gt;
* Example: https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5412</id>
		<title>USRP X410 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5412"/>
				<updated>2022-05-13T14:27:59Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Updated instructions for flashing eMMC to fix incorrect filename and add copy arg to bmaptool.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
===X410===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* NI Ettus USRP X410&lt;br /&gt;
* DC Power Supply (12V, 20A)&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to USB-C Cable (1m)&lt;br /&gt;
* Getting Started Guide URL (QR Code)&lt;br /&gt;
* Safety, Environmental, and Regulatory Information&lt;br /&gt;
||[[File:X410.jpg|450px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
* For Network Mode: A host computer with an available 1 or 10 Gigabit Ethernet interface for sample streaming. In addition to the Ethernet interface used for sampling streaming, your host computer will require a separate 1 Gigabit Ethernet interface for command and control streaming.&lt;br /&gt;
 &lt;br /&gt;
* For Stand-Alone Embedded Mode: A host computer with an available 1 Gigabit Ethernet port or a USB 2.0 port to remotely access the embedded Linux operating system running on ARM CPU.&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow metal objects to touch the circuit board while powered.&lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than +14 dBm continuous &amp;lt;=3GHz, +17 dBm continuous &amp;gt;3GHz, or +20dBm more than 5 minutes &amp;gt;3GHz of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
In order to use your Universal Software Radio Peripheral (USRP™), you must have the software tools correctly installed and configured on your host computer. A step-by-step guide for doing this is available at the Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]] Application Notes.&lt;br /&gt;
&lt;br /&gt;
To find the latest release of UHD, see the UHD repository at https://github.com/EttusResearch/uhd.&lt;br /&gt;
&lt;br /&gt;
The USRP X410 requires UHD version 4.1 or later. &lt;br /&gt;
&lt;br /&gt;
'''When you receive a brand-new device, it is strongly recommended that you download the latest filesystem image from the Ettus Research website update the unit. It is not recommended that you use the filesystem from the factory as-is. Instructions on downloading the latest filesystem image and updating it is listed below.'''&lt;br /&gt;
&lt;br /&gt;
'''Note that if you are operating the device in Network Mode, the version of UHD running on the host computer and the USRP X410 must match.'''&lt;br /&gt;
&lt;br /&gt;
==Assembling the X410==&lt;br /&gt;
Inside the kit you will find the X410 and an X410 power supply. Plug these in, connect the 1GbE RJ45 interface to your network, and power on the device by pressing the power button.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The STM32 Microcontroller==&lt;br /&gt;
&lt;br /&gt;
The STM32 microcontroller (also referred to as the &amp;quot;SCU&amp;quot;) controls various low-level features of the X4x0 series motherboard: It controls the power sequencing, reads out fan speeds and some of the temperature sensors. It is connected to the RFSoC via an I2C bus. It is running software based on Chromium EC.&lt;br /&gt;
&lt;br /&gt;
It is possible to log into the STM32 using the serial interface (see Connecting to the Microcontroller). This will allow certain low-level controls, such as remote power cycling should the CPU have become unresponsive for whatever reason.&lt;br /&gt;
&lt;br /&gt;
===Updating the SCU===&lt;br /&gt;
&lt;br /&gt;
The writable SCU image file is stored on the filesystem under /lib/firmware/ni/ec-titanium-revX.RW.bin (where X is a revision compatibility number). To update, simply replace the .bin file with the updated version and reboot.&lt;br /&gt;
&lt;br /&gt;
==eMMC Storage==&lt;br /&gt;
&lt;br /&gt;
The main non-volatile storage of the USRP is a 16 GB eMMC storage. This storage can be made accessible as a USB Mass Storage device through the USB-OTG connector on the back panel.&lt;br /&gt;
&lt;br /&gt;
The entire root file system (Linux kernel, libraries) and any user data are stored on the eMMC. It is partitioned into four partitions:&lt;br /&gt;
&lt;br /&gt;
Boot partition (contains the bootloader). This partition usually does not require modification.&lt;br /&gt;
A data partition, mounted in /data. This is the only partition that is not erased during file system updates.&lt;br /&gt;
Two identical system partitions (root file systems). These contain the operating system and the home directory (anything mounted under / that is not the data or boot partition). The reason there are two of these is to enable remote updates: An update running on one partition can update the other one without any effect to the currently running system. Note that the system partitions are erased during updates and are thus unsuitable for permanently storing information.&lt;br /&gt;
Note: It is possible to access the currently inactive root file system by mounting it. After logging into the device using serial console or SSH (see the following two sections), run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ mkdir temp&lt;br /&gt;
&lt;br /&gt;
$ mount /dev/mmcblk0p3 temp # This assumes mmcblk0p3 is currently not mounted&lt;br /&gt;
&lt;br /&gt;
$ ls temp # You are now accessing the idle partition:&lt;br /&gt;
&lt;br /&gt;
bin   data  etc   lib         media  proc  sbin  tmp    usr&lt;br /&gt;
boot  dev   home  lost+found  mnt    run   sys   uboot  var&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The device node in the mount command might differ, depending on which partition is currently already mounted.&lt;br /&gt;
&lt;br /&gt;
==USB Access to eMMC==&lt;br /&gt;
&lt;br /&gt;
While Mender should be used for routine filesystem updates (see Updating Filesystems), it is also possible to access the X410's internal eMMC from an external host over USB. This allows accessing or modifying the filesystem, as well as the ability to flash the device with an entirely new filesystem.&lt;br /&gt;
&lt;br /&gt;
In order to do so, you'll need an external computer with two USB ports, and two USB cables to connect the computer to your X410. The instructions below assume a Linux host.&lt;br /&gt;
&lt;br /&gt;
First, connect to the APU serial console at a baud rate of 115200. Boot the device, and stop the boot sequence by typing noautoboot at the prompt. Then, run the following command in the U-boot command prompt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ums 0 mmc 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will start the USB mass storage gadget to expose the eMMC as a USB mass storage device. You should see a spinning indicator on the console, which indicates the gadget is active.&lt;br /&gt;
&lt;br /&gt;
Next, connect your external computer to the X410's USB to PS port using an OTG cable. Your computer should recognize the X410 as a mass storage device, and you should see an entry in your kernel logs (dmesg) that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
usb 3-1: New USB device found, idVendor=3923, idProduct=7a7d, bcdDevice= 2.23&lt;br /&gt;
&lt;br /&gt;
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Product: USB download gadget&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Manufacturer: National Instruments&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] 30932992 512-byte logical blocks: (15.8 GB/14.8 GiB)&lt;br /&gt;
&lt;br /&gt;
sdc: sdc1 sdc2 sdc3 sdc4&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] Attached SCSI removable disk&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact output will depend on your machine, but from this log you can see that the X410 was recognized and /dev/sdc is the block device representing the eMMC, with 4 partitions detected (see eMMC Storage for details on the partition layout).&lt;br /&gt;
&lt;br /&gt;
It is now possible to treat the X410's eMMC as you would any other USB drive: the individual partitions can be mounted and accessed, or the entire block device can be read/written.&lt;br /&gt;
&lt;br /&gt;
Once you're finished accessing the device over USB, the u-boot gadget may be stopped by hitting Ctrl-C at the APU serial console.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Flashing the eMMC==&lt;br /&gt;
&lt;br /&gt;
Once the X410's eMMC is accessible over USB, it's possible to write the filesystem image using bmaptool. You can obtain the latest filesystem image by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader -t sdimg -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output of this command will indicate where the downloaded images were put, or specify a custom location using using the &amp;lt;code&amp;gt;-i INSTALL_LOCATION&amp;lt;/code&amp;gt; argument.&lt;br /&gt;
&lt;br /&gt;
To write the image to the X410's eMMC, run the following command, replacing &amp;lt;code&amp;gt;/dev/sdX&amp;lt;/code&amp;gt; with the block device of the X410's eMMC (found in your kernel log or by running &amp;lt;code&amp;gt;lsblk&amp;lt;/code&amp;gt;). Take care to use the correct block device or else you might overwrite the wrong drive!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo bmaptool copy --bmap /path/to/usrp_x4xx_fs.sdimg.bmap /path/to/usrp_x4xx_fs.sdimg /dev/sdX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Using a USRP X4x0 from UHD==&lt;br /&gt;
Like any other USRP, all X4x0 USRPs are controlled by the UHD software. To integrate a USRP X4x0 into your C++ application, you would generate a UHD device in the same way you would for any other USRP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;auto usrp = uhd::usrp::multi_usrp::make(&amp;quot;type=x4xx&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a list of which arguments can be passed into make(), see Section Device Arguments.&lt;br /&gt;
&lt;br /&gt;
==Updating Filesystems==&lt;br /&gt;
&lt;br /&gt;
Mender is a third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Mender servers can be self-hosted, or hosted by Mender (see mender.io for pricing and availability).&lt;br /&gt;
&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted (note: the onboard flash storage contains two separate root file system partitions, only one is ever used at a single time). Any data stored on that partition will be permanently lost, including the currently loaded FPGA image. After updating that partition, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched (which presumably is in a working state). Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To initiate an update from the device itself, download a Mender artifact containing the update itself. These are files with a .mender suffix. They can be downloaded by using the uhd_images_downloader utility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Append the -l switch to print out the URLs only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx -l&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run mender on the command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install /path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install http://server.name/path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a while. If the new filesystem requires an update to the MB CPLD, see Updating the Motherboard CPLD before proceeding. After mender has logged a successful update, reboot the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so the boot loader knows to permanently boot into this partition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender commit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ cat /etc/mender/artifact_info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are running a hosted server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Network Interfaces==&lt;br /&gt;
The Ettus USRP X410 has various network interfaces:&lt;br /&gt;
&lt;br /&gt;
eth0: RJ45 port.&lt;br /&gt;
&lt;br /&gt;
The RJ45 port comes up with a default configuration of DHCP, that will request a network address from your DHCP server (if available on your network). This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
int0: internal interface for network communication between the embedded ARM processor and FPGA.&lt;br /&gt;
&lt;br /&gt;
The internal network interface is configured with a static address: 169.254.0.1/24. This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
sfpX [, sfpX_1, sfpX_2, sfpX_3]: QSFP28 network interface(s), up-to four (one per lane) based on implemented protocol.&lt;br /&gt;
&lt;br /&gt;
Each QSFP28 port has four high-speed transceiver lanes. Therefore, depending on the FPGA image flavor, up-to four different network interfaces may exist per QSFP28 port, using the sfpXfor the first lane, and sfpX_1-3 for the other three lanes. Each network interface has a default static IP address. Note that for multi-lane protocols, such as 100 GbE, a single interface is used (sfpX).&lt;br /&gt;
The configuration files for these network interfaces are stored in: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Interface Name&lt;br /&gt;
! Description&lt;br /&gt;
! Default Configuration&lt;br /&gt;
! Configuration File&lt;br /&gt;
! Example: X4_200 FPGA image&lt;br /&gt;
|-&lt;br /&gt;
| eth0&lt;br /&gt;
| RJ45&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | DHCP&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | eth0.network&lt;br /&gt;
| DHCP&lt;br /&gt;
|-&lt;br /&gt;
| int0&lt;br /&gt;
| Internal&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | int0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0&lt;br /&gt;
| QSFP28 0 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_1&lt;br /&gt;
| QSFP28 0 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_2&lt;br /&gt;
| QSFP28 0 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0_3&lt;br /&gt;
| QSFP28 0 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp1&lt;br /&gt;
| QSFP28 1 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.20.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| sfp1_1&lt;br /&gt;
| QSFP28 1 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.21.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_2&lt;br /&gt;
| QSFP28 1 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.22.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_3&lt;br /&gt;
| QSFP28 1 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.23.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Network Connectivity==&lt;br /&gt;
Once the X410 has booted, determine the IP address and verify network connectivity by running uhd_find_devices on the host computer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ uhd_find_devices&lt;br /&gt;
&lt;br /&gt;
-- UHD Device 0&lt;br /&gt;
&lt;br /&gt;
Device Address:&lt;br /&gt;
serial: 1234ABC&lt;br /&gt;
addr: 10.2.161.10&lt;br /&gt;
claimed: False&lt;br /&gt;
mgmt_addr: 10.2.161.10&lt;br /&gt;
product: x410&lt;br /&gt;
type: x4xx&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, an X410 will use DHCP to attempt to find an address.&lt;br /&gt;
&lt;br /&gt;
At this point, you should run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_usrp_probe --args addr=&amp;lt;IP address&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
to ensure functionality of the device.&lt;br /&gt;
&lt;br /&gt;
Note: If you receive the following error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Error: RuntimeError: Graph edge list is empty for rx channel 0&amp;lt;/code&amp;gt;&lt;br /&gt;
then you will need to download a UHD-compatible FPGA as described in Updating the FPGA or using the following command (it assumes that FPGA images have been downloaded previously using uhd_images_downloader, or that the command is run on the device itself):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;ip address&amp;gt;,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
When running on the device, use &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; as the IP address.&lt;br /&gt;
&lt;br /&gt;
You can now use existing UHD examples or applications (such as rx_sample_to_file, rx_ascii_art_dft, or tx_waveforms) or other UHD-compatible applications to start receiving and transmitting with the device.&lt;br /&gt;
&lt;br /&gt;
See Network Interfaces for further details on the various network interfaces available on the X410.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Status LEDs===&lt;br /&gt;
The Ettus USRP X410 is equipped with status LEDs for its network-capable ports: RJ45 and QSFP28s, see RJ45 LED Behavior and QSFP28 LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
====RJ45 LED Behavior====&lt;br /&gt;
The RJ45 port has two independent LEDs: green (right) and yellow (left). The table below summarizes the LEDs' behavior. Note that link speed indication is not currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! Green LED&lt;br /&gt;
! Yellow LED&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| On&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| On&lt;br /&gt;
| Blinking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====QSFP28 LED Behavior====&lt;br /&gt;
Each QSFP28 connector has four LEDs, one for each high-speed transceiver lane. The table below summarizes the LEDs' behavior, note that for multi-lane protocols, such as 100 GbE, the corresponding LEDs are ganged together. Within the same image, multiple speeds on the same port (e.g., both 10 GbE and 100 GbE) are not supported, therefore link speed indication is not supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! QSFP28 LED (4 Total)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| Green (solid)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| Amber (blinking)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Security-related Settings==&lt;br /&gt;
The X410 ships without a root password set. It is possible to ssh into the device by simply connecting as root, and thus gaining access to all subsystems. To set a password, run the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ passwd&amp;lt;/code&amp;gt;&lt;br /&gt;
on the device.&lt;br /&gt;
&lt;br /&gt;
==Serial Connection==&lt;br /&gt;
It is possible to gain access to the device using a serial terminal emulator. To do so, the USB debug port needs to be connected to a separate computer to gain access. Most Linux, OSX, or other Unix flavors have a tool called 'screen' which can be used for this purpose, by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/ttyUSB2 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
In this command, we prepend 'sudo' to elevate user privileges (by default, accessing serial ports is not available to regular users), we specify the device node (in this case, /dev/ttyUSB2), and the baud rate (115200).&lt;br /&gt;
&lt;br /&gt;
The exact device node depends on your operating system's driver and other USB devices that might be already connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ls /dev/serial/by-id&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
The first (with the if02 suffix) connects to the STM32 microcontroller (SCU), whereas the second (with the if03 suffix) connects to Linux running on the RFSoC APU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
After entering the username root (no password is set by default), you should be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
On this prompt, you can enter any Linux command available. Using the default configuration, the serial console will also show all kernel log messages (unlike when using SSH, for example), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or bootloader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
==Connecting to the Microcontroller==&lt;br /&gt;
The microcontroller (which controls the power sequencing, among other things) also has a serial console available. To connect to the microcontroller, use the other UART device. In the example above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It provides a very simple prompt. The command 'help' will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it and other low-level diagnostics. For example, running the command reboot will emulate a reset button press, resetting the state of the device, while the command powerbtn will emulate a power button press, turning the device back on again.&lt;br /&gt;
&lt;br /&gt;
==SSH Connection==&lt;br /&gt;
The USRP X410 has two network connections: The dual QSFP28 ports, and an RJ45 connector. The latter is by default configured by DHCP; by plugging it into into 1 Gigabit switch on a DHCP-capable network, it will get assigned an IP address and thus be accessible via ssh.&lt;br /&gt;
&lt;br /&gt;
In case your network setup does not include a DHCP server, refer to the section Serial Connection. A serial login can be used to assign an IP address manually.&lt;br /&gt;
&lt;br /&gt;
After the device obtained an IP address you can log in from a Linux or OSX machine by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC # Replace with your actual device name!&amp;lt;/code&amp;gt;&lt;br /&gt;
Depending on your network setup, using a .local domain may work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC.local&amp;lt;/code&amp;gt;&lt;br /&gt;
Of course, you can also connect to the IP address directly if you know it (or set it manually using the serial console).&lt;br /&gt;
&lt;br /&gt;
Note: The device's hostname is derived from its serial number by default (&amp;lt;code&amp;gt;ni-x4xx-$SERIAL&amp;lt;/code&amp;gt;). You can change the hostname by creating the file &amp;lt;code&amp;gt;/data/network/hostname&amp;lt;/code&amp;gt;, saving the desired hostname in it, then rebooting.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the connection can be established using a tool such as PuTTY, by selecting a username of root without password.&lt;br /&gt;
&lt;br /&gt;
Like with the serial console, you should be presented with a prompt like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Autoboot ==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 can be configured to power on and boot automatically when power is applied. This setting can be controlled using the &amp;lt;code&amp;gt;eeprom-set-autoboot&amp;lt;/code&amp;gt; script. This script is executed directly on the USRP X410. To enable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot on&amp;lt;/code&amp;gt;; to disable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot off&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA==&lt;br /&gt;
&lt;br /&gt;
The FPGA can be updated simply using uhd_image_loader:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt; --fpga-path &amp;lt;path to .bit&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt;,fpga=FPGA_TYPE&amp;lt;/code&amp;gt;&lt;br /&gt;
A UHD install will likely have pre-built images in /usr/share/uhd/images/. Up-to-date images can be downloaded using the uhd_images_downloader script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt;&lt;br /&gt;
will download images into /usr/share/uhd/images/ (the path may differ, depending on how UHD was installed).&lt;br /&gt;
&lt;br /&gt;
Also note that the USRP already ships with compatible FPGA images on the device - these images can be loaded by SSH'ing into the device and running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,mgmt_addr=127.0.0.1,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FPGA Image Flavors==&lt;br /&gt;
&lt;br /&gt;
Unlike the USRP X310 or other third-generation USRP devices, the FPGA image flavors do not only encode how the QSFP28 connectors are configured, but also which master clock rates are available. This is because the data converter configuration is part of the FPGA image (the ADCs/DACs on the X410 are on the same die as the FPGA). The image flavors consist of two short strings, separated by an underscore, e.g. X4_200 is an image flavor which contains 4x 10 GbE, and can handle an analog bandwidth of 200 MHz. The first two characters describe the configuration of the QSFP28 ports: 'X' stands for 10 GbE, 'C' stands for 100 GbE. See the following table for more details.&lt;br /&gt;
&lt;br /&gt;
1x 10 GbE (Lane 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The analog bandwidth determines the available master clock rates. As of UHD 4.1, only the X4_200 image is shipped with UHD, which allows a 245.76 MHz or 250 MHz master clock rate. The other images are considered experimental (unsupported).&lt;br /&gt;
&lt;br /&gt;
==Device Arguments==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! Example Value&lt;br /&gt;
|-&lt;br /&gt;
| addr&lt;br /&gt;
| IPv4 address of primary SFP+ port to connect to.&lt;br /&gt;
| addr=192.168.30.2&lt;br /&gt;
|-&lt;br /&gt;
| second_addr&lt;br /&gt;
| IPv4 address of secondary SFP+ port to connect to.&lt;br /&gt;
| second_addr=192.168.40.2&lt;br /&gt;
|-&lt;br /&gt;
| mgmt_addr&lt;br /&gt;
| IPv4 address or hostname to which to connect the RPC client. Defaults to `addr'.&lt;br /&gt;
| mgmt_addr=ni-sulfur-311FE00&lt;br /&gt;
|-&lt;br /&gt;
| find_all&lt;br /&gt;
| When using broadcast, find all devices, even if unreachable via CHDR.&lt;br /&gt;
| find_all=1&lt;br /&gt;
|-&lt;br /&gt;
| master_clock_rate&lt;br /&gt;
| Master Clock Rate in Hz.&lt;br /&gt;
| master_clock_rate=250e6&lt;br /&gt;
|-&lt;br /&gt;
| serialize_init&lt;br /&gt;
| Force serial initialization of daughterboards.&lt;br /&gt;
| serialize_init=1&lt;br /&gt;
|-&lt;br /&gt;
| skip_init&lt;br /&gt;
| Skip the initialization process for the device.&lt;br /&gt;
| skip_init=1&lt;br /&gt;
|-&lt;br /&gt;
| time_source&lt;br /&gt;
| Specify the time (PPS) source.&lt;br /&gt;
| time_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| clock_source&lt;br /&gt;
| Specify the reference clock source.&lt;br /&gt;
| clock_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| ref_clk_freq&lt;br /&gt;
| Specify the external reference clock frequency, default is 10 MHz.&lt;br /&gt;
| ref_clk_freq=20e6&lt;br /&gt;
|-&lt;br /&gt;
| discovery_port&lt;br /&gt;
| Override default value for MPM discovery port.&lt;br /&gt;
| discovery_port=49700&lt;br /&gt;
|-&lt;br /&gt;
| rpc_port&lt;br /&gt;
| Override default value for MPM RPC port.&lt;br /&gt;
| rpc_port=49701&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==GPS==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 includes a Jackson Labs LTE-Lite GPS module. Its antenna port is on the rear panel (see Front and Back Panels). When the X410 has access to GPS satellite signals, it can use this module to read out the current GPS time and location as well as to discipline an onboard OCXO.&lt;br /&gt;
&lt;br /&gt;
To use the GPS as a clock and time reference, simply use gpsdo as a clock or time source. Alternatively, set gpsdo as a synchronization source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Set clock/time individually:&lt;br /&gt;
usrp-&amp;gt;set_clock_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
usrp-&amp;gt;set_time_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
// This is equivalent to the previous commands, but faster, as it sets&lt;br /&gt;
// both settings simultaneously and avoids duplicating settings that are shared&lt;br /&gt;
// between these calls.&lt;br /&gt;
usrp-&amp;gt;set_sync_source(&amp;quot;clock_source=gpsdo,time_source=gpsdo&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the GPS module is not always enabled. Its power-on status can be queried using the gps_enabled GPS sensor (see also The Sensor API). When disabled, none of the sensors will return useful (if any) values.&lt;br /&gt;
&lt;br /&gt;
When selecting gpsdo as a clock source, the GPS will always be enabled. Note that acquiring a GPS lock can take some time after enabling the GPS, so if a UHD application is enabling the GPS dynamically, it might take some time before a GPS lock is reported.&lt;br /&gt;
&lt;br /&gt;
==Front-Panel Programmable GPIOs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 has two HDMI front-panel connectors, which are connected to the FPGA.&lt;br /&gt;
&lt;br /&gt;
Support for using these with UHD is not yet available.&lt;br /&gt;
&lt;br /&gt;
==Subdev Specifications==&lt;br /&gt;
&lt;br /&gt;
The RF ports on the front panel of the X410 + ZBX correspond to the following subdev specifications:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Label&lt;br /&gt;
! style=&amp;quot;text-align:center; vertical-align:middle; font-weight:bold;&amp;quot; | Subdev Spec&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 0&lt;br /&gt;
| A:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 1&lt;br /&gt;
| A:1&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 0&lt;br /&gt;
| B:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 1&lt;br /&gt;
| B:1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The subdev spec slot identifiers &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; are not reflected on the front panel. They were set to match valid subdev specifications of previous USRPs, maintaining backward compatibility.&lt;br /&gt;
&lt;br /&gt;
These values can be used for uhd::usrp::multi_usrp::set_rx_subdev_spec() and uhd::usrp::multi_usrp::set_tx_subdev_spec() as with other USRPs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Rear Panel Status LEDs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 is equipped with four LEDs located on the device's rear panel. Each LED supports four different states: Off, Green, Red, and Amber. One LED (PWR) indicates the device's power state (see Power LED below). The other three LEDs (LED 0, LED 1, and LED 2) are user-configurable, different behaviors are supported for each of these LEDs (see User-configurable LEDs below).&lt;br /&gt;
&lt;br /&gt;
[[File:x4xx_rearpanel_status_leds.png|125px]]&lt;br /&gt;
&lt;br /&gt;
===X4x0 Rear Panel Status LEDs===&lt;br /&gt;
Power LED&lt;br /&gt;
The USRP X410's PWR LED is reserved to visually indicate the user the device's power state. Power LED Behavior describes what each LED state represents.&lt;br /&gt;
&lt;br /&gt;
===Power LED Behavior===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! PWR LED State&lt;br /&gt;
! style=&amp;quot;vertical-align:middle;&amp;quot; | Meaning&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Off&lt;br /&gt;
| No power is applied&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Amber&lt;br /&gt;
| Power is good but X410 is powered off&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Green&lt;br /&gt;
| Power is good and X410 is powered on&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Red&lt;br /&gt;
| Power error state&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===User-configurable LEDs===&lt;br /&gt;
The USRP X410's user-configurable rear panel status LEDs (LED 0, LED 1, and LED 2) allow the user to have visual indication of various device conditions. Supported LED Behaviors provides a complete list of the supported behaviors for each user-configurable LED. By default, these LEDs are configured as described in LEDs Default Behavior.&lt;br /&gt;
&lt;br /&gt;
The user may alter the default LEDs behavior either temporarily or persistently, see the Temporarily change the LED Behavior or Persistently in the UHD manual to change the LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
https://files.ettus.com/manual/page_usrp_x4xx.html&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:X410]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5395</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5395"/>
				<updated>2022-04-21T15:39:26Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# This was tested using UHD 4.2.&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assume 4 bytes per sample (sc16).&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5390</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5390"/>
				<updated>2022-04-20T22:54:37Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assumes 4 bytes per sample.&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X3xx || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X3xx====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X3xx&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5389</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5389"/>
				<updated>2022-04-20T22:50:33Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add Vivado Information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assumes 4 bytes per sample.&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Xilinx Vivado ==&lt;br /&gt;
&lt;br /&gt;
=== Do I need a Vivado license to build custom RFNoC FPGA images? ===&lt;br /&gt;
&lt;br /&gt;
All RFNoC-capable USRPs use Xilinx FPGAs that require a license to use Vivado, except for E31x USRPs, which can use the free Vivado HL WebPACK Edition. Vivado is required to build FPGAs for RFNoC. &lt;br /&gt;
&lt;br /&gt;
=== Which version and edition of Vivado do I need? ===&lt;br /&gt;
&lt;br /&gt;
See the [https://files.ettus.com/manual/md_usrp3_build_instructions.html UHD User Manual] for the latest Vivado version requirements. UHD versions 4.0 through 4.2 require Vivado 2019.1.&lt;br /&gt;
&lt;br /&gt;
For E31x devices, you can use the free Vivado HL Webpack. For all other USRPs, you can use Design Edition or System Edition. We recommend Design Edition, unless you plan to use System Generator for DSP. System Generator is not required by RFNoC.&lt;br /&gt;
&lt;br /&gt;
=== Do I need to install all components of Vivado? ===&lt;br /&gt;
&lt;br /&gt;
No. You only need to install device support for the FPGA you intend to build. Other devices can be unchecked to save disk space. The following FPGA types are used by USRPs:&lt;br /&gt;
&lt;br /&gt;
* '''SoCs &amp;gt; Zynq-7000:''' E31x, E320, N3xx&lt;br /&gt;
* '''SOCs &amp;gt; Zynq UltraScale+ RFSoC:''' X410&lt;br /&gt;
* '''7 Series &amp;gt; Kintex-7''': X31x&lt;br /&gt;
&lt;br /&gt;
The Software Development Kit (SDK) is typically not required, but can be installed if desired.&lt;br /&gt;
&lt;br /&gt;
The Cable Drivers are needed if you plan to do JTAG download or debug. Note that on Linux, the cable drivers are copied to the install folder, but are not installed onto your system automatically. See Xilinx UG973 for instructions on installing the cable drivers on Linux.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5387</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5387"/>
				<updated>2022-04-20T22:12:46Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What DRAM data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assumes 4 bytes per sample.&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5386</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5386"/>
				<updated>2022-04-20T22:11:24Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add DRAM throughput numbers.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. The DRAM is shared between channels, so throughput goes down as the number of channels going through the DRAM is increased.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! BIST (MB/s) !! 1 Ch (MS/s) !! 2 Ch (MS/s) !! 3 Ch (MS/s) !! 4 Ch (MS/s)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 666 || 166 || 91 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 1361 || 340 || 170 || 113 || 85&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 1368 || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1347 || 336 || 115 || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || 1288 || 321|| 316|| 314 || 303&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || 2801 || 697 || 672 || 672 || 672&lt;br /&gt;
|}&lt;br /&gt;
Notes:&lt;br /&gt;
# BIST refers to the built-in self test, which gives a measure of raw data throughput for a single channel.&lt;br /&gt;
# For MS/s, we assumes 4 bytes per sample.&lt;br /&gt;
# The 128-bit DRAM on X410 uses two memory banks. Channels 0 and 1 are on Bank 0, and channels 2 and 3 are on Bank 1.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5370</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5370"/>
				<updated>2022-04-18T21:02:53Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (MS/s)*&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! 1 Ch !! 2 Ch !!  3 Ch !! 4 Ch&lt;br /&gt;
|-&lt;br /&gt;
| E31x || TBD || TBD || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&amp;amp;#42; Assumes 4 bytes per sample.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5369</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5369"/>
				<updated>2022-04-18T20:51:56Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (MS/s)*&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! 1 Ch !! 2 Ch !!  3 Ch !! 4 Ch&lt;br /&gt;
|-&lt;br /&gt;
| E31x || TBD || TBD || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&amp;amp;#42; Assumes 4 bytes per sample.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, {32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5368</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5368"/>
				<updated>2022-04-18T20:44:15Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Cleaned up DRAM tables.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ USRP DRAM Summary&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example DRAM Throughput (MS/s)*&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! 1 Ch !! 2 Ch !!  3 Ch !! 4 Ch&lt;br /&gt;
|-&lt;br /&gt;
| E31x || TBD || TBD || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 341 || 295 || 191 || 144&lt;br /&gt;
|-&lt;br /&gt;
| X31x || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&amp;amp;#42; Assumes 4 bytes per sample.&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RFNoC Block Memory Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max)&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The DMA FIFO has a few additional parameters that should be provided. The clock rate (&amp;lt;code&amp;gt;MEM_CLK_RATE&amp;lt;/code&amp;gt;) must match the value below for the built-in self test (BIST) to work correctly. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;) are written as Verilog constants and can be changed depending on your application. The &amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt; parameter contains the byte address for the first byte of the memory region to use for each port. The &amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt; parameter contains the address mask for each port, which tells the FIFO how much memory to use for each port. For example, an address mask of &amp;lt;code&amp;gt;30'h1FFFFFFF&amp;lt;/code&amp;gt; means that 0x1FFFFFFF+1 bytes (i.e., 0x20000000 bytes or 512 MiB) will be used by the corresponding port. The address mask must be 1 less than a power of 2.&lt;br /&gt;
&lt;br /&gt;
The example values in the table below use the entire memory and divide it evenly between all available ports. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ DMA FIFO Parameters&lt;br /&gt;
|-&lt;br /&gt;
! USRP Model !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || &amp;quot;300e6&amp;quot; || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, {32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L69 x310_rfnoc_image_core.yml] for an example of how to instantiate the Replay block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/e320/e320_rfnoc_image_core.yml#L49 e320_rfnoc_image_core.yml] for an example of how to instantiate the DMA FIFO block in the RFNoC image core YAML description. The following is a generic example that can be used for any USRP:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5363</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5363"/>
				<updated>2022-04-18T19:22:28Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added DRAM section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USRP DRAM ==&lt;br /&gt;
&lt;br /&gt;
=== How much and what speed DRAM is available on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
The table below summarizes the DRAM that is connected to the USRP for use by RFNoC.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! USRP Model !! DRAM Size !! Default DRAM Speed !! Default User Interface&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 512 MiB || 16-bit @ 800 MT/s (1.6 GB/s) || 2 ch x 64-bit @ 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 2 GiB || 32-bit @ 1333 MT/s (5.33 GB/s) || 4 ch x 64-bit @ 300 MHz MHz&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 2 GiB || 32-bit @ 1300 MT/s (5.2 GB/s) || 4 ch x 64-bit @ 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 1 GiB || 32-bit @ 1200 MT/s (4.8 GB/s) || 2 ch x 64-bit @ 150 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 4 GiB || 64-bit @ 2.0 GT/s (16.0 GB/s) || 4 x 64-bit @ 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 4 GiB per bank&amp;lt;br&amp;gt;(8 GiB total) || 64-bit @ 2.0 GT/s (16.0 GB/s) per bank&amp;lt;br&amp;gt;(32.0 GB/s total) || 4 x 128-bit @ 250 MHz (using 2 banks)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What data rates can I expect on each USRP? ===&lt;br /&gt;
&lt;br /&gt;
DRAM performance is highly application-specific. For example, reading vs. reading and writing simultaneously, one data stream vs. multiple data streams, random access vs. sequential access, etc., can give dramatically different performance. Below are some measurements taken on different USRPs where a Null-Source-Sink RFNoC block is directly connected to a DMA FIFO block to test maximum streaming rates through the DRAM. This assumes 4 bytes per sample.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! USRP Model !! 1 Ch !! 2 Ch !!  3 Ch !! 4 Ch&lt;br /&gt;
|-&lt;br /&gt;
| E31x || TBD || TBD || N/A || N/A&lt;br /&gt;
|-&lt;br /&gt;
| E320 || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 341 MS/s || 295 MS/s || 191 MS/s || 144 MS/s&lt;br /&gt;
|-&lt;br /&gt;
| X31x || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (64-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| X410 (128-bit) || TBD || TBD || TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== What can the DRAM be used for? ===&lt;br /&gt;
&lt;br /&gt;
* '''DMA FIFO Block:''' The DMA FIFO block is used in situations where you need a large buffer to store samples.&lt;br /&gt;
&lt;br /&gt;
* '''Replay Block:''' The Replay block is used to record and play back RF data. For example, you can record data from a host computer, then play it back over the radio. Or, record data from the radio, then play it back later to the host for analysis, or play it back to a radio at a specific timestamp. See [[Using the RFNoC Replay Block in UHD 4]] for additional information. The Replay block also has a FIFO capability for situations in which the DMA FIFO block is not available in your FPGA image.&lt;br /&gt;
&lt;br /&gt;
* '''Custom Blocks:''' You can also create your own RFNoC block that uses DRAM. Refer to the DMA FIFO and/or Replay blocks as examples.&lt;br /&gt;
&lt;br /&gt;
=== How do I add the Replay/DMA FIFO block to my FPGA image? ===&lt;br /&gt;
&lt;br /&gt;
If the block you want is not included by default in the FPGA image you are using, you can add it to the RFNoC image core YAML file and rebuild the FPGA image using Vivado. See [[Getting Started with RFNoC in UHD 4.0]] for additional information on customizing an RFNoC image.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' DRAM is not enabled by default on E31x FPGA builds because the FPGA is not large enough to fit the default image with DRAM. You will need to remove components from your RFNoC image's YAML file to make room, then build the E31x image with the variable DRAM=1 set, or modify the E31x Makefile to enable DRAM by default.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The X410 configures its DRAM differently for 100/200 MHz bandwidth images and 400 MHz bandwidth. The parameters used will be different in each case, as shown in the table below.&lt;br /&gt;
&lt;br /&gt;
When adding the blocks to your RFNoC image core YAML file, the parameters must be set correctly for the type of USRP you intend to use. The memory data width (&amp;lt;code&amp;gt;MEM_DATA_W&amp;lt;/code&amp;gt;) and address width (&amp;lt;code&amp;gt;MEM_ADDR_W&amp;lt;/code&amp;gt;) must match exactly. The number of ports (&amp;lt;code&amp;gt;NUM_PORTS&amp;lt;/code&amp;gt;) must not exceed the maximum number available. You can use fewer ports to save resources if you don't need all the DRAM ports. The base address (&amp;lt;code&amp;gt;FIFO_ADDR_BASE&amp;lt;/code&amp;gt;) and address mask (&amp;lt;code&amp;gt;FIFO_ADDR_MASK&amp;lt;/code&amp;gt;), which are needed for the DMA FIFO only, can be changed depending on your application. The values in the table below assume that you want to use the entire memory divided evenly between all available ports.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! USRP Model !! MEM_DATA_W !! MEM_ADDR_W !! NUM_PORTS (Max) !! MEM_CLK_RATE !! FIFO_ADDR_BASE !! FIFO_ADDR_MASK&lt;br /&gt;
|-&lt;br /&gt;
| E31x || 64 || 29 || 2 || &amp;quot;200e6&amp;quot; || &amp;quot;{29'h10000000, 29'h00000000}&amp;quot; || &amp;quot;{29'h0FFFFFFF, 29'h0FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| E320 || 64 || 31 || 4 || &amp;quot;300e6&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| N3xx || 64 || 31 || 4 || &amp;quot;303819444&amp;quot; || &amp;quot;{31'h60000000, 31'h40000000, 31'h20000000, 31'h00000000}&amp;quot; || &amp;quot;{31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF, 31'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X31x || 64 || 30 || 2 || 300 || &amp;quot;{30'h20000000, 30'h00000000}&amp;quot; || &amp;quot;{30'h1FFFFFFF, 30'h1FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (100 and 200 MHz BW) || 64 || 32 || 4 || &amp;quot;250e6&amp;quot; || &amp;quot;{32'hC0000000, 32'h80000000, 32'h40000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF, 32'h3FFFFFFF}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| X410 (400 MHz BW) || 128 || 32 || 4 || &amp;quot;250e6&amp;quot; || &amp;quot;{32'h80000000, 32'h00000000, 32'h80000000, 32'h00000000}&amp;quot; || &amp;quot;{32'h7FFFFFFF, 32'h7FFFFFFF, {32'h7FFFFFFF, 32'h7FFFFFFF}&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Replay Example ====&lt;br /&gt;
&lt;br /&gt;
The following example shows how to include the Replay block in your image core YAML file.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the replay block&lt;br /&gt;
  replay0:&lt;br /&gt;
    block_desc: 'replay.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the replay block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
Connect the DRAM clock to the block:&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: replay0, dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DMA FIFO Example ====&lt;br /&gt;
&lt;br /&gt;
The following example shows how to include the DMA FIFO block in your image core YAML file.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
noc_blocks:&lt;br /&gt;
  # Instantiate the DMA FIFO block&lt;br /&gt;
  fifo0:&lt;br /&gt;
    block_desc: 'axi_ram_fifo.yml'&lt;br /&gt;
    parameters:&lt;br /&gt;
      NUM_PORTS: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_DATA_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_ADDR_W: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_BASE: &amp;lt;see table&amp;gt;&lt;br /&gt;
      FIFO_ADDR_MASK: &amp;lt;see table&amp;gt;&lt;br /&gt;
      MEM_CLK_RATE: &amp;lt;see table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
connections:&lt;br /&gt;
  # Connect the DMA FIFO block memory interface to the USRP DRAM&lt;br /&gt;
  - { srcblk: fifo0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
&lt;br /&gt;
clk_domains:&lt;br /&gt;
  # Connect the DRAM clock to the replay block&lt;br /&gt;
  - { srcblk: _device_, srcport: dram, dstblk: fifo0,  dstport: mem }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5344</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5344"/>
				<updated>2022-04-18T16:26:26Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added additional details about adding or changing clocks.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. Describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock.&lt;br /&gt;
&lt;br /&gt;
If you only need the clock within your own RFNoC block, you can modify the HDL for your block to generate the clock that you need from one of the available clocks. To do this, add a new clock to your block's YAML description, connect the available clock to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP instance to your block's HDL and connect the available clock to its input.&lt;br /&gt;
&lt;br /&gt;
If the clock is needed by multiple RFNoC blocks, or if you want to change an existing clock, you can modify the HDL for the USRP you are using to add or change a clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core &amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists. How and where the clocks are generated varies between USRPs. Please refer to the source code for that USRP ([https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/top &amp;lt;repo&amp;gt;/fpga/usrp3/top]).&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5336</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5336"/>
				<updated>2022-04-15T22:09:58Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X410====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. In other words, describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock. You can:&lt;br /&gt;
&lt;br /&gt;
* Modify the HDL for your block to create the clock you need. In this case, connect one of the available clocks to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP block to your block's HDL and connect the available clock to its input.&lt;br /&gt;
* Modify the HDL for the USRP you are using to either change a clock to the rate you need or to add a new clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5335</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5335"/>
				<updated>2022-04-15T22:08:11Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added RFNoC clocks FAQ&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;br /&gt;
&lt;br /&gt;
== RFNoC Clocks ==&lt;br /&gt;
&lt;br /&gt;
=== What clocks are available for me to use? ===&lt;br /&gt;
&lt;br /&gt;
Each device has different clocks available. See below for a list of clocks exposed to RFNoC. Although they have intended purposes, you can use any of these clocks for any purpose. The &amp;lt;code&amp;gt;rfnoc_chdr_clock&amp;lt;/code&amp;gt; is a good default choice. This clock is always available in your block, even if it is not explicitly connected in the RFNoC image YAML description.&lt;br /&gt;
&lt;br /&gt;
=== What are the clock frequencies? ===&lt;br /&gt;
&lt;br /&gt;
See the table below for the clock rates. The radio clock rate depends on the master clock rate.&lt;br /&gt;
&lt;br /&gt;
====E31x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 100 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====E320====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 166.667 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 kHz to 61.44 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N300/N310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.189 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (122.88 MHz, 125.0 MHz, or 153.6 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====N32x====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 303.819 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (200 MHz, 245.76 MHz, or 250 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====X310====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 187.5 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; || Compute Engine clock || 214.286 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || Same as master clock rate (184.32 MHz or 200 MHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===X410===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Clock Name !! Description !! Frequency&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; || RFNoC CHDR clock || 200 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dram&amp;lt;/code&amp;gt; || DRAM interface clock || 250 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; || Radio interface clock || 122.88 MHz when master clock rate is 122.88, 245.76, or 491.52 MHz&amp;lt;br&amp;gt;125 MHz when master clock rate is 125, 250, or 500 MHz&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;radio_2x&amp;lt;/code&amp;gt; || Radio interface clock 2x || Twice the frequency of &amp;lt;code&amp;gt;radio_clk&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How do I add a clock with a different frequency? ===&lt;br /&gt;
&lt;br /&gt;
Adding custom clocks is not directly supported yet. In other words, describing them in the YAML file will not cause them to be generated for you. If you can't use any of the available clocks, you can modify the HDL code to generate a clock. You can:&lt;br /&gt;
&lt;br /&gt;
* Modify the HDL for your block to create the clock you need. In this case, connect one of the available clocks to your block in the YAML description of your RFNoC image, then add a Xilinx MMCM IP block to your block's HDL and connect the available clock to its input.&lt;br /&gt;
* Modify the HDL for the USRP you are using to either change a clock to the rate you need or to add a new clock. If you add a new clock to the RFNoC image core, you must also update the BSP YAML file (located in [https://github.com/EttusResearch/uhd/tree/master/host/include/uhd/rfnoc/core host/include/uhd/rfnoc/core]) so that the &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; knows that the clock exists.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5334</id>
		<title>RFNoC Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=RFNoC_Frequently_Asked_Questions&amp;diff=5334"/>
				<updated>2022-04-15T21:15:41Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added Stream Endpoint buffer size questions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring the Stream Endpoint Buffer Size in RFNoC ==&lt;br /&gt;
&lt;br /&gt;
=== What is the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
Each stream endpoint (SEP) has an ingress buffer to store data received from others stream endpoints. This size of this buffer affects the data transfer rate that can be achieved when streaming to that endpoint. A larger ingress buffer in the stream endpoint means that there is more space to put data, minimizing idle time on the network. Additionally, streamers can queue up data before it is needed, reducing the chance of a buffer underflow.&lt;br /&gt;
&lt;br /&gt;
=== How do I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The stream endpoint buffer size is set by adding a parameter under the endpoint you want to configure in the RFNoC image core YAML file. There are two parameters you can use to set the stream endpoint ingress buffer size in your RFNoC image core YAML file.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt;: Buffer size in CHDR words. The size in bytes depends on the CHDR width. For example, if the &amp;lt;code&amp;gt;chdr_width&amp;lt;/code&amp;gt; parameter for the device is 64, then each CHDR word is 8 bytes. So a buff size of 32768 would be 262,144 bytes or 256 KiB. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml#L20 here] for an example.&lt;br /&gt;
* &amp;lt;code&amp;gt;buff_size_bytes&amp;lt;/code&amp;gt;:  Buffer size in bytes. See [https://github.com/EttusResearch/uhd/blob/197cdc4f665cbd4e6394a7eeb44b405f67ab10b1/fpga/usrp3/top/x400/x410_200_rfnoc_image_core.yml#L21 here] for an example.&lt;br /&gt;
&lt;br /&gt;
=== To what value should I set the SEP buffer size? ===&lt;br /&gt;
&lt;br /&gt;
The buffer size should be a power of two in size to make optimal use of FPGA RAM resources. The default FPGA bitstreams typically set them to the largest size the FPGA can fit in order to maximize performance. Here are some general recommendations:&lt;br /&gt;
&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; if you don't need to send data to that SEP.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;8192&amp;lt;/code&amp;gt; bytes (8 KiB = 1 MTU) minimum in order to stream data packets.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;32768&amp;lt;/code&amp;gt; bytes (32 KiB = 4 MTU) in order to stream at maximum rates between SEPs on the same FPGA.&lt;br /&gt;
* Set to &amp;lt;code&amp;gt;262144&amp;lt;/code&amp;gt; bytes (256 KiB = 32 MTU) or lager for high performance streaming between a host computer and the FPGA.&lt;br /&gt;
&lt;br /&gt;
Note that the requirements are application-dependent, so optimal sizes for your application may be different. MTU refers to the maximum transmission unit, which is the largest CHDR packet supported by the FPGA.&lt;br /&gt;
&lt;br /&gt;
If you need to free up FPGA resources (particularly block RAM) for your application, you can reduce the SEP buffer sizes. Just keep in mind that the maximum streaming rate may be affected.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5333</id>
		<title>USRP X410 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5333"/>
				<updated>2022-04-15T17:52:15Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
===X410===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* NI Ettus USRP X410&lt;br /&gt;
* DC Power Supply (12V, 20A)&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to USB-C Cable (1m)&lt;br /&gt;
* Getting Started Guide URL (QR Code)&lt;br /&gt;
* Safety, Environmental, and Regulatory Information&lt;br /&gt;
||[[File:X410.jpg|450px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
* For Network Mode: A host computer with an available 1 or 10 Gigabit Ethernet interface for sample streaming. In addition to the Ethernet interface used for sampling streaming, your host computer will require a separate 1 Gigabit Ethernet interface for command and control streaming.&lt;br /&gt;
 &lt;br /&gt;
* For Stand-Alone Embedded Mode: A host computer with an available 1 Gigabit Ethernet port or a USB 2.0 port to remotely access the embedded Linux operating system running on ARM CPU.&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow metal objects to touch the circuit board while powered.&lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than +14 dBm continuous &amp;lt;=3GHz, +17 dBm continuous &amp;gt;3GHz, or +20dBm more than 5 minutes &amp;gt;3GHz of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
In order to use your Universal Software Radio Peripheral (USRP™), you must have the software tools correctly installed and configured on your host computer. A step-by-step guide for doing this is available at the Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]] Application Notes.&lt;br /&gt;
&lt;br /&gt;
To find the latest release of UHD, see the UHD repository at https://github.com/EttusResearch/uhd.&lt;br /&gt;
&lt;br /&gt;
The USRP X410 requires UHD version 4.1 or later. &lt;br /&gt;
&lt;br /&gt;
'''When you receive a brand-new device, it is strongly recommended that you download the latest filesystem image from the Ettus Research website update the unit. It is not recommended that you use the filesystem from the factory as-is. Instructions on downloading the latest filesystem image and updating it is listed below.'''&lt;br /&gt;
&lt;br /&gt;
'''Note that if you are operating the device in Network Mode, the version of UHD running on the host computer and the USRP X410 must match.'''&lt;br /&gt;
&lt;br /&gt;
==Assembling the X410==&lt;br /&gt;
Inside the kit you will find the X410 and an X410 power supply. Plug these in, connect the 1GbE RJ45 interface to your network, and power on the device by pressing the power button.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The STM32 Microcontroller==&lt;br /&gt;
&lt;br /&gt;
The STM32 microcontroller (also referred to as the &amp;quot;SCU&amp;quot;) controls various low-level features of the X4x0 series motherboard: It controls the power sequencing, reads out fan speeds and some of the temperature sensors. It is connected to the RFSoC via an I2C bus. It is running software based on Chromium EC.&lt;br /&gt;
&lt;br /&gt;
It is possible to log into the STM32 using the serial interface (see Connecting to the Microcontroller). This will allow certain low-level controls, such as remote power cycling should the CPU have become unresponsive for whatever reason.&lt;br /&gt;
&lt;br /&gt;
===Updating the SCU===&lt;br /&gt;
&lt;br /&gt;
The writable SCU image file is stored on the filesystem under /lib/firmware/ni/ec-titanium-revX.RW.bin (where X is a revision compatibility number). To update, simply replace the .bin file with the updated version and reboot.&lt;br /&gt;
&lt;br /&gt;
==eMMC Storage==&lt;br /&gt;
&lt;br /&gt;
The main non-volatile storage of the USRP is a 16 GB eMMC storage. This storage can be made accessible as a USB Mass Storage device through the USB-OTG connector on the back panel.&lt;br /&gt;
&lt;br /&gt;
The entire root file system (Linux kernel, libraries) and any user data are stored on the eMMC. It is partitioned into four partitions:&lt;br /&gt;
&lt;br /&gt;
Boot partition (contains the bootloader). This partition usually does not require modification.&lt;br /&gt;
A data partition, mounted in /data. This is the only partition that is not erased during file system updates.&lt;br /&gt;
Two identical system partitions (root file systems). These contain the operating system and the home directory (anything mounted under / that is not the data or boot partition). The reason there are two of these is to enable remote updates: An update running on one partition can update the other one without any effect to the currently running system. Note that the system partitions are erased during updates and are thus unsuitable for permanently storing information.&lt;br /&gt;
Note: It is possible to access the currently inactive root file system by mounting it. After logging into the device using serial console or SSH (see the following two sections), run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ mkdir temp&lt;br /&gt;
&lt;br /&gt;
$ mount /dev/mmcblk0p3 temp # This assumes mmcblk0p3 is currently not mounted&lt;br /&gt;
&lt;br /&gt;
$ ls temp # You are now accessing the idle partition:&lt;br /&gt;
&lt;br /&gt;
bin   data  etc   lib         media  proc  sbin  tmp    usr&lt;br /&gt;
boot  dev   home  lost+found  mnt    run   sys   uboot  var&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The device node in the mount command might differ, depending on which partition is currently already mounted.&lt;br /&gt;
&lt;br /&gt;
==USB Access to eMMC==&lt;br /&gt;
&lt;br /&gt;
While Mender should be used for routine filesystem updates (see Updating Filesystems), it is also possible to access the X410's internal eMMC from an external host over USB. This allows accessing or modifying the filesystem, as well as the ability to flash the device with an entirely new filesystem.&lt;br /&gt;
&lt;br /&gt;
In order to do so, you'll need an external computer with two USB ports, and two USB cables to connect the computer to your X410. The instructions below assume a Linux host.&lt;br /&gt;
&lt;br /&gt;
First, connect to the APU serial console at a baud rate of 115200. Boot the device, and stop the boot sequence by typing noautoboot at the prompt. Then, run the following command in the U-boot command prompt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ums 0 mmc 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will start the USB mass storage gadget to expose the eMMC as a USB mass storage device. You should see a spinning indicator on the console, which indicates the gadget is active.&lt;br /&gt;
&lt;br /&gt;
Next, connect your external computer to the X410's USB to PS port using an OTG cable. Your computer should recognize the X410 as a mass storage device, and you should see an entry in your kernel logs (dmesg) that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
usb 3-1: New USB device found, idVendor=3923, idProduct=7a7d, bcdDevice= 2.23&lt;br /&gt;
&lt;br /&gt;
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Product: USB download gadget&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Manufacturer: National Instruments&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] 30932992 512-byte logical blocks: (15.8 GB/14.8 GiB)&lt;br /&gt;
&lt;br /&gt;
sdc: sdc1 sdc2 sdc3 sdc4&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] Attached SCSI removable disk&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact output will depend on your machine, but from this log you can see that the X410 was recognized and /dev/sdc is the block device representing the eMMC, with 4 partitions detected (see eMMC Storage for details on the partition layout).&lt;br /&gt;
&lt;br /&gt;
It is now possible to treat the X410's eMMC as you would any other USB drive: the individual partitions can be mounted and accessed, or the entire block device can be read/written.&lt;br /&gt;
&lt;br /&gt;
Once you're finished accessing the device over USB, the u-boot gadget may be stopped by hitting Ctrl-C at the APU serial console.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Flashing the eMMC==&lt;br /&gt;
&lt;br /&gt;
Once the X410's eMMC is accessible over USB, it's possible to write the filesystem image using bmaptool. You can obtain the latest filesystem image by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader -t sdimg -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output of this command will indicate where the downloaded image can be found.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; sudo bmaptool /path/to/usrp_x4xx_fs.sdimg.bz2 /dev/sdX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to flash the eMMC with this image (replacing /dev/sdX with the block device of the X410's eMMC as indicated by your kernel log).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Using a USRP X4x0 from UHD==&lt;br /&gt;
Like any other USRP, all X4x0 USRPs are controlled by the UHD software. To integrate a USRP X4x0 into your C++ application, you would generate a UHD device in the same way you would for any other USRP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;auto usrp = uhd::usrp::multi_usrp::make(&amp;quot;type=x4xx&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a list of which arguments can be passed into make(), see Section Device Arguments.&lt;br /&gt;
&lt;br /&gt;
==Updating Filesystems==&lt;br /&gt;
&lt;br /&gt;
Mender is a third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Mender servers can be self-hosted, or hosted by Mender (see mender.io for pricing and availability).&lt;br /&gt;
&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted (note: the onboard flash storage contains two separate root file system partitions, only one is ever used at a single time). Any data stored on that partition will be permanently lost, including the currently loaded FPGA image. After updating that partition, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched (which presumably is in a working state). Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To initiate an update from the device itself, download a Mender artifact containing the update itself. These are files with a .mender suffix. They can be downloaded by using the uhd_images_downloader utility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Append the -l switch to print out the URLs only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx -l&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run mender on the command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install /path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install http://server.name/path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a while. If the new filesystem requires an update to the MB CPLD, see Updating the Motherboard CPLD before proceeding. After mender has logged a successful update, reboot the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so the boot loader knows to permanently boot into this partition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender commit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ cat /etc/mender/artifact_info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are running a hosted server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Network Interfaces==&lt;br /&gt;
The Ettus USRP X410 has various network interfaces:&lt;br /&gt;
&lt;br /&gt;
eth0: RJ45 port.&lt;br /&gt;
&lt;br /&gt;
The RJ45 port comes up with a default configuration of DHCP, that will request a network address from your DHCP server (if available on your network). This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
int0: internal interface for network communication between the embedded ARM processor and FPGA.&lt;br /&gt;
&lt;br /&gt;
The internal network interface is configured with a static address: 169.254.0.1/24. This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
sfpX [, sfpX_1, sfpX_2, sfpX_3]: QSFP28 network interface(s), up-to four (one per lane) based on implemented protocol.&lt;br /&gt;
&lt;br /&gt;
Each QSFP28 port has four high-speed transceiver lanes. Therefore, depending on the FPGA image flavor, up-to four different network interfaces may exist per QSFP28 port, using the sfpXfor the first lane, and sfpX_1-3 for the other three lanes. Each network interface has a default static IP address. Note that for multi-lane protocols, such as 100 GbE, a single interface is used (sfpX).&lt;br /&gt;
The configuration files for these network interfaces are stored in: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Interface Name&lt;br /&gt;
! Description&lt;br /&gt;
! Default Configuration&lt;br /&gt;
! Configuration File&lt;br /&gt;
! Example: X4_200 FPGA image&lt;br /&gt;
|-&lt;br /&gt;
| eth0&lt;br /&gt;
| RJ45&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | DHCP&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | eth0.network&lt;br /&gt;
| DHCP&lt;br /&gt;
|-&lt;br /&gt;
| int0&lt;br /&gt;
| Internal&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | int0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0&lt;br /&gt;
| QSFP28 0 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_1&lt;br /&gt;
| QSFP28 0 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_2&lt;br /&gt;
| QSFP28 0 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0_3&lt;br /&gt;
| QSFP28 0 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp1&lt;br /&gt;
| QSFP28 1 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.20.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| sfp1_1&lt;br /&gt;
| QSFP28 1 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.21.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_2&lt;br /&gt;
| QSFP28 1 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.22.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_3&lt;br /&gt;
| QSFP28 1 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.23.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Network Connectivity==&lt;br /&gt;
Once the X410 has booted, determine the IP address and verify network connectivity by running uhd_find_devices on the host computer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ uhd_find_devices&lt;br /&gt;
&lt;br /&gt;
-- UHD Device 0&lt;br /&gt;
&lt;br /&gt;
Device Address:&lt;br /&gt;
serial: 1234ABC&lt;br /&gt;
addr: 10.2.161.10&lt;br /&gt;
claimed: False&lt;br /&gt;
mgmt_addr: 10.2.161.10&lt;br /&gt;
product: x410&lt;br /&gt;
type: x4xx&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, an X410 will use DHCP to attempt to find an address.&lt;br /&gt;
&lt;br /&gt;
At this point, you should run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_usrp_probe --args addr=&amp;lt;IP address&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
to ensure functionality of the device.&lt;br /&gt;
&lt;br /&gt;
Note: If you receive the following error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Error: RuntimeError: Graph edge list is empty for rx channel 0&amp;lt;/code&amp;gt;&lt;br /&gt;
then you will need to download a UHD-compatible FPGA as described in Updating the FPGA or using the following command (it assumes that FPGA images have been downloaded previously using uhd_images_downloader, or that the command is run on the device itself):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;ip address&amp;gt;,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
When running on the device, use &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; as the IP address.&lt;br /&gt;
&lt;br /&gt;
You can now use existing UHD examples or applications (such as rx_sample_to_file, rx_ascii_art_dft, or tx_waveforms) or other UHD-compatible applications to start receiving and transmitting with the device.&lt;br /&gt;
&lt;br /&gt;
See Network Interfaces for further details on the various network interfaces available on the X410.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Status LEDs===&lt;br /&gt;
The Ettus USRP X410 is equipped with status LEDs for its network-capable ports: RJ45 and QSFP28s, see RJ45 LED Behavior and QSFP28 LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
====RJ45 LED Behavior====&lt;br /&gt;
The RJ45 port has two independent LEDs: green (right) and yellow (left). The table below summarizes the LEDs' behavior. Note that link speed indication is not currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! Green LED&lt;br /&gt;
! Yellow LED&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| On&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| On&lt;br /&gt;
| Blinking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====QSFP28 LED Behavior====&lt;br /&gt;
Each QSFP28 connector has four LEDs, one for each high-speed transceiver lane. The table below summarizes the LEDs' behavior, note that for multi-lane protocols, such as 100 GbE, the corresponding LEDs are ganged together. Within the same image, multiple speeds on the same port (e.g., both 10 GbE and 100 GbE) are not supported, therefore link speed indication is not supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! QSFP28 LED (4 Total)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| Green (solid)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| Amber (blinking)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Security-related Settings==&lt;br /&gt;
The X410 ships without a root password set. It is possible to ssh into the device by simply connecting as root, and thus gaining access to all subsystems. To set a password, run the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ passwd&amp;lt;/code&amp;gt;&lt;br /&gt;
on the device.&lt;br /&gt;
&lt;br /&gt;
==Serial Connection==&lt;br /&gt;
It is possible to gain access to the device using a serial terminal emulator. To do so, the USB debug port needs to be connected to a separate computer to gain access. Most Linux, OSX, or other Unix flavors have a tool called 'screen' which can be used for this purpose, by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/ttyUSB2 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
In this command, we prepend 'sudo' to elevate user privileges (by default, accessing serial ports is not available to regular users), we specify the device node (in this case, /dev/ttyUSB2), and the baud rate (115200).&lt;br /&gt;
&lt;br /&gt;
The exact device node depends on your operating system's driver and other USB devices that might be already connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ls /dev/serial/by-id&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
The first (with the if02 suffix) connects to the STM32 microcontroller (SCU), whereas the second (with the if03 suffix) connects to Linux running on the RFSoC APU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
After entering the username root (no password is set by default), you should be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
On this prompt, you can enter any Linux command available. Using the default configuration, the serial console will also show all kernel log messages (unlike when using SSH, for example), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or bootloader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
==Connecting to the Microcontroller==&lt;br /&gt;
The microcontroller (which controls the power sequencing, among other things) also has a serial console available. To connect to the microcontroller, use the other UART device. In the example above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It provides a very simple prompt. The command 'help' will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it and other low-level diagnostics. For example, running the command reboot will emulate a reset button press, resetting the state of the device, while the command powerbtn will emulate a power button press, turning the device back on again.&lt;br /&gt;
&lt;br /&gt;
==SSH Connection==&lt;br /&gt;
The USRP X410 has two network connections: The dual QSFP28 ports, and an RJ45 connector. The latter is by default configured by DHCP; by plugging it into into 1 Gigabit switch on a DHCP-capable network, it will get assigned an IP address and thus be accessible via ssh.&lt;br /&gt;
&lt;br /&gt;
In case your network setup does not include a DHCP server, refer to the section Serial Connection. A serial login can be used to assign an IP address manually.&lt;br /&gt;
&lt;br /&gt;
After the device obtained an IP address you can log in from a Linux or OSX machine by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC # Replace with your actual device name!&amp;lt;/code&amp;gt;&lt;br /&gt;
Depending on your network setup, using a .local domain may work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC.local&amp;lt;/code&amp;gt;&lt;br /&gt;
Of course, you can also connect to the IP address directly if you know it (or set it manually using the serial console).&lt;br /&gt;
&lt;br /&gt;
Note: The device's hostname is derived from its serial number by default (&amp;lt;code&amp;gt;ni-x4xx-$SERIAL&amp;lt;/code&amp;gt;). You can change the hostname by creating the file &amp;lt;code&amp;gt;/data/network/hostname&amp;lt;/code&amp;gt;, saving the desired hostname in it, then rebooting.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the connection can be established using a tool such as PuTTY, by selecting a username of root without password.&lt;br /&gt;
&lt;br /&gt;
Like with the serial console, you should be presented with a prompt like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Autoboot ==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 can be configured to power on and boot automatically when power is applied. This setting can be controlled using the &amp;lt;code&amp;gt;eeprom-set-autoboot&amp;lt;/code&amp;gt; script. This script is executed directly on the USRP X410. To enable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot on&amp;lt;/code&amp;gt;; to disable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot off&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA==&lt;br /&gt;
&lt;br /&gt;
The FPGA can be updated simply using uhd_image_loader:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt; --fpga-path &amp;lt;path to .bit&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt;,fpga=FPGA_TYPE&amp;lt;/code&amp;gt;&lt;br /&gt;
A UHD install will likely have pre-built images in /usr/share/uhd/images/. Up-to-date images can be downloaded using the uhd_images_downloader script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt;&lt;br /&gt;
will download images into /usr/share/uhd/images/ (the path may differ, depending on how UHD was installed).&lt;br /&gt;
&lt;br /&gt;
Also note that the USRP already ships with compatible FPGA images on the device - these images can be loaded by SSH'ing into the device and running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,mgmt_addr=127.0.0.1,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FPGA Image Flavors==&lt;br /&gt;
&lt;br /&gt;
Unlike the USRP X310 or other third-generation USRP devices, the FPGA image flavors do not only encode how the QSFP28 connectors are configured, but also which master clock rates are available. This is because the data converter configuration is part of the FPGA image (the ADCs/DACs on the X410 are on the same die as the FPGA). The image flavors consist of two short strings, separated by an underscore, e.g. X4_200 is an image flavor which contains 4x 10 GbE, and can handle an analog bandwidth of 200 MHz. The first two characters describe the configuration of the QSFP28 ports: 'X' stands for 10 GbE, 'C' stands for 100 GbE. See the following table for more details.&lt;br /&gt;
&lt;br /&gt;
1x 10 GbE (Lane 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The analog bandwidth determines the available master clock rates. As of UHD 4.1, only the X4_200 image is shipped with UHD, which allows a 245.76 MHz or 250 MHz master clock rate. The other images are considered experimental (unsupported).&lt;br /&gt;
&lt;br /&gt;
==Device Arguments==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! Example Value&lt;br /&gt;
|-&lt;br /&gt;
| addr&lt;br /&gt;
| IPv4 address of primary SFP+ port to connect to.&lt;br /&gt;
| addr=192.168.30.2&lt;br /&gt;
|-&lt;br /&gt;
| second_addr&lt;br /&gt;
| IPv4 address of secondary SFP+ port to connect to.&lt;br /&gt;
| second_addr=192.168.40.2&lt;br /&gt;
|-&lt;br /&gt;
| mgmt_addr&lt;br /&gt;
| IPv4 address or hostname to which to connect the RPC client. Defaults to `addr'.&lt;br /&gt;
| mgmt_addr=ni-sulfur-311FE00&lt;br /&gt;
|-&lt;br /&gt;
| find_all&lt;br /&gt;
| When using broadcast, find all devices, even if unreachable via CHDR.&lt;br /&gt;
| find_all=1&lt;br /&gt;
|-&lt;br /&gt;
| master_clock_rate&lt;br /&gt;
| Master Clock Rate in Hz.&lt;br /&gt;
| master_clock_rate=250e6&lt;br /&gt;
|-&lt;br /&gt;
| serialize_init&lt;br /&gt;
| Force serial initialization of daughterboards.&lt;br /&gt;
| serialize_init=1&lt;br /&gt;
|-&lt;br /&gt;
| skip_init&lt;br /&gt;
| Skip the initialization process for the device.&lt;br /&gt;
| skip_init=1&lt;br /&gt;
|-&lt;br /&gt;
| time_source&lt;br /&gt;
| Specify the time (PPS) source.&lt;br /&gt;
| time_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| clock_source&lt;br /&gt;
| Specify the reference clock source.&lt;br /&gt;
| clock_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| ref_clk_freq&lt;br /&gt;
| Specify the external reference clock frequency, default is 10 MHz.&lt;br /&gt;
| ref_clk_freq=20e6&lt;br /&gt;
|-&lt;br /&gt;
| discovery_port&lt;br /&gt;
| Override default value for MPM discovery port.&lt;br /&gt;
| discovery_port=49700&lt;br /&gt;
|-&lt;br /&gt;
| rpc_port&lt;br /&gt;
| Override default value for MPM RPC port.&lt;br /&gt;
| rpc_port=49701&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==GPS==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 includes a Jackson Labs LTE-Lite GPS module. Its antenna port is on the rear panel (see Front and Back Panels). When the X410 has access to GPS satellite signals, it can use this module to read out the current GPS time and location as well as to discipline an onboard OCXO.&lt;br /&gt;
&lt;br /&gt;
To use the GPS as a clock and time reference, simply use gpsdo as a clock or time source. Alternatively, set gpsdo as a synchronization source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Set clock/time individually:&lt;br /&gt;
usrp-&amp;gt;set_clock_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
usrp-&amp;gt;set_time_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
// This is equivalent to the previous commands, but faster, as it sets&lt;br /&gt;
// both settings simultaneously and avoids duplicating settings that are shared&lt;br /&gt;
// between these calls.&lt;br /&gt;
usrp-&amp;gt;set_sync_source(&amp;quot;clock_source=gpsdo,time_source=gpsdo&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the GPS module is not always enabled. Its power-on status can be queried using the gps_enabled GPS sensor (see also The Sensor API). When disabled, none of the sensors will return useful (if any) values.&lt;br /&gt;
&lt;br /&gt;
When selecting gpsdo as a clock source, the GPS will always be enabled. Note that acquiring a GPS lock can take some time after enabling the GPS, so if a UHD application is enabling the GPS dynamically, it might take some time before a GPS lock is reported.&lt;br /&gt;
&lt;br /&gt;
==Front-Panel Programmable GPIOs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 has two HDMI front-panel connectors, which are connected to the FPGA.&lt;br /&gt;
&lt;br /&gt;
Support for using these with UHD is not yet available.&lt;br /&gt;
&lt;br /&gt;
==Subdev Specifications==&lt;br /&gt;
&lt;br /&gt;
The RF ports on the front panel of the X410 + ZBX correspond to the following subdev specifications:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Label&lt;br /&gt;
! style=&amp;quot;text-align:center; vertical-align:middle; font-weight:bold;&amp;quot; | Subdev Spec&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 0&lt;br /&gt;
| A:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 1&lt;br /&gt;
| A:1&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 0&lt;br /&gt;
| B:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 1&lt;br /&gt;
| B:1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The subdev spec slot identifiers &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; are not reflected on the front panel. They were set to match valid subdev specifications of previous USRPs, maintaining backward compatibility.&lt;br /&gt;
&lt;br /&gt;
These values can be used for uhd::usrp::multi_usrp::set_rx_subdev_spec() and uhd::usrp::multi_usrp::set_tx_subdev_spec() as with other USRPs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Rear Panel Status LEDs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 is equipped with four LEDs located on the device's rear panel. Each LED supports four different states: Off, Green, Red, and Amber. One LED (PWR) indicates the device's power state (see Power LED below). The other three LEDs (LED 0, LED 1, and LED 2) are user-configurable, different behaviors are supported for each of these LEDs (see User-configurable LEDs below).&lt;br /&gt;
&lt;br /&gt;
[[File:x4xx_rearpanel_status_leds.png|125px]]&lt;br /&gt;
&lt;br /&gt;
===X4x0 Rear Panel Status LEDs===&lt;br /&gt;
Power LED&lt;br /&gt;
The USRP X410's PWR LED is reserved to visually indicate the user the device's power state. Power LED Behavior describes what each LED state represents.&lt;br /&gt;
&lt;br /&gt;
===Power LED Behavior===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! PWR LED State&lt;br /&gt;
! style=&amp;quot;vertical-align:middle;&amp;quot; | Meaning&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Off&lt;br /&gt;
| No power is applied&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Amber&lt;br /&gt;
| Power is good but X410 is powered off&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Green&lt;br /&gt;
| Power is good and X410 is powered on&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Red&lt;br /&gt;
| Power error state&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===User-configurable LEDs===&lt;br /&gt;
The USRP X410's user-configurable rear panel status LEDs (LED 0, LED 1, and LED 2) allow the user to have visual indication of various device conditions. Supported LED Behaviors provides a complete list of the supported behaviors for each user-configurable LED. By default, these LEDs are configured as described in LEDs Default Behavior.&lt;br /&gt;
&lt;br /&gt;
The user may alter the default LEDs behavior either temporarily or persistently, see the Temporarily change the LED Behavior or Persistently in the UHD manual to change the LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
https://files.ettus.com/manual/page_usrp_x4xx.html&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:X410]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5302</id>
		<title>Using the RFNoC Replay Block</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5302"/>
				<updated>2022-03-23T17:40:25Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Updated link to &amp;quot;Using the RFNoC Replay Block in UHD 4&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This application note guides a user through basic use of the &lt;br /&gt;
RFNoC Replay block in UHD 3.x and explains how to run the UHD Replay example. This example covers use on the X300/X310 and N310 products. UHD 4.0 and later is covered in [[Using the RFNoC Replay Block in UHD 4]].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay block, it must be instantiated in the design and connected to the DRAM interface. It can take the place of the DMA FIFO(s) or be used concert with the DMA FIFO(s). In this note we will be replacing the DMA FIFO block with the Replay block and running a UHD example that records data to DRAM from a file then plays it back over the radio continuously.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Your system must be configured for RFNoC development to compile and use the RFNoC examples. Here we briefly explain how to setup a system to build and run the RFNoC Replay example.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note AN-823 [[Getting Started with RFNoC Development]] for a more detailed overview of RFNoC development.&lt;br /&gt;
&lt;br /&gt;
To begin, use the following &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; command to download the needed UHD repository. The &amp;lt;code&amp;gt;--recursive&amp;lt;/code&amp;gt; option causes the latest compatible FPGA code to also be cloned into the &amp;lt;code&amp;gt;fpga-src&amp;lt;/code&amp;gt; subfolder.&lt;br /&gt;
&lt;br /&gt;
    $ git clone --recursive https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
Then checkout the appropriate version of UHD that you intend to use. Replay block support was added in UHD 3.14. The latest UHD 3.x version is recommended.&lt;br /&gt;
&lt;br /&gt;
    $ git checkout UHD-3.15.LTS&lt;br /&gt;
    $ git submodule update --recursive&lt;br /&gt;
&lt;br /&gt;
===Building and Installing UHD===&lt;br /&gt;
&lt;br /&gt;
If you have not already done so, follow the steps in Application Note '''AN-445''' under the heading [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux#Update_and_Install_dependencies|Update and Install dependencies]].&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux|AN-445]] for detailed instructions on building and installing UHD from the source code. However, RFNoC must be enabled when running CMake in order to run the RFNoC examples. The instructions below summarize the basic steps required to build and install UHD so that you can run the Replay example.&lt;br /&gt;
&lt;br /&gt;
To build and install UHD, begin by opening a terminal in the UHD repository that you cloned, then create a &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; folder within the &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; host folder of the repository.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
&lt;br /&gt;
Run CMake with RFNoC enabled to create the Makefiles.&lt;br /&gt;
&lt;br /&gt;
    $ cmake -DENABLE_RFNOC=ON ../&lt;br /&gt;
&lt;br /&gt;
Run Make to build UHD with RFNoC support.&lt;br /&gt;
&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
Install UHD, using the default install prefix, which will install UHD under the &amp;lt;code&amp;gt;/usr/local/lib&amp;lt;/code&amp;gt; folder. You need to run this as root due to the permissions on that folder.&lt;br /&gt;
&lt;br /&gt;
   $ sudo make install&lt;br /&gt;
&lt;br /&gt;
Update the system's shared library cache.&lt;br /&gt;
&lt;br /&gt;
   $ sudo ldconfig&lt;br /&gt;
&lt;br /&gt;
Make sure that the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; environment variable is defined and includes the folder under which UHD was installed. Most commonly, you can add the line below to the end of your &amp;lt;code&amp;gt;$HOME/.bashrc&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; location may vary depending on your Linux distribution.&lt;br /&gt;
&lt;br /&gt;
   $ export LD_LIBRARY_PATH=/usr/local/lib&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need to have the Xilinx development tools installed. The specific version required depends on the branch and state of the FPGA code. The UHD-3.13 branches require Vivado 17.4. Refer to the installation instructions for Vivado in order to install these tools. It is recommended that you use the default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt; to ensure compatibility with the FPGA build flow.&lt;br /&gt;
&lt;br /&gt;
==Building the FPGA==&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the USRP you plan to use. This is currently a manual step. The instructions below are for the X310, but similar instructions apply to the N310.&lt;br /&gt;
&lt;br /&gt;
First, we must modify the Verilog code to include the Replay Block. To do this, modify the file &amp;lt;code&amp;gt;fpga-src/top/x300/x300_core.v&amp;lt;/code&amp;gt; and change localparam &amp;lt;code&amp;gt;USE_REPLAY&amp;lt;/code&amp;gt; from 0 to 1. This causes the FPGA code to instantiate &amp;lt;code&amp;gt;noc_block_replay&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt;. Note that the DMA FIFO will not be included in this example and therefore cannot be used.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If using the N310, modify the file &amp;lt;code&amp;gt;fpga-src/top/n3xx/n3xx_core.v&amp;lt;/code&amp;gt; and make the same change. Other products that support RFNoC can also use the replay block. However, in other products, the noc_block_replay instance would need to be manually instantiated in the code following the examples given in the &amp;lt;code&amp;gt;x300_core.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;n3xx_core.v&amp;lt;/code&amp;gt; files.&lt;br /&gt;
&lt;br /&gt;
After making the required code change, you are ready to rebuild the FPGA image. Begin by setting up the environment to use the FPGA build tools.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/fpga-src/usrp3/top/x300&lt;br /&gt;
    $ source ./setup.sh&lt;br /&gt;
&lt;br /&gt;
Run make to build the desired FPGA image. For example, to build the X310 HG image, use the following command:&lt;br /&gt;
&lt;br /&gt;
    $ make X310_HG&lt;br /&gt;
&lt;br /&gt;
Once compilation is complete, download the image to your USRP product. For example, if the X310 HG image were connected to SFP port 0 (1 Gigabit Ethernet) using the default IP address, then you would run the following command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args=&amp;quot;type=x300,addr=192.168.10.2&amp;quot; --fpga-path=./build-X310_HG/x300.bit&lt;br /&gt;
&lt;br /&gt;
After the download has completed, power cycle the X310 to load the new bitstream. Confirm that the Replay block appears in the system by running &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe --args=&amp;quot;addr=192.168.10.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You should see the &amp;lt;code&amp;gt;Replay&amp;lt;/code&amp;gt; block listed among the RFNoC blocks on the device.&lt;br /&gt;
&lt;br /&gt;
   |   |     _____________________________________________________&lt;br /&gt;
   |   |    /&lt;br /&gt;
   |   |   |       RFNoC blocks on this device:&lt;br /&gt;
   |   |   |   &lt;br /&gt;
   |   |   |   * Replay_0&lt;br /&gt;
   |   |   |   * Radio_0&lt;br /&gt;
   |   |   |   * Radio_1&lt;br /&gt;
   |   |   |   * DDC_0&lt;br /&gt;
   |   |   |   * DDC_1&lt;br /&gt;
   |   |   |   * DUC_0&lt;br /&gt;
   |   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
==Building the Replay Example==&lt;br /&gt;
&lt;br /&gt;
In this section we will compile the replay_from_file UHD example. Begin by creating a CMake file for the Replay example using &amp;lt;code&amp;gt;uhd/host/examples/init_usrp/CMakeLists.txt&amp;lt;/code&amp;gt; as an example.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host/examples&lt;br /&gt;
    $ mkdir replay_samples_from_file&lt;br /&gt;
    $ cd replay_samples_from_file&lt;br /&gt;
    $ cp ../init_usrp/CMakeLists.txt ./&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;init_usrp&amp;lt;/code&amp;gt; references to &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;init_usrp.cpp&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;../replay_samples_from_file.cpp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:uhd cpp makefile edits.png|650px]]&lt;br /&gt;
&lt;br /&gt;
You can now invoke CMake and run Make to build the example.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
    $ cmake ../&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a file containing the samples you wish to replay. This could be generated in advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;) to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000 samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz. Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real and 16-bit imaginary components). We can run the program by invoking python from the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does not perform rate conversion (i.e., the the DUC is not used), so the rate specified must match the native sample rate of your device (i.e., 200&amp;amp;nbsp;Msps for the X300/X310 or 125&amp;amp;nbsp;Msps for the N310). The samples file should contain &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; data samples and should be a multiple of 2 samples (8 bytes) in size, since the Replay block records and plays back in multiples of 8 bytes. For example, for the N310 you could change &amp;lt;code&amp;gt;SAMPLE_RATE&amp;lt;/code&amp;gt; in the Python program to 125.0e6, which would result in 64 periods of the 500&amp;amp;nbsp;kHz tone.&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, you could enter a command like the following.&lt;br /&gt;
&lt;br /&gt;
    $ ./replay_samples_from_file --freq 915e6 --gain 10 --file samples.dat&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the FPGA, where they are recorded into the USRP's on-board DRAM, then would cause Replay block to play back the samples to the radio continuously with a base frequency of 915 MHz, creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
The Replay block is contained in &amp;lt;code&amp;gt;noc_block_replay.v&amp;lt;/code&amp;gt;. This block works like a record and playback buffer that uses DRAM on the USRP to store samples. It connects to the RFNoC crossbar and to the DRAM in the same way that the &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt; block does. Data can be streamed to the block, like to any other RFNoC block. Playback is analogous to the way the &amp;lt;code&amp;gt;noc_block_radio_core&amp;lt;/code&amp;gt; works when we ask it to receive radio samples.&lt;br /&gt;
&lt;br /&gt;
One key difference is that the Replay block works only with 64-bit samples. Therefore, all addresses, buffer sizes, and transfers should be a multiple of 8 bytes. For example, when using &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; samples (4 bytes each) everything should be a multiple of two samples to ensure we are always working with multiples of 8 bytes.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to the example source code in &amp;lt;code&amp;gt;replay_samples_from_file.cpp&amp;lt;/code&amp;gt; for a more detailed example of how to use the Replay block.&lt;br /&gt;
&lt;br /&gt;
Prior to streaming data to the Replay block for recording, it is necessary to configure the base address and size of the record buffer.&lt;br /&gt;
&lt;br /&gt;
    // Configure the record buffer&lt;br /&gt;
    replay_ctrl-&amp;gt;config_record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt; and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is filled, recording automatically stops. Care should be taken to configure the memory buffers so that they do not overlap if more than one Replay block or buffer is being used simultaneously. The memory addresses and sizes should be 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block than the size of the record buffer. Additional data is not accepted or dropped by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the size of the DRAM on the USRP and how the memory interface is configured on the USRP. For example, the &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; IP used by the X310 is configured to give each connected device an address space of 32&amp;amp;nbsp;MiB. As a result, the Replay block will be limited to this amount of memory. The &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; file must be modified if more than 32&amp;amp;nbsp;MiB needs to be buffered.&lt;br /&gt;
&lt;br /&gt;
To begin recording data to the Replay block, the record logic should be initialized:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and it resets the internal counters that track how much data has been recorded. If a previous recording has taken place then it is a good idea to ensure that stale data was not queued up in the RF network on the FPGA from a previous run. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling &amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up unexpectedly in the record buffer. If so, it restarts recording then waits again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected);&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base address and size of the playback buffer. To play back previously recorded data, set the start address to the same address that was used for the record buffer and set the size of the playback buffer to the match the amount of data that was recorded. Note that the record and playback buffers do not need to the same, allowing a single Replay block to both record and playback to different regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command. Playback automatically wraps around to the start of the buffer if more data is requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only the specified number of samples to be played once. The &amp;lt;code&amp;gt;num_samps&amp;lt;/code&amp;gt; parameter is a 28-bit value, limiting this mode of playback to 2&amp;lt;sup&amp;gt;28&amp;lt;/sup&amp;gt; words at a time. Playback can be stopped by issuing a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is received (DRAM reads are not aborted mid-transaction). As a result, some data will continue to stream from the Replay block after the stop command is issued while waiting for the DRAM read to complete and for all the internal buffers to empty. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example determines when playback streaming has stopped by reading the 64-bit &amp;lt;code&amp;gt;SR_READBACK_REG_GLOBAL_PARAMS&amp;lt;/code&amp;gt; register and waiting for the packet count to stop increasing.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Application_Notes&amp;diff=5301</id>
		<title>Application Notes</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Application_Notes&amp;diff=5301"/>
				<updated>2022-03-23T17:39:18Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added new AN for Replay Block in UHD 4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Application Notes (AN) and technical articles written by engineers, for engineers. These articles offer experienced analysis, design ideas, reference designs, and tutorials—to make you productive and successful using USRP devices.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Application Notes&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot;| Number&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot;| Title&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot;| Abstract&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot;| Author(s)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-088&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[USRP Host Performance Tuning Tips and Tricks]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note provides various tips and tricks for tuning your host computer for best performance when working with USRP devices. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-111&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[UHD Device Eraser and Certificates of Volatility]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides an overview of the UHD Device Eraser utility as well as links to the Certificates of Volatility for all Ettus products.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Michael Dickens&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-117&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[GPSDO Selection Guide]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explains how to select and use a GPSDO with the USRP B-, N-, and X-series devices.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-121&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Debugging FPGA images]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers the basics to get you through the process of probing the signals inside an FPGA. In order to accomplish that, we will review briefly the 'Xilinx ChipScope Analyzer' and will apply it to one of our core RFNoC blocks: the RFNoC Signal generator. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nicolas Cuervo &amp;lt;br&amp;gt; Sugandha Gupta &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-142&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Transmitting DVB-S2 with GNU Radio and an USRP B210]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note will demonstrate using an USRP B210 and the GNU Radio DTV example flowgraph to transmit a DVB-S2 video stream to an off-the-shelf satellite receiver.    &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-158&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Using Ethernet-Based Synchronization on the USRP™ N3xx Devices]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note provides instructions for synchronizing multiple USRP N3xx devices using White Rabbit Ethernet-based synchronization.    &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Dan Baker&lt;br /&gt;
Wan Liu &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-177&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[About USRP Bandwidths and Sampling Rates]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides insight into the topics of USRP architecture, system bandwidth, host interface throughput, and available sampling rates.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-178&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Resolving Audio Codec Enumeration Issues On The E31x]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers Resolving Audio Codec Enumeration Issues On The E31x. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Logan Fagg&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-188&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Interrogating Passive Wireless SAW Sensors with the USRP]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Typical interrogator design for wireless SAW sensor systems require many discrete components and lengthy build times, making it difficult to rapidly adapt to sensor designs in a research environment. We have employed the USRP B200 as a SAW sensor interrogation system. Interrogation of wideband orthogonal frequency coded (OFC) SAW sensors imposes strict requirements on the timing and synchronization of the transceiver. The USRP FPGA has been modified to operate in a synchronous, pulsed mode of operation, allowing rapid data acquisition and the full 56MHz bandwidth to be utilized. Data from the USRP is passed to a custom matched filter correlator routine to extract sensor parameters. The system is capable of interrogating multiple sensors, simultaneously. Demonstration of the system is accomplished by wirelessly interrogating SAW sensors at 915MHz and extracting temperature.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Trip Humphries&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-204&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Getting Started with UHD and C++]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explains how to write and build C++ programs that use the UHD API and introduces&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-244&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Direction Finding with the USRP™ X-Series and TwinRX™]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers using the USRP™ TwinRX™ daughterboard in a direction find application using the MUSIC algorithm. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Srikanth Pagadarai &amp;lt;br&amp;gt; Travis Collins &amp;lt;br&amp;gt; Alexander M. Wyglinski&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-296&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Using Dual 10 Gigabit Ethernet on the USRP X300/X310]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This short guide is meant to help in quickly setting up an X-series USRP for use over two 10 Gigabit Ethernet links simultaneously. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Paul David&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-305&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[X300/X310 Device Recovery]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers the details of recovering the USRP X300/X310 via JTAG.   &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-309&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[About the Motherboard and Daughtercard EEPROM on USRP Devices]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN discusses the EEPROM storage on various USRP devices and daughtercards. This guides explains how to update the EEPROM contents and recover from EEPROM corruption. The product codes, which are also stored in the EEPROM, for all USRP devices and daughtercards are also given for reference.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Trip Humphries&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-311&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Software Development on the E310 and E312]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers the software development process on the USRP E310 and E312. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Martin Braun &amp;lt;br&amp;gt; Nicolas Cuervo&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-315&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Software Development on the E3xx USRP - Building RFNoC UHD / GNU Radio / gr-ettus from Source]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note is one of a multi-part series which will cover the software development process on the USRP E310, E312 and E313. It will cover building the rfnoc-devel branch of UHD, GNU Radio and gr-ettus from source for the host machine, and cross-compiling the rfnoc-devel branch of UHD, GNU Radio and gr-ettus for the E3xx USRP.   &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-322&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Experiments with the UBX Daughterboard in the HF Band]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| We show the results of experiments with the UBX daughtercard on an USRP X310 platform for use in the HF frequency range, from 1.8MHz to 30MHz. While the UBX is nominally rated for use only down to 10 MHz, with careful flow-graph design, and pre-filtering, it provides quite-good performance across the HF bands.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Marcus Leech&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-325&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[N200/N210 Device Recovery]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers the details of recovering your N200/N210.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-335&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Streaming processed data from the E31x with GNU Radio and ZMQ]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note will demonstrate using the USRP E310 to remotely stream processed data to a host machine.  &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-355&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Modifying an X310 Chassis for External LO Sharing]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This document describes how to modify an X310 chassis to wire the LO out of the back plate. Doing this will allow the user to export and import an LO signal as desired when using a compatible daughterboard such as the TwinRX. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sam Reiter&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-363&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Implementation of an ADS-B/Mode-S Receiver in GNU Radio]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN guides the reader through the implementation of an ADS-B receiver using the gr-air-modes Out-of-Tree (OOT) module for GNU Radio. An explanation of ADS-B is also provided, and several real-world, over-the-air examples and profiled.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-400&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Getting Started with RFNoC in UHD 4.0]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN describes how use RFNoC in UHD 4.0, including building FPGA images for RFNoC, changing which blocks are included in the build, and creating your own RFNoC blocks.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sugandha Gupta &amp;lt;br&amp;gt; Brent Stapleton &amp;lt;br&amp;gt; Wade Fife &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-401&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[RFNoC 4 Migration Guide]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Guide on how to migrate RFNoC blocks written for RFNoC 3 to RFNoC 4.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Jonathon Pendlum&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-444&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Using B200/B210/B200mini/B205mini on OSX / macOS with UHD]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides a basic guide for what to expect when using a USB-based B-series USRP on OSX / macOS with UHD.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Michael Dickens&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-445&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides a comprehensive step-by-step guide for building, installing, and maintaining the open-source toolchain, specifically UHD and GNU Radio, for the USRP from source code on the Linux platform. Other alternate installation methods are also discussed.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-452&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[5G NR EVM Measurements with the USRP N320/N321]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Example EVM measurements are shown using the USRP N320/N321 receiver and the 5G New Radio (5G NR) modulation standard. The use of I/Q image calibration and spur-dodging are demonstrated as methods to improve EVM performance. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Drew Fischer&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-492&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Selecting a RF Daughterboard]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explores the RF daughterboards used by the N-series and X-series USRP devices at a high level, compares devices across several primary features, and walks the reader through the process of selecting a particular device for the their application.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-500&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Getting Started with DPDK and UHD]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note walks through the process to get started with the Data Plane Development Kit (DPDK) driver within UHD. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple &amp;lt;br&amp;gt; Alex Williams &amp;lt;br&amp;gt; Wade Fife &amp;lt;br&amp;gt; Matt Prost&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-503&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Converting an X310 into an NI-USRP Rio]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This Application Note explains how to use an Ettus Research-branded USRP with LabVIEW, and in effect, convert it into an NI-USRP RIO.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Tim Fountain&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-504&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[USRP N Series Quick Start (Daughterboard Installation)]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note is a detailed step-by-step guide to install a daughterboard into the USRP N200/N210.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-524&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Building and Installing UHD and GNU Radio in an Offline Environment]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note will provide step-by-step instructions on building and installing UHD and GNU Radio in an offline environment. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-525&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Building and Installing UHD and GNU Radio to a Custom Prefix]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note provides step-by-step instructions on building and installing UHD and GNU Radio to a local directory. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-561&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Implementation of a Simple FM Receiver in GNU Radio]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN shows a quick and simple implementation of an FM receiver for the USRP using GNU Radio. The goal is to easily demonstrate a practical application, and to verify that the USRP is functioning properly.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-611&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides a comprehensive step-by-step guide for building, installing, and maintaining the open-source toolchain, specifically UHD and GNU Radio, for the USRP from source code on the Windows platform.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Derek Kozel&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-620&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Troubleshooting X300/X310 Device Discovery Issues]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Troubleshooting guide to intended to cover some of the most commonly recommended steps to enable USRP connectivity. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sam Reiter&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-621&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Troubleshooting N310/N320 Device Discovery Issues]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Troubleshooting guide to intended to cover some of the most commonly recommended steps to enable USRP connectivity. Serves as a supplement to the N3xx getting started guide. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sam Reiter&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-630&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Writing the USRP File System Disk Image to a SD Card]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note will provide step-by-step instructions on writing a file system disk image to a SD card using Linux.   &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-638&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Running UHD and GNU Radio on NI USRP-RIO]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explains the process to updating your NI USRP-RIO to run UHD and GNU Radio. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple &amp;lt;br&amp;gt; Michael Dickens&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-642&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Using the RFNoC Replay Block]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note guides a user through basic use of the RFNoC Replay block in UHD 3.x and explains how to run the UHD Replay example. This example covers use on the X300/X310 and N310 products.  &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Wade Fife&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-642b&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Using the RFNoC Replay Block in UHD 4]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note guides a user through basic use of the RFNoC Replay block in UHD 4.x and explains how to run the UHD Replay example.  &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Martin Braun&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-666&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Mean Time Between Failure (MTBF) of USRPs and Daughterboards]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides information about the MTBF for USRPs and daughterboards&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Michael Dickens&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-725&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[USRP N320/N321 LO Distribution]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note provides an overview of using the LO Distribution of the N320/N321 USRPs.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Brian Avenell 	&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-732&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[USRP E312 Battery Replacement Instructions]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers replacing the battery cell inside the USRP E312.  &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Robin Coxe&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-788&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN provides a comprehensive step-by-step guide for building, installing, and maintaining the open-source toolchain, specifically UHD and GNU Radio, for the USRP from source code on the Mac OS X platform.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Michael Dickens&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-800&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Enabling Ethernet Connectivity on Octoclock and Octoclock-G]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This document supplements the UHD Manual's guide for updating the Octoclock bootloader to allow for Ethernet communications with the device. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sam Reiter&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-822&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Open Architecture For Radar and EW Research]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note provides guidance for designing a system that uses the NI Open Architecture for Radar and EW Research. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Michael Dickens &amp;lt;br&amp;gt; Neel Pandeya &amp;lt;br&amp;gt; Jovian Wysocki&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-823&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Getting Started with RFNoC Development]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note gives a brief introduction into the steps required to start developing RFNoC blocks on your computer with UHD 3. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Martin Braun &amp;lt;br&amp;gt; Nicolas Cuervo&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-832&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Mapping Between ER-USRP and NI-USRP Product Numbers]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note covers the details of the mapping between Ettus Research USRP and National Instruments USRP product numbers.    &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-881&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Selecting a USRP Device]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explores the USRP family at a high level, compares devices across several primary features, and walks the reader through the process of selecting a particular device for the their application.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-882&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Synchronization and MIMO Capability with USRP Devices]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Discusses the requirements for Multiple-In-Multiple-Out (MIMO) and phased-array systems. Summarizes the MIMO capability of each USRP device and daughterboard, and shows how to build MIMO systems with the USRP product family.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-883&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Synchronizing USRP Events Using Timed Commands in UHD]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| Guide to cover common USRP synchronization scenarios and deep-dive into the use of timed commands within USRPs. &lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Sam Reiter&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-904&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[USRP X Series Quick Start (Daughterboard Installation)]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This application note is a detailed step-by-step guide to install a daughterboard into the USRP X300/X310.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya &amp;lt;br&amp;gt; Nate Temple&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| AN-936&lt;br /&gt;
|style=&amp;quot;width: 30%;&amp;quot;| [[Verifying the Operation of the USRP Using UHD and GNU Radio]]&lt;br /&gt;
|style=&amp;quot;width: 50%;&amp;quot;| This AN explains how to use UHD and GNU Radio, once installed, to verify the correct operation of the USRP. Several test procedures are explained in detail. Several tests make use of an optional spectrum analyzer and signal generator.&lt;br /&gt;
|style=&amp;quot;width: 10%; text-align: center;&amp;quot;| Neel Pandeya&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5299</id>
		<title>Using the RFNoC Replay Block in UHD 4</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5299"/>
				<updated>2022-03-23T17:38:08Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: WadeFife moved page Using the RFNoC Replay Block 4 to Using the RFNoC Replay Block in UHD 4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642b'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
This application note guides a user through basic use of the RFNoC Replay block&lt;br /&gt;
in UHD 4.x and explains how to run the UHD Replay example. This example covers&lt;br /&gt;
the USRP X410, X310/X300, N300/N310/N320 and E320 devices. For UHD 3.x, please&lt;br /&gt;
refer to [[Using_the_RFNoC_Replay_Block|the UHD 3.x replay block Application Note]].&lt;br /&gt;
&lt;br /&gt;
An introduction to RFNoC with UHD 4.0 and above can be found [[Getting_Started_with_RFNoC_in_UHD_4.0|here]].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of&lt;br /&gt;
arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay&lt;br /&gt;
block, it must be instantiated in the design and connected to the DRAM interface.&lt;br /&gt;
&lt;br /&gt;
The replay block is a standard feature of UHD and RFNoC, and a custom compile of&lt;br /&gt;
UHD is not required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs, so when using these images,&lt;br /&gt;
the following examples can be run without any manual builds of UHD or FPGA images.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
To follow this application note, you need a device with a replay block instantiated,&lt;br /&gt;
and a UHD version recent enough to have the full support for the replay block&lt;br /&gt;
(UHD 4.2 and beyond). To test for the replay block capabilities, connect and&lt;br /&gt;
enable your USRP device, and run the following command:&lt;br /&gt;
&lt;br /&gt;
    uhd_usrp_probe --args &amp;lt;device args&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Insert the appropriate device args for your device, e.g.&lt;br /&gt;
&lt;br /&gt;
    uhd_usrp_probe --args type=x4xx,addr=192.168.30.2&lt;br /&gt;
&lt;br /&gt;
Depending on your device, the output could look like this (truncated):&lt;br /&gt;
&lt;br /&gt;
     _____________________________________________________&lt;br /&gt;
    /&lt;br /&gt;
    |       Device: X400-Series Device&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Mboard: ni-x4xx-&amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   pid: 1040&lt;br /&gt;
    |   |   rev: 4&lt;br /&gt;
    |   |   rev_compat: 4&lt;br /&gt;
    |   |   serial: &amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   MPM Version: 4.0&lt;br /&gt;
    |   |   FPGA Version: 7.6&lt;br /&gt;
    |   |   FPGA git hash: &amp;lt;hash&amp;gt;.clean&lt;br /&gt;
    |   |   RFNoC capable: Yes&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   Time sources:  internal, external, qsfp0, gpsdo&lt;br /&gt;
    |   |   Clock sources: mboard, internal, external, nsync, gpsdo&lt;br /&gt;
    |   |   Sensors: ...&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/DDC#0&lt;br /&gt;
    |   |   * 0/DDC#1&lt;br /&gt;
    |   |   * 0/DUC#0&lt;br /&gt;
    |   |   * 0/DUC#1&lt;br /&gt;
    |   |   * 0/Radio#0&lt;br /&gt;
    |   |   * 0/Radio#1&lt;br /&gt;
    |   |   * 0/Replay#0&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Static connections on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/SEP#0:0==&amp;gt;0/DUC#0:0&lt;br /&gt;
    |   |   * 0/DUC#0:0==&amp;gt;0/Radio#0:0&lt;br /&gt;
    |   |   * 0/Radio#0:0==&amp;gt;0/DDC#0:0&lt;br /&gt;
    |   |   * 0/DDC#0:0==&amp;gt;0/SEP#0:0&lt;br /&gt;
    |   |   * 0/SEP#1:0==&amp;gt;0/DUC#0:1&lt;br /&gt;
    |   |   * 0/DUC#0:1==&amp;gt;0/Radio#0:1&lt;br /&gt;
    |   |   * 0/Radio#0:1==&amp;gt;0/DDC#0:1&lt;br /&gt;
    |   |   * 0/DDC#0:1==&amp;gt;0/SEP#1:0&lt;br /&gt;
    |   |   * 0/SEP#2:0==&amp;gt;0/DUC#1:0&lt;br /&gt;
    |   |   * 0/DUC#1:0==&amp;gt;0/Radio#1:0&lt;br /&gt;
    |   |   * 0/Radio#1:0==&amp;gt;0/DDC#1:0&lt;br /&gt;
    |   |   * 0/DDC#1:0==&amp;gt;0/SEP#2:0&lt;br /&gt;
    |   |   * 0/SEP#3:0==&amp;gt;0/DUC#1:1&lt;br /&gt;
    |   |   * 0/DUC#1:1==&amp;gt;0/Radio#1:1&lt;br /&gt;
    |   |   * 0/Radio#1:1==&amp;gt;0/DDC#1:1&lt;br /&gt;
    |   |   * 0/DDC#1:1==&amp;gt;0/SEP#3:0&lt;br /&gt;
    |   |   * 0/SEP#4:0==&amp;gt;0/Replay#0:0&lt;br /&gt;
    |   |   * 0/Replay#0:0==&amp;gt;0/SEP#4:0&lt;br /&gt;
    |   |   * 0/SEP#5:0==&amp;gt;0/Replay#0:1&lt;br /&gt;
    |   |   * 0/Replay#0:1==&amp;gt;0/SEP#5:0&lt;br /&gt;
    |   |   * 0/SEP#6:0==&amp;gt;0/Replay#0:2&lt;br /&gt;
    |   |   * 0/Replay#0:2==&amp;gt;0/SEP#6:0&lt;br /&gt;
    |   |   * 0/SEP#7:0==&amp;gt;0/Replay#0:3&lt;br /&gt;
    |   |   * 0/Replay#0:3==&amp;gt;0/SEP#7:0&lt;br /&gt;
&lt;br /&gt;
The output tells us that this USRP has a Replay block instantiated (&amp;lt;code&amp;gt;0/Replay#0&amp;lt;/code&amp;gt;).&lt;br /&gt;
It has four static connections to stream endpoints, which also tells us that&lt;br /&gt;
this is a four-port replay block.&lt;br /&gt;
&lt;br /&gt;
If your device does not report a replay block, then you need to load&lt;br /&gt;
an FPGA image which includes this block. See [[#building_fpga|this section]] for instructions on how to do&lt;br /&gt;
this before you proceed. If it does report a block, you can move to the next&lt;br /&gt;
section.&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a&lt;br /&gt;
file containing the samples you wish to replay. This could be generated in&lt;br /&gt;
advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For&lt;br /&gt;
this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;)&lt;br /&gt;
to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000&lt;br /&gt;
samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz.&lt;br /&gt;
Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real&lt;br /&gt;
and 16-bit imaginary components). We can run the program by invoking python from&lt;br /&gt;
the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, enter a command like the following (the path to&lt;br /&gt;
the examples depends on your installation method, for a normal installation via&lt;br /&gt;
apt-get, examples will be located in &amp;lt;code&amp;gt;/usr/lib/uhd/examples&amp;lt;/code&amp;gt; or&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/lib/uhd/examples&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
    $ cd /path/to/examples&lt;br /&gt;
    $ ./replay_samples_from_file --args &amp;lt;device args&amp;gt; --freq 915e6 --gain 10 --file samples.dat --rate 200e6&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the&lt;br /&gt;
FPGA, where they are recorded into the USRP's on-board DRAM. Then, the Replay block&lt;br /&gt;
will play the samples to the radio continuously with a base frequency of 915 MHz,&lt;br /&gt;
creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
Alternatively, use the &amp;lt;code&amp;gt;--nsamps&amp;lt;/code&amp;gt; command line argument to transmit&lt;br /&gt;
a certain number of samples before returning to the command line. Use the&lt;br /&gt;
&amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; argument to see a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
The advantage of this example compared to directly streaming the file to the&lt;br /&gt;
device is twofold:&lt;br /&gt;
&lt;br /&gt;
* The initial upload to DRAM can happen at any link rate. Even when using 1 GbE, this example will work.&lt;br /&gt;
* Once uploaded, the host computer is basically idle. The FPGA will handle the streaming to the radio front-end.&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp source code]&lt;br /&gt;
for &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; may be considered an example&lt;br /&gt;
for best practices on how to use the replay block.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
This block works like a record and playback buffer that uses DRAM on the USRP to&lt;br /&gt;
store samples.&lt;br /&gt;
Data can be streamed to the block, like to any other RFNoC block.&lt;br /&gt;
&lt;br /&gt;
Refer the [https://files.ettus.com/manual/classuhd_1_1rfnoc_1_1replay__block__control.html manual of the replay block controller]&lt;br /&gt;
for a comprehensive description of its features and API calls.&lt;br /&gt;
&lt;br /&gt;
In the following, we shall use the C++ API to demonstrate the most important&lt;br /&gt;
API calls. We will assume there is a replay block controller called&lt;br /&gt;
&amp;lt;code&amp;gt;replay_ctrl&amp;lt;/code&amp;gt; available in the current context, and it is of type&lt;br /&gt;
&amp;lt;code&amp;gt;uhd::rfnoc::replay_block_control::sptr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Recording Data===&lt;br /&gt;
&lt;br /&gt;
Before streaming data to the replay block, it needs to be configured for recording:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives&lt;br /&gt;
on port &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt; into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt;&lt;br /&gt;
and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is&lt;br /&gt;
filled, recording automatically stops. Care should be taken to configure the&lt;br /&gt;
memory buffers so that they do not overlap if more than one Replay block or&lt;br /&gt;
buffer is being used simultaneously.&lt;br /&gt;
&lt;br /&gt;
Call this once for every port that you expect to stream data into.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block&lt;br /&gt;
than the size of the record buffer. Additional data is not accepted or dropped&lt;br /&gt;
by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the&lt;br /&gt;
size of the DRAM on the USRP and how the memory interface is configured on the USRP.&lt;br /&gt;
By default, we expose the entire memory of the device, but it is possible to modify&lt;br /&gt;
&amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; if less memory should be made accessible.&lt;br /&gt;
&lt;br /&gt;
Devices have the following amount of memory:&lt;br /&gt;
{|&lt;br /&gt;
|E310&lt;br /&gt;
|512 MiB&lt;br /&gt;
|-&lt;br /&gt;
|E320&lt;br /&gt;
|2 GiB&lt;br /&gt;
|-&lt;br /&gt;
|N3xx&lt;br /&gt;
|2 GiB&lt;br /&gt;
|-&lt;br /&gt;
|X310&lt;br /&gt;
|1 GiB&lt;br /&gt;
|-&lt;br /&gt;
|X410&lt;br /&gt;
|4 GiB per bank (note: not all banks may be connected)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The currently available memory can be queried using the block controller and the &lt;br /&gt;
&amp;lt;code&amp;gt;get_mem_size()&amp;lt;/code&amp;gt; API call.&lt;br /&gt;
&lt;br /&gt;
To restart recording from the same offset, the following API call can be used:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and&lt;br /&gt;
it resets the internal counters that track how much data has been recorded. If&lt;br /&gt;
a previous recording has taken place then it is a good idea to ensure that&lt;br /&gt;
stale data was not queued up in the RF network on the FPGA from a previous run.&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling&lt;br /&gt;
&amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up&lt;br /&gt;
unexpectedly in the record buffer. If so, it restarts recording then waits&lt;br /&gt;
again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the&lt;br /&gt;
record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected)&lt;br /&gt;
        std::this_thread::sleep_for(100ms);&lt;br /&gt;
&lt;br /&gt;
===Playing Back Data===&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base&lt;br /&gt;
address and size of the playback buffer. To play back previously recorded data,&lt;br /&gt;
set the start address to the same address that was used for the record buffer&lt;br /&gt;
and set the size of the playback buffer to the match the amount of data that&lt;br /&gt;
was recorded. Note that the record and playback buffers do not need to be the&lt;br /&gt;
same, allowing a single Replay block to both record and playback to different&lt;br /&gt;
regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command.&lt;br /&gt;
Playback automatically wraps around to the start of the buffer if more data is&lt;br /&gt;
requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely&lt;br /&gt;
until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only&lt;br /&gt;
the specified number of samples to be played once. Playback can be stopped by issuing&lt;br /&gt;
 a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is&lt;br /&gt;
received (DRAM reads are not aborted mid-transaction). As a result, some data&lt;br /&gt;
will continue to stream from the Replay block after the stop command is issued&lt;br /&gt;
while waiting for the DRAM read to complete and for all the internal buffers to&lt;br /&gt;
empty.&lt;br /&gt;
&lt;br /&gt;
When using the C++ API, the &amp;lt;code&amp;gt;play()&amp;lt;/code&amp;gt; API call is a useful shorthand&lt;br /&gt;
for configuring playback and submitting the stream command at the same time:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;play(buffer_start_byte_address, num_bytes_to_play, replay_chan, start_time, repeat);&lt;br /&gt;
&lt;br /&gt;
In either case, the start time is optional. When given, the first sample to leave&lt;br /&gt;
the block on playback is tagged with this timestamp.&lt;br /&gt;
&lt;br /&gt;
===Memory Alignment and Word Sizes===&lt;br /&gt;
&lt;br /&gt;
There are two memory alignment values that need to be considered when dealing&lt;br /&gt;
with the replay block. The first is the word size, which is the minimum number of&lt;br /&gt;
bytes per DRAM transaction. For most configurations, the word size is 64 bits,&lt;br /&gt;
which means that only even numbers of samples can be recorded or played back&lt;br /&gt;
when using 16-bit complex samples (at 4 bytes per sample). Use the &amp;lt;code&amp;gt;get_word_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
API call to identify the correct word size. The word size can go up to 512 bits.&lt;br /&gt;
&lt;br /&gt;
The second alignment value is the memory's page boundaries. The start addresses&lt;br /&gt;
for record and replay should fall onto a 4 kiB memory boundary to ensure correct&lt;br /&gt;
alignment of data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;building_fpga&amp;quot;&amp;gt;&lt;br /&gt;
==Building Custom FPGA Images with a Replay Block==&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Note: Cloning the repository is only required when building custom FPGA images.&lt;br /&gt;
If the replay block is already built into the USRP's bit file, this is not&lt;br /&gt;
required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs.&lt;br /&gt;
&lt;br /&gt;
If you do require access to the source code, e.g. to build an FPGA image with a&lt;br /&gt;
custom replay block configuration, run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ git clone https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
For the rest of the Application Note, we assume the repository was cloned into&lt;br /&gt;
the location &amp;lt;code&amp;gt;~/src/uhd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need&lt;br /&gt;
to have the Xilinx development tools installed. The specific version required&lt;br /&gt;
depends on the UHD version. Refer to the&lt;br /&gt;
[https://files.ettus.com/manual/md_usrp3_build_instructions.html manual] for the&lt;br /&gt;
correct version for your UHD version, and the installation instructions for&lt;br /&gt;
Vivado in order to install these tools. It is recommended that you use the&lt;br /&gt;
default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Building the FPGA===&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Most bitfiles already include the replay block! This section is&lt;br /&gt;
only relevant if you want to build your own bitfile, or the bitfile you're using&lt;br /&gt;
does not contain the replay block already.&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the&lt;br /&gt;
USRP you plan to use. This is currently a manual step. The instructions below&lt;br /&gt;
are for the X310, but similar instructions apply to other RFNoC-capable&lt;br /&gt;
devices.&lt;br /&gt;
&lt;br /&gt;
To create a custom FPGA image with a replay, you need to create an image core file.&lt;br /&gt;
The following lines are the relevant lines from the&lt;br /&gt;
[https://github.com/EttusResearch/uhd/blob/master/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml X310 default image core file]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      # ... all the other stream endpoints...&lt;br /&gt;
      ep4:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
      ep5:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
    &lt;br /&gt;
    noc_blocks:&lt;br /&gt;
      # ... all the other blocks...&lt;br /&gt;
      replay0:&lt;br /&gt;
        block_desc: 'replay.yml'&lt;br /&gt;
        parameters:&lt;br /&gt;
          NUM_PORTS: 2&lt;br /&gt;
          MEM_ADDR_W: 30&lt;br /&gt;
    &lt;br /&gt;
    connections:&lt;br /&gt;
      # ...connections for all the other blocks...&lt;br /&gt;
      # ep4 to replay0(0)&lt;br /&gt;
      - { srcblk: ep4,     srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
      # replay0(0) to ep4&lt;br /&gt;
      - { srcblk: replay0, srcport: out_0, dstblk: ep4,     dstport: in0  }&lt;br /&gt;
      # ep5 to replay0(1)&lt;br /&gt;
      - { srcblk: ep5,     srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
      # replay0(1) to ep5&lt;br /&gt;
      - { srcblk: replay0, srcport: out_1, dstblk: ep5,     dstport: in0  }&lt;br /&gt;
      # BSP Connections&lt;br /&gt;
      - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      # ...all other clock domains...&lt;br /&gt;
      - { srcblk: _device_, srcport: dram,  dstblk: replay0, dstport: mem  }&lt;br /&gt;
&lt;br /&gt;
As you can see, the replay block requires configuration in up to four sections:&lt;br /&gt;
* For maximum flexibility, every port of the replay block will receive its own stream endpoint. This is not a requirement of the replay block, but allows its flexible use.&lt;br /&gt;
* Of course, the block needs to be declared in the &amp;lt;code&amp;gt;noc_blocks&amp;lt;/code&amp;gt; section. The blocks contain two parameters, NUM_PORTS, and MEM_ADDR_W. The former is the number of ports this RFNoC block may have. The latter is the width of the memory address word, i.e., it is log2(memory_size).&lt;br /&gt;
* It must be connected to the stream endpoints in the &amp;lt;code&amp;gt;connections&amp;lt;/code&amp;gt; section, as well as to the DRAM banks (BSP connection).&lt;br /&gt;
* Finally, the clock domain needs to be connected.&lt;br /&gt;
&lt;br /&gt;
All devices have limits regarding the number of ports and the memory size. The following values may not be exceeded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
E310:&lt;br /&gt;
    NUM_PORTS: 2&lt;br /&gt;
    MEM_ADDR_W: 29&lt;br /&gt;
E320:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 31&lt;br /&gt;
N3xx:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 31&lt;br /&gt;
X310:&lt;br /&gt;
    NUM_PORTS: 2&lt;br /&gt;
    MEM_ADDR_W: 30&lt;br /&gt;
X410:&lt;br /&gt;
    NUM_PORTS: 4&lt;br /&gt;
    MEM_ADDR_W: 32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When the YAML image core file is complete, save it, e.g., as x310_replay_image_core.yml,&lt;br /&gt;
and pass it to the image builder:&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y x310_replay_image_core.yml [ --fpga-dir ~/usr/uhd/fpga ]&lt;br /&gt;
&lt;br /&gt;
This will create a bitfile that contains the replay block. It can be loaded onto&lt;br /&gt;
the device using the &amp;lt;code&amp;gt;uhd_image_loader&amp;lt;/code&amp;gt; tool:&lt;br /&gt;
&lt;br /&gt;
    uhd_image_loader --args type=x300,addr=&amp;lt;ip address&amp;gt; --fpga-path=/path/to/usrp_x310_fpga_HG.bit&lt;br /&gt;
&lt;br /&gt;
When this is complete, the replay block is ready to use.&lt;br /&gt;
&lt;br /&gt;
==Source files==&lt;br /&gt;
&lt;br /&gt;
For reference, the following files implement the replay block:&lt;br /&gt;
&lt;br /&gt;
* Verilog/HDL sources: https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_replay&lt;br /&gt;
* C++ Block controller sources (header, block controller, Python bindings, unit tests):&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/include/uhd/rfnoc/replay_block_control.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control.cpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control_python.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/tests/rfnoc_block_tests/replay_block_test.cpp&lt;br /&gt;
* Example: https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_4&amp;diff=5300</id>
		<title>Using the RFNoC Replay Block 4</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_4&amp;diff=5300"/>
				<updated>2022-03-23T17:38:08Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: WadeFife moved page Using the RFNoC Replay Block 4 to Using the RFNoC Replay Block in UHD 4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Using the RFNoC Replay Block in UHD 4]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5298</id>
		<title>Using the RFNoC Replay Block</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5298"/>
				<updated>2022-03-23T17:32:08Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Removed &amp;quot;not&amp;quot; that shouldn't be there&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This application note guides a user through basic use of the &lt;br /&gt;
RFNoC Replay block in UHD 3.x and explains how to run the UHD Replay example. This example covers use on the X300/X310 and N310 products. UHD 4.0 and later is covered in [[Using the RFNoC Replay Block 4]].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay block, it must be instantiated in the design and connected to the DRAM interface. It can take the place of the DMA FIFO(s) or be used concert with the DMA FIFO(s). In this note we will be replacing the DMA FIFO block with the Replay block and running a UHD example that records data to DRAM from a file then plays it back over the radio continuously.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Your system must be configured for RFNoC development to compile and use the RFNoC examples. Here we briefly explain how to setup a system to build and run the RFNoC Replay example.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note AN-823 [[Getting Started with RFNoC Development]] for a more detailed overview of RFNoC development.&lt;br /&gt;
&lt;br /&gt;
To begin, use the following &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; command to download the needed UHD repository. The &amp;lt;code&amp;gt;--recursive&amp;lt;/code&amp;gt; option causes the latest compatible FPGA code to also be cloned into the &amp;lt;code&amp;gt;fpga-src&amp;lt;/code&amp;gt; subfolder.&lt;br /&gt;
&lt;br /&gt;
    $ git clone --recursive https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
Then checkout the appropriate version of UHD that you intend to use. Replay block support was added in UHD 3.14. The latest UHD 3.x version is recommended.&lt;br /&gt;
&lt;br /&gt;
    $ git checkout UHD-3.15.LTS&lt;br /&gt;
    $ git submodule update --recursive&lt;br /&gt;
&lt;br /&gt;
===Building and Installing UHD===&lt;br /&gt;
&lt;br /&gt;
If you have not already done so, follow the steps in Application Note '''AN-445''' under the heading [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux#Update_and_Install_dependencies|Update and Install dependencies]].&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux|AN-445]] for detailed instructions on building and installing UHD from the source code. However, RFNoC must be enabled when running CMake in order to run the RFNoC examples. The instructions below summarize the basic steps required to build and install UHD so that you can run the Replay example.&lt;br /&gt;
&lt;br /&gt;
To build and install UHD, begin by opening a terminal in the UHD repository that you cloned, then create a &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; folder within the &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; host folder of the repository.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
&lt;br /&gt;
Run CMake with RFNoC enabled to create the Makefiles.&lt;br /&gt;
&lt;br /&gt;
    $ cmake -DENABLE_RFNOC=ON ../&lt;br /&gt;
&lt;br /&gt;
Run Make to build UHD with RFNoC support.&lt;br /&gt;
&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
Install UHD, using the default install prefix, which will install UHD under the &amp;lt;code&amp;gt;/usr/local/lib&amp;lt;/code&amp;gt; folder. You need to run this as root due to the permissions on that folder.&lt;br /&gt;
&lt;br /&gt;
   $ sudo make install&lt;br /&gt;
&lt;br /&gt;
Update the system's shared library cache.&lt;br /&gt;
&lt;br /&gt;
   $ sudo ldconfig&lt;br /&gt;
&lt;br /&gt;
Make sure that the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; environment variable is defined and includes the folder under which UHD was installed. Most commonly, you can add the line below to the end of your &amp;lt;code&amp;gt;$HOME/.bashrc&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; location may vary depending on your Linux distribution.&lt;br /&gt;
&lt;br /&gt;
   $ export LD_LIBRARY_PATH=/usr/local/lib&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need to have the Xilinx development tools installed. The specific version required depends on the branch and state of the FPGA code. The UHD-3.13 branches require Vivado 17.4. Refer to the installation instructions for Vivado in order to install these tools. It is recommended that you use the default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt; to ensure compatibility with the FPGA build flow.&lt;br /&gt;
&lt;br /&gt;
==Building the FPGA==&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the USRP you plan to use. This is currently a manual step. The instructions below are for the X310, but similar instructions apply to the N310.&lt;br /&gt;
&lt;br /&gt;
First, we must modify the Verilog code to include the Replay Block. To do this, modify the file &amp;lt;code&amp;gt;fpga-src/top/x300/x300_core.v&amp;lt;/code&amp;gt; and change localparam &amp;lt;code&amp;gt;USE_REPLAY&amp;lt;/code&amp;gt; from 0 to 1. This causes the FPGA code to instantiate &amp;lt;code&amp;gt;noc_block_replay&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt;. Note that the DMA FIFO will not be included in this example and therefore cannot be used.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If using the N310, modify the file &amp;lt;code&amp;gt;fpga-src/top/n3xx/n3xx_core.v&amp;lt;/code&amp;gt; and make the same change. Other products that support RFNoC can also use the replay block. However, in other products, the noc_block_replay instance would need to be manually instantiated in the code following the examples given in the &amp;lt;code&amp;gt;x300_core.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;n3xx_core.v&amp;lt;/code&amp;gt; files.&lt;br /&gt;
&lt;br /&gt;
After making the required code change, you are ready to rebuild the FPGA image. Begin by setting up the environment to use the FPGA build tools.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/fpga-src/usrp3/top/x300&lt;br /&gt;
    $ source ./setup.sh&lt;br /&gt;
&lt;br /&gt;
Run make to build the desired FPGA image. For example, to build the X310 HG image, use the following command:&lt;br /&gt;
&lt;br /&gt;
    $ make X310_HG&lt;br /&gt;
&lt;br /&gt;
Once compilation is complete, download the image to your USRP product. For example, if the X310 HG image were connected to SFP port 0 (1 Gigabit Ethernet) using the default IP address, then you would run the following command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args=&amp;quot;type=x300,addr=192.168.10.2&amp;quot; --fpga-path=./build-X310_HG/x300.bit&lt;br /&gt;
&lt;br /&gt;
After the download has completed, power cycle the X310 to load the new bitstream. Confirm that the Replay block appears in the system by running &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe --args=&amp;quot;addr=192.168.10.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You should see the &amp;lt;code&amp;gt;Replay&amp;lt;/code&amp;gt; block listed among the RFNoC blocks on the device.&lt;br /&gt;
&lt;br /&gt;
   |   |     _____________________________________________________&lt;br /&gt;
   |   |    /&lt;br /&gt;
   |   |   |       RFNoC blocks on this device:&lt;br /&gt;
   |   |   |   &lt;br /&gt;
   |   |   |   * Replay_0&lt;br /&gt;
   |   |   |   * Radio_0&lt;br /&gt;
   |   |   |   * Radio_1&lt;br /&gt;
   |   |   |   * DDC_0&lt;br /&gt;
   |   |   |   * DDC_1&lt;br /&gt;
   |   |   |   * DUC_0&lt;br /&gt;
   |   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
==Building the Replay Example==&lt;br /&gt;
&lt;br /&gt;
In this section we will compile the replay_from_file UHD example. Begin by creating a CMake file for the Replay example using &amp;lt;code&amp;gt;uhd/host/examples/init_usrp/CMakeLists.txt&amp;lt;/code&amp;gt; as an example.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host/examples&lt;br /&gt;
    $ mkdir replay_samples_from_file&lt;br /&gt;
    $ cd replay_samples_from_file&lt;br /&gt;
    $ cp ../init_usrp/CMakeLists.txt ./&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;init_usrp&amp;lt;/code&amp;gt; references to &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;init_usrp.cpp&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;../replay_samples_from_file.cpp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:uhd cpp makefile edits.png|650px]]&lt;br /&gt;
&lt;br /&gt;
You can now invoke CMake and run Make to build the example.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
    $ cmake ../&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a file containing the samples you wish to replay. This could be generated in advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;) to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000 samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz. Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real and 16-bit imaginary components). We can run the program by invoking python from the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does not perform rate conversion (i.e., the the DUC is not used), so the rate specified must match the native sample rate of your device (i.e., 200&amp;amp;nbsp;Msps for the X300/X310 or 125&amp;amp;nbsp;Msps for the N310). The samples file should contain &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; data samples and should be a multiple of 2 samples (8 bytes) in size, since the Replay block records and plays back in multiples of 8 bytes. For example, for the N310 you could change &amp;lt;code&amp;gt;SAMPLE_RATE&amp;lt;/code&amp;gt; in the Python program to 125.0e6, which would result in 64 periods of the 500&amp;amp;nbsp;kHz tone.&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, you could enter a command like the following.&lt;br /&gt;
&lt;br /&gt;
    $ ./replay_samples_from_file --freq 915e6 --gain 10 --file samples.dat&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the FPGA, where they are recorded into the USRP's on-board DRAM, then would cause Replay block to play back the samples to the radio continuously with a base frequency of 915 MHz, creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
The Replay block is contained in &amp;lt;code&amp;gt;noc_block_replay.v&amp;lt;/code&amp;gt;. This block works like a record and playback buffer that uses DRAM on the USRP to store samples. It connects to the RFNoC crossbar and to the DRAM in the same way that the &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt; block does. Data can be streamed to the block, like to any other RFNoC block. Playback is analogous to the way the &amp;lt;code&amp;gt;noc_block_radio_core&amp;lt;/code&amp;gt; works when we ask it to receive radio samples.&lt;br /&gt;
&lt;br /&gt;
One key difference is that the Replay block works only with 64-bit samples. Therefore, all addresses, buffer sizes, and transfers should be a multiple of 8 bytes. For example, when using &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; samples (4 bytes each) everything should be a multiple of two samples to ensure we are always working with multiples of 8 bytes.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to the example source code in &amp;lt;code&amp;gt;replay_samples_from_file.cpp&amp;lt;/code&amp;gt; for a more detailed example of how to use the Replay block.&lt;br /&gt;
&lt;br /&gt;
Prior to streaming data to the Replay block for recording, it is necessary to configure the base address and size of the record buffer.&lt;br /&gt;
&lt;br /&gt;
    // Configure the record buffer&lt;br /&gt;
    replay_ctrl-&amp;gt;config_record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt; and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is filled, recording automatically stops. Care should be taken to configure the memory buffers so that they do not overlap if more than one Replay block or buffer is being used simultaneously. The memory addresses and sizes should be 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block than the size of the record buffer. Additional data is not accepted or dropped by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the size of the DRAM on the USRP and how the memory interface is configured on the USRP. For example, the &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; IP used by the X310 is configured to give each connected device an address space of 32&amp;amp;nbsp;MiB. As a result, the Replay block will be limited to this amount of memory. The &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; file must be modified if more than 32&amp;amp;nbsp;MiB needs to be buffered.&lt;br /&gt;
&lt;br /&gt;
To begin recording data to the Replay block, the record logic should be initialized:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and it resets the internal counters that track how much data has been recorded. If a previous recording has taken place then it is a good idea to ensure that stale data was not queued up in the RF network on the FPGA from a previous run. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling &amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up unexpectedly in the record buffer. If so, it restarts recording then waits again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected);&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base address and size of the playback buffer. To play back previously recorded data, set the start address to the same address that was used for the record buffer and set the size of the playback buffer to the match the amount of data that was recorded. Note that the record and playback buffers do not need to the same, allowing a single Replay block to both record and playback to different regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command. Playback automatically wraps around to the start of the buffer if more data is requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only the specified number of samples to be played once. The &amp;lt;code&amp;gt;num_samps&amp;lt;/code&amp;gt; parameter is a 28-bit value, limiting this mode of playback to 2&amp;lt;sup&amp;gt;28&amp;lt;/sup&amp;gt; words at a time. Playback can be stopped by issuing a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is received (DRAM reads are not aborted mid-transaction). As a result, some data will continue to stream from the Replay block after the stop command is issued while waiting for the DRAM read to complete and for all the internal buffers to empty. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example determines when playback streaming has stopped by reading the 64-bit &amp;lt;code&amp;gt;SR_READBACK_REG_GLOBAL_PARAMS&amp;lt;/code&amp;gt; register and waiting for the packet count to stop increasing.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_Development&amp;diff=5297</id>
		<title>Getting Started with RFNoC Development</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_Development&amp;diff=5297"/>
				<updated>2022-03-23T17:24:33Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added note that this AN is for UHD 3 and added link to UHD 4 version.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
&lt;br /&gt;
'''AN-823'''&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2016-07-12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Martin Braun&amp;lt;br&amp;gt; Nicolas Cuervo&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Initial creation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-01-10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Team&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added “Digital Gain” example&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-05-08&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Updated example code. Update to Testbench section.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-08-26&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Updated following sections: '''Abstract'''(This AN is specific to USRP X300/X310), '''Using a graphical interface'''(updated GUI image with newest version and the explanation section), '''Testing out the custom block'''(Updated GRC image that has correct Sampling Rate for RFNoC:Radio block).&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2017-09-07&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Jose Loera&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Added link to Video that follows this App Note in the Resources section. Also [https://youtube.com/watch?v=j-EfyPVpaJ8 here]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2019-10-24&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Fixed list of USRPs that this AN is applicable to: all current 3rd generation USRP hardware.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
'''Note:''' This application note applies to UHD 3.x and does not cover UHD 4.x. For UHD 4.x, see [[Getting Started with RFNoC in UHD 4.0]].&lt;br /&gt;
&lt;br /&gt;
This application note guides a user through basic information on the RFNoC architecture, installing necessary software to develop custom RFNoC blocks, also called Computation Engines (CE), and walks through the steps of creating a custom RFNoC block using an example. RFNoC is currently supported on any 3rd generation USRP hardware, currently: E310/E312, E320, N300/N310/N320/N321, and X300/X310.  '''However''', this document primarily covers using RFNoC for the USRP X300/X310 and E310/E312. Using RFNoC with the other USRPs is similar to that documented herein.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
First sections deal with installing tools and validating correct tool installation in order to do RFNoC development. Later sections deal with creating a custom RFNoC block, using the built-in testbench architecture, building an FPGA image with the custom block and finally testing out the new block within GNU Radio.&lt;br /&gt;
&lt;br /&gt;
==Licensing==&lt;br /&gt;
The RFNoC code base is open source, including code that executes on the host, as well as code targeted to the USRP hardware (FPGA and microcontroller firmware). RFNoC is available under the open-source GNU Lesser General Public License (LGPL). For more information on our licensing policy, please contact [mailto:info@ettus.com info@ettus.com].&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
RFNoC is only supported on 3rd generation USRP hardware as noted in the Abstract.&lt;br /&gt;
&lt;br /&gt;
In order to build custom USRP FPGA images and RFNoC blocks the following hardware and software are needed.&lt;br /&gt;
&lt;br /&gt;
* '''Ubuntu 14.04.5 or 16.04.1 (preferred):''' Currently PyBOMBS (which can be used to install the ''Software build tools''), works most reliably in Ubuntu, and thus, we recommend using this distribution. Also, a majority of the scripts used during the build process are Linux (Ubuntu) specific. A PC with multiple cores and 8GB+ of RAM is recommended.&lt;br /&gt;
&lt;br /&gt;
* '''Xilinx Vivado tools (version 2017.4):''' The specific version depends on the branch and state of the FPGA code. The default install location is &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;. Once all of the Software build tools are installed the specific version for the downloaded code can be found in the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{DEVICE}&amp;lt;/code&amp;gt; directory. Further information can be found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here].&lt;br /&gt;
&lt;br /&gt;
* '''Software build tools:''' If UHD can be or has been compiled from source on the development PC then all the necessary software build components are present (PyBOMBS can be used to set all this up and instructions on how to do so are given in a following step).&lt;br /&gt;
&lt;br /&gt;
* Any 3rd generation USRP hardware as noted in the Abstract.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:'''&lt;br /&gt;
* The edition of Xilinx Vivado that is required will depend on which USRP device is being used.&lt;br /&gt;
** X3xx series devices: Design Edition or System Edition.&lt;br /&gt;
** E3xx series devices: Design Edition, System Edition, or the free WebPack Edition.&lt;br /&gt;
* Other operating systems can be used, but the exact steps on how to proceed are not given in this Application Note.&lt;br /&gt;
* In some Linux distributions (e.g. Ubuntu) &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; is set as default shell, which may cause some issues. It is recommended to set the shell to &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt; by running the following commands in the terminal. Choose &amp;lt;code&amp;gt;&amp;lt;No&amp;gt;&amp;lt;/code&amp;gt; when prompted by the first command and the second command will validate the that bash will be used.&lt;br /&gt;
&lt;br /&gt;
    $ sudo dpkg-reconfigure dash&lt;br /&gt;
    $ ll /bin/sh&lt;br /&gt;
&lt;br /&gt;
==Creating a development environment==&lt;br /&gt;
While this Application Note goes through the process of integrating GNU Radio into the RFNoC development flow, it is by no means required to use or develop within the RFNoC framework, but it makes it a great deal easier to use a framework on top of RFNoC for aspects such as visualization and other features. GNU Radio is freely available and more information about it can be found [http://gnuradio.org/ here].&lt;br /&gt;
&lt;br /&gt;
The following software packages are required in order to setup a development environment/sandbox:&lt;br /&gt;
&lt;br /&gt;
* UHD&lt;br /&gt;
* GNU Radio &lt;br /&gt;
* gr-ettus&lt;br /&gt;
&lt;br /&gt;
===Create development environment using PyBOMBS===&lt;br /&gt;
The cleanest way to set this up is to install everything into a dedicated directory. [https://github.com/gnuradio/pybombs PyBOMBS] is the simplest way to do this. If not already installed, PyBOMBS can be setup with the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ sudo apt-get install git&lt;br /&gt;
    $ sudo apt-get install python-setuptools python-dev python-pip build-essential &lt;br /&gt;
    &lt;br /&gt;
    $ sudo pip install git+https://github.com/gnuradio/pybombs.git&lt;br /&gt;
    $ pybombs recipes add gr-recipes git+https://github.com/gnuradio/gr-recipes.git&lt;br /&gt;
    $ pybombs recipes add ettus git+https://github.com/EttusResearch/ettus-pybombs.git&lt;br /&gt;
&lt;br /&gt;
These commands will do the following:&lt;br /&gt;
* Install &amp;lt;code&amp;gt;Git&amp;lt;/code&amp;gt;&lt;br /&gt;
* Install &amp;lt;code&amp;gt;pip&amp;lt;/code&amp;gt; and other Python dependencies&lt;br /&gt;
* Install the latest &amp;lt;code&amp;gt;PyBOMBS&amp;lt;/code&amp;gt; from its Git repository&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;gr-recipes&amp;lt;/code&amp;gt; recipes which are used to install GNU Radio specific software&lt;br /&gt;
* Add the &amp;lt;code&amp;gt;ettus&amp;lt;/code&amp;gt; recipes which are used to install Ettus Research specific software&lt;br /&gt;
&lt;br /&gt;
From here, PyBOMBS can be used to setup and install the development environment/sandbox by running the following command:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs prefix init ~/rfnoc -R rfnoc -a rfnoc&lt;br /&gt;
&lt;br /&gt;
This will do the following:&lt;br /&gt;
&lt;br /&gt;
* Create a directory in the user’s home directory called &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; (any valid directory name will work)&lt;br /&gt;
&lt;br /&gt;
* Give the prefix an alias of &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; ( &amp;lt;code&amp;gt;[-a alias]&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;–a rfnoc&amp;lt;/code&amp;gt; ), which would be the name given to this path. This name will be used in further steps that use PyBOMBS. When creating the first prefix and omitting the alias, the prefix will be setup as the default.&lt;br /&gt;
&lt;br /&gt;
* Use the &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt; prefix recipe ( as opposed to a package recipe like &amp;lt;code&amp;gt;gqrx&amp;lt;/code&amp;gt; ) to clone UHD, FPGA, GNU Radio, and gr-ettus sources into the &amp;lt;code&amp;gt;~/rfnoc&amp;lt;/code&amp;gt; directory as well as compile and install all the software&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' A user can specify how many cores are used by builds when using PyBOMBS. The default is set to 4. For example, this will set the number of cores used to 3:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs config makewidth 3&lt;br /&gt;
&lt;br /&gt;
The value will be written into a configuration file and then applied to subsequent PyBOMBS commands. This value can temporarily be overridden for a specific build by specifying the &amp;lt;code&amp;gt;--config makewidth=X&amp;lt;/code&amp;gt; argument, where “&amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt;” is an integer number. If the user only has 4 cores it is recommend to use this argument in the pybombs command to limit the number of cores to &amp;lt;4 (e.g. 3) so that the computer stays responsive. Following are 2 examples, one using less cores and the other using more cores:&lt;br /&gt;
&lt;br /&gt;
    $ pybombs --config makewidth=3 prefix init ~/rfnoc -R rfnoc -a rfnoc &lt;br /&gt;
    $ pybombs --config makewidth=7 prefix init ~/rfnoc -R rfnoc -a rfnoc&lt;br /&gt;
&lt;br /&gt;
Then, it is necessary to setup the PyBOMBS environment, so that the system/terminal session will have the environmental variables pointing to this newly created prefix, which is done with the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ cd ~/rfnoc&lt;br /&gt;
    $ source ./setup_env.sh&lt;br /&gt;
&lt;br /&gt;
Once the previous command is run, this terminal session will have access to the environmental variables that allow the complete use of the set of software that was just installed with PyBOMBS. If access to the software is needed in other terminals the same command must be run within them.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Throughout the rest of this document the term &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; will used at the beginning of different directories. For example, &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&amp;lt;/code&amp;gt; is a directory that contains useful scripts for compiling. The term &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; is used to denote the folders that precede the &amp;lt;code&amp;gt;/src&amp;lt;/code&amp;gt; directory. Examples of what &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; could be: &amp;lt;code&amp;gt;/home/user/rfnoc&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;/home/user/myDevfolder/&amp;lt;/code&amp;gt;. On many Linux environments using &amp;lt;code&amp;gt;~/&amp;lt;/code&amp;gt; at the beginning of the target directory path is equivalent to the user’s home directory.( i.e &amp;lt;code&amp;gt;~/&amp;lt;/code&amp;gt; is equal to &amp;lt;code&amp;gt;/home/user/&amp;lt;/code&amp;gt;). So &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; could also look like &amp;lt;code&amp;gt;~/rfnoc&amp;lt;/code&amp;gt;  or &amp;lt;code&amp;gt;~/myDevfolder/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Create the development environment manually===&lt;br /&gt;
As an alternative to using PyBOMBS, manually installing and configuring the software is done by following the individual install notes for [http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGRFromSource GNU Radio], [https://files.ettus.com/manual/page_build_guide.html UHD] and [https://github.com/EttusResearch/gr-ettus gr-ettus] and by making sure they are reachable by linkers and compilers.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The Application Note found [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux here] goes through the process of manually installing UHD and GNU Radio on Linux platforms.&lt;br /&gt;
&lt;br /&gt;
To manually download the software, use these &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; commands, which will select the correct branches:&lt;br /&gt;
&lt;br /&gt;
    $ git clone --recursive -b rfnoc-devel https://github.com/EttusResearch/uhd.git &lt;br /&gt;
    $ git clone --recursive -b maint https://github.com/gnuradio/gnuradio.git # master branch is also fine instead of maint&lt;br /&gt;
    $ git clone -b master https://github.com/EttusResearch/gr-ettus.git &lt;br /&gt;
    $ git clone -b rfnoc-devel https://github.com/EttusResearch/fpga.git&lt;br /&gt;
&lt;br /&gt;
If UHD, GNU Radio and/or gr-ettus are already installed, it would be sufficient to checkout the branches mentioned and update them them (&amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt;). Thereafter, rebuild each of the repositories (rebuild order: UHD, GNU Radio, gr-ettus).&lt;br /&gt;
&lt;br /&gt;
===Verify Environment===&lt;br /&gt;
Running the command “&amp;lt;code&amp;gt;uhd_config_info&amp;lt;/code&amp;gt;” with the “&amp;lt;code&amp;gt;--version&amp;lt;/code&amp;gt;” flag will verify that the installation has been completed successfully.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The version string output from this command may differ, however it should be similar to the output below.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_config_info --version&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-161- g83150fdd&lt;br /&gt;
    &lt;br /&gt;
    4.0.0.rfnoc-devel-161-g83150fdd&lt;br /&gt;
&lt;br /&gt;
===Testing the default FPGA image and building from existing blocks===&lt;br /&gt;
&lt;br /&gt;
It is recommended to spend a moment looking at the Ettus Research default image, which is pre-built with a set of RFNoC blocks, as well as building a custom image with a unique set of pre-built RFNoC blocks. To get the default image(s), run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_images_downloader&lt;br /&gt;
&lt;br /&gt;
Ettus Research will be updating the default image(s) occasionally, and &amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt; can be run anytime after running &amp;lt;code&amp;gt;git pull&amp;lt;/code&amp;gt; and re-installing to pull the most current images. Images are stored in the &amp;lt;code&amp;gt;{USER_PREFIX}/share/uhd/images&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
The following images have the corresponding RFNoC blocks (Computation Engines):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Image Name&lt;br /&gt;
!Included Blocks&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x300_fpga_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x300_fpga_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;2x DDC, 2x DUC&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x300_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x300_fpga_RFNOC_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;DUC, DDC (one channel), fosphor, window, fft, 2x AXI FIFOs&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_XG.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;DUC, DDC (one channel), fosphor, window, fft, 2x AXI FIFOs, Keep One in N, FIR, Siggen&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_e310_fpga.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_e310_fpga_sg3.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;1x DDC, 1x DUC&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;code&amp;gt;usrp_e310_fpga_RFNOC.bit (sg1 version)&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;usrp_e310_fpga_RFNOC_sg3.bit&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;fosphor, window, fft, 2x AXI FIFOs, FIR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Instructions on flashing the image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
  &lt;br /&gt;
'''NOTE:''' FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device.&lt;br /&gt;
&lt;br /&gt;
By following the steps above the following should now be available:&lt;br /&gt;
* UHD/RFNoC code downloaded and installed&lt;br /&gt;
* FPGA code available&lt;br /&gt;
* A valid RFNoC image on your X3xx or E3xx series device&lt;br /&gt;
&lt;br /&gt;
====Inspect default images====&lt;br /&gt;
Run the following command, with a USRP connected to your PC, to verify current image on the USRP.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe&lt;br /&gt;
&lt;br /&gt;
If an RFNoC image was successfully loaded onto the USRP, there will be a lot of output text (RFNoC code is currently very verbose). The final lines of the output should be similar to the following for an USRP X310 ( e.g. &amp;lt;code&amp;gt;usrp_x310_fpga_HG&amp;lt;/code&amp;gt; ):&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * DDC_1&lt;br /&gt;
    |   |   |   * DUC_0&lt;br /&gt;
    |   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Final output for &amp;lt;code&amp;gt;usrp_x310_fpga_RFNOC_HG.bit&amp;lt;/code&amp;gt; image:&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * DUC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * Window_0&lt;br /&gt;
    |   |   |   * FIR_0&lt;br /&gt;
    |   |   |   * SigGen_0&lt;br /&gt;
    |   |   |   * KeepOneInN_0&lt;br /&gt;
    |   |   |   * fosphor_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The actual names and number of blocks can differ. The list of blocks should start with the &amp;lt;code&amp;gt;DmaFIFO_x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Radio_x&amp;lt;/code&amp;gt;, and then a couple more lines of block IDs should follow.&lt;br /&gt;
&lt;br /&gt;
====Build custom image with pre-built RFNoC blocks====&lt;br /&gt;
Because of the growing number of RFNoC blocks, the user has the option to build an FPGA image with a set of pre-built RFNoC blocks of their choosing. The following steps describe the process for doing this and by so doing will also validate proper tool installation. Because compilation can take a couple of hours, it is recommended the user begin this process while continuing the rest of this guide.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' FPGA compilations can run in the background, however they are very resource intensive. If the user intents to use the same computer that is compiling to walk through the rest of this Application Note, it is recommended that the computer has plenty of resources.&lt;br /&gt;
&lt;br /&gt;
The script to initiate a compile is called &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt;, and is located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&amp;lt;/code&amp;gt; directory. Run the help menu by typing:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts &lt;br /&gt;
    $ ./uhd_image_builder.py --help&lt;br /&gt;
&lt;br /&gt;
A more detailed discussion of this script is given in an upcoming section. For now, compiling an FPGA image that has 2 RFNoC blocks (&amp;lt;code&amp;gt;window&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fft&amp;lt;/code&amp;gt;) and some &amp;lt;code&amp;gt;FIFOs&amp;lt;/code&amp;gt;, is done by running the script with the following arguments.&lt;br /&gt;
&lt;br /&gt;
Example for an X310 USRP:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py window fft -d x310 -t X310_RFNOC_HG -m 5 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
Example for an E310 USRP with Speed Grade 3 (sg3) FPGA:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py window fft -d e310 -t E310_RFNOC_sg3 -m 5 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
At the end of a successful compilation process, write the new image to a USRP. If the image was compiled for a USRP X310, the following command will load the new image. Update the &amp;lt;code&amp;gt;{IP_Address}&amp;lt;/code&amp;gt; of the USRP and &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; to the appropriate values for your configuration before running the command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=x300,addr={IP_ADDRESS}&amp;quot; --fpga-path {USER_PREFIX}/src/uhd-fpga/usrp3/top/x300/build/usrp_x310_fpga_RFNOC_HG.bit&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. Additional instructions on flashing a custom image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
&lt;br /&gt;
After the image has been successfully written to the USRP, power-cycle it and run the “&amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;” utility to view the newly compiled blocks.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe&lt;br /&gt;
&lt;br /&gt;
The final lines of output for the image built for the X310 is as follows:&lt;br /&gt;
&lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * Window_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
===Getting started with UHD + RFNoC===&lt;br /&gt;
The following new examples included within the &amp;lt;code&amp;gt;rfnoc-devel&amp;lt;/code&amp;gt; branch of UHD, are a good reference on how to use RFNoC from UHD.&lt;br /&gt;
&lt;br /&gt;
The following example is based off of &amp;lt;code&amp;gt;rx_samples_to_file.cpp&amp;lt;/code&amp;gt;. The example can be configured to place an RFNoC block in between the radio and host.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_rx_to_file.cpp&lt;br /&gt;
&lt;br /&gt;
This next example chains a null source to another block and streams the data to the host.&lt;br /&gt;
&lt;br /&gt;
    rfnoc_nullsource_ce_rx.cpp&lt;br /&gt;
&lt;br /&gt;
These examples demonstrate the core features and flexibility of RFNoC.&lt;br /&gt;
&lt;br /&gt;
For more information on UHD and UHD development please refer to the [https://kb.ettus.com/UHD UHD Software Resource page], [https://kb.ettus.com/Getting_Started_with_UHD_and_C%2B%2B Getting Started with UHD and C++ Application Note] or directly to the [http://files.ettus.com/manual/ UHD user manual].&lt;br /&gt;
&lt;br /&gt;
===Getting started with GNU Radio + RFNoC===&lt;br /&gt;
A good way of getting started with RFNoC in a more visual way is to use GNU Radio. The &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; out-of-tree module (OOT) allows a user to use RFNoC blocks in their local GNU Radio / GNU Radio Companion (GRC) installation. This GNU Radio OOT contains blocks that allow you to configure your FPGA through GRC.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' As blocks in the &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; OOT mature, they will be upstreamed to &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt;. Also, &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; is a container used by Ettus Research to disseminate experimental or under-development features for &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt;. It is not a replacement for &amp;lt;code&amp;gt;gr-uhd&amp;lt;/code&amp;gt; (in fact, the latter is a requirement for &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;).&lt;br /&gt;
    &lt;br /&gt;
Examples can be run from &amp;lt;code&amp;gt;gr-ettus/examples/rfnoc&amp;lt;/code&amp;gt;, provided that the appropriate RFNoC blocks are compiled into the FPGA image currently running on the USRP.&lt;br /&gt;
&lt;br /&gt;
A couple of rules for building GNU Radio flowgraphs with RFNoC blocks:&lt;br /&gt;
&lt;br /&gt;
* You always need a &amp;lt;code&amp;gt;Device3&amp;lt;/code&amp;gt; object in your flow graph (it does not get connected, see screenshot below).&lt;br /&gt;
* You should have at least two RFNoC blocks connected together. Going &amp;lt;code&amp;gt;GNU Radio Block&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;RFNoC Block&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;GNU Radio Block&amp;lt;/code&amp;gt; is not recommended (it will work, but with suboptimal performance).&lt;br /&gt;
&lt;br /&gt;
The GNU Radio flowgraph &amp;lt;code&amp;gt;rfnoc_ddc.grc&amp;lt;/code&amp;gt; is an example that can be run using the default RFNoC image. Below are screenshots of the flowgraph and what it produces.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 1.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Copy Block: In the RFNoC domain, streams of data can not be split as easily as they are in the GNU Radio domain. The “copy” block depicted in the screenshot above serves the function as a stream splitter. Its main purpose, when “enabled”, is to copy the samples it is getting at its input and put them into the output, but here it is also serving as a boundary between a RFNoC-domain and a GNURadio-domain. In the flowgraph above, after this boundary is passed, the data stream can easily be split into the two sinks to have them run simultaneously (standard GNU Radio functionality). It is possible to connect the GNU Radio blocks directly to RFNoC blocks without a “copy” block, but only one would work at a time (the other ones would have to be disabled). Another way to split data streams from the RFNoC-domain is to use the ”RFNoC: split stream” block, which would split the streams in the RFNoC domain, but this is not very useful here as we are, in any case, moving into the GNURadio-domain.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 2.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
For more information on GNURadio development please refer to the [http://gnuradio.org/doc/doxygen/ GNURadio user's manual and API].&lt;br /&gt;
&lt;br /&gt;
==Starting a custom RFNoC block using RFNoC Modtool==&lt;br /&gt;
The figure below shows the basic structure of the RFNoC Stack. Corresponding code is needed in each of the three sections in order to build a custom RFNoC block with GNU Radio integration. A tool called RFNoC Modtool was created in order to minimize the effort needed to implement a new RFNoC block. RFNoC Modtool creates a custom GNU Radio OOT module with the basic structure and the necessary files for each of these sections. RFNoC Modtool is currently a part of the GNU Radio OOT module &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 3.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
===RFNoC Modtool Utilization===&lt;br /&gt;
'''NOTE:''' Console outputs may vary depending on the version of UHD the user is running. However, functionality should be the same or similar.&lt;br /&gt;
&lt;br /&gt;
Because the RFNoC Modtool has similar functionality to the &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt; [ [http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules gr_modtool] ] provided by GNU Radio, those that have worked with &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt; in the past will find the RFNoC Modtool familiar.&lt;br /&gt;
&lt;br /&gt;
To check the usage of the tool, run the following:&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool help&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    Usage:&lt;br /&gt;
    rfnocmodtool &amp;lt;command&amp;gt; [options] -- Run &amp;lt;command&amp;gt; with the given options.&lt;br /&gt;
    rfnocmodtool help -- Show a list of commands.&lt;br /&gt;
    rfnocmodtool help &amp;lt;command&amp;gt; -- Shows the help for a given command. &lt;br /&gt;
    &lt;br /&gt;
    List of possible commands:&lt;br /&gt;
    &lt;br /&gt;
    Name      Aliases          Description&lt;br /&gt;
    =====================================================================&lt;br /&gt;
    disable   dis              Disable block (comments out CMake entries for files) &lt;br /&gt;
    info      getinfo,inf      Return information about a given module &lt;br /&gt;
    remove    rm,del           Remove block (delete files and remove Makefile entries) &lt;br /&gt;
    makexml   mx               Make XML file for GRC block bindings &lt;br /&gt;
    add       insert           Add block to the out-of-tree module. &lt;br /&gt;
    newmod    nm,create        Create a new out-of-tree module &lt;br /&gt;
    rename    mv               Rename a block in the out-of-tree module.&lt;br /&gt;
&lt;br /&gt;
===Creating an RFNoC OOT Module===&lt;br /&gt;
&lt;br /&gt;
To start generating an RFNoC OOT module navigate to the source location ( i.e. &amp;lt;code&amp;gt;cd ~/{USER_PREFIX}/src&amp;lt;/code&amp;gt; ) and type:&lt;br /&gt;
    $ rfnocmodtool newmod [NAME OF THE MODULE]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;[NAME OF THE MODULE]&amp;lt;/code&amp;gt; is a name the user gives the new module. In the following, a module is created with the name “&amp;lt;code&amp;gt;tutorial&amp;lt;/code&amp;gt;”. If the user does not write the name of the module following the &amp;lt;code&amp;gt;newmod&amp;lt;/code&amp;gt; command the tool will ask for it interactively. Running this command will create a folder containing the basic folders that you may need for a functional module.&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool newmod tutorial&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    Creating out-of-tree module in ./rfnoc-tutorial... Done.&lt;br /&gt;
    Use 'rfnocmodtool add' to add a new block to this currently empty module.&lt;br /&gt;
&lt;br /&gt;
To see what files and directories were created run:&lt;br /&gt;
&lt;br /&gt;
    $ ls rfnoc-tutorial/&lt;br /&gt;
    apps  cmake  CMakeLists.txt  docs  examples  grc  include  lib  MANIFEST.md  python  README.md  rfnoc  swig&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In contrast with &amp;lt;code&amp;gt;gr_modtool&amp;lt;/code&amp;gt;, this includes a folder called &amp;lt;code&amp;gt;rfnoc&amp;lt;/code&amp;gt;, which is where the UHD/FPGA files are located.&lt;br /&gt;
&lt;br /&gt;
===Adding custom blocks to OOT Module===&lt;br /&gt;
In order to add blocks to a module, navigate to the folder just created and use the &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt; command of &amp;lt;code&amp;gt;rfnocmodtool&amp;lt;/code&amp;gt;. Continuing with the example above, run the following:&lt;br /&gt;
&lt;br /&gt;
    $ cd rfnoc-tutorial&lt;br /&gt;
    $ rfnocmodtool add [NAME OF THE BLOCK]&lt;br /&gt;
&lt;br /&gt;
For demonstrative purposes, a block named &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; will be created. The &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block will multiply samples that pass through it by a constant. As before, if the name is not given, the tool will ask the user for the name. There are several arguments that can be passed to the tool, but running the tool without any of these arguments will give the following interactive parsing output:&lt;br /&gt;
&lt;br /&gt;
    $ rfnocmodtool add gain&lt;br /&gt;
    linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_4.0.0.rfnoc-devel-162-g335a1317&lt;br /&gt;
    &lt;br /&gt;
    RFNoC module name identified: tutorial&lt;br /&gt;
    Block/code identifier: gain&lt;br /&gt;
    Enter valid argument list, including default arguments: &lt;br /&gt;
    Block NoC ID (Hexadecimal): 1111222233334444&lt;br /&gt;
    Skip Block Controllers Generation? [UHD block ctrl files] [y/N] N&lt;br /&gt;
    Skip Block interface files Generation? [GRC block ctrl files] [y/N] N&lt;br /&gt;
&lt;br /&gt;
Hitting &amp;lt;code&amp;gt;enter&amp;lt;/code&amp;gt; on each one of the options will take the default values.&lt;br /&gt;
&lt;br /&gt;
The following is a description of the valid argument list items:&lt;br /&gt;
&lt;br /&gt;
* '''NoC ID:''' This ID is a Hexadecimal number which serves as identification between the hardware part and the software part of the design. It can be as long as 16 0-9 A-F digits. If a NoC ID is not provided, it will be set to a random number.&lt;br /&gt;
&lt;br /&gt;
* '''Block Controllers Generation:''' The block controllers are the C++ control that the user can apply to the UHD-part of the design. In these files, the user can add more control over this layer of the design. Depending on the complexity of the block it may be possible to add all necessary control using NoCScript (more details on NoCScript can be found in the section labeled UHD Integration). In this case the cpp/hpp block control files generation are not needed. Default is to generate as their existence will be ignored if not edited.&lt;br /&gt;
&lt;br /&gt;
* '''Block Interface:''' Add more design specific functionality to the design at the GNU Radio interface by generating these block-interface files and adding necessary logic.  Depending on the complexity of the block it may be possible to add all necessary control using NoC-Script. In this case the block-interface files are not needed. Default is to generate as their existence will be ignored if not edited.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' If the user does not intend to use the block controllers or is not sure if they are needed, the presence of them in the design will do no harm. It is recommended to add them. This leaves the possibility to add more functions inside them in a future stage of development. &lt;br /&gt;
&lt;br /&gt;
After finishing the parsing, the following files will be generated/edited:&lt;br /&gt;
&lt;br /&gt;
    Adding file 'lib/gain_impl.h'...&lt;br /&gt;
    Adding file 'lib/gain_impl.cc'...&lt;br /&gt;
    Adding file 'include/tutorial/gain.h'...&lt;br /&gt;
    Adding file 'include/tutorial/gain_block_ctrl.hpp'...&lt;br /&gt;
    Adding file 'lib/gain_block_ctrl_impl.cpp'...&lt;br /&gt;
    Editing swig/tutorial_swig.i...&lt;br /&gt;
    Adding file 'python/qa_gain.py'...&lt;br /&gt;
    Editing python/CMakeLists.txt...&lt;br /&gt;
    Adding file 'grc/tutorial_gain.xml'...&lt;br /&gt;
    Adding file 'rfnoc/blocks/gain.xml'...&lt;br /&gt;
    Adding file 'rfnoc/fpga-src/noc_block_gain.v'...&lt;br /&gt;
    rfnoc/testbenches/noc_block_gain_tb folder created&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/Makefile'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/CMakeLists.txt'...&lt;br /&gt;
&lt;br /&gt;
==Creating FPGA portion of custom RFNoC Block==&lt;br /&gt;
===RFNoC FPGA User Interface (API)===&lt;br /&gt;
RFNoC blocks or Computation Engines (CEs) in the FPGA use a NoC Shell instance to interface with the rest of RFNoC. NoC Shell implements RFNoC's core functionality: packet muxing and demuxing, flow control, and the settings register bus (i.e. write/read control/status registers). The NoC Shell has an interface to the RFNoC AXI stream crossbar and a user interface. NoC Shell AXI stream interfaces expect CHDR packets with a proper header. See the manual for information on [https://files.ettus.com/manual/page_rtp.html CHDR and SID].&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' AXI Stream is an ARM AMBA standard interface. Xilinx has an [http://www.xilinx.com/support/documentation/ip_documentation/ug761_axi_reference_guide.pdf AXI Reference Guide] with more details on this standard.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 4.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Many designs will want to use an AXI Stream interface with only sample data. However, as stated earlier, the NoC Shell block expects CHDR packets. To ease interfacing user code, the AXI Wrapper block provides the necessary logic to strip and insert the CHDR header, effectively converting packetized sample data into streaming sample data and vice versa. The example RFNoC blocks &amp;lt;code&amp;gt;noc_block_fft.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;noc_block_fir.v&amp;lt;/code&amp;gt; show how AXI Wrapper is used to implement existing Xilinx AXI Stream based IP within a computation engine.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' AXI Wrapper also supports AXI Stream buses for configuration. These buses are driven via the setting register bus and do not have back pressure. They also consume two user register addresses per bus.&lt;br /&gt;
&lt;br /&gt;
The primary user interface consists of four AXI stream interfaces ( &amp;lt;code&amp;gt;tready, tvalid, tlast, tdata&amp;lt;/code&amp;gt; ) and a settings register bus ( 8-bit, valid user register addresses: &amp;lt;code&amp;gt;128-255&amp;lt;/code&amp;gt; ).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
AXI Stream signals:&lt;br /&gt;
* '''m_axis_data_tdata:''' Input sample data packets &lt;br /&gt;
** Data coming from host or another CE&lt;br /&gt;
* '''s_axis_data_tdata:''' Output sample data packets &lt;br /&gt;
** Data going to another CE or host&lt;br /&gt;
* '''m_axis_data_tready:''' Input signal to CE&lt;br /&gt;
** Used to notify CE that downstream CE is ready for data &lt;br /&gt;
* '''s_axis_data_tready:''' Output signal to CE&lt;br /&gt;
** Used to notify upstream CE that CE is ready for data &lt;br /&gt;
* '''m_axis_data_tvalid:''' Input signal to CE&lt;br /&gt;
** Used to indicate upstream CE has valid data &lt;br /&gt;
* '''s_axis_data_tvalid:''' Output signal to CE&lt;br /&gt;
** Used to indicate to downstream CE that CE has valid data &lt;br /&gt;
* '''m_axis_data_tlast:''' Input signal to CE&lt;br /&gt;
** Used to delimit packets from upstream CE &lt;br /&gt;
* '''s_axis_data_tlast:''' Output signal to CE&lt;br /&gt;
** Used to delimit packets to downstream CE&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |[[File:rfnoc gsg an 5.png|right|500px|]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 6.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|&lt;br /&gt;
Settings Bus signals:&lt;br /&gt;
* '''set_stb:''' Assert to write '''set_data''' to register at '''set_addr'''ess&lt;br /&gt;
* '''set_addr:''' Register address to set&lt;br /&gt;
* '''set_data:''' Data to set&lt;br /&gt;
* '''rb_data:''' Data to read back&lt;br /&gt;
* '''rb_strobe:''' Assert to read '''rb_data''' from register at '''set_addr'''ess&lt;br /&gt;
&lt;br /&gt;
| style=&amp;quot;vertical-align:top&amp;quot; |[[File:rfnoc gsg an 7.png|right|500px|]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
For the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; example block the following architecture is desired:&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 8.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Open the file &amp;lt;code&amp;gt;rfnoc-tutorial/rfnoc/fpga-src/noc_block_gain.v&amp;lt;/code&amp;gt; that contains the RFNoC block skeleton code that was created when the &amp;lt;code&amp;gt;$ rfnocmodtool add gain&amp;lt;/code&amp;gt; command was run and modify the following ('''BOLD''' indicates changes to the skeleton code).&lt;br /&gt;
&lt;br /&gt;
    '''localparam [7:0] SR_GAIN = SR_USER_REG_BASE;'''&lt;br /&gt;
    localparam [7:0] SR_TEST_REG_1 = SR_USER_REG_BASE + 8'd1;&lt;br /&gt;
    &lt;br /&gt;
    '''wire [15:0] gain;'''&lt;br /&gt;
    '''setting_reg #('''&lt;br /&gt;
      '''.my_addr(SR_GAIN), .awidth(8), .width(16))'''&lt;br /&gt;
    '''sr_gain ('''&lt;br /&gt;
      '''.clk(ce_clk), .rst(ce_rst),'''&lt;br /&gt;
      '''.strobe(set_stb), .addr(set_addr), .in(set_data), .out(gain), .changed());'''&lt;br /&gt;
    &lt;br /&gt;
     always @(posedge ce_clk) begin&lt;br /&gt;
        case(rb_addr)&lt;br /&gt;
          '''8'd0 : rb_data &amp;lt;= {48'd0, gain};'''&lt;br /&gt;
          8'd1 : rb_data &amp;lt;= {32'd0, test_reg_1};&lt;br /&gt;
          default : rb_data &amp;lt;= 64'h0BADC0DE0BADC0DE;&lt;br /&gt;
        endcase&lt;br /&gt;
     end&lt;br /&gt;
     &lt;br /&gt;
     '''wire [31:0] pipe_in_tdata;'''&lt;br /&gt;
     '''wire pipe_in_tvalid, pipe_in_tlast;'''&lt;br /&gt;
     '''wire pipe_in_tready;'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] pipe_out_tdata;'''&lt;br /&gt;
     '''wire pipe_out_tvalid, pipe_out_tlast;'''&lt;br /&gt;
     '''wire pipe_out_tready;'''&lt;br /&gt;
 &lt;br /&gt;
     '''// Adding FIFO to ensure Pipeline'''&lt;br /&gt;
     '''axi_fifo_flop #(.WIDTH(32+1))'''&lt;br /&gt;
     '''pipeline0_axi_fifo_flop ('''&lt;br /&gt;
       '''.clk(ce_clk),'''&lt;br /&gt;
       '''.reset(ce_rst),'''&lt;br /&gt;
       '''.clear(clear_tx_seqnum),'''&lt;br /&gt;
       '''.i_tdata({m_axis_data_tlast,m_axis_data_tdata}),'''&lt;br /&gt;
       '''.i_tvalid(m_axis_data_tvalid),'''&lt;br /&gt;
       '''.i_tready(m_axis_data_tready),'''&lt;br /&gt;
       '''.o_tdata({pipe_in_tlast,pipe_in_tdata}),'''&lt;br /&gt;
       '''.o_tvalid(pipe_in_tvalid),'''&lt;br /&gt;
       '''.o_tready(pipe_in_tready));'''  &lt;br /&gt;
 &lt;br /&gt;
     '''wire [15:0] i = pipe_in_tdata[31:16];'''&lt;br /&gt;
     '''wire [15:0] q = pipe_in_tdata[15:0];'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] i_mult_gain = i*gain;'''&lt;br /&gt;
     '''wire [31:0] q_mult_gain = q*gain;'''&lt;br /&gt;
 &lt;br /&gt;
     '''wire [31:0] mult_gain = {i_mult_gain[15:0], q_mult_gain[15:0]};'''&lt;br /&gt;
     '''axi_fifo_flop #(.WIDTH(32+1))'''&lt;br /&gt;
     '''pipeline1_axi_fifo_flop ('''&lt;br /&gt;
       '''.clk(ce_clk),'''&lt;br /&gt;
       '''.reset(ce_rst),'''&lt;br /&gt;
       '''.clear(clear_tx_seqnum),'''&lt;br /&gt;
       '''.i_tdata({pipe_in_tlast,mult_gain}),'''&lt;br /&gt;
       '''.i_tvalid(pipe_in_tvalid),'''&lt;br /&gt;
       '''.i_tready(pipe_in_tready),'''&lt;br /&gt;
       '''.o_tdata({pipe_out_tlast,pipe_out_tdata}),'''&lt;br /&gt;
       '''.o_tvalid(pipe_out_tvalid),'''&lt;br /&gt;
       '''.o_tready(pipe_out_tready));'''&lt;br /&gt;
 &lt;br /&gt;
     '''/* Output Signals */'''&lt;br /&gt;
     '''assign pipe_out_tready = s_axis_data_tready;'''&lt;br /&gt;
     '''assign s_axis_data_tvalid = pipe_out_tvalid;'''&lt;br /&gt;
     '''assign s_axis_data_tlast  = pipe_out_tlast;'''&lt;br /&gt;
     '''assign s_axis_data_tdata  = pipe_out_tdata;'''&lt;br /&gt;
&lt;br /&gt;
The following is a block diagram of the code created by the above Verilog:&lt;br /&gt;
&lt;br /&gt;
[[File:gain_block_diagram_v01.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:'''  In order to meet timing, FIFO blocks were added to either side of the Multiplication process.&lt;br /&gt;
&lt;br /&gt;
===Creating and running HDL testbenches===&lt;br /&gt;
In order to make the coding iteration process more efficient, it is recommended to create testbenches for all RFNoC blocks before compiling them into the FPGA image. This allows for flaw and/or bug detection early in the design. RFNoC Modtool provides the structure and files ( e.g. noc_block_{USER_BLOCK_NAME}_tb ) for the testbenches of each of the OOT blocks that are added with the &amp;lt;code&amp;gt;$ rfnocmodtool add&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
Below is a figure that shows the general testbench architecture  that is created by the RFNoC Modtool. This architecture allows a user to test their custom block in the exact same environment it will be placed in when it is built into the RFNoC architecture. Other benefits of the testbench architecture include:&lt;br /&gt;
* Testing through multiple blocks (e.g. FILTER -&amp;gt; FFT -&amp;gt; AVE) &lt;br /&gt;
* Testing with multiple streams (e.g. RFNoC block ADD/SUB takes 2 streams, one that will have a constant added to it and one that will have a constant subtracted from it)&lt;br /&gt;
* Data transfer abstraction (e.g. RFNoC Sim Lib API calls to &amp;lt;code&amp;gt;tb_streamer.send&amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;tb_streamer.recv&amp;lt;/code&amp;gt; which take care of all the AXI stream signaling)&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 9.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The &amp;lt;code&amp;gt;noc_block_tb&amp;lt;/code&amp;gt; block is an instantiation of the &amp;lt;code&amp;gt;noc_block_export_io&amp;lt;/code&amp;gt; that is used in testbenches to communicate to the RFNoC architecture. This makes it possible to talk “RFNoC” to the user’s custom block and as such the custom block has a complete RFNoC experience (signaling, flowcontrol, addressing, etc)&lt;br /&gt;
&lt;br /&gt;
From the [[Getting Started with RFNoC Development#Adding_custom_blocks_to_OOT_Module|Adding custom blocks to OOT Module section]] where the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block was initially created, the last files generated were:&lt;br /&gt;
&lt;br /&gt;
    rfnoc/testbenches/noc_block_gain_tb folder created&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/Makefile'...&lt;br /&gt;
    Adding file 'rfnoc/testbenches/noc_block_gain_tb/CMakeLists.txt'...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;noc_block_gain_tb&amp;lt;/code&amp;gt; is a folder generated to contain all the files related to the test bench of the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block. Each time a new OOT block is created, a new folder will be generated as well. &lt;br /&gt;
&lt;br /&gt;
Inside of this folder are the following three files:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;CMakeLists.txt:&amp;lt;/code&amp;gt; this is an empty file used, so far, only to increase the scope of the compilers.&lt;br /&gt;
* &amp;lt;code&amp;gt;noc_block_gain_tb.sv:&amp;lt;/code&amp;gt; this is a ''System Verilog'' file, in which user custom tests are to be located.  This is the '''only''' file that needs to be modified.&lt;br /&gt;
* &amp;lt;code&amp;gt;Makefile:&amp;lt;/code&amp;gt; This file determines the directives that run the simulation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;noc_block_gain_tb.sv&amp;lt;/code&amp;gt; testbench skeleton code creates the following architecture:&lt;br /&gt;
&lt;br /&gt;
[[File:testbench_arch_gain_v01.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
Open the file &amp;lt;code&amp;gt;rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv&amp;lt;/code&amp;gt; and modify the following lines:&lt;br /&gt;
&lt;br /&gt;
Right under the “Verification” section:&lt;br /&gt;
&lt;br /&gt;
    initial begin : tb_main&lt;br /&gt;
      string s;&lt;br /&gt;
      logic [31:0] random_word;&lt;br /&gt;
      logic [63:0] readback;&lt;br /&gt;
      '''logic [15:0] gain;'''&lt;br /&gt;
&lt;br /&gt;
In the “Test 4 -- Write / readback user registers” section:&lt;br /&gt;
    &lt;br /&gt;
    `TEST_CASE_START(&amp;quot;Write / readback user registers&amp;quot;);&lt;br /&gt;
    random_word = $random();&lt;br /&gt;
    '''tb_streamer.write_user_reg(sid_noc_block_gain, noc_block_gain.SR_GAIN, random_word[15:0]);'''&lt;br /&gt;
    '''tb_streamer.read_user_reg(sid_noc_block_gain, 0, readback);'''&lt;br /&gt;
    '''$sformat(s, &amp;quot;User register 0 incorrect readback! Expected: %0d, Actual %0d&amp;quot;, readback[15:0], random_word[15:0]);'''&lt;br /&gt;
    '''`ASSERT_ERROR(readback[15:0] == random_word[15:0], s);'''&lt;br /&gt;
    &lt;br /&gt;
In the “Test 5 -- Test sequence” section:&lt;br /&gt;
&lt;br /&gt;
    `TEST_CASE_START(&amp;quot;Test sequence&amp;quot;);&lt;br /&gt;
    '''gain = 100;'''&lt;br /&gt;
    '''tb_streamer.write_user_reg(sid_noc_block_gain, noc_block_gain.SR_GAIN, gain);'''&lt;br /&gt;
    fork&lt;br /&gt;
      begin&lt;br /&gt;
        cvita_payload_t send_payload;&lt;br /&gt;
        for (int i = 0; i &amp;lt; SPP/2; i++) begin&lt;br /&gt;
          send_payload.push_back(64'(i));&lt;br /&gt;
        end&lt;br /&gt;
        tb_streamer.send(send_payload);&lt;br /&gt;
      end&lt;br /&gt;
      begin&lt;br /&gt;
        cvita_payload_t recv_payload;&lt;br /&gt;
        cvita_metadata_t md;&lt;br /&gt;
        logic [63:0] expected_value;&lt;br /&gt;
        tb_streamer.recv(recv_payload,md);&lt;br /&gt;
        for (int i = 0; i &amp;lt; SPP/2; i++) begin&lt;br /&gt;
          '''expected_value = i*gain;'''&lt;br /&gt;
&lt;br /&gt;
Test #4 verifies that we can write and readback the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; value. Test #5 writes to the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; register, sends a sample set in the form of a ramp (1, 2, 3, 4, etc) to the RFNoC gain block and finally reads the values from the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block and compares them to expected values. The followings steps will allow the user to run this testbench.&lt;br /&gt;
&lt;br /&gt;
From within the &amp;lt;code&amp;gt;rfnoc-tutorial&amp;lt;/code&amp;gt; directory, create a &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; directory and enter it by running:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build &amp;amp;&amp;amp; cd build/&lt;br /&gt;
&lt;br /&gt;
The next step is to run &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt;. If PyBOMBS was used to create the development sandbox, &amp;lt;code&amp;gt;cmake&amp;lt;/code&amp;gt; will automatically detect the location of the &amp;lt;code&amp;gt;fpga&amp;lt;/code&amp;gt; repository. If PyBOMBS was not used, the user must provide the location of where the &amp;lt;code&amp;gt;fpga&amp;lt;/code&amp;gt; repository is installed.&lt;br /&gt;
&lt;br /&gt;
If PyBOMBS used, run:&lt;br /&gt;
&lt;br /&gt;
    $ cmake ../&lt;br /&gt;
&lt;br /&gt;
If PyBOMBS not used, run:&lt;br /&gt;
&lt;br /&gt;
    $ cmake [-DUHD_FPGA_DIR=/PATH/TO/FPGA/REPOSITORY] ../&lt;br /&gt;
&lt;br /&gt;
Final output from the &amp;lt;code&amp;gt;$ cmake ../&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
    -- Configuring done&lt;br /&gt;
    -- Generating done&lt;br /&gt;
    -- Build files have been written to: /home/widow/rfnoc/src/rfnoc-tutorial/build&lt;br /&gt;
&lt;br /&gt;
The following command will modify the necessary files and set the correct path to the simulation tools. From now on, every time a new block is added, this command will be run automatically. Remember, only run the following command once for each OOT module (not RFNoC block, but OOT module) created:&lt;br /&gt;
&lt;br /&gt;
    $ make test_tb&lt;br /&gt;
    Scanning dependencies of target test_tb&lt;br /&gt;
    Built target test_tb&lt;br /&gt;
&lt;br /&gt;
Testbenches can be executed by running the command:&lt;br /&gt;
&lt;br /&gt;
    $ make noc_block_[name_of_your_block]_tb &lt;br /&gt;
&lt;br /&gt;
The gain block testbench can be run by running the following command:&lt;br /&gt;
&lt;br /&gt;
    $ make noc_block_gain_tb&lt;br /&gt;
&lt;br /&gt;
The simulation will start.  Final output should look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ========================================================&lt;br /&gt;
    TESTBENCH STARTED: noc_block_gain&lt;br /&gt;
    ========================================================&lt;br /&gt;
    [TEST CASE   1] (t=000000000) BEGIN: Wait for Reset...&lt;br /&gt;
    [TEST CASE   1] (t=000001002) DONE... Passed&lt;br /&gt;
    [TEST CASE   2] (t=000001002) BEGIN: Check NoC ID...&lt;br /&gt;
    Read GAIN NOC ID: 1111222233334444&lt;br /&gt;
    [TEST CASE   2] (t=000001238) DONE... Passed&lt;br /&gt;
    [TEST CASE   3] (t=000001238) BEGIN: Connect RFNoC blocks...&lt;br /&gt;
    Connecting noc_block_tb (SID: 1:0) to noc_block_gain (SID: 0:0)&lt;br /&gt;
    Connecting noc_block_gain (SID: 0:0) to noc_block_tb (SID: 1:0)&lt;br /&gt;
    [TEST CASE   3] (t=000005457) DONE... Passed&lt;br /&gt;
    [TEST CASE   4] (t=000005457) BEGIN: Write / readback user registers...&lt;br /&gt;
    [TEST CASE   4] (t=000006888) DONE... Passed&lt;br /&gt;
    [TEST CASE   5] (t=000006888) BEGIN: Test sequence...&lt;br /&gt;
    [TEST CASE   5] (t=000007633) DONE... Passed&lt;br /&gt;
    ========================================================&lt;br /&gt;
    '''TESTBENCH FINISHED: noc_block_gain'''&lt;br /&gt;
    ''' - Time elapsed:   7700 ns'''             &lt;br /&gt;
    ''' - Tests Expected: 5'''&lt;br /&gt;
    ''' - Tests Run:      5'''&lt;br /&gt;
    ''' - Tests Passed:   5'''&lt;br /&gt;
    '''Result: PASSED'''   &lt;br /&gt;
    ========================================================&lt;br /&gt;
    $finish called at time : 7700 ns : File &amp;quot;/home/widow/rfnoc/src/rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/noc_block_gain_tb.sv&amp;quot; Line 10&lt;br /&gt;
    INFO: [USF-XSim-96] XSim completed. Design snapshot 'noc_block_gain_tb_behav' loaded.&lt;br /&gt;
    INFO: [USF-XSim-97] XSim simulation ran for 1000000000us&lt;br /&gt;
    launch_simulation: Time (s): cpu = 00:00:10 ; elapsed = 00:00:12 . Memory (MB): peak = 966.387 ; gain = 54.848 ; free physical = 3080 ; free virtual = 29888&lt;br /&gt;
    # if [string equal $vivado_mode &amp;quot;batch&amp;quot;] {&lt;br /&gt;
    #     puts &amp;quot;BUILDER: Closing project&amp;quot;&lt;br /&gt;
    #     close_project&lt;br /&gt;
    # } else {&lt;br /&gt;
    #     puts &amp;quot;BUILDER: In GUI mode. Leaving project open.&amp;quot;&lt;br /&gt;
    # }&lt;br /&gt;
    BUILDER: Closing project&lt;br /&gt;
    ****** Webtalk v2015.4 (64-bit)&lt;br /&gt;
      **** SW Build 1412921 on Wed Nov 18 09:44:32 MST 2015&lt;br /&gt;
      **** IP Build 1412160 on Tue Nov 17 13:47:24 MST 2015&lt;br /&gt;
        ** Copyright 1986-2015 Xilinx, Inc. All Rights Reserved.&lt;br /&gt;
    &lt;br /&gt;
    source /home/widow/rfnoc/src/rfnoc-tutorial/rfnoc/testbenches/noc_block_gain_tb/xsim_proj/xsim_proj.hw/webtalk/labtool_webtalk.tcl -notrace&lt;br /&gt;
    INFO: [Common 17-206] Exiting Webtalk at Tue Jan 10 23:26:20 2017...&lt;br /&gt;
    INFO: [Common 17-206] Exiting Vivado at Tue Jan 10 23:26:22 2017...&lt;br /&gt;
    Built target noc_block_gain_tb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With every custom block created, a &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; directive will be available to run the simulation from the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
===Building the FPGA image with a custom user block===&lt;br /&gt;
In this section steps are given on how to initiate an FPGA build while incorporating the user’s custom RFNoC block. The first sections give general information on building RFNoC images. The remaining two sections show how to initiate FPGA builds using a command line interface and using a graphical interface (coming out soon), respectively.&lt;br /&gt;
&lt;br /&gt;
====Discussion on number of blocks in an FPGA image====&lt;br /&gt;
There is a maximum number of blocks that can be added for each device. The maximum amount of computation engines (CEs/RFNoC blocks) that each device can use is 16, but the amount of custom blocks that can be added depends on the device. &lt;br /&gt;
&lt;br /&gt;
If using a device from the X3xx series, from the 16 CEs, there are 6 that will be always added and are not subject to direct customization: 1 CE for the AXI bus, 1 CE for the Ethernet Interface, 2 Radios and 2 Dma FIFOS. Because of this, the application will only allow a number of 10 custom blocks on the X3xx series. &lt;br /&gt;
&lt;br /&gt;
If using a device from the E3xx series, 2 CE engines are always added and are not subject to direct customization: 1 CE for the AXI bus and 1 Radio. This would virtually allow 14 slots for custom blocks. However, given the size of the FPGA on the E3xx series of devices, the application only allows a number of 6 custom blocks. &lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Blocks with higher resource utilization may fill up the FPGA and force the user to include less blocks.&lt;br /&gt;
&lt;br /&gt;
Verify the current maximum values by running the &amp;lt;code&amp;gt;uhd_images_builder.py&amp;lt;/code&amp;gt; utility from the scripts directory.&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&lt;br /&gt;
    $ uhd_image_builder.py --help&lt;br /&gt;
&lt;br /&gt;
====Discussion on FPGA image targets====&lt;br /&gt;
RFNoC target names follow the pattern &amp;lt;code&amp;gt;{DEVICE}_RFNOC_{BUILD_TYPE}&amp;lt;/code&amp;gt; with the following build types: &lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;HG:&amp;lt;/code&amp;gt; 1GigE on SFP+ Port0, 10Gig on SFP+ Port&lt;br /&gt;
* &amp;lt;code&amp;gt;XG:&amp;lt;/code&amp;gt; 10GigE on both SFP+ ports&lt;br /&gt;
* &amp;lt;code&amp;gt;HLS:&amp;lt;/code&amp;gt; Vivado High Level Synthesis enabled&lt;br /&gt;
* &amp;lt;code&amp;gt;sgX:&amp;lt;/code&amp;gt; Speed grade for E300 devices (1 or 3)&lt;br /&gt;
&lt;br /&gt;
Some examples are:&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_XG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_XG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X310_RFNOC_HLS_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;X300_RFNOC_HLS_HG&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;E310_RFNOC&amp;lt;/code&amp;gt; (this is for the speed grade 1 FPGA version of E310, append &amp;lt;code&amp;gt;_sg3&amp;lt;/code&amp;gt; for speed grade 3)&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' E310, E312 and E313 all have the same FPGA hardware and therefore will use the &amp;lt;code&amp;gt;E310_RFNOC_{BUILD_TYPE}&amp;lt;/code&amp;gt; target. USRP E3xx devices have either &amp;lt;code&amp;gt;sg1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sg3&amp;lt;/code&amp;gt; hardware, please visit [http://files.ettus.com/e3xx_images/README here] to find out how to differentiate.&lt;br /&gt;
&lt;br /&gt;
Additional information about the build targets can be found at the build instructions for USRP3, found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here].&lt;br /&gt;
&lt;br /&gt;
====Image building using the command line====&lt;br /&gt;
The script &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; is used to generate the NoC block instantiation file and build the FPGA image. Run the help menu by typing:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts&lt;br /&gt;
    $ ./uhd_image_builder.py --help&lt;br /&gt;
         &lt;br /&gt;
    usage: uhd_image_builder.py [-h] [-I INCLUDE_DIR [INCLUDE_DIR ...]]&lt;br /&gt;
                                [-m MAX_NUM_BLOCKS] [--fill-with-fifos]&lt;br /&gt;
                                [-o OUTFILE] [-d DEVICE] [-t TARGET] [-g] [-c]&lt;br /&gt;
                                [blocks [blocks ...]]&lt;br /&gt;
    &lt;br /&gt;
    Generate the NoC block instantiation file&lt;br /&gt;
    &lt;br /&gt;
    positional arguments:&lt;br /&gt;
      blocks                List block names to instantiate.&lt;br /&gt;
    &lt;br /&gt;
    optional arguments:&lt;br /&gt;
      -h, --help            show this help message and exit&lt;br /&gt;
      -I INCLUDE_DIR [INCLUDE_DIR ...], --include-dir INCLUDE_DIR [INCLUDE_DIR ...]&lt;br /&gt;
                            Path directory of the RFNoC Out-of-Tree module&lt;br /&gt;
      -m MAX_NUM_BLOCKS, --max-num-blocks MAX_NUM_BLOCKS&lt;br /&gt;
                            Maximum number of blocks (Max. Allowed for x310|x300:&lt;br /&gt;
                            10, for e300: 6)&lt;br /&gt;
      --fill-with-fifos     If the number of blocks provided was smaller than the&lt;br /&gt;
                            max number, fill the rest with FIFOs&lt;br /&gt;
      -o OUTFILE, --outfile OUTFILE&lt;br /&gt;
                            Output /path/filename - By running this directive, you&lt;br /&gt;
                            won't build your IP&lt;br /&gt;
      -d DEVICE, --device DEVICE&lt;br /&gt;
                            Device to be programmed [x300, x310, e310]&lt;br /&gt;
      -t TARGET, --target TARGET&lt;br /&gt;
                            Build target - image type [X3X0_RFNOC_HG,&lt;br /&gt;
                            X3X0_RFNOC_XG, E310_RFNOC_sg3...]&lt;br /&gt;
      -g, --GUI             Open Vivado GUI during the FPGA building process&lt;br /&gt;
      -c, --clean-all       Cleans the IP before a new build&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are details on the usage of the script which is followed by an example:&lt;br /&gt;
&lt;br /&gt;
'''Blocks:''' The first arguments are the names of RFNoC blocks that the user wants to have compiled into the new image which are separated by a space. They can be custom blocks from the user’s OOT module or from the ones that are provided from Ettus, or a combination. Blocks provided by Ettus Research are listed (among other sources necessary for the FPGA build) in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/lib/rfnoc/Makefile.srcs&amp;lt;/code&amp;gt; file. &lt;br /&gt;
&lt;br /&gt;
These blocks can be identified by the following pattern: &lt;br /&gt;
&lt;br /&gt;
    noc_block_{NAME}.v&lt;br /&gt;
&lt;br /&gt;
However, as all the RFNoC blocks have the same &amp;lt;code&amp;gt;noc_block_&amp;lt;/code&amp;gt; prefix, for simplicity this prefix is omitted when listing the blocks in the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; utility. As an example of the incorrect and correct way of adding blocks, consider the following examples when adding the &amp;lt;code&amp;gt;noc_block_null_source_sink&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;noc_block_siggen&amp;lt;/code&amp;gt; blocks:&lt;br /&gt;
&lt;br /&gt;
Incorrect method:  &lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py noc_block_null_source_sink noc_block_siggen ...&lt;br /&gt;
&lt;br /&gt;
Correct method:&lt;br /&gt;
&lt;br /&gt;
    $ ./uhd_image_builder.py null_source_sink siggen ...&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Blocks generated by the RFNoC Modtool follow the same naming convention.&lt;br /&gt;
&lt;br /&gt;
There is an increasing list of pre-built blocks. Here is a sample:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;axi_fifo_loopback&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;axi_dma_fifo&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fir_filter&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fft&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;null_source_sink&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;schmidl_cox&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;packet_resizer&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;split_stream&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;vector_iir&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;addsub&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;window&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;keep_one_in_n&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;pfb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;export_io&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;conv_encoder_qpsk&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;siggen&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;logpwr&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;fosphor&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;moving_avg&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ddc&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;duc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
RFNoC related blocks generally reside in &amp;lt;code&amp;gt;fpga/usrp3/lib/rfnoc/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
!Block&lt;br /&gt;
!Filename&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FIFO&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_axi_fifo_loopback.v noc_block_axi_fifo_loopback.v]&lt;br /&gt;
|Simple FIFO loopback / passthrough block.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FFT&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_fft.v noc_block_fft.v]&lt;br /&gt;
|Xilinx coregen based Fast Fourier Transform up to length 4096.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|FIR&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_fir_filter.v noc_block_fir_filter.v]&lt;br /&gt;
|Xilinx coregen based Finite Impulse Response Filter, 41 taps, reconfigurable tap coefficients.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|Window&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_window.v noc_block_window.v]&lt;br /&gt;
|Windowing block for use with FFT block.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Vector IIR&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_vector_iir.v noc_block_vector_iir.v]&lt;br /&gt;
|Single pole IIR with configurable coefficients that filters data along vectors (i.e. parallel streams of samples). Useful with FFT output.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Keep One in N&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_keep_one_in_n.v noc_block_keep_one_in_n.v]&lt;br /&gt;
|Keeps one packet every N packets.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|AddSub&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_addsub.v noc_block_addsub.v]&lt;br /&gt;
|Example of using multiple block ports in a single RFNoC block to add and subtract streams.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Null Source Sink&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_null_source_sink.v noc_block_null_source_sink.v]&lt;br /&gt;
|Generates dummy packets and can consume packets at a configurable rate. Useful for testing.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Packet Resizer&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_packet_resizer.v noc_block_packet_resizer.v]&lt;br /&gt;
|Resizes input packets to a configurable size (larger or smaller than source packets).&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Split Stream&lt;br /&gt;
|[https://github.com/EttusResearch/fpga/blob/maint/usrp3/lib/rfnoc/noc_block_split_stream.v noc_block_split_stream.v]&lt;br /&gt;
|Replicates an input stream to a configurable number of output streams.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' There is a restriction on the amount of blocks that can added into the FPGA image, see the section in this Application Note labeled [[Getting_Started_with_RFNoC_Development#Discussion_on_number_of_blocks_in_an_FPGA_image|Discussion on number of blocks in an FPGA image]] for more information. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-I INCLUDE_DIR:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt; directive provides the path to top OOT directory, which contains the users &amp;lt;code&amp;gt;rfnoc/fpga-src&amp;lt;/code&amp;gt; directory which contains the custom blocks. This path is needed by the Xilinx Vivado tool. Inside the &amp;lt;code&amp;gt;fpga-src&amp;lt;/code&amp;gt; directory there is a file called &amp;lt;code&amp;gt;Makefile.srcs&amp;lt;/code&amp;gt; that contains the path of the OOT module and a list of all the custom OOT blocks. This is an auto generated file, which is amended every time a new block is added to the OOT module. Manually modifying this file is not recommended. If there are multiple OOT modules with various custom blocks that reside in different directories the way to include them all is by separating the different paths by a space (e.g. &amp;lt;code&amp;gt;-I /first/OOT/path/ /second/OOT/path/&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''IMPORTANT:''' Please be sure to terminate the path of your OOT with the &amp;quot;/&amp;quot; character. Otherwise the path might not be recognized.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-d DEVICE:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;-d&amp;lt;/code&amp;gt; directive directs the script on which USRP device the build is for. If no &amp;lt;code&amp;gt;–d&amp;lt;/code&amp;gt; is included the default is &amp;lt;code&amp;gt;–d x310&amp;lt;/code&amp;gt;. Generation-3 USRPs and above all support RFNoC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-t TARGET:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;–t&amp;lt;/code&amp;gt; directive directs the script on which type of image to build for the chosen device. With each USRP device there are several build options to choose from. Detailed information about the build targets can be found at the build instructions for USRP3, found [http://files.ettus.com/manual/md_usrp3_build_instructions.html here]. If &amp;lt;code&amp;gt;-t&amp;lt;/code&amp;gt; is not included, a default target will be chosen for the given device. For example, the default &amp;lt;code&amp;gt;X310_RFNOC_HG&amp;lt;/code&amp;gt; target builds for the &amp;lt;code&amp;gt;–d x310&amp;lt;/code&amp;gt; device. More details on targets can be found in the section of this Application Note labeled [[Getting Started with RFNoC Development#Discussion_on_FPGA_image_targets|Discussion on FPGA image targets]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-m MAX_NUM_BLOCKS:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;–m&amp;lt;/code&amp;gt; directive specifies the max number of RFNoC blocks to build on the FPGA image. An RFNoC image does not need to fill all available slots with RFNoC blocks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--fill-with-fifos:&amp;lt;/code&amp;gt; The &amp;lt;code&amp;gt;--fill-with-fifos&amp;lt;/code&amp;gt; directive will fill the empty RFNoC block slots with FIFOS. As an example, if a user indicates three RFNoC blocks by name and also specifies &amp;lt;code&amp;gt;–m 5&amp;lt;/code&amp;gt; then the other two slots will be filed with FIFOs. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-o OUTFILE:&amp;lt;/code&amp;gt; With the &amp;lt;code&amp;gt;-o&amp;lt;/code&amp;gt; directive, the RFNoC blocks instantiation file is generated and saved at the desired path with the given name for the user to inspect. The FPGA image will NOT build if this directive is provided. The purpose of the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script is to auto generate an instantiation file and populate the source files needed for the Xilinx Vivado tool to build the FPGA image, however, it may be desirable to only see the effect of adding a custom OOT module in the &amp;lt;code&amp;gt;fpga/&amp;lt;/code&amp;gt; directory, or for inspecting the instantiation file. When the directive is not provided the &amp;lt;code&amp;gt;rfnoc_ce_auto_inst_x3x0.v&amp;lt;/code&amp;gt; file is overwritten and the FPGA image build process will start automatically (standard use).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-g, --GUI:&amp;lt;/code&amp;gt; Open Vivado GUI during the FPGA building process&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-c, --clean-all:&amp;lt;/code&amp;gt; Cleans the IP before a new build&lt;br /&gt;
&lt;br /&gt;
Here is how to create an X310 FPGA image incorporating the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block that was created earlier in this Application Note:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts     &lt;br /&gt;
    $ ./uhd_image_builder.py gain ddc fft -I {USER_PREFIX}/src/rfnoc-tutorial/ -d x310 -t X310_RFNOC_HG -m 6 --fill-with-fifos&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At the end of a successful compilation process, write the new image to a USRP. The following command will load the new image. Update the &amp;lt;code&amp;gt;{IP_Address}&amp;lt;/code&amp;gt; of the USRP and &amp;lt;code&amp;gt;{USER_PREFIX}&amp;lt;/code&amp;gt; to the appropriate values for your configuration before running the command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=x300,addr={IP_ADDRESS}&amp;quot; --fpga-path {USER_PREFIX}/src/uhd-fpga/usrp3/top/x300/build/usrp_x310_fpga_RFNOC_HG.bit&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' &lt;br /&gt;
* The FPGA image building process may take over an hour.&lt;br /&gt;
&lt;br /&gt;
* FPGA images are specific to the USRP device NOT the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. Additional instructions on flashing a custom image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series.&lt;br /&gt;
&lt;br /&gt;
* [Environment setup] - The &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script will also set up the Xilinx Vivado environment by automatically running the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{device}&amp;lt;/code&amp;gt; directory. The &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script assumes that Xilinx Vivado is installed in the default location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;.  If the installation is in a different directory the &amp;lt;code&amp;gt;setupenv_base.sh&amp;lt;/code&amp;gt; script will need to be modified. The script is located at: &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts/setupenv_base.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besides the custom &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block, a &amp;lt;code&amp;gt;DDC&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FFT&amp;lt;/code&amp;gt; block are also being added along with three &amp;lt;code&amp;gt;FIFOs&amp;lt;/code&amp;gt;.  The &amp;lt;code&amp;gt;DDC&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FFT&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FIFO&amp;lt;/code&amp;gt; blocks are already in the script's path and therefore do not need their path specified (they ship with the Ettus Research FPGA code). The reason three FIFOs are added is because the max number of blocks was specified to be 6 ( &amp;lt;code&amp;gt;-m 6&amp;lt;/code&amp;gt; ) and since only 3 blocks were specifically named the other three slots are filled with FIFOs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 10.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Instructions on flashing the image to a device can be found [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs here] for X3xx series and [http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_load_fpga_imgs here] for E3xx series. FPGA images are specific to the USRP device '''NOT''' the USRP series. For example, a USRP X300 FPGA image will '''NOT''' work on a USRP X310 and vice versa. Loading an image that does not correspond to a USRP device will likely brick the device. &lt;br /&gt;
&lt;br /&gt;
Once the newly compiled image is loaded onto a USRP X3xx running the following command will show what RFNoC blocks are available on the FPGA:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * '''Block_0'''&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' The reason the custom block is called &amp;lt;code&amp;gt;Block_0&amp;lt;/code&amp;gt; and not &amp;lt;code&amp;gt;gain_0&amp;lt;/code&amp;gt; is because there is still host side software/files that need updated in order for this block to populate it’s proper name. A following section (UHD Integration) will step through the process of updating those host side files.&lt;br /&gt;
&lt;br /&gt;
====Using a graphical interface====&lt;br /&gt;
A graphical user interface for FPGA generation and building is shipped along with the &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script. This intuitive application aids in setting up a custom FPGA build. &lt;br /&gt;
&lt;br /&gt;
This utility is located in the same &amp;lt;code&amp;gt;scripts&amp;lt;/code&amp;gt; directory as &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
To run it, enter the following commands:&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/uhd-fpga/usrp3/tools/scripts/&lt;br /&gt;
    $ ./uhd_image_builder_gui&lt;br /&gt;
&lt;br /&gt;
The application will then be launched:&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 11.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''1. Select build target:''' In this panel the available build targets are listed. This list may vary depending on which branch of the FPGA repository this user is using. Only RFNoC targets are listed. The build type descriptions are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;HG:&amp;lt;/code&amp;gt; 1GigE on SFP+ Port0, 10Gig on SFP+ Port1&lt;br /&gt;
* &amp;lt;code&amp;gt;XG:&amp;lt;/code&amp;gt; 10GigE on both SFP+ ports&lt;br /&gt;
* &amp;lt;code&amp;gt;HLS:&amp;lt;/code&amp;gt; Vivado High Level Synthesis enabled&lt;br /&gt;
* &amp;lt;code&amp;gt;sgX:&amp;lt;/code&amp;gt; Speed grade for E300 devices (1 or 3)&lt;br /&gt;
&lt;br /&gt;
'''2. List of blocks available:''' In this panel the available blocks are listed that can be included into a custom design. This list separates the RFNoC blocks provided by Ettus Research and the OOT modules and corresponding blocks that the user adds. Given the hardware differences between the X3xx and E3xx devices, this list will dynamically change when a different device is selected from the panel on the left. This implies that it is necessary to add the OOT modules for each device independently. This is accomplished by using the &amp;lt;code&amp;gt;Add OOT Blocks&amp;lt;/code&amp;gt; feature of the application, details of which are explained at #7 (&amp;lt;code&amp;gt;Add OOT Blocks&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''3. Blocks in current design:''' This section gives information on the MAX number of blocks for a given USRP (based on the target selection). There is a maximum number of blocks that can be added for each device. See the section in this App Note labeled &amp;quot;Discussion on number of blocks in an FPGA image&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
'''4. Blocks in current design:''' This panel will be populated by adding elements from the available blocks. All the blocks listed in here will be compiled into the FPGA custom image. There is a maximum number of blocks that can be added for each device. See the section in this App Note labeled &amp;quot;Discussion on number of blocks in an FPGA image&amp;quot; for more information. &lt;br /&gt;
&lt;br /&gt;
'''5. Add button (&amp;gt;&amp;gt;):''' Manually add the blocks from the central panel into your design.&lt;br /&gt;
&lt;br /&gt;
'''6. Remove button (&amp;lt;&amp;lt;):''' Remove blocks from the current design (far-left panel)&lt;br /&gt;
&lt;br /&gt;
'''7. Fill with FIFOs:''' By checking this box, the design will fill any available/unspecified block slots with FIFOs. The number of FIFO blocks that will be instantiated is based on the rules of amount of blocks explained at #3. When less than the max amount of blocks are needed for certain implementation, many users choose to fill their design with FIFO blocks. &lt;br /&gt;
&lt;br /&gt;
'''8. Open Vivado GUI:''' Open Vivado GUI during the FPGA building process. This allows the user to save a Vivado project with all IP and work within the Vivado GUI for development.&lt;br /&gt;
&lt;br /&gt;
'''9. Clean IP:''' Cleans the IP before a new build (recompiles all IP).&lt;br /&gt;
&lt;br /&gt;
'''10. Add OOT blocks:''' Manually add RFNoC Modtool-generated OOT modules by pointing the application to the &amp;lt;code&amp;gt;Makefile.srcs&amp;lt;/code&amp;gt; file, which is located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/{USER-OOT-moddir}/rfnoc/fpga-srcs/&amp;lt;/code&amp;gt; directory. After adding this file, blocks will appear under “&amp;lt;code&amp;gt;OOT blocks for XXXX devices&amp;lt;/code&amp;gt;”&lt;br /&gt;
&lt;br /&gt;
'''11. Show Instantiation File:''' The application auto-generates the instantiation file that is going to be used by Vivado to build the FPGA image. This instantiation file can be viewed and edited before starting the build by clicking this button. &lt;br /&gt;
&lt;br /&gt;
'''12. Import from GRC:''' If the user has a GNU Radio flowgraph with RFNoC blocks already in it, this application can read what RFNoC blocks are in the flowgraph and populate the &amp;lt;code&amp;gt;Blocks in current design&amp;lt;/code&amp;gt; section of the application with the necessary RFNoC blocks. '''NOTE:''' All RFNoC blocks pulled from a &amp;lt;code&amp;gt;.grc&amp;lt;/code&amp;gt; file must be in the of &amp;lt;code&amp;gt;List of blocks available&amp;lt;/code&amp;gt; before beginning the build.&lt;br /&gt;
&lt;br /&gt;
'''13. Generate .bit file:''' Start the build by clicking this button. &lt;br /&gt;
&lt;br /&gt;
'''14. uhd_image_builder command:''' The command line command with arguments is dynamically build here as the user selects different options. The user could save this command to use next time they build/compile an FPGA image to avoid having to select all options again. &lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' See the latter end of the previous section for additional information on what to expect once the compile has started as well as final output.&lt;br /&gt;
&lt;br /&gt;
==Creating Software/Host portion of custom RFNoC Block==&lt;br /&gt;
Now that the FPGA portion is complete the next step is to add software integration to UHD and GNU Radio as depicted in the RFNoC Stack below.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 12.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
===UHD integration===&lt;br /&gt;
Despite the data processing happening on the FPGA, the host software still has a lot of responsibilities in order for an RFNoC application to function. For example, it needs to know which settings registers are available within an RFNoC block, or what kind of input and output a block has. All of this information goes into the &amp;lt;code&amp;gt;Block Declaration&amp;lt;/code&amp;gt;, which is an XML file that is readable by UHD. Often, some simple logic needs to be embedded in the XML file, which we can do by using a simple scripting language called Noc-Script. Changes to the block declaration file are immediately imported into UHD every time an application is executed, and therefore, no software development toolchain needs to be set up.&lt;br /&gt;
&lt;br /&gt;
The list of things declared by the block declaration file includes:&lt;br /&gt;
&lt;br /&gt;
* Block name and Noc-ID&lt;br /&gt;
* Registers&lt;br /&gt;
* Inputs and outputs (including types)&lt;br /&gt;
&lt;br /&gt;
In some cases, additional C++ code is required to properly control a block from software. In this case, a &amp;lt;code&amp;gt;Block Controller&amp;lt;/code&amp;gt; file is required as well as the declaration file. In most cases, the default block controller provided by UHD is sufficient, so no C++ code needs to be written. Writing custom block controllers requires more effort, and means having to set up a programming toolchain. A common reason to write custom C++ block controllers is if setting a register requires a lot of computation, which is not feasible to do within a block declaration file (e.g., using Noc-Script).&lt;br /&gt;
&lt;br /&gt;
Skeleton code for both the block declaration and the block controller (if required) can be generated through RFNoC Modtool.&lt;br /&gt;
&lt;br /&gt;
Because the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block does not require anything other than simply reading and writing to a single register the default block controller will suffice for this example. However, we will need to add information about the register.&lt;br /&gt;
&lt;br /&gt;
Open the &amp;lt;code&amp;gt;gain.xml&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;/rfnoc-tutorial/rfnoc/blocks&amp;lt;/code&amp;gt; directory and add the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;&amp;lt;!--Default XML file--&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;nocblock&amp;gt;&lt;br /&gt;
      &amp;lt;name&amp;gt;gain&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;blockname&amp;gt;gain&amp;lt;/blockname&amp;gt;&lt;br /&gt;
      &amp;lt;ids&amp;gt;&lt;br /&gt;
        &amp;lt;id revision=&amp;quot;0&amp;quot;&amp;gt;1111222233334444&amp;lt;/id&amp;gt;&lt;br /&gt;
      &amp;lt;/ids&amp;gt;&lt;br /&gt;
      '''&amp;lt;nowiki&amp;gt;&amp;lt;!-- Registers --&amp;gt;&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;registers&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;setreg&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;name&amp;gt;GAIN&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;address&amp;gt;128&amp;lt;/address&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;/setreg&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;/registers&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;nowiki&amp;gt;&amp;lt;!-- Args --&amp;gt;&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;args&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;arg&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;name&amp;gt;gain&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;double&amp;lt;/type&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;value&amp;gt;1.0&amp;lt;/value&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;check&amp;gt;GE($gain, 0.0) AND LE($gain, 32767.0)&amp;lt;/check&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;check_message&amp;gt;Invalid gain.&amp;lt;/check_message&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;action&amp;gt;'''&lt;br /&gt;
            '''SR_WRITE(&amp;quot;GAIN&amp;quot;, IROUND($gain))'''&lt;br /&gt;
          '''&amp;lt;/action&amp;gt;'''&lt;br /&gt;
        '''&amp;lt;/arg&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;/args&amp;gt;'''&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!--One input, one output. If this is used, better have all the info the C++ file.--&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;ports&amp;gt;&lt;br /&gt;
        &amp;lt;sink&amp;gt;&lt;br /&gt;
          '''&amp;lt;name&amp;gt;in0&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;sc16&amp;lt;/type&amp;gt;'''&lt;br /&gt;
        &amp;lt;/sink&amp;gt;&lt;br /&gt;
        &amp;lt;nowiki&amp;gt;&amp;lt;source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
          '''&amp;lt;name&amp;gt;out0&amp;lt;/name&amp;gt;'''&lt;br /&gt;
          '''&amp;lt;type&amp;gt;sc16&amp;lt;/type&amp;gt;'''&lt;br /&gt;
        &amp;lt;nowiki&amp;gt;&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;/ports&amp;gt;&lt;br /&gt;
    &amp;lt;/nocblock&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GNU Radio Integration===&lt;br /&gt;
GNU Radio is built around the concept of blocks, similarly to RFNoC. When mapping RFNoC into an application, the simple constraint is made that every RFNoC block maps to a single GNU Radio block. Thus, when creating mixed GNU Radio/RFNoC applications, there is a very clear 1:1 mapping between what’s happening in RFNoC and GNU Radio.&lt;br /&gt;
&lt;br /&gt;
Since most RFNoC blocks behave very similar to one another from GNU Radio’s perspective, it is generally not required to write C++ code for another block. Rather, a default block provided by RFNoC can be used with appropriate configuration. However, in some cases it may be desirable or even necessary to write a custom GNU Radio block for more specific controlling of the underlying RFNoC block. GNU Radio allows writing blocks in either C++ or Python, but since UHD and RFNoC do not have a Python API, a custom wrapper for an RFNoC block needs to be written in C++. RFNoC Modtool will create skeleton files for this purpose.&lt;br /&gt;
&lt;br /&gt;
The most popular and effective way to use GNU Radio is through the graphical interface, the GNU Radio Companion (GRC). GRC requires a separate description of every GNU Radio block in order to become available in the graphical UI, and the same is true for an RFNoC block that is wrapped in a GNU Radio block (even if the generic RFNoC block wrapper is used). For GNU Radio 3.7 and earlier, GRC bindings for blocks are written as XML files with interspersed Cheetah or Python statements. For a more detailed tutorial on how to write these files, refer to the [http://gnuradio.org/redmine/projects/gnuradio/wiki GNU Radio Documentation] and associated [http://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorials tutorials].&lt;br /&gt;
&lt;br /&gt;
====GNU Radio Block Code====&lt;br /&gt;
&lt;br /&gt;
* C++ or Python, although RFNoC blocks need to be written in C++ (if at all)&lt;br /&gt;
* How does GNU Radio interface to RFNoC?&lt;br /&gt;
** via C++ infrastructure code in &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gr-ettus&amp;lt;/code&amp;gt; provides a base RFNoC block class&lt;br /&gt;
** Users extend base class for their RFNoC blocks&lt;br /&gt;
** Many blocks can use base class “as is”&lt;br /&gt;
** No C++ or Python code!&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-tutorial/lib/gain_impl.cc&amp;lt;/code&amp;gt;&lt;br /&gt;
** The gain block does not need anything additional&lt;br /&gt;
&lt;br /&gt;
====GNU Radio Companion Bindings====&lt;br /&gt;
* XML&lt;br /&gt;
* Describes GNU Radio blocks to GRC&lt;br /&gt;
* No recompilation&lt;br /&gt;
* Requirement of GNU Radio Companion&lt;br /&gt;
* Not strictly necessary for GNU Radio&lt;br /&gt;
* Tutorial on how to write them:&lt;br /&gt;
** [http://gnuradio.org/redmine/projects/gnuradio/wiki/GNURadioCompanion http://gnuradio.org/redmine/projects/gnuradio/wiki/GNURadioCompanion ]&lt;br /&gt;
* Skeleton file generated by RFNoC Modtool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Open the &amp;lt;code&amp;gt;tutorial-gain.xml&amp;lt;/code&amp;gt; file located in the &amp;lt;code&amp;gt;rfnoc-tutorial/grc&amp;lt;/code&amp;gt; directory and edit as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;nowiki&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;block&amp;gt;&lt;br /&gt;
      &amp;lt;name&amp;gt;RFNoC: gain&amp;lt;/name&amp;gt;&lt;br /&gt;
      &amp;lt;key&amp;gt;tutorial_gain&amp;lt;/key&amp;gt;&lt;br /&gt;
      &amp;lt;category&amp;gt;tutorial&amp;lt;/category&amp;gt;&lt;br /&gt;
      &amp;lt;import&amp;gt;import tutorial&amp;lt;/import&amp;gt;&lt;br /&gt;
      &amp;lt;make&amp;gt;tutorial.gain(&lt;br /&gt;
        self.device3,&lt;br /&gt;
        uhd.stream_args( \# TX Stream Args&lt;br /&gt;
            cpu_format=&amp;quot;'''fc32'''&amp;quot;,&lt;br /&gt;
            otw_format=&amp;quot;'''sc16'''&amp;quot;,&lt;br /&gt;
            args=&amp;quot;gr_vlen={0},{1}&amp;quot;.format(${grvlen}, &amp;quot;&amp;quot; if $grvlen == 1 else &amp;quot;spp={0}&amp;quot;.format($grvlen)),&lt;br /&gt;
        ),&lt;br /&gt;
        uhd.stream_args( \# RX Stream Args&lt;br /&gt;
            cpu_format=&amp;quot;'''fc32'''&amp;quot;,&lt;br /&gt;
            otw_format=&amp;quot;'''sc16'''&amp;quot;,&lt;br /&gt;
            args=&amp;quot;gr_vlen={0},{1}&amp;quot;.format(${grvlen}, &amp;quot;&amp;quot; if $grvlen == 1 else &amp;quot;spp={0}&amp;quot;.format($grvlen)),&lt;br /&gt;
        ),&lt;br /&gt;
        $block_index, $device_index,&lt;br /&gt;
      )&lt;br /&gt;
    '''self.$(id).set_arg(&amp;quot;gain&amp;quot;, $gain)'''&lt;br /&gt;
      '''&amp;lt;/make&amp;gt;'''&lt;br /&gt;
      '''&amp;lt;callback&amp;gt;set_arg(&amp;quot;gain&amp;quot;, $gain)&amp;lt;/callback&amp;gt;'''&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'param' node for every Parameter you want settable from the GUI.&lt;br /&gt;
           Sub-nodes:&lt;br /&gt;
           * name&lt;br /&gt;
           * key (makes the value accessible as $keyname, e.g. in the make node)&lt;br /&gt;
           * type --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
         .  &lt;br /&gt;
         .&lt;br /&gt;
         .&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;option&amp;gt;&lt;br /&gt;
          &amp;lt;name&amp;gt;Byte&amp;lt;/name&amp;gt;&lt;br /&gt;
          &amp;lt;key&amp;gt;u8&amp;lt;/key&amp;gt;&lt;br /&gt;
        &amp;lt;/option&amp;gt;&lt;br /&gt;
      &amp;lt;/param&amp;gt;&lt;br /&gt;
      &amp;lt;param&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;'''Gain'''&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;key&amp;gt;'''gain'''&amp;lt;/key&amp;gt;&lt;br /&gt;
        '''&amp;lt;value&amp;gt;1.0&amp;lt;/value&amp;gt;'''&lt;br /&gt;
        &amp;lt;type&amp;gt;'''real'''&amp;lt;/type&amp;gt;&lt;br /&gt;
      &amp;lt;/param&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'sink' node per input. Sub-nodes:&lt;br /&gt;
           * name (an identifier for the GUI)&lt;br /&gt;
           * type&lt;br /&gt;
           * vlen&lt;br /&gt;
           * optional (set to 1 for optional inputs) --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;sink&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;in&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;'''complex'''&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;vlen&amp;gt;$grvlen&amp;lt;/vlen&amp;gt;&lt;br /&gt;
        &amp;lt;domain&amp;gt;rfnoc&amp;lt;/domain&amp;gt;&lt;br /&gt;
      &amp;lt;/sink&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;!-- Make one 'source' node per output. Sub-nodes:&lt;br /&gt;
           * name (an identifier for the GUI)&lt;br /&gt;
           * type&lt;br /&gt;
           * vlen&lt;br /&gt;
           * optional (set to 1 for optional inputs) --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;out&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;'''complex'''&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;vlen&amp;gt;$grvlen&amp;lt;/vlen&amp;gt;&lt;br /&gt;
        &amp;lt;domain&amp;gt;rfnoc&amp;lt;/domain&amp;gt;&lt;br /&gt;
      &amp;lt;nowiki&amp;gt;&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    &amp;lt;/block&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Indentation spacing is important in the &amp;lt;code&amp;gt;&amp;lt;make&amp;gt;&amp;lt;/code&amp;gt; section.&lt;br /&gt;
&lt;br /&gt;
===Compile, Install and Verify===&lt;br /&gt;
&lt;br /&gt;
    $ cd {USER_PREFIX}/src/rfnoc-tutorial/build&lt;br /&gt;
    $ make install&lt;br /&gt;
    &lt;br /&gt;
    $ uhd_usrp_probe &lt;br /&gt;
    &lt;br /&gt;
    |   |     _____________________________________________________&lt;br /&gt;
    |   |    /&lt;br /&gt;
    |   |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |   |   &lt;br /&gt;
    |   |   |   * DmaFIFO_0&lt;br /&gt;
    |   |   |   * Radio_0&lt;br /&gt;
    |   |   |   * Radio_1&lt;br /&gt;
    |   |   |   * '''gain_0'''&lt;br /&gt;
    |   |   |   * DDC_0&lt;br /&gt;
    |   |   |   * FFT_0&lt;br /&gt;
    |   |   |   * FIFO_0&lt;br /&gt;
    |   |   |   * FIFO_1&lt;br /&gt;
    |   |   |   * FIFO_2&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' In the case where the &amp;lt;code&amp;gt;gain_0&amp;lt;/code&amp;gt; does not appear but &amp;lt;code&amp;gt;Block_0&amp;lt;/code&amp;gt; does: Most likely, the XML block declaration file (see [[Getting_Started_with_RFNoC_Development#UHD_integration|UHD Integration]] section) for the block contains a NoC-ID that does not match with any NoC-ID defined in the hardware part of the design. The user has to be certain that the description files are up-to-date and that the NoC-ID matches in the SW and HW side. See the [[Getting_Started_with_RFNoC_Development#UHD_integration|UHD Integration]] section to update those host side files.&lt;br /&gt;
&lt;br /&gt;
==Testing out the custom block==&lt;br /&gt;
At this point the custom &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; RFNoc Block (Computation Engine) can be used within a GNU Radio flowgraph. Below is an example GRC flowgraph using our new block as well as the output application it produces. &lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 13.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' Copy Block: In the RFNoC domain, streams of data can not be split as easily as they are in the GNU Radio domain. The “copy” block depicted in the screenshot above serves the function as a stream splitter . It’s main purpose, when “enabled”, is to copy the samples it is getting at its input and putting then into the output, but here it is also serving as a boundary between a RFNoC-domain and a GNURadio-domain. In the flowgraph above. after this boundary is passed, the data stream can easily be split into the two sinks to have them run simultaneously (standard GNU Radio functionality). It is possible to connect the GNU Radio blocks directly to RFNoC blocks without a “copy” block, but only one would work at a time (the other ones would have to be disabled). Another way to split data streams from the RFNoC-domain is to use the ”RFNoC: split stream” block, which would split the streams in the RFNoC domain, but this is not very useful here as we are, in any case, moving into the GNURadio-domain.&lt;br /&gt;
&lt;br /&gt;
[[File:rfnoc gsg an 14.png|center|800px|]]&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===Xilinx Vivado===&lt;br /&gt;
====Compile issues====&lt;br /&gt;
=====Synthesis is failing=====&lt;br /&gt;
Verify all the correct Xilinx [[Getting Started with RFNoC Development#Prerequisites|prerequisite software]] is installed.&lt;br /&gt;
&lt;br /&gt;
Additional helpful information can be found in the following Xilinx forum posts:&lt;br /&gt;
* https://forums.xilinx.com/t5/Synthesis/Synthesis-failed-without-reporting-any-error/td-p/686000&lt;br /&gt;
* https://forums.xilinx.com/t5/Installation-and-Licensing/Vivado-on-Linux-synthesis-fails-with-no-error-message/td-p/732143&lt;br /&gt;
&lt;br /&gt;
====Environment Setup====&lt;br /&gt;
The &amp;lt;code&amp;gt;uhd_image_builder.py&amp;lt;/code&amp;gt; script will also set up the Xilinx Vivado environment by automatically running the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; located in the &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3/top/{device}&amp;lt;/code&amp;gt; directory. The &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script assumes that Xilinx Vivado is installed in the default location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;. If the installation is in a different directory, then the &amp;lt;code&amp;gt;setupenv_base.sh&amp;lt;/code&amp;gt; script will need to be modified. The script is located at: &amp;lt;code&amp;gt;{USER_PREFIX}/src/uhd-fpga/usrp3_rfnoc/tools/scripts/setupenv_base.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Reference Files==&lt;br /&gt;
The following reference files are included within the gain_src.tar.gz archive linked below:&lt;br /&gt;
&lt;br /&gt;
* gain.xml		&lt;br /&gt;
* noc_block_gain.v	&lt;br /&gt;
* noc_block_gain_tb.sv	&lt;br /&gt;
* tutorial_gain.xml&lt;br /&gt;
* rfnoc_gain.grc&lt;br /&gt;
&lt;br /&gt;
[[Media:gain src.tar.gz]]&lt;br /&gt;
&lt;br /&gt;
==Links and Additional Resources==&lt;br /&gt;
===RFNoC additional resources===&lt;br /&gt;
* [https://youtube.com/watch?v=j-EfyPVpaJ8 Video: RFNoC Getting Started Video Tutorial]&lt;br /&gt;
* [http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com USRP Mailing List]&lt;br /&gt;
* [https://kb.ettus.com/RFNoC RFNoC Software Resources Page]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_Intro.pdf RFNoC Introduction]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_FPGA.pdf RFNoC Deep Dive: FPGA]&lt;br /&gt;
* [https://www.ettus.com/content/files/RFNoC_Wireless_at_VT_Host.pdf RFNoC Deep Dive: Host side]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8cPd3t88djE Video: RFNoC presented at Wireless @ Virginia Tech, 2015 ]&lt;br /&gt;
** Explaining the slides of Intro, FPGA and Host presentations above (in that order).&lt;br /&gt;
* [https://www.youtube.com/watch?v=51rpjJ2W0Qs Video: It's the RFNoC Life for Us by Martin Braun at GRCon16, 2016]&lt;br /&gt;
&lt;br /&gt;
===GNU Radio resources===&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/OutOfTreeModules GNU Radio OutOfTree Modules tutorial]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGRFromSource GNU Radio Installation]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/gnuradio/wiki/Tutorials GNU Radio Tutorials]&lt;br /&gt;
&lt;br /&gt;
===UHD resources===&lt;br /&gt;
* [http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com USRP Mailing List]&lt;br /&gt;
* [https://kb.ettus.com/UHD UHD Software Resources Page]&lt;br /&gt;
* [http://files.ettus.com/manual/md_usrp3_build_instructions.html USRP3 build instructions]&lt;br /&gt;
* [http://files.ettus.com/manual/ UHD Manual]&lt;br /&gt;
&lt;br /&gt;
===Other resources===&lt;br /&gt;
* [https://www.xilinx.com/support/documentation/ip_documentation/ug761_axi_reference_guide.pdf Xilinx - AXI reference guide]&lt;br /&gt;
* [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux UHD + GNU Radio Application Note (Linux)]&lt;br /&gt;
* [http://gnuradio.org/redmine/projects/pybombs/wiki PyBOMBS]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Application Notes]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5296</id>
		<title>USRP X410 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5296"/>
				<updated>2022-03-22T21:27:30Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Change SFP network port config file location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
===X410===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* NI Ettus USRP X410&lt;br /&gt;
* DC Power Supply (12V, 20A)&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to USB-C Cable (1m)&lt;br /&gt;
* Getting Started Guide URL (QR Code)&lt;br /&gt;
* Safety, Environmental, and Regulatory Information&lt;br /&gt;
||[[File:X410.jpg|450px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
* For Network Mode: A host computer with an available 1 or 10 Gigabit Ethernet interface for sample streaming. In addition to the Ethernet interface used for sampling streaming, your host computer will require a separate 1 Gigabit Ethernet interface for command and control streaming.&lt;br /&gt;
 &lt;br /&gt;
* For Stand-Alone Embedded Mode: A host computer with an available 1 Gigabit Ethernet port or a USB 2.0 port to remotely access the embedded Linux operating system running on ARM CPU.&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow metal objects to touch the circuit board while powered.&lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than +14 dBm continuous &amp;lt;=3GHz, +17 dBm continuous &amp;gt;3GHz, or +20dBm more than 5 minutes &amp;gt;3GHz of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
In order to use your Universal Software Radio Peripheral (USRP™), you must have the software tools correctly installed and configured on your host computer. A step-by-step guide for doing this is available at the Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]] Application Notes.&lt;br /&gt;
&lt;br /&gt;
To find the latest release of UHD, see the UHD repository at https://github.com/EttusResearch/uhd.&lt;br /&gt;
&lt;br /&gt;
The USRP X410 requires UHD version 4.1 or later. &lt;br /&gt;
&lt;br /&gt;
'''When you receive a brand-new device, it is strongly recommended that you download the latest filesystem image from the Ettus Research website update the unit. It is not recommended that you use the filesystem from the factory as-is. Instructions on downloading the latest filesystem image and updating it is listed below.'''&lt;br /&gt;
&lt;br /&gt;
'''Note that if you are operating the device in Network Mode, the version of UHD running on the host computer and the USRP X410 must match.'''&lt;br /&gt;
&lt;br /&gt;
==Assembling the X410==&lt;br /&gt;
Inside the kit you will find the X410 and an X410 power supply. Plug these in, connect the 1GbE RJ45 interface to your network, and power on the device by pressing the power button.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The STM32 Microcontroller==&lt;br /&gt;
&lt;br /&gt;
The STM32 microcontroller (also referred to as the &amp;quot;SCU&amp;quot;) controls various low-level features of the X4x0 series motherboard: It controls the power sequencing, reads out fan speeds and some of the temperature sensors. It is connected to the RFSoC via an I2C bus. It is running software based on Chromium EC.&lt;br /&gt;
&lt;br /&gt;
It is possible to log into the STM32 using the serial interface (see Connecting to the Microcontroller). This will allow certain low-level controls, such as remote power cycling should the CPU have become unresponsive for whatever reason.&lt;br /&gt;
&lt;br /&gt;
===Updating the SCU===&lt;br /&gt;
&lt;br /&gt;
The writable SCU image file is stored on the filesystem under /lib/firmware/ni/ec-titanium-revX.RW.bin (where X is a revision compatibility number). To update, simply replace the .bin file with the updated version and reboot.&lt;br /&gt;
&lt;br /&gt;
==eMMC Storage==&lt;br /&gt;
&lt;br /&gt;
The main non-volatile storage of the USRP is a 16 GB eMMC storage. This storage can be made accessible as a USB Mass Storage device through the USB-OTG connector on the back panel.&lt;br /&gt;
&lt;br /&gt;
The entire root file system (Linux kernel, libraries) and any user data are stored on the eMMC. It is partitioned into four partitions:&lt;br /&gt;
&lt;br /&gt;
Boot partition (contains the bootloader). This partition usually does not require modification.&lt;br /&gt;
A data partition, mounted in /data. This is the only partition that is not erased during file system updates.&lt;br /&gt;
Two identical system partitions (root file systems). These contain the operating system and the home directory (anything mounted under / that is not the data or boot partition). The reason there are two of these is to enable remote updates: An update running on one partition can update the other one without any effect to the currently running system. Note that the system partitions are erased during updates and are thus unsuitable for permanently storing information.&lt;br /&gt;
Note: It is possible to access the currently inactive root file system by mounting it. After logging into the device using serial console or SSH (see the following two sections), run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ mkdir temp&lt;br /&gt;
&lt;br /&gt;
$ mount /dev/mmcblk0p3 temp # This assumes mmcblk0p3 is currently not mounted&lt;br /&gt;
&lt;br /&gt;
$ ls temp # You are now accessing the idle partition:&lt;br /&gt;
&lt;br /&gt;
bin   data  etc   lib         media  proc  sbin  tmp    usr&lt;br /&gt;
boot  dev   home  lost+found  mnt    run   sys   uboot  var&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The device node in the mount command might differ, depending on which partition is currently already mounted.&lt;br /&gt;
&lt;br /&gt;
==USB Access to eMMC==&lt;br /&gt;
&lt;br /&gt;
While Mender should be used for routine filesystem updates (see Updating Filesystems), it is also possible to access the X410's internal eMMC from an external host over USB. This allows accessing or modifying the filesystem, as well as the ability to flash the device with an entirely new filesystem.&lt;br /&gt;
&lt;br /&gt;
In order to do so, you'll need an external computer with two USB ports, and two USB cables to connect the computer to your X410. The instructions below assume a Linux host.&lt;br /&gt;
&lt;br /&gt;
First, connect to the APU serial console at a baud rate of 115200. Boot the device, and stop the boot sequence by typing noautoboot at the prompt. Then, run the following command in the U-boot command prompt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ums 0 mmc 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will start the USB mass storage gadget to expose the eMMC as a USB mass storage device. You should see a spinning indicator on the console, which indicates the gadget is active.&lt;br /&gt;
&lt;br /&gt;
Next, connect your external computer to the X410's USB to PS port using an OTG cable. Your computer should recognize the X410 as a mass storage device, and you should see an entry in your kernel logs (dmesg) that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
usb 3-1: New USB device found, idVendor=3923, idProduct=7a7d, bcdDevice= 2.23&lt;br /&gt;
&lt;br /&gt;
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Product: USB download gadget&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Manufacturer: National Instruments&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] 30932992 512-byte logical blocks: (15.8 GB/14.8 GiB)&lt;br /&gt;
&lt;br /&gt;
sdc: sdc1 sdc2 sdc3 sdc4&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] Attached SCSI removable disk&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact output will depend on your machine, but from this log you can see that the X410 was recognized and /dev/sdc is the block device representing the eMMC, with 4 partitions detected (see eMMC Storage for details on the partition layout).&lt;br /&gt;
&lt;br /&gt;
It is now possible to treat the X410's eMMC as you would any other USB drive: the individual partitions can be mounted and accessed, or the entire block device can be read/written.&lt;br /&gt;
&lt;br /&gt;
Once you're finished accessing the device over USB, the u-boot gadget may be stopped by hitting Ctrl-C at the APU serial console.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Flashing the eMMC==&lt;br /&gt;
&lt;br /&gt;
Once the X410's eMMC is accessible over USB, it's possible to write the filesystem image using bmaptool. You can obtain the latest filesystem image by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader -t sdimg -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output of this command will indicate where the downloaded image can be found.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; sudo bmaptool /path/to/usrp_x4xx_fs.sdimg.bz2 /dev/sdX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to flash the eMMC with this image (replacing /dev/sdX with the block device of the X410's eMMC as indicated by your kernel log).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Using a USRP X4x0 from UHD==&lt;br /&gt;
Like any other USRP, all X4x0 USRPs are controlled by the UHD software. To integrate a USRP X4x0 into your C++ application, you would generate a UHD device in the same way you would for any other USRP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;auto usrp = uhd::usrp::multi_usrp::make(&amp;quot;type=x4xx&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a list of which arguments can be passed into make(), see Section Device Arguments.&lt;br /&gt;
&lt;br /&gt;
==Updating Filesystems==&lt;br /&gt;
&lt;br /&gt;
Mender is a third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Mender servers can be self-hosted, or hosted by Mender (see mender.io for pricing and availability).&lt;br /&gt;
&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted (note: the onboard flash storage contains two separate root file system partitions, only one is ever used at a single time). Any data stored on that partition will be permanently lost, including the currently loaded FPGA image. After updating that partition, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched (which presumably is in a working state). Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To initiate an update from the device itself, download a Mender artifact containing the update itself. These are files with a .mender suffix. They can be downloaded by using the uhd_images_downloader utility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Append the -l switch to print out the URLs only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx -l&amp;lt;/code&amp;gt;&lt;br /&gt;
Then run mender on the command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install /path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install http://server.name/path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a while. If the new filesystem requires an update to the MB CPLD, see Updating the Motherboard CPLD before proceeding. After mender has logged a successful update, reboot the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so the boot loader knows to permanently boot into this partition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender commit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ cat /etc/mender/artifact_info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are running a hosted server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Network Interfaces==&lt;br /&gt;
The Ettus USRP X410 has various network interfaces:&lt;br /&gt;
&lt;br /&gt;
eth0: RJ45 port.&lt;br /&gt;
&lt;br /&gt;
The RJ45 port comes up with a default configuration of DHCP, that will request a network address from your DHCP server (if available on your network). This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
int0: internal interface for network communication between the embedded ARM processor and FPGA.&lt;br /&gt;
&lt;br /&gt;
The internal network interface is configured with a static address: 169.254.0.1/24. This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
sfpX [, sfpX_1, sfpX_2, sfpX_3]: QSFP28 network interface(s), up-to four (one per lane) based on implemented protocol.&lt;br /&gt;
&lt;br /&gt;
Each QSFP28 port has four high-speed transceiver lanes. Therefore, depending on the FPGA image flavor, up-to four different network interfaces may exist per QSFP28 port, using the sfpXfor the first lane, and sfpX_1-3 for the other three lanes. Each network interface has a default static IP address. Note that for multi-lane protocols, such as 100 GbE, a single interface is used (sfpX).&lt;br /&gt;
The configuration files for these network interfaces are stored in: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Interface Name&lt;br /&gt;
! Description&lt;br /&gt;
! Default Configuration&lt;br /&gt;
! Configuration File&lt;br /&gt;
! Example: X4_200 FPGA image&lt;br /&gt;
|-&lt;br /&gt;
| eth0&lt;br /&gt;
| RJ45&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | DHCP&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | eth0.network&lt;br /&gt;
| DHCP&lt;br /&gt;
|-&lt;br /&gt;
| int0&lt;br /&gt;
| Internal&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | int0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0&lt;br /&gt;
| QSFP28 0 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_1&lt;br /&gt;
| QSFP28 0 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_2&lt;br /&gt;
| QSFP28 0 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0_3&lt;br /&gt;
| QSFP28 0 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp1&lt;br /&gt;
| QSFP28 1 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.20.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| sfp1_1&lt;br /&gt;
| QSFP28 1 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.21.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_2&lt;br /&gt;
| QSFP28 1 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.22.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_3&lt;br /&gt;
| QSFP28 1 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.23.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Network Connectivity==&lt;br /&gt;
Once the X410 has booted, determine the IP address and verify network connectivity by running uhd_find_devices on the host computer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ uhd_find_devices&lt;br /&gt;
&lt;br /&gt;
-- UHD Device 0&lt;br /&gt;
&lt;br /&gt;
Device Address:&lt;br /&gt;
serial: 1234ABC&lt;br /&gt;
addr: 10.2.161.10&lt;br /&gt;
claimed: False&lt;br /&gt;
mgmt_addr: 10.2.161.10&lt;br /&gt;
product: x410&lt;br /&gt;
type: x4xx&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, an X410 will use DHCP to attempt to find an address.&lt;br /&gt;
&lt;br /&gt;
At this point, you should run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_usrp_probe --args addr=&amp;lt;IP address&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
to ensure functionality of the device.&lt;br /&gt;
&lt;br /&gt;
Note: If you receive the following error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Error: RuntimeError: Graph edge list is empty for rx channel 0&amp;lt;/code&amp;gt;&lt;br /&gt;
then you will need to download a UHD-compatible FPGA as described in Updating the FPGA or using the following command (it assumes that FPGA images have been downloaded previously using uhd_images_downloader, or that the command is run on the device itself):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;ip address&amp;gt;,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
When running on the device, use &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; as the IP address.&lt;br /&gt;
&lt;br /&gt;
You can now use existing UHD examples or applications (such as rx_sample_to_file, rx_ascii_art_dft, or tx_waveforms) or other UHD-compatible applications to start receiving and transmitting with the device.&lt;br /&gt;
&lt;br /&gt;
See Network Interfaces for further details on the various network interfaces available on the X410.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Status LEDs===&lt;br /&gt;
The Ettus USRP X410 is equipped with status LEDs for its network-capable ports: RJ45 and QSFP28s, see RJ45 LED Behavior and QSFP28 LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
====RJ45 LED Behavior====&lt;br /&gt;
The RJ45 port has two independent LEDs: green (right) and yellow (left). The table below summarizes the LEDs' behavior. Note that link speed indication is not currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! Green LED&lt;br /&gt;
! Yellow LED&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| On&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| On&lt;br /&gt;
| Blinking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====QSFP28 LED Behavior====&lt;br /&gt;
Each QSFP28 connector has four LEDs, one for each high-speed transceiver lane. The table below summarizes the LEDs' behavior, note that for multi-lane protocols, such as 100 GbE, the corresponding LEDs are ganged together. Within the same image, multiple speeds on the same port (e.g., both 10 GbE and 100 GbE) are not supported, therefore link speed indication is not supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! QSFP28 LED (4 Total)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| Green (solid)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| Amber (blinking)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Security-related Settings==&lt;br /&gt;
The X410 ships without a root password set. It is possible to ssh into the device by simply connecting as root, and thus gaining access to all subsystems. To set a password, run the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ passwd&amp;lt;/code&amp;gt;&lt;br /&gt;
on the device.&lt;br /&gt;
&lt;br /&gt;
==Serial Connection==&lt;br /&gt;
It is possible to gain access to the device using a serial terminal emulator. To do so, the USB debug port needs to be connected to a separate computer to gain access. Most Linux, OSX, or other Unix flavors have a tool called 'screen' which can be used for this purpose, by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/ttyUSB2 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
In this command, we prepend 'sudo' to elevate user privileges (by default, accessing serial ports is not available to regular users), we specify the device node (in this case, /dev/ttyUSB2), and the baud rate (115200).&lt;br /&gt;
&lt;br /&gt;
The exact device node depends on your operating system's driver and other USB devices that might be already connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ls /dev/serial/by-id&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
The first (with the if02 suffix) connects to the STM32 microcontroller (SCU), whereas the second (with the if03 suffix) connects to Linux running on the RFSoC APU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
After entering the username root (no password is set by default), you should be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
On this prompt, you can enter any Linux command available. Using the default configuration, the serial console will also show all kernel log messages (unlike when using SSH, for example), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or bootloader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
==Connecting to the Microcontroller==&lt;br /&gt;
The microcontroller (which controls the power sequencing, among other things) also has a serial console available. To connect to the microcontroller, use the other UART device. In the example above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It provides a very simple prompt. The command 'help' will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it and other low-level diagnostics. For example, running the command reboot will emulate a reset button press, resetting the state of the device, while the command powerbtn will emulate a power button press, turning the device back on again.&lt;br /&gt;
&lt;br /&gt;
==SSH Connection==&lt;br /&gt;
The USRP X410 has two network connections: The dual QSFP28 ports, and an RJ45 connector. The latter is by default configured by DHCP; by plugging it into into 1 Gigabit switch on a DHCP-capable network, it will get assigned an IP address and thus be accessible via ssh.&lt;br /&gt;
&lt;br /&gt;
In case your network setup does not include a DHCP server, refer to the section Serial Connection. A serial login can be used to assign an IP address manually.&lt;br /&gt;
&lt;br /&gt;
After the device obtained an IP address you can log in from a Linux or OSX machine by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC # Replace with your actual device name!&amp;lt;/code&amp;gt;&lt;br /&gt;
Depending on your network setup, using a .local domain may work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC.local&amp;lt;/code&amp;gt;&lt;br /&gt;
Of course, you can also connect to the IP address directly if you know it (or set it manually using the serial console).&lt;br /&gt;
&lt;br /&gt;
Note: The device's hostname is derived from its serial number by default (&amp;lt;code&amp;gt;ni-x4xx-$SERIAL&amp;lt;/code&amp;gt;). You can change the hostname by creating the file &amp;lt;code&amp;gt;/data/network/hostname&amp;lt;/code&amp;gt;, saving the desired hostname in it, then rebooting.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the connection can be established using a tool such as PuTTY, by selecting a username of root without password.&lt;br /&gt;
&lt;br /&gt;
Like with the serial console, you should be presented with a prompt like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Autoboot ==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 can be configured to power on and boot automatically when power is applied. This setting can be controlled using the &amp;lt;code&amp;gt;eeprom-set-autoboot&amp;lt;/code&amp;gt; script. This script is executed directly on the USRP X410. To enable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot on&amp;lt;/code&amp;gt;; to disable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot off&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA==&lt;br /&gt;
&lt;br /&gt;
The FPGA can be updated simply using uhd_image_loader:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt; --fpga-path &amp;lt;path to .bit&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt;,fpga=FPGA_TYPE&amp;lt;/code&amp;gt;&lt;br /&gt;
A UHD install will likely have pre-built images in /usr/share/uhd/images/. Up-to-date images can be downloaded using the uhd_images_downloader script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt;&lt;br /&gt;
will download images into /usr/share/uhd/images/ (the path may differ, depending on how UHD was installed).&lt;br /&gt;
&lt;br /&gt;
Also note that the USRP already ships with compatible FPGA images on the device - these images can be loaded by SSH'ing into the device and running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,mgmt_addr=127.0.0.1,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FPGA Image Flavors==&lt;br /&gt;
&lt;br /&gt;
Unlike the USRP X310 or other third-generation USRP devices, the FPGA image flavors do not only encode how the QSFP28 connectors are configured, but also which master clock rates are available. This is because the data converter configuration is part of the FPGA image (the ADCs/DACs on the X410 are on the same die as the FPGA). The image flavors consist of two short strings, separated by an underscore, e.g. X4_200 is an image flavor which contains 4x 10 GbE, and can handle an analog bandwidth of 200 MHz. The first two characters describe the configuration of the QSFP28 ports: 'X' stands for 10 GbE, 'C' stands for 100 GbE. See the following table for more details.&lt;br /&gt;
&lt;br /&gt;
1x 10 GbE (Lane 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The analog bandwidth determines the available master clock rates. As of UHD 4.1, only the X4_200 image is shipped with UHD, which allows a 245.76 MHz or 250 MHz master clock rate. The other images are considered experimental (unsupported).&lt;br /&gt;
&lt;br /&gt;
==Device Arguments==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! Example Value&lt;br /&gt;
|-&lt;br /&gt;
| addr&lt;br /&gt;
| IPv4 address of primary SFP+ port to connect to.&lt;br /&gt;
| addr=192.168.30.2&lt;br /&gt;
|-&lt;br /&gt;
| second_addr&lt;br /&gt;
| IPv4 address of secondary SFP+ port to connect to.&lt;br /&gt;
| second_addr=192.168.40.2&lt;br /&gt;
|-&lt;br /&gt;
| mgmt_addr&lt;br /&gt;
| IPv4 address or hostname to which to connect the RPC client. Defaults to `addr'.&lt;br /&gt;
| mgmt_addr=ni-sulfur-311FE00&lt;br /&gt;
|-&lt;br /&gt;
| find_all&lt;br /&gt;
| When using broadcast, find all devices, even if unreachable via CHDR.&lt;br /&gt;
| find_all=1&lt;br /&gt;
|-&lt;br /&gt;
| master_clock_rate&lt;br /&gt;
| Master Clock Rate in Hz.&lt;br /&gt;
| master_clock_rate=250e6&lt;br /&gt;
|-&lt;br /&gt;
| serialize_init&lt;br /&gt;
| Force serial initialization of daughterboards.&lt;br /&gt;
| serialize_init=1&lt;br /&gt;
|-&lt;br /&gt;
| skip_init&lt;br /&gt;
| Skip the initialization process for the device.&lt;br /&gt;
| skip_init=1&lt;br /&gt;
|-&lt;br /&gt;
| time_source&lt;br /&gt;
| Specify the time (PPS) source.&lt;br /&gt;
| time_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| clock_source&lt;br /&gt;
| Specify the reference clock source.&lt;br /&gt;
| clock_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| ref_clk_freq&lt;br /&gt;
| Specify the external reference clock frequency, default is 10 MHz.&lt;br /&gt;
| ref_clk_freq=20e6&lt;br /&gt;
|-&lt;br /&gt;
| discovery_port&lt;br /&gt;
| Override default value for MPM discovery port.&lt;br /&gt;
| discovery_port=49700&lt;br /&gt;
|-&lt;br /&gt;
| rpc_port&lt;br /&gt;
| Override default value for MPM RPC port.&lt;br /&gt;
| rpc_port=49701&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==GPS==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 includes a Jackson Labs LTE-Lite GPS module. Its antenna port is on the rear panel (see Front and Back Panels). When the X410 has access to GPS satellite signals, it can use this module to read out the current GPS time and location as well as to discipline an onboard OCXO.&lt;br /&gt;
&lt;br /&gt;
To use the GPS as a clock and time reference, simply use gpsdo as a clock or time source. Alternatively, set gpsdo as a synchronization source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Set clock/time individually:&lt;br /&gt;
usrp-&amp;gt;set_clock_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
usrp-&amp;gt;set_time_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
// This is equivalent to the previous commands, but faster, as it sets&lt;br /&gt;
// both settings simultaneously and avoids duplicating settings that are shared&lt;br /&gt;
// between these calls.&lt;br /&gt;
usrp-&amp;gt;set_sync_source(&amp;quot;clock_source=gpsdo,time_source=gpsdo&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the GPS module is not always enabled. Its power-on status can be queried using the gps_enabled GPS sensor (see also The Sensor API). When disabled, none of the sensors will return useful (if any) values.&lt;br /&gt;
&lt;br /&gt;
When selecting gpsdo as a clock source, the GPS will always be enabled. Note that acquiring a GPS lock can take some time after enabling the GPS, so if a UHD application is enabling the GPS dynamically, it might take some time before a GPS lock is reported.&lt;br /&gt;
&lt;br /&gt;
==Front-Panel Programmable GPIOs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 has two HDMI front-panel connectors, which are connected to the FPGA.&lt;br /&gt;
&lt;br /&gt;
Support for using these with UHD is not yet available.&lt;br /&gt;
&lt;br /&gt;
==Subdev Specifications==&lt;br /&gt;
&lt;br /&gt;
The RF ports on the front panel of the X410 + ZBX correspond to the following subdev specifications:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Label&lt;br /&gt;
! style=&amp;quot;text-align:center; vertical-align:middle; font-weight:bold;&amp;quot; | Subdev Spec&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 0&lt;br /&gt;
| A:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 1&lt;br /&gt;
| A:1&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 0&lt;br /&gt;
| B:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 1&lt;br /&gt;
| B:1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The subdev spec slot identifiers &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; are not reflected on the front panel. They were set to match valid subdev specifications of previous USRPs, maintaining backward compatibility.&lt;br /&gt;
&lt;br /&gt;
These values can be used for uhd::usrp::multi_usrp::set_rx_subdev_spec() and uhd::usrp::multi_usrp::set_tx_subdev_spec() as with other USRPs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Rear Panel Status LEDs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 is equipped with four LEDs located on the device's rear panel. Each LED supports four different states: Off, Green, Red, and Amber. One LED (PWR) indicates the device's power state (see Power LED below). The other three LEDs (LED 0, LED 1, and LED 2) are user-configurable, different behaviors are supported for each of these LEDs (see User-configurable LEDs below).&lt;br /&gt;
&lt;br /&gt;
[[File:x4xx_rearpanel_status_leds.png|125px]]&lt;br /&gt;
&lt;br /&gt;
===X4x0 Rear Panel Status LEDs===&lt;br /&gt;
Power LED&lt;br /&gt;
The USRP X410's PWR LED is reserved to visually indicate the user the device's power state. Power LED Behavior describes what each LED state represents.&lt;br /&gt;
&lt;br /&gt;
===Power LED Behavior===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! PWR LED State&lt;br /&gt;
! style=&amp;quot;vertical-align:middle;&amp;quot; | Meaning&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Off&lt;br /&gt;
| No power is applied&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Amber&lt;br /&gt;
| Power is good but X410 is powered off&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Green&lt;br /&gt;
| Power is good and X410 is powered on&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Red&lt;br /&gt;
| Power error state&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===User-configurable LEDs===&lt;br /&gt;
The USRP X410's user-configurable rear panel status LEDs (LED 0, LED 1, and LED 2) allow the user to have visual indication of various device conditions. Supported LED Behaviors provides a complete list of the supported behaviors for each user-configurable LED. By default, these LEDs are configured as described in LEDs Default Behavior.&lt;br /&gt;
&lt;br /&gt;
The user may alter the default LEDs behavior either temporarily or persistently, see the Temporarily change the LED Behavior or Persistently in the UHD manual to change the LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
https://files.ettus.com/manual/page_usrp_x4xx.html&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:X410]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=E320_Getting_Started_Guide&amp;diff=5295</id>
		<title>E320 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=E320_Getting_Started_Guide&amp;diff=5295"/>
				<updated>2022-03-22T21:22:21Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Show both old and new SFP network port config file locations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
&lt;br /&gt;
===E320 Board-only===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP E320&lt;br /&gt;
* Power connector (assembly required) &lt;br /&gt;
* 4 M3x0.5, M3x5 Standoffs &lt;br /&gt;
* 1 Gb Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* 1 Gb SFP+ to RJ45 Adapter&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
|[[File:e320 board only.jpg|500px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===E320 Full Enclosure===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP E320 in enclosure &lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 Gb Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* 1 Gb SFP+ to RJ45 Adapter&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
* T8 Torx Wrench&lt;br /&gt;
|[[File:e320 enclosure kit.jpg|500px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Verify the Contents of Your Kit==&lt;br /&gt;
Ensure that your kit contains all the items listed above. If any items are missing, please contact sales@ettus.com​ immediately.&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
&lt;br /&gt;
* For Network Mode: A host computer with an 1 or 10 Gb Ethernet interface. If operating with the 10 Gb Ethernet interface, the &amp;quot;XG&amp;quot; FPGA image must be loaded before the SFP+ port will operate at 10 Gb speeds. Optionally a second 1 Gb Ethernet interface can be used to connect to the onboard ARM CPU for remote management. &lt;br /&gt;
&lt;br /&gt;
* For Embedded Mode: A host computer is only required for initial device configuration, remote control and management, or data visualization. The host computer can connect to the RJ45 1 Gb port or Serial Console port to remotely access the Open Embedded Linux operating system running on the ARM CPU. Once configured, the USRP E320 can operate as a stand-alone device without a connection to a remote host computer.  &lt;br /&gt;
&lt;br /&gt;
* For Board-only Version: A third-party 10-14V/3A power supply, which requires assembly with the power connect components included in the kit. An assembled power supply can be purchased here: https://www.ettus.com/product/details/12V-PWR&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow anything especially metal objects to touch the board while it is powered on. &lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
* Never touch the circuit board or heatsink while the device is powered on. &lt;br /&gt;
* All connections should be made/removed while is device is powered off. &lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than -15 dBm of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
&lt;br /&gt;
To use your Universal Software Radio Peripheral (USRP™), you must have software tools correctly installed and configured on your host computer. Step-by-step guides for these software tools are found in the Application Notes for Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]].&lt;br /&gt;
&lt;br /&gt;
The USRP E320 requires UHD version 3.13.0.2 or later. It is strongly​ recommended to use the latest stable release of UHD on both the host computer and the USRP via the filesystem on the SD card. If this release fails to work in some way, then try the maintenance branch of the latest stable version. If you are operating the device in Network Mode, the version of UHD running on the host machine and E320 USRP must match to within the same maintenance release and branch. See the [https://github.com/ettusresearch/uhd UHD GitHub repository] for the latest release and maintenance branch.&lt;br /&gt;
&lt;br /&gt;
==Connecting the Device==&lt;br /&gt;
===Interfaces Overview===&lt;br /&gt;
Listed below are the interfaces to connect to the USRP E320. Each interface has specific functionality, limitations and purpose.&lt;br /&gt;
&lt;br /&gt;
'''Serial Console'''&lt;br /&gt;
&lt;br /&gt;
The Serial Console provides a low-level interface to the ARM CPU and STM32 microcontroller, typically used for debugging. The serial console can also be used as a JTAG connection to the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''1 Gb RJ45 Connection'''&lt;br /&gt;
&lt;br /&gt;
The 1 Gb RJ45 Connection interfaces with the on-board ARM CPU. When operated in &amp;quot;Network mode&amp;quot;, this interface can optionally be used for remote control and management traffic. Regardless of the operation mode (Host vs Embedded) this interface can be used to connect to the ARM via SSH. By default, the 1 Gb RJ45 connection is configured to use a DHCP assigned IP address.&lt;br /&gt;
&lt;br /&gt;
'''SFP+ Connection'''&lt;br /&gt;
&lt;br /&gt;
The SFP+ Connection supports multiple interfaces for streaming high-speed, low-latency data, depending upon which FPGA image is loaded.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Serial Console Connection===&lt;br /&gt;
It is possible to gain shell access to the device using a serial terminal emulator via the Serial Console port. Most Linux, OS X, or other Unix based operating systems have a utility called &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; which can be used for this purpose. &lt;br /&gt;
&lt;br /&gt;
If you do not have &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; installed, it can be installed via your distribution's package manager. For Ubuntu/Debian based operating systems it can be installed with the package manager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; such as:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install screen&lt;br /&gt;
&lt;br /&gt;
The default Baud Rate for the Serial Console is: &amp;lt;code&amp;gt;115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact device node you should attach to depends on your operating system's driver and other USB devices that might already be connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under &amp;lt;code&amp;gt;/dev/serial/by-id&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ ls /dev/serial/by-id&lt;br /&gt;
    usb-FTDI_Dual_RS232-HS-if00-port0&lt;br /&gt;
    usb-FTDI_Dual_RS232-HS-if01-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if00-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if01-port0&lt;br /&gt;
&lt;br /&gt;
NOTE: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
Every E320 series device connected to USB will by default show up as four different devices. The devices labeled &amp;lt;code&amp;gt;&amp;quot;USB_to_UART_Bridge_Controller&amp;quot;&amp;lt;/code&amp;gt; are the devices that offer a serial prompt. The first (with the &amp;lt;code&amp;gt;if00&amp;lt;/code&amp;gt; suffix) connects to the &amp;lt;code&amp;gt;STM32 Microcontroller&amp;lt;/code&amp;gt;, whereas the second connects to the &amp;lt;code&amp;gt;ARM CPU&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you have multiple E320 Serial Consoles connected to a single host, you may have to empirically test nodes.&lt;br /&gt;
&lt;br /&gt;
Connecting to the ARM CPU can be performed with the command:&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen  /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if01-port0 115200&lt;br /&gt;
&lt;br /&gt;
Upon starting the USRP E320, boot messages will appear and rapidly update. Once the boot process successfully completes, a login prompt like the following should appear:&lt;br /&gt;
&lt;br /&gt;
    Alchemy 2018.04 ni-e320-serial ttyPS0&lt;br /&gt;
    ni-e320-serial login:&lt;br /&gt;
&lt;br /&gt;
Enter the username: ​&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;​&lt;br /&gt;
&lt;br /&gt;
By default, the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user's password is left blank. Press the &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; key when prompted for a password.&lt;br /&gt;
&lt;br /&gt;
You should now be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
Using the default configuration, the serial console will show all kernel log messages (which are not available when using SSH) and give access to the boot loader (U-boot prompt). This can be used to debug kernel or boot-loader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
===Connecting to the microcontroller===&lt;br /&gt;
&lt;br /&gt;
Using the Serial Console interface, it is possible to connect to the STM32 microcontroller with the command below. The STM32 controls the power sequencing and several other low-level device operations.&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen  /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if00-port0 115200&lt;br /&gt;
&lt;br /&gt;
The STM32 interface provides a very simple prompt. The command &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt; will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it (i.e., emulating a power button press) and other low-level diagnostics.&lt;br /&gt;
&lt;br /&gt;
===Connecting to the ARM via SSH===&lt;br /&gt;
By default, the RJ45 1 Gb management interface is configured to be assigned a DHCP IP address.&lt;br /&gt;
&lt;br /&gt;
If you have access to a network which provides a DHCP server (such as a common router's LAN), attach the RJ45 1 Gb port to this network. Details vary by vendor, however, most router management interfaces will provide a list of attached devices to the LAN including their IP address.&lt;br /&gt;
&lt;br /&gt;
Without access to a router management interface, you can identify the IP address by connecting to the ARM CPU via Serial Console as detailed in the section above and running the command &amp;lt;code&amp;gt;ip a&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ip a&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.1.151/24 brd 192.168.1.255 scope global dynamic eth0&lt;br /&gt;
       valid_lft 42865sec preferred_lft 42865sec&lt;br /&gt;
3: sfp0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 8000 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.10.2/24 brd 192.168.10.255 scope global sfp0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do not have access to a network with a DHCP server, you can create one using the Linux utility &amp;lt;code&amp;gt;dnsmasq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ sudo dnsmasq -i &amp;lt;ETHERNET_ADAPTER_NAME&amp;gt; --dhcp-range=192.168.1.50,192.168.1.100 --except-interface=lo --bind-dynamic --no-daemon&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the value &amp;lt;code&amp;gt;&amp;lt;ETHERNET_ADAPTER_NAME&amp;gt;&amp;lt;/code&amp;gt; to match the interface you would like to create a DHCP server on.&lt;br /&gt;
&lt;br /&gt;
After the device has obtained an IP address, you can remotely log into it from a Linux or macOS systems with SSH, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ssh root@192.168.1.51&lt;br /&gt;
&lt;br /&gt;
NOTE: The IP address may vary depending on your network setup.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password is empty/blank.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the SSH connection can be established using the third-party program, such as ​PuTTY.&lt;br /&gt;
&lt;br /&gt;
After logging in, you should be presented with a shell prompt like the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
==Updating the Linux File System==&lt;br /&gt;
Before operating the device, it is​ ​strongly​ recommended to update to the latest version of the Embedded Linux file system. If you are operating the device in Network Mode, the version of UHD running on the host machine and E320 USRP must match. &lt;br /&gt;
&lt;br /&gt;
There is two ways to update the file system for the E320 USRP: &lt;br /&gt;
&lt;br /&gt;
1. Mender&lt;br /&gt;
&lt;br /&gt;
2. Physically remove microSD card from device and write a new file system to the microSD card. &lt;br /&gt;
&lt;br /&gt;
===File System Partition Layout===&lt;br /&gt;
The SD Card is divided into four partitions. There are two root file system partitions, a &amp;quot;boot&amp;quot; partition and a &amp;quot;data&amp;quot; partition. &lt;br /&gt;
&lt;br /&gt;
Any data you would like to preserve through Mender updates should be saved to the &amp;quot;data&amp;quot; partition, which is mounted at &amp;lt;code&amp;gt;/data&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Updating the file system with Mender===&lt;br /&gt;
Mender is third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website https://mender.io). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Users can host their own local Mender server, or use servers hosted by Mender as a paid service; contact Mender for more information. &lt;br /&gt;
&lt;br /&gt;
====Mender Update Process====&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted. Any data stored in the root partitions will be permanently lost with a Mender update.&lt;br /&gt;
&lt;br /&gt;
After updating a partition with Mender, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched, which presumably is in a working state. Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To obtain the file system Mender image (these are files with a &amp;lt;code&amp;gt;.mender&amp;lt;/code&amp;gt; suffix), run the following command on the host computer with Internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader -t mender -t e320 --yes&lt;br /&gt;
&lt;br /&gt;
Example Output:    &lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    395769 kB / 395769 kB (100%) e3xx_e320_mender_default-v3.13.1.0.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
NOTE: In the output of the command, the folder destination where the images are saved is printed out.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to copy this Mender file system image to the USRP E320. This can be done with the Linux utility &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ scp /usr/local/share/uhd/images/usrp_e320_fs.mender root@192.168.1.51:~/. &lt;br /&gt;
&lt;br /&gt;
Note: The path and IP may different for your configuration, the command above assumes you're using the default installation path of &amp;lt;code&amp;gt;/usr/local&amp;lt;/code&amp;gt; and that the E320's IP is &amp;lt;code&amp;gt;192.168.1.51&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
After copying the Mender file system image to the E320, connect to the E320 using either the Serial Console, or via SSH to gain shell access.&lt;br /&gt;
&lt;br /&gt;
On the E320, run &amp;lt;code&amp;gt;mender -rootfs /path/to/latest.mender&amp;lt;/code&amp;gt; to update the file system:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-serial:~# mender -rootfs /home/root/usrp_e320_fs.mender&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-316E375:~# mender -rootfs /home/root/usrp_e320_fs.mender                       &lt;br /&gt;
INFO[0000] Start updating from local image file: [/home/root/usrp_e320_fs.mender]  module=rootfs&lt;br /&gt;
Installing update from the artifact of size 399640064&lt;br /&gt;
INFO[0000] opening device /dev/mmcblk0p3 for writing     module=block_device&lt;br /&gt;
INFO[0000] partition /dev/mmcblk0p3 size: 2046820352     module=block_device&lt;br /&gt;
................................   0% 1024 KiB&lt;br /&gt;
................................   0% 2048 KiB&lt;br /&gt;
................................   0% 3072 KiB&lt;br /&gt;
[truncated for readability]&lt;br /&gt;
................................  99% 389120 KiB&lt;br /&gt;
................................  99% 390144 KiB&lt;br /&gt;
................................ 100% 390273 KiB&lt;br /&gt;
INFO[0740] wrote 2046820352/2046820352 bytes of update to device /dev/mmcblk0p3  module=device&lt;br /&gt;
INFO[0744] Enabling partition with new image installed to be a boot candidate: 3  module=device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
    $ mender -rootfs &amp;lt;http://server.name/path/to/latest.mender&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a few minutes to complete. After mender has logged a successful update, reboot the device:&lt;br /&gt;
    $ reboot&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so that the boot loader knows to permanently boot into this partition:&lt;br /&gt;
    $ mender -commit&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried on the E320:&lt;br /&gt;
    $ cat /etc/mender/artifact_info&lt;br /&gt;
&lt;br /&gt;
If you are using a Mender server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and you can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
For more information on updating the file-system, refer to the UHD Manual at ​http://uhd.ettus.com​.&lt;br /&gt;
&lt;br /&gt;
===Updating the files system by writing the disk image===&lt;br /&gt;
The microSD card is accessible directly on the Board-only version of the E320 USRP. The E320 Full Enclosure version must be opened with the included Torx wrench. &lt;br /&gt;
&lt;br /&gt;
NOTE: This method will overwrite all data saved on the microSD card, including any data saved to the &amp;lt;code&amp;gt;/data&amp;lt;/code&amp;gt; partition.&lt;br /&gt;
&lt;br /&gt;
Please see the separate application note, [[Writing the USRP File System Disk Image to a SD Card]], for step-by-step instructions on writing the file system image to the microSD card.&lt;br /&gt;
&lt;br /&gt;
==Updating the Network Configurations==&lt;br /&gt;
The USRP E320 systemd network configuration files are located either at: &amp;lt;code&amp;gt;/etc/systemd/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    # ls /etc/systemd/network/&lt;br /&gt;
    eth0.network  sfp0.network &lt;br /&gt;
&lt;br /&gt;
or for newer versions of the file system: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    # ls /data/network/&lt;br /&gt;
    eth0.network  int0.network  sfp0.network&lt;br /&gt;
&lt;br /&gt;
For details on configuration please refer to the [https://www.freedesktop.org/software/systemd/man/systemd.network.html systemd-networkd manual pages].&lt;br /&gt;
&lt;br /&gt;
The factory settings are as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
eth0 (DHCP):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=eth0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    DHCP=v4&lt;br /&gt;
&lt;br /&gt;
    [DHCPv4]&lt;br /&gt;
    UseHostname=false&lt;br /&gt;
&lt;br /&gt;
sfp0 (static):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=sfp0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    Address=192.168.10.2/24&lt;br /&gt;
&lt;br /&gt;
    [Link]&lt;br /&gt;
    MTUBytes=8000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional notes on networking:&lt;br /&gt;
&lt;br /&gt;
* Care needs to be taken when editing these files on the device, since &amp;lt;code&amp;gt;vi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;vim&amp;lt;/code&amp;gt; sometimes generates undo files (e.g. &amp;lt;code&amp;gt;/data/network/sfp0.network~&amp;lt;/code&amp;gt;), that &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; might accidentally pick up.&lt;br /&gt;
* Temporarily setting the IP addresses or MTU sizes via &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; or other command line tools will only change the value until the next reboot or reload of the FPGA image.&lt;br /&gt;
* If the MTU of the device and host computers differ, streaming issues can occur.&lt;br /&gt;
* Streaming via SFP0 at 1 Gb rates requires a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;&lt;br /&gt;
* Streaming via SFP0 at 10 Gb rates requires a MTU of &amp;lt;code&amp;gt;8000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For addition details on network configuration here: https://files.ettus.com/manual/page_usrp_e320.html#e320_network_configuration&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA Image==&lt;br /&gt;
&lt;br /&gt;
===Network mode FPGA Image Update===&lt;br /&gt;
The FPGA image should match the version of UHD installed on the host computer when operated in Network mode. &lt;br /&gt;
&lt;br /&gt;
Network mode FPGA image updates must be made through the RJ45 management interface.&lt;br /&gt;
&lt;br /&gt;
To obtain all the FPGA images for your installed version of UHD, run the following command on the host computer with internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    [INFO] No inventory file found at /usr/local/share/uhd/images/inventory.json. Creating an empty one.&lt;br /&gt;
    05920 kB / 05920 kB (100%) e3xx_e320_fpga_default-g494ae8bb.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
There is two versions of the E320 FPGA images shipped with UHD:&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; for 1 Gb rates on the SFP+ port (default image)&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; for 10 Gb rates on the SFP+ port&lt;br /&gt;
&lt;br /&gt;
In this example, we load the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; variant of the FPGA image.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=e3xx,mgmt_addr=&amp;lt;E320_RJ45_IP_ADDR&amp;gt;,fpga=XG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;mgmt_addr=192.168.1.51,type=e3xx,fpga=XG&amp;quot;&lt;br /&gt;
    [INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
    [INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.1.51,type=e3xx,product=e320,serial=316E375,claimed=False,skip_init=1&lt;br /&gt;
    [INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
    [INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Device serial number: 316E375&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Found 1 daughterboard(s).&lt;br /&gt;
&lt;br /&gt;
The FPGA is immediately updated, and this FPGA image will continue to be used. The device does not need to be power cycled to use the new image. &lt;br /&gt;
&lt;br /&gt;
To load a different FPGA image (i.e. &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt;), modify the device argument &amp;lt;code&amp;gt;fpga=&amp;lt;/code&amp;gt; to a value of &amp;lt;code&amp;gt;fpga=1G&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To specify the path to a custom FPGA image, use the ​&amp;lt;code&amp;gt;--fpga-path&amp;lt;/code&amp;gt;​ argument.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=e3xx,mgmt_addr=&amp;lt;E320_RJ45_IP_ADDR&amp;gt;&amp;quot; --fpga-path=/path/to/custom/fpga.bit&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |The Verilog code for the FPGA in the USRP E320 is open-source, and users are free to modify and customize it for their needs. However, certain modifications may result in either bricking the device, or even in physical damage to the unit. Please note that modifications to the FPGA are made at the risk of the user, and may not be covered by the warranty of the device.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Embedded Mode FPGA Image Update===&lt;br /&gt;
&lt;br /&gt;
It is possible to update the FPGA image when operated in Embedded mode. Connect to the ARM CPU [[#Setting_up_a_Serial_Console_Connection|via Serial Console]] or [[E320_Getting_Started_Guide#Connecting_to_the_ARM_via_SSH| via SSH]]. It is generally recommend to use SSH over the RJ45 interface for remote management. &lt;br /&gt;
&lt;br /&gt;
Run the command &amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt; to download the FPGA images to the device's file system:&lt;br /&gt;
&lt;br /&gt;
NOTE: The 1 Gb RJ45 management interface will require Internet access for this next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-serial:~# python3 /usr/bin/uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
[INFO] Images destination: /usr/share/uhd/images&lt;br /&gt;
[INFO] No inventory file found at /usr/share/uhd/images/inventory.json. Creating an empty one.&lt;br /&gt;
05920 kB / 05920 kB (100%) e3xx_e320_fpga_default-g494ae8bb.zip&lt;br /&gt;
[INFO] Images download complete.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: The default UHD FPGA Images destination within the E320's file-system is &amp;lt;code&amp;gt;/usr/share/uhd/images&amp;lt;/code&amp;gt;. The default UHD FPGA Images destination on a typical host installation is &amp;lt;code&amp;gt;/usr/local/share/uhd/images&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Updating the FPGA image from the ARM CPU is the same as detailed above for a Network mode update:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-serial:~# uhd_image_loader --args &amp;quot;type=e3xx,fpga=1G&amp;quot;&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106600; UHD_3.13.1.0-0-unknown&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=127.0.0.1,type=e3xx,product=e320,serial=316E375,claimed=False,skip_init=1&lt;br /&gt;
[INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
[INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
[INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
[INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 316E375&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Found 1 daughterboard(s).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on updating the FPGA image, refer to the UHD Manual at http://uhd.ettus.com​.&lt;br /&gt;
&lt;br /&gt;
==Setting Up a Streaming Connection==&lt;br /&gt;
The device supports multiple high-speed, low-latency interfaces on the SFP+ port for streaming samples to the host computer.&lt;br /&gt;
&lt;br /&gt;
===1 Gb Streaming via SFP+ Port ===&lt;br /&gt;
Complete the steps below to set up a streaming connection over the 1 Gb Ethernet interface on the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; FPGA image must be loaded for the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; to operate at 1 Gb speeds. If the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 1Gb speeds.&lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's 1 Gb Ethernet interface as shown below. This interface should be separate from the 1 Gb NIC/network which is connected to the 1 Gb RJ45 management interface. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 1500&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; at 1 Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;. Mismatched MTU values on either the Host or E320 may cause flow control errors. Your computer may need to be restarted for the MTU value to take effect.&lt;br /&gt;
&lt;br /&gt;
2. Insert the RJ45-to-SFP+ adapter ​into the​ &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​.&lt;br /&gt;
&lt;br /&gt;
3. Connect the SFP+ adapter on the device to an Ethernet port on the host computer using a standard Ethernet cable.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above the ​&amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
    PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.&lt;br /&gt;
    64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=1.06 ms&lt;br /&gt;
    ^C&lt;br /&gt;
    --- 192.168.10.2 ping statistics ---&lt;br /&gt;
    1 packets transmitted, 1 received, 0% packet loss, time 0ms&lt;br /&gt;
    rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms&lt;br /&gt;
    &lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program.&lt;br /&gt;
&lt;br /&gt;
5. Verify your MTU is set correctly for 1 Gb speeds on the E320. See the section [[E320_Getting_Started_Guide#Updating_the_Network_Configurations|Updating the Network Configurations]] for additional details.&lt;br /&gt;
&lt;br /&gt;
Proceed to the next section [[E320_Getting_Started_Guide#Verifying_Device_Operation|Verifying Device Operation]].&lt;br /&gt;
&lt;br /&gt;
===10 Gb Streaming via SFP+ Port===&lt;br /&gt;
Load the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image for 10 Gb streaming as detailed in the section [[E320_Getting_Started_Guide#Updating_the_FPGA_Image|Updating the FPGA Image]]. You will need to use a 10 GigE cable that can be plugged in directly to the SFP+ connector on the board. &lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image must be loaded for the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; to operate at 10 Gb speeds. If the &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 10 Gb speeds. Mismatched MTU values on either the Host or E320 may cause flow control errors.&lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's 10 Gb Ethernet interface as shown below. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 8000&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; at 10 Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;8000&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;. Mismatched MTU values on either the Host or E320 may cause flow control errors. Your computer may need to be restarted for the MTU value to take effect.&lt;br /&gt;
&lt;br /&gt;
2. Connect the SFP+ port on the device to an Ethernet port on the host computer using a 10 Gb SFP+ copper or fiber cable.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above the ​&amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
    PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.&lt;br /&gt;
    64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=1.06 ms&lt;br /&gt;
    ^C&lt;br /&gt;
    --- 192.168.10.2 ping statistics ---&lt;br /&gt;
    1 packets transmitted, 1 received, 0% packet loss, time 0ms&lt;br /&gt;
    rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms&lt;br /&gt;
    &lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program.&lt;br /&gt;
&lt;br /&gt;
5. Verify your MTU is set correctly for 10 Gb speeds on the E320. See the section [[E320_Getting_Started_Guide#Updating_the_Network_Configurations|Updating the Network Configurations]] for additional details.&lt;br /&gt;
&lt;br /&gt;
Proceed to the next section [[E320_Getting_Started_Guide#Verifying_Device_Operation|Verifying Device Operation]].&lt;br /&gt;
&lt;br /&gt;
==Verifying Device Operation==&lt;br /&gt;
Once you have successfully setup a management interface and streaming interface, you can now verify the devices operation using the include UHD utilities.&lt;br /&gt;
&lt;br /&gt;
===Subdevice Specification Mapping===&lt;br /&gt;
The USRP E320 contains 2 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF A&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;RF B&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
'''E320'''&lt;br /&gt;
* RF A = A:0&lt;br /&gt;
* RF B = A:1&lt;br /&gt;
&lt;br /&gt;
Additional details of UHD Subdevice Specifications can be found here in the UHD Manual: http://files.ettus.com/manual/page_configuration.html#config_subdev&lt;br /&gt;
&lt;br /&gt;
===Supported Sample Rates===&lt;br /&gt;
&lt;br /&gt;
The USRP E320 supports master clock rate from 200 kHz to 61.44 MHz and can be changed by adding &amp;lt;code&amp;gt;master_clock_rate=&amp;lt;rate&amp;gt;&amp;lt;/code&amp;gt; to the default UHD args. The default master clock rate is 16 MHz. &lt;br /&gt;
&lt;br /&gt;
Sample rates as delivered to/from the host computer for USRP devices are constrained to follow several important rules.&lt;br /&gt;
&lt;br /&gt;
It is important to understand that strictly-integer decimation and interpolation are used within USRP hardware to meet the requested sample rate requirements of the application at hand. That means that the desired sample rate must meet the requirement that master-clock-rate/desired-sample-rate be an integer ratio. Further, it is strongly desirable for that ratio to be even. This ratio is the decimation (down-conversion) or interpolation (up-conversion) factor. The decimation or interpolation factor may be between 1 and 1024. There are further constraints on the decimation or interpolation factor. If the decimation or interpolation factor exceeds 128, then it must be evenly divisible by 2. If the decimation or interpolation factor exceeds 256, then it must be evenly divisible by 4.&lt;br /&gt;
&lt;br /&gt;
Additional information on Sample Rates can be found here in the UHD Manual: http://files.ettus.com/manual/page_general.html#general_sampleratenotes&lt;br /&gt;
&lt;br /&gt;
===Probe the USRP E320===&lt;br /&gt;
The UHD utility &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt; provides detailed information of the USRP device.&lt;br /&gt;
&lt;br /&gt;
From your host computer, run the command &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ uhd_usrp_probe --args &amp;quot;addr=192.168.10.2&amp;quot;&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.10.2,type=e3xx,product=e320,serial=316E375,claimed=False,addr=192.168.10.2&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `product=e320,mgmt_addr=192.168.10.2'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1343 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1335 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000003320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: E300-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: ni-e320-316E375&lt;br /&gt;
|   |   eeprom_version: 2&lt;br /&gt;
|   |   mpm_version: 3.13.1.0-gd3b7e90a&lt;br /&gt;
|   |   pid: 58144&lt;br /&gt;
|   |   product: e320&lt;br /&gt;
|   |   rev: 2&lt;br /&gt;
|   |   rpc_connection: remote&lt;br /&gt;
|   |   serial: 316E375&lt;br /&gt;
|   |   type: e3xx&lt;br /&gt;
|   |   MPM Version: 1.2&lt;br /&gt;
|   |   FPGA Version: 3.0&lt;br /&gt;
|   |   RFNoC capable: Yes&lt;br /&gt;
|   |   &lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo&lt;br /&gt;
|   |   Clock sources: external, internal, gpsdo&lt;br /&gt;
|   |   Sensors: gps_locked, temp_main_power, ref_locked, temp_rf_channelA, temp_fpga, gps_sky, temp_rf_channelB, fan, temp_internal, gps_tpv, gps_time&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: RX2, TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature, rssi, lo_lock&lt;br /&gt;
|   |   |   |   Freq range: 70.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 76.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: RX2, TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature, rssi, lo_lock&lt;br /&gt;
|   |   |   |   Freq range: 70.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 76.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9361 Dual ADC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature&lt;br /&gt;
|   |   |   |   Freq range: 47.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 89.8 step 0.2 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature&lt;br /&gt;
|   |   |   |   Freq range: 47.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 89.8 step 0.2 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9361 Dual DAC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RFNoC blocks on this device:&lt;br /&gt;
|   |   |   &lt;br /&gt;
|   |   |   * DmaFIFO_0&lt;br /&gt;
|   |   |   * Radio_0&lt;br /&gt;
|   |   |   * DDC_0&lt;br /&gt;
|   |   |   * DUC_0&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ASCII Art Example===&lt;br /&gt;
The UHD driver includes several example programs, which may serve as test programs or the basis for your application program. The source code can be obtained from the UHD repository on github at: https://github.com/EttusResearch/uhd/tree/master/host/examples&lt;br /&gt;
&lt;br /&gt;
You can quickly verify the operation of your USRP E320 by running the &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; UHD example program.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; utility is a simple console ­based, real-time FFT display tool. It is not graphical in nature, so it can be easily run over an SSH connection within a terminal window, and does not need any graphical capability, such as X Windows, to be installed. It can also be run over a serial console connection, although this is not recommended, as the formatting may not render correctly.&lt;br /&gt;
&lt;br /&gt;
You can run a simple test of the E320 USRP by connecting an antenna and observing the spectrum of a commercial FM radio station in real-time, following the steps below:&lt;br /&gt;
&lt;br /&gt;
1. Attach an antenna to the &amp;lt;code&amp;gt;RF A / RX2&amp;lt;/code&amp;gt;­ antenna port of the E320.&lt;br /&gt;
&lt;br /&gt;
2. From your host computer, run the command:&lt;br /&gt;
&lt;br /&gt;
    $ /usr/local/lib/uhd/examples/rx_ascii_art_dft \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --freq 98.5e6 \&lt;br /&gt;
    --rate 2e6 \&lt;br /&gt;
    --gain 40 \&lt;br /&gt;
    --ref-lvl=&amp;quot;-30&amp;quot; \&lt;br /&gt;
    --dyn-rng 90 \&lt;br /&gt;
    --ant &amp;quot;RX2&amp;quot; \&lt;br /&gt;
    --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the command­line argument &amp;lt;code&amp;gt;freq&amp;lt;/code&amp;gt; ​above to specify a tuning frequency for a strong local FM radio station. You will also need to update the IP Address to match your device IP.&lt;br /&gt;
&lt;br /&gt;
3. You should see a real-time FFT display of 2 MHz of spectrum, centered at the specified tuning frequency.&lt;br /&gt;
&lt;br /&gt;
4. Type &amp;quot;&amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;&amp;quot; to stop the program and to return to the Linux command line.&lt;br /&gt;
&lt;br /&gt;
5. You can run with the &amp;lt;code&amp;gt;​­­--help&amp;lt;/code&amp;gt; ​argument to see a description of all available command-line options.&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ./rx_ascii_art_dft --args &amp;quot;addr=192.168.10.2&amp;quot; --freq 98.5e6 --rate 2e6 --gain 40 --ref-lvl=&amp;quot;-30&amp;quot; --dyn-rng 90 --ant &amp;quot;RX2&amp;quot; --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Creating the usrp device with: addr=192.168.10.2...&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.10.2,type=e3xx,product=e320,serial=316E375,claimed=False,addr=192.168.10.2&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1334 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1325 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000003320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `product=e320,mgmt_addr=192.168.10.2'.&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: E300-Series Device&lt;br /&gt;
  Mboard 0: ni-e320-316E375&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Neon&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Neon&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 1&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Neon&lt;br /&gt;
&lt;br /&gt;
Setting RX Rate: 2.000000 Msps...&lt;br /&gt;
Actual RX Rate: 2.000000 Msps...&lt;br /&gt;
&lt;br /&gt;
Setting RX Freq: 98.500000 MHz...&lt;br /&gt;
Actual RX Freq: 98.500000 MHz...&lt;br /&gt;
&lt;br /&gt;
Setting RX Gain: 40.000000 dB...&lt;br /&gt;
Actual RX Gain: 40.000000 dB...&lt;br /&gt;
&lt;br /&gt;
Checking RX: all_los: locked ...&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Benchmarking your system===&lt;br /&gt;
Included with the UHD driver example programs is a utility, &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; to benchmark the transport link of the system.&lt;br /&gt;
&lt;br /&gt;
A system's maximum performance is dependent upon many factors. &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; will exercise the transport link and CPU of the system.&lt;br /&gt;
&lt;br /&gt;
====1 Gb Interface====&lt;br /&gt;
NOTE: This example requires the &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RFA/A:0&amp;quot;, at a rate of 2 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 2e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 2e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 2 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 2e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 2e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 12.5 MS/s, for 60 seconds:&lt;br /&gt;
 &lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=25e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 12.5e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 12.5e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When streaming samples over a 1 Gb transport link, the maximum accumulative rate for all channels is 25 MS/s with a &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; OTW format. To achieve higher streaming rates, it is recommended to use the 10 Gb interfaces.&lt;br /&gt;
&lt;br /&gt;
====10 Gb Interface ====&lt;br /&gt;
NOTE: These examples require the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RFA/A:0&amp;quot;, at a rate of 61.44 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=61.44e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 61.44e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 61.44e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot; &lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex stream, at a rate of 30.72 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=61.44e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 30.72e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 30.72e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==USRP E320 Device Specific Operations==&lt;br /&gt;
&lt;br /&gt;
===Turning the Device Off/On===&lt;br /&gt;
To avoid damaging the file system and causing any corruption, do not turn the device off with the power button without first shutting down the system. Use this command to cleanly and properly shut the system down:&lt;br /&gt;
&lt;br /&gt;
    shutdown ­-h now&lt;br /&gt;
&lt;br /&gt;
=== Autoboot ===&lt;br /&gt;
&lt;br /&gt;
The USRP E320 can be configured to power on and boot automatically when power is applied. By default, autoboot is disabled on all USRPs that support it. To control autoboot on the USRP E320, first determine the current value for &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; by running &amp;lt;code&amp;gt;eeprom-dump&amp;lt;/code&amp;gt;. The least significant bit when &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; is viewed as a binary value controls the autoboot.&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-dump&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
shows &amp;lt;code&amp;gt;-- MCU_FLAGS[0]: 00000008&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;0x08&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00001000&amp;lt;/code&amp;gt; in binary) indicates that autoboot is disabled. If this value were &amp;lt;code&amp;gt;0x09&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00001001&amp;lt;/code&amp;gt; in binary) it would indicate that autoboot is enabled because least significant bit is 1; same would be true if this value is &amp;lt;code&amp;gt;0x01&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00000001&amp;lt;/code&amp;gt; in binary).&lt;br /&gt;
&lt;br /&gt;
To enable or disable autoboot, copy the existing value of &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; retrieved by &amp;lt;code&amp;gt;eeprom-dump&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;&amp;lt;MCU_FLAGS[0]&amp;gt;&amp;lt;/code&amp;gt; below and run the command:&lt;br /&gt;
&lt;br /&gt;
* Disable autoboot on USRP E320 (sets least significant bit to 0), regardless of whether currently enabled or disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x&amp;lt;MCU_FLAGS[0]&amp;gt; &amp;amp; ~0x1))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus, for the value noted above (autoboot is already disabled, so this command doesn't actually change anything):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x00000008 &amp;amp; ~0x1))&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
-- Reading back &lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: 448fb572 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable autoboot on USRP E320 (sets least significant bit to 1), regardless of whether currently enabled or disabled. For example when changing from autoboot disabled to enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x&amp;lt;MCU_FLAGS[0]&amp;gt; | 0x1))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus, for the value noted above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x00000008 | 0x1))&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
-- Reading back &lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000009&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: 448fb572 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If setting this flag ''does not'' allow autoboot control on the USRP E320, then the device boot firmware needs to be updated. This update is accomplished via the following instructions.&lt;br /&gt;
&lt;br /&gt;
On the USRP E320 via ssh or serial terminal, [https://files.ettus.com/binaries/misc/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6.tar.gz download the update MCU firmware] and extract it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# curl https://files.ettus.com/binaries/misc/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6.tar.gz | tar zxf -&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will create a directory &amp;lt;code&amp;gt;upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6&amp;lt;/code&amp;gt;. Go into this directory and run the firmware flash script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# cd upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6&lt;br /&gt;
root@ni-e320-XXXXXXX:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# ./flash-firmware.sh&lt;br /&gt;
This script updates the microcontroller firmware (RO part). The change is&lt;br /&gt;
persistent across power cycles. Incorrect updates can only fixed be a manual&lt;br /&gt;
process which requires opening the enclosure.&lt;br /&gt;
&lt;br /&gt;
Updating the microcontroller firmware (RO part) is only required if the Ettus&lt;br /&gt;
Research support told you to do so.&lt;br /&gt;
&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the prompt, press the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key to continue. Pressing any other key aborts the procedure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue n&lt;br /&gt;
&lt;br /&gt;
aborting&lt;br /&gt;
root@ni-e320-317F9BF:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Pressing the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue y&lt;br /&gt;
&lt;br /&gt;
This script will flash ec-neon-rev3.RO.flat to the device&lt;br /&gt;
old RO version:    neon_vX.X.XXXX-XXXXXXX&lt;br /&gt;
new RO version:    neon_v1.1.7358-a190641&lt;br /&gt;
&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the prompt, press the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key ''again'' to continue. Pressing any other key aborts the procedure as before.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue y&lt;br /&gt;
&lt;br /&gt;
./ectool --interface=dev reboot_ec RW&lt;br /&gt;
./ectool --interface=dev flashread 0x0 65536 ec-neon-rev3.RO.flat.old&lt;br /&gt;
Reading 65536 bytes at offset 0...&lt;br /&gt;
done.&lt;br /&gt;
./ectool --interface=dev flasherase 0x0 65536&lt;br /&gt;
Erasing 65536 bytes at offset 0...&lt;br /&gt;
done.&lt;br /&gt;
./ectool --interface=dev flashwrite 0x0 ec-neon-rev3.RO.flat&lt;br /&gt;
Reading 49592 bytes from ec-neon-rev3.RO.flat...&lt;br /&gt;
Writing to offset 0...&lt;br /&gt;
Write size 112...&lt;br /&gt;
done.&lt;br /&gt;
&lt;br /&gt;
copying new firmware files&lt;br /&gt;
'ec-neon-rev3.bin' -&amp;gt; '/lib/firmware/ni/ec-neon-rev3.bin'&lt;br /&gt;
'ec-neon-rev3.RW.bin' -&amp;gt; '/lib/firmware/ni/ec-neon-rev3.RW.bin'&lt;br /&gt;
root@ni-e320-317F9BF:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the script is done, reboot the USRP (e.g., &amp;lt;code&amp;gt;shutdown -r now&amp;lt;/code&amp;gt;), and when it comes up the autoboot flag should now work as desired. If these instructions ''do not'' work, then email [mailto:support@ettus.com support@ettus.com] and ask for alternative instructions on how to update the USRP E320 RO and RW boot firmware such that this EEPROM flag setting is honored.&lt;br /&gt;
&lt;br /&gt;
===Default Password===&lt;br /&gt;
The default user is &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; and the password is empty (no password).&lt;br /&gt;
&lt;br /&gt;
It is recommended to update the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password, which can be done with the command &amp;lt;code&amp;gt;passwd&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-serial:~# passwd&lt;br /&gt;
    Changing password for root&lt;br /&gt;
    New password:&lt;br /&gt;
    Re-enter new password:&lt;br /&gt;
    passwd: password changed.&lt;br /&gt;
&lt;br /&gt;
==Known Issues==&lt;br /&gt;
===Problematic NICs===&lt;br /&gt;
In some streaming modes, the Intel I219-LM NIC can produce flow control and sequence errors. It is recommended to use a USB3 to 1 Gb Ethernet Adapter for hosts which have an I219-LM NIC.&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:E320]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=E320_Getting_Started_Guide&amp;diff=5294</id>
		<title>E320 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=E320_Getting_Started_Guide&amp;diff=5294"/>
				<updated>2022-03-22T21:16:22Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Change SFP network port config file location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
&lt;br /&gt;
===E320 Board-only===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP E320&lt;br /&gt;
* Power connector (assembly required) &lt;br /&gt;
* 4 M3x0.5, M3x5 Standoffs &lt;br /&gt;
* 1 Gb Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* 1 Gb SFP+ to RJ45 Adapter&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
|[[File:e320 board only.jpg|500px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===E320 Full Enclosure===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* USRP E320 in enclosure &lt;br /&gt;
* DC Power Supply (12V, 7A)&lt;br /&gt;
* 1 Gb Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to Micro USB-B Cable (1m)&lt;br /&gt;
* 1 Gb SFP+ to RJ45 Adapter&lt;br /&gt;
* Getting Started Guide&lt;br /&gt;
* Ettus Research Sticker&lt;br /&gt;
* T8 Torx Wrench&lt;br /&gt;
|[[File:e320 enclosure kit.jpg|500px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Verify the Contents of Your Kit==&lt;br /&gt;
Ensure that your kit contains all the items listed above. If any items are missing, please contact sales@ettus.com​ immediately.&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
&lt;br /&gt;
* For Network Mode: A host computer with an 1 or 10 Gb Ethernet interface. If operating with the 10 Gb Ethernet interface, the &amp;quot;XG&amp;quot; FPGA image must be loaded before the SFP+ port will operate at 10 Gb speeds. Optionally a second 1 Gb Ethernet interface can be used to connect to the onboard ARM CPU for remote management. &lt;br /&gt;
&lt;br /&gt;
* For Embedded Mode: A host computer is only required for initial device configuration, remote control and management, or data visualization. The host computer can connect to the RJ45 1 Gb port or Serial Console port to remotely access the Open Embedded Linux operating system running on the ARM CPU. Once configured, the USRP E320 can operate as a stand-alone device without a connection to a remote host computer.  &lt;br /&gt;
&lt;br /&gt;
* For Board-only Version: A third-party 10-14V/3A power supply, which requires assembly with the power connect components included in the kit. An assembled power supply can be purchased here: https://www.ettus.com/product/details/12V-PWR&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow anything especially metal objects to touch the board while it is powered on. &lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
* Never touch the circuit board or heatsink while the device is powered on. &lt;br /&gt;
* All connections should be made/removed while is device is powered off. &lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than -15 dBm of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
&lt;br /&gt;
To use your Universal Software Radio Peripheral (USRP™), you must have software tools correctly installed and configured on your host computer. Step-by-step guides for these software tools are found in the Application Notes for Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]].&lt;br /&gt;
&lt;br /&gt;
The USRP E320 requires UHD version 3.13.0.2 or later. It is strongly​ recommended to use the latest stable release of UHD on both the host computer and the USRP via the filesystem on the SD card. If this release fails to work in some way, then try the maintenance branch of the latest stable version. If you are operating the device in Network Mode, the version of UHD running on the host machine and E320 USRP must match to within the same maintenance release and branch. See the [https://github.com/ettusresearch/uhd UHD GitHub repository] for the latest release and maintenance branch.&lt;br /&gt;
&lt;br /&gt;
==Connecting the Device==&lt;br /&gt;
===Interfaces Overview===&lt;br /&gt;
Listed below are the interfaces to connect to the USRP E320. Each interface has specific functionality, limitations and purpose.&lt;br /&gt;
&lt;br /&gt;
'''Serial Console'''&lt;br /&gt;
&lt;br /&gt;
The Serial Console provides a low-level interface to the ARM CPU and STM32 microcontroller, typically used for debugging. The serial console can also be used as a JTAG connection to the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''1 Gb RJ45 Connection'''&lt;br /&gt;
&lt;br /&gt;
The 1 Gb RJ45 Connection interfaces with the on-board ARM CPU. When operated in &amp;quot;Network mode&amp;quot;, this interface can optionally be used for remote control and management traffic. Regardless of the operation mode (Host vs Embedded) this interface can be used to connect to the ARM via SSH. By default, the 1 Gb RJ45 connection is configured to use a DHCP assigned IP address.&lt;br /&gt;
&lt;br /&gt;
'''SFP+ Connection'''&lt;br /&gt;
&lt;br /&gt;
The SFP+ Connection supports multiple interfaces for streaming high-speed, low-latency data, depending upon which FPGA image is loaded.&lt;br /&gt;
&lt;br /&gt;
===Setting up a Serial Console Connection===&lt;br /&gt;
It is possible to gain shell access to the device using a serial terminal emulator via the Serial Console port. Most Linux, OS X, or other Unix based operating systems have a utility called &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; which can be used for this purpose. &lt;br /&gt;
&lt;br /&gt;
If you do not have &amp;lt;code&amp;gt;screen&amp;lt;/code&amp;gt; installed, it can be installed via your distribution's package manager. For Ubuntu/Debian based operating systems it can be installed with the package manager &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; such as:&lt;br /&gt;
&lt;br /&gt;
    sudo apt install screen&lt;br /&gt;
&lt;br /&gt;
The default Baud Rate for the Serial Console is: &amp;lt;code&amp;gt;115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact device node you should attach to depends on your operating system's driver and other USB devices that might already be connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under &amp;lt;code&amp;gt;/dev/serial/by-id&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ ls /dev/serial/by-id&lt;br /&gt;
    usb-FTDI_Dual_RS232-HS-if00-port0&lt;br /&gt;
    usb-FTDI_Dual_RS232-HS-if01-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if00-port0&lt;br /&gt;
    usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if01-port0&lt;br /&gt;
&lt;br /&gt;
NOTE: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
Every E320 series device connected to USB will by default show up as four different devices. The devices labeled &amp;lt;code&amp;gt;&amp;quot;USB_to_UART_Bridge_Controller&amp;quot;&amp;lt;/code&amp;gt; are the devices that offer a serial prompt. The first (with the &amp;lt;code&amp;gt;if00&amp;lt;/code&amp;gt; suffix) connects to the &amp;lt;code&amp;gt;STM32 Microcontroller&amp;lt;/code&amp;gt;, whereas the second connects to the &amp;lt;code&amp;gt;ARM CPU&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you have multiple E320 Serial Consoles connected to a single host, you may have to empirically test nodes.&lt;br /&gt;
&lt;br /&gt;
Connecting to the ARM CPU can be performed with the command:&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen  /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if01-port0 115200&lt;br /&gt;
&lt;br /&gt;
Upon starting the USRP E320, boot messages will appear and rapidly update. Once the boot process successfully completes, a login prompt like the following should appear:&lt;br /&gt;
&lt;br /&gt;
    Alchemy 2018.04 ni-e320-serial ttyPS0&lt;br /&gt;
    ni-e320-serial login:&lt;br /&gt;
&lt;br /&gt;
Enter the username: ​&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;​&lt;br /&gt;
&lt;br /&gt;
By default, the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; user's password is left blank. Press the &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt; key when prompted for a password.&lt;br /&gt;
&lt;br /&gt;
You should now be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
Using the default configuration, the serial console will show all kernel log messages (which are not available when using SSH) and give access to the boot loader (U-boot prompt). This can be used to debug kernel or boot-loader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
===Connecting to the microcontroller===&lt;br /&gt;
&lt;br /&gt;
Using the Serial Console interface, it is possible to connect to the STM32 microcontroller with the command below. The STM32 controls the power sequencing and several other low-level device operations.&lt;br /&gt;
&lt;br /&gt;
    $ sudo screen  /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_007F6A69-if00-port0 115200&lt;br /&gt;
&lt;br /&gt;
The STM32 interface provides a very simple prompt. The command &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt; will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it (i.e., emulating a power button press) and other low-level diagnostics.&lt;br /&gt;
&lt;br /&gt;
===Connecting to the ARM via SSH===&lt;br /&gt;
By default, the RJ45 1 Gb management interface is configured to be assigned a DHCP IP address.&lt;br /&gt;
&lt;br /&gt;
If you have access to a network which provides a DHCP server (such as a common router's LAN), attach the RJ45 1 Gb port to this network. Details vary by vendor, however, most router management interfaces will provide a list of attached devices to the LAN including their IP address.&lt;br /&gt;
&lt;br /&gt;
Without access to a router management interface, you can identify the IP address by connecting to the ARM CPU via Serial Console as detailed in the section above and running the command &amp;lt;code&amp;gt;ip a&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ip a&lt;br /&gt;
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue qlen 1000&lt;br /&gt;
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;br /&gt;
    inet 127.0.0.1/8 scope host lo&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.1.151/24 brd 192.168.1.255 scope global dynamic eth0&lt;br /&gt;
       valid_lft 42865sec preferred_lft 42865sec&lt;br /&gt;
3: sfp0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 8000 qdisc pfifo_fast qlen 1000&lt;br /&gt;
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff&lt;br /&gt;
    inet 192.168.10.2/24 brd 192.168.10.255 scope global sfp0&lt;br /&gt;
       valid_lft forever preferred_lft forever&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do not have access to a network with a DHCP server, you can create one using the Linux utility &amp;lt;code&amp;gt;dnsmasq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    $ sudo dnsmasq -i &amp;lt;ETHERNET_ADAPTER_NAME&amp;gt; --dhcp-range=192.168.1.50,192.168.1.100 --except-interface=lo --bind-dynamic --no-daemon&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the value &amp;lt;code&amp;gt;&amp;lt;ETHERNET_ADAPTER_NAME&amp;gt;&amp;lt;/code&amp;gt; to match the interface you would like to create a DHCP server on.&lt;br /&gt;
&lt;br /&gt;
After the device has obtained an IP address, you can remotely log into it from a Linux or macOS systems with SSH, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ssh root@192.168.1.51&lt;br /&gt;
&lt;br /&gt;
NOTE: The IP address may vary depending on your network setup.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password is empty/blank.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the SSH connection can be established using the third-party program, such as ​PuTTY.&lt;br /&gt;
&lt;br /&gt;
After logging in, you should be presented with a shell prompt like the following:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-&amp;lt;motherboard serial #&amp;gt;:~#&lt;br /&gt;
&lt;br /&gt;
==Updating the Linux File System==&lt;br /&gt;
Before operating the device, it is​ ​strongly​ recommended to update to the latest version of the Embedded Linux file system. If you are operating the device in Network Mode, the version of UHD running on the host machine and E320 USRP must match. &lt;br /&gt;
&lt;br /&gt;
There is two ways to update the file system for the E320 USRP: &lt;br /&gt;
&lt;br /&gt;
1. Mender&lt;br /&gt;
&lt;br /&gt;
2. Physically remove microSD card from device and write a new file system to the microSD card. &lt;br /&gt;
&lt;br /&gt;
===File System Partition Layout===&lt;br /&gt;
The SD Card is divided into four partitions. There are two root file system partitions, a &amp;quot;boot&amp;quot; partition and a &amp;quot;data&amp;quot; partition. &lt;br /&gt;
&lt;br /&gt;
Any data you would like to preserve through Mender updates should be saved to the &amp;quot;data&amp;quot; partition, which is mounted at &amp;lt;code&amp;gt;/data&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Updating the file system with Mender===&lt;br /&gt;
Mender is third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website https://mender.io). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Users can host their own local Mender server, or use servers hosted by Mender as a paid service; contact Mender for more information. &lt;br /&gt;
&lt;br /&gt;
====Mender Update Process====&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted. Any data stored in the root partitions will be permanently lost with a Mender update.&lt;br /&gt;
&lt;br /&gt;
After updating a partition with Mender, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched, which presumably is in a working state. Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To obtain the file system Mender image (these are files with a &amp;lt;code&amp;gt;.mender&amp;lt;/code&amp;gt; suffix), run the following command on the host computer with Internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader -t mender -t e320 --yes&lt;br /&gt;
&lt;br /&gt;
Example Output:    &lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    395769 kB / 395769 kB (100%) e3xx_e320_mender_default-v3.13.1.0.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
NOTE: In the output of the command, the folder destination where the images are saved is printed out.&lt;br /&gt;
&lt;br /&gt;
Next, you will need to copy this Mender file system image to the USRP E320. This can be done with the Linux utility &amp;lt;code&amp;gt;scp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ scp /usr/local/share/uhd/images/usrp_e320_fs.mender root@192.168.1.51:~/. &lt;br /&gt;
&lt;br /&gt;
Note: The path and IP may different for your configuration, the command above assumes you're using the default installation path of &amp;lt;code&amp;gt;/usr/local&amp;lt;/code&amp;gt; and that the E320's IP is &amp;lt;code&amp;gt;192.168.1.51&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
After copying the Mender file system image to the E320, connect to the E320 using either the Serial Console, or via SSH to gain shell access.&lt;br /&gt;
&lt;br /&gt;
On the E320, run &amp;lt;code&amp;gt;mender -rootfs /path/to/latest.mender&amp;lt;/code&amp;gt; to update the file system:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-serial:~# mender -rootfs /home/root/usrp_e320_fs.mender&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-316E375:~# mender -rootfs /home/root/usrp_e320_fs.mender                       &lt;br /&gt;
INFO[0000] Start updating from local image file: [/home/root/usrp_e320_fs.mender]  module=rootfs&lt;br /&gt;
Installing update from the artifact of size 399640064&lt;br /&gt;
INFO[0000] opening device /dev/mmcblk0p3 for writing     module=block_device&lt;br /&gt;
INFO[0000] partition /dev/mmcblk0p3 size: 2046820352     module=block_device&lt;br /&gt;
................................   0% 1024 KiB&lt;br /&gt;
................................   0% 2048 KiB&lt;br /&gt;
................................   0% 3072 KiB&lt;br /&gt;
[truncated for readability]&lt;br /&gt;
................................  99% 389120 KiB&lt;br /&gt;
................................  99% 390144 KiB&lt;br /&gt;
................................ 100% 390273 KiB&lt;br /&gt;
INFO[0740] wrote 2046820352/2046820352 bytes of update to device /dev/mmcblk0p3  module=device&lt;br /&gt;
INFO[0744] Enabling partition with new image installed to be a boot candidate: 3  module=device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
    $ mender -rootfs &amp;lt;http://server.name/path/to/latest.mender&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a few minutes to complete. After mender has logged a successful update, reboot the device:&lt;br /&gt;
    $ reboot&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so that the boot loader knows to permanently boot into this partition:&lt;br /&gt;
    $ mender -commit&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried on the E320:&lt;br /&gt;
    $ cat /etc/mender/artifact_info&lt;br /&gt;
&lt;br /&gt;
If you are using a Mender server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and you can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
For more information on updating the file-system, refer to the UHD Manual at ​http://uhd.ettus.com​.&lt;br /&gt;
&lt;br /&gt;
===Updating the files system by writing the disk image===&lt;br /&gt;
The microSD card is accessible directly on the Board-only version of the E320 USRP. The E320 Full Enclosure version must be opened with the included Torx wrench. &lt;br /&gt;
&lt;br /&gt;
NOTE: This method will overwrite all data saved on the microSD card, including any data saved to the &amp;lt;code&amp;gt;/data&amp;lt;/code&amp;gt; partition.&lt;br /&gt;
&lt;br /&gt;
Please see the separate application note, [[Writing the USRP File System Disk Image to a SD Card]], for step-by-step instructions on writing the file system image to the microSD card.&lt;br /&gt;
&lt;br /&gt;
==Updating the Network Configurations==&lt;br /&gt;
The USRP E320 systemd network configuration files are located at: &amp;lt;code&amp;gt;/data/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    # ls /data/network/&lt;br /&gt;
    eth0.network  sfp0.network &lt;br /&gt;
&lt;br /&gt;
For details on configuration please refer to the [https://www.freedesktop.org/software/systemd/man/systemd.network.html systemd-networkd manual pages].&lt;br /&gt;
&lt;br /&gt;
The factory settings are as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
eth0 (DHCP):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=eth0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    DHCP=v4&lt;br /&gt;
&lt;br /&gt;
    [DHCPv4]&lt;br /&gt;
    UseHostname=false&lt;br /&gt;
&lt;br /&gt;
sfp0 (static):&lt;br /&gt;
&lt;br /&gt;
    [Match]&lt;br /&gt;
    Name=sfp0&lt;br /&gt;
&lt;br /&gt;
    [Network]&lt;br /&gt;
    Address=192.168.10.2/24&lt;br /&gt;
&lt;br /&gt;
    [Link]&lt;br /&gt;
    MTUBytes=8000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional notes on networking:&lt;br /&gt;
&lt;br /&gt;
* Care needs to be taken when editing these files on the device, since &amp;lt;code&amp;gt;vi&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;vim&amp;lt;/code&amp;gt; sometimes generates undo files (e.g. &amp;lt;code&amp;gt;/data/network/sfp0.network~&amp;lt;/code&amp;gt;), that &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt; might accidentally pick up.&lt;br /&gt;
* Temporarily setting the IP addresses or MTU sizes via &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; or other command line tools will only change the value until the next reboot or reload of the FPGA image.&lt;br /&gt;
* If the MTU of the device and host computers differ, streaming issues can occur.&lt;br /&gt;
* Streaming via SFP0 at 1 Gb rates requires a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt;&lt;br /&gt;
* Streaming via SFP0 at 10 Gb rates requires a MTU of &amp;lt;code&amp;gt;8000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For addition details on network configuration here: https://files.ettus.com/manual/page_usrp_e320.html#e320_network_configuration&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA Image==&lt;br /&gt;
&lt;br /&gt;
===Network mode FPGA Image Update===&lt;br /&gt;
The FPGA image should match the version of UHD installed on the host computer when operated in Network mode. &lt;br /&gt;
&lt;br /&gt;
Network mode FPGA image updates must be made through the RJ45 management interface.&lt;br /&gt;
&lt;br /&gt;
To obtain all the FPGA images for your installed version of UHD, run the following command on the host computer with internet access:&lt;br /&gt;
&lt;br /&gt;
    $ sudo uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
    [INFO] Images destination: /usr/local/share/uhd/images&lt;br /&gt;
    [INFO] No inventory file found at /usr/local/share/uhd/images/inventory.json. Creating an empty one.&lt;br /&gt;
    05920 kB / 05920 kB (100%) e3xx_e320_fpga_default-g494ae8bb.zip&lt;br /&gt;
    [INFO] Images download complete.&lt;br /&gt;
&lt;br /&gt;
There is two versions of the E320 FPGA images shipped with UHD:&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; for 1 Gb rates on the SFP+ port (default image)&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; for 10 Gb rates on the SFP+ port&lt;br /&gt;
&lt;br /&gt;
In this example, we load the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; variant of the FPGA image.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=e3xx,mgmt_addr=&amp;lt;E320_RJ45_IP_ADDR&amp;gt;,fpga=XG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;mgmt_addr=192.168.1.51,type=e3xx,fpga=XG&amp;quot;&lt;br /&gt;
    [INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
    [INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.1.51,type=e3xx,product=e320,serial=316E375,claimed=False,skip_init=1&lt;br /&gt;
    [INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
    [INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Device serial number: 316E375&lt;br /&gt;
    [INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
    [INFO] [MPM.PeriphManager] Found 1 daughterboard(s).&lt;br /&gt;
&lt;br /&gt;
The FPGA is immediately updated, and this FPGA image will continue to be used. The device does not need to be power cycled to use the new image. &lt;br /&gt;
&lt;br /&gt;
To load a different FPGA image (i.e. &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt;), modify the device argument &amp;lt;code&amp;gt;fpga=&amp;lt;/code&amp;gt; to a value of &amp;lt;code&amp;gt;fpga=1G&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To specify the path to a custom FPGA image, use the ​&amp;lt;code&amp;gt;--fpga-path&amp;lt;/code&amp;gt;​ argument.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=e3xx,mgmt_addr=&amp;lt;E320_RJ45_IP_ADDR&amp;gt;&amp;quot; --fpga-path=/path/to/custom/fpga.bit&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |The Verilog code for the FPGA in the USRP E320 is open-source, and users are free to modify and customize it for their needs. However, certain modifications may result in either bricking the device, or even in physical damage to the unit. Please note that modifications to the FPGA are made at the risk of the user, and may not be covered by the warranty of the device.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Embedded Mode FPGA Image Update===&lt;br /&gt;
&lt;br /&gt;
It is possible to update the FPGA image when operated in Embedded mode. Connect to the ARM CPU [[#Setting_up_a_Serial_Console_Connection|via Serial Console]] or [[E320_Getting_Started_Guide#Connecting_to_the_ARM_via_SSH| via SSH]]. It is generally recommend to use SSH over the RJ45 interface for remote management. &lt;br /&gt;
&lt;br /&gt;
Run the command &amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt; to download the FPGA images to the device's file system:&lt;br /&gt;
&lt;br /&gt;
NOTE: The 1 Gb RJ45 management interface will require Internet access for this next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-serial:~# python3 /usr/bin/uhd_images_downloader -t e320 -t fpga&lt;br /&gt;
[INFO] Images destination: /usr/share/uhd/images&lt;br /&gt;
[INFO] No inventory file found at /usr/share/uhd/images/inventory.json. Creating an empty one.&lt;br /&gt;
05920 kB / 05920 kB (100%) e3xx_e320_fpga_default-g494ae8bb.zip&lt;br /&gt;
[INFO] Images download complete.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: The default UHD FPGA Images destination within the E320's file-system is &amp;lt;code&amp;gt;/usr/share/uhd/images&amp;lt;/code&amp;gt;. The default UHD FPGA Images destination on a typical host installation is &amp;lt;code&amp;gt;/usr/local/share/uhd/images&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Updating the FPGA image from the ARM CPU is the same as detailed above for a Network mode update:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-serial:~# uhd_image_loader --args &amp;quot;type=e3xx,fpga=1G&amp;quot;&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 7.3.0; Boost_106600; UHD_3.13.1.0-0-unknown&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=127.0.0.1,type=e3xx,product=e320,serial=316E375,claimed=False,skip_init=1&lt;br /&gt;
[INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
[INFO] [MPM.PeriphManager.UDP] No CHDR interfaces found!&lt;br /&gt;
[INFO] [MPMD] Claimed device without full initialization.&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Starting update. This may take a while.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `fpga'&lt;br /&gt;
[INFO] [MPM.PeriphManager] Updating component `dts'&lt;br /&gt;
[INFO] [MPM.RPCServer] Resetting peripheral manager.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Device serial number: 316E375&lt;br /&gt;
[INFO] [MPMD IMAGE LOADER] Update component function succeeded.&lt;br /&gt;
[INFO] [MPM.PeriphManager] Found 1 daughterboard(s).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on updating the FPGA image, refer to the UHD Manual at http://uhd.ettus.com​.&lt;br /&gt;
&lt;br /&gt;
==Setting Up a Streaming Connection==&lt;br /&gt;
The device supports multiple high-speed, low-latency interfaces on the SFP+ port for streaming samples to the host computer.&lt;br /&gt;
&lt;br /&gt;
===1 Gb Streaming via SFP+ Port ===&lt;br /&gt;
Complete the steps below to set up a streaming connection over the 1 Gb Ethernet interface on the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; FPGA image must be loaded for the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; to operate at 1 Gb speeds. If the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 1Gb speeds.&lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's 1 Gb Ethernet interface as shown below. This interface should be separate from the 1 Gb NIC/network which is connected to the 1 Gb RJ45 management interface. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 1500&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; at 1 Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;1500&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;. Mismatched MTU values on either the Host or E320 may cause flow control errors. Your computer may need to be restarted for the MTU value to take effect.&lt;br /&gt;
&lt;br /&gt;
2. Insert the RJ45-to-SFP+ adapter ​into the​ &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​.&lt;br /&gt;
&lt;br /&gt;
3. Connect the SFP+ adapter on the device to an Ethernet port on the host computer using a standard Ethernet cable.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above the ​&amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
    PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.&lt;br /&gt;
    64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=1.06 ms&lt;br /&gt;
    ^C&lt;br /&gt;
    --- 192.168.10.2 ping statistics ---&lt;br /&gt;
    1 packets transmitted, 1 received, 0% packet loss, time 0ms&lt;br /&gt;
    rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms&lt;br /&gt;
    &lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program.&lt;br /&gt;
&lt;br /&gt;
5. Verify your MTU is set correctly for 1 Gb speeds on the E320. See the section [[E320_Getting_Started_Guide#Updating_the_Network_Configurations|Updating the Network Configurations]] for additional details.&lt;br /&gt;
&lt;br /&gt;
Proceed to the next section [[E320_Getting_Started_Guide#Verifying_Device_Operation|Verifying Device Operation]].&lt;br /&gt;
&lt;br /&gt;
===10 Gb Streaming via SFP+ Port===&lt;br /&gt;
Load the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image for 10 Gb streaming as detailed in the section [[E320_Getting_Started_Guide#Updating_the_FPGA_Image|Updating the FPGA Image]]. You will need to use a 10 GigE cable that can be plugged in directly to the SFP+ connector on the board. &lt;br /&gt;
&lt;br /&gt;
NOTE: The &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image must be loaded for the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; to operate at 10 Gb speeds. If the &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; image is loaded, the port will be unresponsive at 10 Gb speeds. Mismatched MTU values on either the Host or E320 may cause flow control errors.&lt;br /&gt;
&lt;br /&gt;
1. Configure your Host's 10 Gb Ethernet interface as shown below. &lt;br /&gt;
&lt;br /&gt;
    IP Address: 192.168.10.1&lt;br /&gt;
    Subnet Mask: 255.255.255.0&lt;br /&gt;
    Gateway: 0.0.0.0&lt;br /&gt;
    MTU: 8000&lt;br /&gt;
&lt;br /&gt;
NOTE: When operating the &amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt; at 10 Gb speeds, it is important to set a MTU of &amp;lt;code&amp;gt;8000&amp;lt;/code&amp;gt; and not a value of &amp;lt;code&amp;gt;automatic&amp;lt;/code&amp;gt;. Mismatched MTU values on either the Host or E320 may cause flow control errors. Your computer may need to be restarted for the MTU value to take effect.&lt;br /&gt;
&lt;br /&gt;
2. Connect the SFP+ port on the device to an Ethernet port on the host computer using a 10 Gb SFP+ copper or fiber cable.&lt;br /&gt;
&lt;br /&gt;
The ​ Green LED​ above the ​&amp;lt;code&amp;gt;SFP+ Port&amp;lt;/code&amp;gt;​ should illuminate.&lt;br /&gt;
&lt;br /&gt;
4. To test the connection,​ ​&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;​ the device at address &amp;lt;code&amp;gt;192.168.10.2​&amp;lt;/code&amp;gt; from the host, as shown below:&lt;br /&gt;
&lt;br /&gt;
    $ ping 192.168.10.2&lt;br /&gt;
    PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.&lt;br /&gt;
    64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=1.06 ms&lt;br /&gt;
    ^C&lt;br /&gt;
    --- 192.168.10.2 ping statistics ---&lt;br /&gt;
    1 packets transmitted, 1 received, 0% packet loss, time 0ms&lt;br /&gt;
    rtt min/avg/max/mdev = 1.065/1.065/1.065/0.000 ms&lt;br /&gt;
    &lt;br /&gt;
Press &amp;lt;code&amp;gt;CTRL+C&amp;lt;/code&amp;gt; to stop the ping program.&lt;br /&gt;
&lt;br /&gt;
5. Verify your MTU is set correctly for 10 Gb speeds on the E320. See the section [[E320_Getting_Started_Guide#Updating_the_Network_Configurations|Updating the Network Configurations]] for additional details.&lt;br /&gt;
&lt;br /&gt;
Proceed to the next section [[E320_Getting_Started_Guide#Verifying_Device_Operation|Verifying Device Operation]].&lt;br /&gt;
&lt;br /&gt;
==Verifying Device Operation==&lt;br /&gt;
Once you have successfully setup a management interface and streaming interface, you can now verify the devices operation using the include UHD utilities.&lt;br /&gt;
&lt;br /&gt;
===Subdevice Specification Mapping===&lt;br /&gt;
The USRP E320 contains 2 channels, each represented on the front panel as &amp;lt;code&amp;gt;RF A&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;RF B&amp;lt;/code&amp;gt;. Below is the &amp;lt;code&amp;gt;subdev&amp;lt;/code&amp;gt; mapping of RF Ports.&lt;br /&gt;
&lt;br /&gt;
'''E320'''&lt;br /&gt;
* RF A = A:0&lt;br /&gt;
* RF B = A:1&lt;br /&gt;
&lt;br /&gt;
Additional details of UHD Subdevice Specifications can be found here in the UHD Manual: http://files.ettus.com/manual/page_configuration.html#config_subdev&lt;br /&gt;
&lt;br /&gt;
===Supported Sample Rates===&lt;br /&gt;
&lt;br /&gt;
The USRP E320 supports master clock rate from 200 kHz to 61.44 MHz and can be changed by adding &amp;lt;code&amp;gt;master_clock_rate=&amp;lt;rate&amp;gt;&amp;lt;/code&amp;gt; to the default UHD args. The default master clock rate is 16 MHz. &lt;br /&gt;
&lt;br /&gt;
Sample rates as delivered to/from the host computer for USRP devices are constrained to follow several important rules.&lt;br /&gt;
&lt;br /&gt;
It is important to understand that strictly-integer decimation and interpolation are used within USRP hardware to meet the requested sample rate requirements of the application at hand. That means that the desired sample rate must meet the requirement that master-clock-rate/desired-sample-rate be an integer ratio. Further, it is strongly desirable for that ratio to be even. This ratio is the decimation (down-conversion) or interpolation (up-conversion) factor. The decimation or interpolation factor may be between 1 and 1024. There are further constraints on the decimation or interpolation factor. If the decimation or interpolation factor exceeds 128, then it must be evenly divisible by 2. If the decimation or interpolation factor exceeds 256, then it must be evenly divisible by 4.&lt;br /&gt;
&lt;br /&gt;
Additional information on Sample Rates can be found here in the UHD Manual: http://files.ettus.com/manual/page_general.html#general_sampleratenotes&lt;br /&gt;
&lt;br /&gt;
===Probe the USRP E320===&lt;br /&gt;
The UHD utility &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt; provides detailed information of the USRP device.&lt;br /&gt;
&lt;br /&gt;
From your host computer, run the command &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ uhd_usrp_probe --args &amp;quot;addr=192.168.10.2&amp;quot;&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.10.2,type=e3xx,product=e320,serial=316E375,claimed=False,addr=192.168.10.2&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `product=e320,mgmt_addr=192.168.10.2'.&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1343 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1335 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000003320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: E300-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: ni-e320-316E375&lt;br /&gt;
|   |   eeprom_version: 2&lt;br /&gt;
|   |   mpm_version: 3.13.1.0-gd3b7e90a&lt;br /&gt;
|   |   pid: 58144&lt;br /&gt;
|   |   product: e320&lt;br /&gt;
|   |   rev: 2&lt;br /&gt;
|   |   rpc_connection: remote&lt;br /&gt;
|   |   serial: 316E375&lt;br /&gt;
|   |   type: e3xx&lt;br /&gt;
|   |   MPM Version: 1.2&lt;br /&gt;
|   |   FPGA Version: 3.0&lt;br /&gt;
|   |   RFNoC capable: Yes&lt;br /&gt;
|   |   &lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo&lt;br /&gt;
|   |   Clock sources: external, internal, gpsdo&lt;br /&gt;
|   |   Sensors: gps_locked, temp_main_power, ref_locked, temp_rf_channelA, temp_fpga, gps_sky, temp_rf_channelB, fan, temp_internal, gps_tpv, gps_time&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: RX2, TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature, rssi, lo_lock&lt;br /&gt;
|   |   |   |   Freq range: 70.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 76.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: RX2, TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature, rssi, lo_lock&lt;br /&gt;
|   |   |   |   Freq range: 70.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 76.0 step 1.0 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       RX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9361 Dual ADC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       TX Dboard: A&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 0&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature&lt;br /&gt;
|   |   |   |   Freq range: 47.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 89.8 step 0.2 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Frontend: 1&lt;br /&gt;
|   |   |   |   Name: Neon&lt;br /&gt;
|   |   |   |   Antennas: TX/RX&lt;br /&gt;
|   |   |   |   Sensors: lo_locked, ad9361_temperature&lt;br /&gt;
|   |   |   |   Freq range: 47.000 to 6000.000 MHz&lt;br /&gt;
|   |   |   |   Gain range PGA: 0.0 to 89.8 step 0.2 dB&lt;br /&gt;
|   |   |   |   Bandwidth range: 20000000.0 to 40000000.0 step 0.0 Hz&lt;br /&gt;
|   |   |   |   Connection Type: IQ&lt;br /&gt;
|   |   |   |   Uses LO offset: No&lt;br /&gt;
|   |   |     _____________________________________________________&lt;br /&gt;
|   |   |    /&lt;br /&gt;
|   |   |   |       TX Codec: A&lt;br /&gt;
|   |   |   |   Name: AD9361 Dual DAC&lt;br /&gt;
|   |   |   |   Gain Elements: None&lt;br /&gt;
|   |     _____________________________________________________&lt;br /&gt;
|   |    /&lt;br /&gt;
|   |   |       RFNoC blocks on this device:&lt;br /&gt;
|   |   |   &lt;br /&gt;
|   |   |   * DmaFIFO_0&lt;br /&gt;
|   |   |   * Radio_0&lt;br /&gt;
|   |   |   * DDC_0&lt;br /&gt;
|   |   |   * DUC_0&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ASCII Art Example===&lt;br /&gt;
The UHD driver includes several example programs, which may serve as test programs or the basis for your application program. The source code can be obtained from the UHD repository on github at: https://github.com/EttusResearch/uhd/tree/master/host/examples&lt;br /&gt;
&lt;br /&gt;
You can quickly verify the operation of your USRP E320 by running the &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; UHD example program.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rx_ascii_art_dft&amp;lt;/code&amp;gt; utility is a simple console ­based, real-time FFT display tool. It is not graphical in nature, so it can be easily run over an SSH connection within a terminal window, and does not need any graphical capability, such as X Windows, to be installed. It can also be run over a serial console connection, although this is not recommended, as the formatting may not render correctly.&lt;br /&gt;
&lt;br /&gt;
You can run a simple test of the E320 USRP by connecting an antenna and observing the spectrum of a commercial FM radio station in real-time, following the steps below:&lt;br /&gt;
&lt;br /&gt;
1. Attach an antenna to the &amp;lt;code&amp;gt;RF A / RX2&amp;lt;/code&amp;gt;­ antenna port of the E320.&lt;br /&gt;
&lt;br /&gt;
2. From your host computer, run the command:&lt;br /&gt;
&lt;br /&gt;
    $ /usr/local/lib/uhd/examples/rx_ascii_art_dft \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --freq 98.5e6 \&lt;br /&gt;
    --rate 2e6 \&lt;br /&gt;
    --gain 40 \&lt;br /&gt;
    --ref-lvl=&amp;quot;-30&amp;quot; \&lt;br /&gt;
    --dyn-rng 90 \&lt;br /&gt;
    --ant &amp;quot;RX2&amp;quot; \&lt;br /&gt;
    --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
NOTE: Modify the command­line argument &amp;lt;code&amp;gt;freq&amp;lt;/code&amp;gt; ​above to specify a tuning frequency for a strong local FM radio station. You will also need to update the IP Address to match your device IP.&lt;br /&gt;
&lt;br /&gt;
3. You should see a real-time FFT display of 2 MHz of spectrum, centered at the specified tuning frequency.&lt;br /&gt;
&lt;br /&gt;
4. Type &amp;quot;&amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;&amp;quot; to stop the program and to return to the Linux command line.&lt;br /&gt;
&lt;br /&gt;
5. You can run with the &amp;lt;code&amp;gt;​­­--help&amp;lt;/code&amp;gt; ​argument to see a description of all available command-line options.&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ./rx_ascii_art_dft --args &amp;quot;addr=192.168.10.2&amp;quot; --freq 98.5e6 --rate 2e6 --gain 40 --ref-lvl=&amp;quot;-30&amp;quot; --dyn-rng 90 --ant &amp;quot;RX2&amp;quot; --subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Creating the usrp device with: addr=192.168.10.2...&lt;br /&gt;
[INFO] [UHD] linux; GNU C++ version 5.4.0 20160609; Boost_105800; UHD_3.13.1.0-1-gd3b7e90a&lt;br /&gt;
[INFO] [MPMD] Initializing 1 device(s) in parallel with args: mgmt_addr=192.168.10.2,type=e3xx,product=e320,serial=316E375,claimed=False,addr=192.168.10.2&lt;br /&gt;
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1334 MB/s)&lt;br /&gt;
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1325 MB/s)&lt;br /&gt;
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000003320)&lt;br /&gt;
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)&lt;br /&gt;
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000002)&lt;br /&gt;
[INFO] [MPM.PeriphManager] init() called with device args `product=e320,mgmt_addr=192.168.10.2'.&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
[INFO] [0/Radio_0] Performing CODEC loopback test... &lt;br /&gt;
[INFO] [0/Radio_0] CODEC loopback test passed&lt;br /&gt;
Using Device: Single USRP:&lt;br /&gt;
  Device: E300-Series Device&lt;br /&gt;
  Mboard 0: ni-e320-316E375&lt;br /&gt;
  RX Channel: 0&lt;br /&gt;
    RX DSP: 0&lt;br /&gt;
    RX Dboard: A&lt;br /&gt;
    RX Subdev: Neon&lt;br /&gt;
  TX Channel: 0&lt;br /&gt;
    TX DSP: 0&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Neon&lt;br /&gt;
  TX Channel: 1&lt;br /&gt;
    TX DSP: 1&lt;br /&gt;
    TX Dboard: A&lt;br /&gt;
    TX Subdev: Neon&lt;br /&gt;
&lt;br /&gt;
Setting RX Rate: 2.000000 Msps...&lt;br /&gt;
Actual RX Rate: 2.000000 Msps...&lt;br /&gt;
&lt;br /&gt;
Setting RX Freq: 98.500000 MHz...&lt;br /&gt;
Actual RX Freq: 98.500000 MHz...&lt;br /&gt;
&lt;br /&gt;
Setting RX Gain: 40.000000 dB...&lt;br /&gt;
Actual RX Gain: 40.000000 dB...&lt;br /&gt;
&lt;br /&gt;
Checking RX: all_los: locked ...&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Benchmarking your system===&lt;br /&gt;
Included with the UHD driver example programs is a utility, &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; to benchmark the transport link of the system.&lt;br /&gt;
&lt;br /&gt;
A system's maximum performance is dependent upon many factors. &amp;lt;code&amp;gt;benchmark_rate&amp;lt;/code&amp;gt; will exercise the transport link and CPU of the system.&lt;br /&gt;
&lt;br /&gt;
====1 Gb Interface====&lt;br /&gt;
NOTE: This example requires the &amp;lt;code&amp;gt;1G&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RFA/A:0&amp;quot;, at a rate of 2 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 2e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 2e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 2 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 2e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 2e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex streams at 12.5 MS/s, for 60 seconds:&lt;br /&gt;
 &lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=25e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 12.5e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 12.5e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When streaming samples over a 1 Gb transport link, the maximum accumulative rate for all channels is 25 MS/s with a &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; OTW format. To achieve higher streaming rates, it is recommended to use the 10 Gb interfaces.&lt;br /&gt;
&lt;br /&gt;
====10 Gb Interface ====&lt;br /&gt;
NOTE: These examples require the &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; FPGA image to be loaded.&lt;br /&gt;
&lt;br /&gt;
This example will test one full-duplex stream using &amp;quot;RFA/A:0&amp;quot;, at a rate of 61.44 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=61.44e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0&amp;quot; \&lt;br /&gt;
    --rx_rate 61.44e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0&amp;quot; \&lt;br /&gt;
    --tx_rate 61.44e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0&amp;quot; &lt;br /&gt;
&lt;br /&gt;
This example will test two full-duplex stream, at a rate of 30.72 MS/s, for 60 seconds:&lt;br /&gt;
&lt;br /&gt;
    /usr/local/lib/uhd/examples/benchmark_rate  \&lt;br /&gt;
    --args &amp;quot;addr=192.168.10.2,master_clock_rate=61.44e6&amp;quot; \&lt;br /&gt;
    --duration 60 \&lt;br /&gt;
    --channels &amp;quot;0,1&amp;quot; \&lt;br /&gt;
    --rx_rate 30.72e6 \&lt;br /&gt;
    --rx_subdev &amp;quot;A:0 A:1&amp;quot; \&lt;br /&gt;
    --tx_rate 30.72e6 \&lt;br /&gt;
    --tx_subdev &amp;quot;A:0 A:1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==USRP E320 Device Specific Operations==&lt;br /&gt;
&lt;br /&gt;
===Turning the Device Off/On===&lt;br /&gt;
To avoid damaging the file system and causing any corruption, do not turn the device off with the power button without first shutting down the system. Use this command to cleanly and properly shut the system down:&lt;br /&gt;
&lt;br /&gt;
    shutdown ­-h now&lt;br /&gt;
&lt;br /&gt;
=== Autoboot ===&lt;br /&gt;
&lt;br /&gt;
The USRP E320 can be configured to power on and boot automatically when power is applied. By default, autoboot is disabled on all USRPs that support it. To control autoboot on the USRP E320, first determine the current value for &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; by running &amp;lt;code&amp;gt;eeprom-dump&amp;lt;/code&amp;gt;. The least significant bit when &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; is viewed as a binary value controls the autoboot.&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-dump&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
shows &amp;lt;code&amp;gt;-- MCU_FLAGS[0]: 00000008&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;0x08&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00001000&amp;lt;/code&amp;gt; in binary) indicates that autoboot is disabled. If this value were &amp;lt;code&amp;gt;0x09&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00001001&amp;lt;/code&amp;gt; in binary) it would indicate that autoboot is enabled because least significant bit is 1; same would be true if this value is &amp;lt;code&amp;gt;0x01&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;0b00000001&amp;lt;/code&amp;gt; in binary).&lt;br /&gt;
&lt;br /&gt;
To enable or disable autoboot, copy the existing value of &amp;lt;code&amp;gt;MCU_FLAGS[0]&amp;lt;/code&amp;gt; retrieved by &amp;lt;code&amp;gt;eeprom-dump&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;&amp;lt;MCU_FLAGS[0]&amp;gt;&amp;lt;/code&amp;gt; below and run the command:&lt;br /&gt;
&lt;br /&gt;
* Disable autoboot on USRP E320 (sets least significant bit to 0), regardless of whether currently enabled or disabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x&amp;lt;MCU_FLAGS[0]&amp;gt; &amp;amp; ~0x1))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus, for the value noted above (autoboot is already disabled, so this command doesn't actually change anything):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x00000008 &amp;amp; ~0x1))&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
-- Reading back &lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: 448fb572 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Enable autoboot on USRP E320 (sets least significant bit to 1), regardless of whether currently enabled or disabled. For example when changing from autoboot disabled to enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x&amp;lt;MCU_FLAGS[0]&amp;gt; | 0x1))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Thus, for the value noted above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# eeprom-set-flags $((0x00000008 | 0x1))&lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000008&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: cbd79a61 (matches)&lt;br /&gt;
-- Reading back &lt;br /&gt;
-- PID/REV: e320 0002&lt;br /&gt;
-- MCU_FLAGS[0]: 00000009&lt;br /&gt;
-- MCU_FLAGS[1]: 00000000&lt;br /&gt;
-- MCU_FLAGS[2]: 00000000&lt;br /&gt;
-- MCU_FLAGS[3]: 00000000&lt;br /&gt;
-- Serial: XXXXXXX&lt;br /&gt;
-- eth_addr0: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr1: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- eth_addr2: XX:XX:XX:XX:XX:XX&lt;br /&gt;
-- DT-Compat/MCU-Compat: 0000 0002&lt;br /&gt;
-- CRC: 448fb572 (matches)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If setting this flag ''does not'' allow autoboot control on the USRP E320, then the device boot firmware needs to be updated. This update is accomplished via the following instructions.&lt;br /&gt;
&lt;br /&gt;
On the USRP E320 via ssh or serial terminal, [https://files.ettus.com/binaries/misc/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6.tar.gz download the update MCU firmware] and extract it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# curl https://files.ettus.com/binaries/misc/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6.tar.gz | tar zxf -&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will create a directory &amp;lt;code&amp;gt;upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6&amp;lt;/code&amp;gt;. Go into this directory and run the firmware flash script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root@ni-e320-XXXXXXX:~# cd upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6&lt;br /&gt;
root@ni-e320-XXXXXXX:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# ./flash-firmware.sh&lt;br /&gt;
This script updates the microcontroller firmware (RO part). The change is&lt;br /&gt;
persistent across power cycles. Incorrect updates can only fixed be a manual&lt;br /&gt;
process which requires opening the enclosure.&lt;br /&gt;
&lt;br /&gt;
Updating the microcontroller firmware (RO part) is only required if the Ettus&lt;br /&gt;
Research support told you to do so.&lt;br /&gt;
&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the prompt, press the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key to continue. Pressing any other key aborts the procedure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue n&lt;br /&gt;
&lt;br /&gt;
aborting&lt;br /&gt;
root@ni-e320-317F9BF:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Pressing the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue y&lt;br /&gt;
&lt;br /&gt;
This script will flash ec-neon-rev3.RO.flat to the device&lt;br /&gt;
old RO version:    neon_vX.X.XXXX-XXXXXXX&lt;br /&gt;
new RO version:    neon_v1.1.7358-a190641&lt;br /&gt;
&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the prompt, press the &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; key ''again'' to continue. Pressing any other key aborts the procedure as before.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Press &amp;quot;y&amp;quot; to continue y&lt;br /&gt;
&lt;br /&gt;
./ectool --interface=dev reboot_ec RW&lt;br /&gt;
./ectool --interface=dev flashread 0x0 65536 ec-neon-rev3.RO.flat.old&lt;br /&gt;
Reading 65536 bytes at offset 0...&lt;br /&gt;
done.&lt;br /&gt;
./ectool --interface=dev flasherase 0x0 65536&lt;br /&gt;
Erasing 65536 bytes at offset 0...&lt;br /&gt;
done.&lt;br /&gt;
./ectool --interface=dev flashwrite 0x0 ec-neon-rev3.RO.flat&lt;br /&gt;
Reading 49592 bytes from ec-neon-rev3.RO.flat...&lt;br /&gt;
Writing to offset 0...&lt;br /&gt;
Write size 112...&lt;br /&gt;
done.&lt;br /&gt;
&lt;br /&gt;
copying new firmware files&lt;br /&gt;
'ec-neon-rev3.bin' -&amp;gt; '/lib/firmware/ni/ec-neon-rev3.bin'&lt;br /&gt;
'ec-neon-rev3.RW.bin' -&amp;gt; '/lib/firmware/ni/ec-neon-rev3.RW.bin'&lt;br /&gt;
root@ni-e320-317F9BF:~/upgrade_mcu_neon_v1.1.7358-a190641-musl-glibc-rev3-6# &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the script is done, reboot the USRP (e.g., &amp;lt;code&amp;gt;shutdown -r now&amp;lt;/code&amp;gt;), and when it comes up the autoboot flag should now work as desired. If these instructions ''do not'' work, then email [mailto:support@ettus.com support@ettus.com] and ask for alternative instructions on how to update the USRP E320 RO and RW boot firmware such that this EEPROM flag setting is honored.&lt;br /&gt;
&lt;br /&gt;
===Default Password===&lt;br /&gt;
The default user is &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; and the password is empty (no password).&lt;br /&gt;
&lt;br /&gt;
It is recommended to update the &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; password, which can be done with the command &amp;lt;code&amp;gt;passwd&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Example Output:&lt;br /&gt;
&lt;br /&gt;
    root@ni-e320-serial:~# passwd&lt;br /&gt;
    Changing password for root&lt;br /&gt;
    New password:&lt;br /&gt;
    Re-enter new password:&lt;br /&gt;
    passwd: password changed.&lt;br /&gt;
&lt;br /&gt;
==Known Issues==&lt;br /&gt;
===Problematic NICs===&lt;br /&gt;
In some streaming modes, the Intel I219-LM NIC can produce flow control and sequence errors. It is recommended to use a USB3 to 1 Gb Ethernet Adapter for hosts which have an I219-LM NIC.&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:E320]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5293</id>
		<title>USRP X410 Getting Started Guide</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=USRP_X410_Getting_Started_Guide&amp;diff=5293"/>
				<updated>2022-03-22T00:08:29Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Correct instructions for changing hostname.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kit Contents==&lt;br /&gt;
===X410===&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;vertical-align:top&amp;quot;|&lt;br /&gt;
* NI Ettus USRP X410&lt;br /&gt;
* DC Power Supply (12V, 20A)&lt;br /&gt;
* 1 Gigabit Ethernet Cat-5e Cable (3m)&lt;br /&gt;
* USB-A to USB-C Cable (1m)&lt;br /&gt;
* Getting Started Guide URL (QR Code)&lt;br /&gt;
* Safety, Environmental, and Regulatory Information&lt;br /&gt;
||[[File:X410.jpg|450px|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==You Will Need==&lt;br /&gt;
* For Network Mode: A host computer with an available 1 or 10 Gigabit Ethernet interface for sample streaming. In addition to the Ethernet interface used for sampling streaming, your host computer will require a separate 1 Gigabit Ethernet interface for command and control streaming.&lt;br /&gt;
 &lt;br /&gt;
* For Stand-Alone Embedded Mode: A host computer with an available 1 Gigabit Ethernet port or a USB 2.0 port to remotely access the embedded Linux operating system running on ARM CPU.&lt;br /&gt;
&lt;br /&gt;
==Proper Care and Handling==&lt;br /&gt;
All Ettus Research products are individually tested before shipment. The USRP is guaranteed to be functional at the time it is received by the customer. Improper use or handling of the USRP can cause the device to become non-functional. Take the following precautions to prevent damage to the unit.&lt;br /&gt;
&lt;br /&gt;
* Never allow metal objects to touch the circuit board while powered.&lt;br /&gt;
* Always properly terminate the transmit port with an antenna or 50Ω load.&lt;br /&gt;
* Always handle the board with proper anti-static methods.&lt;br /&gt;
* Never allow the board to directly or indirectly come into contact with any voltage spikes.&lt;br /&gt;
* Never allow any water or condensing moisture to come into contact with the device.&lt;br /&gt;
* Always use caution with FPGA, firmware, or software modifications.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Never apply more than +14 dBm continuous &amp;lt;=3GHz, +17 dBm continuous &amp;gt;3GHz, or +20dBm more than 5 minutes &amp;gt;3GHz of power into any RF input.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |[[File:Caution.png|24px|center]]&lt;br /&gt;
|style=&amp;quot;padding-left:10px; padding-right:10px; padding-bottom:10px;&amp;quot; |Always use at least 30dB attenuation if operating in loopback configuration&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install and Setup the Software Tools on Your Host Computer==&lt;br /&gt;
In order to use your Universal Software Radio Peripheral (USRP™), you must have the software tools correctly installed and configured on your host computer. A step-by-step guide for doing this is available at the Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on Linux|Linux]], [[Building and Installing the USRP Open-Source Toolchain (UHD and GNU Radio) on OS X|OS X]] and [[Building and Installing the USRP Open Source Toolchain (UHD and GNU Radio) on Windows|Windows]] Application Notes.&lt;br /&gt;
&lt;br /&gt;
To find the latest release of UHD, see the UHD repository at https://github.com/EttusResearch/uhd.&lt;br /&gt;
&lt;br /&gt;
The USRP X410 requires UHD version 4.1 or later. &lt;br /&gt;
&lt;br /&gt;
'''When you receive a brand-new device, it is strongly recommended that you download the latest filesystem image from the Ettus Research website update the unit. It is not recommended that you use the filesystem from the factory as-is. Instructions on downloading the latest filesystem image and updating it is listed below.'''&lt;br /&gt;
&lt;br /&gt;
'''Note that if you are operating the device in Network Mode, the version of UHD running on the host computer and the USRP X410 must match.'''&lt;br /&gt;
&lt;br /&gt;
==Assembling the X410==&lt;br /&gt;
Inside the kit you will find the X410 and an X410 power supply. Plug these in, connect the 1GbE RJ45 interface to your network, and power on the device by pressing the power button.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The STM32 Microcontroller==&lt;br /&gt;
&lt;br /&gt;
The STM32 microcontroller (also referred to as the &amp;quot;SCU&amp;quot;) controls various low-level features of the X4x0 series motherboard: It controls the power sequencing, reads out fan speeds and some of the temperature sensors. It is connected to the RFSoC via an I2C bus. It is running software based on Chromium EC.&lt;br /&gt;
&lt;br /&gt;
It is possible to log into the STM32 using the serial interface (see Connecting to the Microcontroller). This will allow certain low-level controls, such as remote power cycling should the CPU have become unresponsive for whatever reason.&lt;br /&gt;
&lt;br /&gt;
===Updating the SCU===&lt;br /&gt;
&lt;br /&gt;
The writable SCU image file is stored on the filesystem under /lib/firmware/ni/ec-titanium-revX.RW.bin (where X is a revision compatibility number). To update, simply replace the .bin file with the updated version and reboot.&lt;br /&gt;
&lt;br /&gt;
==eMMC Storage==&lt;br /&gt;
&lt;br /&gt;
The main non-volatile storage of the USRP is a 16 GB eMMC storage. This storage can be made accessible as a USB Mass Storage device through the USB-OTG connector on the back panel.&lt;br /&gt;
&lt;br /&gt;
The entire root file system (Linux kernel, libraries) and any user data are stored on the eMMC. It is partitioned into four partitions:&lt;br /&gt;
&lt;br /&gt;
Boot partition (contains the bootloader). This partition usually does not require modification.&lt;br /&gt;
A data partition, mounted in /data. This is the only partition that is not erased during file system updates.&lt;br /&gt;
Two identical system partitions (root file systems). These contain the operating system and the home directory (anything mounted under / that is not the data or boot partition). The reason there are two of these is to enable remote updates: An update running on one partition can update the other one without any effect to the currently running system. Note that the system partitions are erased during updates and are thus unsuitable for permanently storing information.&lt;br /&gt;
Note: It is possible to access the currently inactive root file system by mounting it. After logging into the device using serial console or SSH (see the following two sections), run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ mkdir temp&lt;br /&gt;
&lt;br /&gt;
$ mount /dev/mmcblk0p3 temp # This assumes mmcblk0p3 is currently not mounted&lt;br /&gt;
&lt;br /&gt;
$ ls temp # You are now accessing the idle partition:&lt;br /&gt;
&lt;br /&gt;
bin   data  etc   lib         media  proc  sbin  tmp    usr&lt;br /&gt;
boot  dev   home  lost+found  mnt    run   sys   uboot  var&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The device node in the mount command might differ, depending on which partition is currently already mounted.&lt;br /&gt;
&lt;br /&gt;
==USB Access to eMMC==&lt;br /&gt;
&lt;br /&gt;
While Mender should be used for routine filesystem updates (see Updating Filesystems), it is also possible to access the X410's internal eMMC from an external host over USB. This allows accessing or modifying the filesystem, as well as the ability to flash the device with an entirely new filesystem.&lt;br /&gt;
&lt;br /&gt;
In order to do so, you'll need an external computer with two USB ports, and two USB cables to connect the computer to your X410. The instructions below assume a Linux host.&lt;br /&gt;
&lt;br /&gt;
First, connect to the APU serial console at a baud rate of 115200. Boot the device, and stop the boot sequence by typing noautoboot at the prompt. Then, run the following command in the U-boot command prompt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ums 0 mmc 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will start the USB mass storage gadget to expose the eMMC as a USB mass storage device. You should see a spinning indicator on the console, which indicates the gadget is active.&lt;br /&gt;
&lt;br /&gt;
Next, connect your external computer to the X410's USB to PS port using an OTG cable. Your computer should recognize the X410 as a mass storage device, and you should see an entry in your kernel logs (dmesg) that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
usb 3-1: New USB device found, idVendor=3923, idProduct=7a7d, bcdDevice= 2.23&lt;br /&gt;
&lt;br /&gt;
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Product: USB download gadget&lt;br /&gt;
&lt;br /&gt;
usb 3-1: Manufacturer: National Instruments&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] 30932992 512-byte logical blocks: (15.8 GB/14.8 GiB)&lt;br /&gt;
&lt;br /&gt;
sdc: sdc1 sdc2 sdc3 sdc4&lt;br /&gt;
&lt;br /&gt;
sd 6:0:0:0: [sdc] Attached SCSI removable disk&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact output will depend on your machine, but from this log you can see that the X410 was recognized and /dev/sdc is the block device representing the eMMC, with 4 partitions detected (see eMMC Storage for details on the partition layout).&lt;br /&gt;
&lt;br /&gt;
It is now possible to treat the X410's eMMC as you would any other USB drive: the individual partitions can be mounted and accessed, or the entire block device can be read/written.&lt;br /&gt;
&lt;br /&gt;
Once you're finished accessing the device over USB, the u-boot gadget may be stopped by hitting Ctrl-C at the APU serial console.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Flashing the eMMC==&lt;br /&gt;
&lt;br /&gt;
Once the X410's eMMC is accessible over USB, it's possible to write the filesystem image using bmaptool. You can obtain the latest filesystem image by running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader -t sdimg -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output of this command will indicate where the downloaded image can be found.&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; sudo bmaptool /path/to/usrp_x4xx_fs.sdimg.bz2 /dev/sdX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to flash the eMMC with this image (replacing /dev/sdX with the block device of the X410's eMMC as indicated by your kernel log).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Using a USRP X4x0 from UHD==&lt;br /&gt;
Like any other USRP, all X4x0 USRPs are controlled by the UHD software. To integrate a USRP X4x0 into your C++ application, you would generate a UHD device in the same way you would for any other USRP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;auto usrp = uhd::usrp::multi_usrp::make(&amp;quot;type=x4xx&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a list of which arguments can be passed into make(), see Section Device Arguments.&lt;br /&gt;
&lt;br /&gt;
==Updating Filesystems==&lt;br /&gt;
&lt;br /&gt;
Mender is a third-party software that enables remote updating of the root file system without physically accessing the device (see also the Mender website). Mender can be executed locally on the device, or a Mender server can be set up which can be used to remotely update an arbitrary number of USRP devices. Mender servers can be self-hosted, or hosted by Mender (see mender.io for pricing and availability).&lt;br /&gt;
&lt;br /&gt;
When updating the file system using Mender, the tool will overwrite the root file system partition that is not currently mounted (note: the onboard flash storage contains two separate root file system partitions, only one is ever used at a single time). Any data stored on that partition will be permanently lost, including the currently loaded FPGA image. After updating that partition, it will reboot into the newly updated partition. Only if the update is confirmed by the user, the update will be made permanent. This means that if an update fails, the device will be always able to reboot into the partition from which the update was originally launched (which presumably is in a working state). Another update can be launched now to correct the previous, failed update, until it works.&lt;br /&gt;
&lt;br /&gt;
To initiate an update from the device itself, download a Mender artifact containing the update itself. These are files with a .mender suffix. They can be downloaded by using the uhd_images_downloader utility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Append the -l switch to print out the URLs only:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ uhd_images_downloader -t mender -t x4xx -l&amp;lt;/code&amp;gt;&lt;br /&gt;
Then run mender on the command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install /path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The artifact can also be stored on a remote server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender install http://server.name/path/to/latest.mender&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This procedure will take a while. If the new filesystem requires an update to the MB CPLD, see Updating the Motherboard CPLD before proceeding. After mender has logged a successful update, reboot the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the reboot worked, and the device seems functional, commit the changes so the boot loader knows to permanently boot into this partition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ mender commit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To identify the currently installed Mender artifact from the command line, the following file can be queried:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ cat /etc/mender/artifact_info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are running a hosted server, the updates can be initiated from a web dashboard. From there, you can start the updates without having to log into the device, and can update groups of USRPs with a few clicks in a web GUI. The dashboard can also be used to inspect the state of USRPs. This is a simple way to update groups of rack-mounted USRPs with custom file systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Network Interfaces==&lt;br /&gt;
The Ettus USRP X410 has various network interfaces:&lt;br /&gt;
&lt;br /&gt;
eth0: RJ45 port.&lt;br /&gt;
&lt;br /&gt;
The RJ45 port comes up with a default configuration of DHCP, that will request a network address from your DHCP server (if available on your network). This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
int0: internal interface for network communication between the embedded ARM processor and FPGA.&lt;br /&gt;
&lt;br /&gt;
The internal network interface is configured with a static address: 169.254.0.1/24. This interface is agnostic of FPGA image flavor.&lt;br /&gt;
&lt;br /&gt;
sfpX [, sfpX_1, sfpX_2, sfpX_3]: QSFP28 network interface(s), up-to four (one per lane) based on implemented protocol.&lt;br /&gt;
&lt;br /&gt;
Each QSFP28 port has four high-speed transceiver lanes. Therefore, depending on the FPGA image flavor, up-to four different network interfaces may exist per QSFP28 port, using the sfpXfor the first lane, and sfpX_1-3 for the other three lanes. Each network interface has a default static IP address. Note that for multi-lane protocols, such as 100 GbE, a single interface is used (sfpX).&lt;br /&gt;
The configuration files for these network interfaces are stored in: &amp;lt;code&amp;gt;/etc/systemd/network/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Interface Name&lt;br /&gt;
! Description&lt;br /&gt;
! Default Configuration&lt;br /&gt;
! Configuration File&lt;br /&gt;
! Example: X4_200 FPGA image&lt;br /&gt;
|-&lt;br /&gt;
| eth0&lt;br /&gt;
| RJ45&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | DHCP&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | eth0.network&lt;br /&gt;
| DHCP&lt;br /&gt;
|-&lt;br /&gt;
| int0&lt;br /&gt;
| Internal&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | int0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 169.254.0.1/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0&lt;br /&gt;
| QSFP28 0 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.10.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_1&lt;br /&gt;
| QSFP28 0 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.11.2/24&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp0_2&lt;br /&gt;
| QSFP28 0 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.12.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp0_3&lt;br /&gt;
| QSFP28 0 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp0_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.13.2/24&lt;br /&gt;
|-&lt;br /&gt;
| sfp1&lt;br /&gt;
| QSFP28 1 (4-lanes interface or lane 0)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.20.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| sfp1_1&lt;br /&gt;
| QSFP28 1 (lane 1)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.21.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_1.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_2&lt;br /&gt;
| QSFP28 1 (lane 2)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.22.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_2.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#FFF;&amp;quot; | sfp1_3&lt;br /&gt;
| QSFP28 1 (lane 3)&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | 192.168.23.2/24&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | sfp1_3.network&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | N/C&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Network Connectivity==&lt;br /&gt;
Once the X410 has booted, determine the IP address and verify network connectivity by running uhd_find_devices on the host computer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ uhd_find_devices&lt;br /&gt;
&lt;br /&gt;
-- UHD Device 0&lt;br /&gt;
&lt;br /&gt;
Device Address:&lt;br /&gt;
serial: 1234ABC&lt;br /&gt;
addr: 10.2.161.10&lt;br /&gt;
claimed: False&lt;br /&gt;
mgmt_addr: 10.2.161.10&lt;br /&gt;
product: x410&lt;br /&gt;
type: x4xx&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, an X410 will use DHCP to attempt to find an address.&lt;br /&gt;
&lt;br /&gt;
At this point, you should run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_usrp_probe --args addr=&amp;lt;IP address&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
to ensure functionality of the device.&lt;br /&gt;
&lt;br /&gt;
Note: If you receive the following error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Error: RuntimeError: Graph edge list is empty for rx channel 0&amp;lt;/code&amp;gt;&lt;br /&gt;
then you will need to download a UHD-compatible FPGA as described in Updating the FPGA or using the following command (it assumes that FPGA images have been downloaded previously using uhd_images_downloader, or that the command is run on the device itself):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;ip address&amp;gt;,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
When running on the device, use &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt; as the IP address.&lt;br /&gt;
&lt;br /&gt;
You can now use existing UHD examples or applications (such as rx_sample_to_file, rx_ascii_art_dft, or tx_waveforms) or other UHD-compatible applications to start receiving and transmitting with the device.&lt;br /&gt;
&lt;br /&gt;
See Network Interfaces for further details on the various network interfaces available on the X410.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Status LEDs===&lt;br /&gt;
The Ettus USRP X410 is equipped with status LEDs for its network-capable ports: RJ45 and QSFP28s, see RJ45 LED Behavior and QSFP28 LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
====RJ45 LED Behavior====&lt;br /&gt;
The RJ45 port has two independent LEDs: green (right) and yellow (left). The table below summarizes the LEDs' behavior. Note that link speed indication is not currently supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! Green LED&lt;br /&gt;
! Yellow LED&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| On&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| On&lt;br /&gt;
| Blinking&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====QSFP28 LED Behavior====&lt;br /&gt;
Each QSFP28 connector has four LEDs, one for each high-speed transceiver lane. The table below summarizes the LEDs' behavior, note that for multi-lane protocols, such as 100 GbE, the corresponding LEDs are ganged together. Within the same image, multiple speeds on the same port (e.g., both 10 GbE and 100 GbE) are not supported, therefore link speed indication is not supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center; vertical-align:middle;&amp;quot;&lt;br /&gt;
! Link / Activity&lt;br /&gt;
! QSFP28 LED (4 Total)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | No Link&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / No Activity&lt;br /&gt;
| Green (solid)&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot; | Link / Activity&lt;br /&gt;
| Amber (blinking)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Security-related Settings==&lt;br /&gt;
The X410 ships without a root password set. It is possible to ssh into the device by simply connecting as root, and thus gaining access to all subsystems. To set a password, run the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ passwd&amp;lt;/code&amp;gt;&lt;br /&gt;
on the device.&lt;br /&gt;
&lt;br /&gt;
==Serial Connection==&lt;br /&gt;
It is possible to gain access to the device using a serial terminal emulator. To do so, the USB debug port needs to be connected to a separate computer to gain access. Most Linux, OSX, or other Unix flavors have a tool called 'screen' which can be used for this purpose, by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/ttyUSB2 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
In this command, we prepend 'sudo' to elevate user privileges (by default, accessing serial ports is not available to regular users), we specify the device node (in this case, /dev/ttyUSB2), and the baud rate (115200).&lt;br /&gt;
&lt;br /&gt;
The exact device node depends on your operating system's driver and other USB devices that might be already connected. Modern Linux systems offer alternatives to simply trying device nodes; instead, the OS might have a directory of symlinks under /dev/serial/by-id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ls /dev/serial/by-id&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0&lt;br /&gt;
usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Exact names depend on the host operating system version and may differ.&lt;br /&gt;
&lt;br /&gt;
The first (with the if02 suffix) connects to the STM32 microcontroller (SCU), whereas the second (with the if03 suffix) connects to Linux running on the RFSoC APU.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if03-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
After entering the username root (no password is set by default), you should be presented with a shell prompt similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
On this prompt, you can enter any Linux command available. Using the default configuration, the serial console will also show all kernel log messages (unlike when using SSH, for example), and give access to the boot loader (U-boot prompt). This can be used to debug kernel or bootloader issues more efficiently than when logged in via SSH.&lt;br /&gt;
&lt;br /&gt;
==Connecting to the Microcontroller==&lt;br /&gt;
The microcontroller (which controls the power sequencing, among other things) also has a serial console available. To connect to the microcontroller, use the other UART device. In the example above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo screen /dev/serial/by-id/usb-Digilent_Digilent_USB_Device_2516351DDCC0-if02-port0 115200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It provides a very simple prompt. The command 'help' will list all available commands. A direct connection to the microcontroller can be used to hard-reset the device without physically accessing it and other low-level diagnostics. For example, running the command reboot will emulate a reset button press, resetting the state of the device, while the command powerbtn will emulate a power button press, turning the device back on again.&lt;br /&gt;
&lt;br /&gt;
==SSH Connection==&lt;br /&gt;
The USRP X410 has two network connections: The dual QSFP28 ports, and an RJ45 connector. The latter is by default configured by DHCP; by plugging it into into 1 Gigabit switch on a DHCP-capable network, it will get assigned an IP address and thus be accessible via ssh.&lt;br /&gt;
&lt;br /&gt;
In case your network setup does not include a DHCP server, refer to the section Serial Connection. A serial login can be used to assign an IP address manually.&lt;br /&gt;
&lt;br /&gt;
After the device obtained an IP address you can log in from a Linux or OSX machine by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC # Replace with your actual device name!&amp;lt;/code&amp;gt;&lt;br /&gt;
Depending on your network setup, using a .local domain may work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ ssh root@ni-x4xx-1234ABC.local&amp;lt;/code&amp;gt;&lt;br /&gt;
Of course, you can also connect to the IP address directly if you know it (or set it manually using the serial console).&lt;br /&gt;
&lt;br /&gt;
Note: The device's hostname is derived from its serial number by default (&amp;lt;code&amp;gt;ni-x4xx-$SERIAL&amp;lt;/code&amp;gt;). You can change the hostname by creating the file &amp;lt;code&amp;gt;/data/network/hostname&amp;lt;/code&amp;gt;, saving the desired hostname in it, then rebooting.&lt;br /&gt;
&lt;br /&gt;
On Microsoft Windows, the connection can be established using a tool such as PuTTY, by selecting a username of root without password.&lt;br /&gt;
&lt;br /&gt;
Like with the serial console, you should be presented with a prompt like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;root@ni-x4xx-1234ABC:~#&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Autoboot ==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 can be configured to power on and boot automatically when power is applied. This setting can be controlled using the &amp;lt;code&amp;gt;eeprom-set-autoboot&amp;lt;/code&amp;gt; script. This script is executed directly on the USRP X410. To enable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot on&amp;lt;/code&amp;gt;; to disable autoboot, run &amp;lt;code&amp;gt;eeprom-set-autoboot off&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Updating the FPGA==&lt;br /&gt;
&lt;br /&gt;
The FPGA can be updated simply using uhd_image_loader:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt; --fpga-path &amp;lt;path to .bit&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,addr=&amp;lt;IP address of device&amp;gt;,fpga=FPGA_TYPE&amp;lt;/code&amp;gt;&lt;br /&gt;
A UHD install will likely have pre-built images in /usr/share/uhd/images/. Up-to-date images can be downloaded using the uhd_images_downloader script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_images_downloader&amp;lt;/code&amp;gt;&lt;br /&gt;
will download images into /usr/share/uhd/images/ (the path may differ, depending on how UHD was installed).&lt;br /&gt;
&lt;br /&gt;
Also note that the USRP already ships with compatible FPGA images on the device - these images can be loaded by SSH'ing into the device and running:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;uhd_image_loader --args type=x4xx,mgmt_addr=127.0.0.1,fpga=X4_200&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FPGA Image Flavors==&lt;br /&gt;
&lt;br /&gt;
Unlike the USRP X310 or other third-generation USRP devices, the FPGA image flavors do not only encode how the QSFP28 connectors are configured, but also which master clock rates are available. This is because the data converter configuration is part of the FPGA image (the ADCs/DACs on the X410 are on the same die as the FPGA). The image flavors consist of two short strings, separated by an underscore, e.g. X4_200 is an image flavor which contains 4x 10 GbE, and can handle an analog bandwidth of 200 MHz. The first two characters describe the configuration of the QSFP28 ports: 'X' stands for 10 GbE, 'C' stands for 100 GbE. See the following table for more details.&lt;br /&gt;
&lt;br /&gt;
1x 10 GbE (Lane 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The analog bandwidth determines the available master clock rates. As of UHD 4.1, only the X4_200 image is shipped with UHD, which allows a 245.76 MHz or 250 MHz master clock rate. The other images are considered experimental (unsupported).&lt;br /&gt;
&lt;br /&gt;
==Device Arguments==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! Key&lt;br /&gt;
! Description&lt;br /&gt;
! Example Value&lt;br /&gt;
|-&lt;br /&gt;
| addr&lt;br /&gt;
| IPv4 address of primary SFP+ port to connect to.&lt;br /&gt;
| addr=192.168.30.2&lt;br /&gt;
|-&lt;br /&gt;
| second_addr&lt;br /&gt;
| IPv4 address of secondary SFP+ port to connect to.&lt;br /&gt;
| second_addr=192.168.40.2&lt;br /&gt;
|-&lt;br /&gt;
| mgmt_addr&lt;br /&gt;
| IPv4 address or hostname to which to connect the RPC client. Defaults to `addr'.&lt;br /&gt;
| mgmt_addr=ni-sulfur-311FE00&lt;br /&gt;
|-&lt;br /&gt;
| find_all&lt;br /&gt;
| When using broadcast, find all devices, even if unreachable via CHDR.&lt;br /&gt;
| find_all=1&lt;br /&gt;
|-&lt;br /&gt;
| master_clock_rate&lt;br /&gt;
| Master Clock Rate in Hz.&lt;br /&gt;
| master_clock_rate=250e6&lt;br /&gt;
|-&lt;br /&gt;
| serialize_init&lt;br /&gt;
| Force serial initialization of daughterboards.&lt;br /&gt;
| serialize_init=1&lt;br /&gt;
|-&lt;br /&gt;
| skip_init&lt;br /&gt;
| Skip the initialization process for the device.&lt;br /&gt;
| skip_init=1&lt;br /&gt;
|-&lt;br /&gt;
| time_source&lt;br /&gt;
| Specify the time (PPS) source.&lt;br /&gt;
| time_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| clock_source&lt;br /&gt;
| Specify the reference clock source.&lt;br /&gt;
| clock_source=internal&lt;br /&gt;
|-&lt;br /&gt;
| ref_clk_freq&lt;br /&gt;
| Specify the external reference clock frequency, default is 10 MHz.&lt;br /&gt;
| ref_clk_freq=20e6&lt;br /&gt;
|-&lt;br /&gt;
| discovery_port&lt;br /&gt;
| Override default value for MPM discovery port.&lt;br /&gt;
| discovery_port=49700&lt;br /&gt;
|-&lt;br /&gt;
| rpc_port&lt;br /&gt;
| Override default value for MPM RPC port.&lt;br /&gt;
| rpc_port=49701&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==GPS==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 includes a Jackson Labs LTE-Lite GPS module. Its antenna port is on the rear panel (see Front and Back Panels). When the X410 has access to GPS satellite signals, it can use this module to read out the current GPS time and location as well as to discipline an onboard OCXO.&lt;br /&gt;
&lt;br /&gt;
To use the GPS as a clock and time reference, simply use gpsdo as a clock or time source. Alternatively, set gpsdo as a synchronization source:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Set clock/time individually:&lt;br /&gt;
usrp-&amp;gt;set_clock_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
usrp-&amp;gt;set_time_source(&amp;quot;gpsdo&amp;quot;);&lt;br /&gt;
// This is equivalent to the previous commands, but faster, as it sets&lt;br /&gt;
// both settings simultaneously and avoids duplicating settings that are shared&lt;br /&gt;
// between these calls.&lt;br /&gt;
usrp-&amp;gt;set_sync_source(&amp;quot;clock_source=gpsdo,time_source=gpsdo&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the GPS module is not always enabled. Its power-on status can be queried using the gps_enabled GPS sensor (see also The Sensor API). When disabled, none of the sensors will return useful (if any) values.&lt;br /&gt;
&lt;br /&gt;
When selecting gpsdo as a clock source, the GPS will always be enabled. Note that acquiring a GPS lock can take some time after enabling the GPS, so if a UHD application is enabling the GPS dynamically, it might take some time before a GPS lock is reported.&lt;br /&gt;
&lt;br /&gt;
==Front-Panel Programmable GPIOs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 has two HDMI front-panel connectors, which are connected to the FPGA.&lt;br /&gt;
&lt;br /&gt;
Support for using these with UHD is not yet available.&lt;br /&gt;
&lt;br /&gt;
==Subdev Specifications==&lt;br /&gt;
&lt;br /&gt;
The RF ports on the front panel of the X410 + ZBX correspond to the following subdev specifications:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Label&lt;br /&gt;
! style=&amp;quot;text-align:center; vertical-align:middle; font-weight:bold;&amp;quot; | Subdev Spec&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 0&lt;br /&gt;
| A:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 0 / RF 1&lt;br /&gt;
| A:1&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 0&lt;br /&gt;
| B:0&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle; background-color:#FFF;&amp;quot;&lt;br /&gt;
| DB 1 / RF 1&lt;br /&gt;
| B:1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The subdev spec slot identifiers &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; are not reflected on the front panel. They were set to match valid subdev specifications of previous USRPs, maintaining backward compatibility.&lt;br /&gt;
&lt;br /&gt;
These values can be used for uhd::usrp::multi_usrp::set_rx_subdev_spec() and uhd::usrp::multi_usrp::set_tx_subdev_spec() as with other USRPs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Rear Panel Status LEDs==&lt;br /&gt;
&lt;br /&gt;
The USRP X410 is equipped with four LEDs located on the device's rear panel. Each LED supports four different states: Off, Green, Red, and Amber. One LED (PWR) indicates the device's power state (see Power LED below). The other three LEDs (LED 0, LED 1, and LED 2) are user-configurable, different behaviors are supported for each of these LEDs (see User-configurable LEDs below).&lt;br /&gt;
&lt;br /&gt;
[[File:x4xx_rearpanel_status_leds.png|125px]]&lt;br /&gt;
&lt;br /&gt;
===X4x0 Rear Panel Status LEDs===&lt;br /&gt;
Power LED&lt;br /&gt;
The USRP X410's PWR LED is reserved to visually indicate the user the device's power state. Power LED Behavior describes what each LED state represents.&lt;br /&gt;
&lt;br /&gt;
===Power LED Behavior===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background-color:#FFF;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold; text-align:center;&amp;quot;&lt;br /&gt;
! PWR LED State&lt;br /&gt;
! style=&amp;quot;vertical-align:middle;&amp;quot; | Meaning&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Off&lt;br /&gt;
| No power is applied&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Amber&lt;br /&gt;
| Power is good but X410 is powered off&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Green&lt;br /&gt;
| Power is good and X410 is powered on&lt;br /&gt;
|- style=&amp;quot;vertical-align:middle;&amp;quot;&lt;br /&gt;
| Red&lt;br /&gt;
| Power error state&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===User-configurable LEDs===&lt;br /&gt;
The USRP X410's user-configurable rear panel status LEDs (LED 0, LED 1, and LED 2) allow the user to have visual indication of various device conditions. Supported LED Behaviors provides a complete list of the supported behaviors for each user-configurable LED. By default, these LEDs are configured as described in LEDs Default Behavior.&lt;br /&gt;
&lt;br /&gt;
The user may alter the default LEDs behavior either temporarily or persistently, see the Temporarily change the LED Behavior or Persistently in the UHD manual to change the LED Behavior accordingly.&lt;br /&gt;
&lt;br /&gt;
https://files.ettus.com/manual/page_usrp_x4xx.html&lt;br /&gt;
&lt;br /&gt;
==Technical Support and Community Knowledge Base==&lt;br /&gt;
Technical support for USRP hardware is available through email only. If the product arrived in a non­functional state or you require technical assistance, please contact [mailto:support@ettus.com support@ettus.com]. Please allow 24 to 48 hours for response by email, depending on holidays and weekends, although we are often able to reply more quickly than that.&lt;br /&gt;
&lt;br /&gt;
We also recommend that you subscribe to the community mailing lists. The mailing lists have a responsive and knowledgeable community of hundreds of developers and technical users who are located around the world. When you join the community, you will be connected to this group of people who can help you learn about SDR and respond to your technical and specific questions. Often your question can be answered quickly on the mailing lists. Each mailing list also provides an archive of all past conversations and discussions going back many years. Your question or problem may have already been addressed before, and a relevant or helpful solution may already exist in the archive.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the USRP hardware and the UHD software itself are best addressed through the '''u​srp­-users''' ​mailing list at [http://usrp-users.ettus.com http://usrp-users.ettus.com].&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://gnuradio.org/ GNU Radio] with USRP hardware and UHD software are best addressed through the '''d​iscuss­-gnuradio'''​ mailing list at [https://lists.gnu.org/mailman/listinfo/discuss­gnuradio https://lists.gnu.org/mailman/listinfo/discuss­gnuradio]​.&lt;br /&gt;
&lt;br /&gt;
Discussions involving the use of [http://openbts.org/ OpenBTS®] with USRP hardware and UHD software are best addressed through the '''o​penbts­-discuss​''' mailing list at [https://lists.sourceforge.net/lists/listinfo/openbts­discuss​ https://lists.sourceforge.net/lists/listinfo/openbts­discuss​].​&lt;br /&gt;
&lt;br /&gt;
The support page on our website is located at [https://www.ettus.com/support https://www.ettus.com/support]​. The Knowledge Base is located at ​[https://kb.ettus.com https://kb.ettus.com]​.&lt;br /&gt;
&lt;br /&gt;
==Legal Considerations==&lt;br /&gt;
Every country has laws governing the transmission and reception of radio signals. Users are solely responsible for insuring they use their USRP system in compliance with all applicable laws and regulations. Before attempting to transmit and/or receive on any frequency, we recommend that you determine what licenses may be required and what restrictions may apply.&lt;br /&gt;
&lt;br /&gt;
*NOTE: This USRP product is a piece of test equipment.&lt;br /&gt;
&lt;br /&gt;
==Sales and Ordering Support==&lt;br /&gt;
If you have any non­-technical questions related to your order, then please contact us by email at [mailto:orders@ettus.com orders@ettus.com]​, or by phone at +1­408­610­6399 (Monday-Friday, 8 AM - 5 PM, Pacific Time). Please be sure to include your order number and the serial number of your USRP.&lt;br /&gt;
&lt;br /&gt;
==Terms and Conditions of Sale==&lt;br /&gt;
Terms and conditions of sale can be accessed online at the following link: http://www.ettus.com/legal/terms-and-conditions-of-sale&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started Guides]]&lt;br /&gt;
[[Category:X410]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5285</id>
		<title>Using the RFNoC Replay Block in UHD 4</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block_in_UHD_4&amp;diff=5285"/>
				<updated>2022-02-25T22:02:43Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Minor edits, formatting changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642b'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
&lt;br /&gt;
This application note guides a user through basic use of the RFNoC Replay block&lt;br /&gt;
in UHD 4.x and explains how to run the UHD Replay example. This example covers&lt;br /&gt;
the USRP X410, X310/X300, N300/N310/N320 and E320 devices. For UHD 3.x, please&lt;br /&gt;
refer to [[Using_the_RFNoC_Replay_Block|the UHD 3.x replay block Application Note]].&lt;br /&gt;
&lt;br /&gt;
An introduction to RFNoC with UHD 4.0 and above can be found [[Getting_Started_with_RFNoC_in_UHD_4.0|here]].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of&lt;br /&gt;
arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay&lt;br /&gt;
block, it must be instantiated in the design and connected to the DRAM interface.&lt;br /&gt;
&lt;br /&gt;
The replay block is a standard feature of UHD and RFNoC, and a custom compile of&lt;br /&gt;
UHD is not required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs, so when using these images,&lt;br /&gt;
the following examples can be run without any manual builds of UHD or FPGA images.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
To follow this application note, you need a device with a replay block instantiated,&lt;br /&gt;
and a UHD version recent enough to have the full support for the replay block&lt;br /&gt;
(UHD 4.2 and beyond). To test for the replay block capabilities, connect and&lt;br /&gt;
enable your USRP device, and run the following command:&lt;br /&gt;
&lt;br /&gt;
    uhd_usrp_probe --args &amp;lt;device args&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depending on your device, the output could look like this (truncated):&lt;br /&gt;
&lt;br /&gt;
     _____________________________________________________&lt;br /&gt;
    /&lt;br /&gt;
    |       Device: X400-Series Device&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Mboard: ni-x4xx-&amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   pid: 1040&lt;br /&gt;
    |   |   rev: 4&lt;br /&gt;
    |   |   rev_compat: 4&lt;br /&gt;
    |   |   serial: &amp;lt;serial&amp;gt;&lt;br /&gt;
    |   |   MPM Version: 4.0&lt;br /&gt;
    |   |   FPGA Version: 7.6&lt;br /&gt;
    |   |   FPGA git hash: &amp;lt;hash&amp;gt;.clean&lt;br /&gt;
    |   |   RFNoC capable: Yes&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   Time sources:  internal, external, qsfp0, gpsdo&lt;br /&gt;
    |   |   Clock sources: mboard, internal, external, nsync, gpsdo&lt;br /&gt;
    |   |   Sensors: ...&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       RFNoC blocks on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/DDC#0&lt;br /&gt;
    |   |   * 0/DDC#1&lt;br /&gt;
    |   |   * 0/DUC#0&lt;br /&gt;
    |   |   * 0/DUC#1&lt;br /&gt;
    |   |   * 0/Radio#0&lt;br /&gt;
    |   |   * 0/Radio#1&lt;br /&gt;
    |   |   * 0/Replay#0&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Static connections on this device:&lt;br /&gt;
    |   |&lt;br /&gt;
    |   |   * 0/SEP#0:0==&amp;gt;0/DUC#0:0&lt;br /&gt;
    |   |   * 0/DUC#0:0==&amp;gt;0/Radio#0:0&lt;br /&gt;
    |   |   * 0/Radio#0:0==&amp;gt;0/DDC#0:0&lt;br /&gt;
    |   |   * 0/DDC#0:0==&amp;gt;0/SEP#0:0&lt;br /&gt;
    |   |   * 0/SEP#1:0==&amp;gt;0/DUC#0:1&lt;br /&gt;
    |   |   * 0/DUC#0:1==&amp;gt;0/Radio#0:1&lt;br /&gt;
    |   |   * 0/Radio#0:1==&amp;gt;0/DDC#0:1&lt;br /&gt;
    |   |   * 0/DDC#0:1==&amp;gt;0/SEP#1:0&lt;br /&gt;
    |   |   * 0/SEP#2:0==&amp;gt;0/DUC#1:0&lt;br /&gt;
    |   |   * 0/DUC#1:0==&amp;gt;0/Radio#1:0&lt;br /&gt;
    |   |   * 0/Radio#1:0==&amp;gt;0/DDC#1:0&lt;br /&gt;
    |   |   * 0/DDC#1:0==&amp;gt;0/SEP#2:0&lt;br /&gt;
    |   |   * 0/SEP#3:0==&amp;gt;0/DUC#1:1&lt;br /&gt;
    |   |   * 0/DUC#1:1==&amp;gt;0/Radio#1:1&lt;br /&gt;
    |   |   * 0/Radio#1:1==&amp;gt;0/DDC#1:1&lt;br /&gt;
    |   |   * 0/DDC#1:1==&amp;gt;0/SEP#3:0&lt;br /&gt;
    |   |   * 0/SEP#4:0==&amp;gt;0/Replay#0:0&lt;br /&gt;
    |   |   * 0/Replay#0:0==&amp;gt;0/SEP#4:0&lt;br /&gt;
    |   |   * 0/SEP#5:0==&amp;gt;0/Replay#0:1&lt;br /&gt;
    |   |   * 0/Replay#0:1==&amp;gt;0/SEP#5:0&lt;br /&gt;
    |   |   * 0/SEP#6:0==&amp;gt;0/Replay#0:2&lt;br /&gt;
    |   |   * 0/Replay#0:2==&amp;gt;0/SEP#6:0&lt;br /&gt;
    |   |   * 0/SEP#7:0==&amp;gt;0/Replay#0:3&lt;br /&gt;
    |   |   * 0/Replay#0:3==&amp;gt;0/SEP#7:0&lt;br /&gt;
&lt;br /&gt;
The output tells us that this USRP has a Replay block instantiated (&amp;lt;code&amp;gt;0/Replay#0&amp;lt;/code&amp;gt;).&lt;br /&gt;
It has four static connections to stream endpoints, which also tells us that&lt;br /&gt;
this is a four-port replay block.&lt;br /&gt;
&lt;br /&gt;
If your device does not report a replay block, then you need to build and load&lt;br /&gt;
an FPGA image which includes this block. See ... for instructions on how to do&lt;br /&gt;
this before you proceed. If it does report a block, you can move to the next&lt;br /&gt;
section.&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a&lt;br /&gt;
file containing the samples you wish to replay. This could be generated in&lt;br /&gt;
advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For&lt;br /&gt;
this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;)&lt;br /&gt;
to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000&lt;br /&gt;
samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz.&lt;br /&gt;
Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real&lt;br /&gt;
and 16-bit imaginary components). We can run the program by invoking python from&lt;br /&gt;
the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, enter a command like the following (the path to&lt;br /&gt;
the examples depends on your installation method, for a normal installation via&lt;br /&gt;
apt-get, examples will be located in &amp;lt;code&amp;gt;/usr/lib/uhd/examples&amp;lt;/code&amp;gt; or&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/lib/uhd/examples&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
    $ cd /path/to/examples&lt;br /&gt;
    $ ./replay_samples_from_file --args &amp;lt;device args&amp;gt; --freq 915e6 --gain 10 --file samples.dat --rate 200e6&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the&lt;br /&gt;
FPGA, where they are recorded into the USRP's on-board DRAM. Then, the Replay block&lt;br /&gt;
will play the samples to the radio continuously with a base frequency of 915 MHz,&lt;br /&gt;
creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
Alternatively, use the &amp;lt;code&amp;gt;--nsamps&amp;lt;/code&amp;gt; command line argument to transmit&lt;br /&gt;
a certain number of samples before returning to the command line. Use the&lt;br /&gt;
&amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; argument to see a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
The advantage of this example compared to directly streaming the file to the&lt;br /&gt;
device is twofold:&lt;br /&gt;
&lt;br /&gt;
* The initial upload to DRAM can happen at any link rate. Even when using 1 GbE, this example will work.&lt;br /&gt;
* Once uploaded, the host computer is basically idle. The FPGA will handle the streaming to the radio front-end.&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp source code]&lt;br /&gt;
for &amp;lt;code&amp;gt;rfnoc_replay_samples_from_file&amp;lt;/code&amp;gt; may be considered an example&lt;br /&gt;
for best practices on how to use the replay block.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
This block works like a record and playback buffer that uses DRAM on the USRP to&lt;br /&gt;
store samples.&lt;br /&gt;
Data can be streamed to the block, like to any other RFNoC block.&lt;br /&gt;
&lt;br /&gt;
Refer the [https://files.ettus.com/manual/classuhd_1_1rfnoc_1_1replay__block__control.html manual of the replay block controller]&lt;br /&gt;
for a comprehensive description of its features and API calls.&lt;br /&gt;
&lt;br /&gt;
In the following, we shall use the C++ API to demonstrate the most important&lt;br /&gt;
API calls. We will assume there is a replay block controller called&lt;br /&gt;
&amp;lt;code&amp;gt;replay_ctrl&amp;lt;/code&amp;gt; available in the current context, and it is of type&lt;br /&gt;
&amp;lt;code&amp;gt;uhd::rfnoc::replay_block_control::sptr&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Recording Data===&lt;br /&gt;
&lt;br /&gt;
Before streaming data to the replay block, it needs to be configured for recording:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives&lt;br /&gt;
on port &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt; into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt;&lt;br /&gt;
and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is&lt;br /&gt;
filled, recording automatically stops. Care should be taken to configure the&lt;br /&gt;
memory buffers so that they do not overlap if more than one Replay block or&lt;br /&gt;
buffer is being used simultaneously.&lt;br /&gt;
&lt;br /&gt;
Call this once for every port that you expect to stream data into.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block&lt;br /&gt;
than the size of the record buffer. Additional data is not accepted or dropped&lt;br /&gt;
by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the&lt;br /&gt;
size of the DRAM on the USRP and how the memory interface is configured on the USRP.&lt;br /&gt;
For example, the &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; IP used by the X310 is&lt;br /&gt;
configured to give each connected device an address space of 32&amp;amp;nbsp;MiB. As a&lt;br /&gt;
result, the Replay block will be limited to this amount of memory. The&lt;br /&gt;
&amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; file must be modified if more than 32&amp;amp;nbsp;MiB needs to be buffered.&lt;br /&gt;
&lt;br /&gt;
To restart recording from the same offset, the following API call can be used:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and&lt;br /&gt;
it resets the internal counters that track how much data has been recorded. If&lt;br /&gt;
a previous recording has taken place then it is a good idea to ensure that&lt;br /&gt;
stale data was not queued up in the RF network on the FPGA from a previous run.&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling&lt;br /&gt;
&amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up&lt;br /&gt;
unexpectedly in the record buffer. If so, it restarts recording then waits&lt;br /&gt;
again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the&lt;br /&gt;
record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected)&lt;br /&gt;
        std::this_thread::sleep_for(100ms);&lt;br /&gt;
&lt;br /&gt;
===Playing Back Data===&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base&lt;br /&gt;
address and size of the playback buffer. To play back previously recorded data,&lt;br /&gt;
set the start address to the same address that was used for the record buffer&lt;br /&gt;
and set the size of the playback buffer to the match the amount of data that&lt;br /&gt;
was recorded. Note that the record and playback buffers do not need to be the&lt;br /&gt;
same, allowing a single Replay block to both record and playback to different&lt;br /&gt;
regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command.&lt;br /&gt;
Playback automatically wraps around to the start of the buffer if more data is&lt;br /&gt;
requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely&lt;br /&gt;
until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only&lt;br /&gt;
the specified number of samples to be played once. The &amp;lt;code&amp;gt;num_samps&amp;lt;/code&amp;gt;&lt;br /&gt;
parameter is a 28-bit value, limiting this mode of playback to 2&amp;lt;sup&amp;gt;28&amp;lt;/sup&amp;gt;&lt;br /&gt;
words at a time. Playback can be stopped by issuing a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is&lt;br /&gt;
received (DRAM reads are not aborted mid-transaction). As a result, some data&lt;br /&gt;
will continue to stream from the Replay block after the stop command is issued&lt;br /&gt;
while waiting for the DRAM read to complete and for all the internal buffers to&lt;br /&gt;
empty.&lt;br /&gt;
&lt;br /&gt;
When using the C++ API, the &amp;lt;code&amp;gt;play()&amp;lt;/code&amp;gt; API call is a useful shorthand&lt;br /&gt;
for configuring playback and submitting the stream command at the same time:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;play(buffer_start_byte_address, num_bytes_to_play, replay_chan, start_time, repeat);&lt;br /&gt;
&lt;br /&gt;
In either case, the start time is optional. When given, the first sample to leave&lt;br /&gt;
the block on playback is tagged with this timestamp.&lt;br /&gt;
&lt;br /&gt;
===Memory Alignment and Word Sizes===&lt;br /&gt;
&lt;br /&gt;
There are two memory alignment values that need to be considered when dealing&lt;br /&gt;
with the replay block. The first is the word size, which is the minimum number of&lt;br /&gt;
bytes per DRAM transaction. For all default configurations, the word size is 64 bits,&lt;br /&gt;
which means that only even numbers of samples can be recorded or played back&lt;br /&gt;
when using 16-bit complex samples (at 4 bytes per sample). Use the &amp;lt;code&amp;gt;get_word_size()&amp;lt;/code&amp;gt;&lt;br /&gt;
API call to identify the correct word size.&lt;br /&gt;
&lt;br /&gt;
The second alignment value is the memory's page boundaries. The start addresses&lt;br /&gt;
for record and replay must fall onto a 4 kiB memory boundary to ensure correct&lt;br /&gt;
alignment of data.&lt;br /&gt;
&lt;br /&gt;
==Building Custom FPGA Images with a Replay Block==&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Note: Cloning the repository is only required when building custom FPGA images.&lt;br /&gt;
If the replay block is already built into the USRP's bit file, this is not&lt;br /&gt;
required. By default, UHD ships the Replay block with the default images for&lt;br /&gt;
the X410, X310/X300, N300/N310/N320 series of USRPs.&lt;br /&gt;
&lt;br /&gt;
If you do require access to the source code, e.g. to build an FPGA image with a&lt;br /&gt;
custom replay block configuration, run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ git clone https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
For the rest of the Application Note, we assume the repository was cloned into&lt;br /&gt;
the location &amp;lt;code&amp;gt;~/src/uhd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need&lt;br /&gt;
to have the Xilinx development tools installed. The specific version required&lt;br /&gt;
depends on the UHD version. Refer to the&lt;br /&gt;
[https://files.ettus.com/manual/md_usrp3_build_instructions.html manual] for the&lt;br /&gt;
correct version for your UHD version, and the installation instructions for&lt;br /&gt;
Vivado in order to install these tools. It is recommended that you use the&lt;br /&gt;
default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Building the FPGA==&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the&lt;br /&gt;
USRP you plan to use. This is currently a manual step. The instructions below&lt;br /&gt;
are for the X310, but similar instructions apply to other RFNoC-capable&lt;br /&gt;
devices.&lt;br /&gt;
&lt;br /&gt;
To create a custom FPGA image with a replay, you need to create an image core file.&lt;br /&gt;
The following lines are the relevant lines from the&lt;br /&gt;
[https://github.com/EttusResearch/uhd/blob/master/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml X310 default image core file]:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      # ... all the other stream endpoints...&lt;br /&gt;
      ep4:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
      ep5:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 4096                 # Ingress buffer size for data&lt;br /&gt;
    &lt;br /&gt;
    noc_blocks:&lt;br /&gt;
      # ... all the other blocks...&lt;br /&gt;
      replay0:&lt;br /&gt;
        block_desc: 'replay.yml'&lt;br /&gt;
        parameters:&lt;br /&gt;
          NUM_PORTS: 2&lt;br /&gt;
          MEM_ADDR_W: 30&lt;br /&gt;
    &lt;br /&gt;
    connections:&lt;br /&gt;
      # ...connections for all the other blocks...&lt;br /&gt;
      # ep4 to replay0(0)&lt;br /&gt;
      - { srcblk: ep4,     srcport: out0,  dstblk: replay0, dstport: in_0 }&lt;br /&gt;
      # replay0(0) to ep4&lt;br /&gt;
      - { srcblk: replay0, srcport: out_0, dstblk: ep4,     dstport: in0  }&lt;br /&gt;
      # ep5 to replay0(1)&lt;br /&gt;
      - { srcblk: ep5,     srcport: out0,  dstblk: replay0, dstport: in_1 }&lt;br /&gt;
      # replay0(1) to ep5&lt;br /&gt;
      - { srcblk: replay0, srcport: out_1, dstblk: ep5,     dstport: in0  }&lt;br /&gt;
      # BSP Connections&lt;br /&gt;
      - { srcblk: replay0, srcport: axi_ram, dstblk: _device_, dstport: dram }&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      # ...all other clock domains...&lt;br /&gt;
      - { srcblk: _device_, srcport: dram,  dstblk: replay0, dstport: mem  }&lt;br /&gt;
&lt;br /&gt;
As you can see, the replay block requires configuration in up to four sections:&lt;br /&gt;
* For maximum flexibility, every port of the replay block will receive its own stream endpoint. This is not a requirement of the replay block, but allows its flexible use.&lt;br /&gt;
* Of course, the block needs to be declared in the &amp;lt;code&amp;gt;noc_blocks&amp;lt;/code&amp;gt; section.&lt;br /&gt;
* It must be connected to the stream endpoints in the &amp;lt;code&amp;gt;connections&amp;lt;/code&amp;gt; section, as well as to the DRAM banks (BSP connection).&lt;br /&gt;
* Finally, the clock domain needs to be connected.&lt;br /&gt;
&lt;br /&gt;
When the YAML image core file is complete, save it, e.g., as x310_replay_image_core.yml,&lt;br /&gt;
and pass it to the image builder:&lt;br /&gt;
&lt;br /&gt;
    rfnoc_image_builder -y x310_replay_image_core.yml&lt;br /&gt;
&lt;br /&gt;
This will create a bitfile that contains the replay block. It can be loaded onto&lt;br /&gt;
the device using the &amp;lt;code&amp;gt;uhd_image_loader&amp;lt;/code&amp;gt; tool:&lt;br /&gt;
&lt;br /&gt;
    uhd_image_loader --args type=x300,addr=&amp;lt;ip address&amp;gt; --fpga-path=/path/to/usrp_x310_fpga_HG.bit&lt;br /&gt;
&lt;br /&gt;
When this is complete, the replay block is ready to use.&lt;br /&gt;
&lt;br /&gt;
==Source files==&lt;br /&gt;
&lt;br /&gt;
For reference, the following files implement the replay block:&lt;br /&gt;
&lt;br /&gt;
* Verilog/HDL sources: https://github.com/EttusResearch/uhd/tree/master/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_replay&lt;br /&gt;
* C++ Block controller sources (header, block controller, Python bindings, unit tests):&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/include/uhd/rfnoc/replay_block_control.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control.cpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/lib/rfnoc/replay_block_control_python.hpp&lt;br /&gt;
** https://github.com/EttusResearch/uhd/blob/master/host/tests/rfnoc_block_tests/replay_block_test.cpp&lt;br /&gt;
* Example: https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc_replay_samples_from_file.cpp&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Knowledge_Base&amp;diff=5271</id>
		<title>Knowledge Base</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Knowledge_Base&amp;diff=5271"/>
				<updated>2022-02-08T20:47:46Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Add UHD 4 version of Getting Started with RFNoC to Other category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the Ettus Research Knowledge Base (KB). The KB is continuously being updated and expanded. If you have any suggestions, or do not find what you are looking for, then please [http://www.ettus.com/contact Contact Us].&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
== [[Getting Started Guides|&amp;lt;i class=&amp;quot;fa fa-road&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Getting Started Guides]] ==&lt;br /&gt;
&lt;br /&gt;
'''Motherboards'''&lt;br /&gt;
* [[B200/B210/B200mini/B205mini Getting Started Guides|B200/B210/B200mini/B205mini]]&lt;br /&gt;
* [[Ettus USRP E300 Embedded Family Getting Started Guides|E310/E312/E313]]&lt;br /&gt;
* [[E320 Getting Started Guide|E320]]&lt;br /&gt;
* [[N200/N210 Getting Started Guides|N200/N210]]&lt;br /&gt;
* [[USRP N300/N310/N320/N321 Getting Started Guide|N300/N310/N320/N321]]&lt;br /&gt;
* [[X300/X310 Getting Started Guides|X300/X310]]&lt;br /&gt;
* [[USRP-2974 Getting Started Guide|USRP-2974]]&lt;br /&gt;
* [[USRP X410 Getting Started Guide|X410]]&lt;br /&gt;
&lt;br /&gt;
'''Daughterboards'''&lt;br /&gt;
* [[BasicTX/BasicRX Getting Started Guides|BasicTX/BasicRX]]&lt;br /&gt;
* [[CBX Getting Started Guides|CBX]]&lt;br /&gt;
* [[LFTX/LFRX Getting Started Guides|LFTX/LFRX]]&lt;br /&gt;
* [[SBX Getting Started Guides|SBX]]&lt;br /&gt;
* [[TwinRX Getting Started Guides|TwinRX]]&lt;br /&gt;
* [[UBX Getting Started Guides|UBX]]&lt;br /&gt;
* [[WBX Getting Started Guides|WBX]]&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* [[Getting_Started_with_RFNoC_in_UHD_4.0|RFNoC Development (UHD 4.x)]]&lt;br /&gt;
* [[Getting_Started_with_RFNoC_Development|RFNoC Development (UHD 3.x)]]&lt;br /&gt;
* [[Live SDR Environment Getting Started Guides|Live SDR Environment]]&lt;br /&gt;
* [[OctoClock CDA-2990 Getting Started Guides|OctoClock CDA-2990]]&lt;br /&gt;
* [[Using Ethernet-Based Synchronization on the USRP™ N3xx Devices|White Rabbit]]&lt;br /&gt;
* [[Getting Started with DPDK and UHD|DPDK]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Hardware Resources|&amp;lt;i class=&amp;quot;fa fa-cogs&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Hardware Resources]] ==&lt;br /&gt;
'''Motherboards'''&lt;br /&gt;
* [[B200/B210/B200mini/B205mini]]&lt;br /&gt;
* [[Ettus USRP E300 Embedded Family Hardware Resources|E310/E312/E313]]&lt;br /&gt;
* [[E320|E320]]&lt;br /&gt;
* [[N200/N210]]&lt;br /&gt;
* [[N300/N310]]&lt;br /&gt;
* [[N320/N321]]&lt;br /&gt;
* [[X300/X310]]&lt;br /&gt;
* [[USRP-2974]]&lt;br /&gt;
&lt;br /&gt;
'''Daughterboards'''&lt;br /&gt;
* [[BasicTX/BasicRX]]&lt;br /&gt;
* [[CBX]]&lt;br /&gt;
* [[LFTX/LFRX]]&lt;br /&gt;
* [[SBX]]&lt;br /&gt;
* [[TwinRX]]&lt;br /&gt;
* [[UBX]]&lt;br /&gt;
* [[WBX]]&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* [[OctoClock CDA-2990]]&lt;br /&gt;
* [[GPSDO]]&lt;br /&gt;
* [[Antennas]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Software Resources|&amp;lt;i class=&amp;quot;fa fa-desktop&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Software Resources]] ==&lt;br /&gt;
'''Ettus Products'''&lt;br /&gt;
* [[UHD]]&lt;br /&gt;
* [[UHD Python API]]&lt;br /&gt;
* [[Getting_Started_with_RFNoC_in_UHD_4.0|RFNoC (UHD 4.x)]]&lt;br /&gt;
* [[RFNoC]] (UHD 3.x)&lt;br /&gt;
&lt;br /&gt;
'''Third Party'''&lt;br /&gt;
* [[GNU Radio]]&lt;br /&gt;
* [[LabVIEW]]&lt;br /&gt;
* [[Matlab/Simulink]]&lt;br /&gt;
* [[OpenBTS]]&lt;br /&gt;
* [[Eurecom OpenAirInterface (OAI)]]&lt;br /&gt;
* [[srsLTE/srsUE]]&lt;br /&gt;
* [[Gqrx]]&lt;br /&gt;
* [[Fosphor]]&lt;br /&gt;
&lt;br /&gt;
'''Reference Architectures'''&lt;br /&gt;
* [[Open Architecture For Radar and EW Research]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[UHD and USRP User Manual|&amp;lt;i class=&amp;quot;fa fa-flag&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; UHD and USRP User Manual]] ==&lt;br /&gt;
'''Software'''&lt;br /&gt;
* [http://files.ettus.com/manual/ UHD Manual (master)]&lt;br /&gt;
* [https://files.ettus.com/manual_archive/ UHD Manual Archive (previous releases)]&lt;br /&gt;
&lt;br /&gt;
'''Motherboards'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_b200.html  B200/B210/B200mini/B205mini]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_x3x0.html X300/X310]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp2.html N200/N210]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_n3xx.html N300/N310/N320/N321]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_e3xx.html E310/E312/E313/E320]&lt;br /&gt;
&lt;br /&gt;
'''Daughterboards'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_basictx BasicRX/LFRX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_basicrx BasicTX/LFTX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_cbx CBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_sbx SBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_wbx WBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_ubx UBX]&lt;br /&gt;
* [http://files.ettus.com/manual/page_dboards.html#dboards_twinrx TwinRX]&lt;br /&gt;
&lt;br /&gt;
'''Other'''&lt;br /&gt;
* [http://files.ettus.com/manual/page_octoclock.html OctoClock]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Application Notes|&amp;lt;i class=&amp;quot;fa fa-file-text-o&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Application Notes]] ==&lt;br /&gt;
Application Notes (AN) and technical articles written by engineers, for engineers. These articles offer experienced analysis, design ideas, reference designs, and tutorials—to make you productive and successful using USRP devices.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Additional Resources|&amp;lt;i class=&amp;quot;fa fa-book&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Additional Resources]] ==&lt;br /&gt;
* [[Suggested Reading|Suggested Reading]]&lt;br /&gt;
* [[Suggested Videos|Suggested Videos]]&lt;br /&gt;
* [[SDR Events]]&lt;br /&gt;
* [[CGRAN]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Technical Support|&amp;lt;i class=&amp;quot;fa fa-life-ring&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Technical Support]] ==&lt;br /&gt;
* [[Email|Email]]&lt;br /&gt;
* [[Mailing Lists|Mailing Lists]]&lt;br /&gt;
* [[Slack|Slack]]&lt;br /&gt;
* [[Internet Relay Chat (IRC)|Internet Relay Chat (IRC)]]&lt;br /&gt;
* [[StackExchange|StackExchange]]&lt;br /&gt;
* [[Ordering and Fulfillment Help | Ordering and Fulfillment Help]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Faq|&amp;lt;i class=&amp;quot;fa fa-info-circle&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; FAQ]] ==&lt;br /&gt;
* [[Technical FAQ|Technical]]&lt;br /&gt;
* [[Licensing FAQ|Licensing]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;col-1-3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Legacy Products| &amp;lt;i class=&amp;quot;fa fa-hourglass-end&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Legacy Products]] ==&lt;br /&gt;
'''Motherboards'''&lt;br /&gt;
* [[USRP1|USRP1]]&lt;br /&gt;
* [[USRP2|USRP2]]&lt;br /&gt;
* [[E100/E110|E100/E110]]&lt;br /&gt;
* [[B100]]&lt;br /&gt;
&lt;br /&gt;
'''Daughterboards'''&lt;br /&gt;
* [[DBSRX2]]&lt;br /&gt;
* [[TVRX2]]&lt;br /&gt;
* [[XCVR2450]]&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5228</id>
		<title>Using the RFNoC Replay Block</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Using_the_RFNoC_Replay_Block&amp;diff=5228"/>
				<updated>2021-10-19T19:10:41Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Removed history section. Updated for UHD 3.15. Added note about UHD 4 not being covered by this article.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number==&lt;br /&gt;
'''AN-642'''&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This application note guides a user through basic use of the RFNoC Replay block in UHD 3.x and explains how to run the UHD Replay example. This example covers use on the X300/X310 and N310 products. UHD 4.0 and later is not covered by this application note.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
The Replay block is an RFNoC block that allows recording and playback of arbitrary data using DRAM on the USRP hardware as a buffer. To use the Replay block, it must be instantiated in the design and connected to the DRAM interface. It can take the place of the DMA FIFO(s) or be used concert with the DMA FIFO(s). In this note we will be replacing the DMA FIFO block with the Replay block and running a UHD example that records data to DRAM from a file then plays it back over the radio continuously.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Before you begin, make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
===Cloning the Repository===&lt;br /&gt;
&lt;br /&gt;
Your system must be configured for RFNoC development to compile and use the RFNoC examples. Here we briefly explain how to setup a system to build and run the RFNoC Replay example.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note AN-823 [[Getting Started with RFNoC Development]] for a more detailed overview of RFNoC development.&lt;br /&gt;
&lt;br /&gt;
To begin, use the following &amp;lt;code&amp;gt;git clone&amp;lt;/code&amp;gt; command to download the needed UHD repository. The &amp;lt;code&amp;gt;--recursive&amp;lt;/code&amp;gt; option causes the latest compatible FPGA code to also be cloned into the &amp;lt;code&amp;gt;fpga-src&amp;lt;/code&amp;gt; subfolder.&lt;br /&gt;
&lt;br /&gt;
    $ git clone --recursive https://github.com/EttusResearch/uhd.git&lt;br /&gt;
&lt;br /&gt;
Then checkout the appropriate version of UHD that you intend to use. Replay block support was added in UHD 3.14. The latest UHD 3.x version is recommended.&lt;br /&gt;
&lt;br /&gt;
    $ git checkout UHD-3.15.LTS&lt;br /&gt;
    $ git submodule update --recursive&lt;br /&gt;
&lt;br /&gt;
===Building and Installing UHD===&lt;br /&gt;
&lt;br /&gt;
If you have not already done so, follow the steps in Application Note '''AN-445''' under the heading [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux#Update_and_Install_dependencies|Update and Install dependencies]].&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to Application Note [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux|AN-445]] for detailed instructions on building and installing UHD from the source code. However, RFNoC must be enabled when running CMake in order to run the RFNoC examples. The instructions below summarize the basic steps required to build and install UHD so that you can run the Replay example.&lt;br /&gt;
&lt;br /&gt;
To build and install UHD, begin by opening a terminal in the UHD repository that you cloned, then create a &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; folder within the &amp;lt;code&amp;gt;host&amp;lt;/code&amp;gt; host folder of the repository.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
&lt;br /&gt;
Run CMake with RFNoC enabled to create the Makefiles.&lt;br /&gt;
&lt;br /&gt;
    $ cmake -DENABLE_RFNOC=ON ../&lt;br /&gt;
&lt;br /&gt;
Run Make to build UHD with RFNoC support.&lt;br /&gt;
&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
Install UHD, using the default install prefix, which will install UHD under the &amp;lt;code&amp;gt;/usr/local/lib&amp;lt;/code&amp;gt; folder. You need to run this as root due to the permissions on that folder.&lt;br /&gt;
&lt;br /&gt;
   $ sudo make install&lt;br /&gt;
&lt;br /&gt;
Update the system's shared library cache.&lt;br /&gt;
&lt;br /&gt;
   $ sudo ldconfig&lt;br /&gt;
&lt;br /&gt;
Make sure that the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; environment variable is defined and includes the folder under which UHD was installed. Most commonly, you can add the line below to the end of your &amp;lt;code&amp;gt;$HOME/.bashrc&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' the &amp;lt;code&amp;gt;LD_LIBRARY_PATH&amp;lt;/code&amp;gt; location may vary depending on your Linux distribution.&lt;br /&gt;
&lt;br /&gt;
   $ export LD_LIBRARY_PATH=/usr/local/lib&lt;br /&gt;
&lt;br /&gt;
===Installing the FPGA Tools===&lt;br /&gt;
&lt;br /&gt;
In order to build the FPGA image for the intended USRP product, you will need to have the Xilinx development tools installed. The specific version required depends on the branch and state of the FPGA code. The UHD-3.13 branches require Vivado 17.4. Refer to the installation instructions for Vivado in order to install these tools. It is recommended that you use the default install location of &amp;lt;code&amp;gt;/opt/Xilinx/Vivado&amp;lt;/code&amp;gt; to ensure compatibility with the FPGA build flow.&lt;br /&gt;
&lt;br /&gt;
==Building the FPGA==&lt;br /&gt;
&lt;br /&gt;
In order to use the Replay block, it must be built into the FPGA image for the USRP you plan to use. This is currently a manual step. The instructions below are for the X310, but similar instructions apply to the N310.&lt;br /&gt;
&lt;br /&gt;
First, we must modify the Verilog code to include the Replay Block. To do this, modify the file &amp;lt;code&amp;gt;fpga-src/top/x300/x300_core.v&amp;lt;/code&amp;gt; and change localparam &amp;lt;code&amp;gt;USE_REPLAY&amp;lt;/code&amp;gt; from 0 to 1. This causes the FPGA code to instantiate &amp;lt;code&amp;gt;noc_block_replay&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt;. Note that the DMA FIFO will not be included in this example and therefore cannot be used.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' If using the N310, modify the file &amp;lt;code&amp;gt;fpga-src/top/n3xx/n3xx_core.v&amp;lt;/code&amp;gt; and make the same change. Other products that support RFNoC can also use the replay block. However, in other products, the noc_block_replay instance would need to be manually instantiated in the code following the examples given in the &amp;lt;code&amp;gt;x300_core.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;n3xx_core.v&amp;lt;/code&amp;gt; files.&lt;br /&gt;
&lt;br /&gt;
After making the required code change, you are ready to rebuild the FPGA image. Begin by setting up the environment to use the FPGA build tools.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/fpga-src/usrp3/top/x300&lt;br /&gt;
    $ source ./setup.sh&lt;br /&gt;
&lt;br /&gt;
Run make to build the desired FPGA image. For example, to build the X310 HG image, use the following command:&lt;br /&gt;
&lt;br /&gt;
    $ make X310_HG&lt;br /&gt;
&lt;br /&gt;
Once compilation is complete, download the image to your USRP product. For example, if the X310 HG image were connected to SFP port 0 (1 Gigabit Ethernet) using the default IP address, then you would run the following command.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args=&amp;quot;type=x300,addr=192.168.10.2&amp;quot; --fpga-path=./build-X310_HG/x300.bit&lt;br /&gt;
&lt;br /&gt;
After the download has completed, power cycle the X310 to load the new bitstream. Confirm that the Replay block appears in the system by running &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe --args=&amp;quot;addr=192.168.10.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You should see the &amp;lt;code&amp;gt;Replay&amp;lt;/code&amp;gt; block listed among the RFNoC blocks on the device.&lt;br /&gt;
&lt;br /&gt;
   |   |     _____________________________________________________&lt;br /&gt;
   |   |    /&lt;br /&gt;
   |   |   |       RFNoC blocks on this device:&lt;br /&gt;
   |   |   |   &lt;br /&gt;
   |   |   |   * Replay_0&lt;br /&gt;
   |   |   |   * Radio_0&lt;br /&gt;
   |   |   |   * Radio_1&lt;br /&gt;
   |   |   |   * DDC_0&lt;br /&gt;
   |   |   |   * DDC_1&lt;br /&gt;
   |   |   |   * DUC_0&lt;br /&gt;
   |   |   |   * DUC_1&lt;br /&gt;
&lt;br /&gt;
==Building the Replay Example==&lt;br /&gt;
&lt;br /&gt;
In this section we will compile the replay_from_file UHD example. Begin by creating a CMake file for the Replay example using &amp;lt;code&amp;gt;uhd/host/examples/init_usrp/CMakeLists.txt&amp;lt;/code&amp;gt; as an example.&lt;br /&gt;
&lt;br /&gt;
    $ cd uhd/host/examples&lt;br /&gt;
    $ mkdir replay_samples_from_file&lt;br /&gt;
    $ cd replay_samples_from_file&lt;br /&gt;
    $ cp ../init_usrp/CMakeLists.txt ./&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; and change the &amp;lt;code&amp;gt;init_usrp&amp;lt;/code&amp;gt; references to &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;init_usrp.cpp&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;../replay_samples_from_file.cpp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:uhd cpp makefile edits.png|650px]]&lt;br /&gt;
&lt;br /&gt;
You can now invoke CMake and run Make to build the example.&lt;br /&gt;
&lt;br /&gt;
    $ mkdir build&lt;br /&gt;
    $ cd build&lt;br /&gt;
    $ cmake ../&lt;br /&gt;
    $ make&lt;br /&gt;
&lt;br /&gt;
==Running the Example==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example assumes that you have a file containing the samples you wish to replay. This could be generated in advance or recorded using &amp;lt;code&amp;gt;rx_samples_to_file&amp;lt;/code&amp;gt; or another method. For this demonstration, we'll create a simple Python program (&amp;lt;code&amp;gt;sample_gen.py&amp;lt;/code&amp;gt;) to generate some samples to use:&lt;br /&gt;
&lt;br /&gt;
    import math&lt;br /&gt;
    import struct&lt;br /&gt;
    &lt;br /&gt;
    SAMPLE_RATE = 200.0e6        # Sample rate in Hz&lt;br /&gt;
    FREQUENCY   = 500.0e3        # Frequency of sinusoid to generate, in Hz&lt;br /&gt;
    NUM_SAMPLES = 16000          # Number of samples to generate&lt;br /&gt;
    AMPLITUDE   = 0.5            # Amplitude of the signal (from 0 to 1.0)&lt;br /&gt;
    FILE_NAME   = 'samples.dat'&lt;br /&gt;
    &lt;br /&gt;
    file = open(FILE_NAME, 'wb')&lt;br /&gt;
    &lt;br /&gt;
    for i in range(NUM_SAMPLES):&lt;br /&gt;
        I = int((2**15-1) * AMPLITUDE * math.cos(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        Q = int((2**15-1) * AMPLITUDE * math.sin(i / (SAMPLE_RATE / FREQUENCY) * 2 * math.pi))&lt;br /&gt;
        file.write(struct.pack('&amp;lt;2h', I, Q))&lt;br /&gt;
    &lt;br /&gt;
    file.close()&lt;br /&gt;
&lt;br /&gt;
This program generates a file named &amp;lt;code&amp;gt;samples.dat&amp;lt;/code&amp;gt; that contains 16000 samples (40 periods) of a 500&amp;amp;nbsp;kHz tone sampled at a rate of 200&amp;amp;nbsp;MHz. Each sample is saved in &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; format (signed complex with 16-bit real and 16-bit imaginary components). We can run the program by invoking python from the command line.&lt;br /&gt;
&lt;br /&gt;
    $ python ./sample_gen.py&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does not perform rate conversion (i.e., the the DUC is not used), so the rate specified must match the native sample rate of your device (i.e., 200&amp;amp;nbsp;Msps for the X300/X310 or 125&amp;amp;nbsp;Msps for the N310). The samples file should contain &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; data samples and should be a multiple of 2 samples (8 bytes) in size, since the Replay block records and plays back in multiples of 8 bytes. For example, for the N310 you could change &amp;lt;code&amp;gt;SAMPLE_RATE&amp;lt;/code&amp;gt; in the Python program to 125.0e6, which would result in 64 periods of the 500&amp;amp;nbsp;kHz tone.&lt;br /&gt;
&lt;br /&gt;
To run the UHD Replay example, you could enter a command like the following.&lt;br /&gt;
&lt;br /&gt;
    $ ./replay_samples_from_file --freq 915e6 --gain 10 --file samples.dat&lt;br /&gt;
&lt;br /&gt;
This example would stream the samples from the file to the Replay block on the FPGA, where they are recorded into the USRP's on-board DRAM, then would cause Replay block to play back the samples to the radio continuously with a base frequency of 915 MHz, creating a tone at 915.5 MHz. Press &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; to stop transmitting.&lt;br /&gt;
&lt;br /&gt;
==Using the Replay Block==&lt;br /&gt;
&lt;br /&gt;
The Replay block is contained in &amp;lt;code&amp;gt;noc_block_replay.v&amp;lt;/code&amp;gt;. This block works like a record and playback buffer that uses DRAM on the USRP to store samples. It connects to the RFNoC crossbar and to the DRAM in the same way that the &amp;lt;code&amp;gt;noc_block_axi_dma_fifo&amp;lt;/code&amp;gt; block does. Data can be streamed to the block, like to any other RFNoC block. Playback is analogous to the way the &amp;lt;code&amp;gt;noc_block_radio_core&amp;lt;/code&amp;gt; works when we ask it to receive radio samples.&lt;br /&gt;
&lt;br /&gt;
One key difference is that the Replay block works only with 64-bit samples. Therefore, all addresses, buffer sizes, and transfers should be a multiple of 8 bytes. For example, when using &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt; samples (4 bytes each) everything should be a multiple of two samples to ensure we are always working with multiples of 8 bytes.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Refer to the example source code in &amp;lt;code&amp;gt;replay_samples_from_file.cpp&amp;lt;/code&amp;gt; for a more detailed example of how to use the Replay block.&lt;br /&gt;
&lt;br /&gt;
Prior to streaming data to the Replay block for recording, it is necessary to configure the base address and size of the record buffer.&lt;br /&gt;
&lt;br /&gt;
    // Configure the record buffer&lt;br /&gt;
    replay_ctrl-&amp;gt;config_record(buffer_start_byte_address, buffer_size_in_bytes, replay_chan);&lt;br /&gt;
&lt;br /&gt;
This tells the Replay block that it should start recording any data it receives into the DRAM at byte offset &amp;lt;code&amp;gt;buffer_start_byte_address&amp;lt;/code&amp;gt; and should use up to &amp;lt;code&amp;gt;buffer_size_in_bytes&amp;lt;/code&amp;gt; bytes. Once the buffer is filled, recording automatically stops. Care should be taken to configure the memory buffers so that they do not overlap if more than one Replay block or buffer is being used simultaneously. The memory addresses and sizes should be 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Care should be taken to not transfer more data to the Replay block than the size of the record buffer. Additional data is not accepted or dropped by the replay block, but flow control will cause data to back up in the RF network on the FPGA.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The amount of memory available to the Replay block is limited by the size of the DRAM on the USRP and how the memory interface is configured on the USRP. For example, the &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; IP used by the X310 is configured to give each connected device an address space of 32&amp;amp;nbsp;MiB. As a result, the Replay block will be limited to this amount of memory. The &amp;lt;code&amp;gt;axi_intercon_2x64_128_bd&amp;lt;/code&amp;gt; file must be modified if more than 32&amp;amp;nbsp;MiB needs to be buffered.&lt;br /&gt;
&lt;br /&gt;
To begin recording data to the Replay block, the record logic should be initialized:&lt;br /&gt;
&lt;br /&gt;
    replay_ctrl-&amp;gt;record_restart(replay_chan);&lt;br /&gt;
&lt;br /&gt;
This resets the record pointer to point back to the beginning of the buffer and it resets the internal counters that track how much data has been recorded. If a previous recording has taken place then it is a good idea to ensure that stale data was not queued up in the RF network on the FPGA from a previous run. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example does this by calling &amp;lt;code&amp;gt;record_restart()&amp;lt;/code&amp;gt; then waiting to see if any new data shows up unexpectedly in the record buffer. If so, it restarts recording then waits again to see if data continues to appear.&lt;br /&gt;
&lt;br /&gt;
You can determine when all data has been received by checking the status of the record fullness.&lt;br /&gt;
&lt;br /&gt;
    // Wait for recording to complete&lt;br /&gt;
    while (replay_ctrl-&amp;gt;get_record_fullness(replay_chan) &amp;lt; num_bytes_expected);&lt;br /&gt;
&lt;br /&gt;
Prior to playing back recorded data, it is necessary to configure the base address and size of the playback buffer. To play back previously recorded data, set the start address to the same address that was used for the record buffer and set the size of the playback buffer to the match the amount of data that was recorded. Note that the record and playback buffers do not need to the same, allowing a single Replay block to both record and playback to different regions of memory simultaneously.&lt;br /&gt;
&lt;br /&gt;
    // Configure the Replay block to play back everything that was recorded&lt;br /&gt;
    num_bytes_recorded = replay_ctrl-&amp;gt;get_record_fullness(replay_chan);&lt;br /&gt;
    replay_ctrl-&amp;gt;config_play(buffer_start_byte_address, num_bytes_recorded, replay_chan);&lt;br /&gt;
&lt;br /&gt;
To play back the data in the playback buffer, issue the appropriate UHD stream command. Playback automatically wraps around to the start of the buffer if more data is requested than the size of the playback buffer.&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);&lt;br /&gt;
    stream_cmd.num_samps  = words_to_replay;&lt;br /&gt;
    stream_cmd.stream_now = true;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd, replay_chan);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;STREAM_MODE_START_CONTINUOUS&amp;lt;/code&amp;gt; causes playback to continue indefinitely until explicitly stopped. &amp;lt;code&amp;gt;STREAM_MODE_NUM_SAMPS_AND_DONE&amp;lt;/code&amp;gt; causes only the specified number of samples to be played once. The &amp;lt;code&amp;gt;num_samps&amp;lt;/code&amp;gt; parameter is a 28-bit value, limiting this mode of playback to 2&amp;lt;sup&amp;gt;28&amp;lt;/sup&amp;gt; words at a time. Playback can be stopped by issuing a stop command.&lt;br /&gt;
&lt;br /&gt;
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;&lt;br /&gt;
    replay_ctrl-&amp;gt;issue_stream_cmd(stream_cmd);&lt;br /&gt;
&lt;br /&gt;
This will stop playback at the end of the next DRAM read after the command is received (DRAM reads are not aborted mid-transaction). As a result, some data will continue to stream from the Replay block after the stop command is issued while waiting for the DRAM read to complete and for all the internal buffers to empty. The &amp;lt;code&amp;gt;replay_samples_from_file&amp;lt;/code&amp;gt; example determines when playback streaming has stopped by reading the 64-bit &amp;lt;code&amp;gt;SR_READBACK_REG_GLOBAL_PARAMS&amp;lt;/code&amp;gt; register and waiting for the packet count to stop increasing.&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	<entry>
		<id>https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_in_UHD_4.0&amp;diff=5114</id>
		<title>Getting Started with RFNoC in UHD 4.0</title>
		<link rel="alternate" type="text/html" href="https://kb.ettus.com/index.php?title=Getting_Started_with_RFNoC_in_UHD_4.0&amp;diff=5114"/>
				<updated>2021-06-28T15:17:28Z</updated>
		
		<summary type="html">&lt;p&gt;WadeFife: Added more information/corrections about how to choose a clock domain for the FFT block.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Application Note Number and Authors==&lt;br /&gt;
'''AN-400''' by Sugandha Gupta, Brent Stapleton, Wade Fife, and Michael Dickens&lt;br /&gt;
&amp;lt;!-- Internal use only: please do keep this updated!&lt;br /&gt;
==Revision History==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Date&lt;br /&gt;
!Author&lt;br /&gt;
!Details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-02-14&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Sugandha Gupta&amp;lt;br&amp;gt;Brent Stapleton&amp;lt;br&amp;gt;Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:left;&amp;quot;| Initial creation&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2020-09-14&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Wade Fife&lt;br /&gt;
|style=&amp;quot;text-align:left;&amp;quot;| Added introduction to RFNoC&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-02-18&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:left;&amp;quot;| Minor but critical tweak of `srcport` per https://github.com/EttusResearch/uhd/issues/416&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| 2021-03-02&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| Michael Dickens&lt;br /&gt;
|style=&amp;quot;text-align:left;&amp;quot;| re-tweak `srcport` per certain USRPs as noted&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This guide describes how to get started with FPGA and Software development for RF Network-on-Chip (RFNoC™). It gives a brief introduction to RFNoC and explains the steps needed to generate, build, and use custom RFNoC images and introduces the process for creating and integrating new RFNoC IP blocks.&lt;br /&gt;
&amp;lt;!-- A guide to migrating a block created in earlier versions of RFNoC (UHD 3) to RFNoC in UHD 4 can be found in the RFNoC Migration Guide. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Intended Audience==&lt;br /&gt;
This guide is written for hardware and software engineers who want to use the RF Network-on-Chip (RFNoC™) architecture or want to develop intellectual property (IP) using the RFNoC architecture. For more details on the architecture please refer to the [https://files.ettus.com/app_notes/RFNoC_Specification.pdf RFNoC Specification].&lt;br /&gt;
&lt;br /&gt;
This guide assumes that you have some basic familiarity with USRPs, such as connecting them, configuring your network interfaces, etc., so that your USRP is ready for use. See the [https://kb.ettus.com/Getting_Started_Guides Getting Started Guide] for your USRP if you are just getting started with USRPs.&lt;br /&gt;
&lt;br /&gt;
==Licensing==&lt;br /&gt;
The RFNoC code base is open source, including code that executes on the host, as well as code targeted to the USRP hardware (FPGA and microcontroller firmware). RFNoC is available under the open-source GNU Lesser General Public License (LGPL). For more information on our licensing policy, please contact [mailto:info@ettus.com info@ettus.com].&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
RFNoC is currently supported on all the Generation-3 USRPs in the X series (X3xx), E series (E3xx) and  N series (N3xx). For details on the hardware, software, and process required to build custom USRP FPGA images that include RFNoC blocks, see the [http://files.ettus.com/manual/md_usrp3_build_instructions.html USRP Build Documentation] in the UHD and USRP Manual.&lt;br /&gt;
&lt;br /&gt;
It is recommended that you learn how to build an FPGA image for your USRP and download it to the device before starting this guide if you have never done so before. This will ensure you have all the necessary software installed.&lt;br /&gt;
&lt;br /&gt;
==Introduction to RFNoC==&lt;br /&gt;
&lt;br /&gt;
===What is RFNoC?===&lt;br /&gt;
&lt;br /&gt;
RFNoC™ is a heterogeneous processing framework used to implement high-throughput DSP in the FPGA for Software Defined Radio (SDR) systems in an easy-to-use and flexible way. It provides all the infrastructure required to insert signal-processing IP into the FPGA logic and communicate with it through software. It also provides highly-optimized software and FPGA code to enable high-performance streaming to and from IP blocks on the USRP device.&lt;br /&gt;
&lt;br /&gt;
The IP blocks in RFNoC are called ''RFNoC blocks''. The RFNoC blocks wrap the IP and provide a custom interface to the RFNoC infrastructure through a tool-generated interface called the ''NoC Shell''. Many standard blocks are included in UHD 4.0. These blocks enable typical operation of the USRP and allow RFNoC to connect to the different hardware components of the USRP. Several of the included blocks are described in the section [[#Available RFNoC Blocks|Available RFNoC Blocks]]. You can mix the available blocks for your application, or develop your own custom RFNoC blocks with your own IP to open up new applications. The NoC Shell hides the complexity of RFNoC from your block, making it easy to plug your IP into the USRP.&lt;br /&gt;
&lt;br /&gt;
RFNoC is used on all Generation-3 USRPs and is installed with UHD 4.0. USRPs ship with a default RFNoC image that can be used as is, or can be modified and/or customized to suite your application. So if you're using a modern USRP, it's running RFNoC under the hood even if you haven't customized anything.&lt;br /&gt;
&lt;br /&gt;
===Example RFNoC Image===&lt;br /&gt;
&lt;br /&gt;
The diagram below shows a simplified view of an RFNoC FPGA image that is similar to the default images available on USRPs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:simplified_rfnoc_image_uhd_4.png|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that an RFNoC FPGA is made up of several components. A description of each one is provided below.&lt;br /&gt;
&lt;br /&gt;
* '''RFNoC Image Core'''&amp;lt;br&amp;gt;This is the main block of the RFNoC framework and instantiates the components that make up RFNoC. The contents of the image core are described by an RFNoC image core YAML file, and the Verilog code that represents this block is automatically generated by the RFNoC Image Builder tool based on the YAML description. In other words, you provide a description of what you want to be included in RFNoC and the tools generate the code to implement that description.&lt;br /&gt;
* '''Transport Adapter'''&amp;lt;br&amp;gt;The transport adapter is a component of the USRP that allows communication with an outside interface. These vary depending on the USRP model in use. For example, this could be a 10 Gbps Ethernet link for SFP+ port of the USRP, or a cabled PCIe interface.&lt;br /&gt;
* '''CHDR Crossbar'''&amp;lt;br&amp;gt;The CHDR crossbar is a dynamic router for RFNoC traffic. This is a high-throughput crossbar designed for RF streaming applications. It is reconfigurable at run time via software and can be used to configure routes between stream endpoints and transport adapters. The number of ports available is configurable by changing the RFNoC image core YAML file. CHDR (Condensed Hierarchical Datagram for RFNoC) refers to the network protocol that is used for RFNoC.&lt;br /&gt;
* '''Stream Endpoint (SEP)'''&amp;lt;br&amp;gt;The stream endpoint (SEP) provides the high-level flow control for traffic over the network. It also separates control traffic from data traffic to create a separate AXIS-Ctrl network for control traffic. Control traffic refers to things like register reads and writes for configuring and monitoring RFNoC blocks.&lt;br /&gt;
* '''Control Crossbar'''&amp;lt;br&amp;gt;The control crossbar is similar to the CHDR Crossbar, but is only for control traffic. It has a much lower throughput and has been optimized for control-traffic, making it much less resource intensive than the CHDR crossbar.&lt;br /&gt;
* '''Other Blocks'''&amp;lt;br&amp;gt;The DDC (digital down converter), DUC (digital up converter), and Radio in this example are RFNoC blocks that are included with UHD. These are standard components included the default USRP images and enable typical RF applications. Most blocks only communicate with the RFNoC network, but some blocks require access to external hardware interfaces, such as the radio or DRAM. In this example, the radio blocks connect to the radio hardware on the USRP.&lt;br /&gt;
&lt;br /&gt;
===Static vs. Dynamic Routing===&lt;br /&gt;
&lt;br /&gt;
The routes between blocks that go through the crossbar are ''dynamic''. That is, the routes can be changed at run time and are controlled by software. The CHDR crossbar is very powerful in that it allows any of its ports to communicate with each other. It allows for streaming between blocks on the same FPGA, between RFNoC blocks and a host computer, or between blocks on different USRPs. New signal processing chains can be added to this crossbar, as needed, for the application.&lt;br /&gt;
&lt;br /&gt;
Similarly, the control crossbar supports dynamic routing, allowing any RFNoC block to send control traffic to any other RFNoC block, even to blocks on a different USRP. Control traffic can also be sent from the host computer to the RFNoC blocks, for example to read/write registers. Additionally, RFNoC blocks can send control to the host computer. In this example, the Radio block sends control traffic to the computer to report specific events, such as overflow or underflow in the radio.&lt;br /&gt;
&lt;br /&gt;
The block connections that don't go through a crossbar (e.g., the connection from the radio to the DDC, and the DDC to the stream endpoint, etc.) are ''static'' connections. That is, they cannot be changed at run time. Making a connection static has the advantage that it does not require additional ports on the crossbar and that the connection can be made much simpler because the high-level network flow-control protocol used by CHDR is not required. This reduces latency between blocks and leads to FPGA resource savings, allowing more logic be included in a single FPGA image. The static connections are described by the RFNoC image core YAML file. In order to change the static connections, the YAML description needs to be updated and the FPGA image needs to be rebuilt.&lt;br /&gt;
&lt;br /&gt;
===RFNoC Customization===&lt;br /&gt;
&lt;br /&gt;
The RFNoC framework makes it easy to customize the RFNoC image and add your own IP blocks. Later on in this guide, we'll explore how you can customize the RFNoC image to add or remove blocks, as well as create your own RFNoC blocks and include them in your FPGA builds. This allows you to create highly-customized and high-performance FPGA images for your USRP.&lt;br /&gt;
&lt;br /&gt;
==Setting Up==&lt;br /&gt;
To use RFNoC in UHD 4.0 you need to perform the following:&lt;br /&gt;
&lt;br /&gt;
* Clone the UHD repository&lt;br /&gt;
* Install UHD&lt;br /&gt;
* Update your device's filesystem and FPGA image&lt;br /&gt;
&lt;br /&gt;
Building custom RFNoC images requires the FPGA source code and build system. These are included in the UHD repository, located in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;&amp;lt;/code&amp;gt; refers to the location where you cloned the UHD repository.&lt;br /&gt;
&lt;br /&gt;
Please see the [http://files.ettus.com/manual/page_install.html Binary Installation] for UHD installation documentation or [https://files.ettus.com/manual/page_build_guide.html Building and Installing] instructions to build and install UHD from source. Additionally, [[Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux|AN-445]] provides step-by step instructions for cloning the repository and installing UHD from source.&lt;br /&gt;
&lt;br /&gt;
Starting with UHD 3.15, RFNoC is enabled by default, and starting with UHD 4.0, it can no longer be disabled, so no additional instructions are necessary to install support for RFNoC in UHD.&lt;br /&gt;
&lt;br /&gt;
Many of the UHD utilities we will use in this guide are based on Python. Please ensure that your &amp;lt;code&amp;gt;PYTHONPATH&amp;lt;/code&amp;gt; is set correctly. If not set correctly, you will see errors indicating that Python could not find the &amp;lt;code&amp;gt;uhd&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;image_builder&amp;lt;/code&amp;gt; libraries. The correct setting may depend on where you installed UHD and which Linux distribution you are using. If you installed UHD from source to the default location on Ubuntu, you may need to add &amp;lt;code&amp;gt;/usr/local/lib/python3/dist-packages&amp;lt;/code&amp;gt; to your &amp;lt;code&amp;gt;PYTHONPATH&amp;lt;/code&amp;gt; variable. For example:&lt;br /&gt;
&lt;br /&gt;
    $ export PYTHONPATH=/usr/local/lib/python3/dist-packages&lt;br /&gt;
&lt;br /&gt;
Instructions for updating your device's filesystem (applicable to E3xx and N3xx) and FPGA image can be found in that device's [https://kb.ettus.com/Getting_Started_Guides Getting Started Guide]. If your filesystem is already up to date, or your device does not use a filesystem (e.g., X3xx), then instructions on flashing an FPGA image to a device can be found in the following locations:&lt;br /&gt;
&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs X3xx series]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_e3xx.html#e3xx_getting_started_fpga_update E3xx series]&lt;br /&gt;
* [http://files.ettus.com/manual/page_usrp_n3xx.html#n3xx_getting_started_fpga_update N3xx series]&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' FPGA images are specific to the USRP device, NOT the USRP series. For example, a USRP X300 FPGA image will NOT work on a USRP X310 and vice versa. Loading an image that does not correspond to your USRP device will likely lead to an error message but can brick the device under some circumstances.&lt;br /&gt;
&lt;br /&gt;
===Configure the Default Shell===&lt;br /&gt;
&lt;br /&gt;
Make sure you are using the &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt; shell. Many of the build scripts used by RFNoC are written for &amp;lt;code&amp;gt;Bash&amp;lt;/code&amp;gt;. See [[Software_Development_on_the_E3xx_USRP_-_Building_RFNoC_UHD_/_GNU_Radio_/_gr-ettus_from_Source#Reconfigure_Default_Shell|Reconfigure Default Shell]] in AN-315 for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
==Testing the Default FPGA Image==&lt;br /&gt;
&lt;br /&gt;
Before continuing, please verify that you have downloaded and flashed the latest FPGA image for your version of UHD. All FPGA images for Generation-3 and above devices are RFNoC images, so there is no requirement to download a special image for RFNoC.&lt;br /&gt;
&lt;br /&gt;
===Inspect the Default Image===&lt;br /&gt;
&lt;br /&gt;
Before we start customizing our FPGA, let's get familiar with the default FPGA image, which is pre-built with a set of RFNoC blocks.&lt;br /&gt;
&lt;br /&gt;
Run the following command, with your USRP connected to your PC, to see what is available on the device.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe --args type=x300&lt;br /&gt;
&lt;br /&gt;
Note that your &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; may be different, depending on the USRP device you're using. The example here works for X300/X310. Refer to the manual page on [https://files.ettus.com/manual/page_identification.html Identifying USRP Devices] for more details. If an RFNoC image was successfully loaded onto the USRP, the output will show something like the following:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;  _____________________________________________________&lt;br /&gt;
 /&lt;br /&gt;
|       Device: X-Series Device&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Mboard: X310&lt;br /&gt;
|   |   revision: 11&lt;br /&gt;
|   |   revision_compat: 7&lt;br /&gt;
|   |   product: 30818&lt;br /&gt;
|   |   mac-addr0: 00:80:2f:17:40:6d&lt;br /&gt;
|   |   mac-addr1: 00:80:2f:17:40:6e&lt;br /&gt;
|   |   gateway: 192.168.10.1&lt;br /&gt;
|   |   ip-addr0: 192.168.10.2&lt;br /&gt;
|   |   subnet0: 255.255.255.0&lt;br /&gt;
|   |   ip-addr1: 192.168.20.2&lt;br /&gt;
|   |   subnet1: 255.255.255.0&lt;br /&gt;
|   |   ip-addr2: 192.168.30.2&lt;br /&gt;
|   |   subnet2: 255.255.255.0&lt;br /&gt;
|   |   ip-addr3: 192.168.40.2&lt;br /&gt;
|   |   subnet3: 255.255.255.0&lt;br /&gt;
|   |   serial: 311EF81&lt;br /&gt;
|   |   FW Version: 6.0&lt;br /&gt;
|   |   FPGA Version: 38.0&lt;br /&gt;
|   |   FPGA git hash: be53058&lt;br /&gt;
|   |&lt;br /&gt;
|   |   Time sources:  internal, external, gpsdo&lt;br /&gt;
|   |   Clock sources: internal, external, gpsdo&lt;br /&gt;
|   |   Sensors: ref_locked&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       RFNoC blocks on this device:&lt;br /&gt;
|   |&lt;br /&gt;
|   |   * 0/DDC#0&lt;br /&gt;
|   |   * 0/DDC#1&lt;br /&gt;
|   |   * 0/DUC#0&lt;br /&gt;
|   |   * 0/DUC#1&lt;br /&gt;
|   |   * 0/Radio#0&lt;br /&gt;
|   |   * 0/Radio#1&lt;br /&gt;
|   |   * 0/Replay#0&lt;br /&gt;
|     _____________________________________________________&lt;br /&gt;
|    /&lt;br /&gt;
|   |       Static connections on this device:&lt;br /&gt;
|   |&lt;br /&gt;
|   |   * 0/SEP#0:0==&amp;gt;0/DUC#0:0&lt;br /&gt;
|   |   * 0/DUC#0:0==&amp;gt;0/Radio#0:0&lt;br /&gt;
|   |   * 0/Radio#0:0==&amp;gt;0/DDC#0:0&lt;br /&gt;
|   |   * 0/DDC#0:0==&amp;gt;0/SEP#0:0&lt;br /&gt;
|   |   * 0/Radio#0:1==&amp;gt;0/DDC#0:1&lt;br /&gt;
|   |   * 0/DDC#0:1==&amp;gt;0/SEP#1:0&lt;br /&gt;
|   |   * 0/SEP#2:0==&amp;gt;0/DUC#1:0&lt;br /&gt;
|   |   * 0/DUC#1:0==&amp;gt;0/Radio#1:0&lt;br /&gt;
|   |   * 0/Radio#1:0==&amp;gt;0/DDC#1:0&lt;br /&gt;
|   |   * 0/DDC#1:0==&amp;gt;0/SEP#2:0&lt;br /&gt;
|   |   * 0/Radio#1:1==&amp;gt;0/DDC#1:1&lt;br /&gt;
|   |   * 0/DDC#1:1==&amp;gt;0/SEP#3:0&lt;br /&gt;
|   |   * 0/SEP#4:0==&amp;gt;0/Replay#0:0&lt;br /&gt;
|   |   * 0/Replay#0:0==&amp;gt;0/SEP#4:0&lt;br /&gt;
|   |   * 0/SEP#5:0==&amp;gt;0/Replay#0:1&lt;br /&gt;
|   |   * 0/Replay#0:1==&amp;gt;0/SEP#5:0&lt;br /&gt;
...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More than this will likely be shown. The specifics of the output depend on the UHD version and which device you're running on. However, we're interested in the following sections:&lt;br /&gt;
&lt;br /&gt;
* '''Device description'''. At the top, there is a section with basic information about your device, such as serial number, revision, etc. You can use this information to verify that you are indeed communicating with the correct device, and that the device has been updated. The FPGA git hash identifies the commit from which the FPGA image was built.&lt;br /&gt;
* '''RFNoC blocks on this device'''. This section lists all the RFNoC blocks in the loaded FPGA image. The blocks are listed by their block IDs. For example, &amp;lt;code&amp;gt;0/Radio#0&amp;lt;/code&amp;gt; means that we're on device zero (&amp;lt;code&amp;gt;0/&amp;lt;/code&amp;gt;), and we're talking about the first radio (with index &amp;lt;code&amp;gt;#0&amp;lt;/code&amp;gt;). Unless you probe multiple devices at once by specifying multiple addresses in the &amp;lt;code&amp;gt;--args&amp;lt;/code&amp;gt; argument, the device number will always be zero, but the block index will change depending on the number of blocks of that type. For example, on X310, &amp;lt;code&amp;gt;Radio#0&amp;lt;/code&amp;gt; corresponds to RF A and &amp;lt;code&amp;gt;Radio#1&amp;lt;/code&amp;gt; corresponds to RF B.&lt;br /&gt;
* '''Static connections on this device'''. This section lists how the blocks are pre-connected in the FPGA image. For example, the line &amp;lt;code&amp;gt;0/Radio#0:0==&amp;gt;0/DDC#0:0&amp;lt;/code&amp;gt; means that radio zero, port zero (&amp;lt;code&amp;gt;:0&amp;lt;/code&amp;gt;), is connected statically to DDC zero, port zero. Static connections can only be changed at compile time when building the FPGA image.&lt;br /&gt;
&lt;br /&gt;
The connection endpoints labeled &amp;lt;code&amp;gt;SEP&amp;lt;/code&amp;gt; are not RFNoC blocks. They are Stream Endpoints (SEPs). SEPs can send data packets to one another, or to streamers in software, using the CHDR crossbar, which is a dynamic router on the FPGA.&lt;br /&gt;
&lt;br /&gt;
===Available RFNoC Blocks===&lt;br /&gt;
&lt;br /&gt;
Many RFNoC blocks come with UHD. The HDL source code for these blocks resides in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/lib/rfnoc/blocks/&amp;lt;/code&amp;gt;. several of the blocks are described below.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Block Name&lt;br /&gt;
!HDL Name&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|AddSub&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_addsub&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add/Subtract Verilog/VHDL/HLS Example&lt;br /&gt;
|-&lt;br /&gt;
|DmaFIFO&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_axi_ram_fifo&amp;lt;/code&amp;gt;&lt;br /&gt;
|FIFO that uses an AXI4 memory-mapped interface for storage. For use with external DRAM or on-chip SRAM.&lt;br /&gt;
|-&lt;br /&gt;
|DDC&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_ddc&amp;lt;/code&amp;gt;&lt;br /&gt;
|Digital Down Converter&lt;br /&gt;
|-&lt;br /&gt;
|DUC&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_duc&amp;lt;/code&amp;gt;&lt;br /&gt;
|Digital Up Converter&lt;br /&gt;
|-&lt;br /&gt;
|FFT&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_fft&amp;lt;/code&amp;gt;&lt;br /&gt;
|Fast Fourier Transform&lt;br /&gt;
|-&lt;br /&gt;
|FIR&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_fir_filter&amp;lt;/code&amp;gt;&lt;br /&gt;
|Finite Impulse Response Filter&lt;br /&gt;
|-&lt;br /&gt;
|Fosphor&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_fosphor&amp;lt;/code&amp;gt;&lt;br /&gt;
|FFT and waterfall display tool&lt;br /&gt;
|-&lt;br /&gt;
|KeepOneInN&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_keep_one_in_n&amp;lt;/code&amp;gt;&lt;br /&gt;
|Keep one sample/packet in N&lt;br /&gt;
|-&lt;br /&gt;
|LogPwr&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_logpwr&amp;lt;/code&amp;gt;&lt;br /&gt;
|Computes an estimate of log2(i^2+q^2)&lt;br /&gt;
|-&lt;br /&gt;
|MovingAverage&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_moving_avg&amp;lt;/code&amp;gt;&lt;br /&gt;
|Outputs the running average of the N most recent inputs of data stream&lt;br /&gt;
|-&lt;br /&gt;
|NullSrcSink&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_null_src_sink&amp;lt;/code&amp;gt;&lt;br /&gt;
|Data source generator, sink, and loopback for testing&lt;br /&gt;
|-&lt;br /&gt;
|Radio&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_radio&amp;lt;/code&amp;gt;&lt;br /&gt;
|Radio Interface&lt;br /&gt;
|-&lt;br /&gt;
|Replay&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_replay&amp;lt;/code&amp;gt;&lt;br /&gt;
|Record/Playblack using AXI4 memory-mapped interface. For use with external DRAM or on-chip SRAM.&lt;br /&gt;
|-&lt;br /&gt;
|SigGen&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_siggen&amp;lt;/code&amp;gt;&lt;br /&gt;
|Signal Generator. Supports sinusoidal, constant, and random outputs, with configurable gain.&lt;br /&gt;
|-&lt;br /&gt;
|SplitStream&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_split_stream&amp;lt;/code&amp;gt;&lt;br /&gt;
|Splits a single data stream into two&lt;br /&gt;
|-&lt;br /&gt;
|Switchboard&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_switchboard&amp;lt;/code&amp;gt;&lt;br /&gt;
|A configurable RFNoC datapath switch for testing&lt;br /&gt;
|-&lt;br /&gt;
|VectorIIR&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_vector_iir&amp;lt;/code&amp;gt;&lt;br /&gt;
|Implements an IIR filter with variable length delay line&lt;br /&gt;
|-&lt;br /&gt;
|Window&lt;br /&gt;
|&amp;lt;code&amp;gt;rfnoc_block_window&amp;lt;/code&amp;gt;&lt;br /&gt;
|Windowing module for use with FFT block&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Streaming Example===&lt;br /&gt;
&lt;br /&gt;
In the UHD installation directory, you'll find example applications (e.g., in &amp;lt;code&amp;gt;/usr/lib/uhd/examples/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;/usr/local/lib/uhd/examples/&amp;lt;/code&amp;gt;). We'll look at &amp;lt;code&amp;gt;rfnoc_rx_to_file&amp;lt;/code&amp;gt; to familiarize ourselves with the RFNoC API.&lt;br /&gt;
&lt;br /&gt;
If we look at the source code for this example (located at &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/host/examples/rfnoc_rx_to_file.cpp&amp;lt;/code&amp;gt;), we can see the components necessary in an RFNoC application. In the &amp;lt;code&amp;gt;UHD_SAFE_MAIN&amp;lt;/code&amp;gt; function, we create a few crucial objects, such as an RFNoC graph, a radio block controller, a DDC block controller, and an RX streamer.&lt;br /&gt;
&lt;br /&gt;
    uhd::rfnoc::rfnoc_graph::sptr graph = uhd::rfnoc::rfnoc_graph::make(args);&lt;br /&gt;
    ...&lt;br /&gt;
    uhd::rfnoc::radio_control::sptr radio_ctrl =&lt;br /&gt;
        graph-&amp;gt;get_block&amp;lt;uhd::rfnoc::radio_control&amp;gt;(radio_ctrl_id);&lt;br /&gt;
    ...&lt;br /&gt;
    uhd::rfnoc::ddc_block_control::sptr ddc_ctrl;&lt;br /&gt;
    ...&lt;br /&gt;
    uhd::rx_streamer::sptr rx_stream = graph-&amp;gt;create_rx_streamer(1, stream_args);&lt;br /&gt;
&lt;br /&gt;
We also make connections in our graph and configure our blocks.&lt;br /&gt;
&lt;br /&gt;
    // Connect blocks and commit the graph&lt;br /&gt;
    for (auto&amp;amp; edge : chain) {&lt;br /&gt;
        if (uhd::rfnoc::block_id_t(edge.dst_blockid).match(uhd::rfnoc::NODE_ID_SEP)) {&lt;br /&gt;
            graph-&amp;gt;connect(edge.src_blockid, edge.src_port, rx_stream, 0);&lt;br /&gt;
        } else {&lt;br /&gt;
            graph-&amp;gt;connect(&lt;br /&gt;
                edge.src_blockid, edge.src_port, edge.dst_blockid, edge.dst_port);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
    rate = radio_ctrl-&amp;gt;set_rate(rate);&lt;br /&gt;
    ...&lt;br /&gt;
    radio_ctrl-&amp;gt;set_rx_frequency(freq, radio_chan);&lt;br /&gt;
&lt;br /&gt;
Once our graph and blocks are configured, we use the &amp;lt;code&amp;gt;recv_to_file&amp;lt;/code&amp;gt; function to receive data from our device and write it to a file on our host computer. Running this example with the &amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; argument shows the available options. For example, to receive 3 seconds of data at a specific frequency and sample rate, we can run:&lt;br /&gt;
&lt;br /&gt;
    rfnoc_rx_to_file --args type=x300 --freq 2.4e9 --rate 10e6 --duration 3&lt;br /&gt;
&lt;br /&gt;
Now you are ready to move to the next step and build your own blocks and FPGA images.&lt;br /&gt;
&lt;br /&gt;
==RFNoC Image Builder==&lt;br /&gt;
&lt;br /&gt;
UHD provides tooling to help develop custom RFNoC images. In this guide we will demonstrate how to use the RFNoC Image Builder, which will allow you to change which blocks are included and the connections between blocks. Let's go over common decisions you'll have to make with this tool.&lt;br /&gt;
&lt;br /&gt;
* '''Blocks Included'''&amp;lt;br&amp;gt;The particular blocks to be included in the image is the most impactful decision you'll make in the image building process, both in terms of image functionality and FPGA resource utilization. Adding more blocks means more processing in the image, but it also means longer FPGA build times and less space in the FPGA.&lt;br /&gt;
* '''Static Connections'''&amp;lt;br&amp;gt;Recall that blocks can be statically connected, as opposed to connecting every block to the CHDR crossbar (dynamically connected). The number of dynamic connections has a large impact on the size of the CHDR crossbar, so static connections are used to lower resource utilization. However, once a block is statically connected in a chain of blocks, data cannot be sent between arbitrary blocks; it must traverse and be processed by each block in the order defined by the static connections.&lt;br /&gt;
* '''Hardware Connections'''&amp;lt;br&amp;gt;All blocks share some connections defined by the [https://files.ettus.com/app_notes/RFNoC_Specification.pdf RFNoC Specification]. These connections are made automatically and cannot be changed. Many blocks require additional connections, such as clocks for the internal DSP or external DRAM interfaces. These connections must also be specified.&lt;br /&gt;
&lt;br /&gt;
Now that we've gone over some of the considerations, let's look at how to actually build a custom RFNoC image. This begins with the RFNoC image core YAML description.&amp;lt;!-- TODO: Originally, I think we were also going to describe how to use GNU Radio to create/build an FPGA image. That would be cool. Maybe that should be in a separate KB? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Understanding the RFNoC Image YAML File===&lt;br /&gt;
&lt;br /&gt;
The image YAML file defines RFNoC blocks in the FPGA image. It is designed to be both human-readable and machine-parseable, which allows us to make edits quickly and easily. Each device type has a default YAML image file, which is named &amp;lt;code&amp;gt;&amp;lt;DEVICE&amp;gt;_rfnoc_image_core.yml&amp;lt;/code&amp;gt; (e.g., &amp;lt;code&amp;gt;x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt;). Take a look at the RFNoC image core YAML file for the X310 by opening &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/top/x300/x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt;. Notice that it has the following sections.&lt;br /&gt;
&lt;br /&gt;
* '''General Parameters'''&amp;lt;br&amp;gt;Here we define the device, the bit width of our CHDR connections, as well as some versioning and licensing.&lt;br /&gt;
* '''Stream Endpoints'''&amp;lt;br&amp;gt;In the &amp;lt;code&amp;gt;stream_endpoints&amp;lt;/code&amp;gt; section we list each stream endpoint (SEP) that we wish to instantiate. These will be directly connected to the CHDR crossbar and will allow us to make dynamic connections within the CHDR crossbar. Typically you will have one SEP that forms the start and end of a single DSP chain of RFNoC blocks.&amp;lt;br&amp;gt;You can also add some per-stream-endpoint configuration here, such as the ingress buffer size, which affects streaming performance from your computer to that SEP. For example, if we know that one SEP will be receiving data transferred from your computer to the USRP then a data buffer is needed to accept those incoming packets, in which case we specify the buffer size by setting the &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt; option on that SEP. Alternatively, if we know that a particular SEP only sends data from the USRP to the computer, then we won't need the ingress data buffer and we can set &amp;lt;code&amp;gt;buff-size&amp;lt;/code&amp;gt; to 0, thus saving FPGA resources.&amp;lt;br&amp;gt;Each SEP can have an AXIS-Ctrl and an AXIS-CHDR port, as indicated by the &amp;lt;code&amp;gt;ctrl&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; options. At least one AXIS-Ctrl port is required to communicate with the RFNoC blocks, so &amp;lt;code&amp;gt;ctrl&amp;lt;/code&amp;gt; typically enabled on just the first SEP. Every SEP will usually have AXIS-CHDR connections to one or more RFNoC blocks, so &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; is usually enabled on all SEPs.&lt;br /&gt;
* '''NoC Blocks'''&amp;lt;br&amp;gt;In the &amp;lt;code&amp;gt;noc_blocks&amp;lt;/code&amp;gt; section we specify all the RFNoC blocks to include in the FPGA image. We'll need to give each block a unique name and reference a block definition YAML file (which we'll discuss in a later section). The blocks chosen have the greatest impact on the functionality of the image, as well as providing very coarse control over the FPGA resource utilization. We'll look at how to change the blocks included in the image as part of our example below.&lt;br /&gt;
*'''Static Connections'''&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;connections&amp;lt;/code&amp;gt; section defines static connections between blocks, stream endpoints, and various hardware interfaces on the USRP. Statically connected chains of blocks will usually start and end at a stream endpoint (SEP). SEPs are automatically connected to the CHDR crossbar by the RFNoC infrastructure. Remember that data must be passed through the entire statically connected chain; dynamic connections cannot be made to the statically connected blocks in the middle of the chain. Other hardware connections, such as to the external DRAM, would also be specified here. We'll take a closer look at making connections as part of our example below.&lt;br /&gt;
* '''Clock Domains'''&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;clk_domains&amp;lt;/code&amp;gt; section defines which clocks to connect to each block's clock inputs. Some blocks do not need any clock connections beyond the base clocks required by RFNoC. These required connections are not listed here, since they are always the same for each block. Other blocks may require additional clocks. For example, the radio blocks should be connected to the &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; clock. Many other blocks require a &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; (Compute Engine) clock, which is used for the block's internal DSP.&lt;br /&gt;
&lt;br /&gt;
===Running the Image Builder===&lt;br /&gt;
&lt;br /&gt;
Before we look at editing the image core YAML file, let's go over how to use the RFNoC image builder to generate a bitstream from that YAML file. Additional details on how to run the image builder can be found with the &amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; option:&lt;br /&gt;
&lt;br /&gt;
    $ rfnoc_image_builder --help&lt;br /&gt;
&lt;br /&gt;
Here are some of the options provided:&lt;br /&gt;
* '''&amp;lt;code&amp;gt;-y&amp;lt;/code&amp;gt;''': Path to the RFNoC image core YAML file&lt;br /&gt;
* '''&amp;lt;code&amp;gt;-t&amp;lt;/code&amp;gt;''': The image target you would like to build. These are the same targets that are used in the FPGA &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; process. More details on these can be found in the [https://files.ettus.com/manual/md_usrp3_build_instructions.html Generation 3 USRP Build Documentation] of the UHD and USRP Manual. If not specified, the default specified in the image core YAML file will be used.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;-l debug&amp;lt;/code&amp;gt;''': Use the &amp;lt;code&amp;gt;debug&amp;lt;/code&amp;gt; log level. This prints more information about the FPGA connections and available port names, which can be useful for debugging connection errors in the YAML file.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;--generate-only&amp;lt;/code&amp;gt;''': Generate the HDL files required, but do not build the FPGA. Users can then build the FPGA later using &amp;lt;code&amp;gt;make &amp;lt;target&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt;''': Path to the directory containing out-of-tree block YAML descriptions (the YAML files installed with UHD are included by default). This option is only needed if using an out-of-tree RFNoC block.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;-F&amp;lt;/code&amp;gt;''': Path to the FPGA source code (e.g., &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga&amp;lt;/code&amp;gt;). This path is only required if the current working directory is not within the UHD repository.&lt;br /&gt;
&lt;br /&gt;
For example, to build the default RFNoC image for X310, you might use the following command:&lt;br /&gt;
&lt;br /&gt;
    $ cd &amp;lt;repo&amp;gt;/fpga/usrp3/top/x300/&lt;br /&gt;
    $ rfnoc_image_builder -y ./x310_rfnoc_image_core.yml -t X310_XG&lt;br /&gt;
&lt;br /&gt;
In this example &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;&amp;lt;/code&amp;gt; refers to the location where you cloned the UHD repository and should be replaced by the location you used. &amp;lt;code&amp;gt;x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt; is the default RFNoC image core YAML file for the X310, which is in the x300 project directory. &amp;lt;code&amp;gt;X310_XG&amp;lt;/code&amp;gt; is the make target to use for the build. &amp;lt;code&amp;gt;XG&amp;lt;/code&amp;gt; in this case refers to dual 10 Gbps Ethernet.&lt;br /&gt;
&lt;br /&gt;
For an out-of-tree RFNoC block, you will also need to specify the location of the block information. For example:&lt;br /&gt;
&lt;br /&gt;
    $ rfnoc_image_builder -F &amp;lt;repo&amp;gt;/fpga -I &amp;lt;repo&amp;gt;/host/examples/rfnoc-example -y &amp;lt;repo&amp;gt;/host/examples/rfnoc-example/icores/x310_rfnoc_image_core.yml -t X310_XG &lt;br /&gt;
&lt;br /&gt;
This example shows how to build an FPGA with the Gain example out-of-tree RFNoC block, which is located in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/host/examples/rfnoc-example/&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;-F&amp;lt;/code&amp;gt; option is added to specify the location of the FPGA source, and &amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt; specifies the location of the out-of-tree block YAML.&lt;br /&gt;
&lt;br /&gt;
The image builder performs several steps in order to build the FPGA image from the image coure YAML:&lt;br /&gt;
&lt;br /&gt;
# It generates the &amp;lt;code&amp;gt;&amp;lt;device&amp;gt;_rfnoc_image_core.v&amp;lt;/code&amp;gt; file. This file includes the Verilog code described by the YAML image core file. A &amp;lt;code&amp;gt;&amp;lt;device&amp;gt;_static_router.hex&amp;lt;/code&amp;gt; file is also generated. This file describes the static connections that should be made by the Verilog code. In the case of the X310 examples above, the output files would be named &amp;lt;code&amp;gt;x310_rfnoc_image_core.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;x310_static_router.hex&amp;lt;/code&amp;gt;, and would be placed in the project directory for the X310 (&amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/top/x300/&amp;lt;/code&amp;gt;).&lt;br /&gt;
# The image builder will configure the environment for building the FPGA. This is equivalent to sourcing the &amp;lt;code&amp;gt;setupenv.sh&amp;lt;/code&amp;gt; script for the device type being built. For example, in our example above, it would run &amp;lt;code&amp;gt;source &amp;lt;repo&amp;gt;/fpga/usrp3/top/x300/setupenv.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
# The image builder runs &amp;lt;code&amp;gt;make &amp;lt;target&amp;gt;&amp;lt;/code&amp;gt; to build the IP and the FPGA bitstream for the indicated target. The generated &amp;lt;code&amp;gt;rfnoc_image_core.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;static_router.hex&amp;lt;/code&amp;gt; are automatically pulled into this build. The completed bitstream will be located in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/top/{project}/build&amp;lt;/code&amp;gt; directory, which is the same directory created through the normal make process. For example, for X310 it would be located in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/fpga/usrp3/top/X300/build&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Example: Adding an FFT Block===&lt;br /&gt;
&lt;br /&gt;
As an example, let's run through how to modify the YAML file to modify the RFNoC image. Suppose we have an application that we'd like to run on a USRP X310 and we would like to offload the FFT processing to the FPGA. UHD provides an FFT RFNoC block, and the default X310 image has some extra space in it, so we should be able to add this block. First, we copy the default X310 image core file, named &amp;lt;code&amp;gt;x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
    $ cd &amp;lt;repo&amp;gt;/fpga/usrp3/top/x300/&lt;br /&gt;
    $ cp x310_rfnoc_image_core.yml x310_with_fft.yml&lt;br /&gt;
&lt;br /&gt;
Now open &amp;lt;code&amp;gt;x310_with_fft.yml&amp;lt;/code&amp;gt; in your favorite text editor. We'll start by making some room for our new block. The default images use very large ingress FIFO buffers for the main SEPs to maximize streaming performance. But we want to make sure we have enough memory buffer space for our new blocks. So Start by reducing the &amp;lt;code&amp;gt;buf_size&amp;lt;/code&amp;gt; parameters for &amp;lt;code&amp;gt;ep0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ep2&amp;lt;/code&amp;gt; from 65536 to 32768. If using a device other than X310, the numbers may be different, but you can similarly reduce the &amp;lt;code&amp;gt;buff_size&amp;lt;/code&amp;gt; parameter by half. On smaller devices, it may be necessary to remove the Replay block to make room for the FFT blocks. After making the changes on X310, the result should look like the following:&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      ep0:                       # Stream endpoint name&lt;br /&gt;
        ctrl: True                      # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 32768                # Ingress buffer size for data&lt;br /&gt;
      ...&lt;br /&gt;
      ep2:                       # Stream endpoint name&lt;br /&gt;
        ctrl: False                     # Endpoint passes control traffic&lt;br /&gt;
        data: True                      # Endpoint passes data traffic&lt;br /&gt;
        buff_size: 32768                # Ingress buffer size for data&lt;br /&gt;
&lt;br /&gt;
Now we can add our FFT block. We'll put it on its own stream endpoint, so we first need to add a new stream endpoint. Add the following to the &amp;lt;code&amp;gt;stream_endpoints&amp;lt;/code&amp;gt; section:&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      ...&lt;br /&gt;
      ep_fft:                # The name can be incremented from previous SEP&lt;br /&gt;
        ctrl: False          # Only the first SEP needs control traffic&lt;br /&gt;
        data: True           # We do want to pass data through this SEP&lt;br /&gt;
        buff_size: 32768     # Ingress buffer size for data&lt;br /&gt;
&lt;br /&gt;
In this example, we've named the SEP &amp;lt;code&amp;gt;ep_fft&amp;lt;/code&amp;gt;. Other names could be given, as long as the name is unique (it does not have to be numbered). Now that we've allocated an SEP for our block, we need to instantiate the actual block. In the next section, add the following:&lt;br /&gt;
&lt;br /&gt;
    noc_blocks:&lt;br /&gt;
      ...&lt;br /&gt;
      fft0:                          # FFT block name&lt;br /&gt;
        block_desc: 'fft_1x64.yml'   # Block YAML descriptor file&lt;br /&gt;
        parameters:                  # Specify any Verilog module parameters (optional)&lt;br /&gt;
          EN_FFT_SHIFT: 1&lt;br /&gt;
&lt;br /&gt;
Again, the name &amp;lt;code&amp;gt;fft0&amp;lt;/code&amp;gt; is arbitrary, but the name must be unique. In some cases, there will also be block parameters you'll want to pass, such as the data format of the FFT output data. In our example, we're setting &amp;lt;code&amp;gt;EN_FFT_SHIFT&amp;lt;/code&amp;gt; parameter to 1, which causes the FFT block to center the zero frequency bin.&lt;br /&gt;
&lt;br /&gt;
Now that we've added our FFT block, we need to connect it to the stream endpoint. In the next section of the YAML file, we add the static connections:&lt;br /&gt;
&lt;br /&gt;
    connections:&lt;br /&gt;
      ...&lt;br /&gt;
      - { srcblk: ep_fft, srcport: out0,  dstblk: fft0,   dstport: in_0 }&lt;br /&gt;
      - { srcblk: fft0,   srcport: out_0, dstblk: ep_fft, dstport: in0  }&lt;br /&gt;
&lt;br /&gt;
This connects the output of SEP &amp;lt;code&amp;gt;ep_fft&amp;lt;/code&amp;gt; to the input of block &amp;lt;code&amp;gt;fft0&amp;lt;/code&amp;gt;, and the output of &amp;lt;code&amp;gt;fft0&amp;lt;/code&amp;gt; to the input of &amp;lt;code&amp;gt;ep_fft&amp;lt;/code&amp;gt;. Since we're placing the FFT block on its own SEP, the only connections we need to make are between the SEP and the FFT. All SEPs are automatically connected to the CHDR crossbar, so this effectively connects the FFT block to the crossbar, allowing it to communicate with anything on the RFNoC network.&lt;br /&gt;
&lt;br /&gt;
The names of block ports are defined in the YAML descriptions for the blocks. Blocks can use any names for their ports, and they don't have to be numbered (unless the number of ports is parameterized). Generally, the block ports are named &amp;lt;code&amp;gt;in_N&amp;lt;/code&amp;gt; for inputs to the block and &amp;lt;code&amp;gt;out_N&amp;lt;/code&amp;gt; for outputs. SEP ports are named &amp;lt;code&amp;gt;in0&amp;lt;/code&amp;gt; for the input &amp;lt;code&amp;gt;out0&amp;lt;/code&amp;gt; for the output.&lt;br /&gt;
&lt;br /&gt;
If you are having trouble connecting a block due to an unresolved connection, running &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; with the &amp;lt;code&amp;gt;-l debug&amp;lt;/code&amp;gt; option will list all available block ports.&lt;br /&gt;
&lt;br /&gt;
Finally, the FFT block has an additional clock input port named &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; that is used for the FFT signal processing. We need to connect it to a clock domain. Any clock that's at least as fast as the incoming data rate should be sufficient. For example, X3xx devices have a &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock (214.286 MHz) that is usually a good choice, but &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock (200 MHz) should also work for this example. For N31x and E3xx devices, &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock is a good choice (200 MHz on N31x and 100 MHz on E3xx). For N32x, &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; clock (250 MHz) is a good choice. For example, this is how you would connect the X310's &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock to the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; port of the FFT block:&lt;br /&gt;
&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      ...&lt;br /&gt;
      - { srcblk: _device_, srcport: ce, dstblk: fft0, dstport: ce }&lt;br /&gt;
&lt;br /&gt;
And this is how you would connect &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock to the &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; port:&lt;br /&gt;
&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      ...&lt;br /&gt;
      - { srcblk: _device_, srcport: rfnoc_chdr, dstblk: fft0, dstport: ce }&lt;br /&gt;
&lt;br /&gt;
And finally, this is how you would connect &amp;lt;code&amp;gt;radio&amp;lt;/code&amp;gt; clock:&lt;br /&gt;
&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      ...&lt;br /&gt;
      - { srcblk: _device_, srcport: radio, dstblk: fft0, dstport: ce }&lt;br /&gt;
&lt;br /&gt;
The source block name &amp;lt;code&amp;gt;_device_&amp;lt;/code&amp;gt; is special and refers to the USRP device itself. Choose a clock that's apprpriate for your device and connect it as shown above.&lt;br /&gt;
&lt;br /&gt;
And that's it! The next step will be to run the image builder on our modified YAML file. Once that's done, and the bitstream has been created, you can load it onto your USRP X310 device, and verify the blocks, as we did in the [[#Inspect_the_Default_Image|Inspect the Default Image]] section.&lt;br /&gt;
&lt;br /&gt;
For example, from the X300 directory, you would run the following command to run the image builder:&lt;br /&gt;
&lt;br /&gt;
    $ rfnoc_image_builder -y x310_with_fft.yml -t X310_XG&lt;br /&gt;
&lt;br /&gt;
To download the FPGA bitstream to the X310, run the following:&lt;br /&gt;
&lt;br /&gt;
    $ uhd_image_loader --args &amp;quot;type=x300,addr=192.168.30.2&amp;quot; --fpga-path ./build/usrp_x310_fpga_XG.bin&lt;br /&gt;
&lt;br /&gt;
You may need to change the IP address to match your device, depending on your configuration. After completing the flash update and power-cycling the USRP, run &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt; to confirm that the FFT block was recognized.&lt;br /&gt;
&lt;br /&gt;
    $ uhd_usrp_probe --args &amp;quot;type=x300,addr=192.168.30.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Take a look at the RFNoC blocks and the static connections on the device. You should see the following new blocks and connections:&lt;br /&gt;
&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       RFNoC blocks on this device:&lt;br /&gt;
    ...&lt;br /&gt;
    |   |   * 0/FFT#0&lt;br /&gt;
    ...&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Static connections on this device:&lt;br /&gt;
    ...&lt;br /&gt;
    |   |   * 0/SEP#6:0==&amp;gt;0/FFT#0:0&lt;br /&gt;
    |   |   * 0/FFT#0:0==&amp;gt;0/SEP#6:0&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;!-- TODO: At this point were were supposed to have a description of how to&lt;br /&gt;
test the FFT block. We might want to use a Python example, to keep it simple, but here's what was originally in the document.&lt;br /&gt;
&lt;br /&gt;
Since we put the FFT block on its own SEP, verifying that it is operating correctly will be simple. We can start by running some test vectors through the block by making an RFNoC application that creates only the RFNoC graph, the FFT block controller, and both an RX and a TX streamer.&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;b&amp;gt;**************TODO**************&amp;lt;/b&amp;gt;&lt;br /&gt;
    // Make our controllers&lt;br /&gt;
    rfnoc_graph graph = graph(&amp;quot;&amp;quot;);&lt;br /&gt;
    auto fft_ctrl = graph-&amp;gt;get_block&amp;lt;fft_block_ctrl&amp;gt;(&amp;quot;0/FFT#0&amp;quot;);&lt;br /&gt;
    auto rx_streamer = graph-&amp;gt;get_rx_streamer();&lt;br /&gt;
    auto tx_streamer = graph-&amp;gt;get_tx_streamer();&lt;br /&gt;
     &lt;br /&gt;
    // Make connections&lt;br /&gt;
    graph-&amp;gt;connect(tx_streamer, fft);&lt;br /&gt;
    graph-&amp;gt;connect(fft, rx_streamer);&lt;br /&gt;
     &lt;br /&gt;
    // Make a test vector&lt;br /&gt;
    vec data = {0, 0.5, 1.};&lt;br /&gt;
    vec result(256);&lt;br /&gt;
     &lt;br /&gt;
    // Transmit to block&lt;br /&gt;
    tx_streamer.send(data);&lt;br /&gt;
    this_thread::sleep(10ms)&lt;br /&gt;
    rx_streamer.recv(result);&lt;br /&gt;
    // Verify&lt;br /&gt;
    // Check that each member in the result is as expected&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example: Adding an FFT Block to the Receive Chain===&lt;br /&gt;
&lt;br /&gt;
Now that we've added the FFT block and verified that it is operating as expected, let's see if we can modify it a little. Let's say that we're sure that we always want to receive the FFT bins from our device, and we don't want to see the raw samples. In order to save some FPGA resources, we can move our FFT block to be between the DDC and the SEP, on the RX data path. Instead of the previous modifications to our YAML file, we want the following:&lt;br /&gt;
&lt;br /&gt;
    stream_endpoints:&lt;br /&gt;
      ...&lt;br /&gt;
      # Unchanged from the default image core (no need for ep_fft).&lt;br /&gt;
    &lt;br /&gt;
    noc_blocks:&lt;br /&gt;
      ...&lt;br /&gt;
      fft0:                          # FFT block name&lt;br /&gt;
        block_desc: 'fft_1x64.yml'   # Block YAML descriptor file&lt;br /&gt;
        parameters:                  # Specify any Verilog module parameters (optional)&lt;br /&gt;
          EN_FFT_SHIFT: 1&lt;br /&gt;
    &lt;br /&gt;
    connections:&lt;br /&gt;
      ...&lt;br /&gt;
      # Change this line:&lt;br /&gt;
      # - { srcblk: ddc0, srcport: out_0, dstblk: ep0, dstport: in0  }&lt;br /&gt;
      # Change it to the following to add fft0 between ddc0 and ep0:&lt;br /&gt;
      - { srcblk: ddc0, srcport: out_0, dstblk: fft0, dstport: in_0 }&lt;br /&gt;
      - { srcblk: fft0, srcport: out_0, dstblk: ep0,  dstport: in0 }&lt;br /&gt;
&lt;br /&gt;
    clk_domains:&lt;br /&gt;
      ...&lt;br /&gt;
      # As before, we still connect our FFT block to the clock domain&lt;br /&gt;
      - { srcblk: _device_, srcport: rfnoc_chdr, dstblk: fft0, dstport: ce }&lt;br /&gt;
&lt;br /&gt;
This last line is valid for E310/E320; for X300/X310/N300/N310/N320/N321 use the following:&lt;br /&gt;
&lt;br /&gt;
      - { srcblk: _device_, srcport: ce, dstblk: fft0, dstport: ce }&lt;br /&gt;
&lt;br /&gt;
And as simply as that, we have added the FFT block to our RX block chain. Remember that this is a static connection, so when the resulting FPGA image is loaded onto your device, you will no longer be able to receive samples from the DDC directly; all samples on that chain will be processed by the FFT block, and you will only receive FFT bins from this radio chain.&lt;br /&gt;
&lt;br /&gt;
==Out-of-tree Modules==&lt;br /&gt;
&lt;br /&gt;
===OOT Overview===&lt;br /&gt;
&lt;br /&gt;
Now that we've gone over what is provided by UHD, let's start to look at custom RFNoC development. It's recommended that custom RFNoC development be kept separate from the in-tree UHD RFNoC infrastructure and examples, in order to simplify version control and licensing. Modules located outside of the repository are called ''out-of-tree'' (OOT).&lt;br /&gt;
&lt;br /&gt;
In order to understand how OOT modules for RFNoC are created, let's take a look at the example that's provided with UHD. You can find the example located in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/host/examples/rfnoc-example/&amp;lt;/code&amp;gt;. This example includes a simple Gain RFNoC block that we can use as a reference for creating our own OOT blocks.&lt;br /&gt;
&lt;br /&gt;
===OOT Subdirectories===&lt;br /&gt;
&lt;br /&gt;
Take a look at the &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt; directory structure. An OOT module is a collection of block implementations, the software controllers for those blocks, and sometimes applications to demonstrate their functionality. These different components within the OOT module are organized into the directories described below.&lt;br /&gt;
&lt;br /&gt;
* HDL and Image Resources&lt;br /&gt;
** &amp;lt;code&amp;gt;fpga/&amp;lt;/code&amp;gt;: Contains the HDL (e.g., Verilog) required for the module. Each RFNoC block should have its own subdirectory here, such as &amp;lt;code&amp;gt;rfnoc_block_gain&amp;lt;/code&amp;gt;, for the Gain block.&lt;br /&gt;
** &amp;lt;code&amp;gt;blocks/&amp;lt;/code&amp;gt;: Contains the YAML RFNoC block definition files. These describe the block's interfaces and are used by the image builder. We'll go into more detail with regards to what goes into these YAML files in the [[#Creating_Your_Own_RFNoC_Block|Creating Your Own RFNoC Block]] section.&lt;br /&gt;
** &amp;lt;code&amp;gt;icores/&amp;lt;/code&amp;gt;: Contains example FPGA image core YAML files, to demonstrate how to create an FPGA image using your custom blocks. These image core files may demonstrate important parameters or show recommended configurations for chains of blocks.&lt;br /&gt;
* Block Controller and Example Software&lt;br /&gt;
** &amp;lt;code&amp;gt;include/&amp;lt;/code&amp;gt;: Contains the headers for the block controller software. Once installed, these headers will be used by UHD and other applications to interface with and control your custom RFNoC blocks.&lt;br /&gt;
** &amp;lt;code&amp;gt;lib/&amp;lt;/code&amp;gt;: Contains the block controller implementations. The files here should implement the features outlined in the headers located in the &amp;lt;code&amp;gt;include/&amp;lt;/code&amp;gt; directory. All unit test code should also be located here.&lt;br /&gt;
** &amp;lt;code&amp;gt;apps/&amp;lt;/code&amp;gt;: Contains example applications for your custom blocks. These applications may demonstrate how to use the block controllers, common configurations, or how to process data from your blocks.&lt;br /&gt;
* Infrastructure&lt;br /&gt;
** &amp;lt;code&amp;gt;cmake/&amp;lt;/code&amp;gt;: Contains any custom CMake commands the module may need. In general, simple modules will not need to modify this directory at all. More complicated modules with additional external dependencies may need to modify this.&lt;br /&gt;
&lt;br /&gt;
Take some time to explore the files in the &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt;. Note the following files and directories related to the Gain example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/fpga/rfnoc_block_gain/&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;This is the HDL for the Gain RFNoC block.&lt;br /&gt;
** &amp;lt;code&amp;gt;rfnoc_block_gain.v&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The top-level synthesizable file for the Gain block&lt;br /&gt;
** &amp;lt;code&amp;gt;noc_shell_gain.v&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The NoC Shell for the Gain block&lt;br /&gt;
** &amp;lt;code&amp;gt;rfnoc_block_gain_tb.sv&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The simulation testbench&lt;br /&gt;
** &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The simulation Makefile&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/blocks/gain.yml&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The YAML block definition file for the Gain block&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/icores/x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;An example RFNoC image core YAML description showing how to connect the Gain block&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/include/rfnoc/example/gain_block_control.hpp&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The software block controller header&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/lib/gain_block_control.cpp&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;The software block controller implementation&lt;br /&gt;
* &amp;lt;code&amp;gt;rfnoc-example/apps/init_gain_block.cpp&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;An example showing how to find and initialize the Gain block&lt;br /&gt;
&amp;lt;!-- We should have an example that streams data that the customers can run using the Gain block --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating Your Own OOT Module===&lt;br /&gt;
&lt;br /&gt;
To create your own OOT module, make a copy of the &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt; directory. This will contain all the subdirectories and infrastructure files that you need to create your custom module. The directory name for your copy should be renamed to your desired name; we recommend something like &amp;lt;code&amp;gt;rfnoc-foo&amp;lt;/code&amp;gt;, for example, where &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name for your OOT module. You'll also need to change &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt; within the module's &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; files to your module's name.&lt;br /&gt;
&lt;br /&gt;
Let's start by creating our own copy of the &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt; to work with. We'll call our module &amp;lt;code&amp;gt;demo&amp;lt;/code&amp;gt;. You can put the copy wherever you like, but for this example we'll put it in our home directory. &lt;br /&gt;
&lt;br /&gt;
    $ cp -r &amp;lt;repo&amp;gt;/host/examples/rfnoc-example ~/&lt;br /&gt;
    $ mv ~/rfnoc-example ~/rfnoc-demo&lt;br /&gt;
&lt;br /&gt;
Now we need to edit our &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; files to rename our module. Edit the following files and change all instances of &amp;lt;code&amp;gt;rfnoc-example&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;rfnoc-demo&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
    ~/rfnoc-demo/CMakeLists.txt&lt;br /&gt;
    ~/rfnoc-demo/lib/CMakeLists.txt&lt;br /&gt;
&lt;br /&gt;
===Building and Installing an OOT Module===&lt;br /&gt;
The OOT module will need to be built and installed in order to use its RFNoC blocks. To build and install the OOT module we just created, do the following:&lt;br /&gt;
&lt;br /&gt;
    $ mkdir ~/rfnoc-demo/build&lt;br /&gt;
    $ cd ~/rfnoc-demo/build&lt;br /&gt;
    $ cmake -DUHD_FPGA_DIR=&amp;lt;repo&amp;gt;/fpga/ ../&lt;br /&gt;
&lt;br /&gt;
This configures the project to be installed in the default location. You may want to provide a different install directory to CMake using the &amp;lt;code&amp;gt;-DCMAKE_INSTALL_PREFIX&amp;lt;/code&amp;gt;. Please refer to the [https://files.ettus.com/manual/page_build_guide.html UHD Installation Guide] or the installation guide for other CMake-based projects for instructions on configuring CMake.&lt;br /&gt;
&lt;br /&gt;
Note that we specify the location of the FPGA source code using the &amp;lt;code&amp;gt;-DUHD_FPGA_DIR&amp;lt;/code&amp;gt; option. This allows you to run the FPGA testbenches and to build the example FPGA image provided with the OOT example.&lt;br /&gt;
&lt;br /&gt;
At this point, you can run &amp;lt;code&amp;gt;make help&amp;lt;/code&amp;gt; to see what options are available. A few of the available make targets are described below:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;make rfnoc-demo&amp;lt;/code&amp;gt;: Build the block controllers for the RFNoC blocks&lt;br /&gt;
* &amp;lt;code&amp;gt;make testbenches&amp;lt;/code&amp;gt;: Run the testbenches for the RFNoC blocks&lt;br /&gt;
* &amp;lt;code&amp;gt;make x310_rfnoc_image_core&amp;lt;/code&amp;gt;: Build the FPGA example image&lt;br /&gt;
* &amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;: Install the module&lt;br /&gt;
&lt;br /&gt;
To build and install the block, perform the following steps.&lt;br /&gt;
&lt;br /&gt;
    $ cd ~/rfnoc-demo/build&lt;br /&gt;
    $ make&lt;br /&gt;
    $ make install&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; may be required depending on the install location.&lt;br /&gt;
&lt;br /&gt;
===Building an FPGA Image with OOT Blocks===&lt;br /&gt;
&lt;br /&gt;
At this point you can build the example FPGA that's included in the &amp;lt;code&amp;gt;icores&amp;lt;/code&amp;gt; directory. Take a look at &amp;lt;code&amp;gt;~/rfnoc-demo/icores/x310_rfnoc_image_core.yml&amp;lt;/code&amp;gt;. Note that the &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; block is added in exactly the same way that the FFT block was in [[#Example:_Adding_an_FFT_Block|Example: Adding an FFT Block]]. You can build this example FPGA for the X310 using the following steps:&lt;br /&gt;
&lt;br /&gt;
    $ cd ~/rfnoc-demo/build&lt;br /&gt;
    $ make x310_rfnoc_image_core&lt;br /&gt;
&lt;br /&gt;
Alternatively, you can call &amp;lt;code&amp;gt;rfnoc_image_builder&amp;lt;/code&amp;gt; directly. In order to get the image builder to find your custom blocks, you may need to supply some additional arguments to find the OOT module, as shown in the following example:&lt;br /&gt;
&lt;br /&gt;
    $ rfnoc_image_builder -F &amp;lt;repo&amp;gt;/fpga –I ~/rfnoc-demo/include/rfnoc -y ~/rfnoc-demo/icores/x310_rfnoc_image_core.yml&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;-I&amp;lt;/code&amp;gt; option is only required if the OOT module has not been installed on the system. &amp;lt;!-- I think this is supposed to be the case, but it's not working right now, so we will see. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have an X310, you can build and use the provided example to test the Gain block. If you have a different USRP, you can use its default &amp;lt;code&amp;gt;rfnoc_image_core.yml&amp;lt;/code&amp;gt; as a starting point and follow the same steps that we followed for the FFT block in [[#Example:_Adding_an_FFT_Block|Example: Adding an FFT Block]], then build it using the process described above.&lt;br /&gt;
&lt;br /&gt;
===Testing the Gain Example===&lt;br /&gt;
&lt;br /&gt;
After building an FPGA image for your USRP and downloading it to your device, the Gain block should be available. Test this by running &amp;lt;code&amp;gt;uhd_usrp_probe&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   $ uhd_usrp_probe --args &amp;quot;type=x300,addr=192.168.30.2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Again, note that your &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; may be different or may not be required if you only have a single USRP connected.&lt;br /&gt;
&lt;br /&gt;
Take a look at the RFNoC blocks and the static connections on the device. You should see the following new blocks and connections:&lt;br /&gt;
&amp;lt;!-- TODO: It should show &amp;quot;0/Gain#0&amp;quot; here --&amp;gt;&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       RFNoC blocks on this device:&lt;br /&gt;
    ...&lt;br /&gt;
    |   |   * 0/Block#0&lt;br /&gt;
    ...&lt;br /&gt;
    |     _____________________________________________________&lt;br /&gt;
    |    /&lt;br /&gt;
    |   |       Static connections on this device:&lt;br /&gt;
    ...&lt;br /&gt;
    |   |   * 0/SEP#4:0==&amp;gt;0/Block#0:0&lt;br /&gt;
    |   |   * 0/Block#0:0==&amp;gt;0/SEP#4:0&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;!-- TODO:&lt;br /&gt;
Next, let's run the provided &amp;lt;code&amp;gt;init_gain_block&amp;lt;/code&amp;gt; application example.&lt;br /&gt;
&lt;br /&gt;
    $ ~/rfnoc-demo/build/apps/init_gain_block&lt;br /&gt;
    ...&lt;br /&gt;
    Gain value read/write loopback successful!&lt;br /&gt;
    $ &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
==Creating Your Own RFNoC Block==&lt;br /&gt;
&lt;br /&gt;
The Gain block is a useful example and could even be used as the starting point for a new block, but rather than trying to copy and edit the Gain block, it is best to use the RFNoC ModTool to create a new block template. This is also required if you want to change the interfaces provided to your IP that are exposed by the NoC Shell.&lt;br /&gt;
&lt;br /&gt;
===Understanding the Block Definition YAML===&lt;br /&gt;
&lt;br /&gt;
The first step in creating a new block is to write a YAML description for the block that you want to create. The options available are described [https://files.ettus.com/app_notes/RFNoC_Specification.pdf RFNoC Specification]. You can also look at the blocks available in &amp;lt;code&amp;gt;&amp;lt;repo&amp;gt;/host/include/uhd/rfnoc/blocks/&amp;lt;/code&amp;gt; for examples. We'll provide a brief overview here.&lt;br /&gt;
&lt;br /&gt;
Open up and take a look at the Gain block definition located in &amp;lt;code&amp;gt;~/rfnoc-demo/blocks/gain.yml&amp;lt;/code&amp;gt;. Notice the different sections, which are described below:&lt;br /&gt;
&lt;br /&gt;
* '''General Parameters'''&amp;lt;br&amp;gt;In this section we give our block a name (&amp;lt;code&amp;gt;module_name&amp;lt;/code&amp;gt;) and a unique block ID (&amp;lt;code&amp;gt;noc_id&amp;lt;/code&amp;gt;). The NoC ID is an arbitrary 32-bit number that will be used by the software to identify the block during system discovery. You can also specify the CHDR bus width, which should be 64 for Generation-3 USRPs.&lt;br /&gt;
* '''Clocks'''&amp;lt;br&amp;gt;In the &amp;lt;code&amp;gt;clocks&amp;lt;/code&amp;gt; section, we define the clocks that will be used by the block. The &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rfnoc_ctrl&amp;lt;/code&amp;gt; clocks are required. Many blocks also have a &amp;lt;code&amp;gt;ce&amp;lt;/code&amp;gt; clock for internal DSP.&lt;br /&gt;
* '''Control Interface'''&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;control&amp;lt;/code&amp;gt; section defines what type of control interface to make available to your block. The control interface is used for register reads and writes. Most blocks do not need to modify this section and will use the &amp;lt;code&amp;gt;ctrlport&amp;lt;/code&amp;gt; interface type. Control Port is the standard register interface used by RFNoC. The &amp;lt;code&amp;gt;clk_domain&amp;lt;/code&amp;gt; parameter allows you to specify which clock domain to use for the register interface exposed to your block. Typically this is the same clock that is used for the &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; interface, to avoid clock crossings.&lt;br /&gt;
* '''Data Interface'''&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; section defines what type of data interface to make available to your block and describes the ports. Most blocks use either the &amp;lt;code&amp;gt;axis_pyld_ctxt&amp;lt;/code&amp;gt; or the &amp;lt;code&amp;gt;axis_data&amp;lt;/code&amp;gt; interface types.&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;clk_domain&amp;lt;/code&amp;gt; parameter allows you to specify which clock domain to use for the data interfaces exposed to your block. Typically this is the same clock that is used for the &amp;lt;code&amp;gt;control&amp;lt;/code&amp;gt; interface, to avoid clock crossings.&amp;lt;br&amp;gt;Under the &amp;lt;code&amp;gt;inputs&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;outputs&amp;lt;/code&amp;gt; sections you can describe the input and output ports.&lt;br /&gt;
* '''IO Ports'''&amp;lt;br&amp;gt;The &amp;lt;code&amp;gt;io_ports&amp;lt;/code&amp;gt; section is used to describe other device-specific ports to which your block needs to connect (such as the DRAM or radio interfaces). For most blocks, this section is not used.&lt;br /&gt;
&lt;br /&gt;
A few other sections might be present in the YAML file (e.g., &amp;lt;code&amp;gt;registers&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;). These sections are reserved for future use and can be left empty.&lt;br /&gt;
&lt;br /&gt;
===Starting Your Own Block Definition===&lt;br /&gt;
&lt;br /&gt;
Let's start by making a copy of the Gain block YAML for our use case. &lt;br /&gt;
&lt;br /&gt;
    $ cp ~/rfnoc-demo/blocks/gain.yml ~/rfnoc-demo/blocks/demo.yml&lt;br /&gt;
&lt;br /&gt;
Now open the &amp;lt;code&amp;gt;demo.yml&amp;lt;/code&amp;gt; file you just created and make the following changes:&lt;br /&gt;
&lt;br /&gt;
# Change the name of the block from &amp;lt;code&amp;gt;gain&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;demo&amp;lt;/code&amp;gt;&lt;br /&gt;
# Change the &amp;lt;code&amp;gt;noc_id&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0x0000DE30&amp;lt;/code&amp;gt;&lt;br /&gt;
# Change the &amp;lt;code&amp;gt;format&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt; ports from &amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;sc16&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This YAML file now describes a block with the following features:&lt;br /&gt;
&lt;br /&gt;
* The block named &amp;quot;demo&amp;quot;&lt;br /&gt;
* NoC ID of 0xDE30&lt;br /&gt;
* CtrlPort register interface on the &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock domain&lt;br /&gt;
* A single 32-bit input port named &amp;quot;In&amp;quot; on the &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock domain that will provide sc16 samples to your IP&lt;br /&gt;
* A single 32-bit output port named &amp;quot;Out&amp;quot; on the &amp;lt;code&amp;gt;rfnoc_chdr&amp;lt;/code&amp;gt; clock domain that will receive sc16 samples from your IP&lt;br /&gt;
&lt;br /&gt;
===Generating Your Block Using the ModTool===&lt;br /&gt;
&lt;br /&gt;
Now that we have a block definition YAML file, we can generate the source code templates and NoC Shell for our block. To do so, run the following command:&lt;br /&gt;
&lt;br /&gt;
    $ python3 &amp;lt;repo&amp;gt;/host/utils/rfnoc_blocktool/rfnoc_create_verilog.py -c ~/rfnoc-demo/blocks/demo.yml -d ~/rfnoc-demo/fpga/rfnoc_block_demo&lt;br /&gt;
&lt;br /&gt;
This will create a folder named &amp;lt;code&amp;gt;~/rfnoc-demo/fpga/rfnoc_block_demo&amp;lt;/code&amp;gt; with an RFNoC block template for you to use. Explore the folder that was created. You should see the following files:&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt;''': This is the Makefile for the simulation testbench. See [https://files.ettus.com/manual/md_usrp3_sim_running_testbenches.html Running a Testbench] in the UHD and USRP Manual for instructions on how to run a testbench.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;Makefile.srcs&amp;lt;/code&amp;gt;''': This is another makefile that identifies the HDL source code that makes up your RFNoC block. &lt;br /&gt;
* '''&amp;lt;code&amp;gt;noc_shell_demo.v&amp;lt;/code&amp;gt;''': This is the NoC Shell that was generated for your block. It provides the interfaces described in the block definition YAML.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;rfnoc_block_demo.v&amp;lt;/code&amp;gt;''': This is a template for your RFNoC block. It includes all the top-level ports required by RFNoC and instantiates the NoC Shell.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;rfnoc_block_demo_tb.sv&amp;lt;/code&amp;gt;''': This is a testbench template for your RFNoC block. It instantiates your RFNoC block and the bus functional models (BFMs) needed to communicate with your block in simulation.&lt;br /&gt;
&lt;br /&gt;
Take a moment to look at the &amp;lt;code&amp;gt;rfnoc_block_demo.v&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rfnoc_block_demo_tb.sv&amp;lt;/code&amp;gt; files that were generated for your block. Notice the &amp;quot;User Logic&amp;quot; section towards the end of the &amp;lt;code&amp;gt;rfnoc_block_demo&amp;lt;/code&amp;gt; module. This is the location where you can insert your own IP.&lt;br /&gt;
&lt;br /&gt;
The input data samples come in on the &amp;lt;code&amp;gt;m_in_payload&amp;lt;/code&amp;gt; AXI4-Stream bus. The output data samples go out on the &amp;lt;code&amp;gt;s_out_payload&amp;lt;/code&amp;gt; AXI4-Stream data bus. &lt;br /&gt;
&lt;br /&gt;
If your input packets are the same size as your output packets (i.e., for every sample in you generate one sample out) then the &amp;lt;code&amp;gt;m_in_context&amp;lt;/code&amp;gt; data bus can be used to drive &amp;lt;code&amp;gt;s_out_context&amp;lt;/code&amp;gt;. The context bus is described in detail in the [https://files.ettus.com/app_notes/RFNoC_Specification.pdf RFNoC Specification].&lt;br /&gt;
&lt;br /&gt;
Similarly, the testbench has a section where you can add your own test sequences to the test bench.&lt;br /&gt;
&lt;br /&gt;
If you decide you need to change the RFNoC interfaces for your block (e.g., add ports, or change the interface type), then it is recommended to update the block definition YAML then regenerate the block. Please take care to not overwrite any code you have written when regenerating the files for your block! Rerunning the tool will cause new files to be generated, with a new NoC Shell, and will demonstrate how to update your code for the new interfaces.&lt;br /&gt;
&lt;br /&gt;
Refer to the Gain example and other RFNoC blocks for examples of how to complete your RFNoC block logic and testbenches.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
In this guide we have given a brief introduction on how to develop for RFNoC in UHD 4.0. There's a lot more you can do than is described here, but this will hopefully get you started. Happy coding!&lt;/div&gt;</summary>
		<author><name>WadeFife</name></author>	</entry>

	</feed>