diff options
44 files changed, 2152 insertions, 651 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 55c9f81f0..27eb345a7 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 3c9a3880a..151a7cdf0 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -27,6 +27,7 @@ SET(example_sources rx_timed_samples.cpp test_messages.cpp test_pps_input.cpp + test_timed_commands.cpp tx_bursts.cpp tx_samples_from_file.cpp tx_timed_samples.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 |