summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/zpu/apps/txrx_uhd.c9
-rw-r--r--firmware/zpu/lib/ad9510.c6
-rw-r--r--firmware/zpu/lib/clocks.c5
-rw-r--r--firmware/zpu/lib/memory_map.h37
-rw-r--r--firmware/zpu/lib/spi.c97
-rw-r--r--firmware/zpu/lib/spi.h42
-rw-r--r--firmware/zpu/lib/u2_init.c2
-rw-r--r--firmware/zpu/usrp2p/spi_flash.c4
-rw-r--r--firmware/zpu/usrp2p/spi_flash.h10
-rw-r--r--firmware/zpu/usrp2p/spif.c1
-rw-r--r--firmware/zpu/usrp2p/udp_fw_update.c4
-rw-r--r--fpga/usrp2/control_lib/Makefile.srcs2
-rw-r--r--fpga/usrp2/control_lib/settings_bus_crossclock.v9
-rw-r--r--fpga/usrp2/control_lib/settings_fifo_ctrl.v391
-rw-r--r--fpga/usrp2/control_lib/simple_spi_core.v214
-rw-r--r--fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_prog_full.gise4
-rw-r--r--fpga/usrp2/fifo/Makefile.srcs1
-rw-r--r--fpga/usrp2/fifo/packet_dispatcher36_x4.v316
-rw-r--r--fpga/usrp2/fifo/packet_router.v23
-rw-r--r--fpga/usrp2/top/N2x0/bootloader.rmi754
-rw-r--r--fpga/usrp2/top/N2x0/u2plus_core.v80
-rw-r--r--fpga/usrp2/top/USRP2/Makefile2
-rw-r--r--fpga/usrp2/top/USRP2/u2_core.v84
-rw-r--r--host/docs/sync.rst35
-rw-r--r--host/examples/CMakeLists.txt3
-rw-r--r--host/examples/test_timed_commands.cpp129
-rw-r--r--host/examples/tx_waveforms.cpp5
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.cpp23
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.hpp3
-rw-r--r--host/lib/usrp/dboard/db_sbx_version3.cpp20
-rw-r--r--host/lib/usrp/dboard/db_sbx_version4.cpp6
-rw-r--r--host/lib/usrp/multi_usrp.cpp23
-rw-r--r--host/lib/usrp/usrp2/CMakeLists.txt3
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp13
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.hpp7
-rw-r--r--host/lib/usrp/usrp2/codec_ctrl.cpp14
-rw-r--r--host/lib/usrp/usrp2/codec_ctrl.hpp7
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp48
-rw-r--r--host/lib/usrp/usrp2/fw_common.h7
-rw-r--r--host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp246
-rw-r--r--host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp47
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp50
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp15
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.hpp4
44 files changed, 2153 insertions, 652 deletions
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index a4bfce0ec..0142aa3d4 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -89,6 +89,10 @@ static void handle_udp_data_packet(
which = 1;
break;
+ case USRP2_UDP_FIFO_CRTL_PORT:
+ which = 3;
+ break;
+
default: return;
}
@@ -177,8 +181,8 @@ static void handle_udp_ctrl_packet(
ctrl_data_in->data.spi_args.dev, //which device
ctrl_data_in->data.spi_args.data, //32 bit data
ctrl_data_in->data.spi_args.num_bits, //length in bits
- (ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_FALL : SPIF_PUSH_RISE |
- (ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL
+ (ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPI_PUSH_FALL : SPI_PUSH_RISE |
+ (ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPI_LATCH_RISE : SPI_LATCH_FALL
);
//load output
@@ -338,6 +342,7 @@ main(void)
register_udp_listener(USRP2_UDP_RX_DSP0_PORT, handle_udp_data_packet);
register_udp_listener(USRP2_UDP_RX_DSP1_PORT, handle_udp_data_packet);
register_udp_listener(USRP2_UDP_TX_DSP0_PORT, handle_udp_data_packet);
+ register_udp_listener(USRP2_UDP_FIFO_CRTL_PORT, handle_udp_data_packet);
#ifdef USRP2P
register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet);
diff --git a/firmware/zpu/lib/ad9510.c b/firmware/zpu/lib/ad9510.c
index 4d3acb65d..4021a9bf7 100644
--- a/firmware/zpu/lib/ad9510.c
+++ b/firmware/zpu/lib/ad9510.c
@@ -1,5 +1,5 @@
-/* -*- c++ -*- */
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2008 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -28,7 +28,7 @@ ad9510_write_reg(int regno, uint8_t value)
{
uint32_t inst = WR | (regno & 0xff);
uint32_t v = (inst << 8) | (value & 0xff);
- spi_transact(SPI_TXONLY, SPI_SS_AD9510, v, 24, SPIF_PUSH_FALL);
+ spi_transact(SPI_TXONLY, SPI_SS_AD9510, v, 24, SPI_PUSH_FALL);
}
int
@@ -37,6 +37,6 @@ ad9510_read_reg(int regno)
uint32_t inst = RD | (regno & 0xff);
uint32_t v = (inst << 8) | 0;
uint32_t r = spi_transact(SPI_TXRX, SPI_SS_AD9510, v, 24,
- SPIF_PUSH_FALL | SPIF_LATCH_FALL);
+ SPI_PUSH_FALL | SPI_LATCH_FALL);
return r & 0xff;
}
diff --git a/firmware/zpu/lib/clocks.c b/firmware/zpu/lib/clocks.c
index c1e8ce827..bc1954e13 100644
--- a/firmware/zpu/lib/clocks.c
+++ b/firmware/zpu/lib/clocks.c
@@ -43,7 +43,10 @@ clocks_init(void)
//enable the 100MHz clock output to the FPGA for 50MHz CPU clock
clocks_enable_fpga_clk(true, 1);
- spi_wait();
+ //! Cannot SPI wait since SPI is on DSP clock
+ //! because DSP clock goes away until DCM reset.
+ //! However, spi is quick, the cpu is slow, its already ready...
+ //spi_wait();
//wait for the clock to stabilize
while(!clocks_lock_detect());
diff --git a/firmware/zpu/lib/memory_map.h b/firmware/zpu/lib/memory_map.h
index 9d47522ca..4290ee20a 100644
--- a/firmware/zpu/lib/memory_map.h
+++ b/firmware/zpu/lib/memory_map.h
@@ -1,4 +1,4 @@
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
/*
* Copyright 2007,2008,2009 Free Software Foundation, Inc.
*
@@ -49,18 +49,6 @@
// SPI Core, Slave 2. See core docs for more info
/////////////////////////////////////////////////////
-typedef struct {
- volatile uint32_t txrx0;
- volatile uint32_t txrx1;
- volatile uint32_t txrx2;
- volatile uint32_t txrx3;
- volatile uint32_t ctrl;
- volatile uint32_t div;
- volatile uint32_t ss;
-} spi_regs_t;
-
-#define spi_regs ((spi_regs_t *) SPI_BASE)
-
// Masks for controlling different peripherals
#define SPI_SS_AD9510 1
#define SPI_SS_AD9777 2
@@ -124,7 +112,8 @@ typedef struct {
///////////////////////////////////////////////////
typedef struct {
- volatile uint32_t _padding[8];
+ volatile uint32_t spi;
+ volatile uint32_t _padding[7];
volatile uint32_t status;
volatile uint32_t _unused;
volatile uint32_t time64_secs_rb;
@@ -133,7 +122,10 @@ typedef struct {
volatile uint32_t irqs;
} router_status_t;
+#define SPI_READY_IRQ (1 << 12)
+
#define router_status ((router_status_t *) READBACK_BASE)
+#define readback_mux ((router_status_t *) READBACK_BASE) //alias with a better name
/*!
* \brief return non-zero if we're running under the simulator
@@ -207,7 +199,7 @@ typedef struct {
#define SR_SIMTIMER 8 // 2
#define SR_TIME64 10 // 6
#define SR_BUF_POOL 16 // 4
-
+#define SR_SPI_CORE 20 // 3
#define SR_RX_FRONT 24 // 5
#define SR_RX_CTRL0 32 // 9
#define SR_RX_DSP0 48 // 7
@@ -224,6 +216,21 @@ typedef struct {
#define SR_ADDR_BLDRDONE _SR_ADDR(5)
+// --- spi core control regs ---
+
+typedef struct {
+ volatile uint32_t divider;
+ volatile uint32_t control;
+ volatile uint32_t data;
+} spi_core_t;
+
+#define SPI_CORE_SLAVE_SELECT_SHIFT 0
+#define SPI_CORE_NUM_BITS_SHIFT 24
+#define SPI_CORE_DATA_IN_EDGE_SHIFT 30
+#define SPI_CORE_DATA_OUT_EDGE_SHIFT 31
+
+#define spi_core ((spi_core_t *) _SR_ADDR(SR_SPI_CORE))
+
// --- packet router control regs ---
typedef struct {
diff --git a/firmware/zpu/lib/spi.c b/firmware/zpu/lib/spi.c
index af0d8a68f..6f2f74899 100644
--- a/firmware/zpu/lib/spi.c
+++ b/firmware/zpu/lib/spi.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2007,2008 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -17,94 +18,38 @@
#include "spi.h"
#include "memory_map.h"
-#include "pic.h"
#include "nonstdio.h"
-//void (*volatile spi_callback)(void); //SPI callback when xfer complete.
-
-//static void spi_irq_handler(unsigned irq);
-
-void
-spi_init(void)
+void spi_init(void)
{
- /*
- * f_sclk = f_wb / ((div + 1) * 2)
- */
- spi_regs->div = 1; // 0 = Div by 2 (25 MHz); 1 = Div-by-4 (12.5 MHz)
+ spi_core->divider = 10;
}
-void
-spi_wait(void)
+void spi_wait(void)
{
- while (spi_regs->ctrl & SPI_CTRL_GO_BSY)
- ;
+ while ((readback_mux->irqs & SPI_READY_IRQ) == 0){
+ //NOP
+ }
}
-uint32_t
-spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags)
+uint32_t spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags)
{
- flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG);
- int ctrl = SPI_CTRL_ASS | (SPI_CTRL_CHAR_LEN_MASK & length) | flags;
-
- spi_wait();
-
- // Tell it which SPI slave device to access
- spi_regs->ss = slave & 0xffff;
-
- // Data we will send
- spi_regs->txrx0 = data;
+ uint32_t control_word = 0;
+ control_word |= (slave << SPI_CORE_SLAVE_SELECT_SHIFT);
+ control_word |= (length << SPI_CORE_NUM_BITS_SHIFT);
+ if ((flags & SPI_PUSH_RISE) != 0) control_word |= (1 << SPI_CORE_DATA_OUT_EDGE_SHIFT);
+ if ((flags & SPI_PUSH_FALL) != 0) control_word |= (0 << SPI_CORE_DATA_OUT_EDGE_SHIFT);
+ if ((flags & SPI_LATCH_RISE) != 0) control_word |= (1 << SPI_CORE_DATA_IN_EDGE_SHIFT);
+ if ((flags & SPI_LATCH_FALL) != 0) control_word |= (0 << SPI_CORE_DATA_IN_EDGE_SHIFT);
- // Run it -- write once and rewrite with GO set
- spi_regs->ctrl = ctrl;
- spi_regs->ctrl = ctrl | SPI_CTRL_GO_BSY;
+ const uint32_t data_out = data << (32 - length);
- if(readback) {
spi_wait();
- return spi_regs->txrx0;
- }
- else
- return 0;
-}
+ spi_core->control = control_word;
+ spi_core->data = data_out;
-/*
-void spi_register_callback(void (*volatile callback)(void)) {
- spi_callback = callback;
-}
-
-static void spi_irq_handler(unsigned irq) {
-// printf("SPI IRQ handler\n");
-// uint32_t wat = spi_regs->ctrl; //read a register just to clear the interrupt
- //spi_regs->ctrl &= ~SPI_CTRL_IE;
- if(spi_callback) spi_callback(); //we could just use the PIC to register the user's callback, but this provides the ability to do other things later
-}
+ if (!readback) return 0;
-uint32_t spi_get_data(void) {
- return spi_regs->txrx0;
-}
-
-bool
-spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*volatile callback)(void)) {
- flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG);
- int ctrl = SPI_CTRL_ASS | SPI_CTRL_IE | (SPI_CTRL_CHAR_LEN_MASK & length) | flags;
-
- if(spi_regs->ctrl & SPI_CTRL_GO_BSY) {
- printf("Async SPI busy!\n");
- return false; //we don't wait on busy, we just return failure. we count on the host to not set up another transaction before the last one finishes.
- }
-
- // Tell it which SPI slave device to access
- spi_regs->ss = slave & 0xffff;
-
- // Data we will send
- spi_regs->txrx0 = data;
-
- spi_register_callback(callback);
- pic_register_handler(IRQ_SPI, spi_irq_handler);
-
- // Run it -- write once and rewrite with GO set
- spi_regs->ctrl = ctrl;
- spi_regs->ctrl = ctrl | SPI_CTRL_GO_BSY;
-
- return true;
+ spi_wait();
+ return readback_mux->spi;
}
-*/
diff --git a/firmware/zpu/lib/spi.h b/firmware/zpu/lib/spi.h
index 71245150a..125e1a502 100644
--- a/firmware/zpu/lib/spi.h
+++ b/firmware/zpu/lib/spi.h
@@ -1,5 +1,5 @@
-/* -*- c -*- */
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2006,2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -19,8 +19,8 @@
#ifndef INCLUDED_SPI_H
#define INCLUDED_SPI_H
-#include <memory_map.h>
#include <stdbool.h>
+#include <stdint.h>
/*!
* \brief One time call to initialize SPI
@@ -39,39 +39,11 @@ void spi_wait(void);
/*
* Flags for spi_transact
*/
-#define SPIF_PUSH_RISE 0 // push tx data on rising edge of SCLK
-#define SPIF_PUSH_FALL SPI_CTRL_TXNEG // push tx data on falling edge of SCLK
-#define SPIF_LATCH_RISE 0 // latch rx data on rising edge of SCLK
-#define SPIF_LATCH_FALL SPI_CTRL_RXNEG // latch rx data on falling edge of SCLK
-
-
-uint32_t
-spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
-
-//uint32_t spi_get_data(void);
-//static void spi_irq_handler(unsigned irq);
-//void spi_register_callback(void (*volatile callback)(void));
-
-//bool
-//spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*volatile callback)(void));
-
-// ----------------------------------------------------------------
-// Routines that manipulate the FLASH SPI BUS
-// ----------------------------------------------------------------
-
-/*!
- * \brief One time call to initialize SPI
- */
-void spif_init(void);
-
-/*!
- * \brief Wait for last SPI transaction to complete.
- * Unless you need to know it completed, it's not necessary to call this.
- */
-void spif_wait(void);
-
-uint32_t
-spif_transact(bool readback_, int slave, uint32_t data, int length, uint32_t flags);
+#define SPI_PUSH_RISE (1 << 0) // push tx data on rising edge of SCLK
+#define SPI_PUSH_FALL (1 << 1) // push tx data on falling edge of SCLK
+#define SPI_LATCH_RISE (1 << 2) // latch rx data on rising edge of SCLK
+#define SPI_LATCH_FALL (1 << 3) // latch rx data on falling edge of SCLK
+uint32_t spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
#endif /* INCLUDED_SPI_H */
diff --git a/firmware/zpu/lib/u2_init.c b/firmware/zpu/lib/u2_init.c
index 71bd2c594..77c8c0722 100644
--- a/firmware/zpu/lib/u2_init.c
+++ b/firmware/zpu/lib/u2_init.c
@@ -51,6 +51,7 @@ u2_init(void)
hal_enable_ints();
// flash all leds to let us know board is alive
+#ifndef BOOTLOADER
hal_set_led_src(0x0, 0x1f); /* software ctrl */
hal_set_leds(0x0, 0x1f); mdelay(300);
hal_set_leds(LED_E, LED_E); mdelay(300);
@@ -61,6 +62,7 @@ u2_init(void)
hal_set_leds(0x0, 0x1f); mdelay(100);
hal_set_leds(blinks, 0x1f); mdelay(100);
}
+#endif
hal_set_led_src(0x1f & ~LED_D, 0x1f); /* hardware ctrl */
hal_set_leds(LED_D, 0x1f); // Leave one on
diff --git a/firmware/zpu/usrp2p/spi_flash.c b/firmware/zpu/usrp2p/spi_flash.c
index 9406f8042..09f908edb 100644
--- a/firmware/zpu/usrp2p/spi_flash.c
+++ b/firmware/zpu/usrp2p/spi_flash.c
@@ -1,7 +1,6 @@
-/* -*- c++ -*- */
/*
* Copyright 2009 Free Software Foundation, Inc.
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 Ettus Research LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "spi_flash.h"
#include "spi_flash_private.h"
//#include <stdlib.h>
#include <nonstdio.h>
diff --git a/firmware/zpu/usrp2p/spi_flash.h b/firmware/zpu/usrp2p/spi_flash.h
index a10533e08..8a8facdca 100644
--- a/firmware/zpu/usrp2p/spi_flash.h
+++ b/firmware/zpu/usrp2p/spi_flash.h
@@ -23,10 +23,18 @@
#include <stdint.h>
#include <stdbool.h>
-
#define SPI_FLASH_PAGE_SIZE 256
#define SPI_SS_FLASH 1
+#define SPIF_PUSH_RISE 0 // push tx data on rising edge of SCLK
+#define SPIF_PUSH_FALL SPI_CTRL_TXNEG // push tx data on falling edge of SCLK
+#define SPIF_LATCH_RISE 0 // latch rx data on rising edge of SCLK
+#define SPIF_LATCH_FALL SPI_CTRL_RXNEG // latch rx data on falling edge of SCLK
+
+void spif_init(void);
+void spif_wait(void);
+
+uint32_t spif_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
uint32_t spi_flash_rdid(void); /* Read ID */
uint32_t spi_flash_rdsr(void); /* Read Status Register */
diff --git a/firmware/zpu/usrp2p/spif.c b/firmware/zpu/usrp2p/spif.c
index 91da73155..60807ca4a 100644
--- a/firmware/zpu/usrp2p/spif.c
+++ b/firmware/zpu/usrp2p/spif.c
@@ -21,6 +21,7 @@
*/
#include "spi.h"
+#include "spi_flash.h"
#include "memory_map.h"
void
diff --git a/firmware/zpu/usrp2p/udp_fw_update.c b/firmware/zpu/usrp2p/udp_fw_update.c
index 5689388a8..cd9e7d902 100644
--- a/firmware/zpu/usrp2p/udp_fw_update.c
+++ b/firmware/zpu/usrp2p/udp_fw_update.c
@@ -1,6 +1,5 @@
-/* -*- c++ -*- */
/*
- * Copyright 2010 Ettus Research LLC
+ * Copyright 2010-2012 Ettus Research LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +18,7 @@
//Routines to handle updating the SPI Flash firmware via UDP
#include <net_common.h>
+#include "memory_map.h"
#include "usrp2/fw_common.h"
#include "spi.h"
#include "spi_flash.h"
diff --git a/fpga/usrp2/control_lib/Makefile.srcs b/fpga/usrp2/control_lib/Makefile.srcs
index 6ee7ea262..0bb9a3efe 100644
--- a/fpga/usrp2/control_lib/Makefile.srcs
+++ b/fpga/usrp2/control_lib/Makefile.srcs
@@ -55,4 +55,6 @@ atr_controller16.v \
fifo_to_wb.v \
gpio_atr.v \
user_settings.v \
+settings_fifo_ctrl.v \
+simple_spi_core.v \
))
diff --git a/fpga/usrp2/control_lib/settings_bus_crossclock.v b/fpga/usrp2/control_lib/settings_bus_crossclock.v
index 9c5912042..a61ee8fad 100644
--- a/fpga/usrp2/control_lib/settings_bus_crossclock.v
+++ b/fpga/usrp2/control_lib/settings_bus_crossclock.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -22,16 +22,17 @@
// the system or dsp clock on the output side
module settings_bus_crossclock
+ #(parameter FLOW_CTRL=0)
(input clk_i, input rst_i, input set_stb_i, input [7:0] set_addr_i, input [31:0] set_data_i,
- input clk_o, input rst_o, output set_stb_o, output [7:0] set_addr_o, output [31:0] set_data_o);
+ input clk_o, input rst_o, output set_stb_o, output [7:0] set_addr_o, output [31:0] set_data_o, input blocked);
wire full, empty;
fifo_xlnx_16x40_2clk settings_fifo
(.rst(rst_i),
.wr_clk(clk_i), .din({set_addr_i,set_data_i}), .wr_en(set_stb_i & ~full), .full(full),
- .rd_clk(clk_o), .dout({set_addr_o,set_data_o}), .rd_en(~empty), .empty(empty));
+ .rd_clk(clk_o), .dout({set_addr_o,set_data_o}), .rd_en(set_stb_o), .empty(empty));
- assign set_stb_o = ~empty;
+ assign set_stb_o = ~empty & (~blocked | ~FLOW_CTRL);
endmodule // settings_bus_crossclock
diff --git a/fpga/usrp2/control_lib/settings_fifo_ctrl.v b/fpga/usrp2/control_lib/settings_fifo_ctrl.v
new file mode 100644
index 000000000..160112169
--- /dev/null
+++ b/fpga/usrp2/control_lib/settings_fifo_ctrl.v
@@ -0,0 +1,391 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+// A settings and readback bus controlled via fifo36 interface
+
+module settings_fifo_ctrl
+ #(
+ parameter FIFO_DEPTH = 6, //64 entries depth
+ parameter PROT_DEST = 0, //protocol framer destination
+ parameter PROT_HDR = 1, //needs a protocol header?
+ parameter ACK_SID = 0 //stream ID for packet ACK
+ )
+ (
+ //clock and synchronous reset for all interfaces
+ input clock, input reset, input clear,
+
+ //current system time
+ input [63:0] vita_time,
+
+ //ready signal for multiple peripherals
+ input perfs_ready,
+
+ //input fifo36 interface control
+ input [35:0] in_data, input in_valid, output in_ready,
+
+ //output fifo36 interface status
+ output [35:0] out_data, output out_valid, input out_ready,
+
+ //32-bit settings bus outputs
+ output strobe, output [7:0] addr, output [31:0] data,
+
+ //16X 32-bit inputs for readback
+ input [31:0] word00,
+ input [31:0] word01,
+ input [31:0] word02,
+ input [31:0] word03,
+ input [31:0] word04,
+ input [31:0] word05,
+ input [31:0] word06,
+ input [31:0] word07,
+ input [31:0] word08,
+ input [31:0] word09,
+ input [31:0] word10,
+ input [31:0] word11,
+ input [31:0] word12,
+ input [31:0] word13,
+ input [31:0] word14,
+ input [31:0] word15,
+
+ //debug output
+ output [31:0] debug
+ );
+
+ wire reading = in_valid && in_ready;
+ wire writing = out_valid && out_ready;
+
+ //------------------------------------------------------------------
+ //-- The command fifo:
+ //-- Stores an individual register access command per line.
+ //------------------------------------------------------------------
+ wire [63:0] in_command_ticks, out_command_ticks;
+ wire [31:0] in_command_hdr, out_command_hdr;
+ wire [31:0] in_command_data, out_command_data;
+ wire in_command_has_time, out_command_has_time;
+ wire command_fifo_full, command_fifo_empty;
+ wire command_fifo_read, command_fifo_write;
+
+ medfifo #(.WIDTH(129), .DEPTH(FIFO_DEPTH-4)) command_fifo (
+ .clk(clock), .rst(reset), .clear(clear),
+ .datain({in_command_ticks, in_command_hdr, in_command_data, in_command_has_time}),
+ .dataout({out_command_ticks, out_command_hdr, out_command_data, out_command_has_time}),
+ .write(command_fifo_write), .full(command_fifo_full), //input interface
+ .empty(command_fifo_empty), .read(command_fifo_read) //output interface
+ );
+
+ //------------------------------------------------------------------
+ //-- The result fifo:
+ //-- Stores an individual result of a command per line.
+ //------------------------------------------------------------------
+ wire [31:0] in_result_hdr, out_result_hdr;
+ wire [31:0] in_result_data, out_result_data;
+ wire result_fifo_full, result_fifo_empty;
+ wire result_fifo_read, result_fifo_write;
+
+ medfifo #(.WIDTH(64), .DEPTH(FIFO_DEPTH-4)) result_fifo (
+ .clk(clock), .rst(reset), .clear(clear),
+ .datain({in_result_hdr, in_result_data}),
+ .dataout({out_result_hdr, out_result_data}),
+ .write(result_fifo_write), .full(result_fifo_full), //input interface
+ .empty(result_fifo_empty), .read(result_fifo_read) //output interface
+ );
+
+ //------------------------------------------------------------------
+ //-- Input state machine:
+ //-- Read input packet and fill a command fifo entry.
+ //------------------------------------------------------------------
+ localparam READ_LINE0 = 0;
+ localparam VITA_HDR = 1;
+ localparam VITA_SID = 2;
+ localparam VITA_CID0 = 3;
+ localparam VITA_CID1 = 4;
+ localparam VITA_TSI = 5;
+ localparam VITA_TSF0 = 6;
+ localparam VITA_TSF1 = 7;
+ localparam READ_HDR = 8;
+ localparam READ_DATA = 9;
+ localparam WAIT_EOF = 10;
+ localparam STORE_CMD = 11;
+
+ reg [4:0] in_state;
+
+ //holdover from current read inputs
+ reg [31:0] in_data_reg, in_hdr_reg;
+ reg [63:0] in_ticks_reg;
+ wire has_sid = in_data[28];
+ wire has_cid = in_data[27];
+ wire has_tsi = in_data[23:22] != 0;
+ wire has_tsf = in_data[21:20] != 0;
+ reg has_sid_reg, has_cid_reg, has_tsi_reg, has_tsf_reg;
+
+ assign in_ready = (in_state < STORE_CMD);
+ assign command_fifo_write = (in_state == STORE_CMD);
+ assign in_command_ticks = in_ticks_reg;
+ assign in_command_data = in_data_reg;
+ assign in_command_hdr = in_hdr_reg;
+ assign in_command_has_time = has_tsf_reg;
+
+ always @(posedge clock) begin
+ if (reset) begin
+ in_state <= READ_LINE0;
+ end
+ else begin
+ case (in_state)
+
+ READ_LINE0: begin
+ if (reading/* && in_data[32]*/) in_state <= VITA_HDR;
+ end
+
+ VITA_HDR: begin
+ if (reading) begin
+ if (has_sid) in_state <= VITA_SID;
+ else if (has_cid) in_state <= VITA_CID0;
+ else if (has_tsi) in_state <= VITA_TSI;
+ else if (has_tsf) in_state <= VITA_TSF0;
+ else in_state <= READ_HDR;
+ end
+ has_sid_reg <= has_sid;
+ has_cid_reg <= has_cid;
+ has_tsi_reg <= has_tsi;
+ has_tsf_reg <= has_tsf;
+ end
+
+ VITA_SID: begin
+ if (reading) begin
+ if (has_cid_reg) in_state <= VITA_CID0;
+ else if (has_tsi_reg) in_state <= VITA_TSI;
+ else if (has_tsf_reg) in_state <= VITA_TSF0;
+ else in_state <= READ_HDR;
+ end
+ end
+
+ VITA_CID0: begin
+ if (reading) in_state <= VITA_CID1;
+ end
+
+ VITA_CID1: begin
+ if (reading) begin
+ if (has_tsi_reg) in_state <= VITA_TSI;
+ else if (has_tsf_reg) in_state <= VITA_TSF0;
+ else in_state <= READ_HDR;
+ end
+ end
+
+ VITA_TSI: begin
+ if (reading) begin
+ if (has_tsf_reg) in_state <= VITA_TSF0;
+ else in_state <= READ_HDR;
+ end
+ end
+
+ VITA_TSF0: begin
+ if (reading) in_state <= VITA_TSF1;
+ in_ticks_reg[63:32] <= in_data;
+ end
+
+ VITA_TSF1: begin
+ if (reading) in_state <= READ_HDR;
+ in_ticks_reg[31:0] <= in_data;
+ end
+
+ READ_HDR: begin
+ if (reading) in_state <= READ_DATA;
+ in_hdr_reg <= in_data[31:0];
+ end
+
+ READ_DATA: begin
+ if (reading) in_state <= (in_data[33])? STORE_CMD : WAIT_EOF;
+ in_data_reg <= in_data[31:0];
+ end
+
+ WAIT_EOF: begin
+ if (reading && in_data[33]) in_state <= STORE_CMD;
+ end
+
+ STORE_CMD: begin
+ if (~command_fifo_full) in_state <= READ_LINE0;
+ end
+
+ endcase //in_state
+ end
+ end
+
+ //------------------------------------------------------------------
+ //-- Command state machine:
+ //-- Read a command fifo entry, act on it, produce result.
+ //------------------------------------------------------------------
+ localparam LOAD_CMD = 0;
+ localparam EVENT_CMD = 1;
+
+ reg cmd_state;
+ reg [31:0] rb_data;
+
+ reg [63:0] command_ticks_reg;
+ reg [31:0] command_hdr_reg;
+ reg [31:0] command_data_reg;
+
+ wire now, early, late, too_early;
+ `ifndef FIFO_CTRL_NO_TIME
+ time_compare time_compare(
+ .time_now(vita_time), .trigger_time(command_ticks_reg),
+ .now(now), .early(early), .late(late), .too_early(too_early));
+ `else
+ assign now = 0;
+ assign late = 1;
+ `endif
+
+ //action occurs in the event state and when there is fifo space (should always be true)
+ //the third condition is that all peripherals in the perfs signal are ready/active high
+ //the fourth condition is that is an event time has been set, action is delayed until that time
+ wire time_ready = (out_command_has_time)? (now || late) : 1;
+ wire action = (cmd_state == EVENT_CMD) && ~result_fifo_full && perfs_ready && time_ready;
+
+ assign command_fifo_read = action;
+ assign result_fifo_write = action;
+ assign in_result_hdr = command_hdr_reg;
+ assign in_result_data = rb_data;
+
+ always @(posedge clock) begin
+ if (reset) begin
+ cmd_state <= LOAD_CMD;
+ end
+ else begin
+ case (cmd_state)
+
+ LOAD_CMD: begin
+ if (~command_fifo_empty) cmd_state <= EVENT_CMD;
+ command_ticks_reg <= out_command_ticks;
+ command_hdr_reg <= out_command_hdr;
+ command_data_reg <= out_command_data;
+ end
+
+ EVENT_CMD: begin // poking and peeking happens here!
+ if (action || clear) cmd_state <= LOAD_CMD;
+ end
+
+ endcase //cmd_state
+ end
+ end
+
+ //------------------------------------------------------------------
+ //-- assign to settings bus interface
+ //------------------------------------------------------------------
+ reg strobe_reg;
+ assign strobe = strobe_reg;
+ assign data = command_data_reg;
+ assign addr = command_hdr_reg[7:0];
+ wire poke = command_hdr_reg[8];
+
+ always @(posedge clock) begin
+ if (reset || clear) strobe_reg <= 0;
+ else strobe_reg <= action && poke;
+ end
+
+ //------------------------------------------------------------------
+ //-- readback mux
+ //------------------------------------------------------------------
+ always @(posedge clock) begin
+ case (out_command_hdr[3:0])
+ 0 : rb_data <= word00;
+ 1 : rb_data <= word01;
+ 2 : rb_data <= word02;
+ 3 : rb_data <= word03;
+ 4 : rb_data <= word04;
+ 5 : rb_data <= word05;
+ 6 : rb_data <= word06;
+ 7 : rb_data <= word07;
+ 8 : rb_data <= word08;
+ 9 : rb_data <= word09;
+ 10: rb_data <= word10;
+ 11: rb_data <= word11;
+ 12: rb_data <= word12;
+ 13: rb_data <= word13;
+ 14: rb_data <= word14;
+ 15: rb_data <= word15;
+ endcase // case(addr_reg[3:0])
+ end
+
+ //------------------------------------------------------------------
+ //-- Output state machine:
+ //-- Read a command fifo entry, act on it, produce ack packet.
+ //------------------------------------------------------------------
+ localparam WRITE_PROT_HDR = 0;
+ localparam WRITE_VRT_HDR = 1;
+ localparam WRITE_VRT_SID = 2;
+ localparam WRITE_RB_HDR = 3;
+ localparam WRITE_RB_DATA = 4;
+
+ //the state for the start of packet condition
+ localparam WRITE_PKT_HDR = (PROT_HDR)? WRITE_PROT_HDR : WRITE_VRT_HDR;
+
+ reg [2:0] out_state;
+
+ assign out_valid = ~result_fifo_empty;
+ assign result_fifo_read = out_data[33] && writing;
+
+ always @(posedge clock) begin
+ if (reset) begin
+ out_state <= WRITE_PKT_HDR;
+ end
+ else if (writing && out_data[33]) begin
+ out_state <= WRITE_PKT_HDR;
+ end
+ else if (writing) begin
+ out_state <= out_state + 1;
+ end
+ end
+
+ //------------------------------------------------------------------
+ //-- assign to output fifo interface
+ //------------------------------------------------------------------
+ wire [31:0] prot_hdr;
+ assign prot_hdr[15:0] = 16; //bytes in proceeding vita packet
+ assign prot_hdr[16] = 1; //yes frame
+ assign prot_hdr[18:17] = PROT_DEST;
+ assign prot_hdr[31:19] = 0; //nothing
+
+ reg [31:0] out_data_int;
+ always @* begin
+ case (out_state)
+ WRITE_PROT_HDR: out_data_int <= prot_hdr;
+ WRITE_VRT_HDR: out_data_int <= {12'b010100000000, out_result_hdr[19:16], 2'b0, prot_hdr[15:2]};
+ WRITE_VRT_SID: out_data_int <= ACK_SID;
+ WRITE_RB_HDR: out_data_int <= out_result_hdr;
+ WRITE_RB_DATA: out_data_int <= out_result_data;
+ default: out_data_int <= 0;
+ endcase //state
+ end
+
+ assign out_data[35:34] = 2'b0;
+ assign out_data[33] = (out_state == WRITE_RB_DATA);
+ assign out_data[32] = (out_state == WRITE_PKT_HDR);
+ assign out_data[31:0] = out_data_int;
+
+ //------------------------------------------------------------------
+ //-- debug outputs
+ //------------------------------------------------------------------
+ assign debug = {
+ in_state, out_state, //8
+ in_valid, in_ready, in_data[33:32], //4
+ out_valid, out_ready, out_data[33:32], //4
+ command_fifo_empty, command_fifo_full, //2
+ command_fifo_read, command_fifo_write, //2
+ addr, //8
+ strobe_reg, strobe, poke, out_command_has_time //4
+ };
+
+endmodule //settings_fifo_ctrl
diff --git a/fpga/usrp2/control_lib/simple_spi_core.v b/fpga/usrp2/control_lib/simple_spi_core.v
new file mode 100644
index 000000000..3c0ed60b9
--- /dev/null
+++ b/fpga/usrp2/control_lib/simple_spi_core.v
@@ -0,0 +1,214 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+// Simple SPI core, the simplest, yet complete spi core I can think of
+
+// Settings register controlled.
+// 2 settings regs, control and data
+// 1 32-bit readback and status signal
+
+// Settings reg map:
+//
+// BASE+0 divider setting
+// bits [15:0] spi clock divider
+//
+// BASE+1 configuration input
+// bits [23:0] slave select, bit0 = slave0 enabled
+// bits [29:24] num bits (1 through 32)
+// bit [30] data input edge = in data bit latched on rising edge of clock
+// bit [31] data output edge = out data bit latched on rising edge of clock
+//
+// BASE+2 input data
+// Writing this register begins a spi transaction.
+// Bits are latched out from bit 0.
+// Therefore, load this register in reverse.
+//
+// Readback
+// Bits are latched into bit 0.
+// Therefore, data will be in-order.
+
+module simple_spi_core
+ #(
+ //settings register base address
+ parameter BASE = 0,
+
+ //width of serial enables (up to 24 is possible)
+ parameter WIDTH = 8,
+
+ //idle state of the spi clock
+ parameter CLK_IDLE = 0,
+
+ //idle state of the serial enables
+ parameter SEN_IDLE = 24'hffffff
+ )
+ (
+ //clock and synchronous reset
+ input clock, input reset,
+
+ //32-bit settings bus inputs
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ //32-bit data readback
+ output [31:0] readback,
+
+ //read is high when spi core can begin another transaction
+ output ready,
+
+ //spi interface, slave selects, clock, data in, data out
+ output [WIDTH-1:0] sen,
+ output sclk,
+ output mosi,
+ input miso,
+
+ //optional debug output
+ output [31:0] debug
+ );
+
+ wire [15:0] sclk_divider;
+ setting_reg #(.my_addr(BASE+0),.width(16)) divider_sr(
+ .clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(sclk_divider),.changed());
+
+ wire [23:0] slave_select;
+ wire [5:0] num_bits;
+ wire datain_edge, dataout_edge;
+ setting_reg #(.my_addr(BASE+1),.width(32)) config_sr(
+ .clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out({dataout_edge, datain_edge, num_bits, slave_select}),.changed());
+
+ wire [31:0] mosi_data;
+ wire trigger_spi;
+ setting_reg #(.my_addr(BASE+2),.width(32)) data_sr(
+ .clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(mosi_data),.changed(trigger_spi));
+
+ localparam WAIT_TRIG = 0;
+ localparam PRE_IDLE = 1;
+ localparam CLK_REG = 2;
+ localparam CLK_INV = 3;
+ localparam POST_IDLE = 4;
+ localparam IDLE_SEN = 5;
+
+ reg [2:0] state;
+
+ reg ready_reg;
+ assign ready = ready_reg && ~trigger_spi;
+
+ //serial clock either idles or is in one of two clock states
+ reg sclk_reg;
+ assign sclk = sclk_reg;
+
+ //serial enables either idle or enabled based on state
+ wire sen_is_idle = (state == WAIT_TRIG) || (state == IDLE_SEN);
+ wire [23:0] sen24 = (sen_is_idle)? SEN_IDLE : (SEN_IDLE ^ slave_select);
+ reg [WIDTH-1:0] sen_reg;
+ always @(posedge clock) sen_reg <= sen24[WIDTH-1:0];
+ assign sen = sen_reg;
+
+ //data output shift register
+ reg [31:0] dataout_reg;
+ wire [31:0] dataout_next = {dataout_reg[30:0], 1'b0};
+ assign mosi = dataout_reg[31];
+
+ //data input shift register
+ reg [31:0] datain_reg;
+ wire [31:0] datain_next = {datain_reg[30:0], miso};
+ assign readback = datain_reg;
+
+ //counter for spi clock
+ reg [15:0] sclk_counter;
+ wire sclk_counter_done = (sclk_counter == sclk_divider);
+ wire [15:0] sclk_counter_next = (sclk_counter_done)? 0 : sclk_counter + 1;
+
+ //counter for latching bits miso/mosi
+ reg [6:0] bit_counter;
+ wire [6:0] bit_counter_next = bit_counter + 1;
+ wire bit_counter_done = (bit_counter_next == num_bits);
+
+ always @(posedge clock) begin
+ if (reset) begin
+ state <= WAIT_TRIG;
+ sclk_reg <= CLK_IDLE;
+ ready_reg <= 0;
+ end
+ else begin
+ case (state)
+
+ WAIT_TRIG: begin
+ if (trigger_spi) state <= PRE_IDLE;
+ ready_reg <= ~trigger_spi;
+ dataout_reg <= mosi_data;
+ sclk_counter <= 0;
+ bit_counter <= 0;
+ sclk_reg <= CLK_IDLE;
+ end
+
+ PRE_IDLE: begin
+ if (sclk_counter_done) state <= CLK_REG;
+ sclk_counter <= sclk_counter_next;
+ sclk_reg <= CLK_IDLE;
+ end
+
+ CLK_REG: begin
+ if (sclk_counter_done) begin
+ state <= CLK_INV;
+ if (datain_edge != CLK_IDLE) datain_reg <= datain_next;
+ if (dataout_edge != CLK_IDLE && bit_counter != 0) dataout_reg <= dataout_next;
+ sclk_reg <= ~CLK_IDLE; //transition to rising when CLK_IDLE == 0
+ end
+ sclk_counter <= sclk_counter_next;
+ end
+
+ CLK_INV: begin
+ if (sclk_counter_done) begin
+ state <= (bit_counter_done)? POST_IDLE : CLK_REG;
+ bit_counter <= bit_counter_next;
+ if (datain_edge == CLK_IDLE) datain_reg <= datain_next;
+ if (dataout_edge == CLK_IDLE && ~bit_counter_done) dataout_reg <= dataout_next;
+ sclk_reg <= CLK_IDLE; //transition to falling when CLK_IDLE == 0
+ end
+ sclk_counter <= sclk_counter_next;
+ end
+
+ POST_IDLE: begin
+ if (sclk_counter_done) state <= IDLE_SEN;
+ sclk_counter <= sclk_counter_next;
+ sclk_reg <= CLK_IDLE;
+ end
+
+ IDLE_SEN: begin
+ if (sclk_counter_done) state <= WAIT_TRIG;
+ sclk_counter <= sclk_counter_next;
+ sclk_reg <= CLK_IDLE;
+ end
+
+ default: state <= WAIT_TRIG;
+
+ endcase //state
+ end
+ end
+
+ assign debug = {
+ trigger_spi, state, //4
+ sclk, mosi, miso, ready, //4
+ sen[7:0], //8
+ 1'b0, bit_counter[6:0], //8
+ sclk_counter_done, bit_counter_done, //2
+ sclk_counter[5:0] //6
+ };
+
+endmodule //simple_spi_core
diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_prog_full.gise b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_prog_full.gise
index 9abec8c3e..660fb2f65 100644
--- a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_prog_full.gise
+++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_prog_full.gise
@@ -21,9 +21,7 @@
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="fifo_xlnx_512x36_2clk_prog_full.xise"/>
- <files xmlns="http://www.xilinx.com/XMLSchema">
- <file xil_pn:fileType="FILE_VEO" xil_pn:name="fifo_xlnx_512x36_2clk_prog_full.veo" xil_pn:origination="imported"/>
- </files>
+ <files xmlns="http://www.xilinx.com/XMLSchema"/>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs
index 28d506571..6cbd5cd3f 100644
--- a/fpga/usrp2/fifo/Makefile.srcs
+++ b/fpga/usrp2/fifo/Makefile.srcs
@@ -32,6 +32,7 @@ splitter36.v \
valve36.v \
fifo_pacer.v \
packet_dispatcher36_x3.v \
+packet_dispatcher36_x4.v \
packet_generator32.v \
packet_generator.v \
packet_verifier32.v \
diff --git a/fpga/usrp2/fifo/packet_dispatcher36_x4.v b/fpga/usrp2/fifo/packet_dispatcher36_x4.v
new file mode 100644
index 000000000..7eedb3e74
--- /dev/null
+++ b/fpga/usrp2/fifo/packet_dispatcher36_x4.v
@@ -0,0 +1,316 @@
+//
+// Copyright 2011-2012 Ettus Research LLC
+//
+// Packet dispatcher with fifo36 interface and 4 outputs.
+//
+// The packet dispatcher expects 2-byte padded ethernet frames.
+// The frames will be inspected at ethernet, IPv4, UDP, and VRT layers.
+// Packets are dispatched into the following streams:
+// * tx dsp stream
+// * tx control stream
+// * to cpu stream
+// * to external stream
+// * to both cpu and external
+//
+// The following registers are used for dispatcher control:
+// * base + 0 = this ipv4 address (32 bits)
+// * base + 1 = udp control port (upper 16 bits), udp dsp port (lower 16 bits)
+//
+
+module packet_dispatcher36_x4
+ #(
+ parameter BASE = 0
+ )
+ (
+ //clocking and reset interface:
+ input clk, input rst, input clr,
+
+ //setting register interface:
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ //input stream interfaces:
+ input [35:0] com_inp_data, input com_inp_valid, output com_inp_ready,
+
+ //output stream interfaces:
+ output [35:0] ext_out_data, output ext_out_valid, input ext_out_ready,
+ output [35:0] dsp_out_data, output dsp_out_valid, input dsp_out_ready,
+ output [35:0] ctl_out_data, output ctl_out_valid, input ctl_out_ready,
+ output [35:0] cpu_out_data, output cpu_out_valid, input cpu_out_ready
+ );
+
+ //setting register to program the IP address
+ wire [31:0] my_ip_addr;
+ setting_reg #(.my_addr(BASE+0)) sreg_ip_addr(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(my_ip_addr),.changed()
+ );
+
+ //setting register to program the UDP DSP port
+ wire [15:0] dsp_udp_port, ctl_udp_port;
+ setting_reg #(.my_addr(BASE+1), .width(32)) sreg_data_port(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out({ctl_udp_port, dsp_udp_port}),.changed()
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // Communication input inspector
+ // - inspect com input and send it to DSP, EXT, CPU, or BOTH
+ ////////////////////////////////////////////////////////////////////
+ localparam PD_STATE_READ_COM_PRE = 0;
+ localparam PD_STATE_READ_COM = 1;
+ localparam PD_STATE_WRITE_REGS = 2;
+ localparam PD_STATE_WRITE_LIVE = 3;
+
+ localparam PD_DEST_DSP = 0;
+ localparam PD_DEST_EXT = 1;
+ localparam PD_DEST_CPU = 2;
+ localparam PD_DEST_BOF = 3;
+ localparam PD_DEST_CTL = 4;
+
+ localparam PD_MAX_NUM_DREGS = 13; //padded_eth + ip + udp + seq + vrt_hdr
+ localparam PD_DREGS_DSP_OFFSET = 11; //offset to start dsp at
+
+ //output inspector interfaces
+ wire [35:0] pd_out_dsp_data;
+ wire pd_out_dsp_valid;
+ wire pd_out_dsp_ready;
+
+ wire [35:0] pd_out_ext_data;
+ wire pd_out_ext_valid;
+ wire pd_out_ext_ready;
+
+ wire [35:0] pd_out_cpu_data;
+ wire pd_out_cpu_valid;
+ wire pd_out_cpu_ready;
+
+ wire [35:0] pd_out_bof_data;
+ wire pd_out_bof_valid;
+ wire pd_out_bof_ready;
+
+ wire [35:0] pd_out_ctl_data;
+ wire pd_out_ctl_valid;
+ wire pd_out_ctl_ready;
+
+ reg [1:0] pd_state;
+ reg [2:0] pd_dest;
+ reg [3:0] pd_dreg_count; //data registers to buffer headers
+ wire [3:0] pd_dreg_count_next = pd_dreg_count + 1'b1;
+ wire pd_dreg_counter_done = (pd_dreg_count_next == PD_MAX_NUM_DREGS)? 1'b1 : 1'b0;
+ reg [35:0] pd_dregs [PD_MAX_NUM_DREGS-1:0];
+
+ reg is_eth_dst_mac_bcast;
+ reg is_eth_type_ipv4;
+ reg is_eth_ipv4_proto_udp;
+ reg is_eth_ipv4_dst_addr_here;
+ reg is_eth_udp_dsp_port_here;
+ reg is_eth_udp_ctl_port_here;
+ wire is_vrt_size_zero = (com_inp_data[15:0] == 16'h0); //needed on the same cycle, so it cant be registered
+
+ //Inspector output flags special case:
+ //Inject SOF into flags at first DSP line.
+ wire [3:0] pd_out_flags = (
+ (pd_dreg_count == PD_DREGS_DSP_OFFSET) &&
+ (pd_dest == PD_DEST_DSP)
+ )? 4'b0001 : pd_dregs[pd_dreg_count][35:32];
+
+ //The communication inspector ouput data and valid signals:
+ //Mux between com input and data registers based on the state.
+ wire [35:0] pd_out_data = (pd_state == PD_STATE_WRITE_REGS)?
+ {pd_out_flags, pd_dregs[pd_dreg_count][31:0]} : com_inp_data
+ ;
+ wire pd_out_valid =
+ (pd_state == PD_STATE_WRITE_REGS)? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE)? com_inp_valid : (
+ 1'b0));
+
+ //The communication inspector ouput ready signal:
+ //Mux between the various destination ready signals.
+ wire pd_out_ready =
+ (pd_dest == PD_DEST_DSP)? pd_out_dsp_ready : (
+ (pd_dest == PD_DEST_EXT)? pd_out_ext_ready : (
+ (pd_dest == PD_DEST_CPU)? pd_out_cpu_ready : (
+ (pd_dest == PD_DEST_BOF)? pd_out_bof_ready : (
+ (pd_dest == PD_DEST_CTL)? pd_out_ctl_ready : (
+ 1'b0)))));
+
+ //Always connected output data lines.
+ assign pd_out_dsp_data = pd_out_data;
+ assign pd_out_ext_data = pd_out_data;
+ assign pd_out_cpu_data = pd_out_data;
+ assign pd_out_bof_data = pd_out_data;
+ assign pd_out_ctl_data = pd_out_data;
+
+ //Destination output valid signals:
+ //Comes from inspector valid when destination is selected, and otherwise low.
+ assign pd_out_dsp_valid = (pd_dest == PD_DEST_DSP)? pd_out_valid : 1'b0;
+ assign pd_out_ext_valid = (pd_dest == PD_DEST_EXT)? pd_out_valid : 1'b0;
+ assign pd_out_cpu_valid = (pd_dest == PD_DEST_CPU)? pd_out_valid : 1'b0;
+ assign pd_out_bof_valid = (pd_dest == PD_DEST_BOF)? pd_out_valid : 1'b0;
+ assign pd_out_ctl_valid = (pd_dest == PD_DEST_CTL)? pd_out_valid : 1'b0;
+
+ //The communication inspector ouput ready signal:
+ //Always ready when storing to data registers,
+ //comes from inspector ready output when live,
+ //and otherwise low.
+ assign com_inp_ready =
+ (pd_state == PD_STATE_READ_COM_PRE) ? 1'b1 : (
+ (pd_state == PD_STATE_READ_COM) ? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE) ? pd_out_ready : (
+ 1'b0)));
+
+ //inspect the incoming data and mark register booleans
+ always @(posedge clk)
+ if (com_inp_ready & com_inp_valid) begin
+ case(pd_dreg_count)
+ 0: begin
+ is_eth_dst_mac_bcast <= (com_inp_data[15:0] == 16'hffff);
+ end
+ 1: begin
+ is_eth_dst_mac_bcast <= is_eth_dst_mac_bcast && (com_inp_data[31:0] == 32'hffffffff);
+ end
+ 3: begin
+ is_eth_type_ipv4 <= (com_inp_data[15:0] == 16'h800);
+ end
+ 6: begin
+ is_eth_ipv4_proto_udp <= (com_inp_data[23:16] == 8'h11);
+ end
+ 8: begin
+ is_eth_ipv4_dst_addr_here <= (com_inp_data[31:0] == my_ip_addr);
+ end
+ 9: begin
+ is_eth_udp_dsp_port_here <= (com_inp_data[15:0] == dsp_udp_port);
+ is_eth_udp_ctl_port_here <= (com_inp_data[15:0] == ctl_udp_port);
+ end
+ endcase //pd_dreg_count
+ end
+
+ always @(posedge clk)
+ if(rst | clr) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ case(pd_state)
+ PD_STATE_READ_COM_PRE: begin
+ if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
+ pd_state <= PD_STATE_READ_COM;
+ pd_dreg_count <= pd_dreg_count_next;
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ end
+ end
+
+ PD_STATE_READ_COM: begin
+ if (com_inp_ready & com_inp_valid) begin
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ if (pd_dreg_counter_done | com_inp_data[33]) begin
+ pd_state <= PD_STATE_WRITE_REGS;
+ pd_dreg_count <= 0;
+
+ //---------- begin inspection decision -----------//
+ //EOF or bcast or not IPv4 or not UDP:
+ if (
+ com_inp_data[33] || is_eth_dst_mac_bcast ||
+ ~is_eth_type_ipv4 || ~is_eth_ipv4_proto_udp
+ ) begin
+ pd_dest <= PD_DEST_BOF;
+ end
+
+ //not my IP address:
+ else if (~is_eth_ipv4_dst_addr_here) begin
+ pd_dest <= PD_DEST_EXT;
+ end
+
+ //UDP control port and VRT:
+ else if (is_eth_udp_ctl_port_here && ~is_vrt_size_zero) begin
+ pd_dest <= PD_DEST_CTL;
+ pd_dreg_count <= PD_DREGS_DSP_OFFSET;
+ end
+
+ //UDP data port and VRT:
+ else if (is_eth_udp_dsp_port_here && ~is_vrt_size_zero) begin
+ pd_dest <= PD_DEST_DSP;
+ pd_dreg_count <= PD_DREGS_DSP_OFFSET;
+ end
+
+ //other:
+ else begin
+ pd_dest <= PD_DEST_CPU;
+ end
+ //---------- end inspection decision -------------//
+
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_REGS: begin
+ if (pd_out_ready & pd_out_valid) begin
+ if (pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else if (pd_dreg_counter_done) begin
+ pd_state <= PD_STATE_WRITE_LIVE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_LIVE: begin
+ if (pd_out_ready & pd_out_valid & pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ end
+ end
+
+ endcase //pd_state
+ end
+
+ //connect this fast-path signals directly to the DSP out
+ assign dsp_out_data = pd_out_dsp_data;
+ assign dsp_out_valid = pd_out_dsp_valid;
+ assign pd_out_dsp_ready = dsp_out_ready;
+
+ assign ctl_out_data = pd_out_ctl_data;
+ assign ctl_out_valid = pd_out_ctl_valid;
+ assign pd_out_ctl_ready = ctl_out_ready;
+
+ ////////////////////////////////////////////////////////////////////
+ // Splitter and output muxes for the bof packets
+ // - split the bof packets into two streams
+ // - mux split packets into cpu out and ext out
+ ////////////////////////////////////////////////////////////////////
+
+ //dummy signals to join the the splitter and muxes below
+ wire [35:0] _split_to_ext_data, _split_to_cpu_data;
+ wire _split_to_ext_valid, _split_to_cpu_valid;
+ wire _split_to_ext_ready, _split_to_cpu_ready;
+
+ splitter36 bof_out_splitter(
+ .clk(clk), .rst(rst), .clr(clr),
+ .inp_data(pd_out_bof_data), .inp_valid(pd_out_bof_valid), .inp_ready(pd_out_bof_ready),
+ .out0_data(_split_to_ext_data), .out0_valid(_split_to_ext_valid), .out0_ready(_split_to_ext_ready),
+ .out1_data(_split_to_cpu_data), .out1_valid(_split_to_cpu_valid), .out1_ready(_split_to_cpu_ready)
+ );
+
+ fifo36_mux ext_out_mux(
+ .clk(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_ext_data), .src0_rdy_i(pd_out_ext_valid), .dst0_rdy_o(pd_out_ext_ready),
+ .data1_i(_split_to_ext_data), .src1_rdy_i(_split_to_ext_valid), .dst1_rdy_o(_split_to_ext_ready),
+ .data_o(ext_out_data), .src_rdy_o(ext_out_valid), .dst_rdy_i(ext_out_ready)
+ );
+
+ fifo36_mux cpu_out_mux(
+ .clk(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_cpu_data), .src0_rdy_i(pd_out_cpu_valid), .dst0_rdy_o(pd_out_cpu_ready),
+ .data1_i(_split_to_cpu_data), .src1_rdy_i(_split_to_cpu_valid), .dst1_rdy_o(_split_to_cpu_ready),
+ .data_o(cpu_out_data), .src_rdy_o(cpu_out_valid), .dst_rdy_i(cpu_out_ready)
+ );
+
+endmodule // packet_dispatcher36_x3
diff --git a/fpga/usrp2/fifo/packet_router.v b/fpga/usrp2/fifo/packet_router.v
index 7bfa6893d..4c0fe14b1 100644
--- a/fpga/usrp2/fifo/packet_router.v
+++ b/fpga/usrp2/fifo/packet_router.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -54,10 +54,12 @@ module packet_router
input [35:0] dsp1_inp_data, input dsp1_inp_valid, output dsp1_inp_ready,
input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,
input [35:0] err_inp_data, input err_inp_valid, output err_inp_ready,
+ input [35:0] ctl_inp_data, input ctl_inp_valid, output ctl_inp_ready,
// Output Interfaces (out of router)
output [35:0] ser_out_data, output ser_out_valid, input ser_out_ready,
output [35:0] dsp_out_data, output dsp_out_valid, input dsp_out_ready,
+ output [35:0] ctl_out_data, output ctl_out_valid, input ctl_out_ready,
output [35:0] eth_out_data, output eth_out_valid, input eth_out_ready
);
@@ -188,9 +190,9 @@ module packet_router
////////////////////////////////////////////////////////////////////
//dummy signals to join the the muxes below
- wire [35:0] _combiner0_data, _combiner1_data;
- wire _combiner0_valid, _combiner1_valid;
- wire _combiner0_ready, _combiner1_ready;
+ wire [35:0] _combiner0_data, _combiner1_data, _combiner2_data;
+ wire _combiner0_valid, _combiner1_valid, _combiner2_valid;
+ wire _combiner0_ready, _combiner1_ready, _combiner2_ready;
fifo36_mux #(.prio(0)) // No priority, fair sharing
_com_output_combiner0(
@@ -201,6 +203,14 @@ module packet_router
);
fifo36_mux #(.prio(0)) // No priority, fair sharing
+ _com_output_combiner2(
+ .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .data0_i(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
+ .data1_i(ctl_inp_data), .src1_rdy_i(ctl_inp_valid), .dst1_rdy_o(ctl_inp_ready),
+ .data_o(_combiner2_data), .src_rdy_o(_combiner2_valid), .dst_rdy_i(_combiner2_ready)
+ );
+
+ fifo36_mux #(.prio(0)) // No priority, fair sharing
_com_output_combiner1(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(dsp0_inp_data), .src0_rdy_i(dsp0_inp_valid), .dst0_rdy_o(dsp0_inp_ready),
@@ -211,7 +221,7 @@ module packet_router
fifo36_mux #(.prio(1)) // Give priority to err/cpu over dsp
com_output_source(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .data0_i(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
+ .data0_i(_combiner2_data), .src0_rdy_i(_combiner2_valid), .dst0_rdy_o(_combiner2_ready),
.data1_i(_combiner1_data), .src1_rdy_i(_combiner1_valid), .dst1_rdy_o(_combiner1_ready),
.data_o(udp_out_data), .src_rdy_o(udp_out_valid), .dst_rdy_i(udp_out_ready)
);
@@ -248,12 +258,13 @@ module packet_router
wire _cpu_out_valid;
wire _cpu_out_ready;
- packet_dispatcher36_x3 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
+ packet_dispatcher36_x4 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
.clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.com_inp_data(com_inp_data), .com_inp_valid(com_inp_valid), .com_inp_ready(com_inp_ready),
.ext_out_data(ext_out_data), .ext_out_valid(ext_out_valid), .ext_out_ready(ext_out_ready),
.dsp_out_data(dsp_out_data), .dsp_out_valid(dsp_out_valid), .dsp_out_ready(dsp_out_ready),
+ .ctl_out_data(ctl_out_data), .ctl_out_valid(ctl_out_valid), .ctl_out_ready(ctl_out_ready),
.cpu_out_data(_cpu_out_data), .cpu_out_valid(_cpu_out_valid), .cpu_out_ready(_cpu_out_ready)
);
diff --git a/fpga/usrp2/top/N2x0/bootloader.rmi b/fpga/usrp2/top/N2x0/bootloader.rmi
index 1b378b5d6..60706081c 100644
--- a/fpga/usrp2/top/N2x0/bootloader.rmi
+++ b/fpga/usrp2/top/N2x0/bootloader.rmi
@@ -1,5 +1,5 @@
-defparam bootram.RAM0.INIT_00=256'h00000000_00000000_00000000_d7fc0400_3a0b0b80_80e4b40c_82700b0b_0b0b0b0b;
-defparam bootram.RAM0.INIT_01=256'h00000000_00000000_00000000_800c0400_880c840c_80d8c62d_88080b0b_80088408;
+defparam bootram.RAM0.INIT_00=256'h00000000_00000000_00000000_d7e40400_3a0b0b80_80e49c0c_82700b0b_0b0b0b0b;
+defparam bootram.RAM0.INIT_01=256'h00000000_00000000_00000000_800c0400_880c840c_80d8ae2d_88080b0b_80088408;
defparam bootram.RAM0.INIT_02=256'h00000000_00000000_04000000_ffff0652_832b2a83_81058205_72830609_71fd0608;
defparam bootram.RAM0.INIT_03=256'h83a70400_0b0b0b0b_7383ffff_2b2b0906_05820583_83060981_83ffff73_71fd0608;
defparam bootram.RAM0.INIT_04=256'h00000000_00000000_53510400_070a8106_73097306_09060906_72057373_72098105;
@@ -18,391 +18,391 @@ defparam bootram.RAM0.INIT_10=256'h00000000_00000000_00000000_00000000_00000000_
defparam bootram.RAM0.INIT_11=256'h00000000_00000000_00000000_00000000_00000000_04000000_05055351_72720981;
defparam bootram.RAM0.INIT_12=256'h00000000_00000000_00000000_00000000_00000000_07535104_73730906_72097206;
defparam bootram.RAM0.INIT_13=256'h00000000_00000000_04000000_81ff0652_1010102a_81058305_72830609_71fc0608;
-defparam bootram.RAM0.INIT_14=256'h00000000_00000000_88aa0400_060b0b0b_10100508_a0738306_0b0b80e4_71fc0608;
-defparam bootram.RAM0.INIT_15=256'h00000000_0c510400_0c840c80_80085688_9d2d5050_0b0b80cf_88087575_80088408;
-defparam bootram.RAM0.INIT_16=256'h00000000_0c510400_0c840c80_80085688_cf2d5050_0b0b80d0_88087575_80088408;
+defparam bootram.RAM0.INIT_14=256'h00000000_00000000_88aa0400_060b0b0b_10100508_88738306_0b0b80e4_71fc0608;
+defparam bootram.RAM0.INIT_15=256'h00000000_0c510400_0c840c80_80085688_852d5050_0b0b80cf_88087575_80088408;
+defparam bootram.RAM0.INIT_16=256'h00000000_0c510400_0c840c80_80085688_b72d5050_0b0b80d0_88087575_80088408;
defparam bootram.RAM0.INIT_17=256'h04000000_07515151_05ff0506_73097274_70547106_8106ff05_0509060a_72097081;
defparam bootram.RAM0.INIT_18=256'h51040000_06075151_7405ff05_06730972_05705471_098106ff_0509060a_72097081;
defparam bootram.RAM0.INIT_19=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_05ff0504;
-defparam bootram.RAM0.INIT_1A=256'h00000000_00000000_00000000_00000000_00000000_51040000_80e4b00c_810b0b0b;
+defparam bootram.RAM0.INIT_1A=256'h00000000_00000000_00000000_00000000_00000000_51040000_80e4980c_810b0b0b;
defparam bootram.RAM0.INIT_1B=256'h00000000_00000000_00000000_00000000_00000000_00000000_04000000_71810552;
defparam bootram.RAM0.INIT_1C=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
defparam bootram.RAM0.INIT_1D=256'h00000000_00000000_00000000_00000000_00000000_04000000_10100552_02840572;
defparam bootram.RAM0.INIT_1E=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
defparam bootram.RAM0.INIT_1F=256'h00000000_00000000_00000000_00000000_00000000_020d0400_05715351_717105ff;
-defparam bootram.RAM0.INIT_20=256'h10101010_10101010_10101010_10101010_10101010_10101010_d0c33f04_82813f80;
+defparam bootram.RAM0.INIT_20=256'h10101010_10101010_10101010_10101010_10101010_10101010_d0ab3f04_82813f80;
defparam bootram.RAM0.INIT_21=256'hfc060c51_102b0772_83051010_06098105_ff067383_51047381_10101053_10101010;
defparam bootram.RAM0.INIT_22=256'h51535104_72ed3851_0a100a53_71105272_09720605_8106ff05_72728072_51043c04;
-defparam bootram.RAM0.INIT_23=256'h800b80e5_8c0c82a0_0b0b80e5_8380800b_822ebd38_80e4b408_802ea438_80e4b008;
-defparam bootram.RAM0.INIT_24=256'h0b80e590_80808280_e58c0cf8_0b0b0b80_808080a4_940c04f8_800b80e5_900c8290;
-defparam bootram.RAM0.INIT_25=256'h940b80e5_80c0a880_80e58c0c_8c0b0b0b_80c0a880_e5940c04_84800b80_0cf88080;
-defparam bootram.RAM0.INIT_26=256'h70085252_80e4bc08_5170a738_80e59833_04ff3d0d_80e5940c_80d8f80b_900c0b0b;
-defparam bootram.RAM0.INIT_27=256'h9834833d_810b80e5_5270ee38_08700852_2d80e4bc_e4bc0c70_38841280_70802e94;
-defparam bootram.RAM0.INIT_28=256'h38823d0d_09810685_800b802e_0b0b0b0b_802e8e38_80e58808_3d0d0b0b_0d040480;
-defparam bootram.RAM0.INIT_29=256'h3d225a79_80d33895_0d685b7a_0404ee3d_3f823d0d_0b0bf5d4_e588510b_040b0b80;
-defparam bootram.RAM0.INIT_2A=256'h2e973881_79838086_3881e439_80842e8e_8b387983_83808524_80c23879_8380852e;
-defparam bootram.RAM0.INIT_2B=256'h7a81e2c4_81e2c00c_39890a0b_e1880c99_840c7a81_0c7a81e1_0b81e180_da39890a;
-defparam bootram.RAM0.INIT_2C=256'h2e9e3879_79838085_973d225a_7c2eab38_0c805c7a_7a81e4d0_c80c8639_0c7a81e2;
-defparam bootram.RAM0.INIT_2D=256'h815c923d_38818039_80862e86_825c7983_38818c39_80842e92_8b387983_83808524;
-defparam bootram.RAM0.INIT_2E=256'h3d415e5c_0b883d99_5b5f4080_0284057d_943f8008_a9893f8a_84055241_7053963d;
-defparam bootram.RAM0.INIT_2F=256'h7d055b5b_7b1d963d_901f5e5c_ef38800b_5c887c26_7b34811c_5b5b7933_7b1d7f1d;
-defparam bootram.RAM0.INIT_30=256'h811c5c86_79337b34_601d5b5b_5e5c7b1d_800b881f_7c26ed38_811c5c88_79337b34;
-defparam bootram.RAM0.INIT_31=256'h3d0d04ee_99ff3f94_7c26ef38_811c5c86_79337b34_611d5b5b_805c7b1e_7c26ef38;
-defparam bootram.RAM0.INIT_32=256'h75538b52_802e8c38_2e943875_0856758b_279c3877_5a588379_84120859_3d0d686a;
-defparam bootram.RAM0.INIT_33=256'h8b5ba05c_f93fa057_d9cc5194_53a45280_268e3878_e15778a3_958c3f80_80d8fc51;
-defparam bootram.RAM0.INIT_34=256'h89a23f80_0480c15c_05567508_2980dbbc_91387584_75922682_ff9f1756_8818085d;
-defparam bootram.RAM0.INIT_35=256'h962a8480_32703070_183380f2_2e923894_577580f2_33568880_fb399518_08085e81;
-defparam bootram.RAM0.INIT_36=256'h83388157_5775772e_97193357_0852800b_08538c18_33549018_76559618_06595156;
-defparam bootram.RAM0.INIT_37=256'h568cd23f_8c193352_3dea0553_33705495_b3398d18_80d35c81_3f80085f_765196a2;
-defparam bootram.RAM0.INIT_38=256'hb5053480_75028405_3f80c85c_52568ddf_538c1933_70548e19_398d1833_80c95c94;
-defparam bootram.RAM0.INIT_39=256'h0476085f_58567508_058c1908_2980dc88_c2387584_75852680_33ff0556_ff399418;
-defparam bootram.RAM0.INIT_3A=256'h70084056_80e59c05_39768429_2277239b_a2399218_1808770c_5fa93990_ae397622;
-defparam bootram.RAM0.INIT_3B=256'h55943ddc_5c8c1808_785e80cc_d25cad39_710c5680_05901908_2980e59c_8e397684;
-defparam bootram.RAM0.INIT_3C=256'ha439a05c_7826ed38_81185888_75337734_79055757_7719963d_833d5a58_0554800b;
-defparam bootram.RAM0.INIT_3D=256'h887826ed_34811858_57753377_3d790557_58771996_0b833d5a_dc055480_a455943d;
-defparam bootram.RAM0.INIT_3E=256'h2e9238a0_993f7280_98525392_705380da_fe3d0d74_943d0d04_519b8b3f_38838080;
-defparam bootram.RAM0.INIT_3F=256'h843d0d04_518fba3f_87c63f72_a0527251_9e3f8d39_8fcb3f9b_d73f8151_52a05187;
-defparam bootram.RAM1.INIT_00=256'h91d43f81_80daf451_dd3f8b52_dad45191_3f885280_b85188ba_8d3f80da_fa3d0d82;
-defparam bootram.RAM1.INIT_01=256'h3f800851_d43f8684_908f3f87_3f800851_843f85b1_859d3f86_0ca9a73f_0b80e5b8;
-defparam bootram.RAM1.INIT_02=256'h85528008_e73f8380_94b63f85_52800851_85933f73_3f800854_c83f85f8_90a93f87;
-defparam bootram.RAM1.INIT_03=256'hb2528380_94f23f8a_83808451_3f8ab252_805194fc_bf528380_94c03f8c_518e9a3f;
-defparam bootram.RAM1.INIT_04=256'h9251a584_d33f8380_80825194_c0865283_94de3f80_83808551_3f8ab252_865194e8;
-defparam bootram.RAM1.INIT_05=256'h802e80c9_08568008_8e873f80_3dfc0551_abe93f88_51a9d73f_903f8fcc_3f80518e;
-defparam bootram.RAM1.INIT_06=256'h055180c4_52800890_5380db98_06ad3884_ee2e0981_557382fd_8e052255_38768008;
-defparam bootram.RAM1.INIT_07=256'h3f883974_73518591_3f86963f_52548ef7_3f941670_a0519086_9a3880db_d43f8008;
-defparam bootram.RAM1.INIT_08=256'hb73f8787_91ce3f82_0d85df3f_9e39fe3d_8bfe3fff_3fa4d73f_8b3f8d8c_5275519a;
-defparam bootram.RAM1.INIT_09=256'h52845184_8af23f84_3f82ac51_80518588_ac3f9f52_52805185_88833f9f_3f8bb33f;
-defparam bootram.RAM1.INIT_0A=256'h82ac518a_5184e13f_3f905290_ac518ad8_84ee3f82_88528851_518ae53f_fb3f82ac;
-defparam bootram.RAM1.INIT_0B=256'haf3fff13_80e4518a_5184c53f_3f9f529c_e4518abc_84d23f80_9f528051_cb3f8253;
-defparam bootram.RAM1.INIT_0C=256'h800c843d_840c810b_890b81e0_5184a93f_3f9f5281_9e5184cd_df389f52_53728025;
-defparam bootram.RAM1.INIT_0D=256'h8c05a705_7a7d7f02_04f93d0d_51823d0d_8106800c_08708b2a_0d82808c_0d04803d;
-defparam bootram.RAM1.INIT_0E=256'h88388855_5575832e_80258805_2e933872_59577582_5a575758_80258205_33703070;
-defparam bootram.RAM1.INIT_0F=256'h2cff0577_97387681_5472802e_259e3872_80548177_9f2a5153_55733070_7383388a;
-defparam bootram.RAM1.INIT_10=256'h7281ff06_51aea93f_5474527b_73538180_80548639_07515454_7072842b_7131fe05;
-defparam bootram.RAM1.INIT_11=256'h0d029f05_0d04fb3d_8f3f893d_80da51ae_973f8152_811851ae_9f3f7352_527751ae;
-defparam bootram.RAM1.INIT_12=256'hade63f81_5280c551_fe3d0d81_873d0d04_51fee63f_53785275_80ca54bd_33568155;
-defparam bootram.RAM1.INIT_13=256'h0781e080_80087090_f33881e0_5372802e_0881ff06_feb83f80_3f8f883f_528151d6;
-defparam bootram.RAM1.INIT_14=256'h52527080_72177033_76279e38_54805372_57817056_0d787a57_0d04fa3d_0c53843d;
-defparam bootram.RAM1.INIT_15=256'h83388151_5170802e_39747407_811353df_83388055_7181ff2e_54713352_2e833880;
-defparam bootram.RAM1.INIT_16=256'h3f843d0d_c451beb1_a45280e4_865380dc_80e5c034_3d0d810b_3d0d04fe_70800c88;
-defparam bootram.RAM1.INIT_17=256'hd051ade5_56825280_873d7054_c0348654_810b80e5_5574bc38_80e5c033_04f93d0d;
-defparam bootram.RAM1.INIT_18=256'h86537552_55748c38_0881ff06_fef43f80_86527551_802e9c38_ff065574_3f800881;
-defparam bootram.RAM1.INIT_19=256'he4c00c04_dca00880_e5bc3480_04810b80_0c893d0d_e4c40b80_bde73f80_80e4c451;
-defparam bootram.RAM1.INIT_1A=256'h51ad863f_8c5280d0_3dfc0553_34845487_0b80e5bc_74b93881_e5bc3355_fb3d0d80;
-defparam bootram.RAM1.INIT_1B=256'h86387580_ff065574_3f800881_0551fe92_52873dfc_2e993884_06557480_800881ff;
-defparam bootram.RAM1.INIT_1C=256'hcc3f8008_80d051ab_75538c52_77568454_04fb3d0d_0c873d0d_e4c00b80_e4c00c80;
-defparam bootram.RAM1.INIT_1D=256'h803d0d73_873d0d04_3474800c_0b80e5bc_e4c00c81_38750880_74802e8d_81ff0655;
-defparam bootram.RAM1.INIT_1E=256'h73097375_04803d0d_51823d0d_81e08c0c_80e5c40c_08060770_7180e5c4_09737506;
-defparam bootram.RAM1.INIT_1F=256'h0d747053_3f04fe3d_0d0481af_0c51823d_0c81e098_7080e5c8_c8080607_067180e5;
-defparam bootram.RAM1.INIT_20=256'h3d0d7779_3d0d04fb_81b63f83_8a528051_04ff3d0d_0c843d0d_c73f7280_53805181;
-defparam bootram.RAM1.INIT_21=256'he539800b_5581913f_06537652_157481ff_2e903881_54547280_7081ff06_56567433;
-defparam bootram.RAM1.INIT_22=256'hffbd3f8a_53705253_3d0d7476_3d0d04fe_51cd3f83_0d735280_0d04ff3d_800c873d;
-defparam bootram.RAM1.INIT_23=256'h3d0d7251_3d0d0480_51dd3f83_0d735280_0d04ff3d_800c843d_e73f800b_52725180;
-defparam bootram.RAM1.INIT_24=256'h05702272_1080dcac_90800575_73a02982_04ff3d0d_34823d0d_80e4cc12_028f0533;
-defparam bootram.RAM1.INIT_25=256'h7251ce3f_d0133352_c63f80e4_33527251_80e4cc13_3d0d8053_3d0d04fe_0c535183;
-defparam bootram.RAM1.INIT_26=256'he4cc1433_06953880_8a2e0981_78565474_fc3d0d76_843d0d04_7325e538_81135382;
-defparam bootram.RAM1.INIT_27=256'h802ef838_14085372_80055484_a0298290_51de3f73_388d5273_09810687_5372812e;
-defparam bootram.RAM1.INIT_28=256'h85389012_5370802e_085252ff_80058811_a0298290_fe3d0d74_863d0d04_748c150c;
-defparam bootram.RAM1.INIT_29=256'h800c7088_ff0681a8_d8227081_880c80e4_800b81a8_04ff3d0d_0c843d0d_08537280;
-defparam bootram.RAM1.INIT_2A=256'h55535481_05970533_76780288_04fd3d0d_0c833d0d_0b81a888_0c518180_2a81a884;
-defparam bootram.RAM1.INIT_2B=256'ha88c0c81_10810781_70f13872_06515151_862a7081_a8900870_81863881_5171802e;
-defparam bootram.RAM1.INIT_2C=256'h2a708106_90087087_f13881a8_51515170_2a708106_90087081_900c81a8_900b81a8;
-defparam bootram.RAM1.INIT_2D=256'h81a8900c_38a05170_71812e83_3880e851_71802eb1_802eba38_51515170_70813251;
-defparam bootram.RAM1.INIT_2E=256'hff1252cc_81055634_51707470_81a88c08_5170f138_81065151_70812a70_81a89008;
-defparam bootram.RAM1.INIT_2F=256'h05335553_02880597_3d0d7678_3d0d04fd_70800c85_81a8900c_3980c00b_39815188;
-defparam bootram.RAM1.INIT_30=256'h2e843881_d0517180_a88c0c81_38721081_515170f1_70810651_0870862a_5481a890;
-defparam bootram.RAM1.INIT_31=256'h872a7081_a8900870_70f13881_06515151_812a7081_a8900870_a8900c81_90517081;
-defparam bootram.RAM1.INIT_32=256'h5171812e_8c0c80d0_733381a8_2e80c538_cf387180_70802e80_51515151_06708132;
-defparam bootram.RAM1.INIT_33=256'h0870872a_3881a890_515170f1_70810651_0870812a_0c81a890_7081a890_83389051;
-defparam bootram.RAM1.INIT_34=256'h80c00b81_81518a39_54ffb739_14ff1353_2e8e3881_51517080_81325151_70810670;
-defparam bootram.RAM1.INIT_35=256'h5281b8ac_81b8ac08_74259b38_54805372_fd3d0d75_853d0d04_5170800c_a8900c80;
-defparam bootram.RAM1.INIT_36=256'h80880c81_0dff0b82_0d04ff3d_e239853d_38811353_9f7127f1_5151868d_08707331;
-defparam bootram.RAM1.INIT_37=256'h8405540c_9efc7270_f0528751_8c0c80ef_ff0b8280_8280840c_800cef0b_e20b8280;
-defparam bootram.RAM1.INIT_38=256'h51528053_08710658_0982808c_80880870_fb3d0d82_833d0d04_8025f138_ff115170;
-defparam bootram.RAM1.INIT_39=256'h8f398113_82808c0c_52712d74_72517308_802e8f38_76065271_f0555574_810b80ef;
-defparam bootram.RAM1.INIT_3A=256'h2980eff0_9f387184_52718726_ff3d0d73_873d0d04_7325dc38_57555387_84157610;
-defparam bootram.RAM1.INIT_3B=256'h04ff3d0d_833d0d04_0c535152_06828088_88087072_70098280_5181722b_0575710c;
-defparam bootram.RAM1.INIT_3C=256'h0c81b8a0_0b81e0cc_803d0d81_833d0d04_81e0c80c_e0c40c52_74700881_02920522;
-defparam bootram.RAM1.INIT_3D=256'h04fe3d0d_81e0c00c_04de3f71_0c823d0d_0b81e0cc_2ef33882_51517080_08708406;
-defparam bootram.RAM1.INIT_3E=256'h80529a39_53538180_902a710c_a0087571_933881b8_5272802e_70810654_81b8a008;
-defparam bootram.RAM1.INIT_3F=256'h843d0d04_5271800c_ff9e3f72_51f8d33f_3880dcb8_71802e8b_81065152_71812a70;
-defparam bootram.RAM2.INIT_00=256'hff3d0d02_823d0d04_800b800c_f2388180_5170802e_80c00651_b8a00870_803d0d81;
-defparam bootram.RAM2.INIT_01=256'h0b81e0cc_2ef33884_51517080_08709006_5281b8a0_81e0cc0c_902b8807_8e052270;
-defparam bootram.RAM2.INIT_02=256'ha5c63f81_70335252_a53f7214_38ba51f7_72802e86_75548053_04fd3d0d_0c833d0d;
-defparam bootram.RAM2.INIT_03=256'h33535680_11335470_11335581_11335682_3d0d7783_3d0d04fb_27e63885_13538573;
-defparam bootram.RAM2.INIT_04=256'h515b5f5d_30709f2a_bb053370_63029005_0d7c7e61_0d04f63d_ed3f873d_dcbc5180;
-defparam bootram.RAM2.INIT_05=256'h55785480_26943879_30577777_51782d76_387952ad_75802e8a_80258f38_5b595776;
-defparam bootram.RAM2.INIT_06=256'h51782d8c_dcc80533_3f800880_7651ada4_bd3f7752_800851ff_51ad8c3f_53775276;
-defparam bootram.RAM2.INIT_07=256'h08a1e35c_70840552_0d8c3d70_0d04f73d_8d3f823d_053351f6_3d0d028b_3d0d0480;
-defparam bootram.RAM2.INIT_08=256'hdb388119_09810680_5675a52e_7681ff06_2e81d138_57577580_7081ff06_5a587833;
-defparam bootram.RAM2.INIT_09=256'h3875802e_80e3248a_2eb93875_387580e3_80f024a0_80fb3875_7580f02e_70335759;
-defparam bootram.RAM2.INIT_0A=256'h7580f32e_f5248b38_ac387580_7580f52e_38818b39_e42e80c6_95397580_819e3881;
-defparam bootram.RAM2.INIT_0B=256'h792d80da_80527551_33525956_84198312_80ec3977_f82eba38_f5397580_80db3880;
-defparam bootram.RAM2.INIT_0C=256'ha1e35481_59568055_19710852_90397784_e3548053_568055a1_71085259_39778419;
-defparam bootram.RAM2.INIT_0D=256'h39778419_fdd03f9e_90527551_e3548053_568055a1_71085259_39778419_538a5292;
-defparam bootram.RAM2.INIT_0E=256'h59fea339_ec398119_3351792d_70810558_38805276_75802e8e_56763356_71085959;
-defparam bootram.RAM2.INIT_0F=256'h51515170_2a708106_90087088_3d0d81a0_940c0480_810b81a0_8b3d0d04_800b800c;
-defparam bootram.RAM2.INIT_10=256'h5354d03f_c0800755_06077080_067b8c80_337980ff_0d029705_0d04fd3d_f138823d;
-defparam bootram.RAM2.INIT_11=256'h73517380_81a0900c_80c28007_a0900c71_800c7281_0c7781a0_0681a098_7683ffff;
-defparam bootram.RAM2.INIT_12=256'h53727427_54555580_0d76787a_0d04fc3d_800c853d_80085170_aa3f81a0_2e8938ff;
-defparam bootram.RAM2.INIT_13=256'hff067290_387183ff_70802e8d_71902a51_5351ee39_05811555_15702273_8f387210;
-defparam bootram.RAM2.INIT_14=256'h0880e5d8_f43f7670_e5d051ae_53755280_fd3d0d86_863d0d04_3971800c_2a0552ec;
-defparam bootram.RAM2.INIT_15=256'h38833d0d_708025f3_ff125252_720c8812_52895180_0d80e5e0_0d04ff3d_0c54853d;
-defparam bootram.RAM2.INIT_16=256'h52528972_81128812_742e8e38_70225472_e5dc5252_53800b80_02960522_04fd3d0d;
-defparam bootram.RAM2.INIT_17=256'h08802e89_56c73f80_ff065358_7a7183ff_fa3d0d78_853d0d04_5170800c_25ee3880;
-defparam bootram.RAM2.INIT_18=256'h802e8f38_15555271_55730888_e5dc5555_e5e00b80_39800880_84050cad_38768008;
-defparam bootram.RAM2.INIT_19=256'h86705493_04f13d0d_0c883d0d_23768414_883f7573_25eb389c_54558975_81158814;
-defparam bootram.RAM2.INIT_1A=256'h028405a2_b43f9080_dc0551ad_0552913d_53923d88_adc33f73_d6055254_3d53923d;
-defparam bootram.RAM2.INIT_1B=256'h052380c0_028405aa_23818080_800b8c3d_05a60523_23800284_800b8b3d_0523818a;
-defparam bootram.RAM2.INIT_1C=256'h80080284_51fdb73f_913de405_80538a52_685d665e_05ae0523_23800284_910b8d3d;
-defparam bootram.RAM2.INIT_1D=256'hbe0523ac_80028405_0b913d23_ba052380_22028405_3d23963d_983d2290_05ae0523;
-defparam bootram.RAM2.INIT_1E=256'h0b973d23_0d805b80_0d04e83d_8c3f913d_8405519e_c02981e6_05526980_53913dd4;
-defparam bootram.RAM2.INIT_1F=256'h80f20522_ac933f02_3df80551_e5d0529a_3f865380_0551aca1_529a3df2_86539b3d;
-defparam bootram.RAM2.INIT_20=256'ha13d0845_05436e44_c41143f0_800b9b3d_8008585a_f73f8008_e20523f7_02840580;
-defparam bootram.RAM2.INIT_21=256'h7508701a_3d568458_fc06408c_3d088305_3d085fa3_5d6e5ea1_59845c90_a33d0846;
-defparam bootram.RAM2.INIT_22=256'h83065473_2e9a3873_08547380_73760c75_75278438_565a5573_80713151_787c3190;
-defparam bootram.RAM2.INIT_23=256'h519cde3f_16085276_75085394_51effb3f_3880dce4_73802e88_08830654_8c389416;
-defparam bootram.RAM2.INIT_24=256'h51f6fd3f_5978822a_843880c0_3878bf26_8025ffac_19595777_570817ff_75708405;
-defparam bootram.RAM2.INIT_25=256'hca052380_02840580_94055a79_3d237f1f_8a800b94_6e404081_ea3d0d6b_9a3d0d04;
-defparam bootram.RAM2.INIT_26=256'h80d20523_80028405_79963d23_c080075a_05236980_840580ce_81808002_0b953d23;
-defparam bootram.RAM2.INIT_27=256'hd2052391_02840580_08095a79_fae03f80_3d70525c_538a5293_46684780_80e5d808;
-defparam bootram.RAM2.INIT_28=256'h7a51f6cb_51f7d73f_3880dd90_065a7992_800881ff_5e8ac83f_3d70535c_3d705398;
-defparam bootram.RAM2.INIT_29=256'h1f5b5b79_5c7b1d7c_90805380_94557b54_586b575d_5a6d5960_a939027f_3fedea3f;
-defparam bootram.RAM2.INIT_2A=256'h3d238d3d_ae05228a_0d7f5802_0d04f73d_893f983d_26ef38fd_1c5c867c_337b3481;
-defparam bootram.RAM2.INIT_2B=256'h3df80553_5588548b_2377567e_8405a605_3d238002_1857768b_a2052388_22028405;
-defparam bootram.RAM2.INIT_2C=256'h0b8f3d34_b2052386_80028405_8e3d2390_3d0d810b_3d0d04ee_fe9e3f8b_91527d51;
-defparam bootram.RAM2.INIT_2D=256'hd03feb80_ec0551a8_0852943d_3f865380_0523eab1_028405b6_b5053481_84028405;
-defparam bootram.RAM2.INIT_2E=256'h3f800808_cd3feae4_f60551a9_8052943d_c03f8653_f20551a8_0852943d_3f845380;
-defparam bootram.RAM2.INIT_2F=256'hdc1b337a_1c5a80dc_53805b7a_05549086_55943de4_5780569c_59805880_43025c80;
-defparam bootram.RAM2.INIT_30=256'h90862e09_225f5d7d_3d088e11_d93d0daa_943d0d04_38fbcb3f_867b26ef_34811b5b;
-defparam bootram.RAM2.INIT_31=256'hb53f86ee_ddc051f5_38795280_799b268d_f2055b5b_3d088429_38901dac_8106829d;
-defparam bootram.RAM2.INIT_32=256'h1b225a79_86d43884_2e098106_5a799080_38821b22_810686e2_79812e09_397a225a;
-defparam bootram.RAM2.INIT_33=256'h853fa81d_70524088_b9389e1d_09810686_5a79812e_38861b22_810686c6_8c842e09;
-defparam bootram.RAM2.INIT_34=256'h08868f38_80085c80_51a6823f_3dffa805_e5d852a9_43845380_fd3f8008_70525f87;
-defparam bootram.RAM2.INIT_35=256'h23841b33_0580fe05_1b220284_a13d2382_e03f7a22_527951a6_5380e5d0_a73d5a86;
-defparam bootram.RAM2.INIT_36=256'h0551a6ad_52a93de4_23865379_05818205_34820284_05818105_1b330284_a23d3485;
-defparam bootram.RAM2.INIT_37=256'h903f7953_527a51a6_8653981d_818e055b_a69f3f02_ea05525a_7f53aa3d_3f847054;
-defparam bootram.RAM2.INIT_38=256'h587c575d_5a7c597c_f83f027c_527e51a5_5f86537a_843f9e3d_f40551a6_7f52a93d;
-defparam bootram.RAM2.INIT_39=256'h993f84ee_26ef38f9_1c5c867c_337b3481_1d5b5b79_537b1d7f_dc05547d_9c55a93d;
-defparam bootram.RAM2.INIT_3A=256'hd1387988_09810684_5b60842e_8c2a435b_1d702270_84e43890_2e098106_397d9080;
-defparam bootram.RAM2.INIT_3B=256'h5e865380_84b4387e_ff065f7e_1b2280ff_84c03886_2e098106_515a7985_2a708f06;
-defparam bootram.RAM2.INIT_3C=256'ha3fb3f80_70535b5c_80e5d854_901c6255_38815e7e_3f800883_1d51a491_dcdc5282;
-defparam bootram.RAM2.INIT_3D=256'h22ec1140_1b33821c_84b83f89_529c1d51_8138881d_7b802e84_5c7d8738_08833881;
-defparam bootram.RAM2.INIT_3E=256'h5d42407d_8411225d_7a08a41f_388c1b08_810683de_7f912e09_2e81bb38_5d407f81;
-defparam bootram.RAM2.INIT_3F=256'hf5c33f80_22535d5d_e41d821d_bd39ac1d_f2843f83_80dde051_79537d52_7a2e8f38;
-defparam bootram.RAM3.INIT_00=256'ha3ef3f9c_7d527951_5f5a8853_9a3d993d_3d237f49_387a2299_802e83a6_08428008;
-defparam bootram.RAM3.INIT_01=256'h51a3ce3f_b4055279_53a93dff_23604788_1b22973d_a3e33f82_79527f51_3d408853;
-defparam bootram.RAM3.INIT_02=256'h811c5c88_79337b34_7c1f5b5b_5e5c7b1d_557e843d_3f7b567c_7d51a3c5_88537952;
-defparam bootram.RAM3.INIT_03=256'h5a792d82_61840508_7b26ef38_811b5b88_84051c34_5a793302_805b7f1b_7c26ef38;
-defparam bootram.RAM3.INIT_04=256'h335a7983_9539811a_81bb3882_387d882e_7d832e8a_33405b42_08a41e70_ad398c1b;
-defparam bootram.RAM3.INIT_05=256'h2251f481_81f4387c_2e098106_5e5c7991_8912335c_1d80c01e_81a238ac_2e098106;
-defparam bootram.RAM3.INIT_06=256'h88537a52_9b3d5c5e_794b983d_229b3d23_1c085a7c_80fe388c_8008802e_3f800841;
-defparam bootram.RAM3.INIT_07=256'h4d8853a9_9d3d2379_5a821d22_3f901c08_7f51a29d_88537d52_3f963d40_7d51a2a9;
-defparam bootram.RAM3.INIT_08=256'h1d7c1f5b_3d5e5c7b_7e557e84_fc3f7e56_527d51a1_3f88537a_7a51a285_3dcc0552;
-defparam bootram.RAM3.INIT_09=256'h887b26ef_34811b5b_0284051c_1b5a7933_38805b7f_887c26ef_34811c5c_5b79337b;
-defparam bootram.RAM3.INIT_0A=256'h02840580_953d347e_1d5d5d7e_39ac1de4_ad3f80de_80e951e5_085a792d_38608405;
-defparam bootram.RAM3.INIT_0B=256'h53605294_d205237e_02840580_23861a22_1a22963d_ce052384_02840580_cd05347e;
-defparam bootram.RAM3.INIT_0C=256'hce05237b_02840580_08095a79_f1c03f80_2a527c51_08537b81_f1cc3f80_3d70525b;
-defparam bootram.RAM3.INIT_0D=256'h53727427_e6ac0855_0d800b80_0d04fc3d_f73fa93d_526151f5_547a537f_567c557d;
-defparam bootram.RAM3.INIT_0E=256'h39811353_3872518b_09810685_5170752e_088c1353_54565171_0880e6b4_a4387670;
-defparam bootram.RAM3.INIT_0F=256'h8025ba38_b93f8008_535755ff_0d777971_0d04fb3d_800c863d_38ff5170_737326e7;
-defparam bootram.RAM3.INIT_10=256'hb00c5473_870680e6_b0088111_8e3980e6_80e6ac0c_89388114_54738726_80e6ac08;
-defparam bootram.RAM3.INIT_11=256'h80080554_39800810_b8145194_755280e6_51548653_e6b4120c_2b760880_10147082;
-defparam bootram.RAM3.INIT_12=256'h54738008_fed83f80_3d0d7551_3d0d04fd_9fbf3f87_e6b80551_73842980_86537552;
-defparam bootram.RAM3.INIT_13=256'h800c853d_3f815473_76519f95_e6b80552_73842980_05548653_08108008_24993880;
-defparam bootram.RAM3.INIT_14=256'h33710780_72078316_3370882b_2b078214_982b7190_81123371_0d757033_0d04fd3d;
-defparam bootram.RAM3.INIT_15=256'hffff068b_a8387383_56595776_80e79422_3d0d7d7f_3d0d04f9_56545285_0c525354;
-defparam bootram.RAM3.INIT_16=256'h742380c0_05515476_2980e798_29147090_d3387390_73832680_31525654_3d227072;
-defparam bootram.RAM3.INIT_17=256'h3d527390_5488538a_74902915_8326ad38_57575474_22707231_ff068d3d_397383ff;
-defparam bootram.RAM3.INIT_18=256'h1656ec39_e3b23f81_53547451_75177033_78279138_3f805675_05519e85_2980e798;
-defparam bootram.RAM3.INIT_19=256'h88140c80_23800b82_54548073_0b80e798_e7942380_9a052280_fc3d0d02_893d0d04;
-defparam bootram.RAM3.INIT_1A=256'hd938863d_54837427_82901454_9b3f8114_740551ef_80e79422_0cb5ab52_0b828c14;
-defparam bootram.RAM3.INIT_1B=256'h881a085b_be387582_51567581_32708106_847c2c81_e7985a5c_0d800b80_0d04f43d;
-defparam bootram.RAM3.INIT_1C=256'hff06708a_38800881_ff2e80c5_f73f8008_5b7b51e2_781a8805_2680d638_5d7981ff;
-defparam bootram.RAM3.INIT_1D=256'h777b7081_8338815d_5876802e_51595158_80250753_72802571_8d327030_32703072;
-defparam bootram.RAM3.INIT_1E=256'h38828819_7a27ffb1_1a5a81ff_8c1a0c81_0c800b82_0582881a_88190881_055d3482;
-defparam bootram.RAM3.INIT_1F=256'h75802eab_38782256_8b7627bf_8c1b0c56_08811182_38828c19_d2387c91_08802e80;
-defparam bootram.RAM3.INIT_20=256'h887826ef_34811858_57753377_1a781a57_3d5b5877_54800b83_08558819_38828819;
-defparam bootram.RAM3.INIT_21=256'h5a5c837c_1c82901a_8c1a0c81_0c800b82_0b82881a_f2a83f80_227c0551_3880e794;
-defparam bootram.RAM3.INIT_22=256'h9d055755_80028405_5194d53f_80c05268_3d705457_ea3d0d88_8e3d0d04_27fea938;
-defparam bootram.RAM3.INIT_23=256'h81992e09_33515473_38741670_09810694_7381aa2e_ff2e9d38_51547381_74177033;
-defparam bootram.RAM3.INIT_24=256'h863d7054_04f93d0d_0c983d0d_80547380_7527d138_811555be_81548b39_81068538;
-defparam bootram.RAM3.INIT_25=256'h83388155_2e098106_3f800875_735199e5_80de8452_80558453_5194853f_54845279;
-defparam bootram.RAM3.INIT_26=256'h55805189_0881ff06_8add3f80_0d8df23f_0c04fc3d_0b81e094_3d0d0481_74800c89;
-defparam bootram.RAM3.INIT_27=256'h80dec051_3974b538_88518183_883880de_51515473_2a708106_b408708d_dc3f81b8;
-defparam bootram.RAM3.INIT_28=256'h82ac51e3_5189a23f_ded83f81_80deec51_802e9a38_bf3f8008_800a51fe_deec3fb0;
-defparam bootram.RAM3.INIT_29=256'h3880dff0_08802ebb_fee33f80_98800a51_5180cc39_3f80dfa4_0a5184b5_8b3fb080;
-defparam bootram.RAM3.INIT_2A=256'h51e2cd3f_953f82ac_e09c51de_92da3f80_98800a51_80ffff52_83808053_51deab3f;
-defparam bootram.RAM3.INIT_2B=256'hf13f863d_e0fc51dd_3f883980_805183e9_51e2bd3f_853f82ac_e0c051de_fee53f80;
-defparam bootram.RAM3.INIT_2C=256'h3f80efd8_a051dca0_dd3fa052_c85254e6_705380e1_fd3d0d75_efd80c04_0d047180;
-defparam bootram.RAM3.INIT_2D=256'h08537280_3f80efd8_8051dc84_3d0da052_3d0d04fe_51722d85_2e853873_08537280;
-defparam bootram.RAM3.INIT_2E=256'h51535481_2a708106_0b800886_89a83fff_3d0d9a51_3d0d04fc_51722d84_2e853880;
-defparam bootram.RAM3.INIT_2F=256'h248a388a_38718280_82802e9b_80e45471_80065355_0b800886_80ec3882_5571802e;
-defparam bootram.RAM3.INIT_30=256'h5188db3f_80085285_5188e33f_38ff5484_84802e83_87e85471_8e388a39_5471802e;
-defparam bootram.RAM3.INIT_31=256'h53515452_80e28055_80efe40c_c0113370_720780e2_2c708306_0680088a_71882a8c;
-defparam bootram.RAM3.INIT_32=256'hefdc0c74_98387480_efdc082e_9d3f7480_085252dc_80e4e011_822b8c06_dc843f71;
-defparam bootram.RAM3.INIT_33=256'he0082e8e_387380ef_09810696_3974822e_fec13f9e_8106a338_74812e09_822ea638;
-defparam bootram.RAM3.INIT_34=256'h3f800851_3d0dd8c5_3d0d04fd_87e83f86_fb3f9951_3f7351fd_e00cfea7_387380ef;
-defparam bootram.RAM3.INIT_35=256'hae80529c_87f13f81_8d529851_5187c73f_efe00c99_0cff0b80_0b80efdc_87bd3f80;
-defparam bootram.RAM3.INIT_36=256'h845187cb_06705354_8007f49f_3f800890_845187aa_51e1853f_bbcb5284_5187e83f;
-defparam bootram.RAM3.INIT_37=256'h3f800884_805186fe_51e3fb3f_5280e298_80085373_082e8d38_953f7380_3f845187;
-defparam bootram.RAM3.INIT_38=256'h71832a84_71872a07_852a8206_97053370_fd3d0d02_853d0d04_5187a43f_80075280;
-defparam bootram.RAM3.INIT_39=256'h852b80c0_81ff0676_73070770_2ba00671_90067483_07077310_88067173_0672812a;
-defparam bootram.RAM3.INIT_3A=256'h04fe3d0d_52853d0d_55525555_51525351_82c0800c_7081ff06_78872b07_06707207;
-defparam bootram.RAM3.INIT_3B=256'h9951ff8c_ff923f81_3f81aa51_ff51ff98_ff9e3f81_5381ff51_81d00a07_74d00a06;
-defparam bootram.RAM3.INIT_3C=256'h51feed3f_7281ff06_52fef53f_81ff0652_72882a70_51ff813f_873f80e1_3fb251ff;
-defparam bootram.RAM3.INIT_3D=256'hcf3fb051_065253fe_2a7081ff_db3f7290_982a51fe_fee23f72_3f818151_b251fee8;
-defparam bootram.RAM3.INIT_3E=256'h3fa051fe_8051feb0_51feb53f_feba3fa0_bf3f8e51_3f8051fe_a151fec4_feca3f81;
-defparam bootram.RAM3.INIT_3F=256'h3f863d22_d05183e9_53805280_873dfc05_3d0d8254_3d0d04fb_fea63f84_ab3f8051;
-defparam bootram.RAM4.INIT_00=256'h90387753_77829326_08585957_3d088412_3d0880d7_3d0d80d5_0d04ffb2_800c873d;
-defparam bootram.RAM4.INIT_01=256'h9c055675_842980e3_81cc3875_56759626_39ff9f16_c93f81d6_e2d051e1_82945280;
-defparam bootram.RAM4.INIT_02=256'he1880c89_0c800b81_0b81e184_e1800c80_890a0b81_8008085e_5cd5f93f_080480c1;
-defparam bootram.RAM4.INIT_03=256'h9a3f8008_818a398c_81e4d00c_c80c800b_800b81e2_81e2c40c_c00c800b_0a0b81e2;
-defparam bootram.RAM4.INIT_04=256'h39901708_d65c80e8_ff065e80_800883ff_39fedc3f_c65c80f8_80085f80_5e8c9e3f;
-defparam bootram.RAM4.INIT_05=256'hff065675_3f800881_90518abb_d33980f0_80c55c80_5189f63f_5280f090_538c1708;
-defparam bootram.RAM4.INIT_06=256'h80d75ca4_5188dd3f_528c1708_53901708_b7399417_3980c25c_80c45cbc_802e8638;
-defparam bootram.RAM4.INIT_07=256'h51fcde3f_80d35c80_d25c8d39_8bba3f80_8c170851_90170852_fe800553_3980d03d;
-defparam bootram.RAM4.INIT_08=256'h57753377_3d790557_771980d2_833d5a58_0554800b_d03dfdec_82945580_8339a05c;
-defparam bootram.RAM4.INIT_09=256'hd6883fff_80e3f851_04803d0d_80d03d0d_51e8a33f_38838082_887826ec_34811858;
-defparam bootram.RAM4.INIT_0A=256'h75538152_80559854_07575788_3371882b_8405ab05_a7053302_f93d0d02_5183983f;
-defparam bootram.RAM4.INIT_0B=256'hb7387581_54807425_74ff1656_5a575758_7a7c7f7f_04f83d0d_3f893d0d_8051e1a2;
-defparam bootram.RAM4.INIT_0C=256'hff0651d8_05527781_538a3dfc_a1053482_33028405_70810558_8a3d3476_17575473;
-defparam bootram.RAM4.INIT_0D=256'h04fa3d0d_0c8a3d0d_81547380_8538c139_3f73802e_8a51da80_81ff0654_d23f8008;
-defparam bootram.RAM4.INIT_0E=256'hd051ff89_81f75280_3dfc0553_34815488_5675883d_748338dc_5580de56_02a30533;
-defparam bootram.RAM4.INIT_0F=256'h705256d7_02a70533_3dfc0552_34815389_0533893d_7c5702ab_04f93d0d_3f883d0d;
-defparam bootram.RAM4.INIT_10=256'h3f800881_7551d6b5_76537b52_77259738_2e9e3880_56547380_81ff0670_f23f8008;
-defparam bootram.RAM4.INIT_11=256'h5381f752_883dfc05_3d0d8154_3d0d04fa_74800c89_83388155_5473802e_ff067056;
-defparam bootram.RAM4.INIT_12=256'h3d0d0499_75800c88_83388156_2e098106_567480de_883d3356_a03f800b_80d051ff;
-defparam bootram.RAM4.INIT_13=256'h0d72882b_0c04803d_0b81c0b0_ac0c89b0_a60b81c0_81c0800c_0c80eb0b_0b81c094;
-defparam bootram.RAM4.INIT_14=256'h515170f1_70810651_0870812a_0c81c0a4_0b81c0a0_980c5182_810781c0_be800670;
-defparam bootram.RAM4.INIT_15=256'h7381c09c_c0980c51_70810781_2bbe8006_3d0d7288_3d0d0480_08800c82_3881c0a8;
-defparam bootram.RAM4.INIT_16=256'h39fa3d0d_3d0d04ff_70f13882_06515151_812a7081_c0a40870_c0a00c81_0c840b81;
-defparam bootram.RAM4.INIT_17=256'h38815188_71802e86_72830652_52718a38_38758306_57577191_83065555_787a7c72;
-defparam bootram.RAM4.INIT_18=256'h1454e939_52545281_7008720c_77117712_3873822b_73752794_2a725555_ca3f7282;
-defparam bootram.RAM4.INIT_19=256'h0680e484_c13f728f_515353d1_84113354_8f0680e4_70842a70_fe3d0d74_883d0d04;
-defparam bootram.RAM4.INIT_1A=256'hf138823d_51515170_2a708106_90087088_3d0d82e0_3d0d0480_d1b43f84_11335253;
-defparam bootram.RAM4.INIT_1B=256'h70882a70_82e09008_80075353_060780c0_067a8c80_337880ff_0d029305_0d04fe3d;
-defparam bootram.RAM4.INIT_1C=256'h800782e0_980c7182_ff0682e0_900c7581_0c7182e0_7682e080_5170f138_81065151;
-defparam bootram.RAM4.INIT_1D=256'h08517080_3882e080_515170f1_70810651_0870882a_3882e090_72802e96_900c7251;
-defparam bootram.RAM4.INIT_1E=256'h863d0d04_51ff873f_53805280_55885480_940c8880_810b82e0_04fc3d0d_0c843d0d;
-defparam bootram.RAM4.INIT_1F=256'h04fc3d0d_0c863d0d_81ff0680_f13f8008_528151fe_8a805381_80559054_fc3d0d88;
-defparam bootram.RAM4.INIT_20=256'h06800c82_08813281_0dca3f80_0d04803d_d53f863d_528051fe_54865381_88805588;
-defparam bootram.RAM4.INIT_21=256'h84e33f75_3d0d7756_3d0d04fb_2ef43882_06517080_800881ff_3d0deb3f_3d0d0480;
-defparam bootram.RAM4.INIT_22=256'hfe843f87_81528051_9b0a0753_fe9b0a06_55a05475_b43f8880_38dd3fff_8008269b;
-defparam bootram.RAM4.INIT_23=256'h38751754_ff2681b4_80557381_11565757_cb3d08ff_c93d0880_ba3d0d80_3d0d04ff;
-defparam bootram.RAM4.INIT_24=256'h3d085273_755380cb_548c8f3f_883d7052_5381ff52_a7388280_80082681_849f3f73;
-defparam bootram.RAM4.INIT_25=256'h0a0680c0_0c76fec0_0b82e090_980c8880_3f7482e0_d43ffd9f_fefd3ffe_518aea3f;
-defparam bootram.RAM4.INIT_26=256'h3f80c83d_900cfcef_a00b82e0_e0900c8a_88a00b82_82e0980c_800c810b_0a0782e0;
-defparam bootram.RAM4.INIT_27=256'h82e0840c_88157008_880c54fe_700882e0_54fe8415_82e08c0c_80157008_558f56fe;
-defparam bootram.RAM4.INIT_28=256'hff169016_0cfcb03f_0b82e090_900c8a80_800b82e0_800c5488_700882e0_54fe8c15;
-defparam bootram.RAM4.INIT_29=256'h7b7d7212_f93d0d79_c83d0d04_74800c80_980c8155_800b82e0_25ffbc38_56567580;
-defparam bootram.RAM4.INIT_2A=256'h5473802e_7581ff06_2e80c338_81577480_2680cb38_57738008_82db3f80_575a5656;
-defparam bootram.RAM4.INIT_2B=256'h19767631_3f731674_7551fdeb_77537352_83387654_57767527_74317555_a2388280;
-defparam bootram.RAM4.INIT_2C=256'h0c893d0d_81577680_39fd8c3f_828054dc_7527e138_74548280_802e8e38_57595674;
-defparam bootram.RAM4.INIT_2D=256'h0b88160c_27903880_3f800874_135481ed_2e8d3873_54557380_76787a56_04fc3d0d;
-defparam bootram.RAM4.INIT_2E=256'h08307276_81bd3f80_16565152_707406ff_3f800830_a63981cb_0c80750c_800b8416;
-defparam bootram.RAM4.INIT_2F=256'h0881ff06_fc983f80_3d0d7554_3d0d04fd_fcc93f86_160c7151_160c7188_0c740684;
-defparam bootram.RAM4.INIT_30=256'h7088160c_08800805_823f8814_2e943881_08841508_81538814_802e9f38_70545271;
-defparam bootram.RAM4.INIT_31=256'h51faa33f_53815281_5481f90a_888055a0_04fc3d0d_0c853d0d_80537280_51fc943f;
-defparam bootram.RAM4.INIT_32=256'h81ff0680_08882a70_38d73f80_efe808a0_ff3d0d80_863d0d04_0a06800c_8008fe80;
-defparam bootram.RAM4.INIT_33=256'h82712784_ea115252_80efe808_80efe80c_06933871_a02e0981_54515170_0881ff06;
-defparam bootram.RAM4.INIT_34=256'h082b800c_3f810b80_800c04f3_e4da0533_3f800880_3d0d04c0_71800c83_38f5b23f;
-defparam bootram.RAM4.INIT_35=256'h0b82e090_980c8880_800b82e0_56f9983f_f63d0d7d_2b800c04_810b8008_04ffa93f;
-defparam bootram.RAM4.INIT_36=256'ha80b82e0_e0900c8a_88a80b82_82e0980c_800c810b_882b82e0_e0840c7c_0c8b0b82;
-defparam bootram.RAM4.INIT_37=256'h0cf8cc3f_0b82e090_900c8a80_800b82e0_80d33888_54737627_3f7e5580_900cf8e7;
-defparam bootram.RAM4.INIT_38=256'h53707327_31525790_883d7675_e080085b_84085a82_085982e0_5882e088_82e08c08;
-defparam bootram.RAM4.INIT_39=256'h1454ffa9_52ec3972_57348112_75708105_17517033_27913871_80527173_83387053;
-defparam bootram.RAM4.INIT_3A=256'h538c088c_fd3d0d80_08028c0c_f7893f8c_3d0d7251_3d0d0480_e0980c8c_39800b82;
-defparam bootram.RAM4.INIT_3B=256'h0cfd3d0d_8c08028c_0d8c0c04_0c54853d_80087080_5182de3f_08880508_0508528c;
-defparam bootram.RAM4.INIT_3C=256'h048c0802_3d0d8c0c_800c5485_3f800870_085182b9_8c088805_8c050852_81538c08;
-defparam bootram.RAM4.INIT_3D=256'h0888050c_0508308c_388c0888_088025ab_8c088805_08fc050c_0d800b8c_8c0cf93d;
-defparam bootram.RAM4.INIT_3E=256'hfc050c8c_05088c08_0c8c08f4_8c08f405_8838810b_08fc0508_f4050c8c_800b8c08;
-defparam bootram.RAM4.INIT_3F=256'hfc050888_050c8c08_0b8c08f0_8c050c80_08308c08_8c088c05_8025ab38_088c0508;
-defparam bootram.RAM5.INIT_00=256'h88050851_08528c08_8c088c05_050c8053_088c08fc_8c08f005_08f0050c_38810b8c;
-defparam bootram.RAM5.INIT_01=256'h08f8050c_0508308c_388c08f8_08802e8c_8c08fc05_f8050c54_08708c08_81a73f80;
-defparam bootram.RAM5.INIT_02=256'h050c8c08_0b8c08fc_fb3d0d80_08028c0c_8c0c048c_54893d0d_0870800c_8c08f805;
-defparam bootram.RAM5.INIT_03=256'h05088025_0c8c088c_8c08fc05_050c810b_308c0888_08880508_2593388c_88050880;
-defparam bootram.RAM5.INIT_04=256'h3f800870_050851ad_528c0888_088c0508_0c81538c_8c088c05_8c050830_8c388c08;
-defparam bootram.RAM5.INIT_05=256'hf8050870_050c8c08_308c08f8_08f80508_2e8c388c_fc050880_0c548c08_8c08f805;
-defparam bootram.RAM5.INIT_06=256'hf8050c8c_800b8c08_08fc050c_0d810b8c_8c0cfd3d_048c0802_3d0d8c0c_800c5487;
-defparam bootram.RAM5.INIT_07=256'h2499388c_088c0508_38800b8c_08802ea3_8c08fc05_0827ac38_8c088805_088c0508;
-defparam bootram.RAM5.INIT_08=256'h802e80c9_08fc0508_0cc9398c_8c08fc05_fc050810_050c8c08_108c088c_088c0508;
-defparam bootram.RAM5.INIT_09=256'h050c8c08_318c0888_088c0508_8805088c_a1388c08_88050826_05088c08_388c088c;
-defparam bootram.RAM5.INIT_0A=256'h8c050881_050c8c08_2a8c08fc_fc050881_050c8c08_078c08f8_08fc0508_f805088c;
-defparam bootram.RAM5.INIT_0B=256'h0c518d39_8c08f405_88050870_8f388c08_0508802e_398c0890_050cffaf_2a8c088c;
-defparam bootram.RAM5.INIT_0C=256'h78777956_04fc3d0d_3d0d8c0c_08800c85_8c08f405_f4050c51_08708c08_8c08f805;
-defparam bootram.RAM5.INIT_0D=256'h74335253_a0387433_5271ff2e_b038ff12_5170802e_74078306_278c3874_56528372;
-defparam bootram.RAM5.INIT_0E=256'h0c863d0d_38800b80_098106e2_5571ff2e_ff145455_81158115_8106bd38_72712e09;
-defparam bootram.RAM5.INIT_0F=256'h38707355_718326e9_14545451_118414fc_068f3884_082e0981_51700873_04747454;
-defparam bootram.RAM5.INIT_10=256'h38727507_8f72278c_55555555_7670797b_04fc3d0d_0c863d0d_72713180_55ffaf39;
-defparam bootram.RAM5.INIT_11=256'hff125271_81055634_54337470_72708105_ff2e9838_ff125271_802ea738_83065170;
-defparam bootram.RAM5.INIT_12=256'h72708405_8405530c_54087170_72708405_0d047451_800c863d_06ea3874_ff2e0981;
-defparam bootram.RAM5.INIT_13=256'h8405530c_54087170_72708405_8405530c_54087170_72708405_8405530c_54087170;
-defparam bootram.RAM5.INIT_14=256'h718326ed_0cfc1252_70840553_05540871_38727084_83722795_8f26c938_f0125271;
-defparam bootram.RAM5.INIT_15=256'h83065170_278a3874_53558372_05335755_028c059f_0d767971_8339fc3d_387054ff;
-defparam bootram.RAM5.INIT_16=256'hef387480_2e098106_125271ff_055534ff_73737081_ff2e9338_ff125271_802ea238;
-defparam bootram.RAM5.INIT_17=256'h05530c72_72717084_7227a538_5154518f_71902b07_2b750770_04747488_0c863d0d;
-defparam bootram.RAM5.INIT_18=256'h83722790_8f26dd38_f0125271_8405530c_0c727170_70840553_530c7271_71708405;
-defparam bootram.RAM5.INIT_19=256'h54555552_787a7c70_39fa3d0d_7053ff90_8326f238_fc125271_8405530c_38727170;
-defparam bootram.RAM5.INIT_1A=256'h74335651_b1387133_5372ff2e_d438ff13_70802e80_07830651_d9387174_72802e80;
-defparam bootram.RAM5.INIT_1B=256'h15ff1555_38811281_802e80fc_ff065170_87387081_72802e81_8106a938_74712e09;
-defparam bootram.RAM5.INIT_1C=256'h52527080_71713151_7581ff06_7081ff06_74335651_d1387133_2e098106_555272ff;
-defparam bootram.RAM5.INIT_1D=256'hfc135372_52ff9739_38747655_74082e88_88387108_55837327_04717457_0c883d0d;
-defparam bootram.RAM5.INIT_1E=256'h15841757_709a3884_06515151_84828180_120670f8_f7fbfdff_74087009_802eb138;
-defparam bootram.RAM5.INIT_1F=256'hfd3d0d80_883d0d04_800b800c_52fedf39_38747655_76082ed0_d0387408_55837327;
-defparam bootram.RAM5.INIT_20=256'h528151ff_3f80e4f4_3fffafe8_0cffb0cc_7380efec_812e9e38_08545472_0b80e4b4;
-defparam bootram.RAM5.INIT_21=256'hffb7c13f_f4528151_cb3f80e4_af3fffaf_ec0cffb0_3f7280ef_0851f6a3_b7de3f80;
-defparam bootram.RAM5.INIT_22=256'h2dfc1270_2e913870_525270ff_fc057008_80e4fc0b_39ff3d0d_863f00ff_800851f6;
-defparam bootram.RAM5.INIT_23=256'h21457272_00000040_04000000_ffb0da3f_3d0d0404_06f13883_ff2e0981_08525270;
-defparam bootram.RAM5.INIT_24=256'h3a204578_646c6572_2068616e_636b6574_6c207061_6e74726f_6e20636f_6f722069;
-defparam bootram.RAM5.INIT_25=256'h25642c20_62657220_206e756d_6c697479_74696269_6f6d7061_65642063_70656374;
-defparam bootram.RAM5.INIT_26=256'h6c207061_6e74726f_6e20636f_6f722069_21457272_25640a00_676f7420_62757420;
-defparam bootram.RAM5.INIT_27=256'h6164206c_61796c6f_65642070_70656374_3a204578_646c6572_2068616e_636b6574;
-defparam bootram.RAM5.INIT_28=256'h206c696e_0a657468_0a000000_74202564_7420676f_2c206275_68202564_656e6774;
-defparam bootram.RAM5.INIT_29=256'h50204e32_0a555352_640a0000_203d2025_70656564_643a2073_616e6765_6b206368;
-defparam bootram.RAM5.INIT_2A=256'h70617469_20636f6d_46504741_720a0000_6f616465_6f6f746c_44502062_31302055;
-defparam bootram.RAM5.INIT_2B=256'h20636f6d_77617265_4669726d_640a0000_723a2025_756d6265_7479206e_62696c69;
-defparam bootram.RAM5.INIT_2C=256'h00000000_61646472_640a0000_723a2025_756d6265_7479206e_62696c69_70617469;
-defparam bootram.RAM5.INIT_2D=256'h00000699_00000000_65743a20_7061636b_65727920_65636f76_69702072_476f7420;
-defparam bootram.RAM5.INIT_2E=256'h000006ee_00000705_0000079e_0000079e_0000079e_0000079e_0000079e_0000079e;
-defparam bootram.RAM5.INIT_2F=256'h0000079e_0000079e_0000079e_0000079e_0000079e_00000774_0000079e_0000079e;
-defparam bootram.RAM5.INIT_30=256'h00000762_00000755_0000074e_00000747_00000742_0000073d_000006a6_00000722;
-defparam bootram.RAM5.INIT_31=256'h25642e25_45000000_01b200d9_05160364_14580a2c_3fff0000_0050c285_c0a80a02;
-defparam bootram.RAM5.INIT_32=256'hffffffff_00000000_43444546_38394142_34353637_30313233_2e256400_642e2564;
-defparam bootram.RAM5.INIT_33=256'h6f66206c_656e7420_69676e6d_6420616c_3a206261_5f706b74_73656e64_ffff0000;
-defparam bootram.RAM5.INIT_34=256'h6661696c_6f6e3a20_636f6d6d_6e65745f_66000000_72206275_6e642f6f_656e2061;
-defparam bootram.RAM5.INIT_35=256'h00000000_666f7220_696e6720_6c6f6f6b_63686520_74206361_6f206869_65642074;
-defparam bootram.RAM5.INIT_36=256'h0a000000_3d202564_697a6520_72642073_20776569_6172703a_646c655f_0a68616e;
-defparam bootram.RAM5.INIT_37=256'h2025640a_3a202564_67746873_206c656e_74656e74_6e736973_696e636f_55445020;
-defparam bootram.RAM5.INIT_38=256'h61666520_696e2073_50322b20_20555352_74696e67_53746172_0b0b0b0b_00000000;
-defparam bootram.RAM5.INIT_39=256'h00000000_6172652e_69726d77_66652066_67207361_6164696e_2e204c6f_6d6f6465;
-defparam bootram.RAM5.INIT_3A=256'h6e204650_6374696f_726f6475_69642070_2076616c_20666f72_6b696e67_43686563;
-defparam bootram.RAM5.INIT_3B=256'h20465047_74696f6e_6f647563_64207072_56616c69_2e2e2e00_6d616765_47412069;
-defparam bootram.RAM5.INIT_3C=256'h20626f6f_6720746f_7074696e_7474656d_642e2041_666f756e_61676520_4120696d;
-defparam bootram.RAM5.INIT_3D=256'h20696d61_46504741_696f6e20_64756374_2070726f_616c6964_4e6f2076_742e0000;
-defparam bootram.RAM5.INIT_3E=256'h20627569_6820746f_726f7567_67207468_6c6c696e_2e0a4661_6f756e64_67652066;
-defparam bootram.RAM5.INIT_3F=256'h74696f6e_6f647563_64207072_56616c69_72652e00_726d7761_6e206669_6c742d69;
-defparam bootram.RAM6.INIT_00=256'h46696e69_2e2e2e00_64696e67_204c6f61_756e642e_6520666f_6d776172_20666972;
-defparam bootram.RAM6.INIT_01=256'h2e000000_6d616765_6e672069_61727469_2e205374_64696e67_206c6f61_73686564;
-defparam bootram.RAM6.INIT_02=256'h72616d21_70726f67_61696e20_6f6d206d_6e206672_65747572_523a2052_4552524f;
-defparam bootram.RAM6.INIT_03=256'h4e6f2076_6e210000_61707065_65722068_206e6576_6f756c64_73207368_20546869;
-defparam bootram.RAM6.INIT_04=256'h6e642e20_20666f75_77617265_6669726d_696f6e20_64756374_2070726f_616c6964;
-defparam bootram.RAM6.INIT_05=256'h6669726d_2d696e20_75696c74_746f2062_75676820_7468726f_696e6720_46616c6c;
-defparam bootram.RAM6.INIT_06=256'h4e4f4e45_00000000_2025640a_7420746f_64207365_53706565_2e000000_77617265;
-defparam bootram.RAM6.INIT_07=256'h43000000_45545249_53594d4d_58000000_57455f52_58000000_57455f54_00000000;
-defparam bootram.RAM6.INIT_08=256'h4155544f_5048595f_6c3a2000_6e74726f_7720636f_20666c6f_726e6574_65746865;
-defparam bootram.RAM6.INIT_09=256'h780a0000_20307825_20676f74_7825782c_74652030_2077726f_4144563a_4e45475f;
-defparam bootram.RAM6.INIT_0A=256'h64617465_6e207570_6f722069_21457272_00030203_00000001_00030003_00000000;
-defparam bootram.RAM6.INIT_0B=256'h796c6f61_64207061_65637465_20457870_6c65723a_68616e64_6b657420_20706163;
-defparam bootram.RAM6.INIT_0C=256'h00002042_00000000_2025640a_20676f74_20627574_2025642c_6e677468_64206c65;
-defparam bootram.RAM6.INIT_0D=256'h00002102_00002102_00002102_0000207b_0000209d_000020b2_00002102_00002102;
-defparam bootram.RAM6.INIT_0E=256'h00002102_00002102_00002102_00002102_00002102_00002102_00002102_00002102;
-defparam bootram.RAM6.INIT_0F=256'h6f72740a_0a0a6162_000020ce_0000208d_00002102_00002102_000020f8_000020e1;
-defparam bootram.RAM6.INIT_10=256'h65000000_792e6578_64756d6d_43444546_38394142_34353637_30313233_00000000;
-defparam bootram.RAM6.INIT_11=256'h00003284_00000000_00000000_00000000_ffffff00_ffff00ff_ff00ffff_00ffffff;
-defparam bootram.RAM6.INIT_12=256'h000b0000_0018000f_ffff0031_05050400_01010100_3fff0000_0050c285_c0a80a02;
-defparam bootram.RAM6.INIT_13=256'h00000000_ffffffff_00003214_10101200_000030f4_000030ec_000030e4_000030dc;
-defparam bootram.RAM6.INIT_14=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_ffffffff;
+defparam bootram.RAM0.INIT_23=256'h800b80e4_f40c82a0_0b0b80e4_8380800b_822ebd38_80e49c08_802ea438_80e49808;
+defparam bootram.RAM0.INIT_24=256'h0b80e4f8_80808280_e4f40cf8_0b0b0b80_808080a4_fc0c04f8_800b80e4_f80c8290;
+defparam bootram.RAM0.INIT_25=256'h940b80e4_80c0a880_80e4f40c_8c0b0b0b_80c0a880_e4fc0c04_84800b80_0cf88080;
+defparam bootram.RAM0.INIT_26=256'h70085252_80e4a408_5170a738_80e58033_04ff3d0d_80e4fc0c_80d8e00b_f80c0b0b;
+defparam bootram.RAM0.INIT_27=256'h8034833d_810b80e5_5270ee38_08700852_2d80e4a4_e4a40c70_38841280_70802e94;
+defparam bootram.RAM0.INIT_28=256'h38823d0d_09810685_800b802e_0b0b0b0b_802e8e38_80e4f008_3d0d0b0b_0d040480;
+defparam bootram.RAM0.INIT_29=256'h3d225a79_80c13895_0d685b7a_0404ee3d_3f823d0d_0b0bf5d4_e4f0510b_040b0b80;
+defparam bootram.RAM0.INIT_2A=256'h8d3881d2_8380862e_81dc3979_842e8e38_38798380_8085248b_ae387983_8380852e;
+defparam bootram.RAM0.INIT_2B=256'h0b983d22_81b83980_81e4d00c_81c0397a_81e2cc0c_c939810b_e18c0c81_39810b81;
+defparam bootram.RAM0.INIT_2C=256'h80862e8b_99397983_2e9f3881_79838084_85248b38_38798380_80852ea7_5b5b7983;
+defparam bootram.RAM0.INIT_2D=256'h055241a9_53963d84_5b923d70_5b833983_5b873981_81883982_872e8c38_38798380;
+defparam bootram.RAM0.INIT_2E=256'h5b79337b_1d7f1d5b_415e5c7b_883d993d_5f40800b_84057c5b_3f800802_953f8a8b;
+defparam bootram.RAM0.INIT_2F=256'h1c5c887c_337b3481_055b5b79_1d963d7d_1f5e5c7b_38800b90_887c26ef_34811c5c;
+defparam bootram.RAM0.INIT_30=256'h5c7b1e61_26ef3880_1c5c867c_337b3481_1d5b5b79_5c7b1d60_0b881f5e_26ed3880;
+defparam bootram.RAM0.INIT_31=256'h1208595a_0d686a84_0d04ee3d_8b3f943d_26ef389a_1c5c867c_337b3481_1d5b5b79;
+defparam bootram.RAM0.INIT_32=256'h833f80e1_d8e45195_538c5280_2e8c3875_94387580_56758c2e_9c387708_58837927;
+defparam bootram.RAM0.INIT_33=256'h9f175675_18085dff_5ba05c88_3fa0578c_b45194f0_a45280d9_8e387853_5778a326;
+defparam bootram.RAM0.INIT_34=256'h39951833_085e81eb_993f8008_80c15c89_56750804_80dba405_38758429_92268281;
+defparam bootram.RAM0.INIT_35=256'h19335757_52800b97_538c1808_54901808_55961833_38845776_80f22e83_56825775;
+defparam bootram.RAM0.INIT_36=256'hea05538c_7054953d_398d1833_d35c81b3_80085f80_5196ab3f_38815776_75772e83;
+defparam bootram.RAM0.INIT_37=256'h80c85c75_568de63f_8c193352_548e1953_8d183370_c95c9439_8cd93f80_19335256;
+defparam bootram.RAM0.INIT_38=256'h8c190858_80dbf005_38758429_852680c2_ff055675_39941833_053480ff_028405b5;
+defparam bootram.RAM0.INIT_39=256'h76842980_77239b39_39921822_08770ca2_a9399018_3976225f_76085fae_56750804;
+defparam bootram.RAM0.INIT_3A=256'h5e80cc5c_5cad3978_0c5680d2_90190871_80e58405_39768429_0840568e_e5840570;
+defparam bootram.RAM0.INIT_3B=256'h18588878_33773481_05575775_19963d79_3d5a5877_54800b83_943ddc05_8c180855;
+defparam bootram.RAM0.INIT_3C=256'h75337734_79055757_7719963d_833d5a58_0554800b_55943ddc_39a05ca4_26ed38a4;
+defparam bootram.RAM0.INIT_3D=256'h525392a0_5380da80_3d0d7470_3d0d04fe_9ba73f94_83808051_7826ed38_81185888;
+defparam bootram.RAM0.INIT_3E=256'hcd3f7251_52725187_3f8d39a0_d23f9bba_3f81518f_a05187de_9238a052_3f72802e;
+defparam bootram.RAM0.INIT_3F=256'h3f8c5280_bc5191e4_8a5280da_5188c13f_3f80daa0_3d0d8297_3d0d04fa_8fc13f84;
+defparam bootram.RAM1.INIT_00=256'h963f87db_80085190_3f85b83f_a43f868b_a9c33f85_80e5a00c_db3f820b_dadc5191;
+defparam bootram.RAM1.INIT_01=256'hd23f85ee_80085194_9a3f7352_80085485_3f85ff3f_b03f87cf_80085190_3f868b3f;
+defparam bootram.RAM1.INIT_02=256'h80845195_8ab25283_5195983f_52838080_dc3f8cb6_8ea13f94_52800851_3f838085;
+defparam bootram.RAM1.INIT_03=256'h5194f03f_52838087_fa3f8ab2_80855194_8ab25283_5195843f_52838086_8e3f8ab2;
+defparam bootram.RAM1.INIT_04=256'h3fabfb3f_b351a9e9_8e8d3f8f_963f8051_809251a5_94e53f83_83808251_80c08952;
+defparam bootram.RAM1.INIT_05=256'hfdee2e09_55557382_088e0522_c9387680_08802e80_80085680_518e843f_883dfc05;
+defparam bootram.RAM1.INIT_06=256'h833f9416_db885190_089a3880_c4cb3f80_90055180_80528008_845380db_8106ad38;
+defparam bootram.RAM1.INIT_07=256'h3f8bfb3f_893fa4e9_9a9d3f8d_74527551_8e3f8839_3f735185_f43f8693_7052548e;
+defparam bootram.RAM1.INIT_08=256'h85a93f9f_9f528051_3f88803f_843f8bb0_82b73f87_3f91cb3f_3d0d85dc_ff9e39fe;
+defparam bootram.RAM1.INIT_09=256'h5184eb3f_3f885288_ac518ae2_84f83f82_84528451_518aef3f_853f82ac_52805185;
+defparam bootram.RAM1.INIT_0A=256'h80e4518a_5184cf3f_539f5280_8ac83f82_3f82ac51_905184de_d53f9052_82ac518a;
+defparam bootram.RAM1.INIT_0B=256'hca3f9f52_529e5184_25df389f_13537280_8aac3fff_3f80e451_9c5184c2_b93f9f52;
+defparam bootram.RAM1.INIT_0C=256'h2a810680_8c08708b_3d0d8280_3d0d0480_0b800c84_e0840c81_3f890b81_815184a6;
+defparam bootram.RAM1.INIT_0D=256'h58595775_055a5757_70802582_05337030_028c05a7_0d7a7d7f_0d04f93d_0c51823d;
+defparam bootram.RAM1.INIT_0E=256'h53805481_709f2a51_8a557330_55738338_2e883888_05557583_72802588_822e9338;
+defparam bootram.RAM1.INIT_0F=256'h54805486_2b075154_05707284_777131fe_812cff05_2e973876_72547280_77259e38;
+defparam bootram.RAM1.INIT_10=256'hae8f3f81_52811851_ae973f73_06527751_3f7281ff_7b51aea1_80547452_39735381;
+defparam bootram.RAM1.INIT_11=256'h7551fee6_bd537852_5580ca54_05335681_3d0d029f_3d0d04fb_ae873f89_5280da51;
+defparam bootram.RAM1.INIT_12=256'hff065372_3f800881_d63ffebb_81528151_51adde3f_815280c5_04fe3d0d_3f873d0d;
+defparam bootram.RAM1.INIT_13=256'h70565480_7a575781_fa3d0d78_843d0d04_e0800c53_70900781_81e08008_802ef338;
+defparam bootram.RAM1.INIT_14=256'h80558113_ff2e8338_33527181_38805471_70802e83_70335252_9e387217_53727627;
+defparam bootram.RAM1.INIT_15=256'ha8348653_810b80e5_04fe3d0d_0c883d0d_81517080_802e8338_74075170_53df3974;
+defparam bootram.RAM1.INIT_16=256'h80e5a834_bc38810b_a8335574_3d0d80e5_3d0d04f9_beab3f84_80e4ac51_80dc8c52;
+defparam bootram.RAM1.INIT_17=256'h7551fef4_9c388652_5574802e_0881ff06_addf3f80_5280d051_70545682_8654873d;
+defparam bootram.RAM1.INIT_18=256'h3d0d0481_0b800c89_3f80e4ac_ac51bde1_755280e4_8c388653_ff065574_3f800881;
+defparam bootram.RAM1.INIT_19=256'he5a43484_38810b80_335574b9_0d80e5a4_0c04fb3d_0880e4a8_3480dc88_0b80e5a4;
+defparam bootram.RAM1.INIT_1A=256'h3dfc0551_38845287_74802e99_81ff0655_803f8008_80d051ad_05538c52_54873dfc;
+defparam bootram.RAM1.INIT_1B=256'h3d0d7756_3d0d04fb_0b800c87_0c80e4a8_7580e4a8_55748638_0881ff06_fe923f80;
+defparam bootram.RAM1.INIT_1C=256'h0c810b80_0880e4a8_2e8d3875_06557480_800881ff_51abc63f_8c5280d0_84547553;
+defparam bootram.RAM1.INIT_1D=256'hac0c81e0_077080e5_e5ac0806_75067180_0d730973_0d04803d_800c873d_e5a43474;
+defparam bootram.RAM1.INIT_1E=256'he0980c51_e5b00c81_06077080_80e5b008_73750671_3d0d7309_3d0d0480_8c0c5182;
+defparam bootram.RAM1.INIT_1F=256'h3d0d8a52_3d0d04ff_72800c84_5181c73f_70535380_fe3d0d74_81af3f04_823d0d04;
+defparam bootram.RAM1.INIT_20=256'h38811574_72802e90_ff065454_74337081_77795656_04fb3d0d_3f833d0d_805181b6;
+defparam bootram.RAM1.INIT_21=256'h3f833d0d_528051cd_ff3d0d73_873d0d04_800b800c_913fe539_76525581_81ff0653;
+defparam bootram.RAM1.INIT_22=256'hff3d0d73_843d0d04_800b800c_5180e73f_3f8a5272_5253ffbd_74765370_04fe3d0d;
+defparam bootram.RAM1.INIT_23=256'h3d0d73a0_3d0d04ff_b4123482_053380e4_7251028f_04803d0d_3f833d0d_528051dd;
+defparam bootram.RAM1.INIT_24=256'hb4133352_805380e4_04fe3d0d_51833d0d_22720c53_dc940570_05751080_29829080;
+defparam bootram.RAM1.INIT_25=256'h0d767856_0d04fc3d_e538843d_53827325_ce3f8113_33527251_80e4b813_7251c63f;
+defparam bootram.RAM1.INIT_26=256'h3f73a029_527351de_0687388d_812e0981_14335372_3880e4b4_09810695_54748a2e;
+defparam bootram.RAM1.INIT_27=256'h82908005_0d74a029_0d04fe3d_150c863d_f838748c_5372802e_54841408_82908005;
+defparam bootram.RAM1.INIT_28=256'h81a8880c_3d0d800b_3d0d04ff_72800c84_90120853_802e8538_52ff5370_88110852;
+defparam bootram.RAM1.INIT_29=256'h3d0d04fd_a8880c83_81800b81_a8840c51_70882a81_81a8800c_7081ff06_80e4c022;
+defparam bootram.RAM1.INIT_2A=256'h70810651_0870862a_3881a890_802e8186_54815171_05335553_02880597_3d0d7678;
+defparam bootram.RAM1.INIT_2B=256'h81065151_70812a70_81a89008_81a8900c_0c81900b_0781a88c_38721081_515170f1;
+defparam bootram.RAM1.INIT_2C=256'h2eb13880_ba387180_5170802e_32515151_81067081_70872a70_81a89008_5170f138;
+defparam bootram.RAM1.INIT_2D=256'hf13881a8_51515170_2a708106_90087081_900c81a8_517081a8_2e8338a0_e8517181;
+defparam bootram.RAM1.INIT_2E=256'h0c853d0d_900c7080_c00b81a8_51883980_52cc3981_5634ff12_74708105_8c085170;
+defparam bootram.RAM1.INIT_2F=256'h70f13872_06515151_862a7081_a8900870_55535481_05970533_76780288_04fd3d0d;
+defparam bootram.RAM1.INIT_30=256'h70810651_0870812a_0c81a890_7081a890_38819051_71802e84_0c81d051_1081a88c;
+defparam bootram.RAM1.INIT_31=256'h71802e80_2e80cf38_51517080_81325151_70810670_0870872a_3881a890_515170f1;
+defparam bootram.RAM1.INIT_32=256'h812a7081_a8900870_a8900c81_90517081_812e8338_80d05171_81a88c0c_c5387333;
+defparam bootram.RAM1.INIT_33=256'h388114ff_70802e8e_51515151_06708132_872a7081_a8900870_70f13881_06515151;
+defparam bootram.RAM1.INIT_34=256'h0d755480_0d04fd3d_800c853d_0c805170_0b81a890_8a3980c0_b7398151_135354ff;
+defparam bootram.RAM1.INIT_35=256'h1353e239_27f13881_868d9f71_73315151_b8ac0870_ac085281_9b3881b8_53727425;
+defparam bootram.RAM1.INIT_36=256'h82808c0c_840cff0b_ef0b8280_8280800c_0c81e20b_0b828088_ff3d0dff_853d0d04;
+defparam bootram.RAM1.INIT_37=256'h0d828088_0d04fb3d_f138833d_51708025_540cff11_72708405_87519eea_80efd852;
+defparam bootram.RAM1.INIT_38=256'h8f387251_5271802e_55747606_80efd855_8053810b_06585152_808c0871_08700982;
+defparam bootram.RAM1.INIT_39=256'h0d04ff3d_dc38873d_53877325_76105755_81138415_8c0c8f39_2d748280_73085271;
+defparam bootram.RAM1.INIT_3A=256'h70720682_82808808_722b7009_710c5181_efd80575_71842980_87269f38_0d735271;
+defparam bootram.RAM1.INIT_3B=256'hc80c833d_0c5281e0_0881e0c4_05227470_3d0d0292_0d0404ff_5152833d_80880c53;
+defparam bootram.RAM1.INIT_3C=256'he0cc0c82_38820b81_70802ef3_84065151_b8a00870_e0cc0c81_0d810b81_0d04803d;
+defparam bootram.RAM1.INIT_3D=256'h81b8a008_802e9338_06545272_a0087081_3d0d81b8_c00c04fe_3f7181e0_3d0d04de;
+defparam bootram.RAM1.INIT_3E=256'hdca051f8_2e8b3880_51527180_2a708106_9a397181_81808052_710c5353_7571902a;
+defparam bootram.RAM1.INIT_3F=256'h802ef238_06515170_087080c0_0d81b8a0_0d04803d_800c843d_3f725271_d33fff9e;
+defparam bootram.RAM2.INIT_00=256'hb8a00870_cc0c5281_880781e0_2270902b_0d028e05_0d04ff3d_800c823d_8180800b;
+defparam bootram.RAM2.INIT_01=256'h2e8638ba_80537280_3d0d7554_3d0d04fd_e0cc0c83_38840b81_70802ef3_90065151;
+defparam bootram.RAM2.INIT_02=256'h77831133_04fb3d0d_38853d0d_857327e6_3f811353_5252a5c0_72147033_51f7a53f;
+defparam bootram.RAM2.INIT_03=256'h7e616302_f63d0d7c_873d0d04_5180ed3f_5680dca4_54703353_55811133_56821133;
+defparam bootram.RAM2.INIT_04=256'h52ad5178_2e8a3879_8f387580_57768025_5f5d5b59_9f2a515b_33703070_9005bb05;
+defparam bootram.RAM2.INIT_05=256'h77527651_51ffbd3f_863f8008_527651ad_54805377_38795578_77772694_2d763057;
+defparam bootram.RAM2.INIT_06=256'h823d0d04_51f68d3f_028b0533_04803d0d_2d8c3d0d_05335178_0880dcb0_ad9e3f80;
+defparam bootram.RAM2.INIT_07=256'hd1387681_75802e81_ff065757_78337081_d15c5a58_055208a1_3d707084_f73d0d8c;
+defparam bootram.RAM2.INIT_08=256'h24a03875_387580f0_f02e80fb_57597580_81197033_0680db38_a52e0981_ff065675;
+defparam bootram.RAM2.INIT_09=256'h8b397580_80c63881_7580e42e_38819539_802e819e_248a3875_387580e3_80e32eb9;
+defparam bootram.RAM2.INIT_0A=256'h39778419_ba3880ec_7580f82e_3880f539_f32e80db_8b387580_7580f524_f52eac38;
+defparam bootram.RAM2.INIT_0B=256'h80539039_55a1d154_52595680_84197108_80da3977_7551792d_59568052_83123352;
+defparam bootram.RAM2.INIT_0C=256'h55a1d154_52595680_84197108_52923977_5481538a_8055a1d1_08525956_77841971;
+defparam bootram.RAM2.INIT_0D=256'h52767081_2e8e3880_33567580_59595676_84197108_3f9e3977_7551fdd0_80539052;
+defparam bootram.RAM2.INIT_0E=256'h04803d0d_81e0d00c_0d048a0b_800c8b3d_a339800b_811959fe_792dec39_05583351;
+defparam bootram.RAM2.INIT_0F=256'h88059b05_0d797b02_0d04fc3d_ef38823d_51515170_32708106_708c2a81_81b8b408;
+defparam bootram.RAM2.INIT_10=256'h81065151_72822a70_810a0752_2e863871_54557080_06555556_7b077281_3372982b;
+defparam bootram.RAM2.INIT_11=256'he0d80c73_d40c7081_3f7181e0_5151ffa9_3179712b_0752a075_3871820a_70802e86;
+defparam bootram.RAM2.INIT_12=256'h55558053_76787a54_04fc3d0d_0c863d0d_08517080_3f81b880_8938ff95_5173802e;
+defparam bootram.RAM2.INIT_13=256'h7183ffff_802e8d38_902a5170_51ee3971_81155553_70227305_38721015_7274278f;
+defparam bootram.RAM2.INIT_14=256'h3f767008_b851aed9_755280e5_3d0d8653_3d0d04fd_71800c86_0552ec39_0672902a;
+defparam bootram.RAM2.INIT_15=256'h8025f338_12525270_0c8812ff_89518072_80e5c852_04ff3d0d_54853d0d_80e5c00c;
+defparam bootram.RAM2.INIT_16=256'h12881252_2e8e3881_22547274_c4525270_800b80e5_96052253_fd3d0d02_833d0d04;
+defparam bootram.RAM2.INIT_17=256'hc73f8008_06535856_7183ffff_3d0d787a_3d0d04fa_70800c85_ee388051_52897225;
+defparam bootram.RAM2.INIT_18=256'h55527180_73088815_c4555555_c80b80e5_800880e5_050cad39_76800884_802e8938;
+defparam bootram.RAM2.INIT_19=256'hf13d0d86_883d0d04_7684140c_3f757323_eb389bee_55897525_15881454_2e8f3881;
+defparam bootram.RAM2.INIT_1A=256'h3f908002_0551ad99_52913ddc_923d8805_a83f7353_055254ad_53923dd6_7054933d;
+defparam bootram.RAM2.INIT_1B=256'h8405aa05_81808002_0b8c3d23_a6052380_80028405_0b8b3d23_23818a80_8405a205;
+defparam bootram.RAM2.INIT_1C=256'hfdb73f80_3de40551_538a5291_5d665e80_ae052368_80028405_0b8d3d23_2380c091;
+defparam bootram.RAM2.INIT_1D=256'h028405be_913d2380_0523800b_028405ba_23963d22_3d22903d_ae052398_08028405;
+defparam bootram.RAM2.INIT_1E=256'h805b800b_04e83d0d_3f913d0d_05519df1_2981e684_526980c0_913dd405_0523ac53;
+defparam bootram.RAM2.INIT_1F=256'hf83f0280_f80551ab_b8529a3d_865380e5_51ac863f_9a3df205_539b3d52_973d2386;
+defparam bootram.RAM2.INIT_20=256'h436e44a1_1143f005_0b9b3dc4_08585a80_3f800880_0523f7e2_840580e2_f2052202;
+defparam bootram.RAM2.INIT_21=256'h56845875_06408c3d_088305fc_085fa33d_6e5ea13d_845c905d_3d084659_3d0845a3;
+defparam bootram.RAM2.INIT_22=256'h9a387383_5473802e_760c7508_27843873_5a557375_71315156_7c319080_08701a78;
+defparam bootram.RAM2.INIT_23=256'h08527651_08539416_efe63f75_80dccc51_802e8838_83065473_38941608_0654738c;
+defparam bootram.RAM2.INIT_24=256'h78822a51_3880c059_78bf2684_25ffac38_59577780_0817ff19_70840557_9cc33f75;
+defparam bootram.RAM2.INIT_25=256'h840580ca_055a7902_237f1f94_800b943d_4040818a_3d0d6b6e_3d0d04ea_f6e83f9a;
+defparam bootram.RAM2.INIT_26=256'h02840580_963d2380_80075a79_236980c0_0580ce05_80800284_953d2381_0523800b;
+defparam bootram.RAM2.INIT_27=256'h840580d2_095a7902_e03f8008_70525cfa_8a52933d_68478053_e5c00846_d2052380;
+defparam bootram.RAM2.INIT_28=256'hf7c23f7a_80dcf851_5a799238_0881ff06_8ac83f80_70535c5e_7053983d_0523913d;
+defparam bootram.RAM2.INIT_29=256'h7b1d7c1f_8053805c_557b5490_6b575d94_6d596058_39027f5a_edd53fa9_51f6b63f;
+defparam bootram.RAM2.INIT_2A=256'h05228a3d_7f5802ae_04f73d0d_3f983d0d_ef38fd89_5c867c26_7b34811c_5b5b7933;
+defparam bootram.RAM2.INIT_2B=256'h88548b3d_77567e55_05a60523_23800284_57768b3d_05238818_028405a2_238d3d22;
+defparam bootram.RAM2.INIT_2C=256'h0523860b_028405b2_3d239080_0d810b8e_0d04ee3d_9e3f8b3d_527d51fe_f8055391;
+defparam bootram.RAM2.INIT_2D=256'h0551a8b5_52943dec_86538008_23ea9c3f_8405b605_05348102_028405b5_8f3d3484;
+defparam bootram.RAM2.INIT_2E=256'h3feacf3f_0551a9b2_52943df6_3f865380_0551a8a5_52943df2_84538008_3feaeb3f;
+defparam bootram.RAM2.INIT_2F=256'h5a80dcc4_805b7a1c_54908653_943de405_80569c55_80588057_025c8059_80080843;
+defparam bootram.RAM2.INIT_30=256'h5f5d7d90_088e1122_3d0daa3d_3d0d04d9_fbcb3f94_7b26ef38_811b5b86_1b337a34;
+defparam bootram.RAM2.INIT_31=256'ha851f5a0_795280dd_9b268d38_055b5b79_088429f2_901dac3d_06829d38_862e0981;
+defparam bootram.RAM2.INIT_32=256'hd438841b_09810686_7990802e_821b225a_0686e238_812e0981_7a225a79_3f86ee39;
+defparam bootram.RAM2.INIT_33=256'h52408885_389e1d70_810686b9_79812e09_861b225a_0686c638_842e0981_225a798c;
+defparam bootram.RAM2.INIT_34=256'h085c8008_a5e73f80_ffa80551_c052a93d_845380e5_3f800843_525f87fd_3fa81d70;
+defparam bootram.RAM2.INIT_35=256'h80fe0523_22028405_3d23821b_3f7a22a1_7951a6c5_80e5b852_3d5a8653_868f38a7;
+defparam bootram.RAM2.INIT_36=256'ha93de405_86537952_81820523_82028405_81810534_33028405_3d34851b_841b33a2;
+defparam bootram.RAM2.INIT_37=256'h7a51a5f5_53981d52_8e055b86_843f0281_05525aa6_53aa3dea_8470547f_51a6923f;
+defparam bootram.RAM2.INIT_38=256'h7c597c58_3f027c5a_7e51a5dd_86537a52_3f9e3d5f_0551a5e9_52a93df4_3f79537f;
+defparam bootram.RAM2.INIT_39=256'hef38f999_5c867c26_7b34811c_5b5b7933_7b1d7f1d_05547d53_55a93ddc_7c575d9c;
+defparam bootram.RAM2.INIT_3A=256'h810684d1_60842e09_2a435b5b_7022708c_e438901d_09810684_7d90802e_3f84ee39;
+defparam bootram.RAM2.INIT_3B=256'hb4387e5e_065f7e84_2280ffff_c038861b_09810684_5a79852e_708f0651_3879882a;
+defparam bootram.RAM2.INIT_3C=256'h535b5ca3_e5c05470_1c625580_815e7e90_80088338_51a3f63f_c452821d_865380dc;
+defparam bootram.RAM2.INIT_3D=256'h33821c22_b83f891b_9c1d5184_38881d52_802e8481_7d87387b_8338815c_e03f8008;
+defparam bootram.RAM2.INIT_3E=256'h11225d5d_08a41f84_8c1b087a_0683de38_912e0981_81bb387f_407f812e_ec11405d;
+defparam bootram.RAM2.INIT_3F=256'h535d5df5_1d821d22_39ac1de4_ef3f83bd_ddc851f1_537d5280_2e8f3879_42407d7a;
+defparam bootram.RAM3.INIT_00=256'h527951a3_5a88537d_3d993d5f_237f499a_7a22993d_2e83a638_42800880_c33f8008;
+defparam bootram.RAM3.INIT_01=256'h05527951_a93dffb4_60478853_22973d23_c83f821b_527f51a3_40885379_d43f9c3d;
+defparam bootram.RAM3.INIT_02=256'h337b3481_1f5b5b79_5c7b1d7c_7e843d5e_7b567c55_51a3aa3f_5379527d_a3b33f88;
+defparam bootram.RAM3.INIT_03=256'h8405085a_26ef3861_1b5b887b_051c3481_79330284_5b7f1b5a_26ef3880_1c5c887c;
+defparam bootram.RAM3.INIT_04=256'h39811a33_bb388295_7d882e81_832e8a38_405b427d_a41e7033_398c1b08_792d82ad;
+defparam bootram.RAM3.INIT_05=256'hf4387c22_09810681_5c79912e_12335c5e_80c01e89_a238ac1d_09810681_5a79832e;
+defparam bootram.RAM3.INIT_06=256'h3d5c5e88_4b983d9b_9b3d2379_085a7c22_fe388c1c_08802e80_80084180_51f4813f;
+defparam bootram.RAM3.INIT_07=256'h3d23794d_821d229d_901c085a_51a2823f_537d527f_963d4088_51a28e3f_537a527d;
+defparam bootram.RAM3.INIT_08=256'h5e5c7b1d_557e843d_3f7e567e_7d51a1e1_88537a52_51a1ea3f_cc05527a_8853a93d;
+defparam bootram.RAM3.INIT_09=256'h811b5b88_84051c34_5a793302_805b7f1b_7c26ef38_811c5c88_79337b34_7c1f5b5b;
+defparam bootram.RAM3.INIT_0A=256'h3d347e02_5d5d7e95_ac1de41d_3f80de39_e951e598_5a792d80_60840508_7b26ef38;
+defparam bootram.RAM3.INIT_0B=256'h05237e53_840580d2_861a2202_22963d23_0523841a_840580ce_05347e02_840580cd;
+defparam bootram.RAM3.INIT_0C=256'h840580ce_095a7902_c03f8008_527c51f1_537b812a_cc3f8008_70525bf1_6052943d;
+defparam bootram.RAM3.INIT_0D=256'h94085553_800b80e6_04fc3d0d_3fa93d0d_6151f5f7_7a537f52_7c557d54_05237b56;
+defparam bootram.RAM3.INIT_0E=256'h72518b39_81068538_70752e09_8c135351_56517108_80e69c54_38767008_727427a4;
+defparam bootram.RAM3.INIT_0F=256'h3f800880_5755ffb9_77797153_04fb3d0d_0c863d0d_ff517080_7326e738_81135373;
+defparam bootram.RAM3.INIT_10=256'h0680e698_08811187_3980e698_e6940c8e_38811480_73872689_e6940854_25ba3880;
+defparam bootram.RAM3.INIT_11=256'h80081080_14519439_5280e6a0_54865375_9c120c51_760880e6_1470822b_0c547310;
+defparam bootram.RAM3.INIT_12=256'hd83f8054_0d7551fe_0d04fd3d_a43f873d_a005519f_842980e6_53755273_08055486;
+defparam bootram.RAM3.INIT_13=256'h81547380_519efa3f_a0055276_842980e6_54865373_10800805_99388008_73800824;
+defparam bootram.RAM3.INIT_14=256'h07831633_70882b72_07821433_2b71902b_12337198_75703381_04fd3d0d_0c853d0d;
+defparam bootram.RAM3.INIT_15=256'h387383ff_595776a8_e6fc2256_0d7d7f80_0d04f93d_5452853d_52535456_7107800c;
+defparam bootram.RAM3.INIT_16=256'h51547674_80e78005_14709029_38739029_832680d3_52565473_22707231_ff068b3d;
+defparam bootram.RAM3.INIT_17=256'h88538a3d_90291554_26ad3874_57547483_70723157_068d3d22_7383ffff_2380c039;
+defparam bootram.RAM3.INIT_18=256'h9d3f8116_547451e3_17703353_27913875_80567578_519dea3f_80e78005_52739029;
+defparam bootram.RAM3.INIT_19=256'h800b8288_54807323_80e78054_fc23800b_052280e6_3d0d029a_3d0d04fc_56ec3989;
+defparam bootram.RAM3.INIT_1A=256'h837427d9_90145454_3f811482_0551ef9b_e6fc2274_b5ae5280_828c140c_140c800b;
+defparam bootram.RAM3.INIT_1B=256'h38758288_567581be_70810651_7c2c8132_805a5c84_800b80e7_04f43d0d_38863d0d;
+defparam bootram.RAM3.INIT_1C=256'h800881ff_2e80c538_3f8008ff_7b51e2e2_1a88055b_80d63878_7981ff26_1a085b5d;
+defparam bootram.RAM3.INIT_1D=256'h38815d77_76802e83_59515858_25075351_80257180_32703072_7030728d_06708a32;
+defparam bootram.RAM3.INIT_1E=256'h27ffb138_5a81ff7a_1a0c811a_800b828c_82881a0c_19088105_5d348288_7b708105;
+defparam bootram.RAM3.INIT_1F=256'h78225675_7627bf38_1b0c568b_8111828c_828c1908_387c9138_802e80d2_82881908;
+defparam bootram.RAM3.INIT_20=256'h81185888_75337734_781a5757_5b58771a_800b833d_55881954_82881908_802eab38;
+defparam bootram.RAM3.INIT_21=256'h82901a5a_1a0c811c_800b828c_82881a0c_a83f800b_7c0551f2_80e6fc22_7826ef38;
+defparam bootram.RAM3.INIT_22=256'h0284059d_94ba3f80_c0526851_70545780_3d0d883d_3d0d04ea_fea9388e_5c837c27;
+defparam bootram.RAM3.INIT_23=256'h51547381_74167033_81069438_81aa2e09_2e9d3873_547381ff_17703351_05575574;
+defparam bootram.RAM3.INIT_24=256'hf93d0d86_983d0d04_5473800c_27d13880_1555be75_548b3981_06853881_992e0981;
+defparam bootram.RAM3.INIT_25=256'h09810683_8008752e_5199ca3f_ddec5273_55845380_93ea3f80_84527951_3d705454;
+defparam bootram.RAM3.INIT_26=256'h81ff0655_c23f8008_8dd73f8a_04fc3d0d_81e0940c_0d04810b_800c893d_38815574;
+defparam bootram.RAM3.INIT_27=256'h74b53880_51818339_3880ddf0_51547388_70810651_08708d2a_3f81b8b4_805189c1;
+defparam bootram.RAM3.INIT_28=256'h89873f82_c33f8151_ded451de_2e9a3880_3f800880_0a51febf_d73fb080_dea851de;
+defparam bootram.RAM3.INIT_29=256'h802ebb38_e33f8008_800a51fe_80cc3998_80df8c51_5184b53f_3fb0800a_ac51e2f6;
+defparam bootram.RAM3.INIT_2A=256'h3f82ac51_8451de80_bf3f80e0_800a5192_ffff5298_80805380_de963f83_80dfd851;
+defparam bootram.RAM3.INIT_2B=256'he451dddc_883980e0_5183e93f_e2a83f80_3f82ac51_a851ddf0_e53f80e0_e2b83ffe;
+defparam bootram.RAM3.INIT_2C=256'h51dc8b3f_3fa052a0_5254e6c8_5380e1b0_3d0d7570_c00c04fd_047180ef_3f863d0d;
+defparam bootram.RAM3.INIT_2D=256'h80efc008_51dbef3f_0da05280_0d04fe3d_722d853d_85387351_5372802e_80efc008;
+defparam bootram.RAM3.INIT_2E=256'h70810651_8008862a_8d3fff0b_0d9a5189_0d04fc3d_722d843d_85388051_5372802e;
+defparam bootram.RAM3.INIT_2F=256'h71828024_802e9b38_e4547182_06535580_80088680_ec38820b_71802e80_53548155;
+defparam bootram.RAM3.INIT_30=256'h08528551_88c83f80_ff548451_802e8338_e8547184_388a3987_71802e8e_8a388a54;
+defparam bootram.RAM3.INIT_31=256'he1e85553_efcc0c80_11337080_0780e2a8_70830672_80088a2c_882a8c06_88c03f71;
+defparam bootram.RAM3.INIT_32=256'h387480ef_c4082e98_3f7480ef_5252dc88_e4c81108_2b8c0680_ef3f7182_515452db;
+defparam bootram.RAM3.INIT_33=256'h7380efc8_81069638_74822e09_c13f9e39_06a338fe_812e0981_2ea63874_c40c7482;
+defparam bootram.RAM3.INIT_34=256'h0dd8b03f_0d04fd3d_cd3f863d_3f995187_7351fdfb_0cfea73f_7380efc8_082e8e38;
+defparam bootram.RAM3.INIT_35=256'hd63f81ae_52985187_87ac3f8d_c80c9951_ff0b80ef_80efc40c_a23f800b_80085187;
+defparam bootram.RAM3.INIT_36=256'h70535484_07f49f06_80089080_51878f3f_e0f03f84_ce528451_87cd3fbb_80529c51;
+defparam bootram.RAM3.INIT_37=256'h5186e33f_e3e63f80_80e28051_08537352_2e8d3880_3f738008_845186fa_5187b03f;
+defparam bootram.RAM3.INIT_38=256'h872a0771_2a820671_05337085_3d0d0297_3d0d04fd_87893f85_07528051_80088480;
+defparam bootram.RAM3.INIT_39=256'hff067685_07077081_a0067173_0674832b_07731090_06717307_72812a88_832a8406;
+defparam bootram.RAM3.INIT_3A=256'h853d0d04_52555552_52535155_c0800c51_81ff0682_872b0770_70720778_2b80c006;
+defparam bootram.RAM3.INIT_3B=256'h923f8199_81aa51ff_51ff983f_9e3f81ff_81ff51ff_d00a0753_d00a0681_fe3d0d74;
+defparam bootram.RAM3.INIT_3C=256'h81ff0651_fef53f72_ff065252_882a7081_ff813f72_3f80e151_b251ff87_51ff8c3f;
+defparam bootram.RAM3.INIT_3D=256'h5253fecf_7081ff06_3f72902a_2a51fedb_e23f7298_818151fe_51fee83f_feed3fb2;
+defparam bootram.RAM3.INIT_3E=256'h51feb03f_feb53f80_ba3fa051_3f8e51fe_8051febf_51fec43f_ca3f81a1_3fb051fe;
+defparam bootram.RAM3.INIT_3F=256'h5183ce3f_805280d0_3dfc0553_0d825487_0d04fb3d_a63f843d_3f8051fe_a051feab;
+defparam bootram.RAM4.INIT_00=256'h82932690_58595777_08841208_0880d73d_0d80d53d_04ffb23d_0c873d0d_863d2280;
+defparam bootram.RAM4.INIT_01=256'h2980e384_b2387584_75962681_ff9f1656_3f81bc39_b851e1b4_945280e2_38775382;
+defparam bootram.RAM4.INIT_02=256'h0b81e4d0_e2cc0c80_0c810b81_0b81e18c_08085e81_d5e43f80_0480c15c_05567508;
+defparam bootram.RAM4.INIT_03=256'hffff065e_3f800883_f839fef6_80c65c80_3f80085f_085e8c9d_8c993f80_0c818a39;
+defparam bootram.RAM4.INIT_04=256'heff8518a_80d33980_3f80c55c_f85189f5_085280ef_08538c17_e8399017_80d65c80;
+defparam bootram.RAM4.INIT_05=256'h08528c17_17539017_5cb73994_bc3980c2_3880c45c_75802e86_81ff0656_ba3f8008;
+defparam bootram.RAM4.INIT_06=256'h80d25c8d_518bb93f_528c1708_53901708_3dfe8005_a43980d0_3f80d75c_085188dc;
+defparam bootram.RAM4.INIT_07=256'h58771980_0b833d5a_ec055480_80d03dfd_5c829455_3f8339a0_8051fcf8_3980d35c;
+defparam bootram.RAM4.INIT_08=256'h0d04803d_3f80d03d_8251e8bd_ec388380_58887826_77348118_57577533_d23d7905;
+defparam bootram.RAM4.INIT_09=256'h2b075757_05337188_028405ab_02a70533_3ff93d0d_ff518397_51d68d3f_0d80e3e0;
+defparam bootram.RAM4.INIT_0A=256'h74ff1656_5a575758_7a7c7f7f_04f83d0d_3f893d0d_8051e1aa_75538152_82559854;
+defparam bootram.RAM4.INIT_0B=256'h538a3dfc_a1053482_33028405_70810558_8a3d3476_17575473_b7387581_54807425;
+defparam bootram.RAM4.INIT_0C=256'h81547380_8538c139_3f73802e_8a51da86_81ff0654_d83f8008_ff0651d8_05527781;
+defparam bootram.RAM4.INIT_0D=256'h3dfc0553_34815488_5675883d_748338dc_5580de56_02a30533_04fa3d0d_0c8a3d0d;
+defparam bootram.RAM4.INIT_0E=256'h3dfc0552_34815389_0533893d_7c5702ab_04f93d0d_3f883d0d_d051ff89_81f75280;
+defparam bootram.RAM4.INIT_0F=256'h76537b52_77259738_2e9e3880_56547380_81ff0670_f83f8008_705256d7_02a70533;
+defparam bootram.RAM4.INIT_10=256'h3d0d8154_3d0d04fa_74800c89_83388155_5473802e_ff067056_3f800881_7551d6bb;
+defparam bootram.RAM4.INIT_11=256'h83388156_2e098106_567480de_883d3356_a03f800b_80d051ff_5381f752_883dfc05;
+defparam bootram.RAM4.INIT_12=256'h0b81c0b0_ac0c89b0_a60b81c0_81c0800c_0c80eb0b_0b81c094_3d0d0499_75800c88;
+defparam bootram.RAM4.INIT_13=256'h0870812a_0c81c0a4_0b81c0a0_980c5182_810781c0_be800670_0d72882b_0c04803d;
+defparam bootram.RAM4.INIT_14=256'h70810781_2bbe8006_3d0d7288_3d0d0480_08800c82_3881c0a8_515170f1_70810651;
+defparam bootram.RAM4.INIT_15=256'h70f13882_06515151_812a7081_c0a40870_c0a00c81_0c840b81_7381c09c_c0980c51;
+defparam bootram.RAM4.INIT_16=256'h72830652_52718a38_38758306_57577191_83065555_787a7c72_39fa3d0d_3d0d04ff;
+defparam bootram.RAM4.INIT_17=256'h7008720c_77117712_3873822b_73752794_2a725555_ca3f7282_38815188_71802e86;
+defparam bootram.RAM4.INIT_18=256'h515353d1_ec113354_8f0680e3_70842a70_fe3d0d74_883d0d04_1454e939_52545281;
+defparam bootram.RAM4.INIT_19=256'h2a708106_90087088_3d0d82e0_3d0d0480_d1ba3f84_11335253_0680e3ec_c73f728f;
+defparam bootram.RAM4.INIT_1A=256'h80075353_060780c0_067a8c80_337880ff_0d029305_0d04fe3d_f138823d_51515170;
+defparam bootram.RAM4.INIT_1B=256'hff0682e0_900c7581_0c7182e0_7682e080_5170f138_81065151_70882a70_82e09008;
+defparam bootram.RAM4.INIT_1C=256'h515170f1_70810651_0870882a_3882e090_72802e96_900c7251_800782e0_980c7182;
+defparam bootram.RAM4.INIT_1D=256'h53805280_55885480_940c8880_810b82e0_04fc3d0d_0c843d0d_08517080_3882e080;
+defparam bootram.RAM4.INIT_1E=256'h81ff0680_f13f8008_528151fe_8a805381_80559054_fc3d0d88_863d0d04_51ff873f;
+defparam bootram.RAM4.INIT_1F=256'h0dca3f80_0d04803d_d53f863d_528051fe_54865381_88805588_04fc3d0d_0c863d0d;
+defparam bootram.RAM4.INIT_20=256'h3d0d04fb_2ef43882_06517080_800881ff_3d0deb3f_3d0d0480_06800c82_08813281;
+defparam bootram.RAM4.INIT_21=256'h9b0a0753_fe9b0a06_55a05475_b43f8880_38dd3fff_8008269b_84e33f75_3d0d7756;
+defparam bootram.RAM4.INIT_22=256'h80557381_11565757_cb3d08ff_c93d0880_ba3d0d80_3d0d04ff_fe843f87_81528051;
+defparam bootram.RAM4.INIT_23=256'h548c8f3f_883d7052_5381ff52_a7388280_80082681_849f3f73_38751754_ff2681b4;
+defparam bootram.RAM4.INIT_24=256'h0b82e090_980c8880_3f7482e0_d43ffd9f_fefd3ffe_518aea3f_3d085273_755380cb;
+defparam bootram.RAM4.INIT_25=256'ha00b82e0_e0900c8a_88a00b82_82e0980c_800c810b_0a0782e0_0a0680c0_0c76fec0;
+defparam bootram.RAM4.INIT_26=256'h880c54fe_700882e0_54fe8415_82e08c0c_80157008_558f56fe_3f80c83d_900cfcef;
+defparam bootram.RAM4.INIT_27=256'h0b82e090_900c8a80_800b82e0_800c5488_700882e0_54fe8c15_82e0840c_88157008;
+defparam bootram.RAM4.INIT_28=256'hc83d0d04_74800c80_980c8155_800b82e0_25ffbc38_56567580_ff169016_0cfcb03f;
+defparam bootram.RAM4.INIT_29=256'h2e80c338_81577480_2680cb38_57738008_82db3f80_575a5656_7b7d7212_f93d0d79;
+defparam bootram.RAM4.INIT_2A=256'h7551fdeb_77537352_83387654_57767527_74317555_a2388280_5473802e_7581ff06;
+defparam bootram.RAM4.INIT_2B=256'h39fd8c3f_828054dc_7527e138_74548280_802e8e38_57595674_19767631_3f731674;
+defparam bootram.RAM4.INIT_2C=256'h3f800874_135481ed_2e8d3873_54557380_76787a56_04fc3d0d_0c893d0d_81577680;
+defparam bootram.RAM4.INIT_2D=256'h16565152_707406ff_3f800830_a63981cb_0c80750c_800b8416_0b88160c_27903880;
+defparam bootram.RAM4.INIT_2E=256'h3d0d7554_3d0d04fd_fcc93f86_160c7151_160c7188_0c740684_08307276_81bd3f80;
+defparam bootram.RAM4.INIT_2F=256'h823f8814_2e943881_08841508_81538814_802e9f38_70545271_0881ff06_fc983f80;
+defparam bootram.RAM4.INIT_30=256'h5481f90a_888055a0_04fc3d0d_0c853d0d_80537280_51fc943f_7088160c_08800805;
+defparam bootram.RAM4.INIT_31=256'h38d73f80_efd008a0_ff3d0d80_863d0d04_0a06800c_8008fe80_51faa33f_53815281;
+defparam bootram.RAM4.INIT_32=256'h80efd008_80efd00c_06933871_a02e0981_54515170_0881ff06_81ff0680_08882a70;
+defparam bootram.RAM4.INIT_33=256'h800c04f3_e4c20533_3f800880_3d0d04c0_71800c83_38f5b33f_82712784_ea115252;
+defparam bootram.RAM4.INIT_34=256'h800b82e0_56f9983f_f63d0d7d_2b800c04_810b8008_04ffa93f_082b800c_3f810b80;
+defparam bootram.RAM4.INIT_35=256'h88a80b82_82e0980c_800c810b_882b82e0_e0840c7c_0c8b0b82_0b82e090_980c8880;
+defparam bootram.RAM4.INIT_36=256'h900c8a80_800b82e0_80d33888_54737627_3f7e5580_900cf8e7_a80b82e0_e0900c8a;
+defparam bootram.RAM4.INIT_37=256'h883d7675_e080085b_84085a82_085982e0_5882e088_82e08c08_0cf8cc3f_0b82e090;
+defparam bootram.RAM4.INIT_38=256'h57348112_75708105_17517033_27913871_80527173_83387053_53707327_31525790;
+defparam bootram.RAM4.INIT_39=256'h08028c0c_f7893f8c_3d0d7251_3d0d0480_e0980c8c_39800b82_1454ffa9_52ec3972;
+defparam bootram.RAM4.INIT_3A=256'h0d8c0c04_0c54853d_80087080_5182de3f_08880508_0508528c_538c088c_fd3d0d80;
+defparam bootram.RAM4.INIT_3B=256'h800c5485_3f800870_085182b9_8c088805_8c050852_81538c08_0cfd3d0d_8c08028c;
+defparam bootram.RAM4.INIT_3C=256'h388c0888_088025ab_8c088805_08fc050c_0d800b8c_8c0cf93d_048c0802_3d0d8c0c;
+defparam bootram.RAM4.INIT_3D=256'h0c8c08f4_8c08f405_8838810b_08fc0508_f4050c8c_800b8c08_0888050c_0508308c;
+defparam bootram.RAM4.INIT_3E=256'h0b8c08f0_8c050c80_08308c08_8c088c05_8025ab38_088c0508_fc050c8c_05088c08;
+defparam bootram.RAM4.INIT_3F=256'h8c088c05_050c8053_088c08fc_8c08f005_08f0050c_38810b8c_fc050888_050c8c08;
+defparam bootram.RAM5.INIT_00=256'h388c08f8_08802e8c_8c08fc05_f8050c54_08708c08_81a73f80_88050851_08528c08;
+defparam bootram.RAM5.INIT_01=256'hfb3d0d80_08028c0c_8c0c048c_54893d0d_0870800c_8c08f805_08f8050c_0508308c;
+defparam bootram.RAM5.INIT_02=256'h8c08fc05_050c810b_308c0888_08880508_2593388c_88050880_050c8c08_0b8c08fc;
+defparam bootram.RAM5.INIT_03=256'h528c0888_088c0508_0c81538c_8c088c05_8c050830_8c388c08_05088025_0c8c088c;
+defparam bootram.RAM5.INIT_04=256'h308c08f8_08f80508_2e8c388c_fc050880_0c548c08_8c08f805_3f800870_050851ad;
+defparam bootram.RAM5.INIT_05=256'h08fc050c_0d810b8c_8c0cfd3d_048c0802_3d0d8c0c_800c5487_f8050870_050c8c08;
+defparam bootram.RAM5.INIT_06=256'h38800b8c_08802ea3_8c08fc05_0827ac38_8c088805_088c0508_f8050c8c_800b8c08;
+defparam bootram.RAM5.INIT_07=256'h0cc9398c_8c08fc05_fc050810_050c8c08_108c088c_088c0508_2499388c_088c0508;
+defparam bootram.RAM5.INIT_08=256'h088c0508_8805088c_a1388c08_88050826_05088c08_388c088c_802e80c9_08fc0508;
+defparam bootram.RAM5.INIT_09=256'h2a8c08fc_fc050881_050c8c08_078c08f8_08fc0508_f805088c_050c8c08_318c0888;
+defparam bootram.RAM5.INIT_0A=256'h88050870_8f388c08_0508802e_398c0890_050cffaf_2a8c088c_8c050881_050c8c08;
+defparam bootram.RAM5.INIT_0B=256'h3d0d8c0c_08800c85_8c08f405_f4050c51_08708c08_8c08f805_0c518d39_8c08f405;
+defparam bootram.RAM5.INIT_0C=256'h5271ff2e_b038ff12_5170802e_74078306_278c3874_56528372_78777956_04fc3d0d;
+defparam bootram.RAM5.INIT_0D=256'h098106e2_5571ff2e_ff145455_81158115_8106bd38_72712e09_74335253_a0387433;
+defparam bootram.RAM5.INIT_0E=256'h14545451_118414fc_068f3884_082e0981_51700873_04747454_0c863d0d_38800b80;
+defparam bootram.RAM5.INIT_0F=256'h55555555_7670797b_04fc3d0d_0c863d0d_72713180_55ffaf39_38707355_718326e9;
+defparam bootram.RAM5.INIT_10=256'h54337470_72708105_ff2e9838_ff125271_802ea738_83065170_38727507_8f72278c;
+defparam bootram.RAM5.INIT_11=256'h54087170_72708405_0d047451_800c863d_06ea3874_ff2e0981_ff125271_81055634;
+defparam bootram.RAM5.INIT_12=256'h72708405_8405530c_54087170_72708405_8405530c_54087170_72708405_8405530c;
+defparam bootram.RAM5.INIT_13=256'h70840553_05540871_38727084_83722795_8f26c938_f0125271_8405530c_54087170;
+defparam bootram.RAM5.INIT_14=256'h53558372_05335755_028c059f_0d767971_8339fc3d_387054ff_718326ed_0cfc1252;
+defparam bootram.RAM5.INIT_15=256'h125271ff_055534ff_73737081_ff2e9338_ff125271_802ea238_83065170_278a3874;
+defparam bootram.RAM5.INIT_16=256'h7227a538_5154518f_71902b07_2b750770_04747488_0c863d0d_ef387480_2e098106;
+defparam bootram.RAM5.INIT_17=256'hf0125271_8405530c_0c727170_70840553_530c7271_71708405_05530c72_72717084;
+defparam bootram.RAM5.INIT_18=256'h39fa3d0d_7053ff90_8326f238_fc125271_8405530c_38727170_83722790_8f26dd38;
+defparam bootram.RAM5.INIT_19=256'h5372ff2e_d438ff13_70802e80_07830651_d9387174_72802e80_54555552_787a7c70;
+defparam bootram.RAM5.INIT_1A=256'h802e80fc_ff065170_87387081_72802e81_8106a938_74712e09_74335651_b1387133;
+defparam bootram.RAM5.INIT_1B=256'h7581ff06_7081ff06_74335651_d1387133_2e098106_555272ff_15ff1555_38811281;
+defparam bootram.RAM5.INIT_1C=256'h38747655_74082e88_88387108_55837327_04717457_0c883d0d_52527080_71713151;
+defparam bootram.RAM5.INIT_1D=256'h06515151_84828180_120670f8_f7fbfdff_74087009_802eb138_fc135372_52ff9739;
+defparam bootram.RAM5.INIT_1E=256'h800b800c_52fedf39_38747655_76082ed0_d0387408_55837327_15841757_709a3884;
+defparam bootram.RAM5.INIT_1F=256'h3fffb080_0cffb0e4_7380efd4_812e9e38_08545472_0b80e49c_fd3d0d80_883d0d04;
+defparam bootram.RAM5.INIT_20=256'he33f80e4_c73fffaf_d40cffb0_3f7280ef_0851f6a3_b7dd3f80_528151ff_3f80e4dc;
+defparam bootram.RAM5.INIT_21=256'h525270ff_fc057008_80e4e40b_39ff3d0d_863f00ff_800851f6_ffb7c03f_dc528151;
+defparam bootram.RAM5.INIT_22=256'h04000000_ffb0f23f_3d0d0404_06f13883_ff2e0981_08525270_2dfc1270_2e913870;
+defparam bootram.RAM5.INIT_23=256'h2068616e_636b6574_6c207061_6e74726f_6e20636f_6f722069_21457272_00000040;
+defparam bootram.RAM5.INIT_24=256'h206e756d_6c697479_74696269_6f6d7061_65642063_70656374_3a204578_646c6572;
+defparam bootram.RAM5.INIT_25=256'h6e20636f_6f722069_21457272_25640a00_676f7420_62757420_25642c20_62657220;
+defparam bootram.RAM5.INIT_26=256'h65642070_70656374_3a204578_646c6572_2068616e_636b6574_6c207061_6e74726f;
+defparam bootram.RAM5.INIT_27=256'h0a000000_74202564_7420676f_2c206275_68202564_656e6774_6164206c_61796c6f;
+defparam bootram.RAM5.INIT_28=256'h640a0000_203d2025_70656564_643a2073_616e6765_6b206368_206c696e_0a657468;
+defparam bootram.RAM5.INIT_29=256'h46504741_720a0000_6f616465_6f6f746c_44502062_31302055_50204e32_0a555352;
+defparam bootram.RAM5.INIT_2A=256'h4669726d_640a0000_723a2025_756d6265_7479206e_62696c69_70617469_20636f6d;
+defparam bootram.RAM5.INIT_2B=256'h640a0000_723a2025_756d6265_7479206e_62696c69_70617469_20636f6d_77617265;
+defparam bootram.RAM5.INIT_2C=256'h65743a20_7061636b_65727920_65636f76_69702072_476f7420_00000000_61646472;
+defparam bootram.RAM5.INIT_2D=256'h00000785_00000785_00000785_00000785_00000785_00000785_00000690_00000000;
+defparam bootram.RAM5.INIT_2E=256'h00000785_00000785_00000785_0000075b_00000785_00000785_000006d5_000006ec;
+defparam bootram.RAM5.INIT_2F=256'h00000735_0000072e_00000729_00000724_0000069d_00000709_00000785_00000785;
+defparam bootram.RAM5.INIT_30=256'h01b200d9_05160364_14580a2c_3fff0000_0050c285_c0a80a02_00000749_0000073c;
+defparam bootram.RAM5.INIT_31=256'h43444546_38394142_34353637_30313233_2e256400_642e2564_25642e25_45000000;
+defparam bootram.RAM5.INIT_32=256'h69676e6d_6420616c_3a206261_5f706b74_73656e64_ffff0000_ffffffff_00000000;
+defparam bootram.RAM5.INIT_33=256'h636f6d6d_6e65745f_66000000_72206275_6e642f6f_656e2061_6f66206c_656e7420;
+defparam bootram.RAM5.INIT_34=256'h696e6720_6c6f6f6b_63686520_74206361_6f206869_65642074_6661696c_6f6e3a20;
+defparam bootram.RAM5.INIT_35=256'h697a6520_72642073_20776569_6172703a_646c655f_0a68616e_00000000_666f7220;
+defparam bootram.RAM5.INIT_36=256'h67746873_206c656e_74656e74_6e736973_696e636f_55445020_0a000000_3d202564;
+defparam bootram.RAM5.INIT_37=256'h50322b20_20555352_74696e67_53746172_0b0b0b0b_00000000_2025640a_3a202564;
+defparam bootram.RAM5.INIT_38=256'h69726d77_66652066_67207361_6164696e_2e204c6f_6d6f6465_61666520_696e2073;
+defparam bootram.RAM5.INIT_39=256'h726f6475_69642070_2076616c_20666f72_6b696e67_43686563_00000000_6172652e;
+defparam bootram.RAM5.INIT_3A=256'h6f647563_64207072_56616c69_2e2e2e00_6d616765_47412069_6e204650_6374696f;
+defparam bootram.RAM5.INIT_3B=256'h7074696e_7474656d_642e2041_666f756e_61676520_4120696d_20465047_74696f6e;
+defparam bootram.RAM5.INIT_3C=256'h696f6e20_64756374_2070726f_616c6964_4e6f2076_742e0000_20626f6f_6720746f;
+defparam bootram.RAM5.INIT_3D=256'h726f7567_67207468_6c6c696e_2e0a4661_6f756e64_67652066_20696d61_46504741;
+defparam bootram.RAM5.INIT_3E=256'h64207072_56616c69_72652e00_726d7761_6e206669_6c742d69_20627569_6820746f;
+defparam bootram.RAM5.INIT_3F=256'h64696e67_204c6f61_756e642e_6520666f_6d776172_20666972_74696f6e_6f647563;
+defparam bootram.RAM6.INIT_00=256'h6e672069_61727469_2e205374_64696e67_206c6f61_73686564_46696e69_2e2e2e00;
+defparam bootram.RAM6.INIT_01=256'h61696e20_6f6d206d_6e206672_65747572_523a2052_4552524f_2e000000_6d616765;
+defparam bootram.RAM6.INIT_02=256'h61707065_65722068_206e6576_6f756c64_73207368_20546869_72616d21_70726f67;
+defparam bootram.RAM6.INIT_03=256'h77617265_6669726d_696f6e20_64756374_2070726f_616c6964_4e6f2076_6e210000;
+defparam bootram.RAM6.INIT_04=256'h75696c74_746f2062_75676820_7468726f_696e6720_46616c6c_6e642e20_20666f75;
+defparam bootram.RAM6.INIT_05=256'h2025640a_7420746f_64207365_53706565_2e000000_77617265_6669726d_2d696e20;
+defparam bootram.RAM6.INIT_06=256'h53594d4d_58000000_57455f52_58000000_57455f54_00000000_4e4f4e45_00000000;
+defparam bootram.RAM6.INIT_07=256'h6c3a2000_6e74726f_7720636f_20666c6f_726e6574_65746865_43000000_45545249;
+defparam bootram.RAM6.INIT_08=256'h20676f74_7825782c_74652030_2077726f_4144563a_4e45475f_4155544f_5048595f;
+defparam bootram.RAM6.INIT_09=256'h6f722069_21457272_00030203_00000001_00030003_00000000_780a0000_20307825;
+defparam bootram.RAM6.INIT_0A=256'h65637465_20457870_6c65723a_68616e64_6b657420_20706163_64617465_6e207570;
+defparam bootram.RAM6.INIT_0B=256'h2025640a_20676f74_20627574_2025642c_6e677468_64206c65_796c6f61_64207061;
+defparam bootram.RAM6.INIT_0C=256'h000020eb_00002064_00002086_0000209b_000020eb_000020eb_00002045_00000000;
+defparam bootram.RAM6.INIT_0D=256'h000020eb_000020eb_000020eb_000020eb_000020eb_000020eb_000020eb_000020eb;
+defparam bootram.RAM6.INIT_0E=256'h000020b7_00002076_000020eb_000020eb_000020e1_000020ca_000020eb_000020eb;
+defparam bootram.RAM6.INIT_0F=256'h64756d6d_43444546_38394142_34353637_30313233_00000000_6f72740a_0a0a6162;
+defparam bootram.RAM6.INIT_10=256'h00000000_00000000_ffffff00_ffff00ff_ff00ffff_00ffffff_65000000_792e6578;
+defparam bootram.RAM6.INIT_11=256'hffff0031_05050400_01010100_3fff0000_0050c285_c0a80a02_0000326c_00000000;
+defparam bootram.RAM6.INIT_12=256'h000031fc_10101200_000030dc_000030d4_000030cc_000030c4_000b0000_0018000f;
+defparam bootram.RAM6.INIT_13=256'h00000000_00000000_00000000_00000000_00000000_ffffffff_00000000_ffffffff;
+defparam bootram.RAM6.INIT_14=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
defparam bootram.RAM6.INIT_15=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
defparam bootram.RAM6.INIT_16=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
defparam bootram.RAM6.INIT_17=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
diff --git a/fpga/usrp2/top/N2x0/u2plus_core.v b/fpga/usrp2/top/N2x0/u2plus_core.v
index 369f01183..703e157cc 100644
--- a/fpga/usrp2/top/N2x0/u2plus_core.v
+++ b/fpga/usrp2/top/N2x0/u2plus_core.v
@@ -149,10 +149,10 @@ module u2plus_core
);
localparam SR_MISC = 0; // 7 regs
- localparam SR_SIMTIMER = 8; // 2
+ localparam SR_USER_REGS = 8; // 2
localparam SR_TIME64 = 10; // 6
localparam SR_BUF_POOL = 16; // 4
- localparam SR_USER_REGS = 20; // 2
+ localparam SR_SPI_CORE = 20; // 3
localparam SR_RX_FRONT = 24; // 5
localparam SR_RX_CTRL0 = 32; // 9
localparam SR_RX_DSP0 = 48; // 7
@@ -278,9 +278,11 @@ module u2plus_core
.sf_dat_o(sf_dat_o),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),
.sf_dat_i(sf_dat_i),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0));
- // Unused Slaves 9, b, c
+ assign s2_ack = 0;
assign s4_ack = 0;
- assign s9_ack = 0; assign sb_ack = 0; assign sc_ack = 0;
+ assign s9_ack = 0;
+ assign sb_ack = 0;
+ assign sc_ack = 0;
// ////////////////////////////////////////////////////////////////////////////////////////
// Reset Controller
@@ -373,6 +375,10 @@ module u2plus_core
wire wr3_ready_i, wr3_ready_o;
wire [35:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
+ wire [35:0] sfc_wr_data, sfc_rd_data;
+ wire sfc_wr_ready, sfc_rd_ready;
+ wire sfc_wr_valid, sfc_rd_valid;
+
wire [35:0] tx_err_data;
wire tx_err_src_rdy, tx_err_dst_rdy;
@@ -393,21 +399,27 @@ module u2plus_core
.dsp0_inp_data(wr1_dat), .dsp0_inp_valid(wr1_ready_i), .dsp0_inp_ready(wr1_ready_o),
.dsp1_inp_data(wr3_dat), .dsp1_inp_valid(wr3_ready_i), .dsp1_inp_ready(wr3_ready_o),
.eth_inp_data(wr2_dat), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
- .err_inp_data(tx_err_data), .err_inp_ready(tx_err_dst_rdy), .err_inp_valid(tx_err_src_rdy),
+ .err_inp_data(tx_err_data), .err_inp_valid(tx_err_src_rdy), .err_inp_ready(tx_err_dst_rdy),
+ .ctl_inp_data(sfc_wr_data), .ctl_inp_valid(sfc_wr_valid), .ctl_inp_ready(sfc_wr_ready),
.ser_out_data(rd0_dat), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
.dsp_out_data(rd1_dat), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
+ .ctl_out_data(sfc_rd_data), .ctl_out_valid(sfc_rd_valid), .ctl_out_ready(sfc_rd_ready),
.eth_out_data(rd2_dat), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
);
// /////////////////////////////////////////////////////////////////////////
// SPI -- Slave #2
- spi_top shared_spi
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.wb_adr_i(s2_adr[4:0]),.wb_dat_i(s2_dat_o),
- .wb_dat_o(s2_dat_i),.wb_sel_i(s2_sel),.wb_we_i(s2_we),.wb_stb_i(s2_stb),
- .wb_cyc_i(s2_cyc),.wb_ack_o(s2_ack),.wb_err_o(),.wb_int_o(spi_int),
- .ss_pad_o({sen_adc, sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
- .sclk_pad_o(sclk),.mosi_pad_o(mosi),.miso_pad_i(miso) );
+ wire [31:0] spi_debug;
+ wire [31:0] spi_readback;
+ wire spi_ready;
+ simple_spi_core #(.BASE(SR_SPI_CORE), .WIDTH(9)) shared_spi(
+ .clock(dsp_clk), .reset(dsp_rst),
+ .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
+ .readback(spi_readback), .ready(spi_ready),
+ .sen({sen_adc, sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
+ .sclk(sclk), .mosi(mosi), .miso(miso), .debug(spi_debug)
+ );
// /////////////////////////////////////////////////////////////////////////
// I2C -- Slave #3
@@ -436,17 +448,18 @@ module u2plus_core
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
- localparam compat_num = {16'd9, 16'd0}; //major, minor
- wire [31:0] churn = status; //tweak churn until timing meets!
+ localparam compat_num = {16'd10, 16'd0}; //major, minor
+
+ wire [31:0] irq_readback = {18'b0, button, spi_ready, clk_status, serdes_link_up, 10'b0};
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
.wb_adr_i(s5_adr), .wb_dat_o(s5_dat_i), .wb_ack_o(s5_ack),
- .word00(churn),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
- .word11(vita_time[31:0]),.word12(compat_num),.word13({18'b0, button, 1'b0, clk_status, serdes_link_up, 10'b0}),
+ .word11(vita_time[31:0]),.word12(compat_num),.word13(irq_readback),
.word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])
);
@@ -477,9 +490,19 @@ module u2plus_core
assign s7_dat_i = 32'd0;
- settings_bus_crossclock settings_bus_crossclock
+ wire set_stb_dsp0, set_stb_dsp1;
+ wire [31:0] set_data_dsp0, set_data_dsp1;
+ wire [7:0] set_addr_dsp0, set_addr_dsp1;
+
+ //mux settings_bus_crossclock and settings_readback_bus_fifo_ctrl with prio
+ assign set_stb_dsp = set_stb_dsp0 | set_stb_dsp1;
+ assign set_addr_dsp = set_stb_dsp1? set_addr_dsp1 : set_addr_dsp0;
+ assign set_data_dsp = set_stb_dsp1? set_data_dsp1 : set_data_dsp0;
+
+ settings_bus_crossclock #(.FLOW_CTRL(1/*on*/)) settings_bus_crossclock
(.clk_i(wb_clk), .rst_i(wb_rst), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data),
- .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp));
+ .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp0), .set_addr_o(set_addr_dsp0), .set_data_o(set_data_dsp0),
+ .blocked(set_stb_dsp1));
user_settings #(.BASE(SR_USER_REGS)) user_settings
(.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb_dsp),
@@ -487,6 +510,29 @@ module u2plus_core
.set_addr_user(set_addr_user),.set_data_user(set_data_user),
.set_stb_user(set_stb_user) );
+ // /////////////////////////////////////////////////////////////////////////
+ // Settings + Readback Bus -- FIFO controlled
+
+ wire [31:0] sfc_debug;
+ wire sfc_clear;
+ settings_fifo_ctrl #(.PROT_DEST(3), .PROT_HDR(1)) sfc
+ (
+ .clock(dsp_clk), .reset(dsp_rst), .clear(sfc_clear),
+ .vita_time(vita_time), .perfs_ready(spi_ready),
+ .in_data(sfc_rd_data), .in_valid(sfc_rd_valid), .in_ready(sfc_rd_ready),
+ .out_data(sfc_wr_data), .out_valid(sfc_wr_valid), .out_ready(sfc_wr_ready),
+ .strobe(set_stb_dsp1), .addr(set_addr_dsp1), .data(set_data_dsp1),
+ .word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
+ .word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
+ .word11(vita_time[31:0]),.word12(compat_num),.word13(irq_readback),
+ .word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0]),
+ .debug(sfc_debug)
+ );
+
+ setting_reg #(.my_addr(SR_BUF_POOL+1/*same as packet dispatcher*/),.width(1)) sr_clear_sfc
+ (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.changed(sfc_clear));
+
// Output control lines
wire [7:0] clock_outs, serdes_outs, adc_outs;
assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0];
diff --git a/fpga/usrp2/top/USRP2/Makefile b/fpga/usrp2/top/USRP2/Makefile
index 10610c7dc..94480a811 100644
--- a/fpga/usrp2/top/USRP2/Makefile
+++ b/fpga/usrp2/top/USRP2/Makefile
@@ -70,7 +70,7 @@ SYNTHESIZE_PROPERTIES = \
"Use Clock Enable" Auto \
"Use Synchronous Reset" Auto \
"Use Synchronous Set" Auto \
-"Verilog Macros" "$(CUSTOM_DEFS)"
+"Verilog Macros" "FIFO_CTRL_NO_TIME=1 $(CUSTOM_DEFS)"
TRANSLATE_PROPERTIES = \
"Macro Search Path" "$(shell pwd)/../../coregen/"
diff --git a/fpga/usrp2/top/USRP2/u2_core.v b/fpga/usrp2/top/USRP2/u2_core.v
index 6bf60fe58..9038ab788 100644
--- a/fpga/usrp2/top/USRP2/u2_core.v
+++ b/fpga/usrp2/top/USRP2/u2_core.v
@@ -154,10 +154,10 @@ module u2_core
);
localparam SR_MISC = 0; // 7 regs
- localparam SR_SIMTIMER = 8; // 2
+ localparam SR_USER_REGS = 8; // 2
localparam SR_TIME64 = 10; // 6
localparam SR_BUF_POOL = 16; // 4
- localparam SR_USER_REGS = 20; // 2
+ localparam SR_SPI_CORE = 20; // 3
localparam SR_RX_FRONT = 24; // 5
localparam SR_RX_CTRL0 = 32; // 9
localparam SR_RX_DSP0 = 48; // 7
@@ -284,10 +284,14 @@ module u2_core
.sf_dat_o(sf_dat_o),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),
.sf_dat_i(sf_dat_i),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0));
- // Unused Slaves 4, 9 and b-f
+ assign s2_ack = 0;
assign s4_ack = 0;
- assign s9_ack = 0; assign sb_ack = 0; assign sc_ack = 0;
- assign sd_ack = 0; assign se_ack = 0; assign fc_ack = 0;
+ assign s9_ack = 0;
+ assign sb_ack = 0;
+ assign sc_ack = 0;
+ assign sd_ack = 0;
+ assign se_ack = 0;
+ assign sf_ack = 0;
// ////////////////////////////////////////////////////////////////////////////////////////
// Reset Controller
@@ -379,6 +383,10 @@ module u2_core
wire wr3_ready_i, wr3_ready_o;
wire [35:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
+ wire [35:0] sfc_wr_data, sfc_rd_data;
+ wire sfc_wr_ready, sfc_rd_ready;
+ wire sfc_wr_valid, sfc_rd_valid;
+
wire [35:0] tx_err_data;
wire tx_err_src_rdy, tx_err_dst_rdy;
@@ -399,21 +407,27 @@ module u2_core
.dsp0_inp_data(wr1_dat), .dsp0_inp_valid(wr1_ready_i), .dsp0_inp_ready(wr1_ready_o),
.dsp1_inp_data(wr3_dat), .dsp1_inp_valid(wr3_ready_i), .dsp1_inp_ready(wr3_ready_o),
.eth_inp_data(wr2_dat), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
- .err_inp_data(tx_err_data), .err_inp_ready(tx_err_dst_rdy), .err_inp_valid(tx_err_src_rdy),
+ .err_inp_data(tx_err_data), .err_inp_valid(tx_err_src_rdy), .err_inp_ready(tx_err_dst_rdy),
+ .ctl_inp_data(sfc_wr_data), .ctl_inp_valid(sfc_wr_valid), .ctl_inp_ready(sfc_wr_ready),
.ser_out_data(rd0_dat), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
.dsp_out_data(rd1_dat), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
+ .ctl_out_data(sfc_rd_data), .ctl_out_valid(sfc_rd_valid), .ctl_out_ready(sfc_rd_ready),
.eth_out_data(rd2_dat), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
);
// /////////////////////////////////////////////////////////////////////////
// SPI -- Slave #2
- spi_top shared_spi
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.wb_adr_i(s2_adr[4:0]),.wb_dat_i(s2_dat_o),
- .wb_dat_o(s2_dat_i),.wb_sel_i(s2_sel),.wb_we_i(s2_we),.wb_stb_i(s2_stb),
- .wb_cyc_i(s2_cyc),.wb_ack_o(s2_ack),.wb_err_o(),.wb_int_o(spi_int),
- .ss_pad_o({sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
- .sclk_pad_o(sclk),.mosi_pad_o(mosi),.miso_pad_i(miso) );
+ wire [31:0] spi_debug;
+ wire [31:0] spi_readback;
+ wire spi_ready;
+ simple_spi_core #(.BASE(SR_SPI_CORE), .WIDTH(8)) shared_spi(
+ .clock(dsp_clk), .reset(dsp_rst),
+ .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
+ .readback(spi_readback), .ready(spi_ready),
+ .sen({sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
+ .sclk(sclk), .mosi(mosi), .miso(miso), .debug(spi_debug)
+ );
// /////////////////////////////////////////////////////////////////////////
// I2C -- Slave #3
@@ -442,17 +456,18 @@ module u2_core
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
- localparam compat_num = {16'd9, 16'd0}; //major, minor
- wire [31:0] churn = 0; //tweak churn until timing meets!
+ localparam compat_num = {16'd10, 16'd0}; //major, minor
+
+ wire [31:0] irq_readback = {19'b0, spi_ready, clk_status, serdes_link_up, 10'b0};
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
.wb_adr_i(s5_adr), .wb_dat_o(s5_dat_i), .wb_ack_o(s5_ack),
- .word00(churn),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
- .word11(vita_time[31:0]),.word12(compat_num),.word13({20'b0, clk_status, serdes_link_up, 10'b0}),
+ .word11(vita_time[31:0]),.word12(compat_num),.word13(irq_readback),
.word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0])
);
@@ -483,9 +498,19 @@ module u2_core
assign s7_dat_i = 32'd0;
- settings_bus_crossclock settings_bus_crossclock
+ wire set_stb_dsp0, set_stb_dsp1;
+ wire [31:0] set_data_dsp0, set_data_dsp1;
+ wire [7:0] set_addr_dsp0, set_addr_dsp1;
+
+ //mux settings_bus_crossclock and settings_readback_bus_fifo_ctrl with prio
+ assign set_stb_dsp = set_stb_dsp0 | set_stb_dsp1;
+ assign set_addr_dsp = set_stb_dsp1? set_addr_dsp1 : set_addr_dsp0;
+ assign set_data_dsp = set_stb_dsp1? set_data_dsp1 : set_data_dsp0;
+
+ settings_bus_crossclock #(.FLOW_CTRL(1/*on*/)) settings_bus_crossclock
(.clk_i(wb_clk), .rst_i(wb_rst), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data),
- .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp));
+ .clk_o(dsp_clk), .rst_o(dsp_rst), .set_stb_o(set_stb_dsp0), .set_addr_o(set_addr_dsp0), .set_data_o(set_data_dsp0),
+ .blocked(set_stb_dsp1));
user_settings #(.BASE(SR_USER_REGS)) user_settings
(.clk(dsp_clk),.rst(dsp_rst),.set_stb(set_stb_dsp),
@@ -493,6 +518,29 @@ module u2_core
.set_addr_user(set_addr_user),.set_data_user(set_data_user),
.set_stb_user(set_stb_user) );
+ // /////////////////////////////////////////////////////////////////////////
+ // Settings + Readback Bus -- FIFO controlled
+
+ wire [31:0] sfc_debug;
+ wire sfc_clear;
+ settings_fifo_ctrl #(.PROT_DEST(3), .PROT_HDR(1)) sfc
+ (
+ .clock(dsp_clk), .reset(dsp_rst), .clear(sfc_clear),
+ .vita_time(vita_time), .perfs_ready(spi_ready),
+ .in_data(sfc_rd_data), .in_valid(sfc_rd_valid), .in_ready(sfc_rd_ready),
+ .out_data(sfc_wr_data), .out_valid(sfc_wr_valid), .out_ready(sfc_wr_ready),
+ .strobe(set_stb_dsp1), .addr(set_addr_dsp1), .data(set_data_dsp1),
+ .word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
+ .word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
+ .word08(status),.word09(gpio_readback),.word10(vita_time[63:32]),
+ .word11(vita_time[31:0]),.word12(compat_num),.word13(irq_readback),
+ .word14(vita_time_pps[63:32]),.word15(vita_time_pps[31:0]),
+ .debug(sfc_debug)
+ );
+
+ setting_reg #(.my_addr(SR_BUF_POOL+1/*same as packet dispatcher*/),.width(1)) sr_clear_sfc
+ (.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.changed(sfc_clear));
+
// Output control lines
wire [7:0] clock_outs, serdes_outs, adc_outs;
assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0];
diff --git a/host/docs/sync.rst b/host/docs/sync.rst
index 4cf52e38d..5abd39f86 100644
--- a/host/docs/sync.rst
+++ b/host/docs/sync.rst
@@ -152,8 +152,41 @@ For transmit, a burst is started when the user calls send(). The metadata should
//send a single packet
size_t num_tx_samps = tx_streamer->send(buffs, samps_to_send, md);
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Align LOs in the front-end (SBX/WBX + N-Series)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Using timed commands, multiple frontends can be tuned at a specific time.
+This timed-tuning ensures that the phase offsets between VCO/PLL chains
+will remain constant after each re-tune. See notes below:
+
+* There is a random phase offset between any two frontends
+* This phase offset is different for different LO frequencies
+* This phase offset remains constant after retuning
+
+ * Due to divider, WBX phase offset will be randomly +/- 180 deg after re-tune
+
+* This phase offset will drift over time due to thermal and other characteristics
+* Periodic calibration will be necessary for phase-coherent applications
+
+Code snippet example, tuning with timed commands:
+::
+
+ //we will tune the frontends in 100ms from now
+ uhd::time_spec_t cmd_time = usrp->get_time_now() + uhd::time_spec_t(0.1);
+
+ //sets command time on all devices
+ //the next commands are all timed
+ usrp->set_command_time(cmd_time);
+
+ //tune channel 0 and channel 1
+ usrp->set_rx_freq(1.03e9, 0/*ch0*/);
+ usrp->set_rx_freq(1.03e9, 1/*ch1*/);
+
+ //end timed commands
+ usrp->set_clear_time();
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Align LOs in the front-end
+Align LOs in the front-end (others)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
After tuning the RF front-ends,
each local oscillator may have a random phase offset due to the dividers
diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt
index b41d53d11..34f2eccba 100644
--- a/host/examples/CMakeLists.txt
+++ b/host/examples/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2010-2011 Ettus Research LLC
+# Copyright 2010-2012 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@ SET(example_sources
rx_timed_samples.cpp
test_messages.cpp
test_pps_input.cpp
+ test_timed_commands.cpp
transport_hammer.cpp
tx_bursts.cpp
tx_samples_from_file.cpp
diff --git a/host/examples/test_timed_commands.cpp b/host/examples/test_timed_commands.cpp
new file mode 100644
index 000000000..34c83dfd6
--- /dev/null
+++ b/host/examples/test_timed_commands.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/utils/thread_priority.hpp>
+#include <uhd/utils/safe_main.hpp>
+#include <uhd/usrp/multi_usrp.hpp>
+#include <boost/program_options.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+#include <complex>
+
+namespace po = boost::program_options;
+
+int UHD_SAFE_MAIN(int argc, char *argv[]){
+ uhd::set_thread_priority_safe();
+
+ //variables to be set by po
+ std::string args;
+
+ //setup the program options
+ po::options_description desc("Allowed options");
+ desc.add_options()
+ ("help", "help message")
+ ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")
+ ;
+ po::variables_map vm;
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+
+ //print the help message
+ if (vm.count("help")){
+ std::cout << boost::format("UHD Test Timed Commands %s") % desc << std::endl;
+ return ~0;
+ }
+
+ //create a usrp device
+ std::cout << std::endl;
+ std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
+ uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
+ std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl;
+
+ //check if timed commands are supported
+ std::cout << std::endl;
+ std::cout << "Testing support for timed commands on this hardware... " << std::flush;
+ try{
+ usrp->set_command_time(uhd::time_spec_t(0.0));
+ usrp->clear_command_time();
+ }
+ catch (const std::exception &e){
+ std::cout << "fail" << std::endl;
+ std::cerr << "Got exception: " << e.what() << std::endl;
+ std::cerr << "Timed commands are not supported on this hardware." << std::endl;
+ return ~0;
+ }
+ std::cout << "pass" << std::endl;
+
+ //readback time really fast, time diff is small
+ std::cout << std::endl;
+ std::cout << "Perform fast readback of registers:" << std::endl;
+ uhd::time_spec_t total_time;
+ for (size_t i = 0; i < 100; i++){
+ const uhd::time_spec_t t0 = usrp->get_time_now();
+ const uhd::time_spec_t t1 = usrp->get_time_now();
+ total_time += (t1-t0);
+ }
+ std::cout << boost::format(
+ "Difference between paired reads: %f us"
+ ) % (total_time.get_real_secs()/100*1e6) << std::endl;
+
+ //use a timed command to start a stream at a specific time
+ //this is not the right way start streaming at time x,
+ //but it should approximate it within control RTT/2
+ //setup streaming
+ std::cout << std::endl;
+ std::cout << "About to start streaming using timed command:" << std::endl;
+
+ //create a receive streamer
+ uhd::stream_args_t stream_args("fc32"); //complex floats
+ uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
+
+ uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
+ stream_cmd.num_samps = 100;
+ stream_cmd.stream_now = true;
+ const uhd::time_spec_t stream_time = usrp->get_time_now() + uhd::time_spec_t(0.1);
+ usrp->set_command_time(stream_time);
+ usrp->issue_stream_cmd(stream_cmd);
+ usrp->clear_command_time();
+
+ //meta-data will be filled in by recv()
+ uhd::rx_metadata_t md;
+
+ //allocate buffer to receive with samples
+ std::vector<std::complex<float> > buff(stream_cmd.num_samps);
+
+ const size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md);
+ if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
+ throw std::runtime_error(str(boost::format(
+ "Unexpected error code 0x%x"
+ ) % md.error_code));
+ }
+ std::cout << boost::format(
+ "Received packet: %u samples, %u full secs, %f frac secs"
+ ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl;
+ std::cout << boost::format(
+ "Stream time was: %u full secs, %f frac secs"
+ ) % stream_time.get_full_secs() % stream_time.get_frac_secs() << std::endl;
+ std::cout << boost::format(
+ "Difference between stream time and first packet: %f us"
+ ) % ((md.time_spec-stream_time).get_real_secs()/100*1e6) << std::endl;
+
+ //finished
+ std::cout << std::endl << "Done!" << std::endl << std::endl;
+
+ return 0;
+}
diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp
index 6a377fdac..3c5eecd65 100644
--- a/host/examples/tx_waveforms.cpp
+++ b/host/examples/tx_waveforms.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
#include <boost/math/special_functions/round.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
+#include <boost/thread.hpp>
#include <iostream>
#include <complex>
#include <csignal>
@@ -174,6 +175,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
if (vm.count("ant")) usrp->set_tx_antenna(ant, chan);
}
+ boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time
+
//for the const wave, set the wave freq for small samples per period
if (wave_freq == 0 and wave_type == "CONST"){
wave_freq = usrp->get_tx_rate()/2;
diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp
index d1cd5b373..3cfc1e95f 100644
--- a/host/lib/usrp/dboard/db_sbx_common.cpp
+++ b/host/lib/usrp/dboard/db_sbx_common.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -213,8 +213,8 @@ void sbx_xcvr::update_atr(void){
int tx_pga0_iobits = tx_pga0_gain_to_iobits(_tx_gains["PGA0"]);
int rx_lo_lpf_en = (_rx_lo_freq == sbx_enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0;
int tx_lo_lpf_en = (_tx_lo_freq == sbx_enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0;
- int rx_ld_led = get_locked(dboard_iface::UNIT_RX).to_bool() ? 0 : RX_LED_LD;
- int tx_ld_led = get_locked(dboard_iface::UNIT_TX).to_bool() ? 0 : TX_LED_LD;
+ int rx_ld_led = _rx_lo_lock_cache ? 0 : RX_LED_LD;
+ int tx_ld_led = _tx_lo_lock_cache ? 0 : TX_LED_LD;
int rx_ant_led = _rx_ant == "TX/RX" ? RX_LED_RX1RX2 : 0;
int tx_ant_led = _tx_ant == "TX/RX" ? 0 : TX_LED_TXRX;
@@ -283,8 +283,14 @@ void sbx_xcvr::set_tx_ant(const std::string &ant){
**********************************************************************/
double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) {
const double actual = db_actual->set_lo_freq(unit, target_freq);
- if (unit == dboard_iface::UNIT_RX) _rx_lo_freq = actual;
- if (unit == dboard_iface::UNIT_TX) _tx_lo_freq = actual;
+ if (unit == dboard_iface::UNIT_RX){
+ _rx_lo_lock_cache = false;
+ _rx_lo_freq = actual;
+ }
+ if (unit == dboard_iface::UNIT_TX){
+ _tx_lo_lock_cache = false;
+ _tx_lo_freq = actual;
+ }
update_atr();
return actual;
}
@@ -292,6 +298,13 @@ double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) {
sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) {
const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0;
+
+ if (unit == dboard_iface::UNIT_RX) _rx_lo_lock_cache = locked;
+ if (unit == dboard_iface::UNIT_TX) _tx_lo_lock_cache = locked;
+
+ //write the new lock cache setting to atr regs
+ update_atr();
+
return sensor_value_t("LO", locked, "locked", "unlocked");
}
diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp
index 501a7f1fc..2a0e83115 100644
--- a/host/lib/usrp/dboard/db_sbx_common.hpp
+++ b/host/lib/usrp/dboard/db_sbx_common.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -138,6 +138,7 @@ protected:
uhd::dict<std::string, double> _tx_gains, _rx_gains;
double _rx_lo_freq, _tx_lo_freq;
std::string _tx_ant, _rx_ant;
+ bool _rx_lo_lock_cache, _tx_lo_lock_cache;
void set_rx_ant(const std::string &ant);
void set_tx_ant(const std::string &ant);
diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp
index 6e20d5882..040bef12f 100644
--- a/host/lib/usrp/dboard/db_sbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version3.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -75,7 +75,6 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
@@ -83,7 +82,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
- adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
+ adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
/*
* The goal here is to loop though possible R dividers,
@@ -91,7 +90,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
* (frac) dividers.
*
* Calculate the N and F dividers for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* from pg.21
@@ -110,7 +109,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
if (pfd_freq > 25e6) continue;
//ignore fractional part of tuning
- N = int(std::floor(vco_freq/pfd_freq));
+ N = int(std::floor(target_freq/pfd_freq));
//keep N > minimum int divider requirement
if (N < prescaler_to_min_int_div[prescaler]) continue;
@@ -125,7 +124,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
//Fractional-N calculation
MOD = 4095; //max fractional accuracy
- FRAC = int((vco_freq/pfd_freq - N)*MOD);
+ FRAC = int((target_freq/pfd_freq - N)*MOD);
//Reference divide-by-2 for 50% duty cycle
// if R even, move one divide by 2 to to regs.reference_divide_by_2
@@ -135,12 +134,12 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T))));
UHD_LOGV(often)
<< boost::format("SBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("SBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -155,6 +154,9 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp
index c8128d5f4..12bc9b76e 100644
--- a/host/lib/usrp/dboard/db_sbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version4.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -142,8 +142,8 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
UHD_LOGV(often)
<< boost::format("SBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("SBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 42c654e6b..e2efa9a00 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -356,12 +356,27 @@ public:
return true;
}
- void set_command_time(const time_spec_t &, size_t){
- throw uhd::not_implemented_error("Not implemented yet, but we have a very good idea of how to do it.");
+ void set_command_time(const time_spec_t &time_spec, size_t mboard){
+ if (mboard != ALL_MBOARDS){
+ if (not _tree->exists(mb_root(mboard) / "time/cmd")){
+ throw uhd::not_implemented_error("timed command feature not implemented on this hardware");
+ }
+ _tree->access<time_spec_t>(mb_root(mboard) / "time/cmd").set(time_spec);
+ return;
+ }
+ for (size_t m = 0; m < get_num_mboards(); m++){
+ set_command_time(time_spec, m);
+ }
}
- void clear_command_time(size_t){
- throw uhd::not_implemented_error("Not implemented yet, but we have a very good idea of how to do it.");
+ void clear_command_time(size_t mboard){
+ if (mboard != ALL_MBOARDS){
+ _tree->access<time_spec_t>(mb_root(mboard) / "time/cmd").set(time_spec_t(0.0));
+ return;
+ }
+ for (size_t m = 0; m < get_num_mboards(); m++){
+ clear_command_time(m);
+ }
}
void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan){
diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt
index 10f7407b0..da39d9df1 100644
--- a/host/lib/usrp/usrp2/CMakeLists.txt
+++ b/host/lib/usrp/usrp2/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Ettus Research LLC
+# Copyright 2011-2012 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,5 +32,6 @@ IF(ENABLE_USRP2)
${CMAKE_CURRENT_SOURCE_DIR}/io_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/usrp2_iface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/usrp2_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/usrp2_fifo_ctrl.cpp
)
ENDIF(ENABLE_USRP2)
diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp
index 7d3ffefa2..769795aad 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -35,8 +35,9 @@ static const bool enb_test_clk = false;
*/
class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl{
public:
- usrp2_clock_ctrl_impl(usrp2_iface::sptr iface){
+ usrp2_clock_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){
_iface = iface;
+ _spiface = spiface;
clk_regs = usrp2_clk_regs_t(_iface->get_rev());
_ad9510_regs.cp_current_setting = ad9510_regs_t::CP_CURRENT_SETTING_3_0MA;
@@ -331,7 +332,7 @@ private:
*/
void write_reg(boost::uint8_t addr){
boost::uint32_t data = _ad9510_regs.get_write_reg(addr);
- _iface->write_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24);
+ _spiface->write_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24);
}
/*!
@@ -377,7 +378,7 @@ private:
}
usrp2_iface::sptr _iface;
-
+ uhd::spi_iface::sptr _spiface;
usrp2_clk_regs_t clk_regs;
ad9510_regs_t _ad9510_regs;
};
@@ -385,6 +386,6 @@ private:
/***********************************************************************
* Public make function for the ad9510 clock control
**********************************************************************/
-usrp2_clock_ctrl::sptr usrp2_clock_ctrl::make(usrp2_iface::sptr iface){
- return sptr(new usrp2_clock_ctrl_impl(iface));
+usrp2_clock_ctrl::sptr usrp2_clock_ctrl::make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){
+ return sptr(new usrp2_clock_ctrl_impl(iface, spiface));
}
diff --git a/host/lib/usrp/usrp2/clock_ctrl.hpp b/host/lib/usrp/usrp2/clock_ctrl.hpp
index 9ccbc959e..067e1e35d 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.hpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -29,10 +29,11 @@ public:
/*!
* Make a clock config for the ad9510 ic.
- * \param _iface a pointer to the usrp2 interface object
+ * \param iface a pointer to the usrp2 interface object
+ * \param spiface the interface to spi
* \return a new clock control object
*/
- static sptr make(usrp2_iface::sptr iface);
+ static sptr make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface);
/*!
* Get the master clock frequency for the fpga.
diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp
index 06bf83b15..b53c4d9df 100644
--- a/host/lib/usrp/usrp2/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp2/codec_ctrl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -32,8 +32,9 @@ using namespace uhd;
*/
class usrp2_codec_ctrl_impl : public usrp2_codec_ctrl{
public:
- usrp2_codec_ctrl_impl(usrp2_iface::sptr iface){
+ usrp2_codec_ctrl_impl(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){
_iface = iface;
+ _spiface = spiface;
//setup the ad9777 dac
_ad9777_regs.x_1r_2r_mode = ad9777_regs_t::X_1R_2R_MODE_1R;
@@ -189,11 +190,12 @@ private:
ad9777_regs_t _ad9777_regs;
ads62p44_regs_t _ads62p44_regs;
usrp2_iface::sptr _iface;
+ uhd::spi_iface::sptr _spiface;
void send_ad9777_reg(boost::uint8_t addr){
boost::uint16_t reg = _ad9777_regs.get_write_reg(addr);
UHD_LOGV(always) << "send_ad9777_reg: " << std::hex << reg << std::endl;
- _iface->write_spi(
+ _spiface->write_spi(
SPI_SS_AD9777, spi_config_t::EDGE_RISE,
reg, 16
);
@@ -201,7 +203,7 @@ private:
void send_ads62p44_reg(boost::uint8_t addr) {
boost::uint16_t reg = _ads62p44_regs.get_write_reg(addr);
- _iface->write_spi(
+ _spiface->write_spi(
SPI_SS_ADS62P44, spi_config_t::EDGE_FALL,
reg, 16
);
@@ -211,6 +213,6 @@ private:
/***********************************************************************
* Public make function for the usrp2 codec control
**********************************************************************/
-usrp2_codec_ctrl::sptr usrp2_codec_ctrl::make(usrp2_iface::sptr iface){
- return sptr(new usrp2_codec_ctrl_impl(iface));
+usrp2_codec_ctrl::sptr usrp2_codec_ctrl::make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface){
+ return sptr(new usrp2_codec_ctrl_impl(iface, spiface));
}
diff --git a/host/lib/usrp/usrp2/codec_ctrl.hpp b/host/lib/usrp/usrp2/codec_ctrl.hpp
index ca300e2b1..b0d815be2 100644
--- a/host/lib/usrp/usrp2/codec_ctrl.hpp
+++ b/host/lib/usrp/usrp2/codec_ctrl.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -28,10 +28,11 @@ public:
/*!
* Make a codec control for the DAC and ADC.
- * \param _iface a pointer to the usrp2 interface object
+ * \param iface a pointer to the usrp2 interface object
+ * \param spiface the interface to spi
* \return a new codec control object
*/
- static sptr make(usrp2_iface::sptr iface);
+ static sptr make(usrp2_iface::sptr iface, uhd::spi_iface::sptr spiface);
/*!
* Set the modulation mode for the DAC.
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index bc510c8a1..edd9ef242 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
//
#include "gpio_core_200.hpp"
-#include "usrp2_iface.hpp"
+#include <uhd/types/serial.hpp>
#include "clock_ctrl.hpp"
#include "usrp2_regs.hpp" //wishbone address constants
#include <uhd/usrp/dboard_iface.hpp>
@@ -35,7 +35,12 @@ using namespace boost::assign;
class usrp2_dboard_iface : public dboard_iface{
public:
- usrp2_dboard_iface(usrp2_iface::sptr iface, usrp2_clock_ctrl::sptr clock_ctrl);
+ usrp2_dboard_iface(
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
+ usrp2_clock_ctrl::sptr clock_ctrl
+ );
~usrp2_dboard_iface(void);
special_props_t get_special_props(void){
@@ -79,7 +84,8 @@ public:
);
private:
- usrp2_iface::sptr _iface;
+ uhd::i2c_iface::sptr _i2c_iface;
+ uhd::spi_iface::sptr _spi_iface;
usrp2_clock_ctrl::sptr _clock_ctrl;
gpio_core_200::sptr _gpio;
@@ -92,22 +98,28 @@ private:
* Make Function
**********************************************************************/
dboard_iface::sptr make_usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clock_ctrl
){
- return dboard_iface::sptr(new usrp2_dboard_iface(iface, clock_ctrl));
+ return dboard_iface::sptr(new usrp2_dboard_iface(wb_iface, i2c_iface, spi_iface, clock_ctrl));
}
/***********************************************************************
* Structors
**********************************************************************/
usrp2_dboard_iface::usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clock_ctrl
-){
- _iface = iface;
- _clock_ctrl = clock_ctrl;
- _gpio = gpio_core_200::make(_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB);
+):
+ _i2c_iface(i2c_iface),
+ _spi_iface(spi_iface),
+ _clock_ctrl(clock_ctrl)
+{
+ _gpio = gpio_core_200::make(wb_iface, U2_REG_SR_ADDR(SR_GPIO), U2_REG_GPIO_RB);
//reset the aux dacs
_dac_regs[UNIT_RX] = ad5623_regs_t();
@@ -202,7 +214,7 @@ void usrp2_dboard_iface::write_spi(
boost::uint32_t data,
size_t num_bits
){
- _iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);
+ _spi_iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
boost::uint32_t usrp2_dboard_iface::read_write_spi(
@@ -211,18 +223,18 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(
boost::uint32_t data,
size_t num_bits
){
- return _iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);
+ return _spi_iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
/***********************************************************************
* I2C
**********************************************************************/
void usrp2_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){
- return _iface->write_i2c(addr, bytes);
+ return _i2c_iface->write_i2c(addr, bytes);
}
byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){
- return _iface->read_i2c(addr, num_bytes);
+ return _i2c_iface->read_i2c(addr, num_bytes);
}
/***********************************************************************
@@ -233,7 +245,7 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){
(UNIT_RX, SPI_SS_RX_DAC)
(UNIT_TX, SPI_SS_TX_DAC)
;
- _iface->write_spi(
+ _spi_iface->write_spi(
unit_to_spi_dac[unit], spi_config_t::EDGE_FALL,
_dac_regs[unit].get_reg(), 24
);
@@ -281,11 +293,11 @@ double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){
} ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn
//write and read spi
- _iface->write_spi(
+ _spi_iface->write_spi(
unit_to_spi_adc[unit], config,
ad7922_regs.get_reg(), 16
);
- ad7922_regs.set_reg(boost::uint16_t(_iface->read_spi(
+ ad7922_regs.set_reg(boost::uint16_t(_spi_iface->read_spi(
unit_to_spi_adc[unit], config,
ad7922_regs.get_reg(), 16
)));
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 2add74c47..acd5d1f3a 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -30,8 +30,8 @@ extern "C" {
#endif
//fpga and firmware compatibility numbers
-#define USRP2_FPGA_COMPAT_NUM 9
-#define USRP2_FW_COMPAT_NUM 11
+#define USRP2_FPGA_COMPAT_NUM 10
+#define USRP2_FW_COMPAT_NUM 12
#define USRP2_FW_VER_MINOR 2
//used to differentiate control packets over data port
@@ -51,6 +51,7 @@ typedef struct{
#define USRP2_UDP_RX_DSP0_PORT 49156
#define USRP2_UDP_TX_DSP0_PORT 49157
#define USRP2_UDP_RX_DSP1_PORT 49158
+#define USRP2_UDP_FIFO_CRTL_PORT 49159
#define USRP2_UDP_UART_BASE_PORT 49170
#define USRP2_UDP_UART_GPS_PORT 49172
diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp
new file mode 100644
index 000000000..0f652b294
--- /dev/null
+++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.cpp
@@ -0,0 +1,246 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "usrp2_regs.hpp"
+#include <uhd/exception.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include "usrp2_fifo_ctrl.hpp"
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/asio.hpp> //htonl
+#include <boost/format.hpp>
+
+using namespace uhd;
+using namespace uhd::transport;
+
+static const size_t POKE32_CMD = (1 << 8);
+static const size_t PEEK32_CMD = 0;
+static const double ACK_TIMEOUT = 0.5;
+static const double MASSIVE_TIMEOUT = 10.0; //for when we wait on a timed command
+static const boost::uint32_t MAX_SEQS_OUT = 64;
+
+#define SPI_DIV SR_SPI_CORE + 0
+#define SPI_CTRL SR_SPI_CORE + 1
+#define SPI_DATA SR_SPI_CORE + 2
+#define SPI_READBACK 0
+// spi clock rate = master_clock/(div+1)/2 (10MHz in this case)
+#define SPI_DIVIDER 4
+
+class usrp2_fifo_ctrl_impl : public usrp2_fifo_ctrl{
+public:
+
+ usrp2_fifo_ctrl_impl(zero_copy_if::sptr xport):
+ _xport(xport),
+ _seq_out(0),
+ _seq_ack(0),
+ _timeout(ACK_TIMEOUT)
+ {
+ while (_xport->get_recv_buff(0.0)){} //flush
+ this->set_time(uhd::time_spec_t(0.0));
+ this->set_tick_rate(1.0); //something possible but bogus
+ this->init_spi();
+ }
+
+ ~usrp2_fifo_ctrl_impl(void){
+ _timeout = ACK_TIMEOUT; //reset timeout to something small
+ UHD_SAFE_CALL(
+ this->peek32(0); //dummy peek with the purpose of ack'ing all packets
+ )
+ }
+
+ /*******************************************************************
+ * Peek and poke 32 bit implementation
+ ******************************************************************/
+ void poke32(wb_addr_type addr, boost::uint32_t data){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD);
+
+ this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
+ }
+
+ boost::uint32_t peek32(wb_addr_type addr){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ this->send_pkt((addr - READBACK_BASE)/4, 0, PEEK32_CMD);
+
+ return this->wait_for_ack(_seq_out);
+ }
+
+ /*******************************************************************
+ * Peek and poke 16 bit not implemented
+ ******************************************************************/
+ void poke16(wb_addr_type, boost::uint16_t){
+ throw uhd::not_implemented_error("poke16 not implemented in fifo ctrl module");
+ }
+
+ boost::uint16_t peek16(wb_addr_type){
+ throw uhd::not_implemented_error("peek16 not implemented in fifo ctrl module");
+ }
+
+ /*******************************************************************
+ * FIFO controlled SPI implementation
+ ******************************************************************/
+ void init_spi(void){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ this->send_pkt(SPI_DIV, SPI_DIVIDER, POKE32_CMD);
+ this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
+
+ _ctrl_word_cache = 0; // force update first time around
+ }
+
+ boost::uint32_t transact_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits,
+ bool readback
+ ){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ //load control word
+ boost::uint32_t ctrl_word = 0;
+ ctrl_word |= ((which_slave & 0xffffff) << 0);
+ ctrl_word |= ((num_bits & 0x3ff) << 24);
+ if (config.mosi_edge == spi_config_t::EDGE_FALL) ctrl_word |= (1 << 31);
+ if (config.miso_edge == spi_config_t::EDGE_RISE) ctrl_word |= (1 << 30);
+
+ //load data word (must be in upper bits)
+ const boost::uint32_t data_out = data << (32 - num_bits);
+
+ //conditionally send control word
+ if (_ctrl_word_cache != ctrl_word){
+ this->send_pkt(SPI_CTRL, ctrl_word, POKE32_CMD);
+ this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
+ _ctrl_word_cache = ctrl_word;
+ }
+
+ //send data word
+ this->send_pkt(SPI_DATA, data_out, POKE32_CMD);
+ this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
+
+ //conditional readback
+ if (readback){
+ this->send_pkt(SPI_READBACK, 0, PEEK32_CMD);
+ return this->wait_for_ack(_seq_out);
+ }
+
+ return 0;
+ }
+
+ /*******************************************************************
+ * Update methods for time
+ ******************************************************************/
+ void set_time(const uhd::time_spec_t &time){
+ boost::mutex::scoped_lock lock(_mutex);
+ _time = time;
+ _use_time = _time != uhd::time_spec_t(0.0);
+ if (_use_time) _timeout = MASSIVE_TIMEOUT; //permanently sets larger timeout
+ }
+
+ void set_tick_rate(const double rate){
+ boost::mutex::scoped_lock lock(_mutex);
+ _tick_rate = rate;
+ }
+
+private:
+
+ /*******************************************************************
+ * Primary control and interaction private methods
+ ******************************************************************/
+ UHD_INLINE void send_pkt(wb_addr_type addr, boost::uint32_t data, int cmd){
+ managed_send_buffer::sptr buff = _xport->get_send_buff(0.0);
+ if (not buff){
+ throw uhd::runtime_error("fifo ctrl timed out getting a send buffer");
+ }
+ boost::uint32_t *trans = buff->cast<boost::uint32_t *>();
+ trans[0] = htonl(++_seq_out);
+ boost::uint32_t *pkt = trans + 1;
+
+ //load packet info
+ vrt::if_packet_info_t packet_info;
+ packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT;
+ packet_info.num_payload_words32 = 2;
+ packet_info.num_payload_bytes = packet_info.num_payload_words32*sizeof(boost::uint32_t);
+ packet_info.packet_count = _seq_out;
+ packet_info.tsf = _time.to_ticks(_tick_rate);
+ packet_info.sob = false;
+ packet_info.eob = false;
+ packet_info.has_sid = false;
+ packet_info.has_cid = false;
+ packet_info.has_tsi = false;
+ packet_info.has_tsf = _use_time;
+ packet_info.has_tlr = false;
+
+ //load header
+ vrt::if_hdr_pack_be(pkt, packet_info);
+
+ //load payload
+ const boost::uint32_t ctrl_word = (addr & 0xff) | cmd | (_seq_out << 16);
+ pkt[packet_info.num_header_words32+0] = htonl(ctrl_word);
+ pkt[packet_info.num_header_words32+1] = htonl(data);
+
+ //send the buffer over the interface
+ buff->commit(sizeof(boost::uint32_t)*(packet_info.num_packet_words32+1));
+ }
+
+ UHD_INLINE bool wraparound_lt16(const boost::int16_t i0, const boost::int16_t i1){
+ if (i0 == i1) return false;
+ const int s0 = boost::uint16_t(i0) >> 15;
+ const int s1 = boost::uint16_t(i1) >> 15;
+ if (s0 != s1) return boost::int16_t(i1 - i0) > 0;
+ return boost::uint16_t(i0) < boost::uint16_t(i1);
+ }
+
+ UHD_INLINE boost::uint32_t wait_for_ack(const boost::uint16_t seq_to_ack){
+
+ while (wraparound_lt16(_seq_ack, seq_to_ack)){
+ managed_recv_buffer::sptr buff = _xport->get_recv_buff(_timeout);
+ if (not buff){
+ throw uhd::runtime_error("fifo ctrl timed out looking for acks");
+ }
+ const boost::uint32_t *pkt = buff->cast<const boost::uint32_t *>();
+ vrt::if_packet_info_t packet_info;
+ packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
+ vrt::if_hdr_unpack_be(pkt, packet_info);
+ _seq_ack = ntohl(pkt[packet_info.num_header_words32+0]) >> 16;
+ if (_seq_ack == seq_to_ack){
+ return ntohl(pkt[packet_info.num_header_words32+1]);
+ }
+ }
+
+ return 0;
+ }
+
+ zero_copy_if::sptr _xport;
+ boost::mutex _mutex;
+ boost::uint16_t _seq_out;
+ boost::uint16_t _seq_ack;
+ uhd::time_spec_t _time;
+ bool _use_time;
+ double _tick_rate;
+ double _timeout;
+ boost::uint32_t _ctrl_word_cache;
+};
+
+
+usrp2_fifo_ctrl::sptr usrp2_fifo_ctrl::make(zero_copy_if::sptr xport){
+ return sptr(new usrp2_fifo_ctrl_impl(xport));
+}
diff --git a/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp
new file mode 100644
index 000000000..b48d05aa2
--- /dev/null
+++ b/host/lib/usrp/usrp2/usrp2_fifo_ctrl.hpp
@@ -0,0 +1,47 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_USRP2_FIFO_CTRL_HPP
+#define INCLUDED_USRP2_FIFO_CTRL_HPP
+
+#include <uhd/types/time_spec.hpp>
+#include <uhd/types/serial.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "wb_iface.hpp"
+#include <string>
+
+/*!
+ * The usrp2 FIFO control class:
+ * Provide high-speed peek/poke interface.
+ */
+class usrp2_fifo_ctrl : public wb_iface, public uhd::spi_iface{
+public:
+ typedef boost::shared_ptr<usrp2_fifo_ctrl> sptr;
+
+ //! Make a new FIFO control object
+ static sptr make(uhd::transport::zero_copy_if::sptr xport);
+
+ //! Set the command time that will activate
+ virtual void set_time(const uhd::time_spec_t &time) = 0;
+
+ //! Set the tick rate (converting time into ticks)
+ virtual void set_tick_rate(const double rate) = 0;
+};
+
+#endif /* INCLUDED_USRP2_FIFO_CTRL_HPP */
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index e6e8ca675..55c5e7dac 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -391,8 +391,15 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
_mbc[mb].tx_dsp_xport = make_xport(
addr, BOOST_STRINGIZE(USRP2_UDP_TX_DSP0_PORT), device_args_i, "send"
);
+ UHD_LOG << "Making transport for Control..." << std::endl;
+ _mbc[mb].fifo_ctrl_xport = make_xport(
+ addr, BOOST_STRINGIZE(USRP2_UDP_FIFO_CRTL_PORT), device_addr_t(), ""
+ );
//set the filter on the router to take dsp data from this port
- _mbc[mb].iface->poke32(U2_REG_ROUTER_CTRL_PORTS, USRP2_UDP_TX_DSP0_PORT);
+ _mbc[mb].iface->poke32(U2_REG_ROUTER_CTRL_PORTS, (USRP2_UDP_FIFO_CRTL_PORT << 16) | USRP2_UDP_TX_DSP0_PORT);
+
+ //create the fifo control interface for high speed register access
+ _mbc[mb].fifo_ctrl = usrp2_fifo_ctrl::make(_mbc[mb].fifo_ctrl_xport);
////////////////////////////////////////////////////////////////
// setup the mboard eeprom
@@ -404,7 +411,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
////////////////////////////////////////////////////////////////
// create clock control objects
////////////////////////////////////////////////////////////////
- _mbc[mb].clock = usrp2_clock_ctrl::make(_mbc[mb].iface);
+ _mbc[mb].clock = usrp2_clock_ctrl::make(_mbc[mb].iface, _mbc[mb].fifo_ctrl/*spi*/);
_tree->create<double>(mb_path / "tick_rate")
.publish(boost::bind(&usrp2_clock_ctrl::get_master_clock_rate, _mbc[mb].clock))
.subscribe(boost::bind(&usrp2_impl::update_tick_rate, this, _1));
@@ -416,7 +423,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
const fs_path tx_codec_path = mb_path / "tx_codecs/A";
_tree->create<int>(rx_codec_path / "gains"); //phony property so this dir exists
_tree->create<int>(tx_codec_path / "gains"); //phony property so this dir exists
- _mbc[mb].codec = usrp2_codec_ctrl::make(_mbc[mb].iface);
+ _mbc[mb].codec = usrp2_codec_ctrl::make(_mbc[mb].iface, _mbc[mb].fifo_ctrl/*spi*/);
switch(_mbc[mb].iface->get_rev()){
case usrp2_iface::USRP_N200:
case usrp2_iface::USRP_N210:
@@ -469,10 +476,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create frontend control objects
////////////////////////////////////////////////////////////////
_mbc[mb].rx_fe = rx_frontend_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_FRONT)
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_FRONT)
);
_mbc[mb].tx_fe = tx_frontend_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_FRONT)
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_FRONT)
);
_tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec")
@@ -503,10 +510,10 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create rx dsp control objects
////////////////////////////////////////////////////////////////
_mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), USRP2_RX_SID_BASE + 0, true
));
_mbc[mb].rx_dsps.push_back(rx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), USRP2_RX_SID_BASE + 1, true
));
for (size_t dspno = 0; dspno < _mbc[mb].rx_dsps.size(); dspno++){
_mbc[mb].rx_dsps[dspno]->set_link_rate(USRP2_LINK_RATE_BPS);
@@ -531,7 +538,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
// create tx dsp control objects
////////////////////////////////////////////////////////////////
_mbc[mb].tx_dsp = tx_dsp_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID
);
_mbc[mb].tx_dsp->set_link_rate(USRP2_LINK_RATE_BPS);
_tree->access<double>(mb_path / "tick_rate")
@@ -565,7 +572,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
time64_rb_bases.rb_hi_pps = U2_REG_TIME64_HI_RB_PPS;
time64_rb_bases.rb_lo_pps = U2_REG_TIME64_LO_RB_PPS;
_mbc[mb].time64 = time64_core_200::make(
- _mbc[mb].iface, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles
+ _mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_TIME64), time64_rb_bases, mimo_clock_sync_delay_cycles
);
_tree->access<double>(mb_path / "tick_rate")
.subscribe(boost::bind(&time64_core_200::set_tick_rate, _mbc[mb].time64, _1));
@@ -585,11 +592,23 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
.subscribe(boost::bind(&usrp2_impl::update_clock_source, this, mb, _1));
static const std::vector<std::string> clock_sources = boost::assign::list_of("internal")("external")("mimo");
_tree->create<std::vector<std::string> >(mb_path / "clock_source/options").set(clock_sources);
+ //plug timed commands into tree here
+ switch(_mbc[mb].iface->get_rev()){
+ case usrp2_iface::USRP_N200:
+ case usrp2_iface::USRP_N210:
+ case usrp2_iface::USRP_N200_R4:
+ case usrp2_iface::USRP_N210_R4:
+ _tree->create<time_spec_t>(mb_path / "time/cmd")
+ .subscribe(boost::bind(&usrp2_fifo_ctrl::set_time, _mbc[mb].fifo_ctrl, _1));
+ default: break; //otherwise, do not register
+ }
+ _tree->access<double>(mb_path / "tick_rate")
+ .subscribe(boost::bind(&usrp2_fifo_ctrl::set_tick_rate, _mbc[mb].fifo_ctrl, _1));
////////////////////////////////////////////////////////////////////
// create user-defined control objects
////////////////////////////////////////////////////////////////////
- _mbc[mb].user = user_settings_core_200::make(_mbc[mb].iface, U2_REG_SR_ADDR(SR_USER_REGS));
+ _mbc[mb].user = user_settings_core_200::make(_mbc[mb].fifo_ctrl, U2_REG_SR_ADDR(SR_USER_REGS));
_tree->create<user_settings_core_200::user_reg_t>(mb_path / "user/regs")
.subscribe(boost::bind(&user_settings_core_200::set_reg, _mbc[mb].user, _1));
@@ -615,7 +634,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
.subscribe(boost::bind(&usrp2_impl::set_db_eeprom, this, mb, "gdb", _1));
//create a new dboard interface and manager
- _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].iface, _mbc[mb].clock);
+ _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].fifo_ctrl/*wb*/, _mbc[mb].iface/*i2c*/, _mbc[mb].fifo_ctrl/*spi*/, _mbc[mb].clock);
_tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_mbc[mb].dboard_iface);
_mbc[mb].dboard_manager = dboard_manager::make(
rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
@@ -685,12 +704,12 @@ void usrp2_impl::set_db_eeprom(const std::string &mb, const std::string &type, c
}
sensor_value_t usrp2_impl::get_mimo_locked(const std::string &mb){
- const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0;
+ const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<10)) != 0;
return sensor_value_t("MIMO", lock, "locked", "unlocked");
}
sensor_value_t usrp2_impl::get_ref_locked(const std::string &mb){
- const bool lock = (_mbc[mb].iface->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0;
+ const bool lock = (_mbc[mb].fifo_ctrl->peek32(U2_REG_IRQ_RB) & (1<<11)) != 0;
return sensor_value_t("Ref", lock, "locked", "unlocked");
}
@@ -729,13 +748,14 @@ meta_range_t usrp2_impl::get_tx_dsp_freq_range(const std::string &mb){
}
void usrp2_impl::update_clock_source(const std::string &mb, const std::string &source){
+ //NOTICE: U2_REG_MISC_CTRL_CLOCK is on the wb clock, and cannot be set from fifo_ctrl
//clock source ref 10mhz
switch(_mbc[mb].iface->get_rev()){
case usrp2_iface::USRP_N200:
case usrp2_iface::USRP_N210:
case usrp2_iface::USRP_N200_R4:
case usrp2_iface::USRP_N210_R4:
- if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12);
+ if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x12);
else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
else throw uhd::value_error("unhandled clock configuration reference source: " + source);
@@ -744,7 +764,7 @@ void usrp2_impl::update_clock_source(const std::string &mb, const std::string &s
case usrp2_iface::USRP2_REV3:
case usrp2_iface::USRP2_REV4:
- if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10);
+ if (source == "internal") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10);
else if (source == "external") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C);
else if (source == "mimo") _mbc[mb].iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15);
else throw uhd::value_error("unhandled clock configuration reference source: " + source);
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 6053c3890..3d2fbf14f 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -18,7 +18,9 @@
#ifndef INCLUDED_USRP2_IMPL_HPP
#define INCLUDED_USRP2_IMPL_HPP
+#include "gpio_core_200.hpp"
#include "usrp2_iface.hpp"
+#include "usrp2_fifo_ctrl.hpp"
#include "clock_ctrl.hpp"
#include "codec_ctrl.hpp"
#include "rx_frontend_core_200.hpp"
@@ -52,14 +54,11 @@ static const size_t USRP2_SRAM_BYTES = size_t(1 << 20);
static const boost::uint32_t USRP2_TX_ASYNC_SID = 2;
static const boost::uint32_t USRP2_RX_SID_BASE = 3;
-/*!
- * Make a usrp2 dboard interface.
- * \param iface the usrp2 interface object
- * \param clk_ctrl the clock control object
- * \return a sptr to a new dboard interface
- */
+//! Make a usrp2 dboard interface.
uhd::usrp::dboard_iface::sptr make_usrp2_dboard_iface(
- usrp2_iface::sptr iface,
+ wb_iface::sptr wb_iface,
+ uhd::i2c_iface::sptr i2c_iface,
+ uhd::spi_iface::sptr spi_iface,
usrp2_clock_ctrl::sptr clk_ctrl
);
@@ -82,6 +81,7 @@ private:
uhd::property_tree::sptr _tree;
struct mb_container_type{
usrp2_iface::sptr iface;
+ usrp2_fifo_ctrl::sptr fifo_ctrl;
usrp2_clock_ctrl::sptr clock;
usrp2_codec_ctrl::sptr codec;
uhd::gps_ctrl::sptr gps;
@@ -95,6 +95,7 @@ private:
user_settings_core_200::sptr user;
std::vector<uhd::transport::zero_copy_if::sptr> rx_dsp_xports;
uhd::transport::zero_copy_if::sptr tx_dsp_xport;
+ uhd::transport::zero_copy_if::sptr fifo_ctrl_xport;
uhd::usrp::dboard_manager::sptr dboard_manager;
uhd::usrp::dboard_iface::sptr dboard_iface;
size_t rx_chan_occ, tx_chan_occ;
diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp
index e14798ecb..7fe83e709 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.hpp
@@ -36,10 +36,10 @@
// Setting register offsets
////////////////////////////////////////////////////////////////////////
#define SR_MISC 0 // 7 regs
-#define SR_SIMTIMER 8 // 2
+#define SR_USER_REGS 8 // 2
#define SR_TIME64 10 // 6
#define SR_BUF_POOL 16 // 4
-#define SR_USER_REGS 20 // 2
+#define SR_SPI_CORE 20 // 3
#define SR_RX_FRONT 24 // 5
#define SR_RX_CTRL0 32 // 9
#define SR_RX_DSP0 48 // 7