summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Foster <nick@nerdnetworks.org>2010-08-10 17:02:47 -0700
committerNick Foster <nick@nerdnetworks.org>2010-08-10 17:02:47 -0700
commit663808e847c4970551c6c8127c2c5d816e2a2014 (patch)
tree12183a2d7ea5434880dccfa414d8a378ae134abc
parent90a5d84a18aaa338092e572ff257aab1fdcc8e6b (diff)
parent9e419c7b7f35062ceb2ed4e508cadb163067593f (diff)
downloaduhd-663808e847c4970551c6c8127c2c5d816e2a2014.tar.gz
uhd-663808e847c4970551c6c8127c2c5d816e2a2014.tar.bz2
uhd-663808e847c4970551c6c8127c2c5d816e2a2014.zip
Merge branch 'master' into usrp2p
this was the merge from hell Conflicts: firmware/microblaze/Makefile.am firmware/microblaze/bootstrap firmware/microblaze/configure.ac firmware/microblaze/lib/Makefile.inc host/lib/CMakeLists.txt host/lib/usrp/mimo_usrp.cpp host/lib/usrp/simple_usrp.cpp host/lib/usrp/usrp2/clock_ctrl.cpp host/lib/usrp/usrp2/codec_impl.cpp host/lib/usrp/usrp2/dboard_impl.cpp host/lib/usrp/usrp2/mboard_impl.cpp host/lib/usrp/usrp2/usrp2_iface.hpp host/lib/usrp/usrp2/usrp2_impl.hpp host/lib/usrp/usrp2/usrp2_regs.hpp host/test/CMakeLists.txt
-rw-r--r--firmware/microblaze/Makefile.am1
-rw-r--r--firmware/microblaze/apps/burnrev40.c162
-rw-r--r--firmware/microblaze/apps/txrx_uhd.c11
l---------firmware/microblaze/config.guess1
l---------firmware/microblaze/config.sub1
-rw-r--r--fpga/usrp2/control_lib/Makefile.srcs1
-rw-r--r--fpga/usrp2/control_lib/ram_harvard.v69
-rw-r--r--fpga/usrp2/control_lib/ram_loader.v460
-rw-r--r--fpga/usrp2/fifo/Makefile.srcs2
-rw-r--r--fpga/usrp2/fifo/fifo36_demux.v50
-rw-r--r--fpga/usrp2/fifo/fifo36_mux.v57
-rw-r--r--fpga/usrp2/fifo/fifo_new_tb.vcd5506
-rw-r--r--fpga/usrp2/fifo/fifo_tb.v25
-rw-r--r--fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_bpcu.v5
-rw-r--r--fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_core_BE.v27
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_tx.v4
-rw-r--r--fpga/usrp2/top/Makefile.common2
-rwxr-xr-x[-rw-r--r--]fpga/usrp2/top/u2_rev3/u2_core.v50
-rw-r--r--fpga/usrp2/top/u2_rev3/u2_core_udp.v126
-rw-r--r--fpga/usrp2/udp/prot_eng_tx.v19
-rw-r--r--fpga/usrp2/vrt/Makefile.srcs2
-rw-r--r--fpga/usrp2/vrt/gen_context_pkt.v72
-rwxr-xr-xfpga/usrp2/vrt/vita_rx.build2
-rw-r--r--fpga/usrp2/vrt/vita_rx_control.v5
-rw-r--r--fpga/usrp2/vrt/vita_rx_framer.v47
-rw-r--r--fpga/usrp2/vrt/vita_rx_tb.v11
-rw-r--r--fpga/usrp2/vrt/vita_tx_chain.v71
-rw-r--r--fpga/usrp2/vrt/vita_tx_control.v115
-rw-r--r--fpga/usrp2/vrt/vita_tx_deframer.v32
-rw-r--r--host/README1
-rw-r--r--host/docs/dboards.rst58
-rw-r--r--host/docs/usrp2.rst4
-rw-r--r--host/include/uhd/device.hpp7
-rw-r--r--host/include/uhd/usrp/CMakeLists.txt1
-rw-r--r--host/include/uhd/usrp/dboard_iface.hpp7
-rw-r--r--host/include/uhd/usrp/dboard_props.hpp1
-rw-r--r--host/include/uhd/usrp/mboard_props.hpp2
-rw-r--r--host/include/uhd/usrp/mimo_usrp.hpp7
-rw-r--r--host/include/uhd/usrp/simple_usrp.hpp7
-rw-r--r--host/include/uhd/usrp/subdev_spec.hpp95
-rw-r--r--host/include/uhd/utils/CMakeLists.txt1
-rw-r--r--host/include/uhd/utils/algorithm.hpp25
-rw-r--r--host/include/uhd/utils/warning.hpp34
-rw-r--r--host/lib/CMakeLists.txt78
-rw-r--r--host/lib/constants.hpp.in28
-rw-r--r--host/lib/ic_reg_maps/CMakeLists.txt5
-rw-r--r--host/lib/ic_reg_maps/common.py4
-rw-r--r--host/lib/ic_reg_maps/gen_max2118_regs.py126
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp12
-rw-r--r--host/lib/transport/zero_copy.cpp6
-rw-r--r--host/lib/types.cpp9
-rw-r--r--host/lib/usrp/CMakeLists.txt4
-rw-r--r--host/lib/usrp/dboard/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/db_dbsrx.cpp610
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp33
-rw-r--r--host/lib/usrp/mimo_usrp.cpp189
-rw-r--r--host/lib/usrp/simple_usrp.cpp158
-rw-r--r--host/lib/usrp/subdev_spec.cpp77
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp6
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp2
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp32
-rw-r--r--host/lib/usrp/usrp2/fw_common.h6
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp10
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp49
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp24
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp2
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp4
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.cpp1
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.hpp1
-rw-r--r--host/lib/utils/CMakeLists.txt87
-rw-r--r--host/lib/utils/assert.cpp24
-rw-r--r--host/lib/utils/gain_group.cpp149
-rw-r--r--host/lib/utils/load_modules.cpp (renamed from host/lib/load_modules.cpp)55
-rw-r--r--host/lib/utils/paths.cpp103
-rw-r--r--host/lib/utils/props.cpp (renamed from host/lib/utils.cpp)24
-rw-r--r--host/lib/utils/thread_priority.cpp (renamed from host/lib/thread_priority.cpp)0
-rw-r--r--host/lib/utils/warning.cpp36
-rw-r--r--host/lib/version.cpp (renamed from host/lib/version.cpp.in)3
-rw-r--r--host/test/CMakeLists.txt2
-rw-r--r--host/test/addr_test.cpp2
-rw-r--r--host/test/subdev_spec_test.cpp45
-rw-r--r--host/test/warning_test.cpp29
-rwxr-xr-xhost/utils/usrp2_card_burner.py40
-rwxr-xr-xhost/utils/usrp2_card_burner_gui.py4
-rw-r--r--images/.gitignore2
-rw-r--r--images/CMakeLists.txt42
-rw-r--r--images/Makefile86
-rw-r--r--images/README20
88 files changed, 2991 insertions, 6425 deletions
diff --git a/firmware/microblaze/Makefile.am b/firmware/microblaze/Makefile.am
index ffc59192d..52fa649c2 100644
--- a/firmware/microblaze/Makefile.am
+++ b/firmware/microblaze/Makefile.am
@@ -26,3 +26,4 @@ SUBDIRS = \
usrp2 \
usrp2p \
usrp2p/bootloader
+
diff --git a/firmware/microblaze/apps/burnrev40.c b/firmware/microblaze/apps/burnrev40.c
deleted file mode 100644
index 362270961..000000000
--- a/firmware/microblaze/apps/burnrev40.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2007,2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "u2_init.h"
-#include "memory_map.h"
-#include "spi.h"
-#include "hal_io.h"
-#include "buffer_pool.h"
-#include "pic.h"
-#include <stdbool.h>
-#include "ethernet.h"
-#include "nonstdio.h"
-#include "usrp2_eth_packet.h"
-#include "dbsm.h"
-#include "app_common_v2.h"
-#include "memcpy_wa.h"
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <i2c.h>
-#include <usrp2_i2c_addr.h>
-#include <clocks.h>
-#include "sd.h"
-#include "mdelay.h"
-
-#define HW_REV_MAJOR 4
-#define HW_REV_MINOR 0
-
-int test_ram()
-{
- int i,j,k;
- output_regs->ram_page = 1<<10;
-
- extram[0] = 0xDEADBEEF;
- extram[1] = 0xF00D1234;
- extram[7] = 0x76543210;
-
- output_regs->ram_page = 2<<10;
- extram[7] = 0x55555555;
- extram[1] = 0xaaaaaaaa;
- extram[0] = 0xeeeeeeee;
-
- output_regs->ram_page = 1<<10;
-
- i = extram[0];
- k = extram[1];
- j = extram[7];
-
- if((i != 0xDEADBEEF)||(j!=0x76543210)||(k!=0xF00D1234)) {
- puts("RAM FAIL1!\n");
- puthex32_nl(i);
- puthex32_nl(j);
- puthex32_nl(k);
- return 0;
- }
-
- output_regs->ram_page = 2<<10;
-
- j = extram[7];
- k = extram[1];
- i = extram[0];
-
- if((i != 0xeeeeeeee)||(j!=0x55555555)||(k!=0xaaaaaaaa)) {
- puts("RAM FAIL2!\n");
- puthex32_nl(i);
- puthex32_nl(j);
- puthex32_nl(k);
- return 0;
- }
- return 1;
-}
-
-int test_sd()
-{
- int i = sd_init();
- if(i==0) {
- puts("FAILED INIT of Card\n");
- return 0;
- }
-
- unsigned char buf[512];
- i = sd_read_block(2048,buf);
- if(i == 0) {
- puts("READ Command Rejected\n");
- return 0;
- }
- if((buf[0]==0xb8)&&(buf[1]==0x08)&&(buf[2]==0x00)&&(buf[3]==0x50))
- ;
- else {
- puts("Read bad data from SD Card\n");
- return 0;
- }
- return 1;
-}
-
-int
-main(void)
-{
- u2_init();
-
- putstr("\nFactory Test, Board Rev 4.0\n");
-
- bool ok = true;
- unsigned char maj = HW_REV_MAJOR;
- unsigned char min = HW_REV_MINOR;
- ok = eeprom_write(I2C_ADDR_MBOARD, MBOARD_REV_MSB, &maj, 1);
- ok &= eeprom_write(I2C_ADDR_MBOARD, MBOARD_REV_LSB, &min, 1);
-
- putstr("\nset_hw_rev\n");
- if (ok)
- printf("OK: set h/w rev to %d.%d\n", HW_REV_MAJOR, HW_REV_MINOR);
- else {
- printf("FAILED to set h/w rev to %d.%d\n", HW_REV_MAJOR, HW_REV_MINOR);
- hal_finish();
- return 0;
- }
-
- if(test_sd())
- puts("SD OK\n");
- else {
- puts("SD FAIL\n");
- //hal_finish();
- //return 0;
- }
- if(test_ram())
- puts("RAM OK\n");
- else {
- puts("RAM FAIL\n");
- hal_finish();
- return 0;
- }
-
- print_mac_addr(ethernet_mac_addr()->addr);
- newline();
-
- clocks_mimo_config(MC_WE_LOCK_TO_SMA);
-
- while (!clocks_lock_detect()) {
- puts("No Lock");
- mdelay(1000);
- }
- puts("Clock Locked\n");
-
-}
diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c
index 092d216aa..f0a9702be 100644
--- a/firmware/microblaze/apps/txrx_uhd.c
+++ b/firmware/microblaze/apps/txrx_uhd.c
@@ -181,9 +181,9 @@ void handle_udp_ctrl_packet(
uint32_t ctrl_data_in_id = ctrl_data_in->id;
//ensure that the protocol versions match
- if (payload_len >= sizeof(uint32_t) && ctrl_data_in->proto_ver != USRP2_PROTO_VERSION){
- printf("!Error in control packet handler: Expected protocol version %d, but got %d\n",
- USRP2_PROTO_VERSION, ctrl_data_in->proto_ver
+ if (payload_len >= sizeof(uint32_t) && ctrl_data_in->proto_ver != USRP2_FW_COMPAT_NUM){
+ printf("!Error in control packet handler: Expected compatibility number %d, but got %d\n",
+ USRP2_FW_COMPAT_NUM, ctrl_data_in->proto_ver
);
ctrl_data_in_id = USRP2_CTRL_ID_WAZZUP_BRO;
}
@@ -198,7 +198,7 @@ void handle_udp_ctrl_packet(
//setup the output data
usrp2_ctrl_data_t ctrl_data_out = {
- .proto_ver = USRP2_PROTO_VERSION,
+ .proto_ver = USRP2_FW_COMPAT_NUM,
.id=USRP2_CTRL_ID_HUH_WHAT,
.seq=ctrl_data_in->seq
};
@@ -441,7 +441,8 @@ main(void)
print_mac_addr(ethernet_mac_addr()->addr);
newline();
print_ip_addr(get_ip_addr()); newline();
- printf("Control protocol version: %d\n", USRP2_PROTO_VERSION);
+ printf("FPGA compatibility number: %d\n", USRP2_FPGA_COMPAT_NUM);
+ printf("Firmware compatibility number: %d\n", USRP2_FW_COMPAT_NUM);
ethernet_register_link_changed_callback(link_changed_callback);
ethernet_init();
diff --git a/firmware/microblaze/config.guess b/firmware/microblaze/config.guess
deleted file mode 120000
index 405bc3235..000000000
--- a/firmware/microblaze/config.guess
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/automake-1.11/config.guess \ No newline at end of file
diff --git a/firmware/microblaze/config.sub b/firmware/microblaze/config.sub
deleted file mode 120000
index 4d47fbcbc..000000000
--- a/firmware/microblaze/config.sub
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/automake-1.11/config.sub \ No newline at end of file
diff --git a/fpga/usrp2/control_lib/Makefile.srcs b/fpga/usrp2/control_lib/Makefile.srcs
index 5e2a96a53..bc8e4d5bc 100644
--- a/fpga/usrp2/control_lib/Makefile.srcs
+++ b/fpga/usrp2/control_lib/Makefile.srcs
@@ -20,6 +20,7 @@ mux8.v \
nsgpio.v \
ram_2port.v \
ram_harv_cache.v \
+ram_harvard.v \
ram_loader.v \
setting_reg.v \
settings_bus.v \
diff --git a/fpga/usrp2/control_lib/ram_harvard.v b/fpga/usrp2/control_lib/ram_harvard.v
new file mode 100644
index 000000000..948f9b36f
--- /dev/null
+++ b/fpga/usrp2/control_lib/ram_harvard.v
@@ -0,0 +1,69 @@
+
+
+// Dual ported, Harvard architecture, cached ram
+
+module ram_harvard
+ #(parameter AWIDTH=15,
+ parameter RAM_SIZE=16384,
+ parameter ICWIDTH=6,
+ parameter DCWIDTH=6)
+
+ (input wb_clk_i,
+ input wb_rst_i,
+ // Firmware download port.
+ input [AWIDTH-1:0] ram_loader_adr_i,
+ input [31:0] ram_loader_dat_i,
+ input [3:0] ram_loader_sel_i,
+ input ram_loader_stb_i,
+ input ram_loader_we_i,
+ input ram_loader_done_i,
+ // Instruction fetch port.
+ input [AWIDTH-1:0] if_adr,
+ output [31:0] if_data,
+ // Data access port.
+ input [AWIDTH-1:0] dwb_adr_i,
+ input [31:0] dwb_dat_i,
+ output [31:0] dwb_dat_o,
+ input dwb_we_i,
+ output dwb_ack_o,
+ input dwb_stb_i,
+ input [3:0] dwb_sel_i,
+
+ input flush_icache );
+
+ reg ack_d1;
+ reg stb_d1;
+
+ dpram32 #(.AWIDTH(AWIDTH),.RAM_SIZE(RAM_SIZE))
+ sys_ram
+ (.clk(wb_clk_i),
+ .adr1_i(ram_loader_done_i ? if_adr : ram_loader_adr_i),
+ .dat1_i(ram_loader_dat_i),
+ .dat1_o(if_data),
+ .we1_i(ram_loader_done_i ? 1'b0 : ram_loader_we_i),
+ .en1_i(ram_loader_done_i ? 1'b1 : ram_loader_stb_i),
+ //.sel1_i(ram_loader_done_i ? 4'hF : ram_loader_sel_i),
+ .sel1_i(ram_loader_sel_i), // Sel is only for writes anyway
+ .adr2_i(dwb_adr_i),
+ .dat2_i(dwb_dat_i),
+ .dat2_o(dwb_dat_o),
+ .we2_i(dwb_we_i),
+ .en2_i(dwb_stb_i),
+ .sel2_i(dwb_sel_i)
+ );
+
+ assign dwb_ack_o = dwb_stb_i & (dwb_we_i | (stb_d1 & ~ack_d1));
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ ack_d1 <= 1'b0;
+ else
+ ack_d1 <= dwb_ack_o;
+
+ always @(posedge wb_clk_i)
+ if(wb_rst_i)
+ stb_d1 <= 0;
+ else
+ stb_d1 <= dwb_stb_i;
+
+endmodule // ram_harvard
diff --git a/fpga/usrp2/control_lib/ram_loader.v b/fpga/usrp2/control_lib/ram_loader.v
index cb67de739..c53ea7aa7 100644
--- a/fpga/usrp2/control_lib/ram_loader.v
+++ b/fpga/usrp2/control_lib/ram_loader.v
@@ -1,225 +1,261 @@
+module ram_loader
+ #(parameter AWIDTH=16, RAM_SIZE=16384)
+ (
+ // Wishbone I/F and clock domain
+ input wb_clk,
+ input dsp_clk,
+ input ram_loader_rst,
+ output wire [31:0] wb_dat,
+ output wire [AWIDTH-1:0] wb_adr,
+ output wb_stb,
+ output reg [3:0] wb_sel,
+ output wb_we,
+ output reg ram_loader_done,
+ // CPLD signals and clock domain
+ input cpld_clk,
+ input cpld_din,
+ output reg cpld_start,
+ output reg cpld_mode,
+ output reg cpld_done,
+ input cpld_detached
+ );
-// Adapted from VHDL code in spi_boot by Arnim Legauer
-// Added a full wishbone master interface (32-bit)
-
-module ram_loader #(parameter AWIDTH=16, RAM_SIZE=16384)
- (input clk_i, input rst_i,
- // CPLD Interface
- input cfg_clk_i, input cfg_data_i,
- output start_o, output mode_o, output done_o,
- input detached_i,
- // Wishbone interface
- output wire [31:0] wb_dat_o,
- output reg [AWIDTH-1:0] wb_adr_o,
- output wb_stb_o,
- output wb_cyc_o,
- output reg [3:0] wb_sel_o,
- output reg wb_we_o,
- input wb_ack_i,
- output ram_loader_done_o);
+ localparam S0 = 0;
+ localparam S1 = 1;
+ localparam S2 = 2;
+ localparam S3 = 3;
+ localparam S4 = 4;
+ localparam S5 = 5;
+ localparam S6 = 6;
+ localparam RESET = 7;
- // FSM to control start signal, clocked on main clock
- localparam FSM1_WAIT_DETACH = 2'b00;
- localparam FSM1_CHECK_NO_DONE = 2'b01;
- localparam FSM1_WAIT_DONE = 2'b10;
-
- reg [1:0] start_fsm_q, start_fsm_s;
- reg start_q, enable_q, start_s, enable_s;
- reg done_q, done_s;
+ localparam WB_IDLE = 0;
+ localparam WB_WRITE = 1;
+
+
+ reg [AWIDTH+2:0] count; // 3 LSB's count bits in, the MSB's generate the Wishbone address
+ reg [6:0] shift_reg;
+ reg [7:0] data_reg;
+ reg sampled_clk;
+ reg sampled_clk_meta;
+ reg sampled_din;
+ reg inc_count;
+ reg load_data_reg;
+ reg shift;
+ reg wb_state, wb_next_state;
+ reg [2:0] state, next_state;
+
+ //
+ // CPLD clock doesn't free run and is approximately 12.5MHz.
+ // Use 50MHz Wishbone clock to sample it as a signal and avoid having
+ // an extra clock domain for no reason.
+ //
+
+ always @(posedge dsp_clk or posedge ram_loader_rst)
+ if (ram_loader_rst)
+ begin
+ sampled_clk_meta <= 1'b0;
+ sampled_clk <= 1'b0;
+ sampled_din <= 1'b0;
+ count <= 'h7FFF8; // Initialize so that address will be 0 when first byte fully received.
+ data_reg <= 0;
+ shift_reg <= 0;
+ end
+ else
+ begin
+ sampled_clk_meta <= cpld_clk;
+ sampled_clk <= sampled_clk_meta;
+ sampled_din <= cpld_din;
+ if (inc_count)
+ count <= count + 1'b1;
+ if (load_data_reg)
+ data_reg <= {shift_reg,sampled_din};
+ if (shift)
+ shift_reg <= {shift_reg[5:0],sampled_din};
+ end // else: !if(ram_loader_rst)
- always @(posedge clk_i or posedge rst_i)
- if(rst_i)
- begin
- start_fsm_q <= FSM1_WAIT_DETACH;
- start_q <= 1'b0;
- enable_q <= 1'b0;
- end
+
+ always @(posedge dsp_clk or posedge ram_loader_rst)
+ if (ram_loader_rst)
+ state <= RESET;
else
- begin
- start_fsm_q <= start_fsm_s;
- enable_q <= enable_s;
- start_q <= start_s;
- end // else: !if(rst_i)
-
+ state <= next_state;
+
+
always @*
- case(start_fsm_q)
- FSM1_WAIT_DETACH:
- if(detached_i == 1'b1)
- begin
- start_fsm_s <= FSM1_CHECK_NO_DONE;
- enable_s <= 1'b1;
- start_s <= 1'b1;
- end
- else
- begin
- start_fsm_s <= FSM1_WAIT_DETACH;
- enable_s <= enable_q;
- start_s <= start_q;
- end // else: !if(detached_i == 1'b1)
- FSM1_CHECK_NO_DONE:
- if(~done_q)
- begin
- start_fsm_s <= FSM1_WAIT_DONE;
- enable_s <= enable_q;
- start_s <= start_q;
- end
- else
- begin
- start_fsm_s <= FSM1_CHECK_NO_DONE;
- enable_s <= enable_q;
- start_s <= start_q;
- end // else: !if(~done_q)
- FSM1_WAIT_DONE:
- if(done_q)
- begin
- start_fsm_s <= FSM1_WAIT_DETACH;
- enable_s <= 1'b0;
- start_s <= 1'b0;
- end
- else
- begin
- start_fsm_s <= FSM1_WAIT_DONE;
- enable_s <= enable_q;
- start_s <= start_q;
- end // else: !if(done_q)
- default:
- begin
- start_fsm_s <= FSM1_WAIT_DETACH;
- enable_s <= enable_q;
- start_s <= start_q;
- end // else: !if(done_q)
- endcase // case(start_fsm_q)
-
- // FSM running on data clock
-
- localparam FSM2_IDLE = 3'b000;
- localparam FSM2_WE_ON = 3'b001;
- localparam FSM2_WE_OFF = 3'b010;
- localparam FSM2_INC_ADDR1 = 3'b011;
- localparam FSM2_INC_ADDR2 = 3'b100;
- localparam FSM2_FINISHED = 3'b101;
-
- reg [AWIDTH-1:0] addr_q;
- reg [7:0] shift_dat_q, ser_dat_q;
- reg [2:0] bit_q, fsm_q, fsm_s;
- reg bit_ovfl_q, ram_we_s, ram_we_q, mode_q, mode_s, inc_addr_s;
-
- always @(posedge cfg_clk_i or posedge rst_i)
- if(rst_i)
- begin
- addr_q <= 0;
- shift_dat_q <= 8'd0;
- ser_dat_q <= 8'd0;
- bit_q <= 3'd0;
- bit_ovfl_q <= 1'b0;
- fsm_q <= FSM2_IDLE;
- ram_we_q <= 1'b0;
- done_q <= 1'b0;
- mode_q <= 1'b0;
- end
+ begin
+ // Defaults
+ next_state = state;
+ cpld_start = 1'b0;
+ shift = 1'b0;
+ inc_count = 0;
+ load_data_reg = 1'b0;
+ ram_loader_done = 1'b0;
+ cpld_mode = 1'b0;
+ cpld_done = 1'b1;
+
+
+
+ case (state) //synthesis parallel_case full_case
+ // After reset wait until CPLD indicates its detached.
+ RESET: begin
+ if (cpld_detached)
+ next_state = S0;
+ else
+ next_state = RESET;
+ end
+
+ // Assert cpld_start to signal the CPLD its to start sending serial clock and data.
+ // Assume cpld_clk is low as we transition into search for first rising edge
+ S0: begin
+ cpld_start = 1'b1;
+ cpld_done = 1'b0;
+ if (~cpld_detached)
+ next_state = S2;
+ else
+ next_state = S0;
+ end
+
+ //
+ S1: begin
+ cpld_start = 1'b1;
+ cpld_done = 1'b0;
+ if (sampled_clk)
+ begin
+ // Found rising edge on cpld_clk.
+ if (count[2:0] == 3'b111)
+ // Its the last bit of a byte, send it out to the Wishbone bus.
+ begin
+ load_data_reg = 1'b1;
+ inc_count = 1'b1;
+ end
+ else
+ // Shift databit into LSB of shift register and increment count
+ begin
+ shift = 1'b1;
+ inc_count = 1'b1;
+ end // else: !if(count[2:0] == 3'b111)
+ next_state = S2;
+ end // if (sampled_clk)
+ else
+ next_state = S1;
+ end // case: S1
+
+ //
+ S2: begin
+ cpld_start = 1'b1;
+ cpld_done = 1'b0;
+ if (~sampled_clk)
+ // Found negative edge of clock
+ if (count[AWIDTH+2:3] == RAM_SIZE-1) // NOTE need to change this constant
+ // All firmware now downloaded
+ next_state = S3;
+ else
+ next_state = S1;
+ else
+ next_state = S2;
+ end // case: S2
+
+ // Now that terminal count is reached and all firmware is downloaded signal CPLD that download is done
+ // and that mode is now SPI mode.
+ S3: begin
+ if (sampled_clk)
+ begin
+ cpld_mode = 1'b1;
+ cpld_done = 1'b1;
+ next_state = S4;
+ end
+ else
+ next_state = S3;
+ end
+
+ // Search for negedge of cpld_clk whilst keeping done sequence asserted.
+ // Keep done assserted
+ S4: begin
+ cpld_mode = 1'b1;
+ cpld_done = 1'b1;
+ if (~sampled_clk)
+ next_state = S5;
+ else
+ next_state = S4;
+ end
+
+ // Search for posedge of cpld_clk whilst keeping done sequence asserted.
+ S5: begin
+ cpld_mode = 1'b1;
+ cpld_done = 1'b1;
+ if (sampled_clk)
+ next_state = S6;
+ else
+ next_state = S5;
+ end
+
+ // Stay in this state until reset/power down
+ S6: begin
+ ram_loader_done = 1'b1;
+ cpld_done = 1'b1;
+ cpld_mode = 1'b1;
+ next_state = S6;
+ end
+
+ endcase // case(state)
+ end
+
+ always @(posedge dsp_clk or posedge ram_loader_rst)
+ if (ram_loader_rst)
+ wb_state <= WB_IDLE;
else
- begin
- if(inc_addr_s)
- addr_q <= addr_q + 1;
- if(enable_q)
- begin
- bit_q <= bit_q + 1;
- bit_ovfl_q <= (bit_q == 3'd7);
- shift_dat_q[0] <= cfg_data_i;
- shift_dat_q[7:1] <= shift_dat_q[6:0];
- end
- if(bit_ovfl_q)
- ser_dat_q <= shift_dat_q;
-
- fsm_q <= fsm_s;
-
- ram_we_q <= ram_we_s;
-
- if(done_s)
- done_q <= 1'b1;
- mode_q <= mode_s;
- end // else: !if(rst_i)
+ wb_state <= wb_next_state;
+ reg do_write;
+ wire empty, full;
+
always @*
begin
- inc_addr_s <= 1'b0;
- ram_we_s <= 1'b0;
- done_s <= 1'b0;
- fsm_s <= FSM2_IDLE;
- mode_s <= 1'b0;
-
- case(fsm_q)
- FSM2_IDLE :
- if(start_q)
- if(bit_ovfl_q)
- fsm_s <= FSM2_WE_ON;
- FSM2_WE_ON:
- begin
- ram_we_s <= 1'b1;
- fsm_s <= FSM2_WE_OFF;
- end
- FSM2_WE_OFF:
- begin
- ram_we_s <= 1'b1;
- fsm_s <= FSM2_INC_ADDR1;
- end
- FSM2_INC_ADDR1:
- fsm_s <= FSM2_INC_ADDR2;
- FSM2_INC_ADDR2:
- if(addr_q == (RAM_SIZE-1))
- //if(&addr_q)
- begin
- fsm_s <= FSM2_FINISHED;
- done_s <= 1'b1;
- mode_s <= 1'b1;
- end
- else
- begin
- inc_addr_s <= 1'b1;
- fsm_s <= FSM2_IDLE;
- end // else: !if(&addr_q)
- FSM2_FINISHED:
- begin
- fsm_s <= FSM2_FINISHED;
- mode_s <= 1'b1;
- end
- endcase // case(fsm_q)
+ wb_next_state = wb_state;
+ do_write = 1'b0;
+
+ case (wb_state) //synthesis full_case parallel_case
+ //
+ WB_IDLE: begin
+ if (load_data_reg)
+ // Data reg will load ready to write wishbone @ next clock edge
+ wb_next_state = WB_WRITE;
+ else
+ wb_next_state = WB_IDLE;
+ end
+
+ // Drive address and data onto wishbone.
+ WB_WRITE: begin
+ do_write = 1'b1;
+ if (~full)
+ wb_next_state = WB_IDLE;
+ else
+ wb_next_state = WB_WRITE;
+ end
+
+ endcase // case(wb_state)
end // always @ *
- assign start_o = start_q;
- assign mode_o = mode_q;
- assign done_o = start_q ? done_q : 1'b1;
- wire [AWIDTH-1:0] ram_addr = addr_q;
- wire [7:0] ram_data = ser_dat_q;
- assign ram_loader_done_o = (fsm_q == FSM2_FINISHED);
-
- // wishbone master, only writes
- reg [7:0] dat_holder;
- assign wb_dat_o = {4{dat_holder}};
- assign wb_stb_o = wb_we_o;
- assign wb_cyc_o = wb_we_o;
+ wire [1:0] count_out;
+ wire [7:0] data_out;
+
+ fifo_xlnx_16x40_2clk crossclk
+ (.rst(ram_loader_rst),
+ .wr_clk(dsp_clk), .din({count[4:3],count[AWIDTH+2:3],data_reg}), .wr_en(do_write), .full(full),
+ .rd_clk(wb_clk), .dout({count_out,wb_adr,data_out}), .rd_en(~empty), .empty(empty));
+
+ assign wb_dat = {4{data_out}};
+
+ always @*
+ case(count_out[1:0]) //synthesis parallel_case full_case
+ 2'b00 : wb_sel = 4'b1000;
+ 2'b01 : wb_sel = 4'b0100;
+ 2'b10 : wb_sel = 4'b0010;
+ 2'b11 : wb_sel = 4'b0001;
+ endcase
+
+ assign wb_we = ~empty;
+ assign wb_stb = ~empty;
- always @(posedge clk_i or posedge rst_i)
- if(rst_i)
- begin
- dat_holder <= 8'd0;
- wb_adr_o <= 0;
- wb_sel_o <= 4'b0000;
- wb_we_o <= 1'b0;
- end
- else if(ram_we_q)
- begin
- dat_holder <= ram_data;
- wb_adr_o <= ram_addr;
- wb_we_o <= 1'b1;
- case(ram_addr[1:0]) // Big Endian
- 2'b00 : wb_sel_o <= 4'b1000;
- 2'b01 : wb_sel_o <= 4'b0100;
- 2'b10 : wb_sel_o <= 4'b0010;
- 2'b11 : wb_sel_o <= 4'b0001;
- endcase // case(ram_addr[1:0])
- end // if (ram_we_q)
- else if(wb_ack_i)
- wb_we_o <= 1'b0;
-
endmodule // ram_loader
diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs
index 22867da7e..c66979132 100644
--- a/fpga/usrp2/fifo/Makefile.srcs
+++ b/fpga/usrp2/fifo/Makefile.srcs
@@ -20,4 +20,6 @@ fifo19_to_ll8.v \
ll8_to_fifo19.v \
fifo36_to_fifo19.v \
fifo19_to_fifo36.v \
+fifo36_mux.v \
+fifo36_demux.v \
))
diff --git a/fpga/usrp2/fifo/fifo36_demux.v b/fpga/usrp2/fifo/fifo36_demux.v
new file mode 100644
index 000000000..a54759d4d
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo36_demux.v
@@ -0,0 +1,50 @@
+
+// Demux packets from a fifo based on the contents of the first line
+// If first line matches the parameter and mask, send to data1, otherwise send to data0
+
+module fifo36_demux
+ #(parameter match_data = 0,
+ parameter match_mask = 0)
+ (input clk, input reset, input clear,
+ input [35:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [35:0] data0_o, output src0_rdy_o, input dst0_rdy_i,
+ output [35:0] data1_o, output src1_rdy_o, input dst1_rdy_i);
+
+ localparam DMX_IDLE = 0;
+ localparam DMX_DATA0 = 1;
+ localparam DMX_DATA1 = 2;
+
+ reg [1:0] state;
+
+ wire match = |( (data_i ^ match_data) & match_mask );
+ wire eof = data_i[33];
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= DMX_IDLE;
+ else
+ case(state)
+ DMX_IDLE :
+ if(src_rdy_i)
+ if(match)
+ state <= DMX_DATA1;
+ else
+ state <= DMX_DATA0;
+ DMX_DATA0 :
+ if(src_rdy_i & dst0_rdy_i & eof)
+ state <= DMX_IDLE;
+ DMX_DATA1 :
+ if(src_rdy_i & dst1_rdy_i & eof)
+ state <= DMX_IDLE;
+ default :
+ state <= DMX_IDLE;
+ endcase // case (state)
+
+ assign dst_rdy_o = (state==DMX_IDLE) ? 0 : (state==DMX_DATA0) ? dst0_rdy_i : dst1_rdy_i;
+ assign src0_rdy_o = (state==DMX_DATA0) ? src_rdy_i : 0;
+ assign src1_rdy_o = (state==DMX_DATA1) ? src_rdy_i : 0;
+
+ assign data0_o = data_i;
+ assign data1_o = data_i;
+
+endmodule // fifo36_demux
diff --git a/fpga/usrp2/fifo/fifo36_mux.v b/fpga/usrp2/fifo/fifo36_mux.v
new file mode 100644
index 000000000..92bf13ff9
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo36_mux.v
@@ -0,0 +1,57 @@
+
+// Mux packets from multiple FIFO interfaces onto a single one.
+// Can alternate or give priority to one port (port 0)
+// In prio mode, port 1 will never get access if port 0 is always busy
+
+module fifo36_mux
+ #(parameter prio = 0)
+ (input clk, input reset, input clear,
+ input [35:0] data0_i, input src0_rdy_i, output dst0_rdy_o,
+ input [35:0] data1_i, input src1_rdy_i, output dst1_rdy_o,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ localparam MUX_IDLE0 = 0;
+ localparam MUX_DATA0 = 1;
+ localparam MUX_IDLE1 = 2;
+ localparam MUX_DATA1 = 3;
+
+ reg [1:0] state;
+
+ wire eof0 = data0_i[33];
+ wire eof1 = data1_i[33];
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= MUX_IDLE0;
+ else
+ case(state)
+ MUX_IDLE0 :
+ if(src0_rdy_i)
+ state <= MUX_DATA0;
+ else if(src1_rdy_i)
+ state <= MUX_DATA1;
+
+ MUX_DATA0 :
+ if(src0_rdy_i & dst_rdy_i & eof0)
+ state <= prio ? MUX_IDLE0 : MUX_IDLE1;
+
+ MUX_IDLE1 :
+ if(src1_rdy_i)
+ state <= MUX_DATA1;
+ else if(src0_rdy_i)
+ state <= MUX_DATA0;
+
+ MUX_DATA1 :
+ if(src1_rdy_i & dst_rdy_i & eof1)
+ state <= MUX_IDLE0;
+
+ default :
+ state <= MUX_IDLE0;
+ endcase // case (state)
+
+ assign dst0_rdy_o = (state==MUX_DATA0) ? dst_rdy_i : 0;
+ assign dst1_rdy_o = (state==MUX_DATA1) ? dst_rdy_i : 0;
+ assign src_rdy_o = (state==MUX_DATA0) ? src0_rdy_i : (state==MUX_DATA1) ? src1_rdy_i : 0;
+ assign data_o = (state==MUX_DATA0) ? data0_i : data1_i;
+
+endmodule // fifo36_demux
diff --git a/fpga/usrp2/fifo/fifo_new_tb.vcd b/fpga/usrp2/fifo/fifo_new_tb.vcd
deleted file mode 100644
index 796889e7d..000000000
--- a/fpga/usrp2/fifo/fifo_new_tb.vcd
+++ /dev/null
@@ -1,5506 +0,0 @@
-$date
- Thu Mar 19 17:21:11 2009
-$end
-$version
- Icarus Verilog
-$end
-$timescale
- 1ps
-$end
-$scope module fifo_new_tb $end
-$var wire 1 ! dst_rdy_f36i $end
-$var wire 36 " f36_in [35:0] $end
-$var wire 36 # i1 [35:0] $end
-$var wire 1 $ i1_dr $end
-$var wire 1 % i1_sr $end
-$var wire 19 & i2 [18:0] $end
-$var wire 1 ' i2_dr $end
-$var wire 1 ( i2_sr $end
-$var wire 19 ) i3 [18:0] $end
-$var wire 1 * i3_dr $end
-$var wire 1 + i3_sr $end
-$var wire 36 , i4 [35:0] $end
-$var wire 1 - i4_sr $end
-$var wire 8 . ll_data [7:0] $end
-$var wire 1 / ll_dst_rdy_n $end
-$var wire 1 0 ll_eof_n $end
-$var wire 1 1 ll_sof_n $end
-$var wire 1 2 ll_src_rdy_n $end
-$var reg 1 3 clear $end
-$var reg 1 4 clk $end
-$var reg 16 5 count [15:0] $end
-$var reg 1 6 dst_rdy_f36o $end
-$var reg 32 7 f36_data [31:0] $end
-$var reg 1 8 f36_eof $end
-$var reg 2 9 f36_occ [1:0] $end
-$var reg 1 : f36_sof $end
-$var reg 1 ; i4_dr $end
-$var reg 1 < rst $end
-$var reg 1 = src_rdy_f36i $end
-$scope module fifo_short1 $end
-$var wire 1 > clear $end
-$var wire 1 ? clk $end
-$var wire 36 @ datain [35:0] $end
-$var wire 36 A dataout [35:0] $end
-$var wire 1 $ dst_rdy_i $end
-$var wire 1 ! dst_rdy_o $end
-$var wire 1 B read $end
-$var wire 1 C reset $end
-$var wire 1 D src_rdy_i $end
-$var wire 1 % src_rdy_o $end
-$var wire 1 E write $end
-$var reg 4 F a [3:0] $end
-$var reg 1 G empty $end
-$var reg 1 H full $end
-$var reg 5 I occupied [4:0] $end
-$var reg 5 J space [4:0] $end
-$scope begin gen_srl16[0] $end
-$scope module srl16e $end
-$var wire 1 K A0 $end
-$var wire 1 L A1 $end
-$var wire 1 M A2 $end
-$var wire 1 N A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 O D $end
-$var wire 1 P Q $end
-$var reg 16 Q data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[1] $end
-$scope module srl16e $end
-$var wire 1 R A0 $end
-$var wire 1 S A1 $end
-$var wire 1 T A2 $end
-$var wire 1 U A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 V D $end
-$var wire 1 W Q $end
-$var reg 16 X data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[2] $end
-$scope module srl16e $end
-$var wire 1 Y A0 $end
-$var wire 1 Z A1 $end
-$var wire 1 [ A2 $end
-$var wire 1 \ A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 ] D $end
-$var wire 1 ^ Q $end
-$var reg 16 _ data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[3] $end
-$scope module srl16e $end
-$var wire 1 ` A0 $end
-$var wire 1 a A1 $end
-$var wire 1 b A2 $end
-$var wire 1 c A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 d D $end
-$var wire 1 e Q $end
-$var reg 16 f data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[4] $end
-$scope module srl16e $end
-$var wire 1 g A0 $end
-$var wire 1 h A1 $end
-$var wire 1 i A2 $end
-$var wire 1 j A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 k D $end
-$var wire 1 l Q $end
-$var reg 16 m data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[5] $end
-$scope module srl16e $end
-$var wire 1 n A0 $end
-$var wire 1 o A1 $end
-$var wire 1 p A2 $end
-$var wire 1 q A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 r D $end
-$var wire 1 s Q $end
-$var reg 16 t data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[6] $end
-$scope module srl16e $end
-$var wire 1 u A0 $end
-$var wire 1 v A1 $end
-$var wire 1 w A2 $end
-$var wire 1 x A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 y D $end
-$var wire 1 z Q $end
-$var reg 16 { data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[7] $end
-$scope module srl16e $end
-$var wire 1 | A0 $end
-$var wire 1 } A1 $end
-$var wire 1 ~ A2 $end
-$var wire 1 !" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 "" D $end
-$var wire 1 #" Q $end
-$var reg 16 $" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[8] $end
-$scope module srl16e $end
-$var wire 1 %" A0 $end
-$var wire 1 &" A1 $end
-$var wire 1 '" A2 $end
-$var wire 1 (" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 )" D $end
-$var wire 1 *" Q $end
-$var reg 16 +" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[9] $end
-$scope module srl16e $end
-$var wire 1 ," A0 $end
-$var wire 1 -" A1 $end
-$var wire 1 ." A2 $end
-$var wire 1 /" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 0" D $end
-$var wire 1 1" Q $end
-$var reg 16 2" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[10] $end
-$scope module srl16e $end
-$var wire 1 3" A0 $end
-$var wire 1 4" A1 $end
-$var wire 1 5" A2 $end
-$var wire 1 6" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 7" D $end
-$var wire 1 8" Q $end
-$var reg 16 9" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[11] $end
-$scope module srl16e $end
-$var wire 1 :" A0 $end
-$var wire 1 ;" A1 $end
-$var wire 1 <" A2 $end
-$var wire 1 =" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 >" D $end
-$var wire 1 ?" Q $end
-$var reg 16 @" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[12] $end
-$scope module srl16e $end
-$var wire 1 A" A0 $end
-$var wire 1 B" A1 $end
-$var wire 1 C" A2 $end
-$var wire 1 D" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 E" D $end
-$var wire 1 F" Q $end
-$var reg 16 G" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[13] $end
-$scope module srl16e $end
-$var wire 1 H" A0 $end
-$var wire 1 I" A1 $end
-$var wire 1 J" A2 $end
-$var wire 1 K" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 L" D $end
-$var wire 1 M" Q $end
-$var reg 16 N" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[14] $end
-$scope module srl16e $end
-$var wire 1 O" A0 $end
-$var wire 1 P" A1 $end
-$var wire 1 Q" A2 $end
-$var wire 1 R" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 S" D $end
-$var wire 1 T" Q $end
-$var reg 16 U" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[15] $end
-$scope module srl16e $end
-$var wire 1 V" A0 $end
-$var wire 1 W" A1 $end
-$var wire 1 X" A2 $end
-$var wire 1 Y" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 Z" D $end
-$var wire 1 [" Q $end
-$var reg 16 \" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[16] $end
-$scope module srl16e $end
-$var wire 1 ]" A0 $end
-$var wire 1 ^" A1 $end
-$var wire 1 _" A2 $end
-$var wire 1 `" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 a" D $end
-$var wire 1 b" Q $end
-$var reg 16 c" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[17] $end
-$scope module srl16e $end
-$var wire 1 d" A0 $end
-$var wire 1 e" A1 $end
-$var wire 1 f" A2 $end
-$var wire 1 g" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 h" D $end
-$var wire 1 i" Q $end
-$var reg 16 j" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[18] $end
-$scope module srl16e $end
-$var wire 1 k" A0 $end
-$var wire 1 l" A1 $end
-$var wire 1 m" A2 $end
-$var wire 1 n" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 o" D $end
-$var wire 1 p" Q $end
-$var reg 16 q" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[19] $end
-$scope module srl16e $end
-$var wire 1 r" A0 $end
-$var wire 1 s" A1 $end
-$var wire 1 t" A2 $end
-$var wire 1 u" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 v" D $end
-$var wire 1 w" Q $end
-$var reg 16 x" data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[20] $end
-$scope module srl16e $end
-$var wire 1 y" A0 $end
-$var wire 1 z" A1 $end
-$var wire 1 {" A2 $end
-$var wire 1 |" A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 }" D $end
-$var wire 1 ~" Q $end
-$var reg 16 !# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[21] $end
-$scope module srl16e $end
-$var wire 1 "# A0 $end
-$var wire 1 ## A1 $end
-$var wire 1 $# A2 $end
-$var wire 1 %# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 &# D $end
-$var wire 1 '# Q $end
-$var reg 16 (# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[22] $end
-$scope module srl16e $end
-$var wire 1 )# A0 $end
-$var wire 1 *# A1 $end
-$var wire 1 +# A2 $end
-$var wire 1 ,# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 -# D $end
-$var wire 1 .# Q $end
-$var reg 16 /# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[23] $end
-$scope module srl16e $end
-$var wire 1 0# A0 $end
-$var wire 1 1# A1 $end
-$var wire 1 2# A2 $end
-$var wire 1 3# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 4# D $end
-$var wire 1 5# Q $end
-$var reg 16 6# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[24] $end
-$scope module srl16e $end
-$var wire 1 7# A0 $end
-$var wire 1 8# A1 $end
-$var wire 1 9# A2 $end
-$var wire 1 :# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 ;# D $end
-$var wire 1 <# Q $end
-$var reg 16 =# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[25] $end
-$scope module srl16e $end
-$var wire 1 ># A0 $end
-$var wire 1 ?# A1 $end
-$var wire 1 @# A2 $end
-$var wire 1 A# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 B# D $end
-$var wire 1 C# Q $end
-$var reg 16 D# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[26] $end
-$scope module srl16e $end
-$var wire 1 E# A0 $end
-$var wire 1 F# A1 $end
-$var wire 1 G# A2 $end
-$var wire 1 H# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 I# D $end
-$var wire 1 J# Q $end
-$var reg 16 K# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[27] $end
-$scope module srl16e $end
-$var wire 1 L# A0 $end
-$var wire 1 M# A1 $end
-$var wire 1 N# A2 $end
-$var wire 1 O# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 P# D $end
-$var wire 1 Q# Q $end
-$var reg 16 R# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[28] $end
-$scope module srl16e $end
-$var wire 1 S# A0 $end
-$var wire 1 T# A1 $end
-$var wire 1 U# A2 $end
-$var wire 1 V# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 W# D $end
-$var wire 1 X# Q $end
-$var reg 16 Y# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[29] $end
-$scope module srl16e $end
-$var wire 1 Z# A0 $end
-$var wire 1 [# A1 $end
-$var wire 1 \# A2 $end
-$var wire 1 ]# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 ^# D $end
-$var wire 1 _# Q $end
-$var reg 16 `# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[30] $end
-$scope module srl16e $end
-$var wire 1 a# A0 $end
-$var wire 1 b# A1 $end
-$var wire 1 c# A2 $end
-$var wire 1 d# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 e# D $end
-$var wire 1 f# Q $end
-$var reg 16 g# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[31] $end
-$scope module srl16e $end
-$var wire 1 h# A0 $end
-$var wire 1 i# A1 $end
-$var wire 1 j# A2 $end
-$var wire 1 k# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 l# D $end
-$var wire 1 m# Q $end
-$var reg 16 n# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[32] $end
-$scope module srl16e $end
-$var wire 1 o# A0 $end
-$var wire 1 p# A1 $end
-$var wire 1 q# A2 $end
-$var wire 1 r# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 s# D $end
-$var wire 1 t# Q $end
-$var reg 16 u# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[33] $end
-$scope module srl16e $end
-$var wire 1 v# A0 $end
-$var wire 1 w# A1 $end
-$var wire 1 x# A2 $end
-$var wire 1 y# A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 z# D $end
-$var wire 1 {# Q $end
-$var reg 16 |# data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[34] $end
-$scope module srl16e $end
-$var wire 1 }# A0 $end
-$var wire 1 ~# A1 $end
-$var wire 1 !$ A2 $end
-$var wire 1 "$ A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 #$ D $end
-$var wire 1 $$ Q $end
-$var reg 16 %$ data [15:0] $end
-$upscope $end
-$upscope $end
-$scope begin gen_srl16[35] $end
-$scope module srl16e $end
-$var wire 1 &$ A0 $end
-$var wire 1 '$ A1 $end
-$var wire 1 ($ A2 $end
-$var wire 1 )$ A3 $end
-$var wire 1 E CE $end
-$var wire 1 ? CLK $end
-$var wire 1 *$ D $end
-$var wire 1 +$ Q $end
-$var reg 16 ,$ data [15:0] $end
-$upscope $end
-$upscope $end
-$upscope $end
-$scope module fifo36_to_fifo19 $end
-$var wire 1 > clear $end
-$var wire 1 ? clk $end
-$var wire 19 -$ f19_dataout [18:0] $end
-$var wire 1 ' f19_dst_rdy_i $end
-$var wire 1 ( f19_src_rdy_o $end
-$var wire 1 .$ f19_xfer $end
-$var wire 36 /$ f36_datain [35:0] $end
-$var wire 1 $ f36_dst_rdy_o $end
-$var wire 1 0$ f36_eof $end
-$var wire 1 1$ f36_occ $end
-$var wire 1 2$ f36_sof $end
-$var wire 1 % f36_src_rdy_i $end
-$var wire 1 3$ f36_xfer $end
-$var wire 1 4$ half_line $end
-$var wire 1 C reset $end
-$var reg 1 5$ phase $end
-$upscope $end
-$scope module fifo19_to_ll8 $end
-$var wire 1 6$ advance $end
-$var wire 1 > clear $end
-$var wire 1 ? clk $end
-$var wire 19 7$ f19_data [18:0] $end
-$var wire 1 ' f19_dst_rdy_o $end
-$var wire 1 8$ f19_eof $end
-$var wire 1 9$ f19_occ $end
-$var wire 1 :$ f19_sof $end
-$var wire 1 ( f19_src_rdy_i $end
-$var wire 1 ;$ ll_dst_rdy $end
-$var wire 1 / ll_dst_rdy_n $end
-$var wire 1 <$ ll_eof $end
-$var wire 1 0 ll_eof_n $end
-$var wire 1 =$ ll_sof $end
-$var wire 1 1 ll_sof_n $end
-$var wire 1 >$ ll_src_rdy $end
-$var wire 1 2 ll_src_rdy_n $end
-$var wire 1 C reset $end
-$var reg 8 ?$ ll_data [7:0] $end
-$var reg 1 @$ state $end
-$upscope $end
-$scope module ll8_to_fifo19 $end
-$var wire 1 > clear $end
-$var wire 1 ? clk $end
-$var wire 19 A$ f19_data [18:0] $end
-$var wire 1 * f19_dst_rdy_i $end
-$var wire 1 + f19_src_rdy_o $end
-$var wire 8 B$ ll_data [7:0] $end
-$var wire 1 C$ ll_dst_rdy $end
-$var wire 1 / ll_dst_rdy_n $end
-$var wire 1 D$ ll_eof $end
-$var wire 1 0 ll_eof_n $end
-$var wire 1 E$ ll_sof $end
-$var wire 1 1 ll_sof_n $end
-$var wire 1 F$ ll_src_rdy $end
-$var wire 1 2 ll_src_rdy_n $end
-$var wire 1 C reset $end
-$var wire 1 G$ xfer_out $end
-$var reg 8 H$ dat0 [7:0] $end
-$var reg 8 I$ dat1 [7:0] $end
-$var reg 1 J$ f19_eof $end
-$var reg 1 K$ f19_occ $end
-$var reg 1 L$ f19_sof $end
-$var reg 2 M$ state [1:0] $end
-$upscope $end
-$scope module fifo19_to_fifo36 $end
-$var wire 1 > clear $end
-$var wire 1 ? clk $end
-$var wire 19 N$ f19_datain [18:0] $end
-$var wire 1 * f19_dst_rdy_o $end
-$var wire 1 O$ f19_eof $end
-$var wire 1 P$ f19_occ $end
-$var wire 1 Q$ f19_sof $end
-$var wire 1 + f19_src_rdy_i $end
-$var wire 36 R$ f36_dataout [35:0] $end
-$var wire 1 S$ f36_dst_rdy_i $end
-$var wire 1 - f36_src_rdy_o $end
-$var wire 1 C reset $end
-$var wire 1 T$ xfer_out $end
-$var reg 16 U$ dat0 [15:0] $end
-$var reg 16 V$ dat1 [15:0] $end
-$var reg 1 W$ f36_eof $end
-$var reg 1 X$ f36_occ $end
-$var reg 1 Y$ f36_sof $end
-$var reg 2 Z$ state [1:0] $end
-$upscope $end
-$scope task PutPacketInFIFO36 $end
-$var reg 32 [$ data_len [31:0] $end
-$var reg 32 \$ data_start [31:0] $end
-$upscope $end
-$scope task ReadFromFIFO36 $end
-$upscope $end
-$upscope $end
-$enddefinitions $end
-#0
-$dumpvars
-bx \$
-bx [$
-bx Z$
-xY$
-xX$
-xW$
-bx V$
-bx U$
-0T$
-0S$
-b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx R$
-xQ$
-xP$
-xO$
-bx N$
-bx M$
-xL$
-xK$
-xJ$
-bx I$
-bx H$
-xG$
-xF$
-xE$
-xD$
-xC$
-bx B$
-bx A$
-x@$
-bx ?$
-x>$
-x=$
-x<$
-x;$
-x:$
-x9$
-x8$
-bx 7$
-x6$
-x5$
-x4$
-x3$
-x2$
-x1$
-x0$
-bx /$
-x.$
-bx -$
-b0 ,$
-x+$
-0*$
-x)$
-x($
-x'$
-x&$
-b0 %$
-x$$
-0#$
-x"$
-x!$
-x~#
-x}#
-b0 |#
-x{#
-0z#
-xy#
-xx#
-xw#
-xv#
-b0 u#
-xt#
-0s#
-xr#
-xq#
-xp#
-xo#
-b0 n#
-xm#
-0l#
-xk#
-xj#
-xi#
-xh#
-b0 g#
-xf#
-0e#
-xd#
-xc#
-xb#
-xa#
-b0 `#
-x_#
-0^#
-x]#
-x\#
-x[#
-xZ#
-b0 Y#
-xX#
-0W#
-xV#
-xU#
-xT#
-xS#
-b0 R#
-xQ#
-0P#
-xO#
-xN#
-xM#
-xL#
-b0 K#
-xJ#
-0I#
-xH#
-xG#
-xF#
-xE#
-b0 D#
-xC#
-0B#
-xA#
-x@#
-x?#
-x>#
-b0 =#
-x<#
-0;#
-x:#
-x9#
-x8#
-x7#
-b0 6#
-x5#
-04#
-x3#
-x2#
-x1#
-x0#
-b0 /#
-x.#
-0-#
-x,#
-x+#
-x*#
-x)#
-b0 (#
-x'#
-0&#
-x%#
-x$#
-x##
-x"#
-b0 !#
-x~"
-0}"
-x|"
-x{"
-xz"
-xy"
-b0 x"
-xw"
-0v"
-xu"
-xt"
-xs"
-xr"
-b0 q"
-xp"
-0o"
-xn"
-xm"
-xl"
-xk"
-b0 j"
-xi"
-0h"
-xg"
-xf"
-xe"
-xd"
-b0 c"
-xb"
-0a"
-x`"
-x_"
-x^"
-x]"
-b0 \"
-x["
-0Z"
-xY"
-xX"
-xW"
-xV"
-b0 U"
-xT"
-0S"
-xR"
-xQ"
-xP"
-xO"
-b0 N"
-xM"
-0L"
-xK"
-xJ"
-xI"
-xH"
-b0 G"
-xF"
-0E"
-xD"
-xC"
-xB"
-xA"
-b0 @"
-x?"
-0>"
-x="
-x<"
-x;"
-x:"
-b0 9"
-x8"
-07"
-x6"
-x5"
-x4"
-x3"
-b0 2"
-x1"
-00"
-x/"
-x."
-x-"
-x,"
-b0 +"
-x*"
-0)"
-x("
-x'"
-x&"
-x%"
-b0 $"
-x#"
-0""
-x!"
-x~
-x}
-x|
-b0 {
-xz
-0y
-xx
-xw
-xv
-xu
-b0 t
-xs
-0r
-xq
-xp
-xo
-xn
-b0 m
-xl
-0k
-xj
-xi
-xh
-xg
-b0 f
-xe
-0d
-xc
-xb
-xa
-x`
-b0 _
-x^
-0]
-x\
-x[
-xZ
-xY
-b0 X
-xW
-0V
-xU
-xT
-xS
-xR
-b0 Q
-xP
-0O
-xN
-xM
-xL
-xK
-bx J
-bx I
-xH
-xG
-bx F
-0E
-0D
-1C
-xB
-bx A
-b0 @
-0?
-0>
-0=
-1<
-0;
-0:
-b0 9
-08
-b0 7
-06
-bx 5
-04
-03
-x2
-x1
-x0
-x/
-bx .
-x-
-b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,
-x+
-x*
-bx )
-x(
-x'
-bx &
-x%
-x$
-bx #
-b0 "
-x!
-$end
-#50000000000000
-0D$
-10
-0E$
-0<$
-11
-08$
-09$
-0=$
-0$
-b0 ?$
-b0 .
-b0 B$
-0:$
-0'
-0F$
-04$
-01$
-b0 &
-b0 -$
-b0 7$
-1;$
-0.$
-06$
-12
-03$
-0B
-02$
-00$
-0/
-1!
-0>$
-0(
-0%
-0K
-0P
-0L
-0M
-0N
-0R
-0W
-0S
-0T
-0U
-0Y
-0^
-0Z
-0[
-0\
-0`
-0e
-0a
-0b
-0c
-0g
-0l
-0h
-0i
-0j
-0n
-0s
-0o
-0p
-0q
-0u
-0z
-0v
-0w
-0x
-0|
-0#"
-0}
-0~
-0!"
-0%"
-0*"
-0&"
-0'"
-0("
-0,"
-01"
-0-"
-0."
-0/"
-03"
-08"
-04"
-05"
-06"
-0:"
-0?"
-0;"
-0<"
-0="
-0A"
-0F"
-0B"
-0C"
-0D"
-0H"
-0M"
-0I"
-0J"
-0K"
-0O"
-0T"
-0P"
-0Q"
-0R"
-0V"
-0["
-0W"
-0X"
-0Y"
-0]"
-0b"
-0^"
-0_"
-0`"
-0d"
-0i"
-0e"
-0f"
-0g"
-0k"
-0p"
-0l"
-0m"
-0n"
-0r"
-0w"
-0s"
-0t"
-0u"
-0y"
-0~"
-0z"
-0{"
-0|"
-0"#
-0'#
-0##
-0$#
-0%#
-0)#
-0.#
-0*#
-0+#
-0,#
-00#
-05#
-01#
-02#
-03#
-07#
-0<#
-08#
-09#
-0:#
-0>#
-0C#
-0?#
-0@#
-0A#
-0E#
-0J#
-0F#
-0G#
-0H#
-0L#
-0Q#
-0M#
-0N#
-0O#
-0S#
-0X#
-0T#
-0U#
-0V#
-0Z#
-0_#
-0[#
-0\#
-0]#
-0a#
-0f#
-0b#
-0c#
-0d#
-0h#
-0m#
-0i#
-0j#
-0k#
-0o#
-0t#
-0p#
-0q#
-0r#
-0v#
-0{#
-0w#
-0x#
-0y#
-0}#
-0$$
-0~#
-0!$
-0"$
-0&$
-0+$
-b0 #
-b0 A
-b0 /$
-0'$
-0($
-0)$
-0P$
-1C$
-0G$
-1*
-0H
-1G
-b0 F
-b10000 J
-b0 I
-05$
-0@$
-0K$
-b0xxxxxxxxxxxxxxxxxx )
-b0xxxxxxxxxxxxxxxxxx A$
-b0xxxxxxxxxxxxxxxxxx N$
-b0 M$
-0+
-0X$
-b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ,
-b0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx R$
-b0 Z$
-0-
-14
-1?
-#100000000000000
-04
-0?
-#150000000000000
-14
-1?
-#200000000000000
-04
-0?
-#250000000000000
-14
-1?
-#300000000000000
-04
-0?
-#350000000000000
-14
-1?
-#400000000000000
-04
-0?
-#450000000000000
-14
-1?
-#500000000000000
-04
-0?
-#550000000000000
-14
-1?
-#600000000000000
-04
-0?
-#650000000000000
-14
-1?
-#700000000000000
-04
-0?
-#750000000000000
-14
-1?
-#800000000000000
-04
-0?
-#850000000000000
-14
-1?
-#900000000000000
-04
-0?
-#950000000000000
-14
-1?
-#1000000000000000
-04
-0?
-0<
-0C
-#1050000000000000
-14
-1?
-#1100000000000000
-04
-0?
-#1150000000000000
-1k
-1y
-1""
-1S"
-1Z"
-1}"
-1&#
-14#
-1^#
-1l#
-1s#
-1E
-1:
-b10100000101100001100000011010000 7
-b110100000101100001100000011010000 "
-b110100000101100001100000011010000 @
-1=
-1D
-b100 5
-b1100 [$
-b10100000101100001100000011010000 \$
-14
-1?
-#1200000000000000
-04
-0?
-#1250000000000000
-1F$
-16$
-02
-1>$
-1(
-1%
-1O
-1)"
-1a"
-1;#
-0s#
-0G
-b1111 J
-b1 I
-b1000 5
-b10100001101100011100000111010001 7
-0:
-b10100001101100011100000111010001 "
-b10100001101100011100000111010001 @
-14
-1?
-#1250000000000100
-1E$
-01
-1=$
-b10100000 ?$
-b10100000 .
-b10100000 B$
-1:$
-b11010000010110000 &
-b11010000010110000 -$
-b11010000010110000 7$
-12$
-b1 m
-1l
-b1 {
-1z
-b1 $"
-1#"
-b1 U"
-1T"
-b1 \"
-1["
-b1 !#
-1~"
-b1 (#
-1'#
-b1 6#
-15#
-b1 `#
-1_#
-b1 n#
-1m#
-b1 u#
-1t#
-b110100000101100001100000011010000 #
-b110100000101100001100000011010000 A
-b110100000101100001100000011010000 /$
-#1300000000000000
-04
-0?
-#1350000000000000
-0E$
-0:$
-1.$
-11
-b0 &
-b0 -$
-b0 7$
-1'
-0=$
-02$
-0O
-1V
-0)"
-10"
-0a"
-1h"
-0;#
-1B#
-1z#
-1Q$
-0O$
-b0 ?$
-b0 .
-b0 B$
-1K
-1R
-1Y
-1`
-1g
-0l
-1n
-1u
-0z
-1|
-0#"
-1%"
-1,"
-13"
-1:"
-1A"
-1H"
-1O"
-0T"
-1V"
-0["
-1]"
-1d"
-1k"
-1r"
-1y"
-0~"
-1"#
-0'#
-1)#
-10#
-05#
-17#
-1>#
-1E#
-1L#
-1S#
-1Z#
-0_#
-1a#
-1h#
-0m#
-1o#
-0t#
-b0 #
-b0 A
-b0 /$
-1v#
-1}#
-1&$
-18
-b10100010101100101100001011010010 7
-b1010100010101100101100001011010010 "
-b1010100010101100101100001011010010 @
-b10100000 H$
-b1 M$
-0J$
-1L$
-b110100000xxxxxxxx )
-b110100000xxxxxxxx A$
-b110100000xxxxxxxx N$
-1@$
-b10 I
-b1110 J
-b1 F
-14
-1?
-#1350000000000100
-b10110000 ?$
-b10110000 .
-b10110000 B$
-1:$
-b11010000010110000 &
-b11010000010110000 -$
-b11010000010110000 7$
-12$
-b10 u#
-1t#
-b11 n#
-1m#
-b11 `#
-1_#
-b1 =#
-b11 6#
-15#
-b11 (#
-1'#
-b11 !#
-1~"
-b1 c"
-b11 \"
-1["
-b11 U"
-1T"
-b1 +"
-b11 $"
-1#"
-b11 {
-1z
-b11 m
-1l
-b110100000101100001100000011010000 #
-b110100000101100001100000011010000 A
-b110100000101100001100000011010000 /$
-b1 Q
-#1351000000000000
-1;
-1S$
-#1400000000000000
-04
-0?
-#1450000000000000
-0E$
-0.$
-11
-02$
-0:$
-0'
-0=$
-0K
-1L
-0R
-1S
-0Y
-1Z
-0`
-1a
-0g
-1h
-0l
-0n
-1o
-0u
-1v
-0z
-0|
-1}
-0#"
-0%"
-1&"
-0,"
-1-"
-03"
-14"
-0:"
-1;"
-0A"
-1B"
-0H"
-1I"
-0O"
-1P"
-0T"
-0V"
-1W"
-0["
-0]"
-1^"
-0d"
-1e"
-0k"
-1l"
-0r"
-1s"
-0y"
-1z"
-0~"
-0"#
-1##
-0'#
-0)#
-1*#
-00#
-11#
-05#
-07#
-18#
-0>#
-1?#
-0E#
-1F#
-0L#
-1M#
-0S#
-1T#
-0Z#
-1[#
-0_#
-0a#
-1b#
-0h#
-1i#
-0m#
-0o#
-1p#
-0t#
-b0 #
-b0 A
-b0 /$
-0v#
-1w#
-0}#
-1~#
-0&$
-1'$
-b0 &
-b0 -$
-b0 7$
-b0 ?$
-b0 .
-b0 B$
-1G$
-0E
-0V
-0k
-0y
-0""
-00"
-0S"
-0Z"
-0h"
-0}"
-0&#
-04#
-0B#
-0^#
-0l#
-0z#
-b10 F
-b1101 J
-b11 I
-15$
-0@$
-b10 M$
-1+
-b10110000 I$
-b11010000010110000 )
-b11010000010110000 A$
-b11010000010110000 N$
-0=
-0D
-b0 7
-08
-b0 "
-b0 @
-14
-1?
-#1450000000000100
-b11000000 ?$
-b11000000 .
-b11000000 B$
-b1100000011010000 &
-b1100000011010000 -$
-b1100000011010000 7$
-12$
-b10 Q
-b1 X
-b111 m
-1l
-b111 {
-1z
-b111 $"
-1#"
-b10 +"
-b1 2"
-b111 U"
-1T"
-b111 \"
-1["
-b10 c"
-b1 j"
-b111 !#
-1~"
-b111 (#
-1'#
-b111 6#
-15#
-b10 =#
-b1 D#
-b111 `#
-1_#
-b111 n#
-1m#
-b100 u#
-1t#
-b110100000101100001100000011010000 #
-b110100000101100001100000011010000 A
-b110100000101100001100000011010000 /$
-b1 |#
-#1500000000000000
-04
-0?
-#1550000000000000
-13$
-1B
-1.$
-1$
-1'
-0G$
-0Q$
-b11010000 ?$
-b11010000 .
-b11010000 B$
-b1010000010110000 U$
-b1 Z$
-0W$
-1Y$
-b11010000010110000xxxxxxxxxxxxxxxx ,
-b11010000010110000xxxxxxxxxxxxxxxx R$
-b11000000 H$
-b1 M$
-0+
-0L$
-b1100000010110000 )
-b1100000010110000 A$
-b1100000010110000 N$
-1@$
-14
-1?
-#1600000000000000
-04
-0?
-#1650000000000000
-0E$
-11
-0=$
-03$
-0B
-0.$
-02$
-0:$
-0$
-0'
-1K
-1P
-0L
-1R
-0S
-0W
-1Y
-0Z
-1`
-0a
-1g
-0h
-1n
-0o
-1u
-0v
-1|
-0}
-1%"
-1*"
-0&"
-1,"
-0-"
-01"
-13"
-04"
-1:"
-0;"
-1A"
-0B"
-1H"
-0I"
-1O"
-0P"
-1V"
-0W"
-1]"
-1b"
-0^"
-1d"
-0e"
-0i"
-1k"
-0l"
-1r"
-0s"
-1y"
-0z"
-1"#
-0##
-1)#
-0*#
-10#
-01#
-17#
-1<#
-08#
-1>#
-0?#
-0C#
-1E#
-0F#
-1L#
-0M#
-1S#
-0T#
-1Z#
-0[#
-1a#
-0b#
-1h#
-0i#
-1o#
-0p#
-0t#
-1v#
-0w#
-0{#
-b10100001101100011100000111010001 #
-b10100001101100011100000111010001 A
-b10100001101100011100000111010001 /$
-1}#
-0~#
-1&$
-0'$
-b1010000110110001 &
-b1010000110110001 -$
-b1010000110110001 7$
-b10100001 ?$
-b10100001 .
-b10100001 B$
-1G$
-b1 F
-b1110 J
-b10 I
-05$
-0@$
-b10 M$
-1+
-b11010000 I$
-b1100000011010000 )
-b1100000011010000 A$
-b1100000011010000 N$
-14
-1?
-#1700000000000000
-04
-0?
-#1750000000000000
-1.$
-1'
-1T$
-0G$
-b10110001 ?$
-b10110001 .
-b10110001 B$
-b1100000011010000 V$
-b110100000101100001100000011010000 ,
-b110100000101100001100000011010000 R$
-b10 Z$
-1-
-b10100001 H$
-b1010000111010000 )
-b1010000111010000 A$
-b1010000111010000 N$
-b1 M$
-0+
-1@$
-14
-1?
-#1800000000000000
-04
-0?
-#1850000000000000
-0.$
-0'
-b1100000111010001 &
-b1100000111010001 -$
-b1100000111010001 7$
-b11000001 ?$
-b11000001 .
-b11000001 B$
-1G$
-0T$
-15$
-0@$
-b10 M$
-1+
-b10110001 I$
-b1010000110110001 )
-b1010000110110001 A$
-b1010000110110001 N$
-b0 Z$
-0-
-14
-1?
-#1900000000000000
-04
-0?
-#1950000000000000
-13$
-1B
-1.$
-1$
-1'
-0G$
-b11010001 ?$
-b11010001 .
-b11010001 B$
-b1010000110110001 U$
-b1 Z$
-0Y$
-b10100001101100011100000011010000 ,
-b10100001101100011100000011010000 R$
-b11000001 H$
-b1100000110110001 )
-b1100000110110001 A$
-b1100000110110001 N$
-b1 M$
-0+
-1@$
-14
-1?
-#2000000000000000
-04
-0?
-#2050000000000000
-03$
-0B
-0.$
-10$
-0$
-0'
-0K
-0P
-0R
-1W
-0Y
-0`
-0g
-0n
-0u
-0|
-0%"
-0*"
-0,"
-11"
-03"
-0:"
-0A"
-0H"
-0O"
-0V"
-0]"
-0b"
-0d"
-1i"
-0k"
-0r"
-0y"
-0"#
-0)#
-00#
-07#
-0<#
-0>#
-1C#
-0E#
-0L#
-0S#
-0Z#
-0a#
-0h#
-0o#
-0v#
-1{#
-b1010100010101100101100001011010010 #
-b1010100010101100101100001011010010 A
-b1010100010101100101100001011010010 /$
-0}#
-0&$
-b1010001010110010 &
-b1010001010110010 -$
-b1010001010110010 7$
-b10100010 ?$
-b10100010 .
-b10100010 B$
-1G$
-b0 F
-b1111 J
-b1 I
-05$
-0@$
-b10 M$
-1+
-b11010001 I$
-b1100000111010001 )
-b1100000111010001 A$
-b1100000111010001 N$
-14
-1?
-#2100000000000000
-04
-0?
-#2150000000000000
-1.$
-1'
-1T$
-0G$
-b10110010 ?$
-b10110010 .
-b10110010 B$
-b1100000111010001 V$
-b10100001101100011100000111010001 ,
-b10100001101100011100000111010001 R$
-b10 Z$
-1-
-b10100010 H$
-b1010001011010001 )
-b1010001011010001 A$
-b1010001011010001 N$
-b1 M$
-0+
-1@$
-14
-1?
-#2200000000000000
-04
-0?
-#2250000000000000
-0.$
-18$
-0'
-b101100001011010010 &
-b101100001011010010 -$
-b101100001011010010 7$
-b11000010 ?$
-b11000010 .
-b11000010 B$
-1G$
-0T$
-15$
-0@$
-b10 M$
-1+
-b10110010 I$
-b1010001010110010 )
-b1010001010110010 A$
-b1010001010110010 N$
-b0 Z$
-0-
-14
-1?
-#2300000000000000
-04
-0?
-#2350000000000000
-1D$
-13$
-1B
-00
-1.$
-1$
-1<$
-1'
-0G$
-b11010010 ?$
-b11010010 .
-b11010010 B$
-b1010001010110010 U$
-b10100010101100101100000111010001 ,
-b10100010101100101100000111010001 R$
-b1 Z$
-b11000010 H$
-b1100001010110010 )
-b1100001010110010 A$
-b1100001010110010 N$
-b1 M$
-0+
-1@$
-14
-1?
-#2400000000000000
-04
-0?
-#2450000000000000
-0D$
-0'
-0F$
-10
-0.$
-06$
-12
-03$
-0B
-08$
-0$
-0<$
-0>$
-0(
-0%
-b1010001010110010 &
-b1010001010110010 -$
-b1010001010110010 7$
-b10100010 ?$
-b10100010 .
-b10100010 B$
-1G$
-1O$
-1G
-b10000 J
-b0 I
-05$
-0@$
-1J$
-b10 M$
-1+
-b11010010 I$
-b101100001011010010 )
-b101100001011010010 A$
-b101100001011010010 N$
-14
-1?
-#2500000000000000
-04
-0?
-#2550000000000000
-1T$
-0G$
-b1100001011010010 V$
-b10 Z$
-1-
-1W$
-b1010100010101100101100001011010010 ,
-b1010100010101100101100001011010010 R$
-b0 M$
-0+
-14
-1?
-#2600000000000000
-04
-0?
-#2650000000000000
-0T$
-b0 Z$
-0-
-14
-1?
-#2700000000000000
-04
-0?
-#2750000000000000
-14
-1?
-#2800000000000000
-04
-0?
-#2850000000000000
-14
-1?
-#2900000000000000
-04
-0?
-#2950000000000000
-14
-1?
-#3000000000000000
-04
-0?
-#3050000000000000
-14
-1?
-#3100000000000000
-04
-0?
-#3150000000000000
-14
-1?
-#3200000000000000
-04
-0?
-#3250000000000000
-14
-1?
-#3300000000000000
-04
-0?
-#3350000000000000
-14
-1?
-#3400000000000000
-04
-0?
-#3450000000000000
-14
-1?
-#3500000000000000
-04
-0?
-#3550000000000000
-14
-1?
-#3600000000000000
-04
-0?
-#3650000000000000
-14
-1?
-#3700000000000000
-04
-0?
-#3750000000000000
-14
-1?
-#3800000000000000
-04
-0?
-#3850000000000000
-14
-1?
-#3900000000000000
-04
-0?
-#3950000000000000
-14
-1?
-#4000000000000000
-04
-0?
-#4050000000000000
-14
-1?
-#4100000000000000
-04
-0?
-#4150000000000000
-14
-1?
-#4200000000000000
-04
-0?
-#4250000000000000
-14
-1?
-#4300000000000000
-04
-0?
-#4350000000000000
-14
-1?
-#4400000000000000
-04
-0?
-#4450000000000000
-14
-1?
-#4500000000000000
-04
-0?
-#4550000000000000
-14
-1?
-#4600000000000000
-04
-0?
-#4650000000000000
-14
-1?
-#4700000000000000
-04
-0?
-#4750000000000000
-14
-1?
-#4800000000000000
-04
-0?
-#4850000000000000
-14
-1?
-#4900000000000000
-04
-0?
-#4950000000000000
-14
-1?
-#5000000000000000
-04
-0?
-#5050000000000000
-14
-1?
-#5100000000000000
-04
-0?
-#5150000000000000
-14
-1?
-#5200000000000000
-04
-0?
-#5250000000000000
-14
-1?
-#5300000000000000
-04
-0?
-#5350000000000000
-14
-1?
-#5400000000000000
-04
-0?
-#5450000000000000
-14
-1?
-#5500000000000000
-04
-0?
-#5550000000000000
-14
-1?
-#5600000000000000
-04
-0?
-#5650000000000000
-14
-1?
-#5700000000000000
-04
-0?
-#5750000000000000
-14
-1?
-#5800000000000000
-04
-0?
-#5850000000000000
-14
-1?
-#5900000000000000
-04
-0?
-#5950000000000000
-14
-1?
-#6000000000000000
-04
-0?
-#6050000000000000
-14
-1?
-#6100000000000000
-04
-0?
-#6150000000000000
-14
-1?
-#6200000000000000
-04
-0?
-#6250000000000000
-14
-1?
-#6300000000000000
-04
-0?
-#6350000000000000
-14
-1?
-#6400000000000000
-04
-0?
-#6450000000000000
-14
-1?
-#6500000000000000
-04
-0?
-#6550000000000000
-14
-1?
-#6600000000000000
-04
-0?
-#6650000000000000
-14
-1?
-#6700000000000000
-04
-0?
-#6750000000000000
-14
-1?
-#6800000000000000
-04
-0?
-#6850000000000000
-14
-1?
-#6900000000000000
-04
-0?
-#6950000000000000
-14
-1?
-#7000000000000000
-04
-0?
-#7050000000000000
-14
-1?
-#7100000000000000
-04
-0?
-#7150000000000000
-14
-1?
-#7200000000000000
-04
-0?
-#7250000000000000
-14
-1?
-#7300000000000000
-04
-0?
-#7350000000000000
-14
-1?
-#7400000000000000
-04
-0?
-#7450000000000000
-14
-1?
-#7500000000000000
-04
-0?
-#7550000000000000
-14
-1?
-#7600000000000000
-04
-0?
-#7650000000000000
-14
-1?
-#7700000000000000
-04
-0?
-#7750000000000000
-14
-1?
-#7800000000000000
-04
-0?
-#7850000000000000
-14
-1?
-#7900000000000000
-04
-0?
-#7950000000000000
-14
-1?
-#8000000000000000
-04
-0?
-#8050000000000000
-14
-1?
-#8100000000000000
-04
-0?
-#8150000000000000
-14
-1?
-#8200000000000000
-04
-0?
-#8250000000000000
-14
-1?
-#8300000000000000
-04
-0?
-#8350000000000000
-14
-1?
-#8400000000000000
-04
-0?
-#8450000000000000
-14
-1?
-#8500000000000000
-04
-0?
-#8550000000000000
-14
-1?
-#8600000000000000
-04
-0?
-#8650000000000000
-14
-1?
-#8700000000000000
-04
-0?
-#8750000000000000
-14
-1?
-#8800000000000000
-04
-0?
-#8850000000000000
-14
-1?
-#8900000000000000
-04
-0?
-#8950000000000000
-14
-1?
-#9000000000000000
-04
-0?
-#9050000000000000
-14
-1?
-#9100000000000000
-04
-0?
-#9150000000000000
-14
-1?
-#9200000000000000
-04
-0?
-#9250000000000000
-14
-1?
-#9300000000000000
-04
-0?
-#9350000000000000
-14
-1?
-#9400000000000000
-04
-0?
-#9450000000000000
-14
-1?
-#9500000000000000
-04
-0?
-#9550000000000000
-14
-1?
-#9600000000000000
-04
-0?
-#9650000000000000
-14
-1?
-#9700000000000000
-04
-0?
-#9750000000000000
-14
-1?
-#9800000000000000
-04
-0?
-#9850000000000000
-14
-1?
-#9900000000000000
-04
-0?
-#9950000000000000
-14
-1?
-#10000000000000000
-04
-0?
-#10050000000000000
-14
-1?
-#10100000000000000
-04
-0?
-#10150000000000000
-14
-1?
-#10200000000000000
-04
-0?
-#10250000000000000
-14
-1?
-#10300000000000000
-04
-0?
-#10350000000000000
-14
-1?
-#10400000000000000
-04
-0?
-#10450000000000000
-14
-1?
-#10500000000000000
-04
-0?
-#10550000000000000
-14
-1?
-#10600000000000000
-04
-0?
-#10650000000000000
-14
-1?
-#10700000000000000
-04
-0?
-#10750000000000000
-14
-1?
-#10800000000000000
-04
-0?
-#10850000000000000
-14
-1?
-#10900000000000000
-04
-0?
-#10950000000000000
-14
-1?
-#11000000000000000
-04
-0?
-#11050000000000000
-14
-1?
-#11100000000000000
-04
-0?
-#11150000000000000
-14
-1?
-#11200000000000000
-04
-0?
-#11250000000000000
-14
-1?
-#11300000000000000
-04
-0?
-#11350000000000000
-14
-1?
-#11400000000000000
-04
-0?
-#11450000000000000
-14
-1?
-#11500000000000000
-04
-0?
-#11550000000000000
-14
-1?
-#11600000000000000
-04
-0?
-#11650000000000000
-1k
-1r
-1""
-1L"
-1Z"
-1}"
-1&#
-1-#
-14#
-1^#
-1e#
-1l#
-1s#
-1E
-1:
-b11100000111100001010000010110000 7
-b111100000111100001010000010110000 "
-b111100000111100001010000010110000 @
-1=
-1D
-b100 5
-b100100 [$
-b11100000111100001010000010110000 \$
-14
-1?
-#11700000000000000
-04
-0?
-#11750000000000000
-1F$
-16$
-02
-1>$
-1(
-1%
-1O
-1)"
-1a"
-1;#
-0s#
-b1 I
-b1111 J
-0G
-b1000 5
-b11100001111100011010000110110001 7
-0:
-b11100001111100011010000110110001 "
-b11100001111100011010000110110001 @
-14
-1?
-#11750000000000100
-1E$
-01
-1=$
-b11100000 ?$
-b11100000 .
-b11100000 B$
-1:$
-b11110000011110000 &
-b11110000011110000 -$
-b11110000011110000 7$
-12$
-00$
-b10 |#
-0{#
-b1001 u#
-1t#
-b1111 n#
-b1 g#
-1f#
-b1111 `#
-b10 D#
-0C#
-b100 =#
-b1111 6#
-b1 /#
-1.#
-b1111 (#
-b1111 !#
-b10 j"
-0i"
-b100 c"
-b1111 \"
-b1110 U"
-0T"
-b1 N"
-1M"
-b10 2"
-01"
-b100 +"
-b1111 $"
-b1110 {
-0z
-b1 t
-1s
-b1111 m
-b10 X
-0W
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-b100 Q
-#11800000000000000
-04
-0?
-#11850000000000000
-0:$
-0E$
-b1010001010110010 &
-b1010001010110010 -$
-b1010001010110010 7$
-1.$
-11
-02$
-10$
-1'
-0=$
-0O
-1V
-0)"
-10"
-0a"
-1h"
-0;#
-1B#
-1K
-1R
-1W
-1Y
-1`
-1g
-1n
-0s
-1u
-1z
-1|
-1%"
-1,"
-11"
-13"
-1:"
-1A"
-1H"
-0M"
-1O"
-1T"
-1V"
-1]"
-1d"
-1i"
-1k"
-1r"
-1y"
-1"#
-1)#
-0.#
-10#
-17#
-1>#
-1C#
-1E#
-1L#
-1S#
-1Z#
-1a#
-0f#
-1h#
-1o#
-0t#
-1v#
-1{#
-b1010100010101100101100001011010010 #
-b1010100010101100101100001011010010 A
-b1010100010101100101100001011010010 /$
-1}#
-1&$
-b10110010 ?$
-b10110010 .
-b10110010 B$
-1Q$
-0O$
-b1100 5
-b11100010111100101010001010110010 7
-b11100010111100101010001010110010 "
-b11100010111100101010001010110010 @
-b1 F
-b1110 J
-b10 I
-1@$
-1L$
-0J$
-b1 M$
-b11100000 H$
-b11110000011010010 )
-b11110000011010010 A$
-b11110000011010010 N$
-14
-1?
-#11850000000000100
-b11110000 ?$
-b11110000 .
-b11110000 B$
-1:$
-b11110000011110000 &
-b11110000011110000 -$
-b11110000011110000 7$
-12$
-00$
-b1001 Q
-b100 X
-0W
-b11111 m
-b11 t
-1s
-b11100 {
-0z
-b11111 $"
-b1001 +"
-b100 2"
-01"
-b11 N"
-1M"
-b11100 U"
-0T"
-b11111 \"
-b1001 c"
-b100 j"
-0i"
-b11111 !#
-b11111 (#
-b11 /#
-1.#
-b11111 6#
-b1001 =#
-b100 D#
-0C#
-b11111 `#
-b11 g#
-1f#
-b11111 n#
-b10010 u#
-1t#
-b100 |#
-0{#
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-#11900000000000000
-04
-0?
-#11950000000000000
-18$
-0.$
-03$
-0B
-0'
-0:$
-0$
-02$
-10$
-1G$
-b11000010 ?$
-b11000010 .
-b11000010 B$
-b101100001011010010 &
-b101100001011010010 -$
-b101100001011010010 7$
-0K
-1L
-0P
-0R
-1W
-1S
-0Y
-1Z
-0`
-1a
-0g
-1h
-0n
-1o
-0s
-0u
-1v
-1z
-0|
-1}
-0%"
-1&"
-0*"
-0,"
-11"
-1-"
-03"
-14"
-0:"
-1;"
-0A"
-1B"
-0H"
-1I"
-0M"
-0O"
-1P"
-1T"
-0V"
-1W"
-0]"
-1^"
-0b"
-0d"
-1i"
-1e"
-0k"
-1l"
-0r"
-1s"
-0y"
-1z"
-0"#
-1##
-0)#
-1*#
-0.#
-00#
-11#
-07#
-18#
-0<#
-0>#
-1C#
-1?#
-0E#
-1F#
-0L#
-1M#
-0S#
-1T#
-0Z#
-1[#
-0a#
-1b#
-0f#
-0h#
-1i#
-0o#
-1p#
-0t#
-0v#
-1{#
-b1010100010101100101100001011010010 #
-b1010100010101100101100001011010010 A
-b1010100010101100101100001011010010 /$
-1w#
-0}#
-1~#
-0&$
-1'$
-1O
-1)"
-1a"
-1;#
-b11110000 I$
-b11110000011110000 )
-b11110000011110000 A$
-b11110000011110000 N$
-b10 M$
-1+
-0@$
-15$
-b11 I
-b1101 J
-b10 F
-b10000 5
-b11100011111100111010001110110011 7
-b11100011111100111010001110110011 "
-b11100011111100111010001110110011 @
-14
-1?
-#11950000000000100
-b10100000 ?$
-b10100000 .
-b10100000 B$
-08$
-b1010000010110000 &
-b1010000010110000 -$
-b1010000010110000 7$
-12$
-00$
-b1000 |#
-0{#
-b100100 u#
-1t#
-b111111 n#
-b111 g#
-1f#
-b111111 `#
-b1001 D#
-0C#
-b10010 =#
-b111111 6#
-b111 /#
-1.#
-b111111 (#
-b111111 !#
-b1001 j"
-0i"
-b10010 c"
-b111111 \"
-b111000 U"
-0T"
-b111 N"
-1M"
-b1001 2"
-01"
-b10010 +"
-b111111 $"
-b111000 {
-0z
-b111 t
-1s
-b111111 m
-b1001 X
-0W
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-b10010 Q
-#12000000000000000
-04
-0?
-#12050000000000000
-1D$
-00
-1<$
-18$
-13$
-1B
-b101100001011010010 &
-b101100001011010010 -$
-b101100001011010010 7$
-1.$
-1$
-02$
-10$
-1'
-0O
-0V
-1]
-0)"
-00"
-17"
-0a"
-0h"
-1o"
-0;#
-0B#
-1I#
-1K
-1R
-1W
-1Y
-1`
-1g
-1n
-0s
-1u
-1z
-1|
-1%"
-1,"
-11"
-13"
-1:"
-1A"
-1H"
-0M"
-1O"
-1T"
-1V"
-1]"
-1d"
-1i"
-1k"
-1r"
-1y"
-1"#
-1)#
-0.#
-10#
-17#
-1>#
-1C#
-1E#
-1L#
-1S#
-1Z#
-1a#
-0f#
-1h#
-1o#
-0t#
-1v#
-1{#
-b1010100010101100101100001011010010 #
-b1010100010101100101100001011010010 A
-b1010100010101100101100001011010010 /$
-1}#
-1&$
-b11010010 ?$
-b11010010 .
-b11010010 B$
-0G$
-0Q$
-b10100 5
-b11100100111101001010010010110100 7
-b11100100111101001010010010110100 "
-b11100100111101001010010010110100 @
-b11 F
-b1100 J
-b100 I
-1@$
-0L$
-b1 M$
-0+
-b10100000 H$
-b1010000011110000 )
-b1010000011110000 A$
-b1010000011110000 N$
-1Y$
-0W$
-b1 Z$
-b1110000011110000 U$
-b111100000111100001100001011010010 ,
-b111100000111100001100001011010010 R$
-14
-1?
-#12050000000000100
-0D$
-10
-0<$
-b10110000 ?$
-b10110000 .
-b10110000 B$
-08$
-b1010000010110000 &
-b1010000010110000 -$
-b1010000010110000 7$
-12$
-00$
-b100101 Q
-b10011 X
-0W
-b1111111 m
-b1111 t
-1s
-b1110000 {
-0z
-b1111111 $"
-b100101 +"
-b10011 2"
-01"
-b1111 N"
-1M"
-b1110000 U"
-0T"
-b1111111 \"
-b100101 c"
-b10011 j"
-0i"
-b1111111 !#
-b1111111 (#
-b1111 /#
-1.#
-b1111111 6#
-b100101 =#
-b10011 D#
-0C#
-b1111111 `#
-b1111 g#
-1f#
-b1111111 n#
-b1001000 u#
-1t#
-b10000 |#
-0{#
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-#12100000000000000
-04
-0?
-#12150000000000000
-1E$
-0.$
-01
-03$
-0B
-0'
-1=$
-1:$
-0$
-1G$
-b11100000 ?$
-b11100000 .
-b11100000 B$
-b11110000011110000 &
-b11110000011110000 -$
-b11110000011110000 7$
-1O
-1)"
-1a"
-1;#
-b10110000 I$
-b1010000010110000 )
-b1010000010110000 A$
-b1010000010110000 N$
-b10 M$
-1+
-0@$
-05$
-b11000 5
-b11100101111101011010010110110101 7
-b11100101111101011010010110110101 "
-b11100101111101011010010110110101 @
-14
-1?
-#12150000000000100
-0E$
-11
-0=$
-b11100001 ?$
-b11100001 .
-b11100001 B$
-0:$
-b1110000111110001 &
-b1110000111110001 -$
-b1110000111110001 7$
-02$
-b100000 |#
-b10010000 u#
-0t#
-b11111111 n#
-b11111 g#
-b11111111 `#
-b1 K#
-b100110 D#
-b1001010 =#
-1<#
-b11111111 6#
-b11111 /#
-b11111111 (#
-b11111111 !#
-b1 q"
-b100110 j"
-b1001010 c"
-1b"
-b11111111 \"
-b11100000 U"
-b11111 N"
-b1 9"
-b100110 2"
-b1001010 +"
-1*"
-b11111111 $"
-b11100000 {
-b11111 t
-b11111111 m
-b1 _
-b100110 X
-b1001010 Q
-1P
-b11100001111100011010000110110001 #
-b11100001111100011010000110110001 A
-b11100001111100011010000110110001 /$
-#12200000000000000
-04
-0?
-#12250000000000000
-1:$
-b11110000011110000 &
-b11110000011110000 -$
-b11110000011110000 7$
-1.$
-12$
-1'
-0O
-1V
-0)"
-10"
-0a"
-1h"
-0;#
-1B#
-0K
-0L
-1M
-0P
-0R
-0S
-0W
-1T
-0Y
-0Z
-1[
-0`
-0a
-1b
-0g
-0h
-1i
-0n
-0o
-1p
-1s
-0u
-0v
-1w
-0z
-0|
-0}
-1~
-0%"
-0&"
-1'"
-0*"
-0,"
-0-"
-01"
-1."
-03"
-04"
-15"
-0:"
-0;"
-1<"
-0A"
-0B"
-1C"
-0H"
-0I"
-1J"
-1M"
-0O"
-0P"
-1Q"
-0T"
-0V"
-0W"
-1X"
-0]"
-0^"
-1_"
-0b"
-0d"
-0e"
-0i"
-1f"
-0k"
-0l"
-1m"
-0r"
-0s"
-1t"
-0y"
-0z"
-1{"
-0"#
-0##
-1$#
-0)#
-0*#
-1+#
-1.#
-00#
-01#
-12#
-07#
-08#
-19#
-0<#
-0>#
-0?#
-0C#
-1@#
-0E#
-0F#
-1G#
-0L#
-0M#
-1N#
-0S#
-0T#
-1U#
-0Z#
-0[#
-1\#
-0a#
-0b#
-1c#
-1f#
-0h#
-0i#
-1j#
-0o#
-0p#
-1q#
-1t#
-0v#
-0w#
-0{#
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-1x#
-0}#
-0~#
-1!$
-0&$
-0'$
-1($
-b11110000 ?$
-b11110000 .
-b11110000 B$
-0G$
-1T$
-b11100 5
-b11100110111101101010011010110110 7
-b11100110111101101010011010110110 "
-b11100110111101101010011010110110 @
-b100 F
-b1011 J
-b101 I
-1@$
-b1 M$
-0+
-b11100001 H$
-b1110000110110000 )
-b1110000110110000 A$
-b1110000110110000 N$
-b10 Z$
-1-
-b1010000010110000 V$
-b111100000111100001010000010110000 ,
-b111100000111100001010000010110000 R$
-14
-1?
-#12250000000000100
-b11110001 ?$
-b11110001 .
-b11110001 B$
-0:$
-b1110000111110001 &
-b1110000111110001 -$
-b1110000111110001 7$
-02$
-b10010101 Q
-1P
-b1001100 X
-b11 _
-b111111111 m
-b111111 t
-b111000000 {
-b111111111 $"
-b10010101 +"
-1*"
-b1001100 2"
-b11 9"
-b111111 N"
-b111000000 U"
-b111111111 \"
-b10010101 c"
-1b"
-b1001100 j"
-b11 q"
-b111111111 !#
-b111111111 (#
-b111111 /#
-b111111111 6#
-b10010101 =#
-1<#
-b1001100 D#
-b11 K#
-b111111111 `#
-b111111 g#
-b111111111 n#
-b100100000 u#
-0t#
-b11100001111100011010000110110001 #
-b11100001111100011010000110110001 A
-b11100001111100011010000110110001 /$
-b1000000 |#
-#12300000000000000
-04
-0?
-#12350000000000000
-0.$
-03$
-0B
-0'
-0$
-12$
-0T$
-1G$
-b10100000 ?$
-b10100000 .
-b10100000 B$
-b1010000010110000 &
-b1010000010110000 -$
-b1010000010110000 7$
-1K
-0P
-1R
-1Y
-1`
-1g
-1n
-1u
-1|
-1%"
-0*"
-1,"
-13"
-1:"
-1A"
-1H"
-1O"
-1V"
-1]"
-0b"
-1d"
-1k"
-1r"
-1y"
-1"#
-1)#
-10#
-17#
-0<#
-1>#
-1E#
-1L#
-1S#
-1Z#
-1a#
-1h#
-1o#
-1t#
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-1v#
-1}#
-1&$
-1O
-1)"
-1a"
-1;#
-b0 Z$
-0-
-b11110001 I$
-b1110000111110001 )
-b1110000111110001 A$
-b1110000111110001 N$
-b10 M$
-1+
-0@$
-15$
-b110 I
-b1010 J
-b101 F
-b100000 5
-b11100111111101111010011110110111 7
-b11100111111101111010011110110111 "
-b11100111111101111010011110110111 @
-14
-1?
-#12350000000000100
-b10100001 ?$
-b10100001 .
-b10100001 B$
-b1010000110110001 &
-b1010000110110001 -$
-b1010000110110001 7$
-02$
-b10000000 |#
-b1001000000 u#
-0t#
-b1111111111 n#
-b1111111 g#
-b1111111111 `#
-b111 K#
-b10011001 D#
-b100101010 =#
-1<#
-b1111111111 6#
-b1111111 /#
-b1111111111 (#
-b1111111111 !#
-b111 q"
-b10011001 j"
-b100101010 c"
-1b"
-b1111111111 \"
-b1110000000 U"
-b1111111 N"
-b111 9"
-b10011001 2"
-b100101010 +"
-1*"
-b1111111111 $"
-b1110000000 {
-b1111111 t
-b1111111111 m
-b111 _
-b10011001 X
-b100101010 Q
-1P
-b11100001111100011010000110110001 #
-b11100001111100011010000110110001 A
-b11100001111100011010000110110001 /$
-#12400000000000000
-04
-0?
-#12450000000000000
-13$
-1B
-b1010000010110000 &
-b1010000010110000 -$
-b1010000010110000 7$
-1.$
-1$
-12$
-1'
-0O
-0V
-0]
-1d
-0)"
-00"
-07"
-1>"
-0a"
-0h"
-0o"
-1v"
-0;#
-0B#
-0I#
-1P#
-1z#
-0K
-1L
-0P
-0R
-1S
-0W
-0Y
-1Z
-0`
-1a
-0g
-1h
-0n
-1o
-1s
-0u
-1v
-0z
-0|
-1}
-0%"
-1&"
-0*"
-0,"
-1-"
-01"
-03"
-14"
-0:"
-1;"
-0A"
-1B"
-0H"
-1I"
-1M"
-0O"
-1P"
-0T"
-0V"
-1W"
-0]"
-1^"
-0b"
-0d"
-1e"
-0i"
-0k"
-1l"
-0r"
-1s"
-0y"
-1z"
-0"#
-1##
-0)#
-1*#
-1.#
-00#
-11#
-07#
-18#
-0<#
-0>#
-1?#
-0C#
-0E#
-1F#
-0L#
-1M#
-0S#
-1T#
-0Z#
-1[#
-0a#
-1b#
-1f#
-0h#
-1i#
-0o#
-1t#
-1p#
-0v#
-1w#
-0{#
-b111100000111100001010000010110000 #
-b111100000111100001010000010110000 A
-b111100000111100001010000010110000 /$
-0}#
-1~#
-0&$
-1'$
-b10110000 ?$
-b10110000 .
-b10110000 B$
-0G$
-18
-b11101000111110001010100010111000 7
-b1011101000111110001010100010111000 "
-b1011101000111110001010100010111000 @
-b110 F
-b1001 J
-b111 I
-1@$
-b1 M$
-0+
-b10100001 H$
-b1010000111110001 )
-b1010000111110001 A$
-b1010000111110001 N$
-0Y$
-b1 Z$
-b1110000111110001 U$
-b11100001111100011010000010110000 ,
-b11100001111100011010000010110000 R$
-14
-1?
-#12450000000000100
-b10110001 ?$
-b10110001 .
-b10110001 B$
-b1010000110110001 &
-b1010000110110001 -$
-b1010000110110001 7$
-02$
-b1001010101 Q
-1P
-b100110011 X
-b1111 _
-b11111111111 m
-b11111111 t
-b11100000000 {
-b11111111111 $"
-b1001010101 +"
-1*"
-b100110011 2"
-b1111 9"
-b11111111 N"
-b11100000000 U"
-b11111111111 \"
-b1001010101 c"
-1b"
-b100110011 j"
-b1111 q"
-b11111111111 !#
-b11111111111 (#
-b11111111 /#
-b11111111111 6#
-b1001010101 =#
-1<#
-b100110011 D#
-b1111 K#
-b11111111111 `#
-b11111111 g#
-b11111111111 n#
-b10010000000 u#
-0t#
-b11100001111100011010000110110001 #
-b11100001111100011010000110110001 A
-b11100001111100011010000110110001 /$
-b100000000 |#
-#12500000000000000
-04
-0?
-#12550000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100001 ?$
-b11100001 .
-b11100001 B$
-b1110000111110001 &
-b1110000111110001 -$
-b1110000111110001 7$
-0E
-0d
-0k
-0r
-0""
-0>"
-0L"
-0Z"
-0v"
-0}"
-0&#
-0-#
-04#
-0P#
-0^#
-0e#
-0l#
-0z#
-b10110001 I$
-b1010000110110001 )
-b1010000110110001 A$
-b1010000110110001 N$
-b10 M$
-1+
-0@$
-05$
-0=
-0D
-b0 7
-08
-b0 "
-b0 @
-14
-1?
-#12550000000000100
-b11100010 ?$
-b11100010 .
-b11100010 B$
-b1110001011110010 &
-b1110001011110010 -$
-b1110001011110010 7$
-b1000000001 |#
-b100100000000 u#
-b111111111111 n#
-b111111111 g#
-b111111111111 `#
-b1 R#
-b11110 K#
-b1001100110 D#
-1C#
-b10010101010 =#
-0<#
-b111111111111 6#
-b111111111 /#
-b111111111111 (#
-b111111111111 !#
-b1 x"
-b11110 q"
-b1001100110 j"
-1i"
-b10010101010 c"
-0b"
-b111111111111 \"
-b111000000000 U"
-b111111111 N"
-b1 @"
-b11110 9"
-b1001100110 2"
-11"
-b10010101010 +"
-0*"
-b111111111111 $"
-b111000000000 {
-b111111111 t
-b111111111111 m
-b1 f
-b11110 _
-b1001100110 X
-1W
-b10010101010 Q
-0P
-b11100010111100101010001010110010 #
-b11100010111100101010001010110010 A
-b11100010111100101010001010110010 /$
-#12600000000000000
-04
-0?
-#12650000000000000
-1.$
-1'
-b11110010 ?$
-b11110010 .
-b11110010 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100010 H$
-b1110001010110001 )
-b1110001010110001 A$
-b1110001010110001 N$
-b10 Z$
-1-
-b1010000110110001 V$
-b11100001111100011010000110110001 ,
-b11100001111100011010000110110001 R$
-14
-1?
-#12700000000000000
-04
-0?
-#12750000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100010 ?$
-b10100010 .
-b10100010 B$
-b1010001010110010 &
-b1010001010110010 -$
-b1010001010110010 7$
-b0 Z$
-0-
-b11110010 I$
-b1110001011110010 )
-b1110001011110010 A$
-b1110001011110010 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#12800000000000000
-04
-0?
-#12850000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110010 ?$
-b10110010 .
-b10110010 B$
-0G$
-1@$
-b1 M$
-0+
-b10100010 H$
-b1010001011110010 )
-b1010001011110010 A$
-b1010001011110010 N$
-b1 Z$
-b1110001011110010 U$
-b11100010111100101010000110110001 ,
-b11100010111100101010000110110001 R$
-14
-1?
-#12900000000000000
-04
-0?
-#12950000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100011 ?$
-b11100011 .
-b11100011 B$
-b1110001111110011 &
-b1110001111110011 -$
-b1110001111110011 7$
-1K
-1P
-0L
-1R
-0S
-1W
-1Y
-0Z
-0^
-1`
-0a
-1g
-0h
-1n
-0o
-1u
-0v
-1|
-0}
-1%"
-1*"
-0&"
-1,"
-0-"
-11"
-13"
-04"
-08"
-1:"
-0;"
-1A"
-0B"
-1H"
-0I"
-1O"
-0P"
-1V"
-0W"
-1]"
-1b"
-0^"
-1d"
-0e"
-1i"
-1k"
-0l"
-0p"
-1r"
-0s"
-1y"
-0z"
-1"#
-0##
-1)#
-0*#
-10#
-01#
-17#
-1<#
-08#
-1>#
-0?#
-1C#
-1E#
-0F#
-0J#
-b11100011111100111010001110110011 #
-b11100011111100111010001110110011 A
-b11100011111100111010001110110011 /$
-1L#
-0M#
-1S#
-0T#
-1Z#
-0[#
-1a#
-0b#
-1h#
-0i#
-1o#
-0p#
-1v#
-0w#
-1}#
-0~#
-1&$
-0'$
-b10110010 I$
-b1010001010110010 )
-b1010001010110010 A$
-b1010001010110010 N$
-b10 M$
-1+
-0@$
-05$
-b110 I
-b1010 J
-b101 F
-14
-1?
-#13000000000000000
-04
-0?
-#13050000000000000
-1.$
-1'
-b11110011 ?$
-b11110011 .
-b11110011 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100011 H$
-b1110001110110010 )
-b1110001110110010 A$
-b1110001110110010 N$
-b10 Z$
-1-
-b1010001010110010 V$
-b11100010111100101010001010110010 ,
-b11100010111100101010001010110010 R$
-14
-1?
-#13100000000000000
-04
-0?
-#13150000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100011 ?$
-b10100011 .
-b10100011 B$
-b1010001110110011 &
-b1010001110110011 -$
-b1010001110110011 7$
-b0 Z$
-0-
-b11110011 I$
-b1110001111110011 )
-b1110001111110011 A$
-b1110001111110011 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#13200000000000000
-04
-0?
-#13250000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110011 ?$
-b10110011 .
-b10110011 B$
-0G$
-1@$
-b1 M$
-0+
-b10100011 H$
-b1010001111110011 )
-b1010001111110011 A$
-b1010001111110011 N$
-b1 Z$
-b1110001111110011 U$
-b11100011111100111010001010110010 ,
-b11100011111100111010001010110010 R$
-14
-1?
-#13300000000000000
-04
-0?
-#13350000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100100 ?$
-b11100100 .
-b11100100 B$
-b1110010011110100 &
-b1110010011110100 -$
-b1110010011110100 7$
-0K
-0P
-0R
-0W
-0Y
-1^
-0`
-0g
-0n
-0u
-0|
-0%"
-0*"
-0,"
-01"
-03"
-18"
-0:"
-0A"
-0H"
-0O"
-0V"
-0]"
-0b"
-0d"
-0i"
-0k"
-1p"
-0r"
-0y"
-0"#
-0)#
-00#
-07#
-0<#
-0>#
-0C#
-0E#
-1J#
-b11100100111101001010010010110100 #
-b11100100111101001010010010110100 A
-b11100100111101001010010010110100 /$
-0L#
-0S#
-0Z#
-0a#
-0h#
-0o#
-0v#
-0}#
-0&$
-b10110011 I$
-b1010001110110011 )
-b1010001110110011 A$
-b1010001110110011 N$
-b10 M$
-1+
-0@$
-05$
-b101 I
-b1011 J
-b100 F
-14
-1?
-#13400000000000000
-04
-0?
-#13450000000000000
-1.$
-1'
-b11110100 ?$
-b11110100 .
-b11110100 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100100 H$
-b1110010010110011 )
-b1110010010110011 A$
-b1110010010110011 N$
-b10 Z$
-1-
-b1010001110110011 V$
-b11100011111100111010001110110011 ,
-b11100011111100111010001110110011 R$
-14
-1?
-#13500000000000000
-04
-0?
-#13550000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100100 ?$
-b10100100 .
-b10100100 B$
-b1010010010110100 &
-b1010010010110100 -$
-b1010010010110100 7$
-b0 Z$
-0-
-b11110100 I$
-b1110010011110100 )
-b1110010011110100 A$
-b1110010011110100 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#13600000000000000
-04
-0?
-#13650000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110100 ?$
-b10110100 .
-b10110100 B$
-0G$
-1@$
-b1 M$
-0+
-b10100100 H$
-b1010010011110100 )
-b1010010011110100 A$
-b1010010011110100 N$
-b1 Z$
-b1110010011110100 U$
-b11100100111101001010001110110011 ,
-b11100100111101001010001110110011 R$
-14
-1?
-#13700000000000000
-04
-0?
-#13750000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100101 ?$
-b11100101 .
-b11100101 B$
-b1110010111110101 &
-b1110010111110101 -$
-b1110010111110101 7$
-1K
-1P
-1L
-0M
-1R
-1S
-0W
-0T
-1Y
-1Z
-0[
-1^
-1`
-1a
-0b
-0e
-1g
-1h
-0i
-1n
-1o
-0p
-1u
-1v
-0w
-1|
-1}
-0~
-1%"
-1*"
-1&"
-0'"
-1,"
-1-"
-01"
-0."
-13"
-14"
-05"
-18"
-1:"
-1;"
-0<"
-0?"
-1A"
-1B"
-0C"
-1H"
-1I"
-0J"
-1O"
-1P"
-0Q"
-1V"
-1W"
-0X"
-1]"
-1b"
-1^"
-0_"
-1d"
-1e"
-0i"
-0f"
-1k"
-1l"
-0m"
-1p"
-1r"
-1s"
-0t"
-0w"
-1y"
-1z"
-0{"
-1"#
-1##
-0$#
-1)#
-1*#
-0+#
-10#
-11#
-02#
-17#
-1<#
-18#
-09#
-1>#
-1?#
-0C#
-0@#
-1E#
-1F#
-0G#
-1J#
-1L#
-1M#
-0N#
-0Q#
-1S#
-1T#
-0U#
-1Z#
-1[#
-0\#
-1a#
-1b#
-0c#
-1h#
-1i#
-0j#
-1o#
-1p#
-0q#
-1v#
-1w#
-0x#
-0{#
-b11100101111101011010010110110101 #
-b11100101111101011010010110110101 A
-b11100101111101011010010110110101 /$
-1}#
-1~#
-0!$
-1&$
-1'$
-0($
-b10110100 I$
-b1010010010110100 )
-b1010010010110100 A$
-b1010010010110100 N$
-b10 M$
-1+
-0@$
-05$
-b100 I
-b1100 J
-b11 F
-14
-1?
-#13800000000000000
-04
-0?
-#13850000000000000
-1.$
-1'
-b11110101 ?$
-b11110101 .
-b11110101 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100101 H$
-b1110010110110100 )
-b1110010110110100 A$
-b1110010110110100 N$
-b10 Z$
-1-
-b1010010010110100 V$
-b11100100111101001010010010110100 ,
-b11100100111101001010010010110100 R$
-14
-1?
-#13900000000000000
-04
-0?
-#13950000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100101 ?$
-b10100101 .
-b10100101 B$
-b1010010110110101 &
-b1010010110110101 -$
-b1010010110110101 7$
-b0 Z$
-0-
-b11110101 I$
-b1110010111110101 )
-b1110010111110101 A$
-b1110010111110101 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#14000000000000000
-04
-0?
-#14050000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110101 ?$
-b10110101 .
-b10110101 B$
-0G$
-1@$
-b1 M$
-0+
-b10100101 H$
-b1010010111110101 )
-b1010010111110101 A$
-b1010010111110101 N$
-b1 Z$
-b1110010111110101 U$
-b11100101111101011010010010110100 ,
-b11100101111101011010010010110100 R$
-14
-1?
-#14100000000000000
-04
-0?
-#14150000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100110 ?$
-b11100110 .
-b11100110 B$
-b1110011011110110 &
-b1110011011110110 -$
-b1110011011110110 7$
-0K
-0P
-0R
-1W
-0Y
-0`
-0g
-0n
-0u
-0|
-0%"
-0*"
-0,"
-11"
-03"
-0:"
-0A"
-0H"
-0O"
-0V"
-0]"
-0b"
-0d"
-1i"
-0k"
-0r"
-0y"
-0"#
-0)#
-00#
-07#
-0<#
-0>#
-1C#
-b11100110111101101010011010110110 #
-b11100110111101101010011010110110 A
-b11100110111101101010011010110110 /$
-0E#
-0L#
-0S#
-0Z#
-0a#
-0h#
-0o#
-0v#
-0}#
-0&$
-b10110101 I$
-b1010010110110101 )
-b1010010110110101 A$
-b1010010110110101 N$
-b10 M$
-1+
-0@$
-05$
-b11 I
-b1101 J
-b10 F
-14
-1?
-#14200000000000000
-04
-0?
-#14250000000000000
-1.$
-1'
-b11110110 ?$
-b11110110 .
-b11110110 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100110 H$
-b1110011010110101 )
-b1110011010110101 A$
-b1110011010110101 N$
-b10 Z$
-1-
-b1010010110110101 V$
-b11100101111101011010010110110101 ,
-b11100101111101011010010110110101 R$
-14
-1?
-#14300000000000000
-04
-0?
-#14350000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100110 ?$
-b10100110 .
-b10100110 B$
-b1010011010110110 &
-b1010011010110110 -$
-b1010011010110110 7$
-b0 Z$
-0-
-b11110110 I$
-b1110011011110110 )
-b1110011011110110 A$
-b1110011011110110 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#14400000000000000
-04
-0?
-#14450000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110110 ?$
-b10110110 .
-b10110110 B$
-0G$
-1@$
-b1 M$
-0+
-b10100110 H$
-b1010011011110110 )
-b1010011011110110 A$
-b1010011011110110 N$
-b1 Z$
-b1110011011110110 U$
-b11100110111101101010010110110101 ,
-b11100110111101101010010110110101 R$
-14
-1?
-#14500000000000000
-04
-0?
-#14550000000000000
-0.$
-03$
-0B
-0'
-0$
-1G$
-b11100111 ?$
-b11100111 .
-b11100111 B$
-b1110011111110111 &
-b1110011111110111 -$
-b1110011111110111 7$
-1K
-1P
-0L
-1R
-0S
-1W
-1Y
-0Z
-1^
-1`
-0a
-0e
-1g
-0h
-1n
-0o
-1u
-0v
-1|
-0}
-1%"
-1*"
-0&"
-1,"
-0-"
-11"
-13"
-04"
-18"
-1:"
-0;"
-0?"
-1A"
-0B"
-1H"
-0I"
-1O"
-0P"
-1V"
-0W"
-1]"
-1b"
-0^"
-1d"
-0e"
-1i"
-1k"
-0l"
-1p"
-1r"
-0s"
-0w"
-1y"
-0z"
-1"#
-0##
-1)#
-0*#
-10#
-01#
-17#
-1<#
-08#
-1>#
-0?#
-1C#
-1E#
-0F#
-1J#
-1L#
-0M#
-0Q#
-1S#
-0T#
-1Z#
-0[#
-1a#
-0b#
-1h#
-0i#
-1o#
-0p#
-1v#
-0w#
-0{#
-b11100111111101111010011110110111 #
-b11100111111101111010011110110111 A
-b11100111111101111010011110110111 /$
-1}#
-0~#
-1&$
-0'$
-b10110110 I$
-b1010011010110110 )
-b1010011010110110 A$
-b1010011010110110 N$
-b10 M$
-1+
-0@$
-05$
-b10 I
-b1110 J
-b1 F
-14
-1?
-#14600000000000000
-04
-0?
-#14650000000000000
-1.$
-1'
-b11110111 ?$
-b11110111 .
-b11110111 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11100111 H$
-b1110011110110110 )
-b1110011110110110 A$
-b1110011110110110 N$
-b10 Z$
-1-
-b1010011010110110 V$
-b11100110111101101010011010110110 ,
-b11100110111101101010011010110110 R$
-14
-1?
-#14700000000000000
-04
-0?
-#14750000000000000
-0.$
-03$
-0B
-0'
-0$
-0T$
-1G$
-b10100111 ?$
-b10100111 .
-b10100111 B$
-b1010011110110111 &
-b1010011110110111 -$
-b1010011110110111 7$
-b0 Z$
-0-
-b11110111 I$
-b1110011111110111 )
-b1110011111110111 A$
-b1110011111110111 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#14800000000000000
-04
-0?
-#14850000000000000
-13$
-1B
-1.$
-1$
-1'
-b10110111 ?$
-b10110111 .
-b10110111 B$
-0G$
-1@$
-b1 M$
-0+
-b10100111 H$
-b1010011111110111 )
-b1010011111110111 A$
-b1010011111110111 N$
-b1 Z$
-b1110011111110111 U$
-b11100111111101111010011010110110 ,
-b11100111111101111010011010110110 R$
-14
-1?
-#14900000000000000
-04
-0?
-#14950000000000000
-0.$
-03$
-0B
-0'
-0$
-10$
-1G$
-b11101000 ?$
-b11101000 .
-b11101000 B$
-b1110100011111000 &
-b1110100011111000 -$
-b1110100011111000 7$
-0K
-0P
-0R
-0W
-0Y
-0^
-0`
-1e
-0g
-0n
-0u
-0|
-0%"
-0*"
-0,"
-01"
-03"
-08"
-0:"
-1?"
-0A"
-0H"
-0O"
-0V"
-0]"
-0b"
-0d"
-0i"
-0k"
-0p"
-0r"
-1w"
-0y"
-0"#
-0)#
-00#
-07#
-0<#
-0>#
-0C#
-0E#
-0J#
-0L#
-1Q#
-0S#
-0Z#
-0a#
-0h#
-0o#
-0v#
-1{#
-b1011101000111110001010100010111000 #
-b1011101000111110001010100010111000 A
-b1011101000111110001010100010111000 /$
-0}#
-0&$
-b10110111 I$
-b1010011110110111 )
-b1010011110110111 A$
-b1010011110110111 N$
-b10 M$
-1+
-0@$
-05$
-b1 I
-b1111 J
-b0 F
-14
-1?
-#15000000000000000
-04
-0?
-#15050000000000000
-1.$
-1'
-b11111000 ?$
-b11111000 .
-b11111000 B$
-0G$
-1T$
-1@$
-b1 M$
-0+
-b11101000 H$
-b1110100010110111 )
-b1110100010110111 A$
-b1110100010110111 N$
-b10 Z$
-1-
-b1010011110110111 V$
-b11100111111101111010011110110111 ,
-b11100111111101111010011110110111 R$
-14
-1?
-#15100000000000000
-04
-0?
-#15150000000000000
-0.$
-03$
-0B
-0'
-18$
-0$
-0T$
-1G$
-b10101000 ?$
-b10101000 .
-b10101000 B$
-b101010100010111000 &
-b101010100010111000 -$
-b101010100010111000 7$
-b0 Z$
-0-
-b11111000 I$
-b1110100011111000 )
-b1110100011111000 A$
-b1110100011111000 N$
-b10 M$
-1+
-0@$
-15$
-14
-1?
-#15200000000000000
-04
-0?
-#15250000000000000
-1D$
-13$
-1B
-00
-1.$
-1$
-1<$
-1'
-b10111000 ?$
-b10111000 .
-b10111000 B$
-0G$
-1@$
-b1 M$
-0+
-b10101000 H$
-b1010100011111000 )
-b1010100011111000 A$
-b1010100011111000 N$
-b1 Z$
-b1110100011111000 U$
-b11101000111110001010011110110111 ,
-b11101000111110001010011110110111 R$
-14
-1?
-#15300000000000000
-04
-0?
-#15350000000000000
-0D$
-10
-0'
-0F$
-0<$
-08$
-0$
-0.$
-06$
-12
-03$
-0B
-1G$
-1O$
-b11101000 ?$
-b11101000 .
-b11101000 B$
-b1110100011111000 &
-b1110100011111000 -$
-b1110100011111000 7$
-0>$
-0(
-0%
-b10111000 I$
-b10 M$
-1+
-1J$
-b101010100010111000 )
-b101010100010111000 A$
-b101010100010111000 N$
-0@$
-05$
-b0 I
-b10000 J
-1G
-14
-1?
-#15400000000000000
-04
-0?
-#15450000000000000
-0G$
-1T$
-b0 M$
-0+
-1W$
-b10 Z$
-1-
-b1010100010111000 V$
-b1011101000111110001010100010111000 ,
-b1011101000111110001010100010111000 R$
-14
-1?
-#15500000000000000
-04
-0?
-#15550000000000000
-0T$
-b0 Z$
-0-
-14
-1?
-#15600000000000000
-04
-0?
-#15650000000000000
-14
-1?
-#15700000000000000
-04
-0?
-#15750000000000000
-14
-1?
-#15800000000000000
-04
-0?
-#15850000000000000
-14
-1?
-#15900000000000000
-04
-0?
-#15950000000000000
-14
-1?
-#16000000000000000
-04
-0?
-#16050000000000000
-14
-1?
-#16100000000000000
-04
-0?
-#16150000000000000
-14
-1?
-#16200000000000000
-04
-0?
-#16250000000000000
-14
-1?
-#16300000000000000
-04
-0?
-#16350000000000000
-14
-1?
-#16400000000000000
-04
-0?
-#16450000000000000
-14
-1?
-#16500000000000000
-04
-0?
-#16550000000000000
-14
-1?
-#16600000000000000
-04
-0?
-#16650000000000000
-14
-1?
-#16700000000000000
-04
-0?
-#16750000000000000
-14
-1?
-#16800000000000000
-04
-0?
-#16850000000000000
-14
-1?
-#16900000000000000
-04
-0?
-#16950000000000000
-14
-1?
-#17000000000000000
-04
-0?
-#17050000000000000
-14
-1?
-#17100000000000000
-04
-0?
-#17150000000000000
-14
-1?
-#17200000000000000
-04
-0?
-#17250000000000000
-14
-1?
-#17300000000000000
-04
-0?
-#17350000000000000
-14
-1?
-#17400000000000000
-04
-0?
-#17450000000000000
-14
-1?
-#17500000000000000
-04
-0?
-#17550000000000000
-14
-1?
-#17600000000000000
-04
-0?
-#17650000000000000
-14
-1?
-#17700000000000000
-04
-0?
-#17750000000000000
-14
-1?
-#17800000000000000
-04
-0?
-#17850000000000000
-14
-1?
-#17900000000000000
-04
-0?
-#17950000000000000
-14
-1?
-#18000000000000000
-04
-0?
-#18050000000000000
-14
-1?
-#18100000000000000
-04
-0?
-#18150000000000000
-14
-1?
-#18200000000000000
-04
-0?
-#18250000000000000
-14
-1?
-#18300000000000000
-04
-0?
-#18350000000000000
-14
-1?
-#18400000000000000
-04
-0?
-#18450000000000000
-14
-1?
-#18500000000000000
-04
-0?
-#18550000000000000
-14
-1?
-#18600000000000000
-04
-0?
-#18650000000000000
-14
-1?
-#18700000000000000
-04
-0?
-#18750000000000000
-14
-1?
-#18800000000000000
-04
-0?
-#18850000000000000
-14
-1?
-#18900000000000000
-04
-0?
-#18950000000000000
-14
-1?
-#19000000000000000
-04
-0?
-#19050000000000000
-14
-1?
-#19100000000000000
-04
-0?
-#19150000000000000
-14
-1?
-#19200000000000000
-04
-0?
-#19250000000000000
-14
-1?
-#19300000000000000
-04
-0?
-#19350000000000000
-14
-1?
-#19400000000000000
-04
-0?
-#19450000000000000
-14
-1?
-#19500000000000000
-04
-0?
-#19550000000000000
-14
-1?
-#19600000000000000
-04
-0?
-#19650000000000000
-14
-1?
-#19700000000000000
-04
-0?
-#19750000000000000
-14
-1?
-#19800000000000000
-04
-0?
-#19850000000000000
-14
-1?
-#19900000000000000
-04
-0?
-#19950000000000000
-14
-1?
-#20000000000000000
-04
-0?
diff --git a/fpga/usrp2/fifo/fifo_tb.v b/fpga/usrp2/fifo/fifo_tb.v
index f561df7fa..327da4700 100644
--- a/fpga/usrp2/fifo/fifo_tb.v
+++ b/fpga/usrp2/fifo/fifo_tb.v
@@ -24,20 +24,39 @@ module fifo_new_tb();
wire i1_sr, i1_dr;
wire i2_sr, i2_dr;
wire i3_sr, i3_dr;
+ wire i7_sr, i7_dr;
+
reg i4_dr = 0;
wire i4_sr;
- wire [35:0] i1, i4;
+ wire [35:0] i1, i4, i7;
wire [18:0] i2, i3;
wire [7:0] ll_data;
wire ll_src_rdy_n, ll_dst_rdy_n, ll_sof_n, ll_eof_n;
+ wire [35:0] err_dat;
+ wire err_src_rdy, err_dst_rdy;
+
+ reg trigger = 0;
+ initial #10000 trigger = 1;
fifo_short #(.WIDTH(36)) fifo_short1
(.clk(clk),.reset(rst),.clear(clear),
.datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i),
- .dataout(i1),.src_rdy_o(i1_sr),.dst_rdy_i(i1_dr) );
+ .dataout(i7),.src_rdy_o(i7_sr),.dst_rdy_i(i7_dr) );
+ gen_context_pkt #(.PROT_ENG_FLAGS(1)) gcp
+ (.clk(clk),.reset(rst),.clear(clear),
+ .trigger(trigger), .sent(),
+ .streamid(32'hDEAD_F00D), .vita_time(64'h01234567_89ABCDEF), .message(32'hBEEF_2940),
+ .data_o(err_dat), .src_rdy_o(err_src_rdy), .dst_rdy_i(err_dst_rdy));
+
+ fifo36_mux #(.prio(0)) fifo36_mux
+ (.clk(clk), .reset(rst), .clear(clear),
+ .data0_i(i7), .src0_rdy_i(i7_sr), .dst0_rdy_o(i7_dr),
+ .data1_i(err_dat), .src1_rdy_i(err_src_rdy), .dst1_rdy_o(err_dst_rdy),
+ .data_o(i1), .src_rdy_o(i1_sr), .dst_rdy_i(i1_dr));
+
fifo36_to_fifo19 fifo36_to_fifo19
(.clk(clk),.reset(rst),.clear(clear),
.f36_datain(i1),.f36_src_rdy_i(i1_sr),.f36_dst_rdy_o(i1_dr),
@@ -59,7 +78,7 @@ module fifo_new_tb();
(.clk(clk),.reset(rst),.clear(clear),
.f19_datain(i3),.f19_src_rdy_i(i3_sr),.f19_dst_rdy_o(i3_dr),
.f36_dataout(i4),.f36_src_rdy_o(i4_sr),.f36_dst_rdy_i(i4_dr) );
-
+
task ReadFromFIFO36;
begin
$display("Read from FIFO36");
diff --git a/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_bpcu.v b/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_bpcu.v
index a7c686e7e..81587e25c 100644
--- a/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_bpcu.v
+++ b/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_bpcu.v
@@ -125,7 +125,7 @@ module aeMB_bpcu (/*AUTOARG*/
reg [31:2] rPC, xPC;
reg [31:2] rPCLNK, xPCLNK;
- assign iwb_adr_o = rIPC[IW-1:2];
+ assign iwb_adr_o = gena ? xIPC[IW-1:2] : rIPC[IW-1:2]; //IJB
always @(/*AUTOSENSE*/rBRA or rIPC or rPC or rRESULT) begin
//xPCLNK <= (^rATOM) ? rPC : rPC;
@@ -168,7 +168,8 @@ module aeMB_bpcu (/*AUTOARG*/
rATOM <= 2'h0;
rBRA <= 1'h0;
rDLY <= 1'h0;
- rIPC <= 30'h0;
+// rIPC <= 30'h0;
+ rIPC <= 30'h3fffffff; // DWORD aligned address
rPC <= 30'h0;
rPCLNK <= 30'h0;
// End of automatics
diff --git a/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_core_BE.v b/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_core_BE.v
index 9ffa20ff2..38ca3a023 100644
--- a/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_core_BE.v
+++ b/fpga/usrp2/opencores/aemb/rtl/verilog/aeMB_core_BE.v
@@ -10,12 +10,10 @@ module aeMB_core_BE
parameter MUL=0, parameter BSF=0)
(input sys_clk_i,
input sys_rst_i,
-
- output iwb_stb_o,
- output [ISIZ-1:0] iwb_adr_o,
- input [31:0] iwb_dat_i,
- input iwb_ack_i,
-
+ // Instruction port
+ output [14:0] if_adr,
+ input [31:0] if_dat,
+ // Data port
output dwb_we_o,
output dwb_stb_o,
output [DSIZ-1:0] dwb_adr_o,
@@ -28,17 +26,28 @@ module aeMB_core_BE
input sys_int_i,
input sys_exc_i);
- assign dwb_cyc_o = dwb_stb_o;
+ wire [ISIZ-1:0] iwb_adr_o;
+ wire [31:0] iwb_dat_i;
+ wire iwb_ack_i;
+ wire iwb_stb_o;
+
+ assign dwb_cyc_o = dwb_stb_o;
+ assign iwb_ack_i = 1'b1;
+ assign if_adr = iwb_adr_o[14:0];
+ assign iwb_dat_i = if_dat;
+
+ // Note some "wishbone" instruction fetch signals pruned on external interface
+ // but not propogated change deep into aeMB.
aeMB_edk32 #(.IW(ISIZ),.DW(DSIZ),.MUL(MUL),.BSF(BSF))
aeMB_edk32 (.sys_clk_i(sys_clk_i),
.sys_rst_i(sys_rst_i),
-
+ // Instruction Port
.iwb_stb_o(iwb_stb_o),
.iwb_adr_o(iwb_adr_o[ISIZ-1:2]),
.iwb_ack_i(iwb_ack_i),
.iwb_dat_i(iwb_dat_i),
-
+ // Data port
.dwb_wre_o(dwb_we_o),
.dwb_stb_o(dwb_stb_o),
.dwb_adr_o(dwb_adr_o[DSIZ-1:2]),
diff --git a/fpga/usrp2/sdr_lib/dsp_core_tx.v b/fpga/usrp2/sdr_lib/dsp_core_tx.v
index 22d3d44a3..79d92c9b3 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_tx.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_tx.v
@@ -29,11 +29,11 @@ module dsp_core_tx
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({scale_i,scale_q}),.changed());
- setting_reg #(.my_addr(BASE+2)) sr_2
+ setting_reg #(.my_addr(BASE+2), .width(10)) sr_2
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({enable_hb1, enable_hb2, interp_rate}),.changed());
- setting_reg #(.my_addr(BASE+4)) sr_4
+ setting_reg #(.my_addr(BASE+4), .width(8)) sr_4
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({dacmux_b,dacmux_a}),.changed());
diff --git a/fpga/usrp2/top/Makefile.common b/fpga/usrp2/top/Makefile.common
index d0435fa1e..4da64ac28 100644
--- a/fpga/usrp2/top/Makefile.common
+++ b/fpga/usrp2/top/Makefile.common
@@ -47,7 +47,7 @@ $(ISE_FILE): $$(SOURCES) $$(MAKEFILE_LIST)
@echo $@
$(ISE_HELPER) ""
-$(BIN_FILE): $(ISE_FILE)
+$(BIN_FILE): $(ISE_FILE) $$(SOURCES) $$(MAKEFILE_LIST)
@echo $@
$(ISE_HELPER) "Generate Programming File"
touch $@
diff --git a/fpga/usrp2/top/u2_rev3/u2_core.v b/fpga/usrp2/top/u2_rev3/u2_core.v
index b67d8edd6..9ba3cc136 100644..100755
--- a/fpga/usrp2/top/u2_rev3/u2_core.v
+++ b/fpga/usrp2/top/u2_rev3/u2_core.v
@@ -277,33 +277,33 @@ module u2_core
// ///////////////////////////////////////////////////////////////////
// RAM Loader
- wire [31:0] ram_loader_dat, iwb_dat;
- wire [15:0] ram_loader_adr, iwb_adr;
+ wire [31:0] ram_loader_dat, if_dat;
+ wire [15:0] ram_loader_adr;
+ wire [14:0] if_adr;
wire [3:0] ram_loader_sel;
- wire ram_loader_stb, ram_loader_we, ram_loader_ack;
+ wire ram_loader_stb, ram_loader_we;
wire iwb_ack, iwb_stb;
ram_loader #(.AWIDTH(16),.RAM_SIZE(RAM_SIZE))
- ram_loader (.clk_i(wb_clk),.rst_i(ram_loader_rst),
+ ram_loader (.wb_clk(wb_clk),.dsp_clk(dsp_clk),.ram_loader_rst(ram_loader_rst),
+ .wb_dat(ram_loader_dat),.wb_adr(ram_loader_adr),
+ .wb_stb(ram_loader_stb),.wb_sel(ram_loader_sel),
+ .wb_we(ram_loader_we),
+ .ram_loader_done(ram_loader_done),
// CPLD Interface
- .cfg_clk_i(cpld_clk),
- .cfg_data_i(cpld_din),
- .start_o(cpld_start_int),
- .mode_o(cpld_mode_int),
- .done_o(cpld_done_int),
- .detached_i(cpld_detached),
- // Wishbone Interface
- .wb_dat_o(ram_loader_dat),.wb_adr_o(ram_loader_adr),
- .wb_stb_o(ram_loader_stb),.wb_cyc_o(),.wb_sel_o(ram_loader_sel),
- .wb_we_o(ram_loader_we),.wb_ack_i(ram_loader_ack),
- .ram_loader_done_o(ram_loader_done));
-
+ .cpld_clk(cpld_clk),
+ .cpld_din(cpld_din),
+ .cpld_start(cpld_start_int),
+ .cpld_mode(cpld_mode_int),
+ .cpld_done(cpld_done_int),
+ .cpld_detached(cpld_detached));
+
// /////////////////////////////////////////////////////////////////////////
// Processor
aeMB_core_BE #(.ISIZ(16),.DSIZ(16),.MUL(0),.BSF(1))
aeMB (.sys_clk_i(wb_clk), .sys_rst_i(wb_rst),
// Instruction Wishbone bus to I-RAM
- .iwb_stb_o(iwb_stb),.iwb_adr_o(iwb_adr),
- .iwb_dat_i(iwb_dat),.iwb_ack_i(iwb_ack),
+ .if_adr(if_adr),
+ .if_dat(if_dat),
// Data Wishbone bus to system bus fabric
.dwb_we_o(m0_we),.dwb_stb_o(m0_stb),.dwb_dat_o(m0_dat_i),.dwb_adr_o(m0_adr),
.dwb_dat_i(m0_dat_o),.dwb_ack_i(m0_ack),.dwb_sel_o(m0_sel),.dwb_cyc_o(m0_cyc),
@@ -317,16 +317,16 @@ module u2_core
// I-port connects directly to processor and ram loader
wire flush_icache;
- ram_harv_cache #(.AWIDTH(15),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
+ ram_harvard #(.AWIDTH(15),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
sys_ram(.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
.ram_loader_adr_i(ram_loader_adr[14:0]), .ram_loader_dat_i(ram_loader_dat),
.ram_loader_stb_i(ram_loader_stb), .ram_loader_sel_i(ram_loader_sel),
- .ram_loader_we_i(ram_loader_we), .ram_loader_ack_o(ram_loader_ack),
+ .ram_loader_we_i(ram_loader_we),
.ram_loader_done_i(ram_loader_done),
- .iwb_adr_i(iwb_adr[14:0]), .iwb_stb_i(iwb_stb),
- .iwb_dat_o(iwb_dat), .iwb_ack_o(iwb_ack),
+ .if_adr(if_adr),
+ .if_data(if_dat),
.dwb_adr_i(s0_adr[14:0]), .dwb_dat_i(s0_dat_o), .dwb_dat_o(s0_dat_i),
.dwb_we_i(s0_we), .dwb_ack_o(s0_ack), .dwb_stb_i(s0_stb), .dwb_sel_i(s0_sel),
@@ -622,7 +622,7 @@ module u2_core
// ///////////////////////////////////////////////////////////////////////////////////
// External RAM Interface
-
+/*
localparam PAGE_SIZE = 10; // PAGE SIZE is in bytes, 10 = 1024 bytes
wire [15:0] bus2ram, ram2bus;
@@ -650,6 +650,7 @@ module u2_core
.sram_bw(),.sram_adv(RAM_LDn),.sram_ce(RAM_CENn),.sram_oe(RAM_OEn),
.sram_mode(),.sram_zz() );
+*/
assign RAM_CE1n = 0;
assign RAM_D[17:16] = 2'bzz;
@@ -700,7 +701,8 @@ module u2_core
{ wr2_flags, rd2_flags },
{ GMII_TX_EN,3'd0, wr2_ready_i, wr2_ready_o, rd2_ready_i, rd2_ready_o } };
- assign debug_gpio_0 = debug_mac; //eth_mac_debug;
+ assign debug_gpio_0 = 0;
+ //debug_mac; //eth_mac_debug;
assign debug_gpio_1 = 0;
endmodule // u2_core
diff --git a/fpga/usrp2/top/u2_rev3/u2_core_udp.v b/fpga/usrp2/top/u2_rev3/u2_core_udp.v
index cb0ed78c7..124930c23 100644
--- a/fpga/usrp2/top/u2_rev3/u2_core_udp.v
+++ b/fpga/usrp2/top/u2_rev3/u2_core_udp.v
@@ -180,6 +180,11 @@ module u2_core
wire [31:0] irq;
wire [63:0] vita_time;
+ wire run_rx, run_tx;
+ reg run_rx_d1;
+ always @(posedge dsp_clk)
+ run_rx_d1 <= run_rx;
+
// ///////////////////////////////////////////////////////////////////////////////////////////////
// Wishbone Single Master INTERCON
localparam dw = 32; // Data bus width
@@ -279,33 +284,33 @@ module u2_core
// ///////////////////////////////////////////////////////////////////
// RAM Loader
- wire [31:0] ram_loader_dat, iwb_dat;
- wire [15:0] ram_loader_adr, iwb_adr;
+ wire [31:0] ram_loader_dat, if_dat;
+ wire [15:0] ram_loader_adr;
+ wire [14:0] if_adr;
wire [3:0] ram_loader_sel;
- wire ram_loader_stb, ram_loader_we, ram_loader_ack;
+ wire ram_loader_stb, ram_loader_we;
wire iwb_ack, iwb_stb;
ram_loader #(.AWIDTH(16),.RAM_SIZE(RAM_SIZE))
- ram_loader (.clk_i(wb_clk),.rst_i(ram_loader_rst),
+ ram_loader (.wb_clk(wb_clk),.dsp_clk(dsp_clk),.ram_loader_rst(ram_loader_rst),
+ .wb_dat(ram_loader_dat),.wb_adr(ram_loader_adr),
+ .wb_stb(ram_loader_stb),.wb_sel(ram_loader_sel),
+ .wb_we(ram_loader_we),
+ .ram_loader_done(ram_loader_done),
// CPLD Interface
- .cfg_clk_i(cpld_clk),
- .cfg_data_i(cpld_din),
- .start_o(cpld_start_int),
- .mode_o(cpld_mode_int),
- .done_o(cpld_done_int),
- .detached_i(cpld_detached),
- // Wishbone Interface
- .wb_dat_o(ram_loader_dat),.wb_adr_o(ram_loader_adr),
- .wb_stb_o(ram_loader_stb),.wb_cyc_o(),.wb_sel_o(ram_loader_sel),
- .wb_we_o(ram_loader_we),.wb_ack_i(ram_loader_ack),
- .ram_loader_done_o(ram_loader_done));
-
+ .cpld_clk(cpld_clk),
+ .cpld_din(cpld_din),
+ .cpld_start(cpld_start_int),
+ .cpld_mode(cpld_mode_int),
+ .cpld_done(cpld_done_int),
+ .cpld_detached(cpld_detached));
+
// /////////////////////////////////////////////////////////////////////////
// Processor
aeMB_core_BE #(.ISIZ(16),.DSIZ(16),.MUL(0),.BSF(1))
aeMB (.sys_clk_i(wb_clk), .sys_rst_i(wb_rst),
// Instruction Wishbone bus to I-RAM
- .iwb_stb_o(iwb_stb),.iwb_adr_o(iwb_adr),
- .iwb_dat_i(iwb_dat),.iwb_ack_i(iwb_ack),
+ .if_adr(if_adr),
+ .if_dat(if_dat),
// Data Wishbone bus to system bus fabric
.dwb_we_o(m0_we),.dwb_stb_o(m0_stb),.dwb_dat_o(m0_dat_i),.dwb_adr_o(m0_adr),
.dwb_dat_i(m0_dat_o),.dwb_ack_i(m0_ack),.dwb_sel_o(m0_sel),.dwb_cyc_o(m0_cyc),
@@ -319,16 +324,16 @@ module u2_core
// I-port connects directly to processor and ram loader
wire flush_icache;
- ram_harv_cache #(.AWIDTH(15),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
+ ram_harvard #(.AWIDTH(15),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
sys_ram(.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
.ram_loader_adr_i(ram_loader_adr[14:0]), .ram_loader_dat_i(ram_loader_dat),
.ram_loader_stb_i(ram_loader_stb), .ram_loader_sel_i(ram_loader_sel),
- .ram_loader_we_i(ram_loader_we), .ram_loader_ack_o(ram_loader_ack),
+ .ram_loader_we_i(ram_loader_we),
.ram_loader_done_i(ram_loader_done),
- .iwb_adr_i(iwb_adr[14:0]), .iwb_stb_i(iwb_stb),
- .iwb_dat_o(iwb_dat), .iwb_ack_o(iwb_ack),
+ .if_adr(if_adr),
+ .if_data(if_dat),
.dwb_adr_i(s0_adr[14:0]), .dwb_dat_i(s0_dat_o), .dwb_dat_o(s0_dat_i),
.dwb_we_i(s0_we), .dwb_ack_o(s0_ack), .dwb_stb_i(s0_stb), .dwb_sel_i(s0_sel),
@@ -418,7 +423,10 @@ module u2_core
cycle_count <= 0;
else
cycle_count <= cycle_count + 1;
-
+
+ //compatibility number -> increment when the fpga has been sufficiently altered
+ localparam compat_num = 32'd1;
+
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),
@@ -426,7 +434,7 @@ module u2_core
.word00(status_b0),.word01(status_b1),.word02(status_b2),.word03(status_b3),
.word04(status_b4),.word05(status_b5),.word06(status_b6),.word07(status_b7),
.word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(vita_time[63:32]),
- .word11(vita_time[31:0]),.word12(32'b0),.word13(irq),.word14(status_enc),.word15(cycle_count)
+ .word11(vita_time[31:0]),.word12(compat_num),.word13(irq),.word14(status_enc),.word15(cycle_count)
);
// /////////////////////////////////////////////////////////////////////////
@@ -461,11 +469,20 @@ module u2_core
.tx_f36_data(udp_tx_data), .tx_f36_src_rdy_i(udp_tx_src_rdy), .tx_f36_dst_rdy_o(udp_tx_dst_rdy),
.debug(debug_udp) );
+ wire [35:0] tx_err_data, udp1_tx_data;
+ wire tx_err_src_rdy, tx_err_dst_rdy, udp1_tx_src_rdy, udp1_tx_dst_rdy;
+
fifo_cascade #(.WIDTH(36), .SIZE(ETH_TX_FIFOSIZE)) tx_eth_fifo
(.clk(dsp_clk), .reset(dsp_rst), .clear(0),
.datain({rd2_flags,rd2_dat}), .src_rdy_i(rd2_ready_o), .dst_rdy_o(rd2_ready_i),
- .dataout(udp_tx_data), .src_rdy_o(udp_tx_src_rdy), .dst_rdy_i(udp_tx_dst_rdy));
+ .dataout(udp1_tx_data), .src_rdy_o(udp1_tx_src_rdy), .dst_rdy_i(udp1_tx_dst_rdy));
+ fifo36_mux #(.prio(0)) mux_err_stream
+ (.clk(dsp_clk), .reset(dsp_reset), .clear(0),
+ .data0_i(udp1_tx_data), .src0_rdy_i(udp1_tx_src_rdy), .dst0_rdy_o(udp1_tx_dst_rdy),
+ .data1_i(tx_err_data), .src1_rdy_i(tx_err_src_rdy), .dst1_rdy_o(tx_err_dst_rdy),
+ .data_o(udp_tx_data), .src_rdy_o(udp_tx_src_rdy), .dst_rdy_i(udp_tx_dst_rdy));
+
fifo_cascade #(.WIDTH(36), .SIZE(ETH_RX_FIFOSIZE)) rx_eth_fifo
(.clk(dsp_clk), .reset(dsp_rst), .clear(0),
.datain(udp_rx_data), .src_rdy_i(udp_rx_src_rdy), .dst_rdy_o(udp_rx_dst_rdy),
@@ -509,12 +526,13 @@ module u2_core
// In Rev3 there are only 6 leds, and the highest one is on the ETH connector
wire [7:0] led_src, led_sw;
- wire [7:0] led_hw = {clk_status,serdes_link_up};
+ wire [7:0] led_hw = {run_tx, run_rx, clk_status, serdes_link_up, 1'b0};
setting_reg #(.my_addr(3),.width(8)) sr_led (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(led_sw),.changed());
- setting_reg #(.my_addr(8),.width(8)) sr_led_src (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(led_src),.changed());
+
+ setting_reg #(.my_addr(8),.width(8), .at_reset(8'b0001_1110))
+ sr_led_src (.clk(wb_clk),.rst(wb_rst), .strobe(set_stb),.addr(set_addr), .in(set_data),.out(led_src),.changed());
assign leds = (led_src & led_hw) | (~led_src & led_sw);
@@ -565,11 +583,6 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// ATR Controller, Slave #11
- wire run_rx, run_tx;
- reg run_rx_d1;
- always @(posedge dsp_clk)
- run_rx_d1 <= run_rx;
-
atr_controller atr_controller
(.clk_i(wb_clk),.rst_i(wb_rst),
.adr_i(sb_adr[5:0]),.sel_i(sb_sel),.dat_i(sb_dat_o),.dat_o(sb_dat_i),
@@ -638,40 +651,26 @@ module u2_core
// DSP TX
wire [35:0] tx_data;
- wire [99:0] tx1_data;
- wire tx_src_rdy, tx_dst_rdy, tx1_src_rdy, tx1_dst_rdy;
-
- wire [31:0] debug_vtc, debug_vtd, debug_vt;
+ wire tx_src_rdy, tx_dst_rdy;
+ wire [31:0] debug_vt;
fifo_cascade #(.WIDTH(36), .SIZE(DSP_TX_FIFOSIZE)) tx_fifo_cascade
(.clk(dsp_clk), .reset(dsp_rst), .clear(0),
.datain({rd1_flags,rd1_dat}), .src_rdy_i(rd1_ready_o), .dst_rdy_o(rd1_ready_i),
.dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy) );
- vita_tx_deframer #(.BASE(SR_TX_CTRL), .MAXCHAN(1)) vita_tx_deframer
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .data_i(tx_data), .src_rdy_i(tx_src_rdy), .dst_rdy_o(tx_dst_rdy),
- .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy),
- .debug(debug_vtd) );
-
- vita_tx_control #(.BASE(SR_TX_CTRL), .WIDTH(32)) vita_tx_control
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .vita_time(vita_time),.underrun(underrun),
- .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy),
- .sample(sample_tx), .run(run_tx), .strobe(strobe_tx),
- .debug(debug_vtc) );
-
- assign debug_vt = debug_vtc | debug_vtd;
-
- dsp_core_tx #(.BASE(SR_TX_DSP)) dsp_core_tx
- (.clk(dsp_clk),.rst(dsp_rst),
+ vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP),
+ .REPORT_ERROR(1), .PROT_ENG_FLAGS(1))
+ vita_tx_chain
+ (.clk(dsp_clk), .reset(dsp_rst),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .sample(sample_tx), .run(run_tx), .strobe(strobe_tx),
+ .vita_time(vita_time),
+ .tx_data_i(tx_data), .tx_src_rdy_i(tx_src_rdy), .tx_dst_rdy_o(tx_dst_rdy),
+ .err_data_o(tx_err_data), .err_src_rdy_o(tx_err_src_rdy), .err_dst_rdy_i(tx_err_dst_rdy),
.dac_a(dac_a),.dac_b(dac_b),
- .debug(debug_tx_dsp) );
-
+ .underrun(underrun), .run(run_tx),
+ .debug(debug_vt));
+
assign dsp_rst = wb_rst;
// ///////////////////////////////////////////////////////////////////////////////////
@@ -773,8 +772,7 @@ endmodule // u2_core
{ s6_adr[15:8] },
{ s6_adr[7:0] },
{ 6'd0, mdio_cpy, MDC } };
-*/
-/*
+
assign debug = { { GMII_TXD },
{ 5'd0, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK },
{ wr2_flags, rd2_flags },
@@ -783,7 +781,6 @@ endmodule // u2_core
{ 5'd0, GMII_RX_DV, GMII_RX_ER, GMII_RX_CLK },
{ wr2_flags, rd2_flags },
{ GMII_TX_EN,3'd0, wr2_ready_i, wr2_ready_o, rd2_ready_i, rd2_ready_o } };
- */
// assign debug = debug_udp;
// assign debug = vrc_debug;
@@ -794,9 +791,8 @@ endmodule // u2_core
{wr1_ready_i, wr1_ready_o, rx1_src_rdy, rx1_dst_rdy, rx1_data[35:32]}};
*/
// assign debug_gpio_1 = {vita_time[63:32] };
-
-/*
- assign debug_gpio_1 = { { tx_f19_data[15:8] },
+/*
+ assign debug_gpio_1 = { { tx_f19_data[15:8] },
{ tx_f19_data[7:0] },
{ 3'd0, tx_f19_src_rdy, tx_f19_dst_rdy, tx_f19_data[18:16] },
{ 2'b0, rd2_ready_i, rd2_ready_o, rd2_flags } };
diff --git a/fpga/usrp2/udp/prot_eng_tx.v b/fpga/usrp2/udp/prot_eng_tx.v
index 9031011f7..a18eb73ae 100644
--- a/fpga/usrp2/udp/prot_eng_tx.v
+++ b/fpga/usrp2/udp/prot_eng_tx.v
@@ -40,11 +40,16 @@ module prot_eng_tx
// Store header values in a small dual-port (distributed) ram
reg [HDR_WIDTH-1:0] header_ram[0:HDR_LEN-1];
wire [HDR_WIDTH-1:0] header_word;
+ reg [15:0] chk_precompute;
always @(posedge clk)
if(set_stb & ((set_addr & 8'hE0) == BASE))
- header_ram[set_addr[4:0]] <= set_data;
-
+ begin
+ header_ram[set_addr[4:0]] <= set_data;
+ if(set_data[18])
+ chk_precompute <= set_data[15:0];
+ end
+
assign header_word = header_ram[state];
wire last_hdr_line = header_word[19];
@@ -56,7 +61,7 @@ module prot_eng_tx
reg [15:0] length;
wire [15:0] ip_length = length + 28; // IP HDR + UDP HDR
wire [15:0] udp_length = length + 8; // UDP HDR
-
+
always @(posedge clk)
if(reset)
begin
@@ -101,12 +106,16 @@ module prot_eng_tx
wire [15:0] checksum;
add_onescomp #(.WIDTH(16)) add_onescomp
- (.A(header_word[15:0]),.B(ip_length),.SUM(checksum));
+ (.A(chk_precompute),.B(ip_length),.SUM(checksum));
+ reg [15:0] checksum_reg;
+ always @(posedge clk)
+ checksum_reg <= checksum;
+
always @*
if(ip_chk)
//dataout_int <= header_word[15:0] ^ ip_length;
- dataout_int <= 16'hFFFF ^ checksum;
+ dataout_int <= 16'hFFFF ^ checksum_reg;
else if(ip_len)
dataout_int <= ip_length;
else if(udp_len)
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs
index 07c62224b..dc4bd8c96 100644
--- a/fpga/usrp2/vrt/Makefile.srcs
+++ b/fpga/usrp2/vrt/Makefile.srcs
@@ -10,4 +10,6 @@ vita_rx_control.v \
vita_rx_framer.v \
vita_tx_control.v \
vita_tx_deframer.v \
+vita_tx_chain.v \
+gen_context_pkt.v \
))
diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v
new file mode 100644
index 000000000..780a027ba
--- /dev/null
+++ b/fpga/usrp2/vrt/gen_context_pkt.v
@@ -0,0 +1,72 @@
+
+
+module gen_context_pkt
+ #(parameter PROT_ENG_FLAGS=1)
+ (input clk, input reset, input clear,
+ input trigger, output sent,
+ input [31:0] streamid,
+ input [63:0] vita_time,
+ input [31:0] message,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ localparam CTXT_IDLE = 0;
+ localparam CTXT_PROT_ENG = 1;
+ localparam CTXT_HEADER = 2;
+ localparam CTXT_STREAMID = 3;
+ localparam CTXT_SECS = 4;
+ localparam CTXT_TICS = 5;
+ localparam CTXT_TICS2 = 6;
+ localparam CTXT_MESSAGE = 7;
+ localparam CTXT_DONE = 8;
+
+ reg [33:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+ wire [3:0] seqno = 0;
+ reg [3:0] ctxt_state;
+ reg [63:0] err_time;
+
+ always @(posedge clk)
+ if(reset | clear)
+ ctxt_state <= CTXT_IDLE;
+ else
+ case(ctxt_state)
+ CTXT_IDLE :
+ if(trigger)
+ begin
+ err_time <= vita_time;
+ if(PROT_ENG_FLAGS)
+ ctxt_state <= CTXT_PROT_ENG;
+ else
+ ctxt_state <= CTXT_HEADER;
+ end
+
+ CTXT_DONE :
+ if(~trigger)
+ ctxt_state <= CTXT_IDLE;
+
+ default :
+ if(dst_rdy_int)
+ ctxt_state <= ctxt_state + 1;
+ endcase // case (ctxt_state)
+
+ assign src_rdy_int = ~( (ctxt_state == CTXT_IDLE) | (ctxt_state == CTXT_DONE) );
+
+ always @*
+ case(ctxt_state)
+ CTXT_PROT_ENG : data_int <= { 2'b01, 16'd1, 16'd24 };
+ CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd6 };
+ CTXT_STREAMID : data_int <= { 2'b00, streamid };
+ CTXT_SECS : data_int <= { 2'b00, err_time[63:32] };
+ CTXT_TICS : data_int <= { 2'b00, 32'd0 };
+ CTXT_TICS2 : data_int <= { 2'b00, err_time[31:0] };
+ CTXT_MESSAGE : data_int <= { 2'b10, message };
+ default : data_int <= {2'b00, 32'b00};
+ endcase // case (ctxt_state)
+
+ fifo_short #(.WIDTH(34)) ctxt_fifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int),
+ .dataout(data_o[33:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i));
+ assign data_o[35:34] = 2'b00;
+
+endmodule // gen_context_pkt
diff --git a/fpga/usrp2/vrt/vita_rx.build b/fpga/usrp2/vrt/vita_rx.build
index f6d2d75a3..010d1be6e 100755
--- a/fpga/usrp2/vrt/vita_rx.build
+++ b/fpga/usrp2/vrt/vita_rx.build
@@ -1 +1 @@
-iverilog -Wimplict -Wportbind -y ../models -y . -y ../control_lib/ -y ../control_lib/newfifo -y ../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -y ../timing -o vita_rx_tb vita_rx_tb.v
+iverilog -Wimplict -Wportbind -y ../models -y . -y ../control_lib/ -y ../fifo -y ../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -y ../timing -o vita_rx_tb vita_rx_tb.v
diff --git a/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v
index 742dd47e0..93673d292 100644
--- a/fpga/usrp2/vrt/vita_rx_control.v
+++ b/fpga/usrp2/vrt/vita_rx_control.v
@@ -67,7 +67,7 @@ module vita_rx_control
shortfifo #(.WIDTH(96)) commandfifo
(.clk(clk),.rst(reset),.clear(clear_int),
.datain({new_command,new_time}), .write(write_ctrl&~full_ctrl), .full(full_ctrl),
- .dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),
+ .dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),
.read(read_ctrl), .empty(empty_ctrl),
.occupied(command_queue_len), .space() );
@@ -98,7 +98,7 @@ module vita_rx_control
.src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i),
.space(), .occupied() );
- // Inband Signallling State Machine
+ // Inband Signalling State Machine
time_compare
time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late));
@@ -189,4 +189,3 @@ module vita_rx_control
{ 2'b0, overrun, chain_pre, sample_fifo_in_rdy, attempt_sample_write, sample_fifo_src_rdy_o,sample_fifo_dst_rdy_i} };
endmodule // rx_control
-
diff --git a/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v
index f3a81664a..fd82263d0 100644
--- a/fpga/usrp2/vrt/vita_rx_framer.v
+++ b/fpga/usrp2/vrt/vita_rx_framer.v
@@ -99,7 +99,7 @@ module vita_rx_framer
localparam VITA_ERR_TICS = 12;
localparam VITA_ERR_TICS2 = 13;
localparam VITA_ERR_PAYLOAD = 14;
- localparam VITA_ERR_TRAILER = 15;
+ localparam VITA_ERR_TRAILER = 15; // Extension context packets have no trailer
always @(posedge clk)
if(reset | clear_pkt_count)
@@ -107,17 +107,30 @@ module vita_rx_framer
else if((vita_state == VITA_TRAILER) & pkt_fifo_rdy)
pkt_count <= pkt_count + 1;
+ wire has_streamid = vita_header[28];
+ wire has_trailer = vita_header[26];
+ reg trl_eob;
+
always @*
case(vita_state)
- VITA_HEADER, VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,vita_header[31:20],pkt_count,vita_pkt_len};
- VITA_STREAMID, VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
- VITA_SECS, VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
- VITA_TICS, VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0};
- VITA_TICS2, VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
+ // Data packets are IF Data packets with or w/o streamid, no classid, with trailer
+ VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:20],pkt_count,vita_pkt_len};
+ VITA_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
+ VITA_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
+ VITA_TICS : pkt_fifo_line <= {2'b00,32'd0};
+ VITA_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o};
- VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b00,28'd0,flags_fifo_o};
- VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer};
- VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer};
+ VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer[31:21],1'b1,vita_trailer[19:9],trl_eob,8'd0};
+
+ // Error packets are Extension Context packets, which have no trailer
+ VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd6};
+ VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
+ VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
+ VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0};
+ VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
+ VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b11,28'd0,flags_fifo_o};
+ //VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer};
+
default : pkt_fifo_line <= 34'h0_FFFF_FFFF;
endcase // case (vita_state)
@@ -141,6 +154,11 @@ module vita_rx_framer
end
else if(pkt_fifo_rdy)
case(vita_state)
+ VITA_HEADER :
+ if(has_streamid)
+ vita_state <= VITA_STREAMID;
+ else
+ vita_state <= VITA_SECS;
VITA_PAYLOAD :
if(sample_fifo_src_rdy_i)
begin
@@ -148,6 +166,7 @@ module vita_rx_framer
begin
sample_phase <= 0;
sample_ctr <= sample_ctr + 1;
+ trl_eob <= flags_fifo_o[0];
if(sample_ctr == samples_per_packet)
vita_state <= VITA_TRAILER;
if(|flags_fifo_o) // end early if any flag is set
@@ -155,8 +174,10 @@ module vita_rx_framer
end
else
sample_phase <= sample_phase + 1;
- end
- VITA_TRAILER, VITA_ERR_TRAILER :
+ end // if (sample_fifo_src_rdy_i)
+ VITA_ERR_PAYLOAD :
+ vita_state <= VITA_IDLE;
+ VITA_TRAILER :
vita_state <= VITA_IDLE;
default :
vita_state <= vita_state + 1;
@@ -172,7 +193,7 @@ module vita_rx_framer
VITA_PAYLOAD :
// Write if sample ready and no error flags
req_write_pkt_fifo <= (sample_fifo_src_rdy_i & ~|flags_fifo_o[3:1]);
- VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD, VITA_ERR_TRAILER :
+ VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD :
req_write_pkt_fifo <= 1;
default :
req_write_pkt_fifo <= 0;
@@ -192,7 +213,7 @@ module vita_rx_framer
( ((vita_state==VITA_PAYLOAD) &
(sample_phase == (numchan-4'd1)) &
~|flags_fifo_o[3:1]) |
- (vita_state==VITA_ERR_TRAILER));
+ (vita_state==VITA_ERR_PAYLOAD));
assign debug_rx = vita_state;
diff --git a/fpga/usrp2/vrt/vita_rx_tb.v b/fpga/usrp2/vrt/vita_rx_tb.v
index b4fda9622..3e01e2ee2 100644
--- a/fpga/usrp2/vrt/vita_rx_tb.v
+++ b/fpga/usrp2/vrt/vita_rx_tb.v
@@ -3,8 +3,8 @@
module vita_rx_tb;
localparam DECIM = 8'd4;
- localparam MAXCHAN=4;
- localparam NUMCHAN=4;
+ localparam MAXCHAN=1;
+ localparam NUMCHAN=1;
reg clk = 0;
reg reset = 1;
@@ -94,7 +94,7 @@ module vita_rx_tb;
@(posedge clk);
write_setting(4,32'hDEADBEEF); // VITA header
write_setting(5,32'hF00D1234); // VITA streamid
- write_setting(6,32'h98765432); // VITA trailer
+ write_setting(6,32'hF0000000); // VITA trailer
write_setting(7,8); // Samples per VITA packet
write_setting(8,NUMCHAN); // Samples per VITA packet
queue_rx_cmd(1,0,8,32'h0,32'h0); // send imm, single packet
@@ -111,8 +111,13 @@ module vita_rx_tb;
queue_rx_cmd(0,0,8,32'h0,32'h340); // send at, on time
queue_rx_cmd(0,0,8,32'h0,32'h100); // send at, but late
+ #100000;
+ $display("\nChained, break chain\n");
queue_rx_cmd(1,1,8,32'h0,32'h0); // chained, but break chain
#100000;
+ $display("\nSingle packet\n");
+ queue_rx_cmd(1,0,8,32'h0,32'h0); // send imm, single packet
+ #100000;
$display("\nEnd chain with zero samples, shouldn't error\n");
queue_rx_cmd(1,1,8,32'h0,32'h0); // chained
queue_rx_cmd(0,0,0,32'h0,32'h0); // end chain with zero samples, should keep us out of error
diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v
new file mode 100644
index 000000000..662cdca62
--- /dev/null
+++ b/fpga/usrp2/vrt/vita_tx_chain.v
@@ -0,0 +1,71 @@
+
+module vita_tx_chain
+ #(parameter BASE_CTRL=0,
+ parameter BASE_DSP=0,
+ parameter REPORT_ERROR=0,
+ parameter PROT_ENG_FLAGS=0)
+ (input clk, input reset,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input [63:0] vita_time,
+ input [35:0] tx_data_i, input tx_src_rdy_i, output tx_dst_rdy_o,
+ output [35:0] err_data_o, output err_src_rdy_o, input err_dst_rdy_i,
+ output [15:0] dac_a, output [15:0] dac_b,
+ output underrun, output run,
+ output [31:0] debug);
+
+ localparam MAXCHAN = 1;
+ localparam FIFOWIDTH = 5+64+16+(32*MAXCHAN);
+
+ wire [FIFOWIDTH-1:0] tx1_data;
+ wire tx1_src_rdy, tx1_dst_rdy;
+ wire clear_vita;
+ wire [31:0] sample_tx;
+ wire [31:0] streamid, message;
+ wire trigger, sent;
+ wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp;
+
+ wire error;
+ wire [31:0] error_code;
+ wire clear_seqnum;
+
+ assign underrun = error;
+ assign message = error_code;
+
+ setting_reg #(.my_addr(BASE_CTRL+2), .at_reset(0)) sr_streamid
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(streamid),.changed(clear_seqnum));
+
+ vita_tx_deframer #(.BASE(BASE_CTRL), .MAXCHAN(MAXCHAN)) vita_tx_deframer
+ (.clk(clk), .reset(reset), .clear(clear_vita), .clear_seqnum(clear_seqnum),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o),
+ .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy),
+ .debug(debug_vtd) );
+
+ vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control
+ (.clk(clk), .reset(reset), .clear(clear_vita),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .vita_time(vita_time),.error(error),.error_code(error_code),
+ .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy),
+ .sample(sample_tx), .run(run), .strobe(strobe_tx),
+ .debug(debug_vtc) );
+
+ dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx
+ (.clk(clk),.rst(reset),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .sample(sample_tx), .run(run), .strobe(strobe_tx),
+ .dac_a(dac_a),.dac_b(dac_b),
+ .debug(debug_tx_dsp) );
+
+ generate
+ if(REPORT_ERROR==1)
+ gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) gen_tx_err_pkt
+ (.clk(clk), .reset(reset), .clear(clear_vita),
+ .trigger(error), .sent(),
+ .streamid(streamid), .vita_time(vita_time), .message(message),
+ .data_o(err_data_o), .src_rdy_o(err_src_rdy_o), .dst_rdy_i(err_dst_rdy_i));
+ endgenerate
+
+ assign debug = debug_vtc | debug_vtd;
+
+endmodule // vita_tx_chain
diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v
index bffc64e52..d0516bec8 100644
--- a/fpga/usrp2/vrt/vita_tx_control.v
+++ b/fpga/usrp2/vrt/vita_tx_control.v
@@ -6,10 +6,11 @@ module vita_tx_control
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input [63:0] vita_time,
- output underrun,
+ output error,
+ output reg [31:0] error_code,
// From vita_tx_deframer
- input [4+64+WIDTH-1:0] sample_fifo_i,
+ input [5+64+16+WIDTH-1:0] sample_fifo_i,
input sample_fifo_src_rdy_i,
output sample_fifo_dst_rdy_o,
@@ -20,14 +21,17 @@ module vita_tx_control
output [31:0] debug
);
-
- assign sample = sample_fifo_i[4+64+WIDTH-1:4+64];
+
+ assign sample = sample_fifo_i[5+64+16+WIDTH-1:5+64+16];
wire [63:0] send_time = sample_fifo_i[63:0];
- wire eop = sample_fifo_i[64];
- wire eob = sample_fifo_i[65];
- wire sob = sample_fifo_i[66];
- wire send_at = sample_fifo_i[67];
+ wire [15:0] seqnum = sample_fifo_i[79:64];
+ wire eop = sample_fifo_i[80];
+ wire eob = sample_fifo_i[81];
+ wire sob = sample_fifo_i[82];
+ wire send_at = sample_fifo_i[83];
+ wire seqnum_err = sample_fifo_i[84];
+
wire now, early, late, too_early;
// FIXME ignore too_early for now for timing reasons
@@ -40,8 +44,15 @@ module vita_tx_control
localparam IBS_IDLE = 0;
localparam IBS_RUN = 1; // FIXME do we need this?
localparam IBS_CONT_BURST = 2;
- localparam IBS_UNDERRUN = 3;
- localparam IBS_UNDERRUN_DONE = 4;
+ localparam IBS_ERROR = 3;
+ localparam IBS_ERROR_DONE = 4;
+ localparam IBS_ERROR_WAIT = 5;
+
+ wire [31:0] CODE_UNDERRUN = {seqnum,16'd2};
+ wire [31:0] CODE_SEQ_ERROR = {seqnum,16'd4};
+ wire [31:0] CODE_TIME_ERROR = {seqnum,16'd8};
+ wire [31:0] CODE_UNDERRUN_MIDPKT = {seqnum,16'd16};
+ wire [31:0] CODE_SEQ_ERROR_MIDBURST = {seqnum,16'd32};
reg [2:0] ibs_state;
@@ -50,22 +61,49 @@ module vita_tx_control
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(),.changed(clear_state));
+ wire [31:0] error_policy;
+ setting_reg #(.my_addr(BASE+3)) sr_error_policy
+ (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(error_policy),.changed());
+
+ wire policy_wait = error_policy[0];
+ wire policy_next_packet = error_policy[1];
+ wire policy_next_burst = error_policy[2];
+ reg send_error;
+
always @(posedge clk)
if(reset | clear_state)
- ibs_state <= 0;
+ begin
+ ibs_state <= IBS_IDLE;
+ send_error <= 0;
+ end
else
case(ibs_state)
IBS_IDLE :
if(sample_fifo_src_rdy_i)
- if(~send_at | now)
+ if(seqnum_err)
+ begin
+ ibs_state <= IBS_ERROR;
+ error_code <= CODE_SEQ_ERROR;
+ send_error <= 1;
+ end
+ else if(~send_at | now)
ibs_state <= IBS_RUN;
else if(late | too_early)
- ibs_state <= IBS_UNDERRUN;
+ begin
+ ibs_state <= IBS_ERROR;
+ error_code <= CODE_TIME_ERROR;
+ send_error <= 1;
+ end
IBS_RUN :
if(strobe)
if(~sample_fifo_src_rdy_i)
- ibs_state <= IBS_UNDERRUN;
+ begin
+ ibs_state <= IBS_ERROR;
+ error_code <= CODE_UNDERRUN_MIDPKT;
+ send_error <= 1;
+ end
else if(eop)
if(eob)
ibs_state <= IBS_IDLE;
@@ -74,24 +112,53 @@ module vita_tx_control
IBS_CONT_BURST :
if(strobe)
- ibs_state <= IBS_UNDERRUN_DONE;
+ begin
+ if(policy_next_packet)
+ ibs_state <= IBS_ERROR_DONE;
+ else if(policy_wait)
+ ibs_state <= IBS_ERROR_WAIT;
+ else
+ ibs_state <= IBS_ERROR;
+ error_code <= CODE_UNDERRUN;
+ send_error <= 1;
+ end
else if(sample_fifo_src_rdy_i)
- ibs_state <= IBS_RUN;
+ if(seqnum_err)
+ begin
+ ibs_state <= IBS_ERROR;
+ error_code <= CODE_SEQ_ERROR_MIDBURST;
+ send_error <= 1;
+ end
+ else
+ ibs_state <= IBS_RUN;
- IBS_UNDERRUN :
- if(sample_fifo_src_rdy_i & eop)
- ibs_state <= IBS_UNDERRUN_DONE;
+ IBS_ERROR :
+ begin
+ send_error <= 0;
+ if(sample_fifo_src_rdy_i & eop)
+ if(policy_next_packet | (policy_next_burst & eob))
+ ibs_state <= IBS_IDLE;
+ else if(policy_wait)
+ ibs_state <= IBS_ERROR_WAIT;
+ end
- IBS_UNDERRUN_DONE :
- ;
+ IBS_ERROR_DONE :
+ begin
+ send_error <= 0;
+ ibs_state <= IBS_IDLE;
+ end
+
+ IBS_ERROR_WAIT :
+ send_error <= 0;
endcase // case (ibs_state)
- assign sample_fifo_dst_rdy_o = (ibs_state == IBS_UNDERRUN) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout
+ assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout
assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST);
- assign underrun = (ibs_state == IBS_UNDERRUN_DONE);
+ //assign error = (ibs_state == IBS_ERROR_DONE);
+ assign error = send_error;
assign debug = { { now,early,late,too_early,eop,eob,sob,send_at },
- { sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, underrun, ibs_state[2:0] },
+ { sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, error, ibs_state[2:0] },
{ 8'b0 },
{ 8'b0 } };
diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v
index 220d3b061..f9cd7d00d 100644
--- a/fpga/usrp2/vrt/vita_tx_deframer.v
+++ b/fpga/usrp2/vrt/vita_tx_deframer.v
@@ -2,7 +2,7 @@
module vita_tx_deframer
#(parameter BASE=0,
parameter MAXCHAN=1)
- (input clk, input reset, input clear,
+ (input clk, input reset, input clear, input clear_seqnum,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
// To FIFO interface of Buffer Pool
@@ -10,7 +10,7 @@ module vita_tx_deframer
input src_rdy_i,
output dst_rdy_o,
- output [4+64+(32*MAXCHAN)-1:0] sample_fifo_o,
+ output [5+64+16+(32*MAXCHAN)-1:0] sample_fifo_o,
output sample_fifo_src_rdy_o,
input sample_fifo_dst_rdy_i,
@@ -21,8 +21,10 @@ module vita_tx_deframer
output [31:0] debug
);
+ localparam FIFOWIDTH = 5+64+16+(32*MAXCHAN);
+
wire [1:0] numchan;
- setting_reg #(.my_addr(BASE), .at_reset(0)) sr_numchan
+ setting_reg #(.my_addr(BASE), .at_reset(0), .width(2)) sr_numchan
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(numchan),.changed());
@@ -36,14 +38,18 @@ module vita_tx_deframer
assign is_sob = data_i[25];
assign is_eob = data_i[24];
wire eof = data_i[33];
-
reg has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg;
reg has_trailer_reg, is_sob_reg, is_eob_reg;
-
+
reg [15:0] pkt_len;
reg [1:0] vector_phase;
wire line_done;
+ reg seqnum_err;
+ reg [3:0] seqnum_reg;
+ wire [3:0] seqnum = data_i[19:16];
+ wire [3:0] next_seqnum = seqnum_reg + 4'd1;
+
// Output FIFO for packetized data
localparam VITA_HEADER = 0;
localparam VITA_STREAMID = 1;
@@ -61,6 +67,13 @@ module vita_tx_deframer
wire eop = eof | (pkt_len==hdr_len); // FIXME would ignoring eof allow larger VITA packets?
wire fifo_space;
+
+ always @(posedge clk)
+ if(reset | clear_seqnum)
+ seqnum_reg <= 4'hF;
+ else
+ if((vita_state==VITA_HEADER) & src_rdy_i)
+ seqnum_reg <= seqnum;
always @(posedge clk)
if(reset | clear)
@@ -68,6 +81,7 @@ module vita_tx_deframer
vita_state <= VITA_HEADER;
{has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg}
<= 0;
+ seqnum_err <= 0;
end
else
if((vita_state == VITA_STORE) & fifo_space)
@@ -99,6 +113,7 @@ module vita_tx_deframer
vita_state <= VITA_TICS;
else
vita_state <= VITA_PAYLOAD;
+ seqnum_err <= ~(seqnum == next_seqnum);
end // case: VITA_HEADER
VITA_STREAMID :
if(has_classid_reg)
@@ -145,7 +160,7 @@ module vita_tx_deframer
assign line_done = (vector_phase == numchan);
- wire [4+64+32*MAXCHAN-1:0] fifo_i;
+ wire [FIFOWIDTH-1:0] fifo_i;
reg [63:0] send_time;
reg [31:0] sample_a, sample_b, sample_c, sample_d;
@@ -169,13 +184,14 @@ module vita_tx_deframer
endcase // case (vector_phase)
wire store = (vita_state == VITA_STORE);
- fifo_short #(.WIDTH(4+64+32*MAXCHAN)) short_tx_q
+ fifo_short #(.WIDTH(FIFOWIDTH)) short_tx_q
(.clk(clk), .reset(reset), .clear(clear),
.datain(fifo_i), .src_rdy_i(store), .dst_rdy_o(fifo_space),
.dataout(sample_fifo_o), .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i) );
// sob, eob, has_secs (send_at) ignored on all lines except first
- assign fifo_i = {sample_d,sample_c,sample_b,sample_a,has_secs_reg,is_sob_reg,is_eob_reg,eop,send_time};
+ assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_secs_reg,is_sob_reg,is_eob_reg,eop,
+ 12'd0,seqnum_reg,send_time};
assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ;
diff --git a/host/README b/host/README
index 6eaf6bb42..5018ef541 100644
--- a/host/README
+++ b/host/README
@@ -18,6 +18,7 @@ LF TX
RFX Series
XCVR 2450
WBX Series
+DBSRX
########################################################################
# Documentation
diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst
index 9c496ebee..b66fd2069 100644
--- a/host/docs/dboards.rst
+++ b/host/docs/dboards.rst
@@ -32,7 +32,20 @@ The Basic TX and LFTX boards have 1 quadrature subdevice using both antennas.
The boards have no tunable elements or programmable gains.
Though the magic of aliasing, you can up-convert signals
-greater than the nyquist rate of the DAC.
+greater than the Nyquist rate of the DAC.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+DBSRX
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The DBSRX board has 1 quadrature subdevice.
+
+Receive Antennas: **J3**
+
+The board has no user selectable antenna setting
+
+Recieve Gains:
+ **GC1**, Range: 0-56dB
+ **GC2**, Range: 0-24dB
^^^^^^^^^^^^^^^^^^^^^^^^^^^
RFX Series
@@ -45,7 +58,7 @@ The user may set the receive antenna to be TX/RX or RX2.
However, when using an RFX board in full-duplex mode,
the receive antenna will always be set to RX2, regardless of the settings.
-Recieve Gains: **PGA0**, Range: 0-45dB
+Recieve Gains: **PGA0**, Range: 0-70dB (except RFX400 range is 0-45dB)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
XCVR 2450
@@ -87,3 +100,44 @@ the receive antenna will always be set to RX2, regardless of the settings.
Transmit Gains: **PGA0**, Range: 0-25dB
Recieve Gains: **PGA0**, Range: 0-31.5dB
+
+------------------------------------------------------------------------
+Daughterboard Modifications
+------------------------------------------------------------------------
+
+Sometimes, daughterboards will require modification
+to work on certain frequencies or to work with certain hardware.
+Modification usually involves moving/removing a SMT component
+and burning a new daughterboard id into the eeprom.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+DBSRX
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Due to different clocking capabilities,
+the DBSRX will require modifications to operate on a non-USRP1 motherboard.
+On a USRP1 motherboard, a divided clock is provided from an FPGA pin
+because the standard daughterboard clock lines cannot provided a divided clock.
+However, on other USRP motherboards, the divided clock is provided
+over the standard daughterboard clock lines.
+
+**Step 1: Move the clock configuration resistor**
+
+Remove R193 (which is 10 ohms, 0603 size) and put it on R194, which is empty.
+This is made somewhat more complicated by the fact that the silkscreen is not clear in that area.
+R193 is on the back, immediately below the large beige connector, J2.
+R194 is just below, and to the left of R193.
+The silkscreen for R193 is ok, but for R194,
+it is upside down, and partially cut off.
+If you lose R193, you can use anything from 0 to 10 ohms there.
+
+**Step 2: Burn a new daughterboard id into the EEPROM**
+
+With the daughterboard plugged-in, run the following commands:
+::
+
+ cd <prefix>/share/uhd/utils
+ ./usrp_burn_db_eeprom --id=0x000d --unit=RX --args=<args> --db=<db>
+
+* <args> are device address arguments (optional if only one USRP is on your machine)
+* <db> is the name of the daughterboard slot (optional if the USRP has only one slot)
diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst
index 76b27fd31..bc4ea0e44 100644
--- a/host/docs/usrp2.rst
+++ b/host/docs/usrp2.rst
@@ -38,7 +38,7 @@ Run the following commands:
./configure --host=mb
make
-*The image file will be ./apps/txrx_uhd.bin*
+*The image file will be ./usrp2/usrp2_txrx_uhd.bin*
------------------------------------------------------------------------
Load the images onto the SD card
@@ -161,7 +161,7 @@ The USRP2 will reply to icmp echo requests.
**Monitor the USRP2:**
You can read the serial port on the rear of the USRP2
to get debug verbose from the embedded microcontroller.
-Use a standard USB to tty-level serial converter at 230400 baud.
+Use a standard USB to 3.3v-level serial converter at 230400 baud.
The microcontroller prints useful information about IP addresses,
MAC addresses, control packets, and fast-path settings.
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp
index 78bb83c66..c48b3dfff 100644
--- a/host/include/uhd/device.hpp
+++ b/host/include/uhd/device.hpp
@@ -161,12 +161,7 @@ public:
* See the rx metadata fragment flags and offset fields for details.
*
* This is a blocking call and will not return until the number
- * of samples returned have been written into each buffer.
- * However, a call to receive may timeout and return zero samples.
- * The timeout duration is decided by the underlying transport layer.
- * The caller should assume that the call to receive will not return
- * immediately when no packets are available to the transport layer,
- * and that the timeout duration is reasonably tuned for performance.
+ * of samples returned have been written into each buffer or timeout.
*
* When using the full buffer recv mode, the metadata only applies
* to the first packet received and written into the recv buffers.
diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt
index bdb4b90a8..76ee24e5f 100644
--- a/host/include/uhd/usrp/CMakeLists.txt
+++ b/host/include/uhd/usrp/CMakeLists.txt
@@ -33,6 +33,7 @@ INSTALL(FILES
dboard_manager.hpp
### utilities ###
+ subdev_spec.hpp
tune_helper.hpp
### interfaces ###
diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp
index caf1e6ee6..fc7ea3052 100644
--- a/host/include/uhd/usrp/dboard_iface.hpp
+++ b/host/include/uhd/usrp/dboard_iface.hpp
@@ -22,6 +22,7 @@
#include <uhd/types/serial.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/cstdint.hpp>
+#include <string>
#include <vector>
namespace uhd{ namespace usrp{
@@ -65,6 +66,12 @@ public:
};
/*!
+ * Get the motherboard name of the form: usrp1, usrp2...
+ * \return string representing the motherboard name
+ */
+ virtual std::string get_mboard_name(void) = 0;
+
+ /*!
* Write to an aux dac.
*
* \param unit which unit rx or tx
diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp
index e2c0f9c7b..aab6c31ce 100644
--- a/host/include/uhd/usrp/dboard_props.hpp
+++ b/host/include/uhd/usrp/dboard_props.hpp
@@ -31,7 +31,6 @@ namespace uhd{ namespace usrp{
DBOARD_PROP_NAME = 'n', //ro, std::string
DBOARD_PROP_SUBDEV = 's', //ro, wax::obj
DBOARD_PROP_SUBDEV_NAMES = 'S', //ro, prop_names_t
- DBOARD_PROP_USED_SUBDEVS = 'u', //ro, prop_names_t
DBOARD_PROP_DBOARD_ID = 'i', //rw, dboard_id_t
DBOARD_PROP_DBOARD_IFACE = 'f', //ro, dboard_iface::sptr
DBOARD_PROP_CODEC = 'c', //ro, wax::obj
diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp
index a432ce50c..0f250f439 100644
--- a/host/include/uhd/usrp/mboard_props.hpp
+++ b/host/include/uhd/usrp/mboard_props.hpp
@@ -39,6 +39,8 @@ namespace uhd{ namespace usrp{
MBOARD_PROP_RX_DBOARD_NAMES = 'E', //ro, prop_names_t
MBOARD_PROP_TX_DBOARD = 'v', //ro, wax::obj
MBOARD_PROP_TX_DBOARD_NAMES = 'V', //ro, prop_names_t
+ MBOARD_PROP_RX_SUBDEV_SPEC = 'r', //rw, subdev_spec_t
+ MBOARD_PROP_TX_SUBDEV_SPEC = 'R', //rw, subdev_spec_t
MBOARD_PROP_CLOCK_CONFIG = 'C', //rw, clock_config_t
MBOARD_PROP_TIME_NOW = 't', //rw, time_spec_t
MBOARD_PROP_TIME_NEXT_PPS = 'T', //wo, time_spec_t
diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp
index fd0f4596f..10a404059 100644
--- a/host/include/uhd/usrp/mimo_usrp.hpp
+++ b/host/include/uhd/usrp/mimo_usrp.hpp
@@ -24,6 +24,7 @@
#include <uhd/types/stream_cmd.hpp>
#include <uhd/types/clock_config.hpp>
#include <uhd/types/tune_result.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <vector>
@@ -119,6 +120,9 @@ public:
/*******************************************************************
* RX methods
******************************************************************/
+ virtual void set_rx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0;
+ virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t chan) = 0;
+
virtual void set_rx_rate_all(double rate) = 0;
virtual double get_rx_rate_all(void) = 0;
@@ -148,6 +152,9 @@ public:
/*******************************************************************
* TX methods
******************************************************************/
+ virtual void set_tx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0;
+ virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t chan) = 0;
+
virtual void set_tx_rate_all(double rate) = 0;
virtual double get_tx_rate_all(void) = 0;
diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp
index 8fc6d59d9..c2c7505af 100644
--- a/host/include/uhd/usrp/simple_usrp.hpp
+++ b/host/include/uhd/usrp/simple_usrp.hpp
@@ -24,6 +24,7 @@
#include <uhd/types/stream_cmd.hpp>
#include <uhd/types/clock_config.hpp>
#include <uhd/types/tune_result.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <vector>
@@ -107,6 +108,9 @@ public:
/*******************************************************************
* RX methods
******************************************************************/
+ virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;
+ virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(void) = 0;
+
virtual void set_rx_rate(double rate) = 0;
virtual double get_rx_rate(void) = 0;
@@ -135,6 +139,9 @@ public:
/*******************************************************************
* TX methods
******************************************************************/
+ virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;
+ virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(void) = 0;
+
virtual void set_tx_rate(double rate) = 0;
virtual double get_tx_rate(void) = 0;
diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp
new file mode 100644
index 000000000..4d8f03b77
--- /dev/null
+++ b/host/include/uhd/usrp/subdev_spec.hpp
@@ -0,0 +1,95 @@
+//
+// Copyright 2010 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_UHD_USRP_SUBDEV_SPEC_HPP
+#define INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP
+
+#include <uhd/config.hpp>
+#include <vector>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+ /*!
+ * A subdevice specification (daughterboard, subdevice) name pairing.
+ */
+ struct UHD_API subdev_spec_pair_t{
+ //! The daughterboard name
+ std::string db_name;
+
+ //! The subdevice name
+ std::string sd_name;
+
+ /*!
+ * Create a new subdevice specification pair from dboard and subdev names.
+ * \param db_name the name of a daughterboard slot
+ * \param sd_name the name of a subdevice on that daughterboard
+ */
+ subdev_spec_pair_t(
+ const std::string &db_name, const std::string &sd_name
+ );
+ };
+
+ /*!
+ * A list of (daughterboard name, subdevice name) pairs:
+ *
+ * A subdevice specification represents a list of subdevices on a motherboard.
+ * The subdevices specified may span across multiple daughterboards;
+ * Hence the need for a subdevice specification over a simple list of strings.
+ * Typically, the user will pass a RX or TX subdevice specification into the API,
+ * and the implementation will infer the channel configuration from the specification.
+ *
+ * The subdevice specification can be represented as a markup-string.
+ * The markup-string is a whitespace separated list of dboard:subdev pairs.
+ * The "dboard:" part is optional on boards with only one daughterboard slot.
+ * The first pair represents the subdevice for channel zero,
+ * the second pair represents the subdevice for channel one, and so on.
+ *
+ * Examples:
+ * - Use subdevice AB on daughterboard A (USRP1): "A:AB"
+ * - Use subdevice A on daughterboard A for channel zero and subdevice A on daughterboard B for channel one (USRP1): "A:A B:A"
+ * - Use subdevice AB (USRP2): "AB" or ":AB"
+ *
+ * An empty subdevice specification can be used to automatically
+ * select the first subdevice on the first present daughterboard.
+ */
+ class UHD_API subdev_spec_t : public std::vector<subdev_spec_pair_t>{
+ public:
+
+ /*!
+ * Create a subdev specification from a markup string.
+ * \param markup the markup string
+ */
+ subdev_spec_t(const std::string &markup = "");
+
+ /*!
+ * Convert a subdev specification into a pretty print string.
+ * \return a printable string representing the subdev specification
+ */
+ std::string to_pp_string(void) const;
+
+ /*!
+ * Convert the subdevice specification into a markup string.
+ * The markup string contains the delimiter symbols.
+ * \return a string with delimiter markup
+ */
+ std::string to_string(void) const;
+ };
+
+}}
+
+#endif /* INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP */
diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt
index f7feab5a8..ef8e64ce0 100644
--- a/host/include/uhd/utils/CMakeLists.txt
+++ b/host/include/uhd/utils/CMakeLists.txt
@@ -28,5 +28,6 @@ INSTALL(FILES
safe_main.hpp
static.hpp
thread_priority.hpp
+ warning.hpp
DESTINATION ${INCLUDE_DIR}/uhd/utils
)
diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp
index 54bc78494..1b5eacfa9 100644
--- a/host/include/uhd/utils/algorithm.hpp
+++ b/host/include/uhd/utils/algorithm.hpp
@@ -69,6 +69,31 @@ namespace std{
}
/*!
+ * A wrapper around std::reverse that takes a range instead of an iterator.
+ *
+ * The elements are reversed into descending order using the less-than operator.
+ *
+ * \param range the range of elements to be reversed
+ */
+ template<typename Range> inline void reverse(Range &range){
+ return std::reverse(boost::begin(range), boost::end(range));
+ }
+
+ /*!
+ * A wrapper around std::reverse that takes a range instead of an iterator.
+ *
+ * The elements are reversed into descending order using the less-than operator.
+ * This wrapper reverses the elements non-destructively into a new range.
+ * Based on the builtin python function reversed(...)
+ *
+ * \param range the range of elements to be reversed
+ * \return a new range with the elements reversed
+ */
+ template<typename Range> inline Range reversed(const Range &range){
+ Range srange(range); std::reverse(srange); return srange;
+ }
+
+ /*!
* Is the value found within the elements in this range?
*
* Uses std::find to search the iterable for an element.
diff --git a/host/include/uhd/utils/warning.hpp b/host/include/uhd/utils/warning.hpp
new file mode 100644
index 000000000..91d8400ab
--- /dev/null
+++ b/host/include/uhd/utils/warning.hpp
@@ -0,0 +1,34 @@
+//
+// Copyright 2010 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_UHD_UTILS_WARNING_HPP
+#define INCLUDED_UHD_UTILS_WARNING_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * Print a formatted warning string to stderr.
+ * \param msg the multiline warning message
+ */
+ UHD_API void print_warning(const std::string &msg);
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_WARNING_HPP */
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index 4899d3dbc..48cfe742e 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -22,6 +22,10 @@ MACRO(LIBUHD_APPEND_SOURCES)
LIST(APPEND libuhd_sources ${ARGV})
ENDMACRO(LIBUHD_APPEND_SOURCES)
+MACRO(LIBUHD_APPEND_LIBS)
+ LIST(APPEND libuhd_libs ${ARGV})
+ENDMACRO(LIBUHD_APPEND_LIBS)
+
MACRO(LIBUHD_PYTHON_GEN_SOURCE pyfile outfile)
#ensure that the directory exists for outfile
GET_FILENAME_COMPONENT(outfile_dir ${outfile} PATH)
@@ -44,80 +48,22 @@ ENDMACRO(LIBUHD_PYTHON_GEN_SOURCE)
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/CMakeLists.txt)
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/transport/CMakeLists.txt)
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/CMakeLists.txt)
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/dboard/CMakeLists.txt)
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/usrp2/CMakeLists.txt)
-
-########################################################################
-# Setup defines for process scheduling
-########################################################################
-MESSAGE(STATUS "Configuring priority scheduling...")
-
-INCLUDE(CheckCXXSourceCompiles)
-CHECK_CXX_SOURCE_COMPILES("
- #include <pthread.h>
- int main(){
- struct sched_param sp;
- pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
- return 0;
- }
- " HAVE_PTHREAD_SETSCHEDPARAM
-)
-
-CHECK_CXX_SOURCE_COMPILES("
- #include <windows.h>
- int main(){
- SetThreadPriority(GetCurrentThread(), 0);
- SetPriorityClass(GetCurrentProcess(), 0);
- return 0;
- }
- " HAVE_WIN_SETTHREADPRIORITY
-)
-
-IF(HAVE_PTHREAD_SETSCHEDPARAM)
- MESSAGE(STATUS " Priority scheduling supported through pthread_setschedparam.")
- ADD_DEFINITIONS(-DHAVE_PTHREAD_SETSCHEDPARAM)
-ELSEIF(HAVE_WIN_SETTHREADPRIORITY)
- MESSAGE(STATUS " Priority scheduling supported through windows SetThreadPriority.")
- ADD_DEFINITIONS(-DHAVE_WIN_SETTHREADPRIORITY)
-ELSE(HAVE_PTHREAD_SETSCHEDPARAM)
- MESSAGE(STATUS " Priority scheduling not supported.")
-ENDIF(HAVE_PTHREAD_SETSCHEDPARAM)
-
-########################################################################
-# Setup defines for module loading
-########################################################################
-MESSAGE(STATUS "Configuring module loading...")
-
-INCLUDE(CheckIncludeFileCXX)
-CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H)
-CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H)
-
-IF(HAVE_DLFCN_H)
- MESSAGE(STATUS " Module loading supported through dlopen.")
- ADD_DEFINITIONS(-DHAVE_DLFCN_H)
-ELSEIF(HAVE_WINDOWS_H)
- MESSAGE(STATUS " Module loading supported through LoadLibrary.")
- ADD_DEFINITIONS(-DHAVE_WINDOWS_H)
-ELSE(HAVE_DLFCN_H)
- MESSAGE(STATUS " Module loading not supported.")
-ENDIF(HAVE_DLFCN_H)
+INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/utils/CMakeLists.txt)
########################################################################
# Append to the list of sources for lib uhd
########################################################################
CONFIGURE_FILE(
- ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp.in
- ${CMAKE_CURRENT_BINARY_DIR}/version.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/constants.hpp.in
+ ${CMAKE_CURRENT_BINARY_DIR}/constants.hpp
@ONLY)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_BINARY_DIR}/constants.hpp
${CMAKE_CURRENT_SOURCE_DIR}/device.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/thread_priority.cpp
${CMAKE_CURRENT_SOURCE_DIR}/types.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/version.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wax.cpp
)
@@ -125,9 +71,7 @@ LIBUHD_APPEND_SOURCES(
# Setup libuhd library
########################################################################
ADD_LIBRARY(uhd SHARED ${libuhd_sources})
-
-TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES} ${CMAKE_DL_LIBS})
-
+TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES} ${libuhd_libs})
SET_TARGET_PROPERTIES(uhd PROPERTIES DEFINE_SYMBOL "UHD_DLL_EXPORTS")
INSTALL(TARGETS uhd
diff --git a/host/lib/constants.hpp.in b/host/lib/constants.hpp.in
new file mode 100644
index 000000000..295c8f16c
--- /dev/null
+++ b/host/lib/constants.hpp.in
@@ -0,0 +1,28 @@
+//
+// Copyright 2010 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_LIBUHD_CONSTANTS_HPP
+#define INCLUDED_LIBUHD_CONSTANTS_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+static const std::string UHD_VERSION_STRING = "@CPACK_PACKAGE_VERSION@";
+static const std::string UHD_INSTALL_PREFIX = "@CMAKE_INSTALL_PREFIX@";
+static const std::string UHD_PKG_DATA_DIR = "@PKG_DATA_DIR@";
+
+#endif /* INCLUDED_LIBUHD_CONSTANTS_HPP */
diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt
index 39f26a5a6..dd188d4c0 100644
--- a/host/lib/ic_reg_maps/CMakeLists.txt
+++ b/host/lib/ic_reg_maps/CMakeLists.txt
@@ -55,6 +55,11 @@ LIBUHD_PYTHON_GEN_SOURCE(
)
LIBUHD_PYTHON_GEN_SOURCE(
+ ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_max2118_regs.py
+ ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/max2118_regs.hpp
+)
+
+LIBUHD_PYTHON_GEN_SOURCE(
${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9862_regs.py
${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9862_regs.hpp
)
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py
index 47325a7e3..986093004 100644
--- a/host/lib/ic_reg_maps/common.py
+++ b/host/lib/ic_reg_maps/common.py
@@ -173,7 +173,7 @@ class mreg:
def get_type(self):
return 'boost::uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8)
-def generate(name, regs_tmpl, body_tmpl='', file=__file__):
+def generate(name, regs_tmpl, body_tmpl='', file=__file__, append=False):
#evaluate the regs template and parse each line into a register
regs = list(); mregs = list()
for entry in parse_tmpl(regs_tmpl).splitlines():
@@ -193,4 +193,4 @@ def generate(name, regs_tmpl, body_tmpl='', file=__file__):
)
#write the generated code to file specified by argv1
- open(sys.argv[1], 'w').write(code)
+ open(sys.argv[1], 'a' if append else 'w').write(code)
diff --git a/host/lib/ic_reg_maps/gen_max2118_regs.py b/host/lib/ic_reg_maps/gen_max2118_regs.py
new file mode 100644
index 000000000..506fbaec8
--- /dev/null
+++ b/host/lib/ic_reg_maps/gen_max2118_regs.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 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/>.
+#
+
+########################################################################
+# Template for raw text data describing write registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+WRITE_REGS_TMPL="""\
+########################################################################
+## Note: offsets given from perspective of data bits (excludes address)
+########################################################################
+##
+########################################################################
+## N-Divider MSB (0) Write
+########################################################################
+div2 0[7] 0 div4, div2
+n_divider_msb 0[0:6] 3
+########################################################################
+## N-Divider LSB (1) Write
+########################################################################
+n_divider_lsb 1[0:7] 0xB6
+~n_divider n_divider_lsb, n_divider_msb
+########################################################################
+## R, Charge Pump, and VCO (2) Write
+########################################################################
+#set $r_divider_names = ', '.join(map(lambda x: 'div' + str(2**(x+1)), range(0,8)))
+r_divider 2[5:7] 1 $r_divider_names
+#set $cp_current_bias = ', '.join(map(lambda x: 'i_cp_%dua'%(50*2**x), range(0,4)))
+cp_current 2[3:4] 3 $cp_current_bias
+osc_band 2[0:2] 5
+########################################################################
+## I/Q Filter DAC (3) Write
+########################################################################
+##unused 3[7] 0
+f_dac 3[0:6] 0x7F ## filter tuning dac, depends on m
+########################################################################
+## LPF Divider DAC (4) Write
+########################################################################
+adl_vco_adc_latch 4[7] 0 disabled, enabled
+ade_vco_ade_read 4[6] 0 disabled, enabled
+dl_output_drive 4[5] 0 iq_590m_vpp, iq_1_vpp
+m_divider 4[0:4] 2 ## filter tuning counter
+########################################################################
+## GC2 and Diag (5) Write
+########################################################################
+diag 5[5:7] 0 normal, cp_i_source, cp_i_sink, cp_high_z, unused, n_and_filt, r_and_gc2, m_div
+gc2 5[0:4] 0x1F ## Step Size: 0-1: 0dB, 2-22: 1dB, 23-31: 0.5dB
+"""
+
+########################################################################
+# Template for raw text data describing read registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+READ_REGS_TMPL="""\
+########################################################################
+## Status (0) Read
+########################################################################
+pwr 0[6] 0 not_reset, reset
+adc 0[2:4] 0 ## VCO tuning voltage, Lock Status
+########################################################################
+## I/Q Filter DAC (1) Read
+########################################################################
+filter_dac 1[0:6] 0 ## I/Q Filter tuning DAC, current
+"""
+
+########################################################################
+# Template for methods in the body of the struct
+########################################################################
+BODY_TMPL="""\
+boost::uint8_t get_reg(boost::uint8_t addr){
+ boost::uint8_t reg = 0;
+ switch(addr){
+ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs)))
+ case $addr:
+ #for $reg in filter(lambda r: r.get_addr() == addr, $regs)
+ reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();
+ #end for
+ break;
+ #end for
+ }
+ return boost::uint8_t(reg);
+}
+
+void set_reg(boost::uint8_t addr, boost::uint8_t reg){
+ switch(addr){
+ #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs)))
+ case $addr:
+ #for $reg in filter(lambda r: r.get_addr() == addr, $regs)
+ $reg.get_name() = $(reg.get_type())((reg >> $reg.get_shift()) & $reg.get_mask());
+ #end for
+ break;
+ #end for
+ }
+}
+"""
+
+if __name__ == '__main__':
+ import common; common.generate(
+ name='max2118_write_regs',
+ regs_tmpl=WRITE_REGS_TMPL,
+ body_tmpl=BODY_TMPL,
+ file=__file__,
+ )
+
+ import common; common.generate(
+ name='max2118_read_regs',
+ regs_tmpl=READ_REGS_TMPL,
+ body_tmpl=BODY_TMPL,
+ file=__file__,
+ append=True,
+ )
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index bbbabf6d0..ee989ee2b 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -18,6 +18,7 @@
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/transport/udp_simple.hpp> //mtu
#include <uhd/utils/assert.hpp>
+#include <uhd/utils/warning.hpp>
#include <boost/cstdint.hpp>
#include <boost/asio.hpp>
#include <boost/format.hpp>
@@ -161,12 +162,11 @@ template<typename Opt> static void resize_buff_helper(
else std::cout << boost::format(
"Current %s sock buff size: %d bytes"
) % name % actual_size << std::endl;
- if (actual_size < target_size) std::cerr << boost::format(
- "Warning:\n"
- " The %s buffer is smaller than the requested size.\n"
- " The minimum recommended buffer size is %d bytes.\n"
- " See the USRP2 application notes on buffer resizing.\n"
- ) % name % min_sock_buff_size << std::endl;
+ if (actual_size < target_size) uhd::print_warning(str(boost::format(
+ "The %s buffer is smaller than the requested size.\n"
+ "The minimum recommended buffer size is %d bytes.\n"
+ "See the USRP2 application notes on buffer resizing.\n"
+ ) % name % min_sock_buff_size));
}
//only enable on platforms that are happy with the large buffer resize
diff --git a/host/lib/transport/zero_copy.cpp b/host/lib/transport/zero_copy.cpp
index 42f69d77b..8a1cde694 100644
--- a/host/lib/transport/zero_copy.cpp
+++ b/host/lib/transport/zero_copy.cpp
@@ -54,12 +54,14 @@ private:
//! phony zero-copy recv interface implementation
struct phony_zero_copy_recv_if::impl{
+ impl(size_t max_buff_size) : max_buff_size(max_buff_size){
+ /* NOP */
+ }
size_t max_buff_size;
};
phony_zero_copy_recv_if::phony_zero_copy_recv_if(size_t max_buff_size){
- _impl = UHD_PIMPL_MAKE(impl, ());
- _impl->max_buff_size = max_buff_size;
+ _impl = UHD_PIMPL_MAKE(impl, (max_buff_size));
}
phony_zero_copy_recv_if::~phony_zero_copy_recv_if(void){
diff --git a/host/lib/types.cpp b/host/lib/types.cpp
index 1cfe84832..5c0fb1f42 100644
--- a/host/lib/types.cpp
+++ b/host/lib/types.cpp
@@ -36,6 +36,7 @@
#include <boost/thread.hpp>
#include <stdexcept>
#include <complex>
+#include <sstream>
using namespace uhd;
@@ -190,7 +191,7 @@ device_addr_t::device_addr_t(const std::string &args){
std::vector<std::string> key_val;
boost::split(key_val, pair, boost::is_any_of(pair_delim));
if (key_val.size() != 2) throw std::runtime_error("invalid args string: "+args);
- (*this)[trim(key_val[0])] = trim(key_val[1]);
+ (*this)[trim(key_val.front())] = trim(key_val.back());
}
}
@@ -198,16 +199,18 @@ std::string device_addr_t::to_pp_string(void) const{
if (this->size() == 0) return "Empty Device Address";
std::stringstream ss;
+ ss << "Device Address:" << std::endl;
BOOST_FOREACH(std::string key, this->keys()){
- ss << boost::format("%s: %s") % key % (*this)[key] << std::endl;
+ ss << boost::format(" %s: %s") % key % (*this)[key] << std::endl;
}
return ss.str();
}
std::string device_addr_t::to_string(void) const{
std::string args_str;
+ size_t count = 0;
BOOST_FOREACH(const std::string &key, this->keys()){
- args_str += key + pair_delim + (*this)[key] + arg_delim;
+ args_str += ((count++)? arg_delim : "") + key + pair_delim + (*this)[key];
}
return args_str;
}
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt
index 4f0710b20..d951ab412 100644
--- a/host/lib/usrp/CMakeLists.txt
+++ b/host/lib/usrp/CMakeLists.txt
@@ -27,5 +27,9 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.hpp
${CMAKE_SOURCE_DIR}/lib/usrp/simple_usrp.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/subdev_spec.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/tune_helper.cpp
)
+
+INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/dboard/CMakeLists.txt)
+INCLUDE(${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/CMakeLists.txt)
diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt
index 6093583d3..3e995009e 100644
--- a/host/lib/usrp/dboard/CMakeLists.txt
+++ b/host/lib/usrp/dboard/CMakeLists.txt
@@ -22,6 +22,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_rfx.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_xcvr2450.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_wbx.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_dbsrx.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_unknown.cpp
)
diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp
new file mode 100644
index 000000000..03e6b6255
--- /dev/null
+++ b/host/lib/usrp/dboard/db_dbsrx.cpp
@@ -0,0 +1,610 @@
+//
+// Copyright 2010 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/>.
+//
+
+// No RX IO Pins Used
+
+// RX IO Functions
+
+#include "max2118_regs.hpp"
+#include <uhd/utils/static.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/warning.hpp>
+#include <uhd/types/ranges.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/usrp/subdev_props.hpp>
+#include <uhd/usrp/dboard_base.hpp>
+#include <uhd/usrp/dboard_manager.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/format.hpp>
+#include <boost/thread.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <utility>
+#include <cmath>
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+/***********************************************************************
+ * The DBSRX constants
+ **********************************************************************/
+static const bool dbsrx_debug = false;
+
+static const freq_range_t dbsrx_freq_range(0.8e9, 2.4e9);
+
+static const freq_range_t dbsrx_pfd_freq_range(0.15e6, 2.01e6);
+
+static const prop_names_t dbsrx_antennas = list_of("J3");
+
+static const uhd::dict<std::string, gain_range_t> dbsrx_gain_ranges = map_list_of
+ ("GC1", gain_range_t(0, 56, 0.5))
+ ("GC2", gain_range_t(0, 24, 1))
+;
+
+/***********************************************************************
+ * The DBSRX dboard class
+ **********************************************************************/
+class dbsrx : public rx_dboard_base{
+public:
+ dbsrx(ctor_args_t args, boost::uint8_t max2118_addr);
+ ~dbsrx(void);
+
+ void rx_get(const wax::obj &key, wax::obj &val);
+ void rx_set(const wax::obj &key, const wax::obj &val);
+
+private:
+ double _lo_freq;
+ float _bandwidth;
+ uhd::dict<std::string, float> _gains;
+ max2118_write_regs_t _max2118_write_regs;
+ max2118_read_regs_t _max2118_read_regs;
+ boost::uint8_t _max2118_addr; //0x67 or 0x65 depending on which side
+
+ void set_lo_freq(double target_freq);
+ void set_gain(float gain, const std::string &name);
+ void set_bandwidth(float bandwidth);
+
+ void send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){
+ start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0x5));
+ stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0x5));
+
+ for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t) - 1){
+ int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) - 1 ? sizeof(boost::uint32_t) - 1 : stop_reg - start_addr + 1;
+
+ //create buffer for register data (+1 for start address)
+ byte_vector_t regs_vector(num_bytes + 1);
+
+ //first byte is the address of first register
+ regs_vector[0] = start_addr;
+
+ //get the register data
+ for(int i=0; i<num_bytes; i++){
+ regs_vector[1+i] = _max2118_write_regs.get_reg(start_addr+i);
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d"
+ ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes << std::endl;
+ }
+
+ //send the data
+ this->get_iface()->write_i2c(
+ _max2118_addr, regs_vector
+ );
+ }
+ }
+
+ void read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){
+ static const boost::uint8_t status_addr = 0x0;
+ start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0x1));
+ stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0x1));
+
+ for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t)){
+ int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) ? sizeof(boost::uint32_t) : stop_reg - start_addr + 1;
+
+ //create buffer for register data
+ byte_vector_t regs_vector(num_bytes);
+
+ //read from i2c
+ regs_vector = this->get_iface()->read_i2c(
+ _max2118_addr, num_bytes
+ );
+
+ for(boost::uint8_t i=0; i < num_bytes; i++){
+ if (i + start_addr >= status_addr){
+ _max2118_read_regs.set_reg(i + start_addr, regs_vector[i]);
+ }
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d"
+ ) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes << std::endl;
+ }
+ }
+ }
+
+ /*!
+ * Is the LO locked?
+ * \return true for locked
+ */
+ bool get_locked(void){
+ read_reg(0x0, 0x0);
+
+ //mask and return lock detect
+ bool locked = 5 >= _max2118_read_regs.adc and _max2118_read_regs.adc >= 2;
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: locked %d"
+ ) % locked << std::endl;
+
+ return locked;
+ }
+
+};
+
+/***********************************************************************
+ * Register the DBSRX dboard
+ **********************************************************************/
+// FIXME 0x67 is the default i2c address on USRP2
+// need to handle which side for USRP1 with different address
+static dboard_base::sptr make_dbsrx(dboard_base::ctor_args_t args){
+ return dboard_base::sptr(new dbsrx(args, 0x67));
+}
+
+//dbid for USRP2 version
+UHD_STATIC_BLOCK(reg_dbsrx_dboard){
+ //register the factory function for the rx dbid
+ dboard_manager::register_dboard(0x000D, &make_dbsrx, "DBSRX");
+}
+
+//dbid for USRP1 version
+UHD_STATIC_BLOCK(reg_dbsrx_on_usrp1_dboard){
+ //register the factory function for the rx dbid
+ dboard_manager::register_dboard(0x0002, &make_dbsrx, "DBSRX");
+}
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+dbsrx::dbsrx(ctor_args_t args, boost::uint8_t max2118_addr) : rx_dboard_base(args){
+ //warn user about incorrect DBID on USRP1, requires R193 populated
+ if (this->get_iface()->get_mboard_name() == "usrp1" and this->get_rx_id() == 0x000D)
+ uhd::print_warning(
+ str(boost::format(
+ "DBSRX: incorrect dbid\n"
+ "%s expects dbid 0x0002 and R193\n"
+ "found dbid == %d\n"
+ "Please see the daughterboard app notes"
+ ) % (this->get_iface()->get_mboard_name()) % (this->get_rx_id().to_pp_string()))
+ );
+
+ //warn user about incorrect DBID on non-USRP1, requires R194 populated
+ if (this->get_iface()->get_mboard_name() != "usrp1" and this->get_rx_id() == 0x0002)
+ uhd::print_warning(
+ str(boost::format(
+ "DBSRX: incorrect dbid\n"
+ "%s expects dbid 0x000D and R194\n"
+ "found dbid == %d\n"
+ "Please see the daughterboard app notes"
+ ) % (this->get_iface()->get_mboard_name()) % (this->get_rx_id().to_pp_string()))
+ );
+
+ //enable only the clocks we need
+ this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);
+
+ //set the gpio directions and atr controls (identically)
+ this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr
+ this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs
+
+ //set the i2c address for the max2118
+ _max2118_addr = max2118_addr;
+
+ //send initial register settings
+ this->send_reg(0x0, 0x5);
+
+ //set defaults for LO, gains, and filter bandwidth
+ _bandwidth = 33e6;
+ set_lo_freq(dbsrx_freq_range.min);
+
+ BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){
+ set_gain(dbsrx_gain_ranges[name].min, name);
+ }
+
+ set_bandwidth(33e6); // default bandwidth from datasheet
+}
+
+dbsrx::~dbsrx(void){
+}
+
+
+/***********************************************************************
+ * Tuning
+ **********************************************************************/
+void dbsrx::set_lo_freq(double target_freq){
+ target_freq = std::clip(target_freq, dbsrx_freq_range.min, dbsrx_freq_range.max);
+
+ double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0;
+ int R=0, N=0, r=0, m=0;
+ bool update_filter_settings = false;
+
+ //choose refclock
+ std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX);
+ BOOST_FOREACH(ref_clock, std::reversed(std::sorted(clock_rates))){
+ if (ref_clock > 27.0e6) continue;
+
+ //choose m_divider such that filter tuning constraint is met
+ m = 31;
+ while ((ref_clock/m < 1e6 or ref_clock/m > 2.5e6) and m > 0){ m--; }
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: trying ref_clock %f and m_divider %d"
+ ) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % m << std::endl;
+
+ if (m >= 32) continue;
+
+ //choose R
+ for(r = 0; r <= 6; r += 1) {
+ //compute divider from setting
+ R = 1 << (r+1);
+ if (dbsrx_debug) std::cerr << boost::format("DBSRX R:%d\n") % R << std::endl;
+
+ //compute PFD compare frequency = ref_clock/R
+ pfd_freq = ref_clock / R;
+
+ //constrain the PFD frequency to specified range
+ if ((pfd_freq < dbsrx_pfd_freq_range.min) or (pfd_freq > dbsrx_pfd_freq_range.max)) continue;
+
+ //compute N
+ N = int(std::floor(target_freq/pfd_freq));
+
+ //constrain N to specified range
+ if ((N < 256) or (N > 32768)) continue;
+
+ goto done_loop;
+ }
+ }
+
+ //Assert because we failed to find a suitable combination of ref_clock, R and N
+ UHD_ASSERT_THROW(ref_clock/(1 << m) < 1e6 or ref_clock/(1 << m) > 2.5e6);
+ UHD_ASSERT_THROW((pfd_freq < dbsrx_pfd_freq_range.min) or (pfd_freq > dbsrx_pfd_freq_range.max));
+ UHD_ASSERT_THROW((N < 256) or (N > 32768));
+ done_loop:
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: choose ref_clock %f and m_divider %d"
+ ) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % m << std::endl;
+
+ //if ref_clock or m divider changed, we need to update the filter settings
+ if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) or m != _max2118_write_regs.m_divider) update_filter_settings = true;
+
+ //compute resulting output frequency
+ actual_freq = pfd_freq * N;
+
+ //apply ref_clock, R, and N settings
+ this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, ref_clock);
+ ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
+ _max2118_write_regs.m_divider = m;
+ _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r;
+ _max2118_write_regs.set_n_divider(N);
+ _max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED;
+
+ //compute prescaler variables
+ int scaler = actual_freq > 1125e6 ? 2 : 4;
+ _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2;
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: scaler %d, actual_freq %f MHz, register bit: %d"
+ ) % scaler % (actual_freq/1e6) % int(_max2118_write_regs.div2) << std::endl;
+
+ //compute vco frequency and select vco
+ double vco_freq = actual_freq * scaler;
+ if (vco_freq < 2433e6)
+ _max2118_write_regs.osc_band = 0;
+ else if (vco_freq < 2711e6)
+ _max2118_write_regs.osc_band = 1;
+ else if (vco_freq < 3025e6)
+ _max2118_write_regs.osc_band = 2;
+ else if (vco_freq < 3341e6)
+ _max2118_write_regs.osc_band = 3;
+ else if (vco_freq < 3727e6)
+ _max2118_write_regs.osc_band = 4;
+ else if (vco_freq < 4143e6)
+ _max2118_write_regs.osc_band = 5;
+ else if (vco_freq < 4493e6)
+ _max2118_write_regs.osc_band = 6;
+ else
+ _max2118_write_regs.osc_band = 7;
+
+ //send settings over i2c
+ send_reg(0x0, 0x4);
+
+ //check vtune for lock condition
+ read_reg(0x0, 0x0);
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: initial guess for vco %d, vtune adc %d"
+ ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;
+
+ //if we are out of lock for chosen vco, change vco
+ while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)){
+
+ //vtune is too low, try lower frequency vco
+ if (_max2118_read_regs.adc == 0){
+ if (_max2118_write_regs.osc_band == 0){
+ uhd::print_warning(
+ str(boost::format(
+ "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
+ ) % int(_max2118_write_regs.osc_band))
+ );
+ UHD_ASSERT_THROW(_max2118_read_regs.adc == 0);
+ }
+ if (_max2118_write_regs.osc_band <= 0) break;
+ _max2118_write_regs.osc_band -= 1;
+ }
+
+ //vtune is too high, try higher frequency vco
+ if (_max2118_read_regs.adc == 7){
+ if (_max2118_write_regs.osc_band == 7){
+ uhd::print_warning(
+ str(boost::format(
+ "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
+ ) % int(_max2118_write_regs.osc_band))
+ );
+ UHD_ASSERT_THROW(_max2118_read_regs.adc == 0);
+ }
+ if (_max2118_write_regs.osc_band >= 7) break;
+ _max2118_write_regs.osc_band += 1;
+ }
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: trying vco %d, vtune adc %d"
+ ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;
+
+ //update vco selection and check vtune
+ send_reg(0x2, 0x2);
+ read_reg(0x0, 0x0);
+ }
+
+ if(dbsrx_debug) std::cerr << boost::format(
+ "DBSRX: final vco %d, vtune adc %d"
+ ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;
+
+ //select charge pump bias current
+ if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA;
+ else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA;
+ else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA;
+
+ //update charge pump bias current setting
+ send_reg(0x2, 0x2);
+
+ //compute actual tuned frequency
+ _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) / std::pow(2.0,(1 + _max2118_write_regs.r_divider)) * _max2118_write_regs.get_n_divider();
+
+ //debug output of calculated variables
+ if (dbsrx_debug) std::cerr
+ << boost::format("DBSRX tune:\n")
+ << boost::format(" VCO=%d, CP=%d, PFD Freq=%fMHz\n") % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current % (pfd_freq/1e6)
+ << boost::format(" R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler % int(_max2118_write_regs.div2)
+ << boost::format(" Ref Freq=%fMHz\n") % (ref_clock/1e6)
+ << boost::format(" Target Freq=%fMHz\n") % (target_freq/1e6)
+ << boost::format(" Actual Freq=%fMHz\n") % (_lo_freq/1e6)
+ << std::endl;
+
+ if (update_filter_settings) set_bandwidth(_bandwidth);
+ get_locked();
+}
+
+/***********************************************************************
+ * Gain Handling
+ **********************************************************************/
+/*!
+ * Convert a requested gain for the GC2 vga into the integer register value.
+ * The gain passed into the function will be set to the actual value.
+ * \param gain the requested gain in dB
+ * \return 5 bit the register value
+ */
+static int gain_to_gc2_vga_reg(float &gain){
+ int reg = 0;
+ gain = std::clip<float>(float(boost::math::iround(gain)), dbsrx_gain_ranges["GC2"].min, dbsrx_gain_ranges["GC2"].max);
+
+ // Half dB steps from 0-5dB, 1dB steps from 5-24dB
+ if (gain < 5) {
+ reg = boost::math::iround(31.0 - gain/0.5);
+ gain = float(boost::math::iround(gain) * 0.5);
+ } else {
+ reg = boost::math::iround(22.0 - (gain - 4.0));
+ gain = float(boost::math::iround(gain));
+ }
+
+ if (dbsrx_debug) std::cerr << boost::format(
+ "DBSRX GC2 Gain: %f dB, reg: %d"
+ ) % gain % reg << std::endl;
+
+ return reg;
+}
+
+/*!
+ * Convert a requested gain for the GC1 rf vga into the dac_volts value.
+ * The gain passed into the function will be set to the actual value.
+ * \param gain the requested gain in dB
+ * \return dac voltage value
+ */
+static float gain_to_gc1_rfvga_dac(float &gain){
+ //clip the input
+ gain = std::clip<float>(gain, dbsrx_gain_ranges["GC1"].min, dbsrx_gain_ranges["GC1"].max);
+
+ //voltage level constants
+ static const float max_volts = float(1.2), min_volts = float(2.7);
+ static const float slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].max;
+
+ //calculate the voltage for the aux dac
+ float dac_volts = gain*slope + min_volts;
+
+ if (dbsrx_debug) std::cerr << boost::format(
+ "DBSRX GC1 Gain: %f dB, dac_volts: %f V"
+ ) % gain % dac_volts << std::endl;
+
+ //the actual gain setting
+ gain = (dac_volts - min_volts)/slope;
+
+ return dac_volts;
+}
+
+void dbsrx::set_gain(float gain, const std::string &name){
+ assert_has(dbsrx_gain_ranges.keys(), name, "dbsrx gain name");
+ if (name == "GC2"){
+ _max2118_write_regs.gc2 = gain_to_gc2_vga_reg(gain);
+ send_reg(0x5, 0x5);
+ }
+ else if(name == "GC1"){
+ //write the new voltage to the aux dac
+ this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain));
+ }
+ else UHD_THROW_INVALID_CODE_PATH();
+ _gains[name] = gain;
+}
+
+/***********************************************************************
+ * Bandwidth Handling
+ **********************************************************************/
+void dbsrx::set_bandwidth(float bandwidth){
+ //clip the input
+ bandwidth = std::clip<float>(bandwidth, 4e6, 33e6);
+
+ double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
+
+ //NOTE: _max2118_write_regs.m_divider set in set_lo_freq
+
+ //compute f_dac setting
+ _max2118_write_regs.f_dac = std::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127);
+
+ //determine actual bandwidth
+ _bandwidth = float((ref_clock/(_max2118_write_regs.m_divider))*(4+0.145*_max2118_write_regs.f_dac));
+
+ if (dbsrx_debug) std::cerr << boost::format(
+ "DBSRX Filter Bandwidth: %f MHz, m: %d, f_dac: %d\n"
+ ) % (_bandwidth/1e6) % int(_max2118_write_regs.m_divider) % int(_max2118_write_regs.f_dac) << std::endl;
+
+ this->send_reg(0x3, 0x4);
+}
+
+/***********************************************************************
+ * RX Get and Set
+ **********************************************************************/
+void dbsrx::rx_get(const wax::obj &key_, wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+ case SUBDEV_PROP_NAME:
+ val = get_rx_id().to_pp_string();
+ return;
+
+ case SUBDEV_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ assert_has(_gains.keys(), name, "dbsrx gain name");
+ val = _gains[name];
+ return;
+
+ case SUBDEV_PROP_GAIN_RANGE:
+ assert_has(dbsrx_gain_ranges.keys(), name, "dbsrx gain name");
+ val = dbsrx_gain_ranges[name];
+ return;
+
+ case SUBDEV_PROP_GAIN_NAMES:
+ val = prop_names_t(dbsrx_gain_ranges.keys());
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ val = _lo_freq;
+ return;
+
+ case SUBDEV_PROP_FREQ_RANGE:
+ val = dbsrx_freq_range;
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ val = std::string("J3");
+ return;
+
+ case SUBDEV_PROP_ANTENNA_NAMES:
+ val = dbsrx_antennas;
+ return;
+
+/*
+ case SUBDEV_PROP_QUADRATURE:
+ val = true;
+ return;
+
+ case SUBDEV_PROP_IQ_SWAPPED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_SPECTRUM_INVERTED:
+ val = false;
+ return;
+*/
+ case SUBDEV_PROP_CONNECTION:
+ val = SUBDEV_CONN_COMPLEX_IQ;
+ return;
+
+ case SUBDEV_PROP_USE_LO_OFFSET:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_LO_LOCKED:
+ val = this->get_locked();
+ return;
+
+/*
+ case SUBDEV_PROP_RSSI:
+ val = this->get_rssi();
+ return;
+*/
+
+ case SUBDEV_PROP_BANDWIDTH:
+ val = _bandwidth;
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+void dbsrx::rx_set(const wax::obj &key_, const wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+
+ case SUBDEV_PROP_FREQ:
+ this->set_lo_freq(val.as<double>());
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ this->set_gain(val.as<float>(), name);
+ return;
+
+ case SUBDEV_PROP_BANDWIDTH:
+ this->set_bandwidth(val.as<float>());
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
+
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 914ca5e19..b6b44199a 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -43,6 +43,7 @@
#include <uhd/utils/assert.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/algorithm.hpp>
+#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/dboard_base.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <boost/assign/list_of.hpp>
@@ -65,6 +66,10 @@ static const prop_names_t rfx_rx_antennas = list_of("TX/RX")("RX2");
static const uhd::dict<std::string, gain_range_t> rfx_tx_gain_ranges; //empty
static const uhd::dict<std::string, gain_range_t> rfx_rx_gain_ranges = map_list_of
+ ("PGA0", gain_range_t(0, 70, float(0.022)))
+;
+
+static const uhd::dict<std::string, gain_range_t> rfx400_rx_gain_ranges = map_list_of
("PGA0", gain_range_t(0, 45, float(0.022)))
;
@@ -88,6 +93,7 @@ public:
private:
freq_range_t _freq_range;
+ uhd::dict<std::string, gain_range_t> _rx_gain_ranges;
uhd::dict<dboard_iface::unit_t, bool> _div2;
double _rx_lo_freq, _tx_lo_freq;
std::string _rx_ant;
@@ -166,6 +172,14 @@ rfx_xcvr::rfx_xcvr(
_div2[dboard_iface::UNIT_RX] = rx_div2;
_div2[dboard_iface::UNIT_TX] = tx_div2;
+ if(this->get_rx_id() == 0x0024) { //RFX400
+ _rx_gain_ranges = rfx400_rx_gain_ranges;
+ }
+ else {
+ _rx_gain_ranges = rfx_rx_gain_ranges;
+ }
+
+
//enable the clocks that we need
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);
@@ -193,8 +207,8 @@ rfx_xcvr::rfx_xcvr(
set_tx_lo_freq((_freq_range.min + _freq_range.max)/2.0);
set_rx_ant("RX2");
- BOOST_FOREACH(const std::string &name, rfx_rx_gain_ranges.keys()){
- set_rx_gain(rfx_rx_gain_ranges[name].min, name);
+ BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){
+ set_rx_gain(_rx_gain_ranges[name].min, name);
}
}
@@ -227,10 +241,10 @@ void rfx_xcvr::set_tx_ant(const std::string &ant){
/***********************************************************************
* Gain Handling
**********************************************************************/
-static float rx_pga0_gain_to_dac_volts(float &gain){
+static float rx_pga0_gain_to_dac_volts(float &gain, float range){
//voltage level constants (negative slope)
static const float max_volts = float(.2), min_volts = float(1.2);
- static const float slope = (max_volts-min_volts)/45;
+ static const float slope = (max_volts-min_volts)/(range);
//calculate the voltage for the aux dac
float dac_volts = std::clip<float>(gain*slope + min_volts, max_volts, min_volts);
@@ -247,9 +261,10 @@ void rfx_xcvr::set_tx_gain(float, const std::string &name){
}
void rfx_xcvr::set_rx_gain(float gain, const std::string &name){
- assert_has(rfx_rx_gain_ranges.keys(), name, "rfx rx gain name");
+ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name");
if(name == "PGA0"){
- float dac_volts = rx_pga0_gain_to_dac_volts(gain);
+ float dac_volts = rx_pga0_gain_to_dac_volts(gain,
+ (_rx_gain_ranges["PGA0"].max - _rx_gain_ranges["PGA0"].min));
_rx_gains[name] = gain;
//write the new voltage to the aux dac
@@ -402,12 +417,12 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_GAIN_RANGE:
- assert_has(rfx_rx_gain_ranges.keys(), name, "rfx rx gain name");
- val = rfx_rx_gain_ranges[name];
+ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name");
+ val = _rx_gain_ranges[name];
return;
case SUBDEV_PROP_GAIN_NAMES:
- val = prop_names_t(rfx_rx_gain_ranges.keys());
+ val = prop_names_t(_rx_gain_ranges.keys());
return;
case SUBDEV_PROP_FREQ:
diff --git a/host/lib/usrp/mimo_usrp.cpp b/host/lib/usrp/mimo_usrp.cpp
index 6b9318c39..e78d38fc0 100644
--- a/host/lib/usrp/mimo_usrp.cpp
+++ b/host/lib/usrp/mimo_usrp.cpp
@@ -20,6 +20,7 @@
#include <uhd/utils/assert.hpp>
#include <uhd/utils/gain_group.hpp>
#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/warning.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
#include <uhd/usrp/device_props.hpp>
@@ -47,31 +48,12 @@ public:
mimo_usrp_impl(const device_addr_t &addr){
_dev = device::make(addr);
- //extract each mboard and its sub-devices
- BOOST_FOREACH(const std::string &name, (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>()){
- _mboards.push_back((*_dev)[named_prop_t(DEVICE_PROP_MBOARD, name)]);
- _rx_dsps.push_back(_mboards.back()[MBOARD_PROP_RX_DSP]);
- _tx_dsps.push_back(_mboards.back()[MBOARD_PROP_TX_DSP]);
-
- //extract rx subdevice
- _rx_dboards.push_back(_mboards.back()[MBOARD_PROP_RX_DBOARD]);
- std::string rx_subdev_in_use = _rx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _rx_subdevs.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)]);
- _rx_gain_groups.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_GAIN_GROUP, rx_subdev_in_use)].as<gain_group::sptr>());
-
- //extract tx subdevice
- _tx_dboards.push_back(_mboards.back()[MBOARD_PROP_TX_DBOARD]);
- std::string tx_subdev_in_use = _tx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _tx_subdevs.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)]);
- _tx_gain_groups.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_GAIN_GROUP, tx_subdev_in_use)].as<gain_group::sptr>());
- }
-
//set the clock config across all mboards (TODO set through api)
clock_config_t clock_config;
clock_config.ref_source = clock_config_t::REF_SMA;
clock_config.pps_source = clock_config_t::PPS_SMA;
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
}
}
@@ -90,7 +72,7 @@ public:
)
% (*_dev)[DEVICE_PROP_NAME].as<std::string>()
);
- for (size_t i = 0; i < get_num_channels(); i++){
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
buff += str(boost::format(
" Channel: %u\n"
" Mboard: %s\n"
@@ -100,21 +82,21 @@ public:
" TX DSP: %s\n"
" TX Dboard: %s\n"
" TX Subdev: %s\n"
- ) % i
- % _mboards.at(i)[MBOARD_PROP_NAME].as<std::string>()
- % _rx_dsps.at(i)[DSP_PROP_NAME].as<std::string>()
- % _rx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>()
- % _rx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>()
- % _tx_dsps.at(i)[DSP_PROP_NAME].as<std::string>()
- % _tx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>()
- % _tx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>()
+ ) % chan
+ % _mboard(chan)[MBOARD_PROP_NAME].as<std::string>()
+ % _rx_dsp(chan)[DSP_PROP_NAME].as<std::string>()
+ % _rx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()
+ % _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()
+ % _tx_dsp(chan)[DSP_PROP_NAME].as<std::string>()
+ % _tx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()
+ % _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()
);
}
return buff;
}
size_t get_num_channels(void){
- return _mboards.size();
+ return (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>().size();
}
/*******************************************************************
@@ -122,12 +104,12 @@ public:
******************************************************************/
time_spec_t get_time_now(void){
//the time on the first mboard better be the same on all
- return _mboards.front()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ return _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
}
void set_time_next_pps(const time_spec_t &time_spec){
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
}
}
@@ -149,33 +131,42 @@ public:
boost::this_thread::sleep(boost::posix_time::seconds(1));
//verify that the time registers are read to be within a few RTT
- for (size_t i = 1; i < get_num_channels(); i++){
- time_spec_t time_0 = _mboards.front()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
- time_spec_t time_i = _mboards.at(i)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ for (size_t chan = 1; chan < get_num_channels(); chan++){
+ time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ time_spec_t time_i = _mboard(chan)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big
- std::cerr << boost::format(
- "Error: time deviation between board %d and board 0.\n"
- " Board 0 time is %f seconds.\n"
- " Board %d time is %f seconds.\n"
- ) % i % time_0.get_real_secs() % i % time_i.get_real_secs() << std::endl;
+ uhd::print_warning(str(boost::format(
+ "Detected time deviation between board %d and board 0.\n"
+ "Board 0 time is %f seconds.\n"
+ "Board %d time is %f seconds.\n"
+ ) % chan % time_0.get_real_secs() % chan % time_i.get_real_secs()));
}
}
}
void issue_stream_cmd(const stream_cmd_t &stream_cmd){
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_STREAM_CMD] = stream_cmd;
}
}
/*******************************************************************
* RX methods
******************************************************************/
+ void set_rx_subdev_spec(size_t chan, const subdev_spec_t &spec){
+ UHD_ASSERT_THROW(spec.size() <= 1);
+ _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC] = spec;
+ }
+
+ subdev_spec_t get_rx_subdev_spec(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>();
+ }
+
void set_rx_rate_all(double rate){
std::vector<double> _actual_rates;
- BOOST_FOREACH(wax::obj rx_dsp, _rx_dsps){
- rx_dsp[DSP_PROP_HOST_RATE] = rate;
- _actual_rates.push_back(rx_dsp[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _rx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ _actual_rates.push_back(_rx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>());
}
_rx_rate = _actual_rates.front();
if (std::count(_actual_rates, _rx_rate) != _actual_rates.size()) throw std::runtime_error(
@@ -188,61 +179,70 @@ public:
}
tune_result_t set_rx_freq(size_t chan, double target_freq){
- return tune_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq);
+ return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), target_freq);
}
tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){
- return tune_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq, lo_off);
+ return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), target_freq, lo_off);
}
double get_rx_freq(size_t chan){
- return derive_freq_from_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan));
+ return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan));
}
freq_range_t get_rx_freq_range(size_t chan){
- return add_dsp_shift(_rx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsps.at(chan));
+ return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan));
}
void set_rx_gain(size_t chan, float gain){
- _rx_gain_groups.at(chan)->set_value(gain);
+ return _rx_gain_group(chan)->set_value(gain);
}
float get_rx_gain(size_t chan){
- return _rx_gain_groups.at(chan)->get_value();
+ return _rx_gain_group(chan)->get_value();
}
gain_range_t get_rx_gain_range(size_t chan){
- return _rx_gain_groups.at(chan)->get_range();
+ return _rx_gain_group(chan)->get_range();
}
void set_rx_antenna(size_t chan, const std::string &ant){
- _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant;
+ _rx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_rx_antenna(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_rx_antennas(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_rx_lo_locked(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _rx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
float read_rssi(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_RSSI].as<float>();
+ return _rx_subdev(chan)[SUBDEV_PROP_RSSI].as<float>();
}
/*******************************************************************
* TX methods
******************************************************************/
+ void set_tx_subdev_spec(size_t chan, const subdev_spec_t &spec){
+ UHD_ASSERT_THROW(spec.size() <= 1);
+ _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC] = spec;
+ }
+
+ subdev_spec_t get_tx_subdev_spec(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>();
+ }
+
void set_tx_rate_all(double rate){
std::vector<double> _actual_rates;
- BOOST_FOREACH(wax::obj tx_dsp, _tx_dsps){
- tx_dsp[DSP_PROP_HOST_RATE] = rate;
- _actual_rates.push_back(tx_dsp[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _tx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ _actual_rates.push_back(_tx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>());
}
_tx_rate = _actual_rates.front();
if (std::count(_actual_rates, _tx_rate) != _actual_rates.size()) throw std::runtime_error(
@@ -255,60 +255,85 @@ public:
}
tune_result_t set_tx_freq(size_t chan, double target_freq){
- return tune_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq);
+ return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), target_freq);
}
tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){
- return tune_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq, lo_off);
+ return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), target_freq, lo_off);
}
double get_tx_freq(size_t chan){
- return derive_freq_from_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan));
+ return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan));
}
freq_range_t get_tx_freq_range(size_t chan){
- return add_dsp_shift(_tx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsps.at(chan));
+ return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan));
}
void set_tx_gain(size_t chan, float gain){
- _tx_gain_groups.at(chan)->set_value(gain);
+ return _tx_gain_group(chan)->set_value(gain);
}
float get_tx_gain(size_t chan){
- return _tx_gain_groups.at(chan)->get_value();
+ return _tx_gain_group(chan)->get_value();
}
gain_range_t get_tx_gain_range(size_t chan){
- return _tx_gain_groups.at(chan)->get_range();
+ return _tx_gain_group(chan)->get_range();
}
void set_tx_antenna(size_t chan, const std::string &ant){
- _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant;
+ _tx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_tx_antenna(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_tx_antennas(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_tx_lo_locked(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _tx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
private:
device::sptr _dev;
- std::vector<wax::obj> _mboards;
- std::vector<wax::obj> _rx_dsps;
- std::vector<wax::obj> _tx_dsps;
- std::vector<wax::obj> _rx_dboards;
- std::vector<wax::obj> _tx_dboards;
- std::vector<wax::obj> _rx_subdevs;
- std::vector<wax::obj> _tx_subdevs;
- std::vector<gain_group::sptr> _rx_gain_groups;
- std::vector<gain_group::sptr> _tx_gain_groups;
+ wax::obj _mboard(size_t chan){
+ prop_names_t names = (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>();
+ return (*_dev)[named_prop_t(DEVICE_PROP_MBOARD, names.at(chan))];
+ }
+ wax::obj _rx_dsp(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_RX_DSP];
+ }
+ wax::obj _tx_dsp(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_TX_DSP];
+ }
+ wax::obj _rx_dboard(size_t chan){
+ std::string db_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name;
+ return _mboard(chan)[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
+ }
+ wax::obj _tx_dboard(size_t chan){
+ std::string db_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name;
+ return _mboard(chan)[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
+ }
+ wax::obj _rx_subdev(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ wax::obj _tx_subdev(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ gain_group::sptr _rx_gain_group(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>();
+ }
+ gain_group::sptr _tx_gain_group(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>();
+ }
//shadows
double _rx_rate, _tx_rate;
diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp
index a8c20c439..5b4a58805 100644
--- a/host/lib/usrp/simple_usrp.cpp
+++ b/host/lib/usrp/simple_usrp.cpp
@@ -27,6 +27,7 @@
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <stdexcept>
+#include <iostream>
using namespace uhd;
using namespace uhd::usrp;
@@ -43,21 +44,6 @@ class simple_usrp_impl : public simple_usrp{
public:
simple_usrp_impl(const device_addr_t &addr){
_dev = device::make(addr);
- _mboard = (*_dev)[DEVICE_PROP_MBOARD];
- _rx_dsp = _mboard[MBOARD_PROP_RX_DSP];
- _tx_dsp = _mboard[MBOARD_PROP_TX_DSP];
-
- //extract rx subdevice
- _rx_dboard = _mboard[MBOARD_PROP_RX_DBOARD];
- std::string rx_subdev_in_use = _rx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _rx_subdev = _rx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)];
- _rx_gain_group = _rx_dboard[named_prop_t(DBOARD_PROP_GAIN_GROUP, rx_subdev_in_use)].as<gain_group::sptr>();
-
- //extract tx subdevice
- _tx_dboard = _mboard[MBOARD_PROP_TX_DBOARD];
- std::string tx_subdev_in_use = _tx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _tx_subdev = _tx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)];
- _tx_gain_group = _tx_dboard[named_prop_t(DBOARD_PROP_GAIN_GROUP, tx_subdev_in_use)].as<gain_group::sptr>();
}
~simple_usrp_impl(void){
@@ -81,13 +67,13 @@ public:
" TX Subdev: %s\n"
)
% (*_dev)[DEVICE_PROP_NAME].as<std::string>()
- % _mboard[MBOARD_PROP_NAME].as<std::string>()
- % _rx_dsp[DSP_PROP_NAME].as<std::string>()
- % _rx_dboard[DBOARD_PROP_NAME].as<std::string>()
- % _rx_subdev[SUBDEV_PROP_NAME].as<std::string>()
- % _tx_dsp[DSP_PROP_NAME].as<std::string>()
- % _tx_dboard[DBOARD_PROP_NAME].as<std::string>()
- % _tx_subdev[SUBDEV_PROP_NAME].as<std::string>()
+ % _mboard()[MBOARD_PROP_NAME].as<std::string>()
+ % _rx_dsp()[DSP_PROP_NAME].as<std::string>()
+ % _rx_dboard()[DBOARD_PROP_NAME].as<std::string>()
+ % _rx_subdev()[SUBDEV_PROP_NAME].as<std::string>()
+ % _tx_dsp()[DSP_PROP_NAME].as<std::string>()
+ % _tx_dboard()[DBOARD_PROP_NAME].as<std::string>()
+ % _tx_subdev()[SUBDEV_PROP_NAME].as<std::string>()
);
}
@@ -95,137 +81,155 @@ public:
* Misc
******************************************************************/
time_spec_t get_time_now(void){
- return _mboard[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ return _mboard()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
}
void set_time_now(const time_spec_t &time_spec){
- _mboard[MBOARD_PROP_TIME_NOW] = time_spec;
+ _mboard()[MBOARD_PROP_TIME_NOW] = time_spec;
}
void set_time_next_pps(const time_spec_t &time_spec){
- _mboard[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
+ _mboard()[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
}
void issue_stream_cmd(const stream_cmd_t &stream_cmd){
- _mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd;
+ _mboard()[MBOARD_PROP_STREAM_CMD] = stream_cmd;
}
void set_clock_config(const clock_config_t &clock_config){
- _mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
+ _mboard()[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
}
/*******************************************************************
* RX methods
******************************************************************/
+ void set_rx_subdev_spec(const subdev_spec_t &spec){
+ _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC] = spec;
+ std::cout << "RX " << _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().to_pp_string() << std::endl;
+ }
+
+ subdev_spec_t get_rx_subdev_spec(void){
+ return _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>();
+ }
+
void set_rx_rate(double rate){
- _rx_dsp[DSP_PROP_HOST_RATE] = rate;
+ _rx_dsp()[DSP_PROP_HOST_RATE] = rate;
}
double get_rx_rate(void){
- return _rx_dsp[DSP_PROP_HOST_RATE].as<double>();
+ return _rx_dsp()[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_rx_freq(double target_freq){
- return tune_rx_subdev_and_dsp(_rx_subdev, _rx_dsp, target_freq);
+ return tune_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp(), target_freq);
}
tune_result_t set_rx_freq(double target_freq, double lo_off){
- return tune_rx_subdev_and_dsp(_rx_subdev, _rx_dsp, target_freq, lo_off);
+ return tune_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp(), target_freq, lo_off);
}
double get_rx_freq(void){
- return derive_freq_from_rx_subdev_and_dsp(_rx_subdev, _rx_dsp);
+ return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp());
}
freq_range_t get_rx_freq_range(void){
- return add_dsp_shift(_rx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp);
+ return add_dsp_shift(_rx_subdev()[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp());
}
void set_rx_gain(float gain){
- _rx_gain_group->set_value(gain);
+ return _rx_gain_group()->set_value(gain);
}
float get_rx_gain(void){
- return _rx_gain_group->get_value();
+ return _rx_gain_group()->get_value();
}
gain_range_t get_rx_gain_range(void){
- return _rx_gain_group->get_range();
+ return _rx_gain_group()->get_range();
}
void set_rx_antenna(const std::string &ant){
- _rx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ _rx_subdev()[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_rx_antenna(void){
- return _rx_subdev[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _rx_subdev()[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_rx_antennas(void){
- return _rx_subdev[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _rx_subdev()[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_rx_lo_locked(void){
- return _rx_subdev[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _rx_subdev()[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
float read_rssi(void){
- return _rx_subdev[SUBDEV_PROP_RSSI].as<float>();
+ return _rx_subdev()[SUBDEV_PROP_RSSI].as<float>();
}
/*******************************************************************
* TX methods
******************************************************************/
+ void set_tx_subdev_spec(const subdev_spec_t &spec){
+ _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC] = spec;
+ std::cout << "TX " << _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().to_pp_string() << std::endl;
+ }
+
+ subdev_spec_t get_tx_subdev_spec(void){
+ return _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>();
+ }
+
void set_tx_rate(double rate){
- _tx_dsp[DSP_PROP_HOST_RATE] = rate;
+ _tx_dsp()[DSP_PROP_HOST_RATE] = rate;
}
double get_tx_rate(void){
- return _tx_dsp[DSP_PROP_HOST_RATE].as<double>();
+ return _tx_dsp()[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_tx_freq(double target_freq){
- return tune_tx_subdev_and_dsp(_tx_subdev, _tx_dsp, target_freq);
+ return tune_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp(), target_freq);
}
tune_result_t set_tx_freq(double target_freq, double lo_off){
- return tune_tx_subdev_and_dsp(_tx_subdev, _tx_dsp, target_freq, lo_off);
+ return tune_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp(), target_freq, lo_off);
}
double get_tx_freq(void){
- return derive_freq_from_tx_subdev_and_dsp(_tx_subdev, _tx_dsp);
+ return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp());
}
freq_range_t get_tx_freq_range(void){
- return add_dsp_shift(_tx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp);
+ return add_dsp_shift(_tx_subdev()[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp());
}
void set_tx_gain(float gain){
- _tx_gain_group->set_value(gain);
+ return _tx_gain_group()->set_value(gain);
}
float get_tx_gain(void){
- return _tx_gain_group->get_value();
+ return _tx_gain_group()->get_value();
}
gain_range_t get_tx_gain_range(void){
- return _tx_gain_group->get_range();
+ return _tx_gain_group()->get_range();
}
void set_tx_antenna(const std::string &ant){
- _tx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ _tx_subdev()[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_tx_antenna(void){
- return _tx_subdev[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _tx_subdev()[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_tx_antennas(void){
- return _tx_subdev[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _tx_subdev()[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_tx_lo_locked(void){
- return _tx_subdev[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _tx_subdev()[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
/*******************************************************************
@@ -233,24 +237,48 @@ public:
******************************************************************/
wax::obj get_rx_dboard_iface(void) {
- return _rx_dboard;
+ return _rx_dboard();
}
wax::obj get_tx_dboard_iface(void) {
- return _tx_dboard;
+ return _tx_dboard();
}
private:
device::sptr _dev;
- wax::obj _mboard;
- wax::obj _rx_dsp;
- wax::obj _tx_dsp;
- wax::obj _rx_dboard;
- wax::obj _tx_dboard;
- wax::obj _rx_subdev;
- wax::obj _tx_subdev;
- gain_group::sptr _rx_gain_group;
- gain_group::sptr _tx_gain_group;
+ wax::obj _mboard(void){
+ return (*_dev)[DEVICE_PROP_MBOARD];
+ }
+ wax::obj _rx_dsp(void){
+ return _mboard()[MBOARD_PROP_RX_DSP];
+ }
+ wax::obj _tx_dsp(void){
+ return _mboard()[MBOARD_PROP_TX_DSP];
+ }
+ wax::obj _rx_dboard(void){
+ std::string db_name = _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name;
+ return _mboard()[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
+ }
+ wax::obj _tx_dboard(void){
+ std::string db_name = _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name;
+ return _mboard()[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
+ }
+ wax::obj _rx_subdev(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _rx_dboard()[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ wax::obj _tx_subdev(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _tx_dboard()[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ gain_group::sptr _rx_gain_group(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _rx_dboard()[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>();
+ }
+ gain_group::sptr _tx_gain_group(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name;
+ return _tx_dboard()[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>();
+ }
};
/***********************************************************************
diff --git a/host/lib/usrp/subdev_spec.cpp b/host/lib/usrp/subdev_spec.cpp
new file mode 100644
index 000000000..0f00e2f74
--- /dev/null
+++ b/host/lib/usrp/subdev_spec.cpp
@@ -0,0 +1,77 @@
+//
+// Copyright 2010 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/usrp/subdev_spec.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+#include <boost/foreach.hpp>
+#include <stdexcept>
+#include <sstream>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+subdev_spec_pair_t::subdev_spec_pair_t(
+ const std::string &db_name, const std::string &sd_name
+):
+ db_name(db_name),
+ sd_name(sd_name)
+{
+ /* NOP */
+}
+
+subdev_spec_t::subdev_spec_t(const std::string &markup){
+ std::vector<std::string> pairs;
+ boost::split(pairs, markup, boost::is_any_of("\t "));
+ BOOST_FOREACH(const std::string &pair, pairs){
+ if (pair == "") continue;
+ std::vector<std::string> db_sd;
+ boost::split(db_sd, pair, boost::is_any_of(":"));
+ switch(db_sd.size()){
+ case 1: this->push_back(subdev_spec_pair_t("", db_sd.front())); break;
+ case 2: this->push_back(subdev_spec_pair_t(db_sd.front(), db_sd.back())); break;
+ default: throw std::runtime_error("invalid subdev-spec markup string: "+markup);
+ }
+ }
+}
+
+std::string subdev_spec_t::to_pp_string(void) const{
+ if (this->size() == 0) return "Empty Subdevice Specification";
+
+ std::stringstream ss;
+ size_t count = 0;
+ ss << "Subdevice Specification:" << std::endl;
+ BOOST_FOREACH(const subdev_spec_pair_t &pair, *this){
+ std::string db_name = pair.db_name;
+ if (db_name == "") db_name = "0";
+ std::string sd_name = pair.sd_name;
+ if (sd_name == "") sd_name = "0";
+ ss << boost::format(
+ " Channel %d: Daughterboard %s, Subdevice %s"
+ ) % (count++) % db_name % sd_name << std::endl;
+ }
+ return ss.str();
+}
+
+std::string subdev_spec_t::to_string(void) const{
+ std::string markup;
+ size_t count = 0;
+ BOOST_FOREACH(const subdev_spec_pair_t &pair, *this){
+ markup += ((count++)? " " : "") + pair.db_name + ":" + pair.sd_name;
+ }
+ return markup;
+}
diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp
index 5ed8ec079..ef027c1df 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.cpp
@@ -90,7 +90,7 @@ public:
void set_rate_rx_dboard_clock(double rate){
assert_has(get_rates_rx_dboard_clock(), rate, "rx dboard clock rate");
- size_t divider = size_t(rate/get_master_clock_rate());
+ size_t divider = size_t(get_master_clock_rate()/rate);
//bypass when the divider ratio is one
_ad9510_regs.bypass_divider_out7 = (divider == 1)? 1 : 0;
//calculate the low and high dividers
@@ -132,7 +132,9 @@ public:
void set_rate_tx_dboard_clock(double rate){
assert_has(get_rates_tx_dboard_clock(), rate, "tx dboard clock rate");
- size_t divider = size_t(rate/get_master_clock_rate());
+ size_t divider = size_t(get_master_clock_rate()/rate);
+ //bypass when the divider ratio is one
+ _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0;
//calculate the low and high dividers
size_t high = divider/2;
size_t low = divider - high;
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index 5c81856bb..be45c2c9e 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -37,6 +37,8 @@ public:
usrp2_dboard_iface(usrp2_iface::sptr iface, usrp2_clock_ctrl::sptr clock_ctrl);
~usrp2_dboard_iface(void);
+ std::string get_mboard_name(void){return "usrp2";}
+
void write_aux_dac(unit_t, aux_dac_t, float);
float read_aux_adc(unit_t, aux_adc_t);
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 3a2a53674..075f22388 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -53,10 +53,6 @@ void usrp2_mboard_impl::dboard_init(void){
boost::bind(&usrp2_mboard_impl::tx_dboard_get, this, _1, _2),
boost::bind(&usrp2_mboard_impl::tx_dboard_set, this, _1, _2)
);
-
- //init the subdevs in use (use the first subdevice)
- rx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0)));
- tx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0)));
}
/***********************************************************************
@@ -80,10 +76,6 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_rx_subdev_names();
return;
- case DBOARD_PROP_USED_SUBDEVS:
- val = _rx_subdevs_in_use;
- return;
-
case DBOARD_PROP_DBOARD_ID:
val = _rx_db_eeprom.id;
return;
@@ -108,16 +100,6 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){
switch(key.as<dboard_prop_t>()){
- case DBOARD_PROP_USED_SUBDEVS:{
- _rx_subdevs_in_use = val.as<prop_names_t>();
- UHD_ASSERT_THROW(_rx_subdevs_in_use.size() == 1);
- wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0));
- std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
- _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word(
- rx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
- ));
- }
- return;
case DBOARD_PROP_DBOARD_ID:
_rx_db_eeprom.id = val.as<dboard_id_t>();
@@ -149,10 +131,6 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_tx_subdev_names();
return;
- case DBOARD_PROP_USED_SUBDEVS:
- val = _tx_subdevs_in_use;
- return;
-
case DBOARD_PROP_DBOARD_ID:
val = _tx_db_eeprom.id;
return;
@@ -177,16 +155,6 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){
switch(key.as<dboard_prop_t>()){
- case DBOARD_PROP_USED_SUBDEVS:{
- _tx_subdevs_in_use = val.as<prop_names_t>();
- UHD_ASSERT_THROW(_tx_subdevs_in_use.size() == 1);
- wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0));
- std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
- _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(
- tx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
- ));
- }
- return;
case DBOARD_PROP_DBOARD_ID:
_tx_db_eeprom.id = val.as<dboard_id_t>();
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 389ac9892..85d41d57f 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -32,9 +32,9 @@ extern "C" {
#define __stdint(type) type
#endif
-//defines the protocol version in this shared header
-//increment this value when the protocol is changed
-#define USRP2_PROTO_VERSION 5
+//fpga and firmware compatibility numbers
+#define USRP2_FPGA_COMPAT_NUM 1
+#define USRP2_FW_COMPAT_NUM 5
//used to differentiate control packets over data port
#define USRP2_INVALID_VRT_HEADER 0
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index aa6d15783..c67bd02fd 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -144,11 +144,13 @@ void usrp2_impl::io_impl::recv_pirate_loop(
**********************************************************************/
void usrp2_impl::io_init(void){
//send a small data packet so the usrp2 knows the udp source port
- for(size_t i = 0; i < _data_transports.size(); i++){
- managed_send_buffer::sptr send_buff = _data_transports[i]->get_send_buff();
- boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER);
- memcpy(send_buff->cast<void*>(), &data, sizeof(data));
+ BOOST_FOREACH(zero_copy_if::sptr data_transport, _data_transports){
+ managed_send_buffer::sptr send_buff = data_transport->get_send_buff();
+ static const boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER);
+ std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
send_buff->commit(sizeof(data));
+ //drain the recv buffers (may have junk)
+ while (data_transport->get_recv_buff().get()){;}
}
//the number of recv frames is the number for the first transport
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index c8e22a709..a3d5e8955 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -105,6 +105,15 @@ usrp2_mboard_impl::usrp2_mboard_impl(
//init the tx and rx dboards (do last)
dboard_init();
+
+ //set default subdev specs
+ (*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t();
+ (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t();
+
+ //Issue a stop streaming command (in case it was left running).
+ //Since this command is issued before the networking is setup,
+ //most if not all junk packets will never make it to the socket.
+ this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
}
usrp2_mboard_impl::~usrp2_mboard_impl(void){
@@ -265,6 +274,14 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
}
return;
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ val = _rx_subdev_spec;
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ val = _tx_subdev_spec;
+ return;
+
default: UHD_THROW_PROP_GET_ERROR();
}
}
@@ -309,6 +326,38 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
issue_ddc_stream_cmd(val.as<stream_cmd_t>());
return;
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ _rx_subdev_spec = val.as<subdev_spec_t>();
+ //handle automatic
+ if (_rx_subdev_spec.empty()) _rx_subdev_spec.push_back(
+ subdev_spec_pair_t("", _dboard_manager->get_rx_subdev_names().front())
+ );
+ //sanity check
+ UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1);
+ uhd::assert_has((*this)[MBOARD_PROP_RX_DBOARD_NAMES].as<prop_names_t>(), _rx_subdev_spec.front().db_name, "rx dboard names");
+ uhd::assert_has(_dboard_manager->get_rx_subdev_names(), _rx_subdev_spec.front().sd_name, "rx subdev names");
+ //set the mux
+ _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word(
+ _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ _tx_subdev_spec = val.as<subdev_spec_t>();
+ //handle automatic
+ if (_tx_subdev_spec.empty()) _tx_subdev_spec.push_back(
+ subdev_spec_pair_t("", _dboard_manager->get_tx_subdev_names().front())
+ );
+ //sanity check
+ UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1);
+ uhd::assert_has((*this)[MBOARD_PROP_TX_DBOARD_NAMES].as<prop_names_t>(), _tx_subdev_spec.front().db_name, "tx dboard names");
+ uhd::assert_has(_dboard_manager->get_tx_subdev_names(), _tx_subdev_spec.front().sd_name, "tx subdev names");
+ //set the mux
+ _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(
+ _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 2a380dc44..44aef2a34 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "usrp2_regs.hpp"
#include "usrp2_iface.hpp"
#include <uhd/utils/assert.hpp>
#include <uhd/types/dict.hpp>
@@ -22,6 +23,7 @@
#include <boost/foreach.hpp>
#include <boost/asio.hpp> //used for htonl and ntohl
#include <boost/assign/list_of.hpp>
+#include <boost/format.hpp>
#include <stdexcept>
#include <algorithm>
@@ -47,6 +49,15 @@ public:
**********************************************************************/
usrp2_iface_impl(udp_simple::sptr ctrl_transport){
_ctrl_transport = ctrl_transport;
+
+ //check the fpga compatibility number
+ const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb);
+ if (fpga_compat_num != USRP2_FPGA_COMPAT_NUM){
+ throw std::runtime_error(str(boost::format(
+ "Expected fpga compatibility number %d, but got %d:\n"
+ "The fpga build is not compatible with the host code build."
+ ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num));
+ }
}
~usrp2_iface_impl(void){
@@ -168,7 +179,7 @@ public:
//fill in the seq number and send
usrp2_ctrl_data_t out_copy = out_data;
- out_copy.proto_ver = htonl(USRP2_PROTO_VERSION);
+ out_copy.proto_ver = htonl(USRP2_FW_COMPAT_NUM);
out_copy.seq = htonl(++_ctrl_seq_num);
_ctrl_transport->send(boost::asio::buffer(&out_copy, sizeof(usrp2_ctrl_data_t)));
@@ -177,12 +188,11 @@ public:
const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem);
while(true){
size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT_MS);
- if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_PROTO_VERSION){
- throw std::runtime_error(str(
- boost::format("Expected protocol version %d, but got %d\n"
- "The firmware build does not match the host code build."
- ) % int(USRP2_PROTO_VERSION) % ntohl(ctrl_data_in->proto_ver)
- ));
+ if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){
+ throw std::runtime_error(str(boost::format(
+ "Expected protocol compatibility number %d, but got %d:\n"
+ "The firmware build is not compatible with the host code build."
+ ) % int(USRP2_FW_COMPAT_NUM) % ntohl(ctrl_data_in->proto_ver)));
}
if (len >= sizeof(usrp2_ctrl_data_t) and ntohl(ctrl_data_in->seq) == _ctrl_seq_num){
return *ctrl_data_in;
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 2c314c085..21f411afe 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -97,7 +97,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){
//send a hello control packet
usrp2_ctrl_data_t ctrl_data_out;
- ctrl_data_out.proto_ver = htonl(USRP2_PROTO_VERSION);
+ ctrl_data_out.proto_ver = htonl(USRP2_FW_COMPAT_NUM);
ctrl_data_out.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO);
udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out)));
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 8421b6b39..21a56cb67 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -35,6 +35,7 @@
#include <uhd/transport/udp_simple.hpp> //mtu
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/usrp/dboard_manager.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
/*!
* Make a usrp2 dboard interface.
@@ -143,6 +144,7 @@ private:
//properties for this mboard
void get(const wax::obj &, wax::obj &);
void set(const wax::obj &, const wax::obj &);
+ uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;
//interfaces
usrp2_iface::sptr _iface;
@@ -177,14 +179,12 @@ private:
void rx_dboard_get(const wax::obj &, wax::obj &);
void rx_dboard_set(const wax::obj &, const wax::obj &);
wax_obj_proxy::sptr _rx_dboard_proxy;
- uhd::prop_names_t _rx_subdevs_in_use;
uhd::usrp::dboard_eeprom_t _rx_db_eeprom;
//properties interface for tx dboard
void tx_dboard_get(const wax::obj &, wax::obj &);
void tx_dboard_set(const wax::obj &, const wax::obj &);
wax_obj_proxy::sptr _tx_dboard_proxy;
- uhd::prop_names_t _tx_subdevs_in_use;
uhd::usrp::dboard_eeprom_t _tx_db_eeprom;
//methods and shadows for the ddc dsp
diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp
index 857fbda9c..49f077221 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.cpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.cpp
@@ -58,6 +58,7 @@ usrp2_regs_t usrp2_get_regs(int hw_rev) {
x.time64_tps = sr_addr(misc_output_base, x.sr_time64 + 4);
x.time64_secs_rb = bp_base + 4*10;
x.time64_ticks_rb = bp_base + 4*11;
+ x.compat_num_rb = bp_base + 4*12;
x.dsp_tx_freq = sr_addr(misc_output_base, x.sr_tx_dsp + 0);
x.dsp_tx_scale_iq = sr_addr(misc_output_base, x.sr_tx_dsp + 1);
x.dsp_tx_interp_rate = sr_addr(misc_output_base, x.sr_tx_dsp + 2);
diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp
index c12098c8e..0a171d20c 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.hpp
@@ -61,6 +61,7 @@ typedef struct {
int time64_tps; // ticks per second rollover count
int time64_secs_rb;
int time64_ticks_rb;
+ int compat_num_rb;
int dsp_tx_freq;
int dsp_tx_scale_iq;
int dsp_tx_interp_rate;
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
new file mode 100644
index 000000000..68945545a
--- /dev/null
+++ b/host/lib/utils/CMakeLists.txt
@@ -0,0 +1,87 @@
+#
+# Copyright 2010 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/>.
+#
+
+#This file will be included by cmake, use absolute paths!
+
+########################################################################
+# Setup defines for process scheduling
+########################################################################
+MESSAGE(STATUS "Configuring priority scheduling...")
+
+INCLUDE(CheckCXXSourceCompiles)
+CHECK_CXX_SOURCE_COMPILES("
+ #include <pthread.h>
+ int main(){
+ struct sched_param sp;
+ pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
+ return 0;
+ }
+ " HAVE_PTHREAD_SETSCHEDPARAM
+)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <windows.h>
+ int main(){
+ SetThreadPriority(GetCurrentThread(), 0);
+ SetPriorityClass(GetCurrentProcess(), 0);
+ return 0;
+ }
+ " HAVE_WIN_SETTHREADPRIORITY
+)
+
+IF(HAVE_PTHREAD_SETSCHEDPARAM)
+ MESSAGE(STATUS " Priority scheduling supported through pthread_setschedparam.")
+ ADD_DEFINITIONS(-DHAVE_PTHREAD_SETSCHEDPARAM)
+ELSEIF(HAVE_WIN_SETTHREADPRIORITY)
+ MESSAGE(STATUS " Priority scheduling supported through windows SetThreadPriority.")
+ ADD_DEFINITIONS(-DHAVE_WIN_SETTHREADPRIORITY)
+ELSE(HAVE_PTHREAD_SETSCHEDPARAM)
+ MESSAGE(STATUS " Priority scheduling not supported.")
+ENDIF(HAVE_PTHREAD_SETSCHEDPARAM)
+
+########################################################################
+# Setup defines for module loading
+########################################################################
+MESSAGE(STATUS "Configuring module loading...")
+
+INCLUDE(CheckIncludeFileCXX)
+CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H)
+CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H)
+
+IF(HAVE_DLFCN_H)
+ MESSAGE(STATUS " Module loading supported through dlopen.")
+ ADD_DEFINITIONS(-DHAVE_DLFCN_H)
+ LIBUHD_APPEND_LIBS(${CMAKE_DL_LIBS})
+ELSEIF(HAVE_WINDOWS_H)
+ MESSAGE(STATUS " Module loading supported through LoadLibrary.")
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_H)
+ELSE(HAVE_DLFCN_H)
+ MESSAGE(STATUS " Module loading not supported.")
+ENDIF(HAVE_DLFCN_H)
+
+########################################################################
+# Append sources
+########################################################################
+LIBUHD_APPEND_SOURCES(
+ ${CMAKE_SOURCE_DIR}/lib/utils/assert.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/gain_group.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/load_modules.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/paths.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/props.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/thread_priority.cpp
+ ${CMAKE_SOURCE_DIR}/lib/utils/warning.cpp
+)
diff --git a/host/lib/utils/assert.cpp b/host/lib/utils/assert.cpp
new file mode 100644
index 000000000..7ace9024c
--- /dev/null
+++ b/host/lib/utils/assert.cpp
@@ -0,0 +1,24 @@
+//
+// Copyright 2010 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/assert.hpp>
+
+using namespace uhd;
+
+assert_error::assert_error(const std::string &what) : std::runtime_error(what){
+ /* NOP */
+}
diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp
new file mode 100644
index 000000000..c113719c8
--- /dev/null
+++ b/host/lib/utils/gain_group.cpp
@@ -0,0 +1,149 @@
+//
+// Copyright 2010 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/gain_group.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/assert.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <algorithm>
+#include <vector>
+#include <iostream>
+
+using namespace uhd;
+
+static const bool verbose = false;
+
+static bool compare_by_step_size(
+ const size_t &rhs, const size_t &lhs, std::vector<gain_fcns_t> &fcns
+){
+ return fcns.at(rhs).get_range().step > fcns.at(lhs).get_range().step;
+}
+
+/***********************************************************************
+ * gain group implementation
+ **********************************************************************/
+class gain_group_impl : public gain_group{
+public:
+ gain_group_impl(void){
+ /*NOP*/
+ }
+
+ gain_range_t get_range(void){
+ float overall_min = 0, overall_max = 0, overall_step = 0;
+ BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){
+ const gain_range_t range = fcns.get_range();
+ overall_min += range.min;
+ overall_max += range.max;
+ //the overall step is the min (zero is invalid, first run)
+ if (overall_step == 0) overall_step = range.step;
+ overall_step = std::min(overall_step, range.step);
+ }
+ return gain_range_t(overall_min, overall_max, overall_step);
+ }
+
+ float get_value(void){
+ float overall_gain = 0;
+ BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){
+ overall_gain += fcns.get_value();
+ }
+ return overall_gain;
+ }
+
+ void set_value(float gain){
+ std::vector<gain_fcns_t> all_fcns = get_all_fcns();
+ if (all_fcns.size() == 0) return; //nothing to set!
+
+ //get the max step size among the gains
+ float max_step = 0;
+ BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){
+ max_step = std::max(max_step, fcns.get_range().step);
+ }
+
+ //create gain bucket to distribute power
+ std::vector<float> gain_bucket;
+
+ //distribute power according to priority (round to max step)
+ float gain_left_to_distribute = gain;
+ BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){
+ const gain_range_t range = fcns.get_range();
+ gain_bucket.push_back(
+ max_step*int(std::clip(gain_left_to_distribute, range.min, range.max)/max_step)
+ );
+ gain_left_to_distribute -= gain_bucket.back();
+ }
+
+ //get a list of indexes sorted by step size large to small
+ std::vector<size_t> indexes_step_size_dec;
+ for (size_t i = 0; i < all_fcns.size(); i++){
+ indexes_step_size_dec.push_back(i);
+ }
+ std::sort(
+ indexes_step_size_dec.begin(), indexes_step_size_dec.end(),
+ boost::bind(&compare_by_step_size, _1, _2, all_fcns)
+ );
+ UHD_ASSERT_THROW(
+ all_fcns.at(indexes_step_size_dec.front()).get_range().step >=
+ all_fcns.at(indexes_step_size_dec.back()).get_range().step
+ );
+
+ //distribute the remainder (less than max step)
+ //fill in the largest step sizes first that are less than the remainder
+ BOOST_FOREACH(size_t i, indexes_step_size_dec){
+ const gain_range_t range = all_fcns.at(i).get_range();
+ float additional_gain = range.step*int(
+ std::clip(gain_bucket.at(i) + gain_left_to_distribute, range.min, range.max
+ )/range.step) - gain_bucket.at(i);
+ gain_bucket.at(i) += additional_gain;
+ gain_left_to_distribute -= additional_gain;
+ }
+ if (verbose) std::cout << "gain_left_to_distribute " << gain_left_to_distribute << std::endl;
+
+ //now write the bucket out to the individual gain values
+ for (size_t i = 0; i < gain_bucket.size(); i++){
+ if (verbose) std::cout << gain_bucket.at(i) << std::endl;
+ all_fcns.at(i).set_value(gain_bucket.at(i));
+ }
+ }
+
+ void register_fcns(
+ const gain_fcns_t &gain_fcns, size_t priority
+ ){
+ _registry[priority].push_back(gain_fcns);
+ }
+
+private:
+ //! get the gain function sets in order (highest priority first)
+ std::vector<gain_fcns_t> get_all_fcns(void){
+ std::vector<gain_fcns_t> all_fcns;
+ BOOST_FOREACH(size_t key, std::sorted(_registry.keys())){
+ const std::vector<gain_fcns_t> &fcns = _registry[key];
+ all_fcns.insert(all_fcns.begin(), fcns.begin(), fcns.end());
+ }
+ return all_fcns;
+ }
+
+ uhd::dict<size_t, std::vector<gain_fcns_t> > _registry;
+};
+
+/***********************************************************************
+ * gain group factory function
+ **********************************************************************/
+gain_group::sptr gain_group::make(void){
+ return sptr(new gain_group_impl());
+}
diff --git a/host/lib/load_modules.cpp b/host/lib/utils/load_modules.cpp
index dbb8d0695..623d31eb6 100644
--- a/host/lib/load_modules.cpp
+++ b/host/lib/utils/load_modules.cpp
@@ -18,13 +18,12 @@
#include <uhd/utils/static.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
-#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
-#include <boost/program_options.hpp>
#include <iostream>
#include <stdexcept>
+#include <string>
+#include <vector>
-namespace po = boost::program_options;
namespace fs = boost::filesystem;
/***********************************************************************
@@ -32,7 +31,6 @@ namespace fs = boost::filesystem;
**********************************************************************/
#if defined(HAVE_DLFCN_H)
#include <dlfcn.h>
-static const std::string env_path_sep = ":";
static void load_module(const std::string &file_name){
if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){
@@ -44,7 +42,6 @@ static void load_module(const std::string &file_name){
#elif defined(HAVE_WINDOWS_H)
#include <windows.h>
-static const std::string env_path_sep = ";";
static void load_module(const std::string &file_name){
if (LoadLibrary(file_name.c_str()) == NULL){
@@ -55,7 +52,6 @@ static void load_module(const std::string &file_name){
}
#else
-static const std::string env_path_sep = ":";
static void load_module(const std::string &file_name){
throw std::runtime_error(str(
@@ -74,9 +70,9 @@ static void load_module(const std::string &file_name){
* Does not throw, prints to std error.
* \param path the filesystem path
*/
-static void load_path(const fs::path &path){
+static void load_module_path(const fs::path &path){
if (not fs::exists(path)){
- std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl;
+ //std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl;
return;
}
@@ -87,7 +83,7 @@ static void load_path(const fs::path &path){
dir_itr != fs::directory_iterator();
++dir_itr
){
- load_path(dir_itr->path());
+ load_module_path(dir_itr->path());
}
return;
}
@@ -101,46 +97,13 @@ static void load_path(const fs::path &path){
}
}
-//! The string constant for the module path environment variable
-static const std::string MODULE_PATH_KEY = "UHD_MODULE_PATH";
+std::vector<fs::path> get_module_paths(void); //defined in paths.cpp
/*!
- * Name mapper function for the environment variable parser.
- * Map environment variable names (that we use) to option names.
- * \param the variable name
- * \return the option name or blank string
- */
-static std::string name_mapper(const std::string &var_name){
- if (var_name == MODULE_PATH_KEY) return var_name;
- return "";
-}
-
-/*!
- * Load all the modules given by the module path enviroment variable.
- * The path variable may be several paths split by path separators.
+ * Load all the modules given in the module paths.
*/
UHD_STATIC_BLOCK(load_modules){
- //register the options
- std::string env_module_path;
- po::options_description desc("UHD Module Options");
- desc.add_options()
- (MODULE_PATH_KEY.c_str(), po::value<std::string>(&env_module_path)->default_value(""))
- ;
-
- //parse environment variables
- po::variables_map vm;
- po::store(po::parse_environment(desc, &name_mapper), vm);
- po::notify(vm);
-
- if (env_module_path == "") return;
- //std::cout << "env_module_path: " << env_module_path << std::endl;
-
- //split the path at the path separators
- std::vector<std::string> module_paths;
- boost::split(module_paths, env_module_path, boost::is_any_of(env_path_sep));
-
- //load modules in each path
- BOOST_FOREACH(const std::string &module_path, module_paths){
- load_path(fs::system_complete(fs::path(module_path)));
+ BOOST_FOREACH(const fs::path &path, get_module_paths()){
+ load_module_path(path);
}
}
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
new file mode 100644
index 000000000..0805a44fe
--- /dev/null
+++ b/host/lib/utils/paths.cpp
@@ -0,0 +1,103 @@
+//
+// Copyright 2010 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 "constants.hpp"
+#include <uhd/config.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+namespace po = boost::program_options;
+namespace fs = boost::filesystem;
+
+/***********************************************************************
+ * Determine the paths separator
+ **********************************************************************/
+#ifdef UHD_PLATFORM_WIN32
+ static const std::string env_path_sep = ";";
+#else
+ static const std::string env_path_sep = ":";
+#endif /*UHD_PLATFORM_WIN32*/
+
+/***********************************************************************
+ * Get a list of paths for an environment variable
+ **********************************************************************/
+static std::string name_mapper(const std::string &key, const std::string &var_name){
+ return (var_name == key)? var_name : "";
+}
+
+static std::vector<fs::path> get_env_paths(const std::string &var_name){
+ //register the options
+ std::string var_value;
+ po::options_description desc;
+ desc.add_options()
+ (var_name.c_str(), po::value<std::string>(&var_value)->default_value(""))
+ ;
+
+ //parse environment variables
+ po::variables_map vm;
+ po::store(po::parse_environment(desc, boost::bind(&name_mapper, var_name, _1)), vm);
+ po::notify(vm);
+
+ //split the path at the path separators
+ std::vector<std::string> path_strings;
+ boost::split(path_strings, var_value, boost::is_any_of(env_path_sep));
+
+ //convert to filesystem path, filter blank paths
+ std::vector<fs::path> paths;
+ BOOST_FOREACH(std::string &path_string, path_strings){
+ if (path_string.size() == 0) continue;
+ paths.push_back(fs::system_complete(path_string));
+ }
+ return paths;
+}
+
+/***********************************************************************
+ * Get a list of special purpose paths
+ **********************************************************************/
+static const fs::path pkg_data_path = fs::path(UHD_INSTALL_PREFIX) / UHD_PKG_DATA_DIR;
+
+std::vector<fs::path> get_image_paths(void){
+ std::vector<fs::path> paths = get_env_paths("UHD_IMAGE_PATH");
+ paths.push_back(pkg_data_path / "images");
+ return paths;
+}
+
+std::vector<fs::path> get_module_paths(void){
+ std::vector<fs::path> paths = get_env_paths("UHD_MODULE_PATH");
+ paths.push_back(pkg_data_path / "modules");
+ return paths;
+}
+
+/***********************************************************************
+ * Find a image in the image paths
+ **********************************************************************/
+std::string find_image_path(const std::string &image_name){
+ if (fs::exists(image_name)){
+ return fs::system_complete(image_name).file_string();
+ }
+ BOOST_FOREACH(const fs::path &path, get_image_paths()){
+ fs::path image_path = path / image_name;
+ if (fs::exists(image_path)) return image_path.file_string();
+ }
+ throw std::runtime_error("Could not find path for image: " + image_name);
+}
diff --git a/host/lib/utils.cpp b/host/lib/utils/props.cpp
index d2f4dfc6e..fac5fe24f 100644
--- a/host/lib/utils.cpp
+++ b/host/lib/utils/props.cpp
@@ -15,28 +15,18 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <uhd/utils/assert.hpp>
#include <uhd/utils/props.hpp>
-#include <stdexcept>
using namespace uhd;
-/***********************************************************************
- * Assert
- **********************************************************************/
-assert_error::assert_error(const std::string &what) : std::runtime_error(what){
- /* NOP */
-}
-
-/***********************************************************************
- * Props
- **********************************************************************/
named_prop_t::named_prop_t(
- const wax::obj &key_,
- const std::string &name_
-){
- key = key_;
- name = name_;
+ const wax::obj &key,
+ const std::string &name
+):
+ key(key),
+ name(name)
+{
+ /* NOP */
}
typedef boost::tuple<wax::obj, std::string> named_prop_tuple;
diff --git a/host/lib/thread_priority.cpp b/host/lib/utils/thread_priority.cpp
index c35e5fcb1..c35e5fcb1 100644
--- a/host/lib/thread_priority.cpp
+++ b/host/lib/utils/thread_priority.cpp
diff --git a/host/lib/utils/warning.cpp b/host/lib/utils/warning.cpp
new file mode 100644
index 000000000..ae4d4c7aa
--- /dev/null
+++ b/host/lib/utils/warning.cpp
@@ -0,0 +1,36 @@
+//
+// Copyright 2010 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/warning.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <vector>
+
+using namespace uhd;
+
+void uhd::print_warning(const std::string &msg){
+ //extract the message lines
+ std::vector<std::string> lines;
+ boost::split(lines, msg, boost::is_any_of("\n"));
+
+ //print the warning message
+ std::cerr << std::endl << "Warning:" << std::endl;
+ BOOST_FOREACH(const std::string &line, lines){
+ std::cerr << " " << line << std::endl;
+ }
+}
diff --git a/host/lib/version.cpp.in b/host/lib/version.cpp
index f3a5afc45..5edbca09b 100644
--- a/host/lib/version.cpp.in
+++ b/host/lib/version.cpp
@@ -15,8 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "constants.hpp"
#include <uhd/version.hpp>
std::string uhd::get_version_string(void){
- return "@CPACK_PACKAGE_VERSION@";
+ return UHD_VERSION_STRING;
}
diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt
index 37832edde..c620fd641 100644
--- a/host/test/CMakeLists.txt
+++ b/host/test/CMakeLists.txt
@@ -27,8 +27,10 @@ ADD_EXECUTABLE(main_test
dict_test.cpp
error_test.cpp
gain_group_test.cpp
+ subdev_spec_test.cpp
tune_helper_test.cpp
vrt_test.cpp
+ warning_test.cpp
wax_test.cpp
)
TARGET_LINK_LIBRARIES(main_test uhd)
diff --git a/host/test/addr_test.cpp b/host/test/addr_test.cpp
index 0c50200d6..d4b45aa1a 100644
--- a/host/test/addr_test.cpp
+++ b/host/test/addr_test.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(test_device_addr){
uhd::device_addr_t new_dev_addr(args_str);
//they should be the same size
- BOOST_CHECK_EQUAL(dev_addr.size(), new_dev_addr.size());
+ BOOST_REQUIRE_EQUAL(dev_addr.size(), new_dev_addr.size());
//the keys should match
std::vector<std::string> old_dev_addr_keys = dev_addr.keys();
diff --git a/host/test/subdev_spec_test.cpp b/host/test/subdev_spec_test.cpp
new file mode 100644
index 000000000..8817d5eee
--- /dev/null
+++ b/host/test/subdev_spec_test.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2010 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 <boost/test/unit_test.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+BOOST_AUTO_TEST_CASE(test_subdevice_spec){
+ std::cout << "Testing subdevice specification..." << std::endl;
+
+ //load the subdev spec with something
+ uhd::usrp::subdev_spec_t sd_spec;
+ sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("A", "AB"));
+ sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("B", "AB"));
+
+ //convert to and from args string
+ std::cout << "Pretty Print: " << std::endl << sd_spec.to_pp_string();
+ std::string markup_str = sd_spec.to_string();
+ std::cout << "Markup String: " << markup_str << std::endl;
+ uhd::usrp::subdev_spec_t new_sd_spec(markup_str);
+
+ //they should be the same size
+ BOOST_REQUIRE_EQUAL(sd_spec.size(), new_sd_spec.size());
+
+ //the contents should match
+ for (size_t i = 0; i < sd_spec.size(); i++){
+ BOOST_CHECK_EQUAL(sd_spec.at(i).db_name, new_sd_spec.at(i).db_name);
+ BOOST_CHECK_EQUAL(sd_spec.at(i).sd_name, new_sd_spec.at(i).sd_name);
+ }
+}
diff --git a/host/test/warning_test.cpp b/host/test/warning_test.cpp
new file mode 100644
index 000000000..6202c4270
--- /dev/null
+++ b/host/test/warning_test.cpp
@@ -0,0 +1,29 @@
+//
+// Copyright 2010 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 <boost/test/unit_test.hpp>
+#include <uhd/utils/warning.hpp>
+#include <iostream>
+
+BOOST_AUTO_TEST_CASE(test_print_warning){
+ std::cerr << "---begin print test ---" << std::endl;
+ uhd::print_warning(
+ "This is a test print for a warning message.\n"
+ "And this is the second line of the test print.\n"
+ );
+ std::cerr << "---end print test ---" << std::endl;
+}
diff --git a/host/utils/usrp2_card_burner.py b/host/utils/usrp2_card_burner.py
index d47a4f5f4..1db5e59ce 100755
--- a/host/utils/usrp2_card_burner.py
+++ b/host/utils/usrp2_card_burner.py
@@ -21,6 +21,7 @@ import tempfile
import subprocess
import urllib
import optparse
+import math
import os
import re
@@ -59,6 +60,14 @@ def get_dd_path():
return dd_path
return 'dd'
+def int_ceil_div(num, den):
+ return int(math.ceil(float(num)/float(den)))
+
+def get_tmp_file():
+ tmp = tempfile.mkstemp()
+ os.close(tmp[0])
+ return tmp[1]
+
########################################################################
# list possible devices
########################################################################
@@ -136,10 +145,12 @@ def get_raw_device_hints():
# write and verify with dd
########################################################################
def verify_image(image_file, device_file, offset):
- #create a temporary file to store the readback
- tmp = tempfile.mkstemp()
- os.close(tmp[0])
- tmp_file = tmp[1]
+ #create a temporary file to store the readback image
+ tmp_file = get_tmp_file()
+
+ #read the image data
+ img_data = open(image_file, 'rb').read()
+ count = int_ceil_div(len(img_data), SECTOR_SIZE)
#execute a dd subprocess
verbose = command(
@@ -148,24 +159,33 @@ def verify_image(image_file, device_file, offset):
"if=%s"%device_file,
"skip=%d"%(offset/SECTOR_SIZE),
"bs=%d"%SECTOR_SIZE,
- "count=%d"%(MAX_FILE_SIZE/SECTOR_SIZE),
+ "count=%d"%count,
)
- #read in the image and readback
- img_data = open(image_file, 'rb').read()
- tmp_data = open(tmp_file, 'rb').read(len(img_data))
-
#verfy the data
+ tmp_data = open(tmp_file, 'rb').read(len(img_data))
if img_data != tmp_data: return 'Verification Failed:\n%s'%verbose
return 'Verification Passed:\n%s'%verbose
def write_image(image_file, device_file, offset):
+ #create a temporary file to store the padded image
+ tmp_file = get_tmp_file()
+
+ #write the padded image data
+ img_data = open(image_file, 'rb').read()
+ count = int_ceil_div(len(img_data), SECTOR_SIZE)
+ pad_len = SECTOR_SIZE*count - len(img_data)
+ pad_str = ''.join([chr(0)]*pad_len) #zero-padding
+ open(tmp_file, 'wb').write(img_data + pad_str)
+
+ #execute a dd subprocess
verbose = command(
get_dd_path(),
- "if=%s"%image_file,
+ "if=%s"%tmp_file,
"of=%s"%device_file,
"seek=%d"%(offset/SECTOR_SIZE),
"bs=%d"%SECTOR_SIZE,
+ "count=%d"%count,
)
try: #exec the sync command (only works on linux)
diff --git a/host/utils/usrp2_card_burner_gui.py b/host/utils/usrp2_card_burner_gui.py
index 61fbadbe3..58b7a514a 100755
--- a/host/utils/usrp2_card_burner_gui.py
+++ b/host/utils/usrp2_card_burner_gui.py
@@ -17,7 +17,7 @@
#
import usrp2_card_burner #import implementation
-import Tkinter, Tkconstants, tkFileDialog, tkFont, tkMessageBox
+import Tkinter, tkFileDialog, tkFont, tkMessageBox
import os
class BinFileEntry(Tkinter.Frame):
@@ -53,7 +53,7 @@ class BinFileEntry(Tkinter.Frame):
class DeviceEntryWidget(Tkinter.Frame):
"""
- Simple entry widget for getting the raw device name.
+ Simple entry widget for getting the raw device name.
Combines a label, entry, and helpful text box with hints.
"""
diff --git a/images/.gitignore b/images/.gitignore
new file mode 100644
index 000000000..8947b7a83
--- /dev/null
+++ b/images/.gitignore
@@ -0,0 +1,2 @@
+/build
+/images
diff --git a/images/CMakeLists.txt b/images/CMakeLists.txt
new file mode 100644
index 000000000..75cb4c9d3
--- /dev/null
+++ b/images/CMakeLists.txt
@@ -0,0 +1,42 @@
+#
+# Copyright 2010 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/>.
+#
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(UHD-images NONE)
+
+########################################################################
+# Config Files (include order is important)
+########################################################################
+INCLUDE(${CMAKE_SOURCE_DIR}/../host/config/Python.cmake)
+INCLUDE(${CMAKE_SOURCE_DIR}/../host/config/Version.cmake)
+
+########################################################################
+# Setup CPack
+########################################################################
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ettus Research - Universal Hardware Driver Images")
+SET(CPACK_PACKAGE_VENDOR "Ettus Research LLC")
+SET(CPACK_PACKAGE_CONTACT "support@ettus.com")
+SET(CPACK_PACKAGE_VERSION_MAJOR ${UHD_VERSION_MAJOR})
+SET(CPACK_PACKAGE_VERSION_MINOR ${UHD_VERSION_MINOR})
+SET(CPACK_PACKAGE_VERSION_PATCH ${UHD_VERSION_PATCH})
+INCLUDE(CPack) #include after setting vars
+MESSAGE(STATUS "Version: ${CPACK_PACKAGE_VERSION}")
+
+########################################################################
+# Install Images
+########################################################################
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/images DESTINATION share/uhd)
diff --git a/images/Makefile b/images/Makefile
new file mode 100644
index 000000000..6ab54e6ac
--- /dev/null
+++ b/images/Makefile
@@ -0,0 +1,86 @@
+#
+# Copyright 2010 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/>.
+#
+
+all:
+ @echo "Pick a specific target"
+
+########################################################################
+# Common Variables
+########################################################################
+TOP_DIR = $(shell pwd)
+TOP_FW_DIR = $(TOP_DIR)/../firmware
+TOP_FPGA_DIR = $(TOP_DIR)/../fpga
+BUILT_IMAGES_DIR = $(TOP_DIR)/images
+CMAKE_BUILD_DIR = $(TOP_DIR)/build
+
+##filled in below
+IMAGES_LIST =
+
+########################################################################
+# USRP2 firmware
+########################################################################
+_usrp2_fw_dir = $(TOP_FW_DIR)/microblaze
+_usrp2_fw_bin = $(BUILT_IMAGES_DIR)/usrp2_fw.bin
+IMAGES_LIST += $(_usrp2_fw_bin)
+
+$(_usrp2_fw_bin):
+ cd $(_usrp2_fw_dir) && ./bootstrap
+ cd $(_usrp2_fw_dir) && ./configure --host=mb
+ make -C $(_usrp2_fw_dir) clean
+ make -C $(_usrp2_fw_dir) all
+ cp $(_usrp2_fw_dir)/usrp2/usrp2_txrx_uhd.bin $@
+
+########################################################################
+# USRP2 fpga
+########################################################################
+_usrp2_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u2_rev3
+_usrp2_fpga_bin = $(BUILT_IMAGES_DIR)/usrp2_fpga.bin
+IMAGES_LIST += $(_usrp2_fpga_bin)
+
+$(_usrp2_fpga_bin):
+ cd $(_usrp2_fpga_dir) && make -f Makefile.udp clean
+ cd $(_usrp2_fpga_dir) && make -f Makefile.udp bin
+ cp $(_usrp2_fpga_dir)/build-udp/u2_rev3.bin $@
+
+########################################################################
+# Build rules
+########################################################################
+##little rule to make the images directory
+$(BUILT_IMAGES_DIR):
+ mkdir $@
+
+images: $(BUILT_IMAGES_DIR) $(IMAGES_LIST)
+
+clean:
+ $(RM) -rf $(BUILT_IMAGES_DIR)
+ $(RM) -rf $(CMAKE_BUILD_DIR)
+
+#packages that a linux machine can build
+linux-packages:
+ mkdir -p $(CMAKE_BUILD_DIR)
+
+ cd $(CMAKE_BUILD_DIR) && cmake -DCPACK_GENERATOR=TGZ $(TOP_DIR)
+ make -C $(CMAKE_BUILD_DIR) package
+
+ cd $(CMAKE_BUILD_DIR) && cmake -DCPACK_GENERATOR=ZIP $(TOP_DIR)
+ make -C $(CMAKE_BUILD_DIR) package
+
+ cd $(CMAKE_BUILD_DIR) && cmake -DCPACK_GENERATOR=DEB $(TOP_DIR)
+ make -C $(CMAKE_BUILD_DIR) package
+
+ cd $(CMAKE_BUILD_DIR) && cmake -DCPACK_GENERATOR=RPM $(TOP_DIR)
+ make -C $(CMAKE_BUILD_DIR) package
diff --git a/images/README b/images/README
new file mode 100644
index 000000000..ec8391826
--- /dev/null
+++ b/images/README
@@ -0,0 +1,20 @@
+The images directory contains the following:
+ - a Makefile for building firmware and fpga images
+ - a CMake file for building an images package
+
+The Makefile and build systems for the images are probably Unix specific.
+Its best to build the images on a Unix system with standard build tools.
+The CMake package target will create an images package for your system.
+
+To build the images (unix):
+ make clean
+ make images
+
+To build the package (unix):
+ mkdir build
+ cd build
+ cmake -DCPACK_GENERATOR=<type> ../
+ make package
+
+The package generator types are described here:
+ http://www.cmake.org/Wiki/CMake:CPackPackageGenerators