aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/zpu/apps/txrx_uhd.c43
-rw-r--r--firmware/zpu/lib/clock_bits.h55
-rw-r--r--firmware/zpu/lib/clocks.c174
-rw-r--r--firmware/zpu/lib/clocks.h71
-rw-r--r--firmware/zpu/lib/net_common.c124
-rw-r--r--firmware/zpu/usrp2/memory_map.h134
-rw-r--r--firmware/zpu/usrp2p/memory_map.h134
-rw-r--r--fpga/usrp2/control_lib/Makefile.srcs5
-rw-r--r--fpga/usrp2/control_lib/newfifo/packet_generator.v59
-rw-r--r--fpga/usrp2/control_lib/newfifo/packet_verifier32.v30
-rw-r--r--fpga/usrp2/extram/.gitignore1
-rw-r--r--fpga/usrp2/extram/Makefile.srcs10
-rw-r--r--fpga/usrp2/extram/extram_interface.v53
-rw-r--r--fpga/usrp2/extram/extram_wb.v146
-rw-r--r--fpga/usrp2/extram/wb_zbt16_b.v63
-rw-r--r--fpga/usrp2/extramfifo/fifo_extram.v188
-rw-r--r--fpga/usrp2/extramfifo/fifo_extram36.v47
-rwxr-xr-xfpga/usrp2/extramfifo/fifo_extram36_tb.build1
-rw-r--r--fpga/usrp2/extramfifo/fifo_extram36_tb.v475
-rwxr-xr-xfpga/usrp2/extramfifo/fifo_extram_tb.build1
-rw-r--r--fpga/usrp2/extramfifo/fifo_extram_tb.v134
-rw-r--r--fpga/usrp2/fifo/Makefile.srcs6
-rw-r--r--fpga/usrp2/fifo/buffer_int2.v22
-rw-r--r--fpga/usrp2/fifo/dsp_framer36.v142
-rw-r--r--fpga/usrp2/fifo/fifo18_to_fifo36.v20
-rw-r--r--fpga/usrp2/fifo/fifo19_to_fifo36.v74
-rw-r--r--fpga/usrp2/fifo/fifo36_mux.v37
-rw-r--r--fpga/usrp2/fifo/fifo36_to_fifo19.v48
-rw-r--r--fpga/usrp2/fifo/fifo36_to_fifo72.v125
-rw-r--r--fpga/usrp2/fifo/fifo36_to_ll8.v80
-rw-r--r--fpga/usrp2/fifo/fifo72_to_fifo36.v63
-rw-r--r--fpga/usrp2/fifo/fifo_pacer.v (renamed from fpga/usrp2/control_lib/newfifo/fifo_pacer.v)0
-rw-r--r--fpga/usrp2/fifo/fifo_tb.v166
-rw-r--r--fpga/usrp2/fifo/ll8_to_fifo19.v76
-rw-r--r--fpga/usrp2/fifo/packet32_tb.v (renamed from fpga/usrp2/control_lib/newfifo/packet32_tb.v)0
-rw-r--r--fpga/usrp2/fifo/packet_dispatcher36_x3.v270
-rw-r--r--fpga/usrp2/fifo/packet_generator.v83
-rw-r--r--fpga/usrp2/fifo/packet_generator32.v (renamed from fpga/usrp2/control_lib/newfifo/packet_generator32.v)2
-rw-r--r--fpga/usrp2/fifo/packet_router.v329
-rw-r--r--fpga/usrp2/fifo/packet_tb.v (renamed from fpga/usrp2/control_lib/newfifo/packet_tb.v)0
-rw-r--r--fpga/usrp2/fifo/packet_verifier.v (renamed from fpga/usrp2/control_lib/newfifo/packet_verifier.v)2
-rw-r--r--fpga/usrp2/fifo/packet_verifier32.v23
-rw-r--r--fpga/usrp2/gpmc/fifo_to_gpmc_async.v5
-rw-r--r--fpga/usrp2/gpmc/gpmc_async.v120
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper.v90
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v38
-rw-r--r--fpga/usrp2/top/safe_u2plus/Makefile1
-rw-r--r--fpga/usrp2/top/u1e/Makefile1
-rw-r--r--fpga/usrp2/top/u1e/u1e_core.v100
-rw-r--r--fpga/usrp2/top/u1e_passthru/Makefile3
-rw-r--r--fpga/usrp2/top/u2_rev3/Makefile1
-rw-r--r--fpga/usrp2/top/u2_rev3/u2_core.v210
-rw-r--r--fpga/usrp2/top/u2_rev3/u2_rev3.v2
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/Makefile1
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/Makefile1
-rw-r--r--fpga/usrp2/top/u2plus/Makefile1
-rw-r--r--fpga/usrp2/top/u2plus/u2plus_core.v209
-rw-r--r--fpga/usrp2/vrt/Makefile.srcs1
-rw-r--r--fpga/usrp2/vrt/vita_rx_chain.v42
-rw-r--r--fpga/usrp2/vrt/vita_rx_control.v2
-rw-r--r--fpga/usrp2/vrt/vita_rx_framer.v11
-rw-r--r--host/CMakeLists.txt5
-rw-r--r--host/Modules/UHDPython.cmake2
-rwxr-xr-xhost/apps/omap_debug/fetch-bin.sh6
-rwxr-xr-xhost/apps/omap_debug/fetch-kernel.sh7
-rwxr-xr-xhost/apps/omap_debug/fetch-module.sh6
-rwxr-xr-xhost/apps/omap_debug/fetch-u-boot.sh7
-rwxr-xr-xhost/apps/omap_debug/read_board_id.sh10
-rwxr-xr-xhost/apps/omap_debug/reload-fpga.sh7
-rwxr-xr-xhost/apps/omap_debug/setup-board-id-eeprom.sh17
-rwxr-xr-xhost/apps/omap_debug/write-eeprom.sh92
-rwxr-xr-xhost/apps/omap_debug/write_board_id.sh10
-rw-r--r--host/include/uhd/CMakeLists.txt1
-rw-r--r--host/include/uhd/exception.hpp133
-rw-r--r--host/include/uhd/types/device_addr.hpp10
-rw-r--r--host/include/uhd/types/dict.ipp6
-rw-r--r--host/include/uhd/types/serial.hpp53
-rw-r--r--host/include/uhd/usrp/CMakeLists.txt1
-rw-r--r--host/include/uhd/usrp/dsp_props.hpp2
-rw-r--r--host/include/uhd/usrp/mboard_iface.hpp85
-rw-r--r--host/include/uhd/usrp/mboard_props.hpp4
-rw-r--r--host/include/uhd/usrp/multi_usrp.hpp33
-rw-r--r--host/include/uhd/usrp/tune_helper.hpp14
-rw-r--r--host/include/uhd/utils/CMakeLists.txt7
-rw-r--r--host/include/uhd/utils/algorithm.hpp62
-rw-r--r--host/include/uhd/utils/assert_has.hpp (renamed from host/include/uhd/utils/assert.hpp)22
-rw-r--r--host/include/uhd/utils/assert_has.ipp (renamed from host/include/uhd/utils/assert.ipp)13
-rw-r--r--host/include/uhd/utils/exception.hpp45
-rw-r--r--host/include/uhd/utils/props.hpp9
-rw-r--r--host/include/uhd/utils/safe_call.hpp2
-rw-r--r--host/include/uhd/wax.hpp18
-rw-r--r--host/lib/CMakeLists.txt5
-rw-r--r--host/lib/convert/convert_impl.cpp2
-rw-r--r--host/lib/convert/gen_convert_pred.py9
-rw-r--r--host/lib/device.cpp11
-rw-r--r--host/lib/exception.cpp43
-rw-r--r--host/lib/ic_reg_maps/common.py4
-rwxr-xr-xhost/lib/transport/gen_vrt_if_packet.py6
-rw-r--r--host/lib/transport/libusb1_base.cpp10
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp15
-rw-r--r--host/lib/transport/usb_dummy_impl.cpp8
-rw-r--r--host/lib/transport/vrt_packet_handler.hpp6
-rw-r--r--host/lib/types/device_addr.cpp53
-rw-r--r--host/lib/types/mac_addr.cpp7
-rw-r--r--host/lib/types/ranges.cpp8
-rw-r--r--host/lib/types/sensors.cpp2
-rw-r--r--host/lib/types/serial.cpp22
-rw-r--r--host/lib/usrp/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/db_basic_and_lf.cpp6
-rw-r--r--host/lib/usrp/dboard/db_dbsrx.cpp18
-rw-r--r--host/lib/usrp/dboard/db_dbsrx2.cpp14
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp4
-rw-r--r--host/lib/usrp/dboard/db_tvrx.cpp8
-rw-r--r--host/lib/usrp/dboard/db_unknown.cpp2
-rw-r--r--host/lib/usrp/dboard/db_wbx.cpp2
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp16
-rw-r--r--host/lib/usrp/dboard_base.cpp16
-rw-r--r--host/lib/usrp/dboard_eeprom.cpp5
-rw-r--r--host/lib/usrp/dboard_manager.cpp8
-rw-r--r--host/lib/usrp/dsp_utils.cpp4
-rw-r--r--host/lib/usrp/gps_ctrl.cpp7
-rw-r--r--host/lib/usrp/misc_utils.cpp12
-rw-r--r--host/lib/usrp/multi_usrp.cpp204
-rw-r--r--host/lib/usrp/subdev_spec.cpp4
-rw-r--r--host/lib/usrp/tune_helper.cpp29
-rw-r--r--host/lib/usrp/usrp1/clock_ctrl.cpp9
-rw-r--r--host/lib/usrp/usrp1/codec_ctrl.cpp18
-rw-r--r--host/lib/usrp/usrp1/codec_impl.cpp2
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp12
-rw-r--r--host/lib/usrp/usrp1/dboard_impl.cpp2
-rw-r--r--host/lib/usrp/usrp1/dsp_impl.cpp95
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp3
-rw-r--r--host/lib/usrp/usrp1/mboard_impl.cpp22
-rw-r--r--host/lib/usrp/usrp1/usrp1_ctrl.cpp206
-rw-r--r--host/lib/usrp/usrp1/usrp1_ctrl.hpp47
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.cpp38
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.hpp39
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp14
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp16
-rw-r--r--host/lib/usrp/usrp2/clock_ctrl.cpp4
-rw-r--r--host/lib/usrp/usrp2/codec_ctrl.cpp12
-rw-r--r--host/lib/usrp/usrp2/codec_impl.cpp4
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp18
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp2
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp161
-rw-r--r--host/lib/usrp/usrp2/fw_common.h13
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp129
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp184
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp14
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.hpp55
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp229
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp70
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.cpp51
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.hpp40
-rw-r--r--host/lib/usrp/usrp_e100/clock_ctrl.cpp14
-rw-r--r--host/lib/usrp/usrp_e100/codec_ctrl.cpp20
-rw-r--r--host/lib/usrp/usrp_e100/codec_impl.cpp2
-rw-r--r--host/lib/usrp/usrp_e100/dboard_iface.cpp8
-rw-r--r--host/lib/usrp/usrp_e100/dboard_impl.cpp2
-rw-r--r--host/lib/usrp/usrp_e100/dsp_impl.cpp14
-rw-r--r--host/lib/usrp/usrp_e100/fpga_downloader.cpp15
-rw-r--r--host/lib/usrp/usrp_e100/mboard_impl.cpp10
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_iface.cpp19
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_iface.hpp48
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_impl.cpp8
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp2
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_regs.hpp1
-rw-r--r--host/lib/usrp/wrapper_utils.hpp66
-rw-r--r--host/lib/utils/CMakeLists.txt1
-rw-r--r--host/lib/utils/assert.cpp24
-rw-r--r--host/lib/utils/gain_group.cpp8
-rw-r--r--host/lib/utils/images.cpp4
-rw-r--r--host/lib/utils/load_modules.cpp10
-rw-r--r--host/lib/utils/paths.cpp1
-rw-r--r--host/lib/utils/thread_priority.cpp14
-rw-r--r--host/lib/utils/warning.cpp4
-rw-r--r--host/lib/wax.cpp9
-rw-r--r--host/tests/error_test.cpp21
-rw-r--r--host/tests/tune_helper_test.cpp22
-rw-r--r--host/tests/wax_test.cpp4
-rw-r--r--host/usrp_e_utils/CMakeLists.txt1
-rw-r--r--host/usrp_e_utils/usrp-e-gpio.c (renamed from host/apps/omap_debug/usrp-e-gpio.c)4
-rw-r--r--host/usrp_e_utils/usrp-e-loopback.c19
-rw-r--r--host/utils/usrp_burn_db_eeprom.cpp2
-rw-r--r--images/CMakeLists.txt3
185 files changed, 3026 insertions, 4478 deletions
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 4ccb585e2..68c24e872 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -53,20 +53,34 @@ static void setup_network(void);
// the fast-path setup global variables
// ----------------------------------------------------------------
static eth_mac_addr_t fp_mac_addr_src, fp_mac_addr_dst;
-extern struct socket_address fp_socket_src, fp_socket_dst;
+struct socket_address fp_socket_src, fp_socket_dst;
+extern uint16_t dsp0_dst_port, err0_dst_port, dsp1_dst_port;
static void handle_udp_err0_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
sr_udp_sm->err0_port = (((uint32_t)dst.port) << 16) | src.port;
+ err0_dst_port = src.port;
printf("Storing for async error path:\n");
printf(" source udp port: %d\n", dst.port);
printf(" destination udp port: %d\n", src.port);
newline();
}
-static void handle_udp_data_packet(
+static void handle_udp_dsp1_packet(
+ struct socket_address src, struct socket_address dst,
+ unsigned char *payload, int payload_len
+){
+ sr_udp_sm->dsp1_port = (((uint32_t)dst.port) << 16) | src.port;
+ dsp1_dst_port = src.port;
+ printf("Storing for dsp1 path:\n");
+ printf(" source udp port: %d\n", dst.port);
+ printf(" destination udp port: %d\n", src.port);
+ newline();
+}
+
+static void handle_udp_dsp0_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
@@ -75,7 +89,8 @@ static void handle_udp_data_packet(
fp_socket_src = dst;
fp_socket_dst = src;
sr_udp_sm->dsp0_port = (((uint32_t)dst.port) << 16) | src.port;
- printf("Storing for fast path:\n");
+ dsp0_dst_port = src.port;
+ printf("Storing for dsp0 path:\n");
printf(" source mac addr: ");
print_mac_addr(&fp_mac_addr_src); newline();
printf(" source ip addr: ");
@@ -188,10 +203,7 @@ static void handle_udp_ctrl_packet(
* Peek and Poke Register
******************************************************************/
case USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO:
- if (0){//ctrl_data_in->data.poke_args.addr < 0xC000){
- printf("error! tried to poke into 0x%x\n", ctrl_data_in->data.poke_args.addr);
- }
- else switch(ctrl_data_in->data.poke_args.num_bytes){
+ switch(ctrl_data_in->data.poke_args.num_bytes){
case sizeof(uint32_t):
*((uint32_t *) ctrl_data_in->data.poke_args.addr) = (uint32_t)ctrl_data_in->data.poke_args.data;
break;
@@ -226,6 +238,9 @@ static void handle_udp_ctrl_packet(
ctrl_data_out.id = USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE;
break;
+ /*******************************************************************
+ * UART Control
+ ******************************************************************/
case USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO:{
//executes a readline()-style read, up to num_bytes long, up to and including newline
int num_bytes = ctrl_data_in->data.uart_args.bytes;
@@ -248,6 +263,15 @@ static void handle_udp_ctrl_packet(
break;
}
+ /*******************************************************************
+ * Echo test
+ ******************************************************************/
+ case USRP2_CTRL_ID_HOLLER_AT_ME_BRO:
+ ctrl_data_out.data.echo_args.len = payload_len;
+ ctrl_data_out.id = USRP2_CTRL_ID_HOLLER_BACK_DUDE;
+ send_udp_pkt(USRP2_UDP_CTRL_PORT, src, &ctrl_data_out, ctrl_data_in->data.echo_args.len);
+ return;
+
default:
ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT;
}
@@ -341,13 +365,14 @@ main(void)
//1) register the addresses into the network stack
register_addrs(ethernet_mac_addr(), get_ip_addr());
- pkt_ctrl_program_inspector(get_ip_addr(), USRP2_UDP_DATA_PORT);
+ pkt_ctrl_program_inspector(get_ip_addr(), USRP2_UDP_DSP0_PORT);
//2) register callbacks for udp ports we service
init_udp_listeners();
register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);
- register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet);
+ register_udp_listener(USRP2_UDP_DSP0_PORT, handle_udp_dsp0_packet);
register_udp_listener(USRP2_UDP_ERR0_PORT, handle_udp_err0_packet);
+ register_udp_listener(USRP2_UDP_DSP1_PORT, handle_udp_dsp1_packet);
#ifdef USRP2P
register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet);
#endif
diff --git a/firmware/zpu/lib/clock_bits.h b/firmware/zpu/lib/clock_bits.h
deleted file mode 100644
index d2052e941..000000000
--- a/firmware/zpu/lib/clock_bits.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright 2010 Ettus Research LLC
-//
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef INCLUDED_USRP2_CLOCK_BITS_H
-#define INCLUDED_USRP2_CLOCK_BITS_H
-
-#define _MC_WE_LOCK 0x0001
-#define _MC_MIMO_CLK_INPUT 0x0002 // else SMA input
-
-/*
- * Derived masks (use these):
- *
- * We get our input from 1 of three places:
- * Our free running oscilator, our SMA connector, or from the MIMO connector
- */
-#define MC_WE_DONT_LOCK 0x0000
-#define MC_WE_LOCK_TO_SMA (_MC_WE_LOCK | 0)
-#define MC_WE_LOCK_TO_MIMO (_MC_WE_LOCK | _MC_MIMO_CLK_INPUT)
-
-/*
- * Independent of the source of the clock, we may or may not drive our
- * clock onto the mimo connector. Note that there are dedicated clock
- * signals in each direction, so disaster doesn't occurs if we're
- * unnecessarily providing clock.
- */
-#define MC_PROVIDE_CLK_TO_MIMO 0x0004
-
-#define MC_REF_CLK_MASK 0x0f
-
-#define MC_PPS_SOURCE_SMA (0x00 << 4)
-#define MC_PPS_SOURCE_MIMO (0x01 << 4)
-
-#define MC_PPS_POLARITY_NEG (0x00 << 5)
-#define MC_PPS_POLARITY_POS (0x01 << 5)
-
-#endif /* INCLUDED_USRP2_CLOCK_BITS_H */
diff --git a/firmware/zpu/lib/clocks.c b/firmware/zpu/lib/clocks.c
index 2b352a385..c1e8ce827 100644
--- a/firmware/zpu/lib/clocks.c
+++ b/firmware/zpu/lib/clocks.c
@@ -1,4 +1,6 @@
-/* -*- c++ -*- */
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
/*
* Copyright 2008 Free Software Foundation, Inc.
*
@@ -16,119 +18,39 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#include <clocks.h>
-
+#include <stdbool.h>
#include "memory_map.h"
#include "ad9510.h"
#include "spi.h"
-#include "u2_init.h"
-//USRP2PLUS clocks:
-//Clock 0: testclk
-//Clock 1: FPGA clk
-//Clock 2: ADC clk
-//Clock 3: DAC clk
-//Clock 4: SER clk
-//Clock 5: TX dboard clk
-//Clock 6: EXP clk
-//Clock 7: RX dboard clk
+/*!
+ * \brief Lock Detect -- Return True if our PLL is locked
+ */
+bool clocks_lock_detect();
-//TODO: should have enough brains to init the FPGA clock for USRP2+. all others are suspect.
-//note that without EEPROM support u2_hw_rev_major is going to be incorrect.
+/*!
+ * \brief Enable or disable fpga clock. Disabling would wedge and require a power cycle.
+ */
+void clocks_enable_fpga_clk(bool enable, int divisor);
void
clocks_init(void)
{
// Set up basic clocking functions in AD9510
- ad9510_write_reg(0x45, 0x01); // CLK2 drives distribution
+ ad9510_write_reg(0x45, 0x01);
//enable the 100MHz clock output to the FPGA for 50MHz CPU clock
clocks_enable_fpga_clk(true, 1);
spi_wait();
- // Set up PLL for 10 MHz reference
- // Reg 4, A counter, Don't Care
-// ad9510_write_reg(0x05, 0x00); // Reg 5, B counter MSBs, 0
-// ad9510_write_reg(0x06, 0x05); // Reg 6, B counter LSBs, 5
- // Reg 7, Loss of reference detect, doesn't work yet, 0
-// ad9510_write_reg(0x5A, 0x01); // Update Regs
-
- // Primary clock configuration
-// clocks_mimo_config(MC_WE_DONT_LOCK);
-
-
//wait for the clock to stabilize
while(!clocks_lock_detect());
//issue a reset to the DCM so it locks up to the new freq
output_regs->clk_ctrl |= CLK_RESET;
-
- // Set up other clocks
- //clocks_enable_test_clk(false, 0);
- //clocks_enable_tx_dboard(false, 0);
- //clocks_enable_rx_dboard(false, 0);
-// clocks_enable_eth_phyclk(false, 0); //PHY clk is separate now (u2r4, u2p)
-
- // Enable clock to ADCs and DACs
- //clocks_enable_dac_clk(true, 1);
- //clocks_enable_adc_clk(true, 1);
-}
-
-/*
-void
-clocks_mimo_config(int flags)
-{
- if (flags & _MC_WE_LOCK){
- // Reg 8, Charge pump on, dig lock det, positive PFD, 47
- ad9510_write_reg(0x08, 0x47);
- }
- else {
- // Reg 8, Charge pump off, dig lock det, positive PFD
- ad9510_write_reg(0x08, 0x00);
- }
-
- // Reg 9, Charge pump current, 0x40=3mA, 0x00=650uA
- ad9510_write_reg(0x09, 0x00);
- // Reg A, Prescaler of 2, everything normal 04
- ad9510_write_reg(0x0A, 0x04);
- // Reg B, R Div MSBs, 0
- ad9510_write_reg(0x0B, 0x00);
- // Reg C, R Div LSBs, 1
- ad9510_write_reg(0x0C, 0x01);
- // Reg D, Antibacklash, Digital lock det, 0
-
- ad9510_write_reg(0x5A, 0x01); // Update Regs
-
- spi_wait();
-
- // Allow for clock switchover
- // The below masks include 0x10, which issues a reset to the DCM.
- if (flags & _MC_WE_LOCK){ // WE LOCK
- if (flags & _MC_MIMO_CLK_INPUT) {
- // Turn on ref output and choose the MIMO connector
- output_regs->clk_ctrl = 0x15;
- }
- else {
- // turn on ref output and choose the SMA
- output_regs->clk_ctrl = 0x1C;
- }
- }
- else { // WE DONT LOCK
- // Disable both ext clk inputs
- output_regs->clk_ctrl = 0x10;
- }
-
- // Do we drive a clock onto the MIMO connector?
-// if (flags & MC_PROVIDE_CLK_TO_MIMO)
-// clocks_enable_clkexp_out(true,10);
-// else
-// clocks_enable_clkexp_out(false,0);
}
-*/
bool
clocks_lock_detect()
@@ -188,79 +110,9 @@ clocks_enable_XXX_clk(bool enable, int divisor, int reg_en, int reg_div, int mod
ad9510_write_reg(0x5A, 0x01); // Update Regs
}
-// Clock 0
-/*void
-clocks_enable_test_clk(bool enable, int divisor)
-{
- clocks_enable_XXX_clk(enable,divisor,0x3C,0x48,CLOCK_MODE_PECL);
-}*/
-
// Clock 1
void
clocks_enable_fpga_clk(bool enable, int divisor)
{
clocks_enable_XXX_clk(enable,divisor,0x3D,0x4A,CLOCK_MODE_PECL);
}
-/*
-// Clock 2 on Rev 3, Clock 5 on Rev 4, Clock 6 on USRP2+
-void
-clocks_enable_clkexp_out(bool enable, int divisor)
-{
- if(u2_hw_rev_major == 3)
- clocks_enable_XXX_clk(enable,divisor,0x3E,0x4C,CLOCK_MODE_PECL);
- else if(u2_hw_rev_major == 4) {
- ad9510_write_reg(0x34,0x00); // Turn on fine delay
- ad9510_write_reg(0x35,0x00); // Set Full Scale to nearly 10ns
- ad9510_write_reg(0x36,0x1c); // Set fine delay. 0x20 is midscale
- clocks_enable_XXX_clk(enable,divisor,0x41,0x52,CLOCK_MODE_LVDS);
- }
- else if(u2_hw_rev_major == 10) {
- ad9510_write_reg(0x34, 0x00);
- ad9510_write_reg(0x35, 0x00);
- ad9510_write_reg(0x36, 0x1C);
- clocks_enable_XXX_clk(enable, divisor, 0x42, 0x52, CLOCK_MODE_LVDS);
- }
- else
- putstr("ERR (clocks_enable_clkexp_out): Invalid hw rev, don't know what to do!\n");
-}
-*/
-/*
-// Clock 5 on Rev 3, none (was 2) on Rev 4, none on USRP2+
-void
-clocks_enable_eth_phyclk(bool enable, int divisor)
-{
- if(u2_hw_rev_major == 3)
- clocks_enable_XXX_clk(enable,divisor,0x41,0x52,CLOCK_MODE_LVDS);
- else if(u2_hw_rev_major == 4)
- clocks_enable_XXX_clk(enable,divisor,0x3E,0x4C,CLOCK_MODE_PECL);
- else
- putstr("(clocks_enable_eth_phyclk): no eth PHY clock or invalid hw rev\n"); //not really an error
-}
-*/
-// Clock 3
-/*void
-clocks_enable_dac_clk(bool enable, int divisor)
-{
- clocks_enable_XXX_clk(enable,divisor,0x3F,0x4E,CLOCK_MODE_PECL);
-}*/
-
-// Clock 4
-/*void
-clocks_enable_adc_clk(bool enable, int divisor)
-{
- clocks_enable_XXX_clk(enable,divisor,0x40,0x50,CLOCK_MODE_LVDS);
-}*/
-
-// Clock 6
-/*void
-clocks_enable_tx_dboard(bool enable, int divisor)
-{
- clocks_enable_XXX_clk(enable,divisor,0x42,0x54,CLOCK_MODE_CMOS);
-}*/
-
-// Clock 7
-/*void
-clocks_enable_rx_dboard(bool enable, int divisor)
-{
- clocks_enable_XXX_clk(enable,divisor,0x43,0x56,CLOCK_MODE_CMOS);
-}*/
diff --git a/firmware/zpu/lib/clocks.h b/firmware/zpu/lib/clocks.h
index 28d1d542f..7bc7a3cda 100644
--- a/firmware/zpu/lib/clocks.h
+++ b/firmware/zpu/lib/clocks.h
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
/*
* Copyright 2008 Free Software Foundation, Inc.
@@ -21,75 +21,10 @@
#ifndef INCLUDED_CLOCKS_H
#define INCLUDED_CLOCKS_H
-/*
- * Routines to configure our multitude of clocks
- */
-
-#include <stdbool.h>
-#include "clock_bits.h"
-
-
/*!
- * One time call to initialize all clocks to a reasonable state. We
- * come out of here using our free running 100MHz oscilator and not
- * providing a clock to the MIMO connector (CMC_WE_DONT_LOCK)
+ * One time call to initialize the master clock to a reasonable state.
+ * We come out of here using our free running 100MHz oscillator.
*/
void clocks_init(void);
-
-/*!
- * \brief MIMO clock configuration.
- *
- * Configure our master clock source, and whether or not we drive a
- * clock onto the mimo connector. See MC_flags in usrp2_mimo_config.h.
- */
-//void clocks_mimo_config(int flags);
-
-/*!
- * \brief Lock Detect -- Return True if our PLL is locked
- */
-bool clocks_lock_detect();
-
-/*!
- * \brief Enable or disable test clock (extra clock signal)
- */
-//void clocks_enable_test_clk(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable fpga clock. Disabling would wedge and require a power cycle.
- */
-void clocks_enable_fpga_clk(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable clock output sent to MIMO connector
- */
-//void clocks_enable_clkexp_out(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable ethernet phyclk, should always be disabled
- */
-//void clocks_enable_eth_phyclk(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable clock to DAC
- */
-//void clocks_enable_dac_clk(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable clock to ADC
- */
-//void clocks_enable_adc_clk(bool enable, int divisor);
-
-/*!
- * \brief Enable or disable clock to Rx daughterboard
- */
-//void clocks_enable_rx_dboard(bool enable, int divisor);
-
-
-/*!
- * \brief Enable or disable clock to Tx daughterboard
- */
-//void clocks_enable_tx_dboard(bool enable, int divisor);
-
-
#endif /* INCLUDED_CLOCKS_H */
diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c
index d1b06976d..f70f279ac 100644
--- a/firmware/zpu/lib/net_common.c
+++ b/firmware/zpu/lib/net_common.c
@@ -1,6 +1,5 @@
-/* -*- c -*- */
/*
- * Copyright 2009,2010 Ettus Research LLC
+ * Copyright 2009-2011 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
@@ -39,10 +38,12 @@
static const bool debug = false;
+static const size_t out_buff_size = 2048;
+
static const eth_mac_addr_t BCAST_MAC_ADDR = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
//used in the top level application...
-struct socket_address fp_socket_src, fp_socket_dst;
+uint16_t dsp0_dst_port, err0_dst_port, dsp1_dst_port;
// ------------------------------------------------------------------------
@@ -119,58 +120,48 @@ register_udp_listener(int port, udp_receiver_t rcvr)
* \param len2 length of third part of data
*/
static void
-send_pkt(eth_mac_addr_t dst, int ethertype,
- const void *buf0, size_t len0,
- const void *buf1, size_t len1,
- const void *buf2, size_t len2)
-{
-
- // Assemble the header
- padded_eth_hdr_t ehdr;
- ehdr.pad = 0;
- ehdr.dst = dst;
- ehdr.src = _local_mac_addr;
- ehdr.ethertype = ethertype;
-
- uint32_t *buff = (uint32_t *)pkt_ctrl_claim_outgoing_buffer();
-
- // Copy the pieces into the buffer
- uint32_t *p = buff;
- *p++ = 0x0; // slow path
- memcpy_wa(p, &ehdr, sizeof(ehdr)); // 4 lines
- p += sizeof(ehdr)/sizeof(uint32_t);
-
-
- // FIXME modify memcpy_wa to do read/modify/write if reqd
-
- if (len0 && ((len0 & 0x3) || (intptr_t) buf0 & 0x3))
- printf("send_pkt: bad alignment of len0 and/or buf0\n");
-
- if (len1 && ((len1 & 0x3) || (intptr_t) buf1 & 0x3))
- printf("send_pkt: bad alignment of len1 and/or buf1\n");
-
- if (len2 && ((len2 & 0x3) || (intptr_t) buf2 & 0x3))
- printf("send_pkt: bad alignment of len2 and/or buf2\n");
-
- if (len0){
- memcpy_wa(p, buf0, len0);
- p += len0/sizeof(uint32_t);
- }
- if (len1){
- memcpy_wa(p, buf1, len1);
- p += len1/sizeof(uint32_t);
- }
- if (len2){
- memcpy_wa(p, buf2, len2);
- p += len2/sizeof(uint32_t);
- }
+send_pkt(
+ eth_mac_addr_t dst, int ethertype,
+ const void *buf0, size_t len0,
+ const void *buf1, size_t len1,
+ const void *buf2, size_t len2
+){
+
+ //control word for framed data
+ uint32_t ctrl_word = 0x0;
+
+ //assemble the ethernet header
+ padded_eth_hdr_t ehdr;
+ ehdr.pad = 0;
+ ehdr.dst = dst;
+ ehdr.src = _local_mac_addr;
+ ehdr.ethertype = ethertype;
+
+ //grab an out buffer and pointer
+ uint8_t *buff = (uint8_t *)pkt_ctrl_claim_outgoing_buffer();
+ uint8_t *p = buff;
+ size_t total_len = 0;
+
+ //create a list of all buffers to copy
+ const void *buffs[] = {&ctrl_word, &ehdr, buf0, buf1, buf2};
+ size_t lens[] = {sizeof(ctrl_word), sizeof(ehdr), len0, len1, len2};
+
+ //copy each buffer into the out buffer
+ for (size_t i = 0; i < sizeof(buffs)/sizeof(buffs[0]); i++){
+ total_len += lens[i]; //use full length (not clipped)
+ size_t bytes_remaining = out_buff_size - (size_t)(p - buff);
+ if (lens[i] > bytes_remaining) lens[i] = bytes_remaining;
+ if (lens[i] && ((lens[i] & 0x3) || (intptr_t) buffs[i] & 0x3))
+ printf("send_pkt: bad alignment of len and/or buf\n");
+ memcpy_wa(p, buffs[i], lens[i]);
+ p += lens[i];
+ }
- size_t total_len = (p - buff) * sizeof(uint32_t);
- if (total_len < 60) // ensure that we don't try to send a short packet
- total_len = 60;
+ //ensure that minimum length requirements are met
+ if (total_len < 64) total_len = 64; //60 + ctrl word
- pkt_ctrl_commit_outgoing_buffer(total_len/4);
- if (debug) printf("sent %d bytes\n", (int)total_len);
+ pkt_ctrl_commit_outgoing_buffer(total_len/sizeof(uint32_t));
+ if (debug) printf("sent %d bytes\n", (int)total_len);
}
unsigned int CHKSUM(unsigned int x, unsigned int *chksum)
@@ -277,15 +268,24 @@ handle_icmp_packet(struct ip_addr src, struct ip_addr dst,
//filter out non udp data response
struct ip_hdr *ip = (struct ip_hdr *)(((uint8_t*)icmp) + sizeof(struct icmp_echo_hdr));
struct udp_hdr *udp = (struct udp_hdr *)(((char *)ip) + IP_HLEN);
- if (IPH_PROTO(ip) != IP_PROTO_UDP || udp->dest != fp_socket_dst.port) return;
-
- //end async update packets per second
- sr_tx_ctrl->cyc_per_up = 0;
-
- //the end continuous streaming command
- sr_rx_ctrl->cmd = 1 << 31; //no samples now
- sr_rx_ctrl->time_secs = 0;
- sr_rx_ctrl->time_ticks = 0; //latch the command
+ if (IPH_PROTO(ip) != IP_PROTO_UDP) break;
+
+ if (udp->dest == dsp0_dst_port){
+ //the end continuous streaming command
+ sr_rx_ctrl0->cmd = 1 << 31; //no samples now
+ sr_rx_ctrl0->time_secs = 0;
+ sr_rx_ctrl0->time_ticks = 0; //latch the command
+ }
+ else if (udp->dest == dsp1_dst_port){
+ //the end continuous streaming command
+ sr_rx_ctrl1->cmd = 1 << 31; //no samples now
+ sr_rx_ctrl1->time_secs = 0;
+ sr_rx_ctrl1->time_ticks = 0; //latch the command
+ }
+ else if (udp->dest == err0_dst_port){
+ //end async update packets per second
+ sr_tx_ctrl->cyc_per_up = 0;
+ }
//struct udp_hdr *udp = (struct udp_hdr *)((char *)icmp + 28);
//printf("icmp port unr %d\n", udp->dest);
diff --git a/firmware/zpu/usrp2/memory_map.h b/firmware/zpu/usrp2/memory_map.h
index e728a1ddb..79b11759a 100644
--- a/firmware/zpu/usrp2/memory_map.h
+++ b/firmware/zpu/usrp2/memory_map.h
@@ -1,4 +1,4 @@
-/* -*- c -*- */
+// Copyright 2010-2011 Ettus Research LLC
/*
* Copyright 2007,2008,2009 Free Software Foundation, Inc.
*
@@ -227,8 +227,10 @@ hwconfig_wishbone_divisor(void)
#define SR_UDP_SM 96
#define SR_TX_DSP 208
#define SR_TX_CTRL 224
-#define SR_RX_DSP 160
-#define SR_RX_CTRL 176
+#define SR_RX_DSP0 160
+#define SR_RX_DSP1 240
+#define SR_RX_CTRL0 176
+#define SR_RX_CTRL1 32
#define SR_TIME64 192
#define SR_SIMTIMER 198
#define SR_LAST 255
@@ -350,10 +352,7 @@ typedef struct {
#define sr_udp_sm ((sr_udp_sm_t *) _SR_ADDR(SR_UDP_SM))
-// --- dsp tx regs ---
-
-#define MIN_CIC_INTERP 1
-#define MAX_CIC_INTERP 128
+// --- VITA TX CTRL regs ---
typedef struct {
volatile uint32_t num_chan;
@@ -366,52 +365,6 @@ typedef struct {
#define sr_tx_ctrl ((sr_tx_ctrl_t *) _SR_ADDR(SR_TX_CTRL))
-typedef struct {
- volatile int32_t freq;
- volatile uint32_t scale_iq; // {scale_i,scale_q}
- volatile uint32_t interp_rate;
- volatile uint32_t _padding0; // padding for the tx_mux
- // NOT freq, scale, interp
- /*!
- * \brief output mux configuration.
- *
- * <pre>
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------------------------------+-------+-------+-------+-------+
- * | | DAC1 | DAC0 |
- * +-------------------------------+-------+-------+-------+-------+
- *
- * There are N DUCs (1 now) with complex inputs and outputs.
- * There are two DACs.
- *
- * Each 4-bit DACx field specifies the source for the DAC
- * Each subfield is coded like this:
- *
- * 3 2 1 0
- * +-------+
- * | N |
- * +-------+
- *
- * N specifies which DUC output is connected to this DAC.
- *
- * N which interp output
- * --- -------------------
- * 0 DUC 0 I
- * 1 DUC 0 Q
- * 2 DUC 1 I
- * 3 DUC 1 Q
- * F All Zeros
- *
- * The default value is 0x10
- * </pre>
- */
- volatile uint32_t tx_mux;
-
-} dsp_tx_regs_t;
-
-#define dsp_tx_regs ((dsp_tx_regs_t *) _SR_ADDR(SR_TX_DSP))
-
// --- VITA RX CTRL regs ---
typedef struct {
// The following 3 are logically a single command register.
@@ -419,81 +372,10 @@ typedef struct {
volatile uint32_t cmd; // {now, chain, num_samples(30)
volatile uint32_t time_secs;
volatile uint32_t time_ticks;
-
- volatile uint32_t clear_overrun; // write anything to clear overrun
- volatile uint32_t vrt_header; // word 0 of packet. FPGA fills in packet counter
- volatile uint32_t vrt_stream_id; // word 1 of packet.
- volatile uint32_t vrt_trailer;
- volatile uint32_t nsamples_per_pkt;
- volatile uint32_t nchannels; // 1 in basic case, up to 4 for vector sources
- volatile uint32_t pad[7]; // Make each structure 16 elements long
} sr_rx_ctrl_t;
-#define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL))
-
-// --- dsp rx regs ---
-#define MIN_CIC_DECIM 1
-#define MAX_CIC_DECIM 128
-
-typedef struct {
- volatile int32_t freq;
- volatile uint32_t scale_iq; // {scale_i,scale_q}
- volatile uint32_t decim_rate;
- volatile uint32_t dcoffset_i; // Bit 31 high sets fixed offset mode, using lower 14 bits,
- // otherwise it is automatic
- volatile uint32_t dcoffset_q; // Bit 31 high sets fixed offset mode, using lower 14 bits
-
- /*!
- * \brief input mux configuration.
- *
- * This determines which ADC (or constant zero) is connected to
- * each DDC input. There are N DDCs (1 now). Each has two inputs.
- *
- * <pre>
- * Mux value:
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | |Q0 |I0 |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- *
- * Each 2-bit I field is either 00 (A/D A), 01 (A/D B) or 1X (const zero)
- * Each 2-bit Q field is either 00 (A/D A), 01 (A/D B) or 1X (const zero)
- *
- * The default value is 0x4
- * </pre>
- */
- volatile uint32_t rx_mux; // called adc_mux in dsp_core_rx.v
-
- /*!
- * \brief Streaming GPIO configuration
- *
- * This determines whether the LSBs of I and Q samples come from the DSP
- * pipeline or from the io_rx GPIO pins. To stream GPIO, one must first
- * set the GPIO data direction register to have io_rx[15] and/or io_rx[14]
- * configured as inputs. The GPIO pins will be sampled at the time the
- * remainder of the DSP sample is strobed into the RX sample FIFO. There
- * will be a decimation-dependent fixed time offset between the GPIO
- * sample stream and the associated RF samples.
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | MBZ |Q|I|
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- *
- * I 0=LSB comes from DSP pipeline (default)
- * 1=LSB comes from io_rx[15]
- *
- * Q 0=LSB comes from DSP pipeline (default)
- * 1=LSB comes from io_rx[14]
- */
- volatile uint32_t gpio_stream_enable;
-
-} dsp_rx_regs_t;
-
-#define dsp_rx_regs ((dsp_rx_regs_t *) _SR_ADDR(SR_RX_DSP))
+#define sr_rx_ctrl0 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL0))
+#define sr_rx_ctrl1 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL1))
// ----------------------------------------------------------------
// VITA49 64 bit time (write only)
diff --git a/firmware/zpu/usrp2p/memory_map.h b/firmware/zpu/usrp2p/memory_map.h
index 36d8ac9f2..2567a4588 100644
--- a/firmware/zpu/usrp2p/memory_map.h
+++ b/firmware/zpu/usrp2p/memory_map.h
@@ -1,4 +1,4 @@
-/* -*- c -*- */
+// Copyright 2010-2011 Ettus Research LLC
/*
* Copyright 2007,2008,2009 Free Software Foundation, Inc.
*
@@ -218,8 +218,10 @@ hwconfig_wishbone_divisor(void)
#define SR_UDP_SM 96
#define SR_TX_DSP 208
#define SR_TX_CTRL 224
-#define SR_RX_DSP 160
-#define SR_RX_CTRL 176
+#define SR_RX_DSP0 160
+#define SR_RX_DSP1 240
+#define SR_RX_CTRL0 176
+#define SR_RX_CTRL1 32
#define SR_TIME64 192
#define SR_SIMTIMER 198
#define SR_LAST 255
@@ -343,10 +345,7 @@ typedef struct {
#define sr_udp_sm ((sr_udp_sm_t *) _SR_ADDR(SR_UDP_SM))
-// --- dsp tx regs ---
-
-#define MIN_CIC_INTERP 1
-#define MAX_CIC_INTERP 128
+// --- VITA TX CTRL regs ---
typedef struct {
volatile uint32_t num_chan;
@@ -359,52 +358,6 @@ typedef struct {
#define sr_tx_ctrl ((sr_tx_ctrl_t *) _SR_ADDR(SR_TX_CTRL))
-typedef struct {
- volatile int32_t freq;
- volatile uint32_t scale_iq; // {scale_i,scale_q}
- volatile uint32_t interp_rate;
- volatile uint32_t _padding0; // padding for the tx_mux
- // NOT freq, scale, interp
- /*!
- * \brief output mux configuration.
- *
- * <pre>
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------------------------------+-------+-------+-------+-------+
- * | | DAC1 | DAC0 |
- * +-------------------------------+-------+-------+-------+-------+
- *
- * There are N DUCs (1 now) with complex inputs and outputs.
- * There are two DACs.
- *
- * Each 4-bit DACx field specifies the source for the DAC
- * Each subfield is coded like this:
- *
- * 3 2 1 0
- * +-------+
- * | N |
- * +-------+
- *
- * N specifies which DUC output is connected to this DAC.
- *
- * N which interp output
- * --- -------------------
- * 0 DUC 0 I
- * 1 DUC 0 Q
- * 2 DUC 1 I
- * 3 DUC 1 Q
- * F All Zeros
- *
- * The default value is 0x10
- * </pre>
- */
- volatile uint32_t tx_mux;
-
-} dsp_tx_regs_t;
-
-#define dsp_tx_regs ((dsp_tx_regs_t *) _SR_ADDR(SR_TX_DSP))
-
// --- VITA RX CTRL regs ---
typedef struct {
// The following 3 are logically a single command register.
@@ -412,81 +365,10 @@ typedef struct {
volatile uint32_t cmd; // {now, chain, num_samples(30)
volatile uint32_t time_secs;
volatile uint32_t time_ticks;
-
- volatile uint32_t clear_overrun; // write anything to clear overrun
- volatile uint32_t vrt_header; // word 0 of packet. FPGA fills in packet counter
- volatile uint32_t vrt_stream_id; // word 1 of packet.
- volatile uint32_t vrt_trailer;
- volatile uint32_t nsamples_per_pkt;
- volatile uint32_t nchannels; // 1 in basic case, up to 4 for vector sources
- volatile uint32_t pad[7]; // Make each structure 16 elements long
} sr_rx_ctrl_t;
-#define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL))
-
-// --- dsp rx regs ---
-#define MIN_CIC_DECIM 1
-#define MAX_CIC_DECIM 128
-
-typedef struct {
- volatile int32_t freq;
- volatile uint32_t scale_iq; // {scale_i,scale_q}
- volatile uint32_t decim_rate;
- volatile uint32_t dcoffset_i; // Bit 31 high sets fixed offset mode, using lower 14 bits,
- // otherwise it is automatic
- volatile uint32_t dcoffset_q; // Bit 31 high sets fixed offset mode, using lower 14 bits
-
- /*!
- * \brief input mux configuration.
- *
- * This determines which ADC (or constant zero) is connected to
- * each DDC input. There are N DDCs (1 now). Each has two inputs.
- *
- * <pre>
- * Mux value:
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | |Q0 |I0 |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- *
- * Each 2-bit I field is either 00 (A/D A), 01 (A/D B) or 1X (const zero)
- * Each 2-bit Q field is either 00 (A/D A), 01 (A/D B) or 1X (const zero)
- *
- * The default value is 0x4
- * </pre>
- */
- volatile uint32_t rx_mux; // called adc_mux in dsp_core_rx.v
-
- /*!
- * \brief Streaming GPIO configuration
- *
- * This determines whether the LSBs of I and Q samples come from the DSP
- * pipeline or from the io_rx GPIO pins. To stream GPIO, one must first
- * set the GPIO data direction register to have io_rx[15] and/or io_rx[14]
- * configured as inputs. The GPIO pins will be sampled at the time the
- * remainder of the DSP sample is strobed into the RX sample FIFO. There
- * will be a decimation-dependent fixed time offset between the GPIO
- * sample stream and the associated RF samples.
- *
- * 3 2 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | MBZ |Q|I|
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- *
- * I 0=LSB comes from DSP pipeline (default)
- * 1=LSB comes from io_rx[15]
- *
- * Q 0=LSB comes from DSP pipeline (default)
- * 1=LSB comes from io_rx[14]
- */
- volatile uint32_t gpio_stream_enable;
-
-} dsp_rx_regs_t;
-
-#define dsp_rx_regs ((dsp_rx_regs_t *) _SR_ADDR(SR_RX_DSP))
+#define sr_rx_ctrl0 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL0))
+#define sr_rx_ctrl1 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL1))
// ----------------------------------------------------------------
// VITA49 64 bit time (write only)
diff --git a/fpga/usrp2/control_lib/Makefile.srcs b/fpga/usrp2/control_lib/Makefile.srcs
index 5ae185ee8..751b40828 100644
--- a/fpga/usrp2/control_lib/Makefile.srcs
+++ b/fpga/usrp2/control_lib/Makefile.srcs
@@ -50,9 +50,4 @@ bootram.v \
nsgpio16LE.v \
settings_bus_16LE.v \
atr_controller16.v \
-newfifo/fifo_pacer.v \
-newfifo/packet_generator32.v \
-newfifo/packet_generator.v \
-newfifo/packet_verifier32.v \
-newfifo/packet_verifier.v \
))
diff --git a/fpga/usrp2/control_lib/newfifo/packet_generator.v b/fpga/usrp2/control_lib/newfifo/packet_generator.v
deleted file mode 100644
index 6e8b45ccd..000000000
--- a/fpga/usrp2/control_lib/newfifo/packet_generator.v
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-module packet_generator
- (input clk, input reset, input clear,
- output reg [7:0] data_o, output sof_o, output eof_o,
- output src_rdy_o, input dst_rdy_i);
-
- localparam len = 32'd2000;
-
- reg [31:0] state;
- reg [31:0] seq;
- wire [31:0] crc_out;
- wire calc_crc = src_rdy_o & dst_rdy_i & ~(state[31:2] == 30'h3FFF_FFFF);
-
-
- always @(posedge clk)
- if(reset | clear)
- seq <= 0;
- else
- if(eof_o & src_rdy_o & dst_rdy_i)
- seq <= seq + 1;
-
- always @(posedge clk)
- if(reset | clear)
- state <= 0;
- else
- if(src_rdy_o & dst_rdy_i)
- if(state == (len - 1))
- state <= 32'hFFFF_FFFC;
- else
- state <= state + 1;
-
- always @*
- case(state)
- 0 : data_o <= len[7:0];
- 1 : data_o <= len[15:8];
- 2 : data_o <= len[23:16];
- 3 : data_o <= len[31:24];
- 4 : data_o <= seq[7:0];
- 5 : data_o <= seq[15:8];
- 6 : data_o <= seq[23:16];
- 7 : data_o <= seq[31:24];
- 32'hFFFF_FFFC : data_o <= crc_out[31:24];
- 32'hFFFF_FFFD : data_o <= crc_out[23:16];
- 32'hFFFF_FFFE : data_o <= crc_out[15:8];
- 32'hFFFF_FFFF : data_o <= crc_out[7:0];
- default : data_o <= state[7:0];
- endcase // case (state)
-
- assign src_rdy_o = 1;
- assign sof_o = (state == 0);
- assign eof_o = (state == 32'hFFFF_FFFF);
-
- wire clear_crc = eof_o & src_rdy_o & dst_rdy_i;
-
- crc crc(.clk(clk), .reset(reset), .clear(clear_crc), .data(data_o),
- .calc(calc_crc), .crc_out(crc_out), .match());
-
-endmodule // packet_generator
diff --git a/fpga/usrp2/control_lib/newfifo/packet_verifier32.v b/fpga/usrp2/control_lib/newfifo/packet_verifier32.v
deleted file mode 100644
index 06a13d242..000000000
--- a/fpga/usrp2/control_lib/newfifo/packet_verifier32.v
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-module packet_verifier32
- (input clk, input reset, input clear,
- input [35:0] data_i, input src_rdy_i, output dst_rdy_o,
- output [31:0] total, output [31:0] crc_err, output [31:0] seq_err, output [31:0] len_err);
-
- wire [7:0] ll_data;
- wire ll_sof_n, ll_eof_n, ll_src_rdy_n, ll_dst_rdy;
- wire [35:0] data_int;
- wire src_rdy_int, dst_rdy_int;
-
- fifo_short #(.WIDTH(36)) fifo_short
- (.clk(clk), .reset(reset), .clear(clear),
- .datain(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o),
- .dataout(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int));
-
- fifo36_to_ll8 f36_to_ll8
- (.clk(clk), .reset(reset), .clear(clear),
- .f36_data(data_int), .f36_src_rdy_i(src_rdy_int), .f36_dst_rdy_o(dst_rdy_int),
- .ll_data(ll_data), .ll_sof_n(ll_sof_n), .ll_eof_n(ll_eof_n),
- .ll_src_rdy_n(ll_src_rdy_n), .ll_dst_rdy_n(~ll_dst_rdy));
-
- packet_verifier pkt_ver
- (.clk(clk), .reset(reset), .clear(clear),
- .data_i(ll_data), .sof_i(~ll_sof_n), .eof_i(~ll_eof_n),
- .src_rdy_i(~ll_src_rdy_n), .dst_rdy_o(ll_dst_rdy),
- .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err));
-
-endmodule // packet_verifier32
diff --git a/fpga/usrp2/extram/.gitignore b/fpga/usrp2/extram/.gitignore
deleted file mode 100644
index 7fc71ccb6..000000000
--- a/fpga/usrp2/extram/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/a.out
diff --git a/fpga/usrp2/extram/Makefile.srcs b/fpga/usrp2/extram/Makefile.srcs
deleted file mode 100644
index 90be02142..000000000
--- a/fpga/usrp2/extram/Makefile.srcs
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Copyright 2010 Ettus Research LLC
-#
-
-##################################################
-# Extram Sources
-##################################################
-EXTRAM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../extram/, \
-wb_zbt16_b.v \
-))
diff --git a/fpga/usrp2/extram/extram_interface.v b/fpga/usrp2/extram/extram_interface.v
deleted file mode 100644
index 7554592ba..000000000
--- a/fpga/usrp2/extram/extram_interface.v
+++ /dev/null
@@ -1,53 +0,0 @@
-
-// Temporary buffer pool storage, mostly useful for pre-generated data streams or
-// for making more space to juggle packets in case of eth frames coming out of order
-
-module extram_interface
- (input clk, input rst,
- input set_stb, input [7:0] set_addr, input [31:0] set_data,
-
- // Buffer pool interfaces
- input [31:0] rd_dat_i, output rd_read_o, output rd_done_o, output rd_error_o,
- input rd_sop_i, input rd_eop_i,
- output [31:0] wr_dat_o, output wr_write_o, output wr_done_o, output wr_error_o,
- input wr_ready_i, input wr_full_i,
-
- // RAM Interface
- inout [17:0] RAM_D,
- output [18:0] RAM_A,
- output RAM_CE1n,
- output RAM_CENn,
- input RAM_CLK,
- output RAM_WEn,
- output RAM_OEn,
- output RAM_LDn );
-
- // Command format --
- // Read/_Write , start address[17:0]
- wire [18:0] cmd_in;
- wire cmd_stb, store_wr_cmd, store_rd_cmd, read_wr_cmd, read_rd_cmd;
- wire empty_wr_cmd, empty_rd_cmd, full_wr_cmd, full_rd_cmd;
-
- // Dummy logic
- assign RAM_OEn = 1;
-
- setting_reg #(.my_addr(0))
- sr_ram_cmd (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(cmd_in),.changed(cmd_stb));
-
- reg cmd_stb_d1;
- always @(posedge clk) cmd_stb_d1 <= cmd_stb;
- assign store_wr_cmd = ~cmd_in[18] & cmd_stb & ~cmd_stb_d1;
- assign store_rd_cmd = cmd_in[18] & cmd_stb & ~cmd_stb_d1;
-
- shortfifo #(.WIDTH(19)) wr_cmd_fifo
- (.clk(clk),.rst(rst),.clear(1'b0),
- .datain(cmd_in), .write(store_wr_cmd), .full(full_wr_cmd),
- .dataout(), .read(read_wr_cmd), .empty(empty_wr_cmd) );
-
- shortfifo #(.WIDTH(19)) rd_cmd_fifo
- (.clk(clk),.rst(rst),.clear(1'b0),
- .datain(cmd_in), .write(store_rd_cmd), .full(full_rd_cmd),
- .dataout(), .read(read_rd_cmd), .empty(empty_rd_cmd) );
-
-endmodule // extram_interface
diff --git a/fpga/usrp2/extram/extram_wb.v b/fpga/usrp2/extram/extram_wb.v
deleted file mode 100644
index c8428783a..000000000
--- a/fpga/usrp2/extram/extram_wb.v
+++ /dev/null
@@ -1,146 +0,0 @@
-
-module extram_wb
- #(parameter PAGE_SIZE = 10,
- parameter ADDR_WIDTH = 16)
- (input clk, input rst,
- input wb_clk, input wb_rst,
- input cyc_i, input stb_i,
- input [ADDR_WIDTH-1:0] adr_i,
- input we_i,
- input [31:0] dat_i,
- output reg [31:0] dat_o,
- output reg ack_o,
-
- inout [17:0] RAM_D,
- output [PAGE_SIZE-2:0] RAM_A,
- output RAM_CE1n, output RAM_CENn,
- output RAM_CLK, output RAM_WEn,
- output RAM_OEn, output RAM_LDn );
-
- wire read_acc = stb_i & cyc_i & ~we_i;
- wire write_acc = stb_i & cyc_i & we_i;
- wire acc = stb_i & cyc_i;
-
- assign RAM_CLK = ~wb_clk; // 50 MHz for now, eventually should be 200 MHz
- assign RAM_LDn = 0; // No burst for now
- assign RAM_CENn = 0; // Use CE1n as our main CE
-
- reg [PAGE_SIZE-2:1] RAM_addr_reg;
- always @(posedge wb_clk)
- if(acc)
- RAM_addr_reg[PAGE_SIZE-2:1] <= adr_i[PAGE_SIZE-1:2];
- assign RAM_A[PAGE_SIZE-2:1] = RAM_addr_reg;
-
- reg [31:0] ram_out;
- always @(posedge wb_clk)
- if(write_acc)
- ram_out <= dat_i;
-
- // RAM access state machine
- localparam RAM_idle = 0;
- localparam RAM_read_1 = 1;
- localparam RAM_read_2 = 2;
- localparam RAM_read_3 = 3;
- localparam RAM_read_4 = 4;
- localparam RAM_write_1 = 6;
- localparam RAM_write_2 = 7;
- localparam RAM_write_3 = 8;
- localparam RAM_write_4 = 9;
-
- reg myOE = 0;
- reg RAM_OE = 0;
- reg RAM_WE = 0;
- reg RAM_EN = 0;
- reg RAM_A0_reg;
- reg [3:0] RAM_state;
-
- always @(posedge wb_clk)
- if(wb_rst)
- begin
- RAM_state <= RAM_idle;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- else
- case(RAM_state)
- RAM_idle :
- if(read_acc & ~ack_o)
- begin
- RAM_state <= RAM_read_1;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 0;
- end
- else if(write_acc & ~ack_o)
- begin
- RAM_state <= RAM_write_1;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 0;
- end
- else
- begin
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_read_1 :
- begin
- RAM_state <= RAM_read_2;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 1;
- end
- RAM_read_2 :
- begin
- RAM_state <= RAM_read_3;
- myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_read_3 :
- begin
- RAM_state <= RAM_read_4;
- myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_read_4 :
- begin
- RAM_state <= RAM_idle;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_write_1 :
- begin
- RAM_state <= RAM_write_2;
- myOE <= 1; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 1;
- end
- RAM_write_2 :
- begin
- RAM_state <= RAM_write_3;
- myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_write_3 :
- begin
- RAM_state <= RAM_write_4;
- myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- RAM_write_4 :
- begin
- RAM_state <= RAM_idle;
- myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
- end
- default : RAM_state <= RAM_idle;
- endcase // case(RAM_state)
-
- assign RAM_A[0] = RAM_A0_reg;
- assign RAM_WEn = ~RAM_WE; // ((RAM_state==RAM_write_1)||(RAM_state==RAM_write_2));
- assign RAM_OEn = ~RAM_OE;
- assign RAM_CE1n = ~RAM_EN; // Active low (RAM_state != RAM_idle);
-
- assign RAM_D[17:16] = 2'bzz;
- assign RAM_D[15:0] = myOE ? ((RAM_state==RAM_write_2)?ram_out[15:0]:ram_out[31:16])
- : 16'bzzzz_zzzz_zzzz_zzzz;
-
- always @(posedge wb_clk)
- if(RAM_state == RAM_read_3)
- dat_o[15:0] <= RAM_D[15:0];
- else
- dat_o[31:16] <= RAM_D[15:0];
-
- always @(posedge wb_clk)
- if(wb_rst)
- ack_o <= 0;
- else if((RAM_state == RAM_write_4)||(RAM_state == RAM_read_4))
- ack_o <= 1;
- else
- ack_o <= 0;
-
-endmodule // extram_wb
diff --git a/fpga/usrp2/extram/wb_zbt16_b.v b/fpga/usrp2/extram/wb_zbt16_b.v
deleted file mode 100644
index d93e21c99..000000000
--- a/fpga/usrp2/extram/wb_zbt16_b.v
+++ /dev/null
@@ -1,63 +0,0 @@
-
-module wb_zbt16_b
- (input clk,
- input rst,
- // Wishbone bus A, highest priority, with prefetch
- input [19:0] wb_adr_i,
- input [15:0] wb_dat_i,
- output reg [15:0] wb_dat_o,
- input [ 1:0] wb_sel_i,
- input wb_cyc_i,
- input wb_stb_i,
- output reg wb_ack_o,
- input wb_we_i,
- // Memory connection
- output sram_clk,
- output [18:0] sram_a,
- inout [15:0] sram_d,
- output sram_we,
- output [ 1:0] sram_bw,
- output sram_adv,
- output sram_ce,
- output sram_oe,
- output sram_mode,
- output sram_zz
- );
-
- assign sram_clk = ~clk;
- //assign sram_oe = 1'b0;
- assign sram_ce = 1'b0;
- assign sram_adv = 1'b0;
- assign sram_mode = 1'b0;
- assign sram_zz = 1'b0;
- assign sram_bw = 2'b0;
-
- // need to drive wb_dat_o, wb_ack_o,
- // sram_a, sram_d, sram_we
- wire myOE;
- assign sram_d = myOE ? wb_dat_i : 16'bzzzz;
- assign sram_a = wb_adr_i[19:1];
-
- reg read_d1, read_d2, read_d3, write_d1, write_d2, write_d3;
- wire acc = wb_cyc_i & wb_stb_i;
- wire read_acc = wb_cyc_i & wb_stb_i & ~wb_we_i & ~read_d1 & ~read_d2 & ~read_d3;
- wire write_acc = wb_cyc_i & wb_stb_i & wb_we_i & ~write_d1 & ~write_d2 & ~write_d3;
-
- assign sram_we = ~write_acc;
- assign sram_oe = ~(read_d2 | read_d3);
- assign myOE = write_d1 | write_d2;
- wire latch_now = read_d2;
-
- always @(posedge clk)
- if(latch_now)
- wb_dat_o <= sram_d;
-
- always @(posedge clk) wb_ack_o <= read_d2 | write_d2;
- always @(posedge clk) read_d1 <= read_acc;
- always @(posedge clk) read_d2 <= read_d1;
- always @(posedge clk) read_d3 <= read_d2;
- always @(posedge clk) write_d1 <= write_acc;
- always @(posedge clk) write_d2 <= write_d1;
- always @(posedge clk) write_d3 <= write_d2;
-endmodule // wb_zbt16_b
-
diff --git a/fpga/usrp2/extramfifo/fifo_extram.v b/fpga/usrp2/extramfifo/fifo_extram.v
deleted file mode 100644
index 4e1f40371..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram.v
+++ /dev/null
@@ -1,188 +0,0 @@
-
-// Everything on sram_clk
-
-module fifo_extram
- (input reset, input clear,
- input [17:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, input [15:0] occ_in,
- output [17:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, input [15:0] space_in,
- input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we,
- output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe,
- output sram_mode, output sram_zz);
-
- localparam AWIDTH = 19; // 1 MB in x18
- localparam RAMSIZE = ((1<<AWIDTH) - 1);
-
- wire do_store, do_retrieve;
- reg [1:0] do_store_del, do_retr_del;
-
- reg [AWIDTH-1:0] addr_retrieve, addr_store;
- always @(posedge sram_clk)
- if(reset | clear)
- addr_retrieve <= 0;
- else if (do_retrieve)
- addr_retrieve <= addr_retrieve + 1;
-
- always @(posedge sram_clk)
- if(reset | clear)
- addr_store <= 0;
- else if(do_store)
- addr_store <= addr_store + 1;
-
- //wire [AWIDTH-1:0] fullness = (addr_store - addr_retrieve);
- reg [AWIDTH-1:0] fullness;
- always @(posedge sram_clk)
- if(reset | clear)
- fullness <= 0;
- else if(do_store)
- fullness <= fullness + 1;
- else if(do_retrieve)
- fullness <= fullness - 1;
-
- // wire empty = (fullness == 0);
- //wire full = (fullness == RAMSIZE); // 19'h7FF);
- reg empty, full;
-
- // The math in the following functions is 'AWIDTH wide. Use
- // continuous assignments to prevent the numbers from being
- // promoted to 32-bit (which would make it wrap wrong).
- //
- wire [AWIDTH-1:0] addr_retrieve_p1, addr_store_p2;
- assign addr_retrieve_p1 = addr_retrieve + 1;
- assign addr_store_p2 = addr_store + 2;
-
- always @(posedge sram_clk)
- if(reset | clear)
- empty <= 1;
- else if(do_store)
- empty <= 0;
- else if(do_retrieve & (/*(addr_retrieve + 1)*/ addr_retrieve_p1 == addr_store))
- empty <= 1;
-
- always @(posedge sram_clk)
- if(reset | clear)
- full <= 0;
- else if(do_retrieve)
- full <= 0;
- else if(do_store & (/*(addr_store+2)*/ addr_store_p2 == addr_retrieve))
- full <= 1;
-
- reg can_store;
- always @*
- if(full | ~src_rdy_i)
- can_store <= 0;
- else if(do_store_del == 0)
- can_store <= 1;
- else if((do_store_del == 1) || (do_store_del == 2))
- can_store <= (occ_in > 1);
- else
- can_store <= (occ_in > 2);
-
- reg can_retrieve;
- always @*
- if(empty | ~dst_rdy_i)
- can_retrieve <= 0;
- else if(do_retr_del == 0)
- can_retrieve <= 1;
- else if((do_retr_del == 1) || (do_retr_del == 2))
- can_retrieve <= (space_in > 1);
- else
- can_retrieve <= (space_in > 2);
-
- reg [1:0] state;
- localparam IDLE_STORE_NEXT = 0;
- localparam STORE = 1;
- localparam IDLE_RETR_NEXT = 2;
- localparam RETRIEVE = 3;
-
- reg [7:0] countdown;
- wire countdown_done = (countdown == 0);
-
- localparam CYCLE_SIZE = 6;
-
- assign do_store = can_store & (state == STORE);
- assign do_retrieve = can_retrieve & (state == RETRIEVE);
- always @(posedge sram_clk)
- if(reset)
- do_store_del <= 0;
- else
- do_store_del <= {do_store_del[0],do_store};
-
- always @(posedge sram_clk)
- if(reset)
- do_retr_del <= 0;
- else
- do_retr_del <= {do_retr_del[0],do_retrieve};
-
- always @(posedge sram_clk)
- if(reset | clear)
- begin
- state <= IDLE_STORE_NEXT;
- countdown <= 0;
- end
- else
- case(state)
- IDLE_STORE_NEXT :
- if(can_store)
- begin
- state <= STORE;
- countdown <= CYCLE_SIZE;
- end
- else if(can_retrieve)
- begin
- state <= RETRIEVE;
- countdown <= CYCLE_SIZE;
- end
- STORE :
- if(~can_store | (can_retrieve & countdown_done))
- state <= IDLE_RETR_NEXT;
- else if(~countdown_done)
- countdown <= countdown - 1;
- IDLE_RETR_NEXT :
- if(can_retrieve)
- begin
- state <= RETRIEVE;
- countdown <= CYCLE_SIZE;
- end
- else if(can_store)
- begin
- state <= STORE;
- countdown <= CYCLE_SIZE;
- end
- RETRIEVE :
- if(~can_retrieve | (can_store & countdown_done))
- state <= IDLE_STORE_NEXT;
- else if(~countdown_done)
- countdown <= countdown - 1;
- endcase // case (state)
-
- // RAM wires
- assign sram_bw = 0;
- assign sram_adv = 0;
- assign sram_mode = 0;
- assign sram_zz = 0;
- assign sram_ce = 0;
-
- assign sram_a = (state==STORE) ? addr_store : addr_retrieve;
- assign sram_we = ~do_store;
- assign sram_oe = ~do_retr_del[1];
- assign my_oe = do_store_del[1] & sram_oe;
- assign sram_d = my_oe ? datain : 18'bz;
-
- // FIFO wires
- assign dataout = sram_d;
- assign src_rdy_o = do_retr_del[1];
- assign dst_rdy_o = do_store_del[1];
-
-endmodule // fifo_extram
-
-
- //wire have_1 = (fullness == 1);
- //wire have_2 = (fullness == 2);
- //wire have_atleast_1 = ~empty;
- //wire have_atleast_2 = ~(empty | have_1);
- //wire have_atleast_3 = ~(empty | have_1 | have_2);
- //wire full_minus_1 = (fullness == (RAMSIZE-1)); // 19'h7FE);
- //wire full_minus_2 = (fullness == (RAMSIZE-2)); // 19'h7FD);
- //wire spacefor_atleast_1 = ~full;
- //wire spacefor_atleast_2 = ~(full | full_minus_1);
- //wire spacefor_atleast_3 = ~(full | full_minus_1 | full_minus_2);
diff --git a/fpga/usrp2/extramfifo/fifo_extram36.v b/fpga/usrp2/extramfifo/fifo_extram36.v
deleted file mode 100644
index 29342fdc4..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram36.v
+++ /dev/null
@@ -1,47 +0,0 @@
-
-// 18 bit interface means we either can't handle errors or can't handle odd lengths
-// unless we go to heroic measures
-
-module fifo_extram36
- (input clk, input reset, input clear,
- input [35:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space,
- output [35:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied,
- input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we,
- output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe, output sram_mode,
- output sram_zz);
-
- wire [17:0] f18_data_1, f18_data_2, f18_data_3, f18_data_4;
- wire f18_src_rdy_1, f18_dst_rdy_1, f18_src_rdy_2, f18_dst_rdy_2;
- wire f18_src_rdy_3, f18_dst_rdy_3, f18_src_rdy_4, f18_dst_rdy_4;
-
- fifo36_to_fifo18 f36_to_f18
- (.clk(clk), .reset(reset), .clear(clear),
- .f36_datain(datain), .f36_src_rdy_i(src_rdy_i), .f36_dst_rdy_o(dst_rdy_o),
- .f18_dataout(f18_data_1), .f18_src_rdy_o(f18_src_rdy_1), .f18_dst_rdy_i(f18_dst_rdy_1) );
-
- wire [15:0] f1_occ, f2_space;
-
- fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_in
- (.wclk(clk), .datain(f18_data_1), .src_rdy_i(f18_src_rdy_1), .dst_rdy_o(f18_dst_rdy_1), .space(),
- .rclk(sram_clk), .dataout(f18_data_2), .src_rdy_o(f18_src_rdy_2), .dst_rdy_i(f18_dst_rdy_2), .short_occupied(f1_occ),
- .arst(reset) );
-
- fifo_extram fifo_extram
- (.reset(reset), .clear(clear),
- .datain(f18_data_2), .src_rdy_i(f18_src_rdy_2), .dst_rdy_o(f18_dst_rdy_2), .space(), .occ_in(f1_occ),
- .dataout(f18_data_3), .src_rdy_o(f18_src_rdy_3), .dst_rdy_i(f18_dst_rdy_3), .occupied(), .space_in(f2_space),
- .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
- .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
- .sram_mode(sram_mode), .sram_zz(sram_zz));
-
- fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_out
- (.wclk(sram_clk), .datain(f18_data_3), .src_rdy_i(f18_src_rdy_3), .dst_rdy_o(f18_dst_rdy_3), .short_space(f2_space),
- .rclk(clk), .dataout(f18_data_4), .src_rdy_o(f18_src_rdy_4), .dst_rdy_i(f18_dst_rdy_4), .occupied(),
- .arst(reset) );
-
- fifo18_to_fifo36 f18_to_f36
- (.clk(clk), .reset(reset), .clear(clear),
- .f18_datain(f18_data_4), .f18_src_rdy_i(f18_src_rdy_4), .f18_dst_rdy_o(f18_dst_rdy_4),
- .f36_dataout(dataout), .f36_src_rdy_o(src_rdy_o), .f36_dst_rdy_i(dst_rdy_i) );
-
-endmodule // fifo_extram36
diff --git a/fpga/usrp2/extramfifo/fifo_extram36_tb.build b/fpga/usrp2/extramfifo/fifo_extram36_tb.build
deleted file mode 100755
index ac9369758..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram36_tb.build
+++ /dev/null
@@ -1 +0,0 @@
-iverilog -y ../models -y . -y ../control_lib/ -y ../coregen -y ../fifo -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram36_tb fifo_extram36_tb.v
diff --git a/fpga/usrp2/extramfifo/fifo_extram36_tb.v b/fpga/usrp2/extramfifo/fifo_extram36_tb.v
deleted file mode 100644
index e5f8cef4c..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram36_tb.v
+++ /dev/null
@@ -1,475 +0,0 @@
-`timescale 1ns/1ns
-
-module fifo_extram36_tb();
-
- reg clk = 0;
- reg sram_clk = 0;
- reg rst = 1;
- reg clear = 0;
-
- reg Verbose = 0; //
- integer ErrorCount = 0;
-
- initial #1000 rst = 0;
-// always #125 clk = ~clk;
- task task_CLK;
- reg [7:0] ran;
- begin
- while (1) begin
- ran = $random;
- if (ran[1])
- #62 clk = ~clk;
- else
- #63 clk = !clk;
- end
- end
- endtask // task_CLK
- initial task_CLK;
-
-// always #100 sram_clk = ~sram_clk;
- task task_SSRAM_clk;
- reg [7:0] ran;
- begin
- while (1) begin
- ran = $random;
- if (ran[0])
- #49 sram_clk = ~sram_clk;
- else
- #51 sram_clk = ~sram_clk;
- end
- end
- endtask // task_SSRAM_clk
- initial task_SSRAM_clk;
-
- reg [31:0] f36_data = 32'hX;
- reg [1:0] f36_occ = 0;
- reg f36_sof = 0, f36_eof = 0;
-
- wire [35:0] f36_in = {1'b0,f36_occ,f36_eof,f36_sof,f36_data};
- reg src_rdy_f36i = 0;
- wire dst_rdy_f36i;
-
- wire [35:0] f36_out;
- wire src_rdy_f36o;
- reg dst_rdy_f36o = 0;
-
- wire [17:0] sram_d;
- wire [18:0] sram_a;
- wire [1:0] sram_bw;
- wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz;
-
- reg [31:0] ScoreBoard [524288:0];
- reg [18:0] put_index = 0;
- reg [18:0] get_index = 0;
-
-// integer put_index = 0;
-// integer get_index = 0;
-
- wire [15:0] DUT_space, DUT_occupied;
-
- fifo_extram36 fifo_extram36
- (.clk(clk), .reset(rst), .clear(clear),
- .datain(f36_in), .src_rdy_i(src_rdy_f36i), .dst_rdy_o(dst_rdy_f36i), .space(DUT_space),
- .dataout(f36_out), .src_rdy_o(src_rdy_f36o), .dst_rdy_i(dst_rdy_f36o), .occupied(DUT_occupied),
- .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
- .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
- .sram_mode(sram_mode), .sram_zz(sram_zz));
-
-`define idt 1
-`ifdef idt
- wire [15:0] dummy16;
- wire [1:0] dummy2;
-
- idt71v65603s150
- ram_model(.A(sram_a[17:0]),
- .adv_ld_(sram_adv), // advance (high) / load (low)
- .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low)
- .ce1_(0), .ce2(1), .ce2_(0), // chip enables
- .cen_(sram_ce), // clock enable (low)
- .clk(sram_clk), // clock
- .IO({dummy16,sram_d[15:0]}),
- .IOP({dummy2,sram_d[17:16]}), // data bus
- .lbo_(sram_mode), // linear burst order (low)
- .oe_(sram_oe), // output enable (low)
- .r_w_(sram_we)); // read (high) / write (low)
-`else
- cy1356 ram_model(.d(sram_d),.clk(~sram_clk),.a(sram_a),
- .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv),
- .ce1b(0),.ce2(1),.ce3b(0),
- .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) );
-`endif
-
- task task_SSRAMMonitor;
- reg last_mode;
- reg last_clock;
- reg last_load;
- reg [18:0] sram_addr;
-
- begin
- last_mode = 1'bX;
- last_clock = 1'bX;
- last_load = 1'bX;
-
- @ (posedge Verbose);
- $dumpvars(0,fifo_extram36_tb);
-
- $display("%t:%m\t*** Task Started",$time);
- while (1) @ (posedge sram_clk) begin
- if (sram_mode !== last_mode) begin
- $display("%t:%m\tSSRAM mode: %b",$time,sram_mode);
- last_mode = sram_mode;
- end
- if (sram_adv !== last_load) begin
- $display("%t:%m\tSSRAM adv/load: %b",$time,sram_adv);
- last_load = sram_adv;
- end
- if (sram_ce !== last_clock) begin
- $display("%t:%m\tSSRAM clock enable: %b",$time,sram_ce);
- last_clock = sram_ce;
- end
- if (sram_ce == 1'b0) begin
- if (sram_adv == 1'b0) begin
-// $display("%t:%m\tSSRAM Address Load A=%h",$time,sram_a);
- sram_addr = sram_a;
- end else begin
- sram_addr = sram_addr + 1;
- end
- if (sram_oe == 1'b0) begin
- $display("%t:%m\tSSRAM Read Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d);
- end
- if (sram_we == 1'b0) begin
- $display("%t:%m\tSSRAM Write Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d);
- end
- if ((sram_we == 1'b0) && (sram_oe == 1'b0)) begin
- $display("%t:%m\t*** ERROR: _oe and _we both active",$time);
- end
-
- end // if (sram_ce == 1'b0)
-
- end // always @ (posedge sram_clk)
- end
- endtask // task_SSRAMMonitor
-
- task ReadFromFIFO36;
- begin
- $display("%t: Read from FIFO36",$time);
- #1 dst_rdy_f36o <= 1;
- while(1)
- begin
- while(~src_rdy_f36o)
- @(posedge clk);
- $display("%t: Read: %h>",$time,f36_out);
- @(posedge clk);
- end
- end
- endtask // ReadFromFIFO36
-
- initial dst_rdy_f36o = 0;
-
- task task_ReadFIFO36;
- reg [7:0] ran;
- begin
- $display("%t:%m\t*** Task Started",$time);
- while (1) begin
- // Read on one of four clocks
- #5 dst_rdy_f36o <= 1;
- @(posedge clk);
- if (src_rdy_f36o) begin
- if (f36_out[31:0] != ScoreBoard[get_index]) begin
- $display("%t:%m\tFIFO Get Error: R:%h, E:%h (%h)",$time,f36_out[31:0],ScoreBoard[get_index],get_index);
- ErrorCount = ErrorCount + 1;
- end else begin
- if (Verbose)
- $display("%t:%m\t(%5h) %o>",$time,get_index,f36_out);
- end
- get_index = get_index+1;
- end else begin
- if (ErrorCount >= 192)
- $finish;
- end // else: !if(src_rdy_f36o)
-
- #10;
- ran = $random;
- if (ran[2:0] != 3'b000) begin
- dst_rdy_f36o <= 0;
- if (ran[2] != 1'b0) begin
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- end
- if (ran[1] != 1'b0) begin
- @(posedge clk);
- @(posedge clk);
- end
- if (ran[0] != 1'b0) begin
- @(posedge clk);
- end
- end
- end // while (1)
- end
-
- endtask // task_ReadFIFO36
-
-
- reg [15:0] count;
-
- task PutPacketInFIFO36;
- input [31:0] data_start;
- input [31:0] data_len;
-
- begin
- count = 4;
- src_rdy_f36i = 1;
- f36_data = data_start;
- f36_sof = 1;
- f36_eof = 0;
- f36_occ = 0;
-
- $display("%t: Put Packet in FIFO36",$time);
- while(~dst_rdy_f36i)
- #1; //@(posedge clk);
- @(posedge clk);
-
- $display("%t: <%h PPI_FIFO36: Entered First Line",$time,f36_data);
- f36_sof <= 0;
- while(count+4 < data_len)
- begin
- f36_data = f36_data + 32'h01010101;
- count = count + 4;
- while(~dst_rdy_f36i)
- #1; //@(posedge clk);
- @(posedge clk);
- $display("%t: <%h PPI_FIFO36: Entered New Line",$time,f36_data);
- end
- f36_data <= f36_data + 32'h01010101;
- f36_eof <= 1;
- if(count + 4 == data_len)
- f36_occ <= 0;
- else if(count + 3 == data_len)
- f36_occ <= 3;
- else if(count + 2 == data_len)
- f36_occ <= 2;
- else
- f36_occ <= 1;
- while(~dst_rdy_f36i)
- @(posedge clk);
- @(posedge clk);
- f36_occ <= 0;
- f36_eof <= 0;
- f36_data <= 0;
- src_rdy_f36i <= 0;
- $display("%t: <%h PPI_FIFO36: Entered Last Line",$time,f36_data);
- end
- endtask // PutPacketInFIFO36
-
- task task_WriteFIFO36;
- integer i;
- reg [7:0] ran;
-
- begin
- f36_data = 32'bX;
- if (rst != 1'b0)
- @ (negedge rst);
- $display("%t:%m\t*** Task Started",$time);
- #10;
- src_rdy_f36i = 1;
- f36_data = $random;
- for (i=0; i<64; i=i+0 ) begin
- @ (posedge clk) ;
- if (dst_rdy_f36i) begin
- if (Verbose)
- $display("%t:%m\t(%5h) %o<",$time,put_index,f36_in);
- ScoreBoard[put_index] = f36_in[31:0];
- put_index = put_index + 1;
- #5;
- f36_data = $random;
- i = i + 1;
- end
- ran = $random;
- if (ran[1:0] != 2'b00) begin
- @ (negedge clk);
- src_rdy_f36i = 0;
- #5;
- @ (negedge clk) ;
- src_rdy_f36i = 1;
- end
- end
- src_rdy_f36i = 0;
- f36_data = 32'bX;
-// if (put_index > 19'h3ff00)
-// Verbose = 1'b1;
-
- end
- endtask // task_WriteFIFO36
-
- initial $dumpfile("fifo_extram36_tb.vcd");
-// initial $dumpvars(0,fifo_extram36_tb);
- initial $timeformat(-9, 0, " ns", 10);
- initial task_SSRAMMonitor;
-
- initial
- begin
- @(negedge rst);
- #40000;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
-// ReadFromFIFO36;
- task_ReadFIFO36;
-
- end
-
- integer i;
-
- initial
- begin
- @(negedge rst);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- task_WriteFIFO36;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
-// PutPacketInFIFO36(32'hA0B0C0D0,12);
- @(posedge clk);
- @(posedge clk);
- #10000;
- @(posedge clk);
-// PutPacketInFIFO36(32'hE0F0A0B0,36);
- @(posedge clk);
- @(posedge clk);
- task_WriteFIFO36;
- @(posedge clk);
- @(posedge clk);
- #10000;
- @(posedge clk);
- @(posedge clk);
- task_WriteFIFO36;
-// @(posedge clk);
-// #30000;
-// @(posedge clk);
-// @(posedge clk);
- task_WriteFIFO36;
-// @(posedge clk);
-// #30000;
-// @(posedge clk);
-// @(posedge clk);
- task_WriteFIFO36;
-// @(posedge clk);
-// #30000;
-// @(posedge clk);
-// @(posedge clk);
- task_WriteFIFO36;
- @(posedge clk);
- #10000;
- @(posedge clk);
- @(posedge clk);
- task_WriteFIFO36;
- for (i=0; i<8192; i = i+1) begin
- @(posedge clk);
- #10000;
- @(posedge clk);
- @(posedge clk);
- task_WriteFIFO36;
- @(posedge clk);
- end
-
-// $dumpvars(0,fifo_extram36_tb);
- @(posedge clk);
- task_WriteFIFO36;
- @(posedge clk);
-
- #100000000;
- $finish;
-
- end
-
-
- initial
- begin
- @(negedge rst);
- f36_occ <= 0;
- repeat (100)
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= 32'h10203040;
- f36_sof <= 1;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= f36_data + 32'h01010101;
- f36_sof <= 0;
- f36_eof <= 0;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 1;
- f36_data <= 32'h1F2F3F4F;
- f36_sof <= 0;
- f36_eof <= 1;
- @(posedge clk);
- @(posedge clk);
- src_rdy_f36i <= 0;
-
-
-
- end
-
-// initial #500000 $finish;
-endmodule // fifo_extram_tb
diff --git a/fpga/usrp2/extramfifo/fifo_extram_tb.build b/fpga/usrp2/extramfifo/fifo_extram_tb.build
deleted file mode 100755
index 5607c8691..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram_tb.build
+++ /dev/null
@@ -1 +0,0 @@
-iverilog -y ../models -y . -y ../control_lib/ -y ../coregen -y ../fifo -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram_tb fifo_extram_tb.v
diff --git a/fpga/usrp2/extramfifo/fifo_extram_tb.v b/fpga/usrp2/extramfifo/fifo_extram_tb.v
deleted file mode 100644
index 73550d9ca..000000000
--- a/fpga/usrp2/extramfifo/fifo_extram_tb.v
+++ /dev/null
@@ -1,134 +0,0 @@
-module fifo_extram_tb();
-
- reg clk = 0;
- reg sram_clk = 0;
- reg reset = 1;
- reg clear = 0;
-
- initial #1000 reset = 0;
- always #125 clk = ~clk;
- always #100 sram_clk = ~sram_clk;
-
- reg [15:0] f18_data = 0;
- reg f18_sof = 0, f18_eof = 0;
-
- wire [17:0] f18_in = {f18_eof,f18_sof,f18_data};
- reg src_rdy_f18i = 0;
- wire dst_rdy_f18i;
-
- wire [17:0] f18_out;
- wire src_rdy_f18o;
- reg dst_rdy_f18o = 0;
-
- wire [17:0] f18_int;
- wire src_rdy_f18int, dst_rdy_f18int;
-
- wire [17:0] sram_d;
- wire [18:0] sram_a;
- wire [1:0] sram_bw;
- wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz;
- wire [15:0] f1_occ;
-
- fifo_short #(.WIDTH(18)) fifo_short
- (.clk(sram_clk), .reset(reset), .clear(clear),
- .datain(f18_in), .src_rdy_i(src_rdy_f18i), .dst_rdy_o(dst_rdy_f18i), .space(),
- .dataout(f18_int), .src_rdy_o(src_rdy_f18int), .dst_rdy_i(dst_rdy_f18int), .occupied(f1_occ[4:0]) );
-
- assign f1_occ[15:5] = 0;
-
- fifo_extram fifo_extram
- (.reset(reset), .clear(clear),
- .datain(f18_int), .src_rdy_i(src_rdy_f18int), .dst_rdy_o(dst_rdy_f18int), .space(), .occ_in(f1_occ),
- .dataout(f18_out), .src_rdy_o(src_rdy_f18o), .dst_rdy_i(dst_rdy_f18o), .occupied(), .space_in(7),
- .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we),
- .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe),
- .sram_mode(sram_mode), .sram_zz(sram_zz));
-
-`define idt 1
-`ifdef idt
- wire [15:0] dummy16;
- wire [1:0] dummy2;
-
- idt71v65603s150
- ram_model(.A(sram_a[17:0]),
- .adv_ld_(sram_adv), // advance (high) / load (low)
- .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low)
- .ce1_(0), .ce2(1), .ce2_(0), // chip enables
- .cen_(sram_ce), // clock enable (low)
- .clk(sram_clk), // clock
- .IO({dummy16,sram_d[15:0]}),
- .IOP({dummy2,sram_d[17:16]}), // data bus
- .lbo_(sram_mode), // linear burst order (low)
- .oe_(sram_oe), // output enable (low)
- .r_w_(sram_we)); // read (high) / write (low)
-`else
- cy1356 ram_model(.d(sram_d),.clk(sram_clk),.a(sram_a),
- .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv),
- .ce1b(0),.ce2(1),.ce3b(0),
- .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) );
-`endif // !`ifdef idt
-
- always @(posedge sram_clk)
- if(dst_rdy_f18o & src_rdy_f18o)
- $display("Read: %h",f18_out);
-
- always @(posedge sram_clk)
- if(dst_rdy_f18int & src_rdy_f18int)
- $display("Write: %h",f18_int);
-
- initial $dumpfile("fifo_extram_tb.vcd");
- initial $dumpvars(0,fifo_extram_tb);
-
- task SendPkt;
- input [15:0] data_start;
- input [31:0] data_len;
- begin
- @(posedge sram_clk);
- f18_data = data_start;
- f18_sof = 1;
- f18_eof = 0;
- src_rdy_f18i = 1;
- while(~dst_rdy_f18i)
- #1;
- @(posedge sram_clk);
- repeat(data_len - 2)
- begin
- f18_data = f18_data + 16'h0101;
- f18_sof = 0;
- while(~dst_rdy_f18i)
- @(posedge sram_clk);
-
- @(posedge sram_clk);
- end
- f18_data = f18_data + 16'h0101;
- f18_eof = 1;
- while(~dst_rdy_f18i)
- #1;
- @(posedge sram_clk);
- src_rdy_f18i = 0;
- f18_data = 0;
- f18_eof = 0;
- end
- endtask // SendPkt
-
- initial
- begin
- @(negedge reset);
- @(posedge sram_clk);
- @(posedge sram_clk);
- #10000;
- @(posedge sram_clk);
- SendPkt(16'hA0B0, 100);
- #10000;
- //SendPkt(16'hC0D0, 220);
- end
-
- initial
- begin
- #20000;
- dst_rdy_f18o = 1;
- end
-
- initial #200000 $finish;
-endmodule // fifo_extram_tb
-
diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs
index f0b5b7bae..31b1f505a 100644
--- a/fpga/usrp2/fifo/Makefile.srcs
+++ b/fpga/usrp2/fifo/Makefile.srcs
@@ -28,4 +28,10 @@ fifo36_demux.v \
packet_router.v \
splitter36.v \
valve36.v \
+fifo_pacer.v \
+packet_dispatcher36_x3.v \
+packet_generator32.v \
+packet_generator.v \
+packet_verifier32.v \
+packet_verifier.v \
))
diff --git a/fpga/usrp2/fifo/buffer_int2.v b/fpga/usrp2/fifo/buffer_int2.v
index 765b125fb..532980aa2 100644
--- a/fpga/usrp2/fifo/buffer_int2.v
+++ b/fpga/usrp2/fifo/buffer_int2.v
@@ -31,13 +31,15 @@ module buffer_int2
input rd_ready_i
);
- reg [BUF_SIZE-1:0] rd_addr, wr_addr;
+ reg [15:0] rd_addr, wr_addr; // Handle pkt bigger than buffer
+ wire [15:0] rd_addr_next = rd_addr + 1;
+ reg [15:0] rd_length;
+
wire [31:0] ctrl;
wire wr_done, wr_error, wr_idle;
wire rd_done, rd_error, rd_idle;
wire we, en, go;
- reg [BUF_SIZE-1:0] lastline;
wire read = ctrl[3];
wire rd_clear = ctrl[2];
wire write = ctrl[1];
@@ -72,13 +74,13 @@ module buffer_int2
begin
rd_addr <= 0;
rd_state <= PRE_READ;
- lastline <= ctrl[15+BUF_SIZE:16];
+ rd_length <= ctrl[31:16];
end
PRE_READ :
begin
rd_state <= READING;
- rd_addr <= rd_addr + 1;
+ rd_addr <= rd_addr_next;
rd_occ <= 2'b00;
rd_sop <= 1;
rd_eop <= 0;
@@ -88,8 +90,8 @@ module buffer_int2
if(rd_ready_i)
begin
rd_sop <= 0;
- rd_addr <= rd_addr + 1;
- if(rd_addr == lastline)
+ rd_addr <= rd_addr_next;
+ if(rd_addr_next == rd_length)
begin
rd_eop <= 1;
// FIXME assign occ here
@@ -145,17 +147,19 @@ module buffer_int2
assign rd_idle = (rd_state == IDLE);
assign wr_idle = (wr_state == IDLE);
+ wire [BUF_SIZE-1:0] wr_addr_clip = (|wr_addr[15:BUF_SIZE]) ? {BUF_SIZE{1'b1}} : wr_addr[BUF_SIZE-1:0];
+
ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_in // CPU reads here
(.clka(wb_clk_i),.ena(wb_stb_i),.wea(1'b0),
.addra(wb_adr_i[BUF_SIZE+1:2]),.dia(0),.doa(wb_dat_o),
.clkb(clk),.enb(1'b1),.web(we),
- .addrb(wr_addr),.dib(wr_data_i[31:0]),.dob());
+ .addrb(wr_addr_clip),.dib(wr_data_i[31:0]),.dob());
ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer_out // CPU writes here
(.clka(wb_clk_i),.ena(wb_stb_i),.wea(wb_we_i),
.addra(wb_adr_i[BUF_SIZE+1:2]),.dia(wb_dat_i),.doa(),
.clkb(clk),.enb(en),.web(1'b0),
- .addrb(rd_addr),.dib(0),.dob(rd_data_o[31:0]));
+ .addrb(rd_addr[BUF_SIZE-1:0]),.dib(0),.dob(rd_data_o[31:0]));
always @(posedge wb_clk_i)
if(wb_rst_i)
@@ -167,7 +171,7 @@ module buffer_int2
sreg(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(ctrl),.changed(go));
- assign status = { {(16-BUF_SIZE){1'b0}},wr_addr,
+ assign status = { wr_addr,
8'b0,1'b0,rd_idle,rd_error,rd_done, 1'b0,wr_idle,wr_error,wr_done};
endmodule // buffer_int2
diff --git a/fpga/usrp2/fifo/dsp_framer36.v b/fpga/usrp2/fifo/dsp_framer36.v
index 34a05d91e..c2ae8f96c 100644
--- a/fpga/usrp2/fifo/dsp_framer36.v
+++ b/fpga/usrp2/fifo/dsp_framer36.v
@@ -2,97 +2,67 @@
// Frame DSP packets with a header line to be handled by the protocol machine
module dsp_framer36
- #(parameter BUF_SIZE = 9)
- (
- input clk, input rst, input clr,
- input [35:0] inp_data, input inp_valid, output inp_ready,
- output [35:0] out_data, output out_valid, input out_ready
- );
+ #(parameter BUF_SIZE = 9,
+ parameter PORT_SEL = 0)
+ (input clk, input reset, input clear,
+ input [35:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
- localparam DSP_FRM_STATE_WAIT_SOF = 0;
- localparam DSP_FRM_STATE_WAIT_EOF = 1;
- localparam DSP_FRM_STATE_WRITE_HDR = 2;
- localparam DSP_FRM_STATE_WRITE = 3;
+ wire dfifo_in_dst_rdy, dfifo_in_src_rdy, dfifo_out_dst_rdy, dfifo_out_src_rdy;
+ wire tfifo_in_dst_rdy, tfifo_in_src_rdy, tfifo_out_dst_rdy, tfifo_out_src_rdy;
- reg [1:0] dsp_frm_state;
- reg [BUF_SIZE-1:0] dsp_frm_addr;
- reg [BUF_SIZE-1:0] dsp_frm_count;
- wire [BUF_SIZE-1:0] dsp_frm_addr_next = dsp_frm_addr + 1'b1;
+ wire do_xfer_in = dfifo_in_src_rdy & dfifo_in_dst_rdy;
+ wire do_xfer_out = src_rdy_o & dst_rdy_i;
+
+ wire have_space = dfifo_in_dst_rdy & tfifo_in_dst_rdy;
+ reg [15:0] pkt_len_in, pkt_len_out;
+ wire [15:0] tfifo_data;
+ wire [35:0] dfifo_out_data;
+
+ assign dst_rdy_o = have_space;
+ assign dfifo_in_src_rdy = src_rdy_i & have_space;
+
+ fifo_cascade #(.WIDTH(36), .SIZE(BUF_SIZE)) dfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data_i), .src_rdy_i(dfifo_in_src_rdy), .dst_rdy_o(dfifo_in_dst_rdy),
+ .dataout(dfifo_out_data), .src_rdy_o(dfifo_out_src_rdy), .dst_rdy_i(dfifo_out_dst_rdy) );
- //DSP input stream ready in the following states
- assign inp_ready = (
- dsp_frm_state == DSP_FRM_STATE_WAIT_SOF ||
- dsp_frm_state == DSP_FRM_STATE_WAIT_EOF
- )? 1'b1 : 1'b0;
+ fifo_short #(.WIDTH(16)) tfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(pkt_len_in), .src_rdy_i(tfifo_in_src_rdy), .dst_rdy_o(tfifo_in_dst_rdy),
+ .dataout(tfifo_data), .src_rdy_o(tfifo_out_src_rdy), .dst_rdy_i(tfifo_out_dst_rdy),
+ .space(), .occupied() );
- //DSP framer output data mux (header or BRAM):
- //The header is generated here from the count.
- wire [31:0] dsp_frm_data_bram;
- wire [15:0] dsp_frm_bytes = {dsp_frm_count, 2'b00};
- assign out_data =
- (dsp_frm_state == DSP_FRM_STATE_WRITE_HDR)? {4'b0001, 16'b1, dsp_frm_bytes} : (
- (dsp_frm_addr == dsp_frm_count) ? {4'b0010, dsp_frm_data_bram} : (
- {4'b0000, dsp_frm_data_bram}));
- assign out_valid = (
- (dsp_frm_state == DSP_FRM_STATE_WRITE_HDR) ||
- (dsp_frm_state == DSP_FRM_STATE_WRITE)
- )? 1'b1 : 1'b0;
+ // FIXME won't handle single-line packets, will show wrong length
+ always @(posedge clk)
+ if(reset | clear)
+ pkt_len_in <= 0;
+ else if(do_xfer_in)
+ if(data_i[32]) // sof
+ pkt_len_in <= 2; // fixes off by one since number is stored before increment
+ else
+ pkt_len_in <= pkt_len_in + 1;
- RAMB16_S36_S36 dsp_frm_buff(
- //port A = DSP input interface (writes to BRAM)
- .DOA(),.ADDRA(dsp_frm_addr),.CLKA(clk),.DIA(inp_data[31:0]),.DIPA(4'h0),
- .ENA(inp_ready & inp_valid),.SSRA(0),.WEA(inp_ready & inp_valid),
- //port B = DSP framer interface (reads from BRAM)
- .DOB(dsp_frm_data_bram),.ADDRB(dsp_frm_addr),.CLKB(clk),.DIB(36'b0),.DIPB(4'h0),
- .ENB(out_ready & out_valid),.SSRB(0),.WEB(1'b0)
- );
+ assign tfifo_in_src_rdy = do_xfer_in & data_i[33]; // store length when at eof in
+ assign tfifo_out_dst_rdy = do_xfer_out & data_o[33]; // remove length from list at eof out
- always @(posedge clk)
- if(rst | clr) begin
- dsp_frm_state <= DSP_FRM_STATE_WAIT_SOF;
- dsp_frm_addr <= 0;
- end
- else begin
- case(dsp_frm_state)
- DSP_FRM_STATE_WAIT_SOF: begin
- if (inp_ready & inp_valid & inp_data[32]) begin
- dsp_frm_addr <= dsp_frm_addr_next;
- dsp_frm_state <= DSP_FRM_STATE_WAIT_EOF;
- end
- end
+ always @(posedge clk)
+ if(reset | clear)
+ pkt_len_out <= 0;
+ else if(do_xfer_out)
+ if(dfifo_out_data[33]) // eof
+ pkt_len_out <= 0;
+ else
+ pkt_len_out <= pkt_len_out + 1;
+
+ assign dfifo_out_dst_rdy = do_xfer_out & (pkt_len_out != 0);
- DSP_FRM_STATE_WAIT_EOF: begin
- if (inp_ready & inp_valid) begin
- if (inp_data[33]) begin
- dsp_frm_count <= dsp_frm_addr_next;
- dsp_frm_addr <= 0;
- dsp_frm_state <= DSP_FRM_STATE_WRITE_HDR;
- end
- else begin
- dsp_frm_addr <= dsp_frm_addr_next;
- end
- end
- end
+ wire [1:0] port_sel_bits = PORT_SEL;
+
+ assign data_o = (pkt_len_out == 0) ? {4'b0001, 13'b0, port_sel_bits, 1'b1, tfifo_data[13:0],2'b00} :
+ (pkt_len_out == 1) ? {4'b0000, dfifo_out_data[31:16],tfifo_data} :
+ {dfifo_out_data[35:33], 1'b0, dfifo_out_data[31:0] };
- DSP_FRM_STATE_WRITE_HDR: begin
- if (out_ready & out_valid) begin
- dsp_frm_addr <= dsp_frm_addr_next;
- dsp_frm_state <= DSP_FRM_STATE_WRITE;
- end
- end
-
- DSP_FRM_STATE_WRITE: begin
- if (out_ready & out_valid) begin
- if (out_data[33]) begin
- dsp_frm_addr <= 0;
- dsp_frm_state <= DSP_FRM_STATE_WAIT_SOF;
- end
- else begin
- dsp_frm_addr <= dsp_frm_addr_next;
- end
- end
- end
- endcase //dsp_frm_state
- end
-
-endmodule //dsp_framer36
+ assign src_rdy_o = dfifo_out_src_rdy & tfifo_out_src_rdy;
+
+endmodule // dsp_framer36
diff --git a/fpga/usrp2/fifo/fifo18_to_fifo36.v b/fpga/usrp2/fifo/fifo18_to_fifo36.v
deleted file mode 100644
index 25bb215a1..000000000
--- a/fpga/usrp2/fifo/fifo18_to_fifo36.v
+++ /dev/null
@@ -1,20 +0,0 @@
-
-// For now just assume FIFO18 is same as FIFO19 without occupancy bit
-
-module fifo18_to_fifo36
- (input clk, input reset, input clear,
- input [17:0] f18_datain,
- input f18_src_rdy_i,
- output f18_dst_rdy_o,
-
- output [35:0] f36_dataout,
- output f36_src_rdy_o,
- input f36_dst_rdy_i
- );
-
- fifo19_to_fifo36 fifo19_to_fifo36
- (.clk(clk), .reset(reset), .clear(clear),
- .f19_datain({1'b0,f18_datain}), .f19_src_rdy_i(f18_src_rdy_i), .f19_dst_rdy_o(f18_dst_rdy_o),
- .f36_dataout(f36_dataout), .f36_src_rdy_o(f36_src_rdy_o), .f36_dst_rdy_i(f36_dst_rdy_i) );
-
-endmodule // fifo18_to_fifo36
diff --git a/fpga/usrp2/fifo/fifo19_to_fifo36.v b/fpga/usrp2/fifo/fifo19_to_fifo36.v
index ae2edddc7..502821435 100644
--- a/fpga/usrp2/fifo/fifo19_to_fifo36.v
+++ b/fpga/usrp2/fifo/fifo19_to_fifo36.v
@@ -15,60 +15,73 @@ module fifo19_to_fifo36
input f36_dst_rdy_i,
output [31:0] debug
);
-
- reg f36_sof, f36_eof;
- reg [1:0] f36_occ;
+ // Shortfifo on input to guarantee no deadlock
+ wire [18:0] f19_data_int;
+ wire f19_src_rdy_int, f19_dst_rdy_int;
+
+ fifo_short #(.WIDTH(19)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f19_datain), .src_rdy_i(f19_src_rdy_i), .dst_rdy_o(f19_dst_rdy_o),
+ .dataout(f19_data_int), .src_rdy_o(f19_src_rdy_int), .dst_rdy_i(f19_dst_rdy_int),
+ .space(),.occupied() );
+
+ // Actual f19 to f36 which could deadlock if not connected to shortfifos
+ reg f36_sof_int, f36_eof_int;
+ reg [1:0] f36_occ_int;
+ wire [35:0] f36_data_int;
+ wire f36_src_rdy_int, f36_dst_rdy_int;
+
reg [1:0] state;
reg [15:0] dat0, dat1;
- wire f19_sof = f19_datain[16];
- wire f19_eof = f19_datain[17];
- wire f19_occ = f19_datain[18];
+ wire f19_sof_int = f19_data_int[16];
+ wire f19_eof_int = f19_data_int[17];
+ wire f19_occ_int = f19_data_int[18];
- wire xfer_out = f36_src_rdy_o & f36_dst_rdy_i;
+ wire xfer_out = f36_src_rdy_int & f36_dst_rdy_int;
always @(posedge clk)
- if(f19_src_rdy_i & ((state==0)|xfer_out))
- f36_sof <= f19_sof;
+ if(f19_src_rdy_int & ((state==0)|xfer_out))
+ f36_sof_int <= f19_sof_int;
always @(posedge clk)
- if(f19_src_rdy_i & ((state != 2)|xfer_out))
- f36_eof <= f19_eof;
+ if(f19_src_rdy_int & ((state != 2)|xfer_out))
+ f36_eof_int <= f19_eof_int;
always @(posedge clk)
if(reset)
begin
state <= 0;
- f36_occ <= 0;
+ f36_occ_int <= 0;
end
else
- if(f19_src_rdy_i)
+ if(f19_src_rdy_int)
case(state)
0 :
begin
- dat0 <= f19_datain;
- if(f19_eof)
+ dat0 <= f19_data_int;
+ if(f19_eof_int)
begin
state <= 2;
- f36_occ <= f19_occ ? 2'b01 : 2'b10;
+ f36_occ_int <= f19_occ_int ? 2'b01 : 2'b10;
end
else
state <= 1;
end
1 :
begin
- dat1 <= f19_datain;
+ dat1 <= f19_data_int;
state <= 2;
- if(f19_eof)
- f36_occ <= f19_occ ? 2'b11 : 2'b00;
+ if(f19_eof_int)
+ f36_occ_int <= f19_occ_int ? 2'b11 : 2'b00;
end
2 :
if(xfer_out)
begin
- dat0 <= f19_datain;
- if(f19_eof) // remain in state 2 if we are at eof
- f36_occ <= f19_occ ? 2'b01 : 2'b10;
+ dat0 <= f19_data_int;
+ if(f19_eof_int) // remain in state 2 if we are at eof
+ f36_occ_int <= f19_occ_int ? 2'b01 : 2'b10;
else
state <= 1;
end
@@ -77,14 +90,21 @@ module fifo19_to_fifo36
if(xfer_out)
begin
state <= 0;
- f36_occ <= 0;
+ f36_occ_int <= 0;
end
- assign f19_dst_rdy_o = xfer_out | (state != 2);
- assign f36_dataout = LE ? {f36_occ,f36_eof,f36_sof,dat1,dat0} :
- {f36_occ,f36_eof,f36_sof,dat0,dat1};
- assign f36_src_rdy_o = (state == 2);
+ assign f19_dst_rdy_int = xfer_out | (state != 2);
+ assign f36_data_int = LE ? {f36_occ_int,f36_eof_int,f36_sof_int,dat1,dat0} :
+ {f36_occ_int,f36_eof_int,f36_sof_int,dat0,dat1};
+ assign f36_src_rdy_int = (state == 2);
assign debug = state;
+
+ // Shortfifo on output to guarantee no deadlock
+ fifo_short #(.WIDTH(36)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f36_data_int), .src_rdy_i(f36_src_rdy_int), .dst_rdy_o(f36_dst_rdy_int),
+ .dataout(f36_dataout), .src_rdy_o(f36_src_rdy_o), .dst_rdy_i(f36_dst_rdy_i),
+ .space(),.occupied() );
endmodule // fifo19_to_fifo36
diff --git a/fpga/usrp2/fifo/fifo36_mux.v b/fpga/usrp2/fifo/fifo36_mux.v
index c6fd40f27..7f0f803ff 100644
--- a/fpga/usrp2/fifo/fifo36_mux.v
+++ b/fpga/usrp2/fifo/fifo36_mux.v
@@ -10,6 +10,19 @@ module fifo36_mux
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);
+ wire [35:0] data0_int, data1_int;
+ wire src0_rdy_int, dst0_rdy_int, src1_rdy_int, dst1_rdy_int;
+
+ fifo_short #(.WIDTH(36)) mux_fifo_in0
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data0_i), .src_rdy_i(src0_rdy_i), .dst_rdy_o(dst0_rdy_o),
+ .dataout(data0_int), .src_rdy_o(src0_rdy_int), .dst_rdy_i(dst0_rdy_int));
+
+ fifo_short #(.WIDTH(36)) mux_fifo_in1
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data1_i), .src_rdy_i(src1_rdy_i), .dst_rdy_o(dst1_rdy_o),
+ .dataout(data1_int), .src_rdy_o(src1_rdy_int), .dst_rdy_i(dst1_rdy_int));
+
localparam MUX_IDLE0 = 0;
localparam MUX_DATA0 = 1;
localparam MUX_IDLE1 = 2;
@@ -17,8 +30,8 @@ module fifo36_mux
reg [1:0] state;
- wire eof0 = data0_i[33];
- wire eof1 = data1_i[33];
+ wire eof0 = data0_int[33];
+ wire eof1 = data1_int[33];
wire [35:0] data_int;
wire src_rdy_int, dst_rdy_int;
@@ -29,33 +42,33 @@ module fifo36_mux
else
case(state)
MUX_IDLE0 :
- if(src0_rdy_i)
+ if(src0_rdy_int)
state <= MUX_DATA0;
- else if(src1_rdy_i)
+ else if(src1_rdy_int)
state <= MUX_DATA1;
MUX_DATA0 :
- if(src0_rdy_i & dst_rdy_int & eof0)
+ if(src0_rdy_int & dst_rdy_int & eof0)
state <= prio ? MUX_IDLE0 : MUX_IDLE1;
MUX_IDLE1 :
- if(src1_rdy_i)
+ if(src1_rdy_int)
state <= MUX_DATA1;
- else if(src0_rdy_i)
+ else if(src0_rdy_int)
state <= MUX_DATA0;
MUX_DATA1 :
- if(src1_rdy_i & dst_rdy_int & eof1)
+ if(src1_rdy_int & dst_rdy_int & eof1)
state <= MUX_IDLE0;
default :
state <= MUX_IDLE0;
endcase // case (state)
- assign dst0_rdy_o = (state==MUX_DATA0) ? dst_rdy_int : 0;
- assign dst1_rdy_o = (state==MUX_DATA1) ? dst_rdy_int : 0;
- assign src_rdy_int = (state==MUX_DATA0) ? src0_rdy_i : (state==MUX_DATA1) ? src1_rdy_i : 0;
- assign data_int = (state==MUX_DATA0) ? data0_i : data1_i;
+ assign dst0_rdy_int = (state==MUX_DATA0) ? dst_rdy_int : 0;
+ assign dst1_rdy_int = (state==MUX_DATA1) ? dst_rdy_int : 0;
+ assign src_rdy_int = (state==MUX_DATA0) ? src0_rdy_int : (state==MUX_DATA1) ? src1_rdy_int : 0;
+ assign data_int = (state==MUX_DATA0) ? data0_int : data1_int;
fifo_short #(.WIDTH(36)) mux_fifo
(.clk(clk), .reset(reset), .clear(clear),
diff --git a/fpga/usrp2/fifo/fifo36_to_fifo19.v b/fpga/usrp2/fifo/fifo36_to_fifo19.v
index e016fe2c6..0e9b2d442 100644
--- a/fpga/usrp2/fifo/fifo36_to_fifo19.v
+++ b/fpga/usrp2/fifo/fifo36_to_fifo19.v
@@ -13,25 +13,37 @@ module fifo36_to_fifo19
output [18:0] f19_dataout,
output f19_src_rdy_o,
input f19_dst_rdy_i );
-
- wire f36_sof = f36_datain[32];
- wire f36_eof = f36_datain[33];
- wire [1:0] f36_occ = f36_datain[35:34];
+
+ wire [18:0] f19_data_int;
+ wire f19_src_rdy_int, f19_dst_rdy_int;
+ wire [35:0] f36_data_int;
+ wire f36_src_rdy_int, f36_dst_rdy_int;
+
+ // Shortfifo on input to guarantee no deadlock
+ fifo_short #(.WIDTH(36)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f36_datain), .src_rdy_i(f36_src_rdy_i), .dst_rdy_o(f36_dst_rdy_o),
+ .dataout(f36_data_int), .src_rdy_o(f36_src_rdy_int), .dst_rdy_i(f36_dst_rdy_int),
+ .space(),.occupied() );
+
+ // Main fifo36_to_fifo19, needs shortfifos to guarantee no deadlock
+ wire [1:0] f36_occ_int = f36_data_int[35:34];
+ wire f36_sof_int = f36_data_int[32];
+ wire f36_eof_int = f36_data_int[33];
reg phase;
+ wire half_line = f36_eof_int & ((f36_occ_int==1)|(f36_occ_int==2));
- wire half_line = f36_eof & ((f36_occ==1)|(f36_occ==2));
-
- assign f19_dataout[15:0] = (LE ^ phase) ? f36_datain[15:0] : f36_datain[31:16];
- assign f19_dataout[16] = phase ? 0 : f36_sof;
- assign f19_dataout[17] = phase ? f36_eof : half_line;
- assign f19_dataout[18] = f19_dataout[17] & ((f36_occ==1)|(f36_occ==3));
+ assign f19_data_int[15:0] = (LE ^ phase) ? f36_data_int[15:0] : f36_data_int[31:16];
+ assign f19_data_int[16] = phase ? 0 : f36_sof_int;
+ assign f19_data_int[17] = phase ? f36_eof_int : half_line;
+ assign f19_data_int[18] = f19_data_int[17] & ((f36_occ_int==1)|(f36_occ_int==3));
- assign f19_src_rdy_o = f36_src_rdy_i;
- assign f36_dst_rdy_o = (phase | half_line) & f19_dst_rdy_i;
+ assign f19_src_rdy_int = f36_src_rdy_int;
+ assign f36_dst_rdy_int = (phase | half_line) & f19_dst_rdy_int;
- wire f19_xfer = f19_src_rdy_o & f19_dst_rdy_i;
- wire f36_xfer = f36_src_rdy_i & f36_dst_rdy_o;
+ wire f19_xfer = f19_src_rdy_int & f19_dst_rdy_int;
+ wire f36_xfer = f36_src_rdy_int & f36_dst_rdy_int;
always @(posedge clk)
if(reset)
@@ -41,5 +53,11 @@ module fifo36_to_fifo19
else if(f19_xfer)
phase <= 1;
-
+ // Shortfifo on output to guarantee no deadlock
+ fifo_short #(.WIDTH(19)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f19_data_int), .src_rdy_i(f19_src_rdy_int), .dst_rdy_o(f19_dst_rdy_int),
+ .dataout(f19_dataout), .src_rdy_o(f19_src_rdy_o), .dst_rdy_i(f19_dst_rdy_i),
+ .space(),.occupied() );
+
endmodule // fifo36_to_fifo19
diff --git a/fpga/usrp2/fifo/fifo36_to_fifo72.v b/fpga/usrp2/fifo/fifo36_to_fifo72.v
new file mode 100644
index 000000000..038eda9e9
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo36_to_fifo72.v
@@ -0,0 +1,125 @@
+
+// Parameter LE tells us if we are little-endian.
+// Little-endian means send lower 16 bits first.
+// Default is big endian (network order), send upper bits first.
+
+module fifo36_to_fifo72
+ #(parameter LE=0)
+ (input clk, input reset, input clear,
+ input [35:0] f36_datain,
+ input f36_src_rdy_i,
+ output f36_dst_rdy_o,
+
+ output [71:0] f72_dataout,
+ output f72_src_rdy_o,
+ input f72_dst_rdy_i,
+ output [31:0] debug
+ );
+
+ // Shortfifo on input to guarantee no deadlock
+ wire [35:0] f36_data_int;
+ wire f36_src_rdy_int, f36_dst_rdy_int;
+
+ fifo_short #(.WIDTH(36)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f36_datain), .src_rdy_i(f36_src_rdy_i), .dst_rdy_o(f36_dst_rdy_o),
+ .dataout(f36_data_int), .src_rdy_o(f36_src_rdy_int), .dst_rdy_i(f36_dst_rdy_int),
+ .space(),.occupied() );
+
+ // Actual f36 to f72 which could deadlock if not connected to shortfifos
+ reg f72_sof_int, f72_eof_int;
+ reg [2:0] f72_occ_int;
+ wire [71:0] f72_data_int;
+ wire f72_src_rdy_int, f72_dst_rdy_int;
+
+ reg [1:0] state;
+ reg [31:0] dat0, dat1;
+
+ wire f36_sof_int = f36_data_int[32];
+ wire f36_eof_int = f36_data_int[33];
+ wire [1:0] f36_occ_int = f36_data_int[35:34];
+
+ wire xfer_out = f72_src_rdy_int & f72_dst_rdy_int;
+
+ always @(posedge clk)
+ if(f36_src_rdy_int & ((state==0)|xfer_out))
+ f72_sof_int <= f36_sof_int;
+
+ always @(posedge clk)
+ if(f36_src_rdy_int & ((state != 2)|xfer_out))
+ f72_eof_int <= f36_eof_int;
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ state <= 0;
+ f72_occ_int <= 0;
+ end
+ else
+ if(f36_src_rdy_int)
+ case(state)
+ 0 :
+ begin
+ dat0 <= f36_data_int;
+ if(f36_eof_int)
+ begin
+ state <= 2;
+ case (f36_occ_int)
+ 0 : f72_occ_int <= 3'd4;
+ 1 : f72_occ_int <= 3'd1;
+ 2 : f72_occ_int <= 3'd2;
+ 3 : f72_occ_int <= 3'd3;
+ endcase // case (f36_occ_int)
+ end
+ else
+ state <= 1;
+ end
+ 1 :
+ begin
+ dat1 <= f36_data_int;
+ state <= 2;
+ if(f36_eof_int)
+ case (f36_occ_int)
+ 0 : f72_occ_int <= 3'd0;
+ 1 : f72_occ_int <= 3'd5;
+ 2 : f72_occ_int <= 3'd6;
+ 3 : f72_occ_int <= 3'd7;
+ endcase // case (f36_occ_int)
+ end
+ 2 :
+ if(xfer_out)
+ begin
+ dat0 <= f36_data_int;
+ if(f36_eof_int) // remain in state 2 if we are at eof
+ case (f36_occ_int)
+ 0 : f72_occ_int <= 3'd4;
+ 1 : f72_occ_int <= 3'd1;
+ 2 : f72_occ_int <= 3'd2;
+ 3 : f72_occ_int <= 3'd3;
+ endcase // case (f36_occ_int)
+ else
+ state <= 1;
+ end
+ endcase // case(state)
+ else
+ if(xfer_out)
+ begin
+ state <= 0;
+ f72_occ_int <= 0;
+ end
+
+ assign f36_dst_rdy_int = xfer_out | (state != 2);
+ assign f72_data_int = LE ? {3'b000,f72_occ_int[2:0],f72_eof_int,f72_sof_int,dat1,dat0} :
+ {3'b000,f72_occ_int[2:0],f72_eof_int,f72_sof_int,dat0,dat1};
+ assign f72_src_rdy_int = (state == 2);
+
+ assign debug = state;
+
+ // Shortfifo on output to guarantee no deadlock
+ fifo_short #(.WIDTH(72)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f72_data_int), .src_rdy_i(f72_src_rdy_int), .dst_rdy_o(f72_dst_rdy_int),
+ .dataout(f72_dataout), .src_rdy_o(f72_src_rdy_o), .dst_rdy_i(f72_dst_rdy_i),
+ .space(),.occupied() );
+
+endmodule // fifo36_to_fifo72
diff --git a/fpga/usrp2/fifo/fifo36_to_ll8.v b/fpga/usrp2/fifo/fifo36_to_ll8.v
index 9604d0e38..390e49962 100644
--- a/fpga/usrp2/fifo/fifo36_to_ll8.v
+++ b/fpga/usrp2/fifo/fifo36_to_ll8.v
@@ -5,25 +5,33 @@ module fifo36_to_ll8
input f36_src_rdy_i,
output f36_dst_rdy_o,
- output reg [7:0] ll_data,
- output ll_sof_n,
- output ll_eof_n,
- output ll_src_rdy_n,
- input ll_dst_rdy_n,
+ output [7:0] ll_data,
+ output ll_sof,
+ output ll_eof,
+ output ll_src_rdy,
+ input ll_dst_rdy,
output [31:0] debug);
- wire ll_sof, ll_eof, ll_src_rdy;
- assign ll_sof_n = ~ll_sof;
- assign ll_eof_n = ~ll_eof;
- assign ll_src_rdy_n = ~ll_src_rdy;
- wire ll_dst_rdy = ~ll_dst_rdy_n;
-
- wire f36_sof = f36_data[32];
- wire f36_eof = f36_data[33];
- wire f36_occ = f36_data[35:34];
- wire advance, end_early;
- reg [1:0] state;
+ // Shortfifo on input to guarantee no deadlock
+ wire [35:0] f36_data_int;
+ wire f36_src_rdy_int, f36_dst_rdy_int;
+ reg [7:0] ll_data_int;
+ wire ll_sof_int, ll_eof_int, ll_src_rdy_int, ll_dst_rdy_int;
+
+ fifo_short #(.WIDTH(36)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f36_data), .src_rdy_i(f36_src_rdy_i), .dst_rdy_o(f36_dst_rdy_o),
+ .dataout(f36_data_int), .src_rdy_o(f36_src_rdy_int), .dst_rdy_i(f36_dst_rdy_int),
+ .space(),.occupied() );
+
+ // Actual fifo36 to ll8, can deadlock if not connected to shortfifo
+ wire [1:0] f36_occ_int = f36_data_int[35:34];
+ wire f36_sof_int = f36_data_int[32];
+ wire f36_eof_int = f36_data_int[33];
+ wire advance, end_early;
+ reg [1:0] state;
+
assign debug = {29'b0,state};
always @(posedge clk)
@@ -31,29 +39,37 @@ module fifo36_to_ll8
state <= 0;
else
if(advance)
- if(ll_eof)
+ if(ll_eof_int)
state <= 0;
else
state <= state + 1;
always @*
case(state)
- 0 : ll_data = f36_data[31:24];
- 1 : ll_data = f36_data[23:16];
- 2 : ll_data = f36_data[15:8];
- 3 : ll_data = f36_data[7:0];
- default : ll_data = f36_data[31:24];
+ 0 : ll_data_int = f36_data_int[31:24];
+ 1 : ll_data_int = f36_data_int[23:16];
+ 2 : ll_data_int = f36_data_int[15:8];
+ 3 : ll_data_int = f36_data_int[7:0];
+ default : ll_data_int = f36_data_int[31:24];
endcase // case (state)
- assign ll_sof = (state==0) & f36_sof;
- assign ll_eof = f36_eof & (((state==0)&(f36_occ==1)) |
- ((state==1)&(f36_occ==2)) |
- ((state==2)&(f36_occ==3)) |
- (state==3));
+ assign ll_sof_int = (state==0) & f36_sof_int;
+ assign ll_eof_int = f36_eof_int & (((state==0)&(f36_occ_int==1)) |
+ ((state==1)&(f36_occ_int==2)) |
+ ((state==2)&(f36_occ_int==3)) |
+ (state==3));
- assign ll_src_rdy = f36_src_rdy_i;
-
- assign advance = ll_src_rdy & ll_dst_rdy;
- assign f36_dst_rdy_o = advance & ((state==3)|ll_eof);
+ assign ll_src_rdy_int = f36_src_rdy_int;
-endmodule // ll8_to_fifo36
+ assign advance = ll_src_rdy_int & ll_dst_rdy_int;
+ assign f36_dst_rdy_int= advance & ((state==3)|ll_eof_int);
+
+ // Short FIFO on output to guarantee no deadlock
+ ll8_shortfifo tail_fifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(ll_data_int), .sof_i(ll_sof_int), .eof_i(ll_eof_int),
+ .error_i(0), .src_rdy_i(ll_src_rdy_int), .dst_rdy_o(ll_dst_rdy_int),
+ .dataout(ll_data), .sof_o(ll_sof), .eof_o(ll_eof),
+ .error_o(), .src_rdy_o(ll_src_rdy), .dst_rdy_i(ll_dst_rdy));
+
+endmodule // fifo36_to_ll8
diff --git a/fpga/usrp2/fifo/fifo72_to_fifo36.v b/fpga/usrp2/fifo/fifo72_to_fifo36.v
new file mode 100644
index 000000000..1b3bc3ab7
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo72_to_fifo36.v
@@ -0,0 +1,63 @@
+
+// Parameter LE tells us if we are little-endian.
+// Little-endian means send lower 16 bits first.
+// Default is big endian (network order), send upper bits first.
+
+module fifo72_to_fifo36
+ #(parameter LE=0)
+ (input clk, input reset, input clear,
+ input [71:0] f72_datain,
+ input f72_src_rdy_i,
+ output f72_dst_rdy_o,
+
+ output [35:0] f36_dataout,
+ output f36_src_rdy_o,
+ input f36_dst_rdy_i );
+
+ wire [35:0] f36_data_int;
+ wire f36_src_rdy_int, f36_dst_rdy_int;
+ wire [71:0] f72_data_int;
+ wire f72_src_rdy_int, f72_dst_rdy_int;
+
+ // Shortfifo on input to guarantee no deadlock
+ fifo_short #(.WIDTH(72)) head_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f72_datain), .src_rdy_i(f72_src_rdy_i), .dst_rdy_o(f72_dst_rdy_o),
+ .dataout(f72_data_int), .src_rdy_o(f72_src_rdy_int), .dst_rdy_i(f72_dst_rdy_int),
+ .space(),.occupied() );
+
+ // Main fifo72_to_fifo36, needs shortfifos to guarantee no deadlock
+ wire [2:0] f72_occ_int = f72_data_int[68:66];
+ wire f72_sof_int = f72_data_int[64];
+ wire f72_eof_int = f72_data_int[65];
+
+ reg phase;
+ wire half_line = f72_eof_int & ( (f72_occ_int==1)|(f72_occ_int==2)|(f72_occ_int==3)|(f72_occ_int==4) );
+
+ assign f36_data_int[31:0] = (LE ^ phase) ? f72_data_int[31:0] : f72_data_int[63:32];
+ assign f36_data_int[32] = phase ? 0 : f72_sof_int;
+ assign f36_data_int[33] = phase ? f72_eof_int : half_line;
+ assign f36_data_int[35:34] = f36_data_int[33] ? f72_occ_int[1:0] : 2'b00;
+
+ assign f36_src_rdy_int = f72_src_rdy_int;
+ assign f72_dst_rdy_int = (phase | half_line) & f36_dst_rdy_int;
+
+ wire f36_xfer = f36_src_rdy_int & f36_dst_rdy_int;
+ wire f72_xfer = f72_src_rdy_int & f72_dst_rdy_int;
+
+ always @(posedge clk)
+ if(reset)
+ phase <= 0;
+ else if(f72_xfer)
+ phase <= 0;
+ else if(f36_xfer)
+ phase <= 1;
+
+ // Shortfifo on output to guarantee no deadlock
+ fifo_short #(.WIDTH(36)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f36_data_int), .src_rdy_i(f36_src_rdy_int), .dst_rdy_o(f36_dst_rdy_int),
+ .dataout(f36_dataout), .src_rdy_o(f36_src_rdy_o), .dst_rdy_i(f36_dst_rdy_i),
+ .space(),.occupied() );
+
+endmodule // fifo72_to_fifo36
diff --git a/fpga/usrp2/control_lib/newfifo/fifo_pacer.v b/fpga/usrp2/fifo/fifo_pacer.v
index 1bf03ab6e..1bf03ab6e 100644
--- a/fpga/usrp2/control_lib/newfifo/fifo_pacer.v
+++ b/fpga/usrp2/fifo/fifo_pacer.v
diff --git a/fpga/usrp2/fifo/fifo_tb.v b/fpga/usrp2/fifo/fifo_tb.v
index 327da4700..3e2862a70 100644
--- a/fpga/usrp2/fifo/fifo_tb.v
+++ b/fpga/usrp2/fifo/fifo_tb.v
@@ -1,4 +1,4 @@
-module fifo_new_tb();
+module fifo_tb();
reg clk = 0;
reg rst = 1;
@@ -9,169 +9,47 @@ module fifo_new_tb();
reg [31:0] f36_data = 0;
reg [1:0] f36_occ = 0;
reg f36_sof = 0, f36_eof = 0;
-
- wire [35:0] f36_in = {f36_occ,f36_eof,f36_sof,f36_data};
- reg src_rdy_f36i = 0;
- wire dst_rdy_f36i;
-
- wire [35:0] f36_out, f36_out2;
- wire src_rdy_f36o;
- reg dst_rdy_f36o = 0;
-
- //fifo_cascade #(.WIDTH(36), .SIZE(4)) fifo_cascade36
- //fifo_long #(.WIDTH(36), .SIZE(4)) fifo_cascade36
-
- 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, i7;
- wire [18:0] i2, i3;
+ reg f36_src_rdy;
+ wire f36_dst_rdy;
wire [7:0] ll_data;
- wire ll_src_rdy_n, ll_dst_rdy_n, ll_sof_n, ll_eof_n;
+ wire ll_src_rdy, ll_dst_rdy, ll_sof, ll_eof;
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
+ fifo36_to_ll8 fifo36_to_ll8
(.clk(clk),.reset(rst),.clear(clear),
- .datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i),
- .dataout(i7),.src_rdy_o(i7_sr),.dst_rdy_i(i7_dr) );
+ .f36_data({f36_occ,f36_eof,f36_sof,f36_data}),.f36_src_rdy_i(f36_src_rdy),.f36_dst_rdy_o(f36_dst_rdy),
+ .ll_data(ll_data),.ll_sof(ll_sof),.ll_eof(ll_eof),
+ .ll_src_rdy(ll_src_rdy),.ll_dst_rdy(ll_dst_rdy));
- 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));
+ assign ll_dst_rdy = 1;
- 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),
- .f19_dataout(i2),.f19_src_rdy_o(i2_sr),.f19_dst_rdy_i(i2_dr) );
-
- fifo19_to_ll8 fifo19_to_ll8
- (.clk(clk),.reset(rst),.clear(clear),
- .f19_data(i2),.f19_src_rdy_i(i2_sr),.f19_dst_rdy_o(i2_dr),
- .ll_data(ll_data),.ll_sof_n(ll_sof_n),.ll_eof_n(ll_eof_n),
- .ll_src_rdy_n(ll_src_rdy_n),.ll_dst_rdy_n(ll_dst_rdy_n));
-
- ll8_to_fifo19 ll8_to_fifo19
- (.clk(clk),.reset(rst),.clear(clear),
- .ll_data(ll_data),.ll_sof_n(ll_sof_n),.ll_eof_n(ll_eof_n),
- .ll_src_rdy_n(ll_src_rdy_n),.ll_dst_rdy_n(ll_dst_rdy_n),
- .f19_data(i3),.f19_src_rdy_o(i3_sr),.f19_dst_rdy_i(i3_dr) );
-
- fifo19_to_fifo36 fifo19_to_fifo36
- (.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");
- #1 i4_dr <= 1;
- while(1)
- begin
- while(~i4_sr)
- @(posedge clk);
- $display("Read: %h",i4);
- @(posedge clk);
- end
- end
- endtask // ReadFromFIFO36
-
- reg [15:0] count;
- task PutPacketInFIFO36;
- input [31:0] data_start;
- input [31:0] data_len;
- begin
- count <= 4;
- src_rdy_f36i <= 1;
- f36_data <= data_start;
- f36_sof <= 1;
- f36_eof <= 0;
- f36_occ <= 0;
-
- $display("Put Packet in FIFO36");
- while(~dst_rdy_f36i)
- @(posedge clk);
- @(posedge clk);
- $display("PPI_FIFO36: Entered First Line");
- f36_sof <= 0;
- while(count+4 < data_len)
- begin
- f36_data <= f36_data + 32'h01010101;
- count <= count + 4;
- while(~dst_rdy_f36i)
- @(posedge clk);
- @(posedge clk);
- $display("PPI_FIFO36: Entered New Line");
- end
- f36_data <= f36_data + 32'h01010101;
- f36_eof <= 1;
- if(count + 4 == data_len)
- f36_occ <= 0;
- else if(count + 3 == data_len)
- f36_occ <= 3;
- else if(count + 2 == data_len)
- f36_occ <= 2;
- else
- f36_occ <= 1;
- while(~dst_rdy_f36i)
- @(posedge clk);
- @(posedge clk);
- f36_occ <= 0;
- f36_eof <= 0;
- f36_data <= 0;
- src_rdy_f36i <= 0;
- $display("PPI_FIFO36: Entered Last Line");
- end
- endtask // PutPacketInFIFO36
+ always @(posedge clk)
+ if(ll_src_rdy)
+ $display("LL: SOF %d, EOF %d, DAT %x",ll_sof,ll_eof,ll_data);
- initial $dumpfile("fifo_new_tb.vcd");
- initial $dumpvars(0,fifo_new_tb);
+ initial $dumpfile("fifo_tb.vcd");
+ initial $dumpvars(0,fifo_tb);
initial
begin
@(negedge rst);
- //#10000;
@(posedge clk);
@(posedge clk);
@(posedge clk);
@(posedge clk);
- ReadFromFIFO36;
- end
-
- initial
- begin
- @(negedge rst);
- @(posedge clk);
- @(posedge clk);
- PutPacketInFIFO36(32'hA0B0C0D0,12);
- @(posedge clk);
- @(posedge clk);
- #10000;
- @(posedge clk);
- PutPacketInFIFO36(32'hE0F0A0B0,36);
- @(posedge clk);
+ f36_src_rdy <= 1;
+ {f36_occ,f36_eof,f36_sof,f36_data} <= { 2'b00,1'b0,1'b1,32'h00010203};
@(posedge clk);
+ {f36_occ,f36_eof,f36_sof,f36_data} <= { 2'b00,1'b0,1'b0,32'h04050607};
@(posedge clk);
+ {f36_occ,f36_eof,f36_sof,f36_data} <= { 2'b00,1'b0,1'b0,32'h08090a0b};
@(posedge clk);
+ {f36_occ,f36_eof,f36_sof,f36_data} <= { 2'b11,1'b1,1'b0,32'h0c0d0e0f};
@(posedge clk);
+ f36_src_rdy <= 0;
end
-
- initial #20000 $finish;
+
+ initial #4000 $finish;
endmodule // longfifo_tb
diff --git a/fpga/usrp2/fifo/ll8_to_fifo19.v b/fpga/usrp2/fifo/ll8_to_fifo19.v
index af3b91afb..ac8ac19a6 100644
--- a/fpga/usrp2/fifo/ll8_to_fifo19.v
+++ b/fpga/usrp2/fifo/ll8_to_fifo19.v
@@ -2,41 +2,47 @@
module ll8_to_fifo19
(input clk, input reset, input clear,
input [7:0] ll_data,
- input ll_sof_n,
- input ll_eof_n,
- input ll_src_rdy_n,
- output ll_dst_rdy_n,
+ input ll_sof,
+ input ll_eof,
+ input ll_src_rdy,
+ output ll_dst_rdy,
output [18:0] f19_data,
output f19_src_rdy_o,
input f19_dst_rdy_i );
+
+ // Short FIFO on input to guarantee no deadlock
+ wire [7:0] ll_data_int;
+ wire ll_sof_int, ll_eof_int, ll_src_rdy_int, ll_dst_rdy_int;
+ ll8_shortfifo head_fifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(ll_data), .sof_i(ll_sof), .eof_i(ll_eof),
+ .error_i(0), .src_rdy_i(ll_src_rdy), .dst_rdy_o(ll_dst_rdy),
+ .dataout(ll_data_int), .sof_o(ll_sof_int), .eof_o(ll_eof_int),
+ .error_o(), .src_rdy_o(ll_src_rdy_int), .dst_rdy_i(ll_dst_rdy_int));
+
+ // Actual ll8_to_fifo19 which could deadlock if not connected to a shortfifo
localparam XFER_EMPTY = 0;
localparam XFER_HALF = 1;
localparam XFER_HALF_WRITE = 3;
- // Why anybody would use active low in an FPGA is beyond me...
- wire ll_sof = ~ll_sof_n;
- wire ll_eof = ~ll_eof_n;
- wire ll_src_rdy = ~ll_src_rdy_n;
- wire ll_dst_rdy;
- assign ll_dst_rdy_n = ~ll_dst_rdy;
-
- wire xfer_out = f19_src_rdy_o & f19_dst_rdy_i;
- wire xfer_in = ll_src_rdy & ll_dst_rdy;
-
- reg hold_sof;
- wire f19_sof, f19_eof, f19_occ;
+ wire [18:0] f19_data_int;
+ wire f19_sof_int, f19_eof_int, f19_occ_int, f19_src_rdy_int, f19_dst_rdy_int;
+
+ wire xfer_out = f19_src_rdy_int & f19_dst_rdy_int;
+ wire xfer_in = ll_src_rdy_int & ll_dst_rdy_int;
+ reg hold_sof;
- reg [1:0] state;
- reg [7:0] hold_reg;
+ reg [1:0] state;
+ reg [7:0] hold_reg;
always @(posedge clk)
- if(ll_src_rdy & (state==XFER_EMPTY))
- hold_reg <= ll_data;
+ if(ll_src_rdy_int & (state==XFER_EMPTY))
+ hold_reg <= ll_data_int;
always @(posedge clk)
- if(ll_sof & (state==XFER_EMPTY))
+ if(ll_sof_int & (state==XFER_EMPTY))
hold_sof <= 1;
else if(xfer_out)
hold_sof <= 0;
@@ -47,27 +53,35 @@ module ll8_to_fifo19
else
case(state)
XFER_EMPTY :
- if(ll_src_rdy)
- if(ll_eof)
+ if(ll_src_rdy_int)
+ if(ll_eof_int)
state <= XFER_HALF_WRITE;
else
state <= XFER_HALF;
XFER_HALF :
- if(ll_src_rdy & f19_dst_rdy_i)
+ if(ll_src_rdy_int & f19_dst_rdy_int)
state <= XFER_EMPTY;
XFER_HALF_WRITE :
- if(f19_dst_rdy_i)
+ if(f19_dst_rdy_int)
state <= XFER_EMPTY;
endcase // case (state)
- assign ll_dst_rdy = (state==XFER_EMPTY) | ((state==XFER_HALF)&f19_dst_rdy_i);
- assign f19_src_rdy_o = (state==XFER_HALF_WRITE) | ((state==XFER_HALF)&ll_src_rdy);
+ assign ll_dst_rdy_int = (state==XFER_EMPTY) | ((state==XFER_HALF)&f19_dst_rdy_int);
+ assign f19_src_rdy_int= (state==XFER_HALF_WRITE) | ((state==XFER_HALF)&ll_src_rdy_int);
- assign f19_sof = hold_sof | (ll_sof & (state==XFER_HALF));
- assign f19_eof = (state == XFER_HALF_WRITE) | ll_eof;
- assign f19_occ = (state == XFER_HALF_WRITE);
+ assign f19_sof_int = hold_sof | (ll_sof_int & (state==XFER_HALF));
+ assign f19_eof_int = (state == XFER_HALF_WRITE) | ll_eof_int;
+ assign f19_occ_int = (state == XFER_HALF_WRITE);
- assign f19_data = {f19_occ,f19_eof,f19_sof,hold_reg,ll_data};
+ assign f19_data_int = {f19_occ_int,f19_eof_int,f19_sof_int,hold_reg,ll_data_int};
+
+ // Shortfifo on output to guarantee no deadlock
+ fifo_short #(.WIDTH(19)) tail_fifo
+ (.clk(clk),.reset(reset),.clear(clear),
+ .datain(f19_data_int), .src_rdy_i(f19_src_rdy_int), .dst_rdy_o(f19_dst_rdy_int),
+ .dataout(f19_data), .src_rdy_o(f19_src_rdy_o), .dst_rdy_i(f19_dst_rdy_i),
+ .space(),.occupied() );
+
endmodule // ll8_to_fifo19
diff --git a/fpga/usrp2/control_lib/newfifo/packet32_tb.v b/fpga/usrp2/fifo/packet32_tb.v
index 82bb09c29..82bb09c29 100644
--- a/fpga/usrp2/control_lib/newfifo/packet32_tb.v
+++ b/fpga/usrp2/fifo/packet32_tb.v
diff --git a/fpga/usrp2/fifo/packet_dispatcher36_x3.v b/fpga/usrp2/fifo/packet_dispatcher36_x3.v
new file mode 100644
index 000000000..fd762d061
--- /dev/null
+++ b/fpga/usrp2/fifo/packet_dispatcher36_x3.v
@@ -0,0 +1,270 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// Packet dispatcher with fifo36 interface and 3 outputs.
+//
+// The packet dispatcher expects 2-byte padded ethernet frames.
+// The frames will be inspected at ethernet, IPv4, UDP, and VRT layers.
+// Packets are dispatched into the following streams:
+// * tx dsp stream
+// * to cpu stream
+// * to external stream
+// * to both cpu and external
+//
+// The following registers are used for dispatcher control:
+// * base + 0 = this ipv4 address (32 bits)
+// * base + 1 = udp dst port (lower 16 bits)
+//
+
+module packet_dispatcher36_x3
+ #(
+ parameter BASE = 0
+ )
+ (
+ //clocking and reset interface:
+ input clk, input rst, input clr,
+
+ //setting register interface:
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ //input stream interfaces:
+ input [35:0] com_inp_data, input com_inp_valid, output com_inp_ready,
+
+ //output stream interfaces:
+ output [35:0] ext_out_data, output ext_out_valid, input ext_out_ready,
+ output [35:0] dsp_out_data, output dsp_out_valid, input dsp_out_ready,
+ output [35:0] cpu_out_data, output cpu_out_valid, input cpu_out_ready
+ );
+
+ //setting register to program the IP address
+ wire [31:0] my_ip_addr;
+ setting_reg #(.my_addr(BASE+0)) sreg_ip_addr(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(my_ip_addr),.changed()
+ );
+
+ //setting register to program the UDP DSP port
+ wire [15:0] dsp_udp_port;
+ setting_reg #(.my_addr(BASE+1), .width(16)) sreg_data_port(
+ .clk(clk),.rst(rst),
+ .strobe(set_stb),.addr(set_addr),.in(set_data),
+ .out(dsp_udp_port),.changed()
+ );
+
+ ////////////////////////////////////////////////////////////////////
+ // Communication input inspector
+ // - inspect com input and send it to DSP, EXT, CPU, or BOTH
+ ////////////////////////////////////////////////////////////////////
+ localparam PD_STATE_READ_COM_PRE = 0;
+ localparam PD_STATE_READ_COM = 1;
+ localparam PD_STATE_WRITE_REGS = 2;
+ localparam PD_STATE_WRITE_LIVE = 3;
+
+ localparam PD_DEST_DSP = 0;
+ localparam PD_DEST_EXT = 1;
+ localparam PD_DEST_CPU = 2;
+ localparam PD_DEST_BOF = 3;
+
+ localparam PD_MAX_NUM_DREGS = 13; //padded_eth + ip + udp + seq + vrt_hdr
+ localparam PD_DREGS_DSP_OFFSET = 11; //offset to start dsp at
+
+ //output inspector interfaces
+ wire [35:0] pd_out_dsp_data;
+ wire pd_out_dsp_valid;
+ wire pd_out_dsp_ready;
+
+ wire [35:0] pd_out_ext_data;
+ wire pd_out_ext_valid;
+ wire pd_out_ext_ready;
+
+ wire [35:0] pd_out_cpu_data;
+ wire pd_out_cpu_valid;
+ wire pd_out_cpu_ready;
+
+ wire [35:0] pd_out_bof_data;
+ wire pd_out_bof_valid;
+ wire pd_out_bof_ready;
+
+ reg [1:0] pd_state;
+ reg [1:0] pd_dest;
+ reg [3:0] pd_dreg_count; //data registers to buffer headers
+ wire [3:0] pd_dreg_count_next = pd_dreg_count + 1'b1;
+ wire pd_dreg_counter_done = (pd_dreg_count_next == PD_MAX_NUM_DREGS)? 1'b1 : 1'b0;
+ reg [35:0] pd_dregs [PD_MAX_NUM_DREGS-1:0];
+
+ //extract various packet components:
+ wire [47:0] pd_dregs_eth_dst_mac = {pd_dregs[0][15:0], pd_dregs[1][31:0]};
+ wire [15:0] pd_dregs_eth_type = pd_dregs[3][15:0];
+ wire [7:0] pd_dregs_ipv4_proto = pd_dregs[6][23:16];
+ wire [31:0] pd_dregs_ipv4_dst_addr = pd_dregs[8][31:0];
+ wire [15:0] pd_dregs_udp_dst_port = pd_dregs[9][15:0];
+ wire [15:0] pd_dregs_vrt_size = com_inp_data[15:0];
+
+ //Inspector output flags special case:
+ //Inject SOF into flags at first DSP line.
+ wire [3:0] pd_out_flags = (
+ (pd_dreg_count == PD_DREGS_DSP_OFFSET) &&
+ (pd_dest == PD_DEST_DSP)
+ )? 4'b0001 : pd_dregs[pd_dreg_count][35:32];
+
+ //The communication inspector ouput data and valid signals:
+ //Mux between com input and data registers based on the state.
+ wire [35:0] pd_out_data = (pd_state == PD_STATE_WRITE_REGS)?
+ {pd_out_flags, pd_dregs[pd_dreg_count][31:0]} : com_inp_data
+ ;
+ wire pd_out_valid =
+ (pd_state == PD_STATE_WRITE_REGS)? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE)? com_inp_valid : (
+ 1'b0));
+
+ //The communication inspector ouput ready signal:
+ //Mux between the various destination ready signals.
+ wire pd_out_ready =
+ (pd_dest == PD_DEST_DSP)? pd_out_dsp_ready : (
+ (pd_dest == PD_DEST_EXT)? pd_out_ext_ready : (
+ (pd_dest == PD_DEST_CPU)? pd_out_cpu_ready : (
+ (pd_dest == PD_DEST_BOF)? pd_out_bof_ready : (
+ 1'b0))));
+
+ //Always connected output data lines.
+ assign pd_out_dsp_data = pd_out_data;
+ assign pd_out_ext_data = pd_out_data;
+ assign pd_out_cpu_data = pd_out_data;
+ assign pd_out_bof_data = pd_out_data;
+
+ //Destination output valid signals:
+ //Comes from inspector valid when destination is selected, and otherwise low.
+ assign pd_out_dsp_valid = (pd_dest == PD_DEST_DSP)? pd_out_valid : 1'b0;
+ assign pd_out_ext_valid = (pd_dest == PD_DEST_EXT)? pd_out_valid : 1'b0;
+ assign pd_out_cpu_valid = (pd_dest == PD_DEST_CPU)? pd_out_valid : 1'b0;
+ assign pd_out_bof_valid = (pd_dest == PD_DEST_BOF)? pd_out_valid : 1'b0;
+
+ //The communication inspector ouput ready signal:
+ //Always ready when storing to data registers,
+ //comes from inspector ready output when live,
+ //and otherwise low.
+ assign com_inp_ready =
+ (pd_state == PD_STATE_READ_COM_PRE) ? 1'b1 : (
+ (pd_state == PD_STATE_READ_COM) ? 1'b1 : (
+ (pd_state == PD_STATE_WRITE_LIVE) ? pd_out_ready : (
+ 1'b0)));
+
+ always @(posedge clk)
+ if(rst | clr) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ case(pd_state)
+ PD_STATE_READ_COM_PRE: begin
+ if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
+ pd_state <= PD_STATE_READ_COM;
+ pd_dreg_count <= pd_dreg_count_next;
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ end
+ end
+
+ PD_STATE_READ_COM: begin
+ if (com_inp_ready & com_inp_valid) begin
+ pd_dregs[pd_dreg_count] <= com_inp_data;
+ if (pd_dreg_counter_done | com_inp_data[33]) begin
+ pd_state <= PD_STATE_WRITE_REGS;
+ pd_dreg_count <= 0;
+
+ //---------- begin inspection decision -----------//
+ //EOF or bcast or not IPv4 or not UDP:
+ if (
+ com_inp_data[33] || (pd_dregs_eth_dst_mac == 48'hffffffffffff) ||
+ (pd_dregs_eth_type != 16'h800) || (pd_dregs_ipv4_proto != 8'h11)
+ ) begin
+ pd_dest <= PD_DEST_BOF;
+ end
+
+ //not my IP address:
+ else if (pd_dregs_ipv4_dst_addr != my_ip_addr) begin
+ pd_dest <= PD_DEST_EXT;
+ end
+
+ //UDP data port and VRT:
+ else if ((pd_dregs_udp_dst_port == dsp_udp_port) && (pd_dregs_vrt_size != 16'h0)) begin
+ pd_dest <= PD_DEST_DSP;
+ pd_dreg_count <= PD_DREGS_DSP_OFFSET;
+ end
+
+ //other:
+ else begin
+ pd_dest <= PD_DEST_CPU;
+ end
+ //---------- end inspection decision -------------//
+
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_REGS: begin
+ if (pd_out_ready & pd_out_valid) begin
+ if (pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ pd_dreg_count <= 0;
+ end
+ else if (pd_dreg_counter_done) begin
+ pd_state <= PD_STATE_WRITE_LIVE;
+ pd_dreg_count <= 0;
+ end
+ else begin
+ pd_dreg_count <= pd_dreg_count_next;
+ end
+ end
+ end
+
+ PD_STATE_WRITE_LIVE: begin
+ if (pd_out_ready & pd_out_valid & pd_out_data[33]) begin
+ pd_state <= PD_STATE_READ_COM_PRE;
+ end
+ end
+
+ endcase //pd_state
+ end
+
+ //connect this fast-path signals directly to the DSP out
+ assign dsp_out_data = pd_out_dsp_data;
+ assign dsp_out_valid = pd_out_dsp_valid;
+ assign pd_out_dsp_ready = dsp_out_ready;
+
+ ////////////////////////////////////////////////////////////////////
+ // Splitter and output muxes for the bof packets
+ // - split the bof packets into two streams
+ // - mux split packets into cpu out and ext out
+ ////////////////////////////////////////////////////////////////////
+
+ //dummy signals to join the the splitter and muxes below
+ wire [35:0] _split_to_ext_data, _split_to_cpu_data;
+ wire _split_to_ext_valid, _split_to_cpu_valid;
+ wire _split_to_ext_ready, _split_to_cpu_ready;
+
+ splitter36 bof_out_splitter(
+ .clk(clk), .rst(rst), .clr(clr),
+ .inp_data(pd_out_bof_data), .inp_valid(pd_out_bof_valid), .inp_ready(pd_out_bof_ready),
+ .out0_data(_split_to_ext_data), .out0_valid(_split_to_ext_valid), .out0_ready(_split_to_ext_ready),
+ .out1_data(_split_to_cpu_data), .out1_valid(_split_to_cpu_valid), .out1_ready(_split_to_cpu_ready)
+ );
+
+ fifo36_mux ext_out_mux(
+ .clk(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_ext_data), .src0_rdy_i(pd_out_ext_valid), .dst0_rdy_o(pd_out_ext_ready),
+ .data1_i(_split_to_ext_data), .src1_rdy_i(_split_to_ext_valid), .dst1_rdy_o(_split_to_ext_ready),
+ .data_o(ext_out_data), .src_rdy_o(ext_out_valid), .dst_rdy_i(ext_out_ready)
+ );
+
+ fifo36_mux cpu_out_mux(
+ .clk(clk), .reset(rst), .clear(clr),
+ .data0_i(pd_out_cpu_data), .src0_rdy_i(pd_out_cpu_valid), .dst0_rdy_o(pd_out_cpu_ready),
+ .data1_i(_split_to_cpu_data), .src1_rdy_i(_split_to_cpu_valid), .dst1_rdy_o(_split_to_cpu_ready),
+ .data_o(cpu_out_data), .src_rdy_o(cpu_out_valid), .dst_rdy_i(cpu_out_ready)
+ );
+
+endmodule // packet_dispatcher36_x3
diff --git a/fpga/usrp2/fifo/packet_generator.v b/fpga/usrp2/fifo/packet_generator.v
new file mode 100644
index 000000000..2ae911e24
--- /dev/null
+++ b/fpga/usrp2/fifo/packet_generator.v
@@ -0,0 +1,83 @@
+
+
+module packet_generator
+ (input clk, input reset, input clear,
+ output reg [7:0] data_o, output sof_o, output eof_o,
+ input [127:0] header,
+ output src_rdy_o, input dst_rdy_i);
+
+ localparam len = 32'd2000;
+
+ reg [31:0] state;
+ reg [31:0] seq;
+ reg [31:0] crc_out;
+ wire calc_crc = src_rdy_o & dst_rdy_i & ~(state[31:2] == 30'h3FFF_FFFF);
+
+
+ always @(posedge clk)
+ if(reset | clear)
+ seq <= 0;
+ else
+ if(eof_o & src_rdy_o & dst_rdy_i)
+ seq <= seq + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= 0;
+ else
+ if(src_rdy_o & dst_rdy_i)
+ if(state == (len - 1))
+ state <= 32'hFFFF_FFFC;
+ else
+ state <= state + 1;
+
+ always @*
+ case(state)
+ 0 : data_o <= len[31:24];
+ 1 : data_o <= len[23:16];
+ 2 : data_o <= len[15:8];
+ 3 : data_o <= len[7:0];
+ 4 : data_o <= seq[31:24];
+ 5 : data_o <= seq[23:16];
+ 6 : data_o <= seq[15:8];
+ 7 : data_o <= seq[7:0];
+ 8 : data_o <= header[7:0];
+ 9 : data_o <= header[15:8];
+ 10 : data_o <= header[23:16];
+ 11 : data_o <= header[31:24];
+ 12 : data_o <= header[39:32];
+ 13 : data_o <= header[47:40];
+ 14 : data_o <= header[55:48];
+ 15 : data_o <= header[63:56];
+ 16 : data_o <= header[71:64];
+ 17 : data_o <= header[79:72];
+ 18 : data_o <= header[87:80];
+ 19 : data_o <= header[95:88];
+ 20 : data_o <= header[103:96];
+ 21 : data_o <= header[111:104];
+ 22 : data_o <= header[119:112];
+ 23 : data_o <= header[127:120];
+
+ 32'hFFFF_FFFC : data_o <= crc_out[31:24];
+ 32'hFFFF_FFFD : data_o <= crc_out[23:16];
+ 32'hFFFF_FFFE : data_o <= crc_out[15:8];
+ 32'hFFFF_FFFF : data_o <= crc_out[7:0];
+ default : data_o <= state[7:0];
+ endcase // case (state)
+
+ assign src_rdy_o = 1;
+ assign sof_o = (state == 0);
+ assign eof_o = (state == 32'hFFFF_FFFF);
+
+ wire clear_crc = eof_o & src_rdy_o & dst_rdy_i;
+
+// crc crc(.clk(clk), .reset(reset), .clear(clear_crc), .data(data_o),
+// .calc(calc_crc), .crc_out(crc_out), .match());
+ always @(posedge clk)
+ if(reset | clear | clear_crc)
+ crc_out <= 0;
+ else
+ if(calc_crc)
+ crc_out <= crc_out + data_o;
+
+endmodule // packet_generator
diff --git a/fpga/usrp2/control_lib/newfifo/packet_generator32.v b/fpga/usrp2/fifo/packet_generator32.v
index 6f8004964..1dc57191d 100644
--- a/fpga/usrp2/control_lib/newfifo/packet_generator32.v
+++ b/fpga/usrp2/fifo/packet_generator32.v
@@ -2,6 +2,7 @@
module packet_generator32
(input clk, input reset, input clear,
+ input [127:0] header,
output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
wire [7:0] ll_data;
@@ -10,6 +11,7 @@ module packet_generator32
packet_generator pkt_gen
(.clk(clk), .reset(reset), .clear(clear),
.data_o(ll_data), .sof_o(ll_sof), .eof_o(ll_eof),
+ .header(header),
.src_rdy_o(ll_src_rdy), .dst_rdy_i(~ll_dst_rdy_n));
ll8_to_fifo36 ll8_to_f36
diff --git a/fpga/usrp2/fifo/packet_router.v b/fpga/usrp2/fifo/packet_router.v
index 161b59016..7774ff076 100644
--- a/fpga/usrp2/fifo/packet_router.v
+++ b/fpga/usrp2/fifo/packet_router.v
@@ -33,7 +33,8 @@ module packet_router
// Input Interfaces (in to router)
input [35:0] ser_inp_data, input ser_inp_valid, output ser_inp_ready,
- input [35:0] dsp_inp_data, input dsp_inp_valid, output dsp_inp_ready,
+ input [35:0] dsp0_inp_data, input dsp0_inp_valid, output dsp0_inp_ready,
+ input [35:0] dsp1_inp_data, input dsp1_inp_valid, output dsp1_inp_ready,
input [35:0] eth_inp_data, input eth_inp_valid, output eth_inp_ready,
input [35:0] err_inp_data, input err_inp_valid, output err_inp_ready,
@@ -68,28 +69,14 @@ module packet_router
//setting register for mode control
wire [31:0] _sreg_mode_ctrl;
+ wire master_mode_flag;
+
setting_reg #(.my_addr(CTRL_BASE+0), .width(1)) sreg_mode_ctrl(
.clk(stream_clk),.rst(stream_rst),
.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(master_mode_flag),.changed()
);
- //setting register to program the IP address
- wire [31:0] my_ip_addr;
- setting_reg #(.my_addr(CTRL_BASE+1)) sreg_ip_addr(
- .clk(stream_clk),.rst(stream_rst),
- .strobe(set_stb),.addr(set_addr),.in(set_data),
- .out(my_ip_addr),.changed()
- );
-
- //setting register to program the UDP data ports
- wire [15:0] dsp0_udp_port, dsp1_udp_port;
- setting_reg #(.my_addr(CTRL_BASE+2)) sreg_data_ports(
- .clk(stream_clk),.rst(stream_rst),
- .strobe(set_stb),.addr(set_addr),.in(set_data),
- .out({dsp1_udp_port, dsp0_udp_port}),.changed()
- );
-
//assign status output signals
wire [31:0] cpu_iface_status;
assign status = {
@@ -116,6 +103,11 @@ module packet_router
wire _eth_inp_valid;
wire _eth_inp_ready;
+ // dummy signals to connect fifo_short
+ wire [35:0] _com_inp_data;
+ wire _com_inp_valid;
+ wire _com_inp_ready;
+
valve36 eth_inp_valve (
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .shutoff(~master_mode_flag),
.data_i(eth_inp_data), .src_rdy_i(eth_inp_valid), .dst_rdy_o(eth_inp_ready),
@@ -126,10 +118,17 @@ module packet_router
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr), .cross(~master_mode_flag),
.data0_i(_eth_inp_data), .src0_rdy_i(_eth_inp_valid), .dst0_rdy_o(_eth_inp_ready),
.data1_i(ser_inp_data), .src1_rdy_i(ser_inp_valid), .dst1_rdy_o(ser_inp_ready),
- .data0_o(com_inp_data), .src0_rdy_o(com_inp_valid), .dst0_rdy_i(com_inp_ready),
+ .data0_o(_com_inp_data), .src0_rdy_o(_com_inp_valid), .dst0_rdy_i(_com_inp_ready),
.data1_o(ext_inp_data), .src1_rdy_o(ext_inp_valid), .dst1_rdy_i(ext_inp_ready)
);
+ // short fifo in the packet inspection path to help timing
+ fifo_short #(.WIDTH(36)) com_inp_fifo
+ (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
+ .datain(_com_inp_data), .src_rdy_i(_com_inp_valid), .dst_rdy_o(_com_inp_ready),
+ .dataout(com_inp_data), .src_rdy_o(com_inp_valid), .dst_rdy_i(com_inp_ready),
+ .space(), .occupied() );
+
////////////////////////////////////////////////////////////////////
// Communication output sink crossbar
// When in master mode:
@@ -166,36 +165,34 @@ module packet_router
////////////////////////////////////////////////////////////////////
// Communication output source combiner (feeds UDP proto machine)
- // - DSP framer
+ // - DSP input
// - CPU input
// - ERR input
////////////////////////////////////////////////////////////////////
- //streaming signals from the dsp framer to the combiner
- wire [35:0] dsp_frm_data;
- wire dsp_frm_valid;
- wire dsp_frm_ready;
-
//dummy signals to join the the muxes below
wire [35:0] _combiner0_data, _combiner1_data;
wire _combiner0_valid, _combiner1_valid;
wire _combiner0_ready, _combiner1_ready;
- fifo36_mux _com_output_combiner0(
+ fifo36_mux #(.prio(0)) // No priority, fair sharing
+ _com_output_combiner0(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .data0_i(dsp_frm_data), .src0_rdy_i(dsp_frm_valid), .dst0_rdy_o(dsp_frm_ready),
- .data1_i(err_inp_data), .src1_rdy_i(err_inp_valid), .dst1_rdy_o(err_inp_ready),
+ .data0_i(err_inp_data), .src0_rdy_i(err_inp_valid), .dst0_rdy_o(err_inp_ready),
+ .data1_i(cpu_inp_data), .src1_rdy_i(cpu_inp_valid), .dst1_rdy_o(cpu_inp_ready),
.data_o(_combiner0_data), .src_rdy_o(_combiner0_valid), .dst_rdy_i(_combiner0_ready)
);
- fifo36_mux _com_output_combiner1(
+ fifo36_mux #(.prio(0)) // No priority, fair sharing
+ _com_output_combiner1(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .data0_i(32'b0), .src0_rdy_i(1'b0), .dst0_rdy_o(), //mux out from dsp1 can go here
- .data1_i(cpu_inp_data), .src1_rdy_i(cpu_inp_valid), .dst1_rdy_o(cpu_inp_ready),
+ .data0_i(dsp0_inp_data), .src0_rdy_i(dsp0_inp_valid), .dst0_rdy_o(dsp0_inp_ready),
+ .data1_i(dsp1_inp_data), .src1_rdy_i(dsp1_inp_valid), .dst1_rdy_o(dsp1_inp_ready),
.data_o(_combiner1_data), .src_rdy_o(_combiner1_valid), .dst_rdy_i(_combiner1_ready)
);
- fifo36_mux com_output_source(
+ fifo36_mux #(.prio(1)) // Give priority to err/cpu over dsp
+ com_output_source(
.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.data0_i(_combiner0_data), .src0_rdy_i(_combiner0_valid), .dst0_rdy_o(_combiner0_ready),
.data1_i(_combiner1_data), .src1_rdy_i(_combiner1_valid), .dst1_rdy_o(_combiner1_ready),
@@ -204,6 +201,7 @@ module packet_router
////////////////////////////////////////////////////////////////////
// Interface CPU to memory mapped wishbone
+ // - Uses 1 setting register
////////////////////////////////////////////////////////////////////
buffer_int2 #(.BASE(CTRL_BASE+3), .BUF_SIZE(BUF_SIZE)) cpu_to_wb(
.clk(stream_clk), .rst(stream_rst | stream_clr),
@@ -225,218 +223,21 @@ module packet_router
);
////////////////////////////////////////////////////////////////////
- // Communication input inspector
- // - inspect com input and send it to DSP, EXT, CPU, or BOTH
- ////////////////////////////////////////////////////////////////////
- localparam COM_INSP_STATE_READ_COM_PRE = 0;
- localparam COM_INSP_STATE_READ_COM = 1;
- localparam COM_INSP_STATE_WRITE_REGS = 2;
- localparam COM_INSP_STATE_WRITE_LIVE = 3;
-
- localparam COM_INSP_DEST_DSP = 0;
- localparam COM_INSP_DEST_EXT = 1;
- localparam COM_INSP_DEST_CPU = 2;
- localparam COM_INSP_DEST_BOF = 3;
-
- localparam COM_INSP_MAX_NUM_DREGS = 13; //padded_eth + ip + udp + seq + vrt_hdr
- localparam COM_INSP_DREGS_DSP_OFFSET = 11; //offset to start dsp at
-
- //output inspector interfaces
- wire [35:0] com_insp_out_dsp_data;
- wire com_insp_out_dsp_valid;
- wire com_insp_out_dsp_ready;
-
- wire [35:0] com_insp_out_ext_data;
- wire com_insp_out_ext_valid;
- wire com_insp_out_ext_ready;
-
- wire [35:0] com_insp_out_cpu_data;
- wire com_insp_out_cpu_valid;
- wire com_insp_out_cpu_ready;
-
- wire [35:0] com_insp_out_bof_data;
- wire com_insp_out_bof_valid;
- wire com_insp_out_bof_ready;
-
- //connect this fast-path signals directly to the DSP out
- assign dsp_out_data = com_insp_out_dsp_data;
- assign dsp_out_valid = com_insp_out_dsp_valid;
- assign com_insp_out_dsp_ready = dsp_out_ready;
-
- reg [1:0] com_insp_state;
- reg [1:0] com_insp_dest;
- reg [3:0] com_insp_dreg_count; //data registers to buffer headers
- wire [3:0] com_insp_dreg_count_next = com_insp_dreg_count + 1'b1;
- wire com_insp_dreg_counter_done = (com_insp_dreg_count_next == COM_INSP_MAX_NUM_DREGS)? 1'b1 : 1'b0;
- reg [35:0] com_insp_dregs [COM_INSP_MAX_NUM_DREGS-1:0];
-
- //extract various packet components:
- wire [47:0] com_insp_dregs_eth_dst_mac = {com_insp_dregs[0][15:0], com_insp_dregs[1][31:0]};
- wire [15:0] com_insp_dregs_eth_type = com_insp_dregs[3][15:0];
- wire [7:0] com_insp_dregs_ipv4_proto = com_insp_dregs[6][23:16];
- wire [31:0] com_insp_dregs_ipv4_dst_addr = com_insp_dregs[8][31:0];
- wire [15:0] com_insp_dregs_udp_dst_port = com_insp_dregs[9][15:0];
- wire [15:0] com_insp_dregs_vrt_size = com_inp_data[15:0];
-
- //Inspector output flags special case:
- //Inject SOF into flags at first DSP line.
- wire [3:0] com_insp_out_flags = (
- (com_insp_dreg_count == COM_INSP_DREGS_DSP_OFFSET) &&
- (com_insp_dest == COM_INSP_DEST_DSP)
- )? 4'b0001 : com_insp_dregs[com_insp_dreg_count][35:32];
-
- //The communication inspector ouput data and valid signals:
- //Mux between com input and data registers based on the state.
- wire [35:0] com_insp_out_data = (com_insp_state == COM_INSP_STATE_WRITE_REGS)?
- {com_insp_out_flags, com_insp_dregs[com_insp_dreg_count][31:0]} : com_inp_data
- ;
- wire com_insp_out_valid =
- (com_insp_state == COM_INSP_STATE_WRITE_REGS)? 1'b1 : (
- (com_insp_state == COM_INSP_STATE_WRITE_LIVE)? com_inp_valid : (
- 1'b0));
-
- //The communication inspector ouput ready signal:
- //Mux between the various destination ready signals.
- wire com_insp_out_ready =
- (com_insp_dest == COM_INSP_DEST_DSP)? com_insp_out_dsp_ready : (
- (com_insp_dest == COM_INSP_DEST_EXT)? com_insp_out_ext_ready : (
- (com_insp_dest == COM_INSP_DEST_CPU)? com_insp_out_cpu_ready : (
- (com_insp_dest == COM_INSP_DEST_BOF)? com_insp_out_bof_ready : (
- 1'b0))));
-
- //Always connected output data lines.
- assign com_insp_out_dsp_data = com_insp_out_data;
- assign com_insp_out_ext_data = com_insp_out_data;
- assign com_insp_out_cpu_data = com_insp_out_data;
- assign com_insp_out_bof_data = com_insp_out_data;
-
- //Destination output valid signals:
- //Comes from inspector valid when destination is selected, and otherwise low.
- assign com_insp_out_dsp_valid = (com_insp_dest == COM_INSP_DEST_DSP)? com_insp_out_valid : 1'b0;
- assign com_insp_out_ext_valid = (com_insp_dest == COM_INSP_DEST_EXT)? com_insp_out_valid : 1'b0;
- assign com_insp_out_cpu_valid = (com_insp_dest == COM_INSP_DEST_CPU)? com_insp_out_valid : 1'b0;
- assign com_insp_out_bof_valid = (com_insp_dest == COM_INSP_DEST_BOF)? com_insp_out_valid : 1'b0;
-
- //The communication inspector ouput ready signal:
- //Always ready when storing to data registers,
- //comes from inspector ready output when live,
- //and otherwise low.
- assign com_inp_ready =
- (com_insp_state == COM_INSP_STATE_READ_COM_PRE) ? 1'b1 : (
- (com_insp_state == COM_INSP_STATE_READ_COM) ? 1'b1 : (
- (com_insp_state == COM_INSP_STATE_WRITE_LIVE) ? com_insp_out_ready : (
- 1'b0)));
-
- always @(posedge stream_clk)
- if(stream_rst | stream_clr) begin
- com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
- com_insp_dreg_count <= 0;
- end
- else begin
- case(com_insp_state)
- COM_INSP_STATE_READ_COM_PRE: begin
- if (com_inp_ready & com_inp_valid & com_inp_data[32]) begin
- com_insp_state <= COM_INSP_STATE_READ_COM;
- com_insp_dreg_count <= com_insp_dreg_count_next;
- com_insp_dregs[com_insp_dreg_count] <= com_inp_data;
- end
- end
-
- COM_INSP_STATE_READ_COM: begin
- if (com_inp_ready & com_inp_valid) begin
- com_insp_dregs[com_insp_dreg_count] <= com_inp_data;
- if (com_insp_dreg_counter_done | com_inp_data[33]) begin
- com_insp_state <= COM_INSP_STATE_WRITE_REGS;
- com_insp_dreg_count <= 0;
-
- //---------- begin inspection decision -----------//
- //EOF or bcast or not IPv4 or not UDP:
- if (
- com_inp_data[33] || (com_insp_dregs_eth_dst_mac == 48'hffffffffffff) ||
- (com_insp_dregs_eth_type != 16'h800) || (com_insp_dregs_ipv4_proto != 8'h11)
- ) begin
- com_insp_dest <= COM_INSP_DEST_BOF;
- end
-
- //not my IP address:
- else if (com_insp_dregs_ipv4_dst_addr != my_ip_addr) begin
- com_insp_dest <= COM_INSP_DEST_EXT;
- end
-
- //UDP data port and VRT:
- else if ((com_insp_dregs_udp_dst_port == dsp0_udp_port) && (com_insp_dregs_vrt_size != 16'h0)) begin
- com_insp_dest <= COM_INSP_DEST_DSP;
- com_insp_dreg_count <= COM_INSP_DREGS_DSP_OFFSET;
- end
-
- //other:
- else begin
- com_insp_dest <= COM_INSP_DEST_CPU;
- end
- //---------- end inspection decision -------------//
-
- end
- else begin
- com_insp_dreg_count <= com_insp_dreg_count_next;
- end
- end
- end
-
- COM_INSP_STATE_WRITE_REGS: begin
- if (com_insp_out_ready & com_insp_out_valid) begin
- if (com_insp_out_data[33]) begin
- com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
- com_insp_dreg_count <= 0;
- end
- else if (com_insp_dreg_counter_done) begin
- com_insp_state <= COM_INSP_STATE_WRITE_LIVE;
- com_insp_dreg_count <= 0;
- end
- else begin
- com_insp_dreg_count <= com_insp_dreg_count_next;
- end
- end
- end
-
- COM_INSP_STATE_WRITE_LIVE: begin
- if (com_insp_out_ready & com_insp_out_valid & com_insp_out_data[33]) begin
- com_insp_state <= COM_INSP_STATE_READ_COM_PRE;
- end
- end
-
- endcase //com_insp_state
- end
-
- ////////////////////////////////////////////////////////////////////
- // Splitter and output muxes for the bof packets
- // - split the bof packets into two streams
- // - mux split packets into cpu out and ext out
+ // Packet Dispatcher
+ // - Uses 2 setting registers
+ // - provide buffering before cpu for random + small packet bursts
////////////////////////////////////////////////////////////////////
+ wire [35:0] _cpu_out_data;
+ wire _cpu_out_valid;
+ wire _cpu_out_ready;
- //dummy signals to join the the splitter and muxes below
- wire [35:0] _split_to_ext_data, _split_to_cpu_data, _cpu_out_data;
- wire _split_to_ext_valid, _split_to_cpu_valid, _cpu_out_valid;
- wire _split_to_ext_ready, _split_to_cpu_ready, _cpu_out_ready;
-
- splitter36 bof_out_splitter(
+ packet_dispatcher36_x3 #(.BASE(CTRL_BASE+1)) packet_dispatcher(
.clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
- .inp_data(com_insp_out_bof_data), .inp_valid(com_insp_out_bof_valid), .inp_ready(com_insp_out_bof_ready),
- .out0_data(_split_to_ext_data), .out0_valid(_split_to_ext_valid), .out0_ready(_split_to_ext_ready),
- .out1_data(_split_to_cpu_data), .out1_valid(_split_to_cpu_valid), .out1_ready(_split_to_cpu_ready)
- );
-
- fifo36_mux ext_out_mux(
- .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .data0_i(com_insp_out_ext_data), .src0_rdy_i(com_insp_out_ext_valid), .dst0_rdy_o(com_insp_out_ext_ready),
- .data1_i(_split_to_ext_data), .src1_rdy_i(_split_to_ext_valid), .dst1_rdy_o(_split_to_ext_ready),
- .data_o(ext_out_data), .src_rdy_o(ext_out_valid), .dst_rdy_i(ext_out_ready)
- );
-
- fifo36_mux cpu_out_mux(
- .clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .data0_i(com_insp_out_cpu_data), .src0_rdy_i(com_insp_out_cpu_valid), .dst0_rdy_o(com_insp_out_cpu_ready),
- .data1_i(_split_to_cpu_data), .src1_rdy_i(_split_to_cpu_valid), .dst1_rdy_o(_split_to_cpu_ready),
- .data_o(_cpu_out_data), .src_rdy_o(_cpu_out_valid), .dst_rdy_i(_cpu_out_ready)
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .com_inp_data(com_inp_data), .com_inp_valid(com_inp_valid), .com_inp_ready(com_inp_ready),
+ .ext_out_data(ext_out_data), .ext_out_valid(ext_out_valid), .ext_out_ready(ext_out_ready),
+ .dsp_out_data(dsp_out_data), .dsp_out_valid(dsp_out_valid), .dsp_out_ready(dsp_out_ready),
+ .cpu_out_data(_cpu_out_data), .cpu_out_valid(_cpu_out_valid), .cpu_out_ready(_cpu_out_ready)
);
fifo_cascade #(.WIDTH(36), .SIZE(9/*512 lines plenty for short pkts*/)) cpu_out_fifo (
@@ -446,23 +247,13 @@ module packet_router
);
////////////////////////////////////////////////////////////////////
- // DSP input framer
- ////////////////////////////////////////////////////////////////////
-
- dsp_framer36 #(.BUF_SIZE(BUF_SIZE)) dsp0_framer36(
- .clk(stream_clk), .rst(stream_rst), .clr(stream_clr),
- .inp_data(dsp_inp_data), .inp_valid(dsp_inp_valid), .inp_ready(dsp_inp_ready),
- .out_data(dsp_frm_data), .out_valid(dsp_frm_valid), .out_ready(dsp_frm_ready)
- );
-
- ////////////////////////////////////////////////////////////////////
// UDP TX Protocol machine
////////////////////////////////////////////////////////////////////
//dummy signals to connect the components below
- wire [18:0] _udp_r2s_data, _udp_s2p_data, _udp_p2s_data, _udp_s2r_data;
- wire _udp_r2s_valid, _udp_s2p_valid, _udp_p2s_valid, _udp_s2r_valid;
- wire _udp_r2s_ready, _udp_s2p_ready, _udp_p2s_ready, _udp_s2r_ready;
+ wire [18:0] _udp_r2s_data, _udp_s2r_data;
+ wire _udp_r2s_valid, _udp_s2r_valid;
+ wire _udp_r2s_ready, _udp_s2r_ready;
wire [35:0] _com_out_data;
wire _com_out_valid, _com_out_ready;
@@ -472,23 +263,11 @@ module packet_router
.f36_datain(udp_out_data), .f36_src_rdy_i(udp_out_valid), .f36_dst_rdy_o(udp_out_ready),
.f19_dataout(_udp_r2s_data), .f19_src_rdy_o(_udp_r2s_valid), .f19_dst_rdy_i(_udp_r2s_ready) );
- fifo_short #(.WIDTH(19)) udp_shortfifo19_inp
- (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .datain(_udp_r2s_data), .src_rdy_i(_udp_r2s_valid), .dst_rdy_o(_udp_r2s_ready),
- .dataout(_udp_s2p_data), .src_rdy_o(_udp_s2p_valid), .dst_rdy_i(_udp_s2p_ready),
- .space(), .occupied() );
-
prot_eng_tx #(.BASE(UDP_BASE)) udp_prot_eng_tx
(.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
- .datain(_udp_s2p_data), .src_rdy_i(_udp_s2p_valid), .dst_rdy_o(_udp_s2p_ready),
- .dataout(_udp_p2s_data), .src_rdy_o(_udp_p2s_valid), .dst_rdy_i(_udp_p2s_ready) );
-
- fifo_short #(.WIDTH(19)) udp_shortfifo19_out
- (.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
- .datain(_udp_p2s_data), .src_rdy_i(_udp_p2s_valid), .dst_rdy_o(_udp_p2s_ready),
- .dataout(_udp_s2r_data), .src_rdy_o(_udp_s2r_valid), .dst_rdy_i(_udp_s2r_ready),
- .space(), .occupied() );
+ .datain(_udp_r2s_data), .src_rdy_i(_udp_r2s_valid), .dst_rdy_o(_udp_r2s_ready),
+ .dataout(_udp_s2r_data), .src_rdy_o(_udp_s2r_valid), .dst_rdy_i(_udp_s2r_ready) );
fifo19_to_fifo36 udp_fifo19_to_fifo36
(.clk(stream_clk), .reset(stream_rst), .clear(stream_clr),
@@ -507,8 +286,10 @@ module packet_router
////////////////////////////////////////////////////////////////////
assign debug = {
- //inputs to the router (8)
- dsp_inp_ready, dsp_inp_valid,
+ //inputs to the router (12)
+ dsp0_inp_ready, dsp0_inp_valid,
+ dsp1_inp_ready, dsp1_inp_valid,
+ err_inp_ready, err_inp_valid,
ser_inp_ready, ser_inp_valid,
eth_inp_ready, eth_inp_valid,
cpu_inp_ready, cpu_inp_valid,
@@ -519,17 +300,13 @@ module packet_router
eth_out_ready, eth_out_valid,
cpu_out_ready, cpu_out_valid,
- //inspector interfaces (8)
- com_insp_out_dsp_ready, com_insp_out_dsp_valid,
- com_insp_out_ext_ready, com_insp_out_ext_valid,
- com_insp_out_cpu_ready, com_insp_out_cpu_valid,
- com_insp_out_bof_ready, com_insp_out_bof_valid,
-
//other interfaces (8)
ext_inp_ready, ext_inp_valid,
com_out_ready, com_out_valid,
ext_out_ready, ext_out_valid,
- com_inp_ready, com_inp_valid
+ com_inp_ready, com_inp_valid,
+
+ 4'b0
};
endmodule // packet_router
diff --git a/fpga/usrp2/control_lib/newfifo/packet_tb.v b/fpga/usrp2/fifo/packet_tb.v
index 3c423d2ba..3c423d2ba 100644
--- a/fpga/usrp2/control_lib/newfifo/packet_tb.v
+++ b/fpga/usrp2/fifo/packet_tb.v
diff --git a/fpga/usrp2/control_lib/newfifo/packet_verifier.v b/fpga/usrp2/fifo/packet_verifier.v
index b49ad1bbb..21a4c136e 100644
--- a/fpga/usrp2/control_lib/newfifo/packet_verifier.v
+++ b/fpga/usrp2/fifo/packet_verifier.v
@@ -18,7 +18,7 @@ module packet_verifier
reg [31:0] length;
wire first_byte, last_byte;
reg second_byte, last_byte_d1;
-
+ wire match_crc;
wire calc_crc = src_rdy_i & dst_rdy_o;
crc crc(.clk(clk), .reset(reset), .clear(last_byte_d1), .data(data_i),
diff --git a/fpga/usrp2/fifo/packet_verifier32.v b/fpga/usrp2/fifo/packet_verifier32.v
new file mode 100644
index 000000000..ec08e657d
--- /dev/null
+++ b/fpga/usrp2/fifo/packet_verifier32.v
@@ -0,0 +1,23 @@
+
+
+module packet_verifier32
+ (input clk, input reset, input clear,
+ input [35:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [31:0] total, output [31:0] crc_err, output [31:0] seq_err, output [31:0] len_err);
+
+ wire [7:0] ll_data;
+ wire ll_sof, ll_eof, ll_src_rdy, ll_dst_rdy;
+
+ fifo36_to_ll8 f36_to_ll8
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f36_data(data_i), .f36_src_rdy_i(src_rdy_i), .f36_dst_rdy_o(dst_rdy_o),
+ .ll_data(ll_data), .ll_sof(ll_sof), .ll_eof(ll_eof),
+ .ll_src_rdy(ll_src_rdy), .ll_dst_rdy(ll_dst_rdy));
+
+ packet_verifier pkt_ver
+ (.clk(clk), .reset(reset), .clear(clear),
+ .data_i(ll_data), .sof_i(ll_sof), .eof_i(ll_eof),
+ .src_rdy_i(ll_src_rdy), .dst_rdy_o(ll_dst_rdy),
+ .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err));
+
+endmodule // packet_verifier32
diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v b/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
index cf8b6e861..9a8e37ce9 100644
--- a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
+++ b/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
@@ -1,9 +1,4 @@
-// Assumes an asynchronous GPMC cycle
-// If a packet bigger or smaller than we are told is sent, behavior is undefined.
-// If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error.
-// If there is a bus error, we should be reset
-
module fifo_to_gpmc_async
(input clk, input reset, input clear,
input [17:0] data_i, input src_rdy_i, output dst_rdy_o,
diff --git a/fpga/usrp2/gpmc/gpmc_async.v b/fpga/usrp2/gpmc/gpmc_async.v
index 23bad56ae..02bf45b8a 100644
--- a/fpga/usrp2/gpmc/gpmc_async.v
+++ b/fpga/usrp2/gpmc/gpmc_async.v
@@ -1,7 +1,9 @@
//////////////////////////////////////////////////////////////////////////////////
module gpmc_async
- #(parameter TXFIFOSIZE = 11, parameter RXFIFOSIZE = 11)
+ #(parameter TXFIFOSIZE = 11,
+ parameter RXFIFOSIZE = 11,
+ parameter BUSDEBUG = 1)
(// GPMC signals
input arst,
input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE,
@@ -21,7 +23,9 @@ module gpmc_async
input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o,
input [15:0] tx_frame_len, output [15:0] rx_frame_len,
-
+
+ output tx_underrun, output rx_overrun,
+ input [7:0] test_rate, input [3:0] test_ctrl,
output [31:0] debug
);
@@ -49,8 +53,8 @@ module gpmc_async
wire [17:0] tx18_data, tx18b_data;
wire tx18_src_rdy, tx18_dst_rdy, tx18b_src_rdy, tx18b_dst_rdy;
wire [15:0] tx_fifo_space;
- wire [35:0] tx36_data;
- wire tx36_src_rdy, tx36_dst_rdy;
+ wire [35:0] tx36_data, tx_data;
+ wire tx36_src_rdy, tx36_dst_rdy, tx_src_rdy, tx_dst_rdy;
gpmc_to_fifo_async gpmc_to_fifo_async
(.EM_D(EM_D), .EM_NBE(EM_NBE), .EM_NCS(EM_NCS4), .EM_NWE(EM_NWE),
@@ -70,9 +74,9 @@ module gpmc_async
.f36_dataout(tx36_data), .f36_src_rdy_o(tx36_src_rdy), .f36_dst_rdy_i(tx36_dst_rdy));
fifo_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_fifo36
- (.clk(wb_clk), .reset(wb_rst), .clear(clear_tx),
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),
.datain(tx36_data), .src_rdy_i(tx36_src_rdy), .dst_rdy_o(tx36_dst_rdy),
- .dataout(tx_data_o), .src_rdy_o(tx_src_rdy_o), .dst_rdy_i(tx_dst_rdy_i));
+ .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy));
// ////////////////////////////////////////////
// RX Data Path
@@ -80,13 +84,13 @@ module gpmc_async
wire [17:0] rx18_data, rx18b_data;
wire rx18_src_rdy, rx18_dst_rdy, rx18b_src_rdy, rx18b_dst_rdy;
wire [15:0] rx_fifo_space;
- wire [35:0] rx36_data;
- wire rx36_src_rdy, rx36_dst_rdy;
+ wire [35:0] rx36_data, rx_data;
+ wire rx36_src_rdy, rx36_dst_rdy, rx_src_rdy, rx_dst_rdy;
wire dummy;
fifo_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_fifo36
- (.clk(wb_clk), .reset(wb_rst), .clear(clear_rx),
- .datain(rx_data_i), .src_rdy_i(rx_src_rdy_i), .dst_rdy_o(rx_dst_rdy_o),
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .datain(rx_data), .src_rdy_i(rx_src_rdy), .dst_rdy_o(rx_dst_rdy),
.dataout(rx36_data), .src_rdy_o(rx36_src_rdy), .dst_rdy_i(rx36_dst_rdy));
fifo36_to_fifo19 #(.LE(1)) f36_to_f19 // Little endian because ARM is LE
@@ -125,6 +129,100 @@ module gpmc_async
.wb_sel_o(wb_sel_o), .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_we_o(wb_we_o),
.wb_ack_i(wb_ack_i) );
- assign debug = pkt_count;
+// assign debug = pkt_count;
+
+ // ////////////////////////////////////////////
+ // Test support, traffic generator, loopback, etc.
+
+ // RX side muxes test data into the same stream
+ wire [35:0] timedrx_data, loopbackrx_data, testrx_data;
+ wire [35:0] timedtx_data, loopbacktx_data, testtx_data;
+ wire timedrx_src_rdy, timedrx_dst_rdy, loopbackrx_src_rdy, loopbackrx_dst_rdy,
+ testrx_src_rdy, testrx_dst_rdy;
+ wire timedtx_src_rdy, timedtx_dst_rdy, loopbacktx_src_rdy, loopbacktx_dst_rdy,
+ testtx_src_rdy, testtx_dst_rdy;
+ wire timedrx_src_rdy_int, timedrx_dst_rdy_int, timedtx_src_rdy_int, timedtx_dst_rdy_int;
+
+ wire [31:0] total, crc_err, seq_err, len_err;
+ wire sel_testtx = test_ctrl[0];
+ wire sel_loopbacktx = test_ctrl[1];
+ wire pkt_src_enable = test_ctrl[2];
+ wire pkt_sink_enable = test_ctrl[3];
+
+ fifo36_mux rx_test_mux_lvl_1
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .data0_i(timedrx_data), .src0_rdy_i(timedrx_src_rdy), .dst0_rdy_o(timedrx_dst_rdy),
+ .data1_i(loopbackrx_data), .src1_rdy_i(loopbackrx_src_rdy), .dst1_rdy_o(loopbackrx_dst_rdy),
+ .data_o(testrx_data), .src_rdy_o(testrx_src_rdy), .dst_rdy_i(testrx_dst_rdy));
+
+ fifo36_mux rx_test_mux_lvl_2
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .data0_i(testrx_data), .src0_rdy_i(testrx_src_rdy), .dst0_rdy_o(testrx_dst_rdy),
+ .data1_i(rx_data_i), .src1_rdy_i(rx_src_rdy_i), .dst1_rdy_o(rx_dst_rdy_o),
+ .data_o(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy));
+
+ fifo_short #(.WIDTH(36)) loopback_fifo
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx | clear_rx),
+ .datain(loopbacktx_data), .src_rdy_i(loopbacktx_src_rdy), .dst_rdy_o(loopbacktx_dst_rdy),
+ .dataout(loopbackrx_data), .src_rdy_o(loopbackrx_src_rdy), .dst_rdy_i(loopbackrx_dst_rdy));
+ // Crossbar used as a demux for switching TX stream to main DSP or to test logic
+ crossbar36 tx_crossbar_lvl_1
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),
+ .cross(sel_testtx),
+ .data0_i(tx_data), .src0_rdy_i(tx_src_rdy), .dst0_rdy_o(tx_dst_rdy),
+ .data1_i(tx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(), // No 2nd input
+ .data0_o(tx_data_o), .src0_rdy_o(tx_src_rdy_o), .dst0_rdy_i(tx_dst_rdy_i),
+ .data1_o(testtx_data), .src1_rdy_o(testtx_src_rdy), .dst1_rdy_i(testtx_dst_rdy) );
+
+ crossbar36 tx_crossbar_lvl_2
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),
+ .cross(sel_loopbacktx),
+ .data0_i(testtx_data), .src0_rdy_i(testtx_src_rdy), .dst0_rdy_o(testtx_dst_rdy),
+ .data1_i(testtx_data), .src1_rdy_i(1'b0), .dst1_rdy_o(), // No 2nd input
+ .data0_o(timedtx_data), .src0_rdy_o(timedtx_src_rdy), .dst0_rdy_i(timedtx_dst_rdy),
+ .data1_o(loopbacktx_data), .src1_rdy_o(loopbacktx_src_rdy), .dst1_rdy_i(loopbacktx_dst_rdy) );
+
+ // Fixed rate TX traffic consumer
+ fifo_pacer tx_pacer
+ (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_sink_enable),
+ .src1_rdy_i(timedtx_src_rdy), .dst1_rdy_o(timedtx_dst_rdy),
+ .src2_rdy_o(timedtx_src_rdy_int), .dst2_rdy_i(timedtx_dst_rdy_int),
+ .underrun(tx_underrun), .overrun());
+
+ packet_verifier32 pktver32
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),
+ .data_i(timedtx_data), .src_rdy_i(timedtx_src_rdy_int), .dst_rdy_o(timedtx_dst_rdy_int),
+ .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err));
+
+ // Fixed rate RX traffic generator
+ packet_generator32 pktgen32
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .header({len_err,seq_err,crc_err,total}),
+ .data_o(timedrx_data), .src_rdy_o(timedrx_src_rdy_int), .dst_rdy_i(timedrx_dst_rdy_int));
+
+ fifo_pacer rx_pacer
+ (.clk(fifo_clk), .reset(fifo_rst), .rate(test_rate), .enable(pkt_src_enable),
+ .src1_rdy_i(timedrx_src_rdy_int), .dst1_rdy_o(timedrx_dst_rdy_int),
+ .src2_rdy_o(timedrx_src_rdy), .dst2_rdy_i(timedrx_dst_rdy),
+ .underrun(), .overrun(rx_overrun));
+
+ // FIXME -- hook up crossbar controls
+ // // FIXME -- collect error stats
+ // FIXME -- set rates and enables on pacers
+ // FIXME -- make sure packet completes before we shutoff
+ // FIXME -- handle overrun and underrun
+
+wire [0:17] dummy18;
+
+assign debug = {8'd0,
+ test_rate,
+ pkt_src_enable, pkt_sink_enable, timedrx_src_rdy_int, timedrx_dst_rdy_int,
+ timedrx_src_rdy, timedrx_dst_rdy,
+ testrx_src_rdy, testrx_dst_rdy,
+ rx_src_rdy, rx_dst_rdy,
+ rx36_src_rdy, rx36_dst_rdy,
+ rx18_src_rdy, rx18_dst_rdy,
+ rx18b_src_rdy, rx18b_dst_rdy};
+
endmodule // gpmc_async
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
index efcf89276..b783729d5 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
@@ -1,7 +1,7 @@
module simple_gemac_wrapper
#(parameter RXFIFOSIZE=9,
- parameter TXFIFOSIZE=6)
+ parameter TXFIFOSIZE=9)
(input clk125, input reset,
// GMII
output GMII_GTX_CLK, output GMII_TX_EN, output GMII_TX_ER, output [7:0] GMII_TXD,
@@ -30,7 +30,9 @@ module simple_gemac_wrapper
wire pause_req;
wire pause_request_en, pause_respect_en;
wire [15:0] pause_time, pause_thresh, pause_time_req, rx_fifo_space;
-
+
+ wire [31:0] debug_state;
+
wire tx_reset, rx_reset;
reset_sync reset_sync_tx (.clk(tx_clk),.reset_in(reset),.reset_out(tx_reset));
reset_sync reset_sync_rx (.clk(rx_clk),.reset_in(reset),.reset_out(rx_reset));
@@ -49,7 +51,8 @@ module simple_gemac_wrapper
.rx_clk(rx_clk), .rx_data(rx_data),
.rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
.tx_clk(tx_clk), .tx_data(tx_data),
- .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack)
+ .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack),
+ .debug(debug_state)
);
simple_gemac_wb simple_gemac_wb
@@ -65,14 +68,12 @@ module simple_gemac_wrapper
// RX FIFO Chain
wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy;
+ wire [7:0] rx_ll_data;
- wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2;
- wire rx_ll_sof2_n, rx_ll_eof2_n, rx_ll_src_rdy2_n, rx_ll_dst_rdy2_n;
-
- wire [7:0] rx_ll_data, rx_ll_data2;
-
- wire [35:0] rx_f36_data_int1;
- wire rx_f36_src_rdy_int1, rx_f36_dst_rdy_int1;
+ wire [18:0] rx_f19_data_int1, rx_f19_data_int2;
+ wire rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_src_rdy_int2, rx_f19_dst_rdy_int2;
+ wire [35:0] rx_f36_data_int;
+ wire rx_f36_src_rdy_int, rx_f36_dst_rdy_int;
rxmac_to_ll8 rx_adapt
(.clk(rx_clk), .reset(rx_reset), .clear(0),
@@ -80,86 +81,69 @@ module simple_gemac_wrapper
.ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(), // error also encoded in sof/eof
.ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy));
- ll8_shortfifo rx_sfifo
+ ll8_to_fifo19 ll8_to_fifo19
(.clk(rx_clk), .reset(rx_reset), .clear(0),
- .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof),
- .error_i(0), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy),
- .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2),
- .error_o(), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2));
+ .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof),
+ .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy),
+ .f19_data(rx_f19_data_int1), .f19_src_rdy_o(rx_f19_src_rdy_int1), .f19_dst_rdy_i(rx_f19_dst_rdy_int1));
- assign rx_ll_dst_rdy2 = ~rx_ll_dst_rdy2_n;
- assign rx_ll_src_rdy2_n = ~rx_ll_src_rdy2;
- assign rx_ll_sof2_n = ~rx_ll_sof2;
- assign rx_ll_eof2_n = ~rx_ll_eof2;
-
- ll8_to_fifo36 ll8_to_fifo36
+ fifo19_rxrealign fifo19_rxrealign
+ (.clk(rx_clk), .reset(rx_reset), .clear(0),
+ .datain(rx_f19_data_int1), .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1),
+ .dataout(rx_f19_data_int2), .src_rdy_o(rx_f19_src_rdy_int2), .dst_rdy_i(rx_f19_dst_rdy_int2) );
+
+ fifo19_to_fifo36 rx_fifo19_to_fifo36
(.clk(rx_clk), .reset(rx_reset), .clear(0),
- .ll_data(rx_ll_data2), .ll_sof_n(rx_ll_sof2_n), .ll_eof_n(rx_ll_eof2_n),
- .ll_src_rdy_n(rx_ll_src_rdy2_n), .ll_dst_rdy_n(rx_ll_dst_rdy2_n),
- .f36_data(rx_f36_data_int1), .f36_src_rdy_o(rx_f36_src_rdy_int1), .f36_dst_rdy_i(rx_f36_dst_rdy_int1));
+ .f19_datain(rx_f19_data_int2), .f19_src_rdy_i(rx_f19_src_rdy_int2), .f19_dst_rdy_o(rx_f19_dst_rdy_int2),
+ .f36_dataout(rx_f36_data_int), .f36_src_rdy_o(rx_f36_src_rdy_int), .f36_dst_rdy_i(rx_f36_dst_rdy_int) );
fifo_2clock_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
- (.wclk(rx_clk), .datain(rx_f36_data_int1),
- .src_rdy_i(rx_f36_src_rdy_int1), .dst_rdy_o(rx_f36_dst_rdy_int1), .space(rx_fifo_space),
+ (.wclk(rx_clk), .datain(rx_f36_data_int),
+ .src_rdy_i(rx_f36_src_rdy_int), .dst_rdy_o(rx_f36_dst_rdy_int), .space(rx_fifo_space),
.rclk(sys_clk), .dataout(rx_f36_data),
.src_rdy_o(rx_f36_src_rdy), .dst_rdy_i(rx_f36_dst_rdy), .occupied(), .arst(reset));
// TX FIFO Chain
wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
- wire tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2;
- wire tx_ll_sof2_n, tx_ll_eof2_n, tx_ll_src_rdy2_n, tx_ll_dst_rdy2_n;
- wire [7:0] tx_ll_data, tx_ll_data2;
+ wire [7:0] tx_ll_data;
wire [35:0] tx_f36_data_int1;
wire tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1;
fifo_2clock_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_2clk_fifo
- (.wclk(sys_clk), .datain(tx_f36_data),
- .src_rdy_i(tx_f36_src_rdy), .dst_rdy_o(tx_f36_dst_rdy), .space(),
- .rclk(tx_clk), .dataout(tx_f36_data_int1),
- .src_rdy_o(tx_f36_src_rdy_int1), .dst_rdy_i(tx_f36_dst_rdy_int1), .occupied(), .arst(reset));
+ (.wclk(sys_clk), .datain(tx_f36_data), .src_rdy_i(tx_f36_src_rdy), .dst_rdy_o(tx_f36_dst_rdy), .space(),
+ .rclk(tx_clk), .dataout(tx_f36_data_int1), .src_rdy_o(tx_f36_src_rdy_int1), .dst_rdy_i(tx_f36_dst_rdy_int1), .occupied(),
+ .arst(reset));
fifo36_to_ll8 fifo36_to_ll8
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
.f36_data(tx_f36_data_int1), .f36_src_rdy_i(tx_f36_src_rdy_int1), .f36_dst_rdy_o(tx_f36_dst_rdy_int1),
- .ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n),
- .ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(tx_ll_dst_rdy2_n));
+ .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof),
+ .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy));
- assign tx_ll_sof2 = ~tx_ll_sof2_n;
- assign tx_ll_eof2 = ~tx_ll_eof2_n;
- assign tx_ll_src_rdy2 = ~tx_ll_src_rdy2_n;
- assign tx_ll_dst_rdy2_n = ~tx_ll_dst_rdy2;
-
- ll8_shortfifo tx_sfifo
- (.clk(tx_clk), .reset(tx_reset), .clear(clear),
- .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2),
- .error_i(0), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2),
- .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof),
- .error_o(), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy));
-
ll8_to_txmac ll8_to_txmac
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
.ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof),
.ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy),
.tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack));
+ // Flow Control
flow_ctrl_rx flow_ctrl_rx
(.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh),
.rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space),
.tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req));
wire [31:0] debug_tx, debug_rx;
-
+
assign debug_tx = { { tx_ll_data },
- { tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy,
- tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2 },
+ { tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy, 4'b0 },
{ tx_valid, tx_error, tx_ack, tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1, tx_f36_data_int1[34:32]},
{ tx_data} };
assign debug_rx = { { rx_ll_data },
- { rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy,
- rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2 },
- { rx_valid, rx_error, rx_ack, rx_f36_src_rdy_int1, rx_f36_dst_rdy_int1, rx_f36_data_int1[34:32]},
+ { rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy, 4'b0 },
+ { rx_valid, rx_error, rx_ack, rx_f36_src_rdy_int, rx_f36_dst_rdy_int, rx_f36_data_int[34:32]},
{ rx_data} };
assign debug = debug_rx;
endmodule // simple_gemac_wrapper
+
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
index 6cdbd1a59..c155b7d41 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
@@ -68,14 +68,10 @@ module simple_gemac_wrapper19
// RX FIFO Chain
wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy;
+ wire [7:0] rx_ll_data;
- wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2;
- wire rx_ll_sof2_n, rx_ll_eof2_n, rx_ll_src_rdy2_n, rx_ll_dst_rdy2_n;
-
- wire [7:0] rx_ll_data, rx_ll_data2;
-
- wire [18:0] rx_f19_data_int1;
- wire rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1;
+ wire [18:0] rx_f19_data_int1, rx_f19_data_int2;
+ wire rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_src_rdy_int2, rx_f19_dst_rdy_int2;
rxmac_to_ll8 rx_adapt
(.clk(rx_clk), .reset(rx_reset), .clear(0),
@@ -83,28 +79,21 @@ module simple_gemac_wrapper19
.ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(), // error also encoded in sof/eof
.ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy));
- ll8_shortfifo rx_sfifo
- (.clk(rx_clk), .reset(rx_reset), .clear(0),
- .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof),
- .error_i(0), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy),
- .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2),
- .error_o(), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2));
-
- assign rx_ll_dst_rdy2 = ~rx_ll_dst_rdy2_n;
- assign rx_ll_src_rdy2_n = ~rx_ll_src_rdy2;
- assign rx_ll_sof2_n = ~rx_ll_sof2;
- assign rx_ll_eof2_n = ~rx_ll_eof2;
-
ll8_to_fifo19 ll8_to_fifo19
(.clk(rx_clk), .reset(rx_reset), .clear(0),
- .ll_data(rx_ll_data2), .ll_sof_n(rx_ll_sof2_n), .ll_eof_n(rx_ll_eof2_n),
- .ll_src_rdy_n(rx_ll_src_rdy2_n), .ll_dst_rdy_n(rx_ll_dst_rdy2_n),
+ .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof),
+ .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy),
.f19_data(rx_f19_data_int1), .f19_src_rdy_o(rx_f19_src_rdy_int1), .f19_dst_rdy_i(rx_f19_dst_rdy_int1));
+ fifo19_rxrealign fifo19_rxrealign
+ (.clk(rx_clk), .reset(rx_reset), .clear(0),
+ .datain(rx_f19_data_int1), .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1),
+ .dataout(rx_f19_data_int2), .src_rdy_o(rx_f19_src_rdy_int2), .dst_rdy_i(rx_f19_dst_rdy_int2) );
+
//fifo_2clock_cascade #(.WIDTH(19), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
fifo_2clock_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
- (.wclk(rx_clk), .datain(rx_f19_data_int1),
- .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1), .space(rx_fifo_space),
+ (.wclk(rx_clk), .datain(rx_f19_data_int2),
+ .src_rdy_i(rx_f19_src_rdy_int2), .dst_rdy_o(rx_f19_dst_rdy_int2), .space(rx_fifo_space),
.rclk(sys_clk), .dataout(rx_f19_data),
.src_rdy_o(rx_f19_src_rdy), .dst_rdy_i(rx_f19_dst_rdy), .occupied(), .arst(reset));
@@ -160,8 +149,7 @@ module simple_gemac_wrapper19
{ tx_valid, tx_error, tx_ack, tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1, tx_f19_data_int1[18:16]},
{ tx_data} };
assign debug_rx = { { rx_f19_src_rdy, rx_f19_dst_rdy, debug_state[5:0] },
- { rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy,
- rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2 },
+ { rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy, 4'b0 },
{ rx_valid, rx_error, rx_ack, rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_data_int1[18:16]},
{ rx_data} };
diff --git a/fpga/usrp2/top/safe_u2plus/Makefile b/fpga/usrp2/top/safe_u2plus/Makefile
index 62a02ff40..b72241050 100644
--- a/fpga/usrp2/top/safe_u2plus/Makefile
+++ b/fpga/usrp2/top/safe_u2plus/Makefile
@@ -117,7 +117,6 @@ coregen/fifo_xlnx_512x36_2clk.v \
coregen/fifo_xlnx_512x36_2clk.xco \
coregen/fifo_xlnx_64x36_2clk.v \
coregen/fifo_xlnx_64x36_2clk.xco \
-extram/wb_zbt16_b.v \
opencores/8b10b/decode_8b10b.v \
opencores/8b10b/encode_8b10b.v \
opencores/aemb/rtl/verilog/aeMB_bpcu.v \
diff --git a/fpga/usrp2/top/u1e/Makefile b/fpga/usrp2/top/u1e/Makefile
index 3cb9fd8f3..5d721979b 100644
--- a/fpga/usrp2/top/u1e/Makefile
+++ b/fpga/usrp2/top/u1e/Makefile
@@ -23,7 +23,6 @@ include ../../opencores/Makefile.srcs
include ../../vrt/Makefile.srcs
include ../../udp/Makefile.srcs
include ../../coregen/Makefile.srcs
-include ../../extram/Makefile.srcs
include ../../gpmc/Makefile.srcs
##################################################
diff --git a/fpga/usrp2/top/u1e/u1e_core.v b/fpga/usrp2/top/u1e/u1e_core.v
index 7d5924bea..b3d71b4ab 100644
--- a/fpga/usrp2/top/u1e/u1e_core.v
+++ b/fpga/usrp2/top/u1e/u1e_core.v
@@ -1,9 +1,5 @@
-//`define LOOPBACK 1
-//`define TIMED 1
-`define DSP 1
-
module u1e_core
(input clk_fpga, input rst_fpga,
output [3:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
@@ -48,13 +44,18 @@ module u1e_core
wire pps_int;
wire [63:0] vita_time, vita_time_pps;
reg [15:0] reg_leds, reg_cgen_ctrl, reg_test, xfer_rate;
+ wire [7:0] test_rate;
+ wire [3:0] test_ctrl;
wire [7:0] set_addr;
wire [31:0] set_data;
wire set_stb;
wire [31:0] debug_vt;
-
+ wire rx_overrun_dsp, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc;
+ assign rx_overrun = rx_overrun_gpmc | rx_overrun_dsp;
+ assign tx_underrun = tx_underrun_gpmc | tx_underrun_dsp;
+
setting_reg #(.my_addr(SR_GLOBAL_RESET), .width(1)) sr_reset
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(),.changed(global_reset));
@@ -79,7 +80,6 @@ module u1e_core
tx_err_src_rdy, tx_err_dst_rdy;
reg [15:0] tx_frame_len;
wire [15:0] rx_frame_len;
- wire [7:0] rate;
wire bus_error;
wire clear_tx, clear_rx;
@@ -111,62 +111,15 @@ module u1e_core
.rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy),
.tx_frame_len(tx_frame_len), .rx_frame_len(rx_frame_len),
+ .tx_underrun(tx_underrun_gpmc), .rx_overrun(rx_overrun_gpmc),
+
+ .test_rate(test_rate), .test_ctrl(test_ctrl),
.debug(debug_gpmc));
wire rx_sof = rx_data[32];
wire rx_eof = rx_data[33];
wire rx_src_rdy_int, rx_dst_rdy_int, tx_src_rdy_int, tx_dst_rdy_int;
-`ifdef LOOPBACK
- wire [7:0] WHOAMI = 1;
-
- fifo_cascade #(.WIDTH(36), .SIZE(12)) loopback_fifo
- (.clk(wb_clk), .reset(wb_rst), .clear(clear_tx | clear_rx),
- .datain(tx_data), .src_rdy_i(tx_src_rdy), .dst_rdy_o(tx_dst_rdy),
- .dataout(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy));
-
- assign tx_underrun = 0;
- assign rx_overrun = 0;
-
- wire run_tx, run_rx, strobe_tx, strobe_rx;
-`endif // LOOPBACK
-
-`ifdef TIMED
- wire [7:0] WHOAMI = 2;
-
- // TX side
- wire tx_enable;
-
- fifo_pacer tx_pacer
- (.clk(wb_clk), .reset(wb_rst), .rate(rate), .enable(tx_enable),
- .src1_rdy_i(tx_src_rdy), .dst1_rdy_o(tx_dst_rdy),
- .src2_rdy_o(tx_src_rdy_int), .dst2_rdy_i(tx_dst_rdy_int),
- .underrun(tx_underrun), .overrun());
-
- packet_verifier32 pktver32
- (.clk(wb_clk), .reset(wb_rst), .clear(clear_tx),
- .data_i(tx_data), .src_rdy_i(tx_src_rdy_int), .dst_rdy_o(tx_dst_rdy_int),
- .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err));
-
- // RX side
- wire rx_enable;
-
- packet_generator32 pktgen32
- (.clk(wb_clk), .reset(wb_rst), .clear(clear_rx),
- .data_o(rx_data), .src_rdy_o(rx_src_rdy_int), .dst_rdy_i(rx_dst_rdy_int));
-
- fifo_pacer rx_pacer
- (.clk(wb_clk), .reset(wb_rst), .rate(rate), .enable(rx_enable),
- .src1_rdy_i(rx_src_rdy_int), .dst1_rdy_o(rx_dst_rdy_int),
- .src2_rdy_o(rx_src_rdy), .dst2_rdy_i(rx_dst_rdy),
- .underrun(), .overrun(rx_overrun));
-
- wire run_tx, run_rx, strobe_tx, strobe_rx;
-`endif // `ifdef TIMED
-
-`ifdef DSP
- wire [7:0] WHOAMI = 0;
-
wire [31:0] debug_rx_dsp, vrc_debug, vrf_debug;
// /////////////////////////////////////////////////////////////////////////
@@ -189,7 +142,7 @@ module u1e_core
vita_rx_control #(.BASE(SR_RX_CTRL), .WIDTH(32)) vita_rx_control
(.clk(wb_clk), .reset(wb_rst), .clear(clear_rx),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .vita_time(vita_time), .overrun(rx_overrun),
+ .vita_time(vita_time), .overrun(rx_overrun_dsp),
.sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
.sample_fifo_o(rx1_data), .sample_fifo_dst_rdy_i(rx1_dst_rdy), .sample_fifo_src_rdy_o(rx1_src_rdy),
.debug_rx(vrc_debug));
@@ -199,7 +152,6 @@ module u1e_core
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.sample_fifo_i(rx1_data), .sample_fifo_dst_rdy_o(rx1_dst_rdy), .sample_fifo_src_rdy_i(rx1_src_rdy),
.data_o(vita_rx_data), .dst_rdy_i(vita_rx_dst_rdy), .src_rdy_o(vita_rx_src_rdy),
- .fifo_occupied(), .fifo_full(), .fifo_empty(),
.debug_rx(vrf_debug) );
fifo36_mux #(.prio(0)) mux_err_stream
@@ -225,29 +177,12 @@ module u1e_core
.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(tx_i_int),.dac_b(tx_q_int),
- .underrun(underrun), .run(run_tx),
+ .underrun(tx_underrun_dsp), .run(run_tx),
.debug(debug_vt));
assign tx_i = tx_i_int[15:2];
assign tx_q = tx_q_int[15:2];
-`else // !`ifdef DSP
- // Dummy DSP signal generator for test purposes
- wire [23:0] tx_i_int, tx_q_int;
- wire [23:0] freq = {reg_test,8'd0};
- reg [23:0] phase;
-
- always @(posedge wb_clk)
- phase <= phase + freq;
-
- cordic_z24 #(.bitwidth(24)) tx_cordic
- (.clock(wb_clk), .reset(wb_rst), .enable(1),
- .xi(24'd2500000), .yi(24'd0), .zi(phase), .xo(tx_i_int), .yo(tx_q_int), .zo());
-
- assign tx_i = tx_i_int[23:10];
- assign tx_q = tx_q_int[23:10];
-`endif // !`ifdef DSP
-
// /////////////////////////////////////////////////////////////////////////////////////
// Wishbone Intercon, single master
wire [dw-1:0] s0_dat_mosi, s1_dat_mosi, s0_dat_miso, s1_dat_miso, s2_dat_mosi, s3_dat_mosi, s2_dat_miso, s3_dat_miso,
@@ -320,7 +255,6 @@ module u1e_core
// Slave 0, Misc LEDs, Switches, controls
localparam REG_LEDS = 7'd0; // out
- localparam REG_SWITCHES = 7'd2; // in
localparam REG_CGEN_CTRL = 7'd4; // out
localparam REG_CGEN_ST = 7'd6; // in
localparam REG_TEST = 7'd8; // out
@@ -353,20 +287,18 @@ module u1e_core
xfer_rate <= s0_dat_mosi;
endcase // case (s0_adr[6:0])
- assign tx_enable = xfer_rate[15];
- assign rx_enable = xfer_rate[14];
- assign rate = xfer_rate[7:0];
+ assign test_ctrl = xfer_rate[11:8];
+ assign test_rate = xfer_rate[7:0];
assign { debug_led[3:0] } = ~{run_rx,run_tx,reg_leds[1:0]};
assign { cgen_sync_b, cgen_ref_sel } = reg_cgen_ctrl;
assign s0_dat_miso = (s0_adr[6:0] == REG_LEDS) ? reg_leds :
- (s0_adr[6:0] == REG_SWITCHES) ? { 16'd0 } :
(s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl :
(s0_adr[6:0] == REG_CGEN_ST) ? {13'b0,cgen_st_status,cgen_st_ld,cgen_st_refmon} :
(s0_adr[6:0] == REG_TEST) ? reg_test :
(s0_adr[6:0] == REG_RX_FRAMELEN) ? rx_frame_len :
- (s0_adr[6:0] == REG_COMPAT) ? { WHOAMI, COMPAT_NUM } :
+ (s0_adr[6:0] == REG_COMPAT) ? { 8'd0, COMPAT_NUM } :
16'hBEEF;
assign s0_ack = s0_stb & s0_cyc;
@@ -475,10 +407,14 @@ module u1e_core
assign debug_clk = { EM_CLK, clk_fpga };
+/*
assign debug = { { rx_have_data, tx_have_space, EM_NCS6, EM_NCS5, EM_NCS4, EM_NWE, EM_NOE, rx_overrun },
{ tx_src_rdy, tx_src_rdy_int, tx_dst_rdy, tx_dst_rdy_int, rx_src_rdy, rx_src_rdy_int, rx_dst_rdy, rx_dst_rdy_int },
{ EM_D } };
+*/
+ assign debug = debug_gpmc;
+
assign debug_gpio_0 = { {run_tx, strobe_tx, run_rx, strobe_rx, tx_i[11:0]},
{2'b00, tx_src_rdy, tx_dst_rdy, tx_q[11:0]} };
diff --git a/fpga/usrp2/top/u1e_passthru/Makefile b/fpga/usrp2/top/u1e_passthru/Makefile
index d1950629b..f2d835608 100644
--- a/fpga/usrp2/top/u1e_passthru/Makefile
+++ b/fpga/usrp2/top/u1e_passthru/Makefile
@@ -23,7 +23,6 @@ include ../../opencores/Makefile.srcs
include ../../vrt/Makefile.srcs
include ../../udp/Makefile.srcs
include ../../coregen/Makefile.srcs
-include ../../extram/Makefile.srcs
include ../../gpmc/Makefile.srcs
##################################################
@@ -51,7 +50,7 @@ passthru.ucf
SOURCES = $(abspath $(TOP_SRCS)) $(FIFO_SRCS) \
$(CONTROL_LIB_SRCS) $(SDR_LIB_SRCS) $(SERDES_SRCS) \
$(SIMPLE_GEMAC_SRCS) $(TIMING_SRCS) $(OPENCORES_SRCS) \
-$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) $(EXTRAM_SRCS) \
+$(VRT_SRCS) $(UDP_SRCS) $(COREGEN_SRCS) \
$(GPMC_SRCS)
##################################################
diff --git a/fpga/usrp2/top/u2_rev3/Makefile b/fpga/usrp2/top/u2_rev3/Makefile
index 05ada2476..e9b43491a 100644
--- a/fpga/usrp2/top/u2_rev3/Makefile
+++ b/fpga/usrp2/top/u2_rev3/Makefile
@@ -23,7 +23,6 @@ include ../../opencores/Makefile.srcs
include ../../vrt/Makefile.srcs
include ../../udp/Makefile.srcs
include ../../coregen/Makefile.srcs
-include ../../extram/Makefile.srcs
include ../../extramfifo/Makefile.srcs
diff --git a/fpga/usrp2/top/u2_rev3/u2_core.v b/fpga/usrp2/top/u2_rev3/u2_core.v
index ab2ed49f0..79470de9e 100644
--- a/fpga/usrp2/top/u2_rev3/u2_core.v
+++ b/fpga/usrp2/top/u2_rev3/u2_core.v
@@ -3,7 +3,6 @@
// ////////////////////////////////////////////////////////////////////////////////
module u2_core
- #(parameter RAM_SIZE=16384, parameter RAM_AW=14)
(// Clocks
input dsp_clk,
input wb_clk,
@@ -137,20 +136,24 @@ module u2_core
input [3:0] clock_divider
);
- localparam SR_BUF_POOL = 64; // Uses 1 reg
+ localparam SR_MISC = 0; // Uses 9 regs
+ localparam SR_BUF_POOL = 64; // Uses 4 regs
localparam SR_UDP_SM = 96; // 64 regs
- localparam SR_RX_DSP = 160; // 16
- localparam SR_RX_CTRL = 176; // 16
+ localparam SR_RX_DSP0 = 160; // 16
+ localparam SR_RX_CTRL0 = 176; // 16
localparam SR_TIME64 = 192; // 3
localparam SR_SIMTIMER = 198; // 2
localparam SR_TX_DSP = 208; // 16
localparam SR_TX_CTRL = 224; // 16
-
+ localparam SR_RX_DSP1 = 240;
+ localparam SR_RX_CTRL1 = 32;
+
+
// FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048
// all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs
- localparam DSP_TX_FIFOSIZE = 10;
+ // localparam DSP_TX_FIFOSIZE = 9; unused -- DSPTX uses extram fifo
localparam DSP_RX_FIFOSIZE = 10;
- localparam ETH_TX_FIFOSIZE = 10;
+ localparam ETH_TX_FIFOSIZE = 9;
localparam ETH_RX_FIFOSIZE = 11;
localparam SERDES_TX_FIFOSIZE = 9;
localparam SERDES_RX_FIFOSIZE = 9; // RX currently doesn't use a fifo?
@@ -159,13 +162,14 @@ module u2_core
wire [31:0] set_data, set_data_dsp;
wire set_stb, set_stb_dsp;
- wire ram_loader_done;
- wire ram_loader_rst, wb_rst, dsp_rst;
- assign dsp_rst = wb_rst;
-
+ wire ram_loader_done, ram_loader_rst;
+ wire wb_rst;
+ wire dsp_rst = wb_rst;
+
wire [31:0] status;
wire bus_error, spi_int, i2c_int, pps_int, onetime_int, periodic_int, buffer_int;
- wire proc_int, overrun, underrun, uart_tx_int, uart_rx_int;
+ wire proc_int, overrun0, overrun1, underrun;
+ wire uart_tx_int, uart_rx_int;
wire [31:0] debug_gpio_0, debug_gpio_1;
wire [31:0] atr_lines;
@@ -182,10 +186,8 @@ module u2_core
wire [31:0] irq;
wire [63:0] vita_time, vita_time_pps;
- wire run_rx, run_tx;
- reg run_rx_d1;
- always @(posedge dsp_clk)
- run_rx_d1 <= run_rx;
+ wire run_rx0, run_rx1, run_tx;
+ reg run_rx0_d1, run_rx1_d1;
// ///////////////////////////////////////////////////////////////////////////////////////////////
// Wishbone Single Master INTERCON
@@ -291,7 +293,7 @@ module u2_core
wire [15:0] ram_loader_adr;
wire [3:0] ram_loader_sel;
wire ram_loader_stb, ram_loader_we;
- ram_loader #(.AWIDTH(aw),.RAM_SIZE(RAM_SIZE))
+ ram_loader #(.AWIDTH(aw),.RAM_SIZE(16384))
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),
@@ -324,21 +326,21 @@ module u2_core
// I-port connects directly to processor and ram loader
wire flush_icache;
- ram_harvard #(.AWIDTH(RAM_AW),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
+ ram_harvard #(.AWIDTH(14),.RAM_SIZE(16384),.ICWIDTH(7),.DCWIDTH(6))
sys_ram(.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
- .ram_loader_adr_i(ram_loader_adr[RAM_AW-1:0]), .ram_loader_dat_i(ram_loader_dat),
+ .ram_loader_adr_i(ram_loader_adr[13: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_done_i(ram_loader_done),
.if_adr(16'b0), .if_data(),
- .dwb_adr_i(s0_adr[RAM_AW-1:0]), .dwb_dat_i(s0_dat_o), .dwb_dat_o(s0_dat_i),
+ .dwb_adr_i(s0_adr[13: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),
.flush_icache(flush_icache));
- setting_reg #(.my_addr(7)) sr_icache (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+7)) sr_icache (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(),.changed(flush_icache));
// /////////////////////////////////////////////////////////////////////////
@@ -347,15 +349,13 @@ module u2_core
wire rd1_ready_i, rd1_ready_o;
wire rd2_ready_i, rd2_ready_o;
wire rd3_ready_i, rd3_ready_o;
- wire [3:0] rd0_flags, rd1_flags, rd2_flags, rd3_flags;
- wire [31:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
+ wire [35:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
wire wr0_ready_i, wr0_ready_o;
wire wr1_ready_i, wr1_ready_o;
wire wr2_ready_i, wr2_ready_o;
wire wr3_ready_i, wr3_ready_o;
- wire [3:0] wr0_flags, wr1_flags, wr2_flags, wr3_flags;
- wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
+ wire [35:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
wire [35:0] tx_err_data;
wire tx_err_src_rdy, tx_err_dst_rdy;
@@ -373,14 +373,15 @@ module u2_core
.status(status), .sys_int_o(buffer_int), .debug(router_debug),
- .ser_inp_data({wr0_flags, wr0_dat}), .ser_inp_valid(wr0_ready_i), .ser_inp_ready(wr0_ready_o),
- .dsp_inp_data({wr1_flags, wr1_dat}), .dsp_inp_valid(wr1_ready_i), .dsp_inp_ready(wr1_ready_o),
- .eth_inp_data({wr2_flags, wr2_dat}), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
+ .ser_inp_data(wr0_dat), .ser_inp_valid(wr0_ready_i), .ser_inp_ready(wr0_ready_o),
+ .dsp0_inp_data(wr1_dat), .dsp0_inp_valid(wr1_ready_i), .dsp0_inp_ready(wr1_ready_o),
+ .dsp1_inp_data(wr3_dat), .dsp1_inp_valid(wr3_ready_i), .dsp1_inp_ready(wr3_ready_o),
+ .eth_inp_data(wr2_dat), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
.err_inp_data(tx_err_data), .err_inp_ready(tx_err_dst_rdy), .err_inp_valid(tx_err_src_rdy),
- .ser_out_data({rd0_flags, rd0_dat}), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
- .dsp_out_data({rd1_flags, rd1_dat}), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
- .eth_out_data({rd2_flags, rd2_dat}), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
+ .ser_out_data(rd0_dat), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
+ .dsp_out_data(rd1_dat), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
+ .eth_out_data(rd2_dat), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
);
// /////////////////////////////////////////////////////////////////////////
@@ -416,7 +417,7 @@ module u2_core
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
- localparam compat_num = 32'd4;
+ localparam compat_num = 32'd5;
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
@@ -432,56 +433,21 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// Ethernet MAC Slave #6
- wire [18:0] rx_f19_data, tx_f19_data;
- wire rx_f19_src_rdy, rx_f19_dst_rdy, tx_f19_src_rdy, tx_f19_dst_rdy;
-
- simple_gemac_wrapper19 #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper19
+ simple_gemac_wrapper #(.RXFIFOSIZE(ETH_RX_FIFOSIZE),
+ .TXFIFOSIZE(ETH_TX_FIFOSIZE)) simple_gemac_wrapper19
(.clk125(clk_to_mac), .reset(wb_rst),
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
.sys_clk(dsp_clk),
- .rx_f19_data(rx_f19_data), .rx_f19_src_rdy(rx_f19_src_rdy), .rx_f19_dst_rdy(rx_f19_dst_rdy),
- .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),
+ .rx_f36_data(wr2_dat), .rx_f36_src_rdy(wr2_ready_i), .rx_f36_dst_rdy(wr2_ready_o),
+ .tx_f36_data(rd2_dat), .tx_f36_src_rdy(rd2_ready_o), .tx_f36_dst_rdy(rd2_ready_i),
.wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(s6_stb), .wb_cyc(s6_cyc), .wb_ack(s6_ack),
.wb_we(s6_we), .wb_adr(s6_adr), .wb_dat_i(s6_dat_o), .wb_dat_o(s6_dat_i),
.mdio(MDIO), .mdc(MDC),
.debug(debug_mac));
- wire [35:0] rx_f36_data, tx_f36_data;
- wire rx_f36_src_rdy, rx_f36_dst_rdy, tx_f36_src_rdy, tx_f36_dst_rdy;
-
- wire [18:0] _rx_f19_data;
- wire _rx_f19_src_rdy, _rx_f19_dst_rdy;
-
- //mac rx to eth input...
- fifo19_rxrealign fifo19_rxrealign
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy), .dst_rdy_o(rx_f19_dst_rdy),
- .dataout(_rx_f19_data), .src_rdy_o(_rx_f19_src_rdy), .dst_rdy_i(_rx_f19_dst_rdy) );
-
- fifo19_to_fifo36 eth_inp_fifo19_to_fifo36
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .f19_datain(_rx_f19_data), .f19_src_rdy_i(_rx_f19_src_rdy), .f19_dst_rdy_o(_rx_f19_dst_rdy),
- .f36_dataout(rx_f36_data), .f36_src_rdy_o(rx_f36_src_rdy), .f36_dst_rdy_i(rx_f36_dst_rdy) );
-
- fifo_cascade #(.WIDTH(36), .SIZE(ETH_RX_FIFOSIZE)) rx_eth_fifo
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .datain(rx_f36_data), .src_rdy_i(rx_f36_src_rdy), .dst_rdy_o(rx_f36_dst_rdy),
- .dataout({wr2_flags,wr2_dat}), .src_rdy_o(wr2_ready_i), .dst_rdy_i(wr2_ready_o));
-
- //eth output to mac tx...
- 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(tx_f36_data), .src_rdy_o(tx_f36_src_rdy), .dst_rdy_i(tx_f36_dst_rdy));
-
- fifo36_to_fifo19 eth_out_fifo36_to_fifo19
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .f36_datain(tx_f36_data), .f36_src_rdy_i(tx_f36_src_rdy), .f36_dst_rdy_o(tx_f36_dst_rdy),
- .f19_dataout(tx_f19_data), .f19_src_rdy_o(tx_f19_src_rdy), .f19_dst_rdy_i(tx_f19_dst_rdy) );
-
// /////////////////////////////////////////////////////////////////////////
// Settings Bus -- Slave #7
settings_bus settings_bus
@@ -504,13 +470,13 @@ module u2_core
wire phy_reset;
assign PHY_RESETn = ~phy_reset;
- setting_reg #(.my_addr(0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),
.in(set_data),.out(clock_outs),.changed());
- setting_reg #(.my_addr(1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(serdes_outs),.changed());
- setting_reg #(.my_addr(2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(adc_outs),.changed());
- setting_reg #(.my_addr(4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(phy_reset),.changed());
// /////////////////////////////////////////////////////////////////////////
@@ -520,12 +486,12 @@ 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 = {run_tx, run_rx, clk_status, serdes_link_up, 1'b0};
+ wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), 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),
+ setting_reg #(.my_addr(SR_MISC+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), .at_reset(8'b0001_1110))
+ setting_reg #(.my_addr(SR_MISC+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);
@@ -537,7 +503,7 @@ module u2_core
wire underrun_wb, overrun_wb, pps_wb;
oneshot_2clk underrun_1s (.clk_in(dsp_clk), .in(underrun), .clk_out(wb_clk), .out(underrun_wb));
- oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun), .clk_out(wb_clk), .out(overrun_wb));
+ oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun0 | overrun1), .clk_out(wb_clk), .out(overrun_wb));
oneshot_2clk pps_1s (.clk_in(dsp_clk), .in(pps_int), .clk_out(wb_clk), .out(pps_wb));
assign irq= {{8'b0},
@@ -580,7 +546,7 @@ module u2_core
(.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),
.we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack),
- .run_rx(run_rx_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
+ .run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
// //////////////////////////////////////////////////////////////////////////
// Time Sync, Slave #12
@@ -601,50 +567,60 @@ module u2_core
assign sd_dat_i[31:8] = 0;
// /////////////////////////////////////////////////////////////////////////
- // DSP RX
- wire [31:0] sample_rx, sample_tx;
- wire strobe_rx, strobe_tx;
- wire rx_dst_rdy, rx_src_rdy, rx1_dst_rdy, rx1_src_rdy;
- wire [99:0] rx_data;
- wire [35:0] rx1_data;
-
- dsp_core_rx #(.BASE(SR_RX_DSP)) dsp_core_rx
+ // DSP RX 0
+ wire [31:0] sample_rx0;
+ wire clear_rx0, strobe_rx0;
+
+ always @(posedge dsp_clk)
+ run_rx0_d1 <= run_rx0;
+
+ dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0
(.clk(dsp_clk),.rst(dsp_rst),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
.adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .sample(sample_rx), .run(run_rx_d1), .strobe(strobe_rx),
- .debug(debug_rx_dsp) );
+ .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0),
+ .debug() );
- wire [31:0] vrc_debug;
- wire clear_rx;
-
- setting_reg #(.my_addr(SR_RX_CTRL+3)) sr_clear
+ setting_reg #(.my_addr(SR_RX_CTRL0+3)) sr_clear_rx0
(.clk(dsp_clk),.rst(dsp_rst),
.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),
- .out(),.changed(clear_rx));
+ .out(),.changed(clear_rx0));
- vita_rx_control #(.BASE(SR_RX_CTRL), .WIDTH(32)) vita_rx_control
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
+ vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx0),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .vita_time(vita_time), .overrun(overrun),
- .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
- .sample_fifo_o(rx_data), .sample_fifo_dst_rdy_i(rx_dst_rdy), .sample_fifo_src_rdy_o(rx_src_rdy),
- .debug_rx(vrc_debug));
+ .vita_time(vita_time), .overrun(overrun0),
+ .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0),
+ .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o),
+ .debug() );
- wire [3:0] vita_state;
+ // /////////////////////////////////////////////////////////////////////////
+ // DSP RX 1
+ wire [31:0] sample_rx1;
+ wire clear_rx1, strobe_rx1;
+
+ always @(posedge dsp_clk)
+ run_rx1_d1 <= run_rx1;
- vita_rx_framer #(.BASE(SR_RX_CTRL), .MAXCHAN(1)) vita_rx_framer
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
+ dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1
+ (.clk(dsp_clk),.rst(dsp_rst),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .sample_fifo_i(rx_data), .sample_fifo_dst_rdy_o(rx_dst_rdy), .sample_fifo_src_rdy_i(rx_src_rdy),
- .data_o(rx1_data), .dst_rdy_i(rx1_dst_rdy), .src_rdy_o(rx1_src_rdy),
- .fifo_occupied(), .fifo_full(), .fifo_empty(),
- .debug_rx(vita_state) );
+ .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
+ .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1),
+ .debug() );
+
+ setting_reg #(.my_addr(SR_RX_CTRL1+3)) sr_clear_rx1
+ (.clk(dsp_clk),.rst(dsp_rst),
+ .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),
+ .out(),.changed(clear_rx1));
- fifo_cascade #(.WIDTH(36), .SIZE(DSP_RX_FIFOSIZE)) rx_fifo_cascade
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
- .datain(rx1_data), .src_rdy_i(rx1_src_rdy), .dst_rdy_o(rx1_dst_rdy),
- .dataout({wr1_flags,wr1_dat}), .src_rdy_o(wr1_ready_i), .dst_rdy_i(wr1_ready_o));
+ vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx1),
+ .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
+ .vita_time(vita_time), .overrun(overrun1),
+ .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1),
+ .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o),
+ .debug() );
// ///////////////////////////////////////////////////////////////////////////////////
// DSP TX
@@ -672,10 +648,10 @@ module u2_core
.RAM_LDn(RAM_LDn),
.RAM_OEn(RAM_OEn),
.RAM_CE1n(RAM_CE1n),
- .datain({rd1_flags[3:2],rd1_dat[31:16],rd1_flags[1:0],rd1_dat[15:0]}),
+ .datain(rd1_dat),
.src_rdy_i(rd1_ready_o),
.dst_rdy_o(rd1_ready_i),
- .dataout({tx_data[35:34],tx_data[31:16],tx_data[33:32],tx_data[15:0]}),
+ .dataout(tx_data),
.src_rdy_o(tx_src_rdy),
.dst_rdy_i(tx_dst_rdy),
.debug(debug_extfifo),
@@ -701,9 +677,9 @@ module u2_core
serdes #(.TXFIFOSIZE(SERDES_TX_FIFOSIZE),.RXFIFOSIZE(SERDES_RX_FIFOSIZE)) serdes
(.clk(dsp_clk),.rst(dsp_rst),
.ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb),
- .rd_dat_i(rd0_dat),.rd_flags_i(rd0_flags),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o),
+ .rd_dat_i(rd0_dat[31:0]),.rd_flags_i(rd0_dat[35:32]),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o),
.ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb),
- .wr_dat_o(wr0_dat),.wr_flags_o(wr0_flags),.wr_ready_o(wr0_ready_i),.wr_ready_i(wr0_ready_o),
+ .wr_dat_o(wr0_dat[31:0]),.wr_flags_o(wr0_dat[35:32]),.wr_ready_o(wr0_ready_i),.wr_ready_i(wr0_ready_o),
.tx_occupied(ser_tx_occ),.tx_full(ser_tx_full),.tx_empty(ser_tx_empty),
.rx_occupied(ser_rx_occ),.rx_full(ser_rx_full),.rx_empty(ser_rx_empty),
.serdes_link_up(serdes_link_up),.debug0(debug_serdes0), .debug1(debug_serdes1) );
@@ -725,7 +701,7 @@ module u2_core
// Debug Pins
assign debug_clk = 2'b00; // {dsp_clk, clk_to_mac};
- assign debug = 32'd0; // debug_extfifo;
+ assign debug = 32'd0;
assign debug_gpio_0 = 32'd0;
assign debug_gpio_1 = 32'd0;
diff --git a/fpga/usrp2/top/u2_rev3/u2_rev3.v b/fpga/usrp2/top/u2_rev3/u2_rev3.v
index 759f7b7b8..bc7ae5f16 100644
--- a/fpga/usrp2/top/u2_rev3/u2_rev3.v
+++ b/fpga/usrp2/top/u2_rev3/u2_rev3.v
@@ -471,7 +471,7 @@ module u2_rev3
//
- u2_core #(.RAM_SIZE(16384), .RAM_AW(14))
+ u2_core
u2_core(.dsp_clk (dsp_clk),
.wb_clk (wb_clk),
.clock_ready (clock_ready),
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile b/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile
index 5b7ed5a8e..334089839 100644
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile
+++ b/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile
@@ -120,7 +120,6 @@ eth/rtl/verilog/flow_ctrl_tx.v \
eth/rtl/verilog/miim/eth_clockgen.v \
eth/rtl/verilog/miim/eth_outputcontrol.v \
eth/rtl/verilog/miim/eth_shiftreg.v \
-extram/wb_zbt16_b.v \
opencores/8b10b/decode_8b10b.v \
opencores/8b10b/encode_8b10b.v \
opencores/aemb/rtl/verilog/aeMB_bpcu.v \
diff --git a/fpga/usrp2/top/u2_rev3_iad/Makefile b/fpga/usrp2/top/u2_rev3_iad/Makefile
index 5ae8846dd..15df9e43e 100644
--- a/fpga/usrp2/top/u2_rev3_iad/Makefile
+++ b/fpga/usrp2/top/u2_rev3_iad/Makefile
@@ -120,7 +120,6 @@ eth/rtl/verilog/flow_ctrl_tx.v \
eth/rtl/verilog/miim/eth_clockgen.v \
eth/rtl/verilog/miim/eth_outputcontrol.v \
eth/rtl/verilog/miim/eth_shiftreg.v \
-extram/wb_zbt16_b.v \
opencores/8b10b/decode_8b10b.v \
opencores/8b10b/encode_8b10b.v \
opencores/aemb/rtl/verilog/aeMB_bpcu.v \
diff --git a/fpga/usrp2/top/u2plus/Makefile b/fpga/usrp2/top/u2plus/Makefile
index c38bd3ec1..38400ce62 100644
--- a/fpga/usrp2/top/u2plus/Makefile
+++ b/fpga/usrp2/top/u2plus/Makefile
@@ -23,7 +23,6 @@ include ../../opencores/Makefile.srcs
include ../../vrt/Makefile.srcs
include ../../udp/Makefile.srcs
include ../../coregen/Makefile.srcs
-include ../../extram/Makefile.srcs
include ../../extramfifo/Makefile.srcs
diff --git a/fpga/usrp2/top/u2plus/u2plus_core.v b/fpga/usrp2/top/u2plus/u2plus_core.v
index 3edb539f7..ec54de73e 100644
--- a/fpga/usrp2/top/u2plus/u2plus_core.v
+++ b/fpga/usrp2/top/u2plus/u2plus_core.v
@@ -131,20 +131,24 @@ module u2plus_core
output spiflash_cs, output spiflash_clk, input spiflash_miso, output spiflash_mosi
);
- localparam SR_BUF_POOL = 64; // router
+ localparam SR_MISC = 0; // Uses 9 regs
+ localparam SR_BUF_POOL = 64; // Uses 4 regs
localparam SR_UDP_SM = 96; // 64 regs
- localparam SR_RX_DSP = 160; // 16
- localparam SR_RX_CTRL = 176; // 16
+ localparam SR_RX_DSP0 = 160; // 16
+ localparam SR_RX_CTRL0 = 176; // 16
localparam SR_TIME64 = 192; // 3
localparam SR_SIMTIMER = 198; // 2
localparam SR_TX_DSP = 208; // 16
localparam SR_TX_CTRL = 224; // 16
-
+ localparam SR_RX_DSP1 = 240;
+ localparam SR_RX_CTRL1 = 32;
+
+
// FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048
// all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs
- localparam DSP_TX_FIFOSIZE = 10;
+ // localparam DSP_TX_FIFOSIZE = 9; unused -- DSPTX uses extram fifo
localparam DSP_RX_FIFOSIZE = 10;
- localparam ETH_TX_FIFOSIZE = 10;
+ localparam ETH_TX_FIFOSIZE = 9;
localparam ETH_RX_FIFOSIZE = 11;
localparam SERDES_TX_FIFOSIZE = 9;
localparam SERDES_RX_FIFOSIZE = 9; // RX currently doesn't use a fifo?
@@ -153,18 +157,19 @@ module u2plus_core
wire [31:0] set_data, set_data_dsp;
wire set_stb, set_stb_dsp;
- reg wb_rst; wire dsp_rst;
-
+ reg wb_rst;
+ wire dsp_rst = wb_rst;
+
wire [31:0] status;
wire bus_error, spi_int, i2c_int, pps_int, onetime_int, periodic_int, buffer_int;
- wire proc_int, overrun, underrun;
+ wire proc_int, overrun0, overrun1, underrun;
wire [3:0] uart_tx_int, uart_rx_int;
wire [31:0] debug_gpio_0, debug_gpio_1;
wire [31:0] atr_lines;
wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc,
- debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp;
+ debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp, debug_extfifo, debug_extfifo2;
wire [15:0] ser_rx_occ, ser_tx_occ, dsp_rx_occ, dsp_tx_occ, eth_rx_occ, eth_tx_occ, eth_rx_occ2;
wire ser_rx_full, ser_tx_full, dsp_rx_full, dsp_tx_full, eth_rx_full, eth_tx_full, eth_rx_full2;
@@ -174,7 +179,9 @@ module u2plus_core
wire epoch;
wire [31:0] irq;
wire [63:0] vita_time, vita_time_pps;
- wire run_rx, run_tx;
+
+ wire run_rx0, run_rx1, run_tx;
+ reg run_rx0_d1, run_rx1_d1;
// ///////////////////////////////////////////////////////////////////////////////////////////////
// Wishbone Single Master INTERCON
@@ -341,15 +348,13 @@ module u2plus_core
wire rd1_ready_i, rd1_ready_o;
wire rd2_ready_i, rd2_ready_o;
wire rd3_ready_i, rd3_ready_o;
- wire [3:0] rd0_flags, rd1_flags, rd2_flags, rd3_flags;
- wire [31:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
+ wire [35:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
wire wr0_ready_i, wr0_ready_o;
wire wr1_ready_i, wr1_ready_o;
wire wr2_ready_i, wr2_ready_o;
wire wr3_ready_i, wr3_ready_o;
- wire [3:0] wr0_flags, wr1_flags, wr2_flags, wr3_flags;
- wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
+ wire [35:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
wire [35:0] tx_err_data;
wire tx_err_src_rdy, tx_err_dst_rdy;
@@ -367,14 +372,15 @@ module u2plus_core
.status(status), .sys_int_o(buffer_int), .debug(router_debug),
- .ser_inp_data({wr0_flags, wr0_dat}), .ser_inp_valid(wr0_ready_i), .ser_inp_ready(wr0_ready_o),
- .dsp_inp_data({wr1_flags, wr1_dat}), .dsp_inp_valid(wr1_ready_i), .dsp_inp_ready(wr1_ready_o),
- .eth_inp_data({wr2_flags, wr2_dat}), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
+ .ser_inp_data(wr0_dat), .ser_inp_valid(wr0_ready_i), .ser_inp_ready(wr0_ready_o),
+ .dsp0_inp_data(wr1_dat), .dsp0_inp_valid(wr1_ready_i), .dsp0_inp_ready(wr1_ready_o),
+ .dsp1_inp_data(wr3_dat), .dsp1_inp_valid(wr3_ready_i), .dsp1_inp_ready(wr3_ready_o),
+ .eth_inp_data(wr2_dat), .eth_inp_valid(wr2_ready_i), .eth_inp_ready(wr2_ready_o),
.err_inp_data(tx_err_data), .err_inp_ready(tx_err_dst_rdy), .err_inp_valid(tx_err_src_rdy),
- .ser_out_data({rd0_flags, rd0_dat}), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
- .dsp_out_data({rd1_flags, rd1_dat}), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
- .eth_out_data({rd2_flags, rd2_dat}), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
+ .ser_out_data(rd0_dat), .ser_out_valid(rd0_ready_o), .ser_out_ready(rd0_ready_i),
+ .dsp_out_data(rd1_dat), .dsp_out_valid(rd1_ready_o), .dsp_out_ready(rd1_ready_i),
+ .eth_out_data(rd2_dat), .eth_out_valid(rd2_ready_o), .eth_out_ready(rd2_ready_i)
);
// /////////////////////////////////////////////////////////////////////////
@@ -410,12 +416,12 @@ module u2plus_core
// Buffer Pool Status -- Slave #5
//compatibility number -> increment when the fpga has been sufficiently altered
- localparam compat_num = 32'd4;
+ localparam compat_num = 32'd5;
wb_readback_mux buff_pool_status
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
.wb_adr_i(s5_adr), .wb_dat_o(s5_dat_i), .wb_ack_o(s5_ack),
-
+
.word00(32'b0),.word01(32'b0),.word02(32'b0),.word03(32'b0),
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
.word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(vita_time[63:32]),
@@ -426,56 +432,21 @@ module u2plus_core
// /////////////////////////////////////////////////////////////////////////
// Ethernet MAC Slave #6
- wire [18:0] rx_f19_data, tx_f19_data;
- wire rx_f19_src_rdy, rx_f19_dst_rdy, tx_f19_src_rdy, tx_f19_dst_rdy;
-
- simple_gemac_wrapper19 #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper19
+ simple_gemac_wrapper #(.RXFIFOSIZE(ETH_RX_FIFOSIZE),
+ .TXFIFOSIZE(ETH_TX_FIFOSIZE)) simple_gemac_wrapper19
(.clk125(clk_to_mac), .reset(wb_rst),
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
.sys_clk(dsp_clk),
- .rx_f19_data(rx_f19_data), .rx_f19_src_rdy(rx_f19_src_rdy), .rx_f19_dst_rdy(rx_f19_dst_rdy),
- .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),
+ .rx_f36_data(wr2_dat), .rx_f36_src_rdy(wr2_ready_i), .rx_f36_dst_rdy(wr2_ready_o),
+ .tx_f36_data(rd2_dat), .tx_f36_src_rdy(rd2_ready_o), .tx_f36_dst_rdy(rd2_ready_i),
.wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(s6_stb), .wb_cyc(s6_cyc), .wb_ack(s6_ack),
.wb_we(s6_we), .wb_adr(s6_adr), .wb_dat_i(s6_dat_o), .wb_dat_o(s6_dat_i),
.mdio(MDIO), .mdc(MDC),
.debug(debug_mac));
- wire [35:0] rx_f36_data, tx_f36_data;
- wire rx_f36_src_rdy, rx_f36_dst_rdy, tx_f36_src_rdy, tx_f36_dst_rdy;
-
- wire [18:0] _rx_f19_data;
- wire _rx_f19_src_rdy, _rx_f19_dst_rdy;
-
- //mac rx to eth input...
- fifo19_rxrealign fifo19_rxrealign
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy), .dst_rdy_o(rx_f19_dst_rdy),
- .dataout(_rx_f19_data), .src_rdy_o(_rx_f19_src_rdy), .dst_rdy_i(_rx_f19_dst_rdy) );
-
- fifo19_to_fifo36 eth_inp_fifo19_to_fifo36
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .f19_datain(_rx_f19_data), .f19_src_rdy_i(_rx_f19_src_rdy), .f19_dst_rdy_o(_rx_f19_dst_rdy),
- .f36_dataout(rx_f36_data), .f36_src_rdy_o(rx_f36_src_rdy), .f36_dst_rdy_i(rx_f36_dst_rdy) );
-
- fifo_cascade #(.WIDTH(36), .SIZE(ETH_RX_FIFOSIZE)) rx_eth_fifo
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .datain(rx_f36_data), .src_rdy_i(rx_f36_src_rdy), .dst_rdy_o(rx_f36_dst_rdy),
- .dataout({wr2_flags,wr2_dat}), .src_rdy_o(wr2_ready_i), .dst_rdy_i(wr2_ready_o));
-
- //eth output to mac tx...
- 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(tx_f36_data), .src_rdy_o(tx_f36_src_rdy), .dst_rdy_i(tx_f36_dst_rdy));
-
- fifo36_to_fifo19 eth_out_fifo36_to_fifo19
- (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
- .f36_datain(tx_f36_data), .f36_src_rdy_i(tx_f36_src_rdy), .f36_dst_rdy_o(tx_f36_dst_rdy),
- .f19_dataout(tx_f19_data), .f19_src_rdy_o(tx_f19_src_rdy), .f19_dst_rdy_i(tx_f19_dst_rdy) );
-
// /////////////////////////////////////////////////////////////////////////
// Settings Bus -- Slave #7
settings_bus settings_bus
@@ -498,15 +469,15 @@ module u2plus_core
wire phy_reset;
assign PHY_RESETn = ~phy_reset;
- setting_reg #(.my_addr(0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+0),.width(8)) sr_clk (.clk(wb_clk),.rst(wb_rst),.strobe(s7_ack),.addr(set_addr),
.in(set_data),.out(clock_outs),.changed());
- setting_reg #(.my_addr(1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+1),.width(8)) sr_ser (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(serdes_outs),.changed());
- setting_reg #(.my_addr(2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+2),.width(8)) sr_adc (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(adc_outs),.changed());
- setting_reg #(.my_addr(4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+4),.width(1)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(phy_reset),.changed());
- setting_reg #(.my_addr(5),.width(1)) sr_bldr (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ setting_reg #(.my_addr(SR_MISC+5),.width(1)) sr_bldr (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(bldr_done),.changed());
// /////////////////////////////////////////////////////////////////////////
@@ -516,12 +487,12 @@ module u2plus_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 = {run_tx, run_rx, clk_status, serdes_link_up, 1'b0};
+ wire [7:0] led_hw = {run_tx, (run_rx0_d1 | run_rx1_d1), 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),
+ setting_reg #(.my_addr(SR_MISC+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), .at_reset(8'b0001_1110))
+ setting_reg #(.my_addr(SR_MISC+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);
@@ -533,7 +504,7 @@ module u2plus_core
wire underrun_wb, overrun_wb, pps_wb;
oneshot_2clk underrun_1s (.clk_in(dsp_clk), .in(underrun), .clk_out(wb_clk), .out(underrun_wb));
- oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun), .clk_out(wb_clk), .out(overrun_wb));
+ oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun0 | overrun1), .clk_out(wb_clk), .out(overrun_wb));
oneshot_2clk pps_1s (.clk_in(dsp_clk), .in(pps_int), .clk_out(wb_clk), .out(pps_wb));
assign irq= {{8'b0},
@@ -572,15 +543,11 @@ module u2plus_core
// /////////////////////////////////////////////////////////////////////////
// ATR Controller, Slave #11
- 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),
.we_i(sb_we),.stb_i(sb_stb),.cyc_i(sb_cyc),.ack_o(sb_ack),
- .run_rx(run_rx_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
+ .run_rx(run_rx0_d1 | run_rx1_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
// //////////////////////////////////////////////////////////////////////////
// Time Sync, Slave #12
@@ -605,50 +572,60 @@ module u2plus_core
.sclk_pad_o(spiflash_clk),.mosi_pad_o(spiflash_mosi),.miso_pad_i(spiflash_miso) );
// /////////////////////////////////////////////////////////////////////////
- // DSP RX
- wire [31:0] sample_rx, sample_tx;
- wire strobe_rx, strobe_tx;
- wire rx_dst_rdy, rx_src_rdy, rx1_dst_rdy, rx1_src_rdy;
- wire [99:0] rx_data;
- wire [35:0] rx1_data;
-
- dsp_core_rx #(.BASE(SR_RX_DSP)) dsp_core_rx
+ // DSP RX 0
+ wire [31:0] sample_rx0;
+ wire clear_rx0, strobe_rx0;
+
+ always @(posedge dsp_clk)
+ run_rx0_d1 <= run_rx0;
+
+ dsp_core_rx #(.BASE(SR_RX_DSP0)) dsp_core_rx0
(.clk(dsp_clk),.rst(dsp_rst),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
.adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .sample(sample_rx), .run(run_rx_d1), .strobe(strobe_rx),
- .debug(debug_rx_dsp) );
+ .sample(sample_rx0), .run(run_rx0_d1), .strobe(strobe_rx0),
+ .debug() );
- wire [31:0] vrc_debug;
- wire clear_rx;
-
- setting_reg #(.my_addr(SR_RX_CTRL+3)) sr_clear
+ setting_reg #(.my_addr(SR_RX_CTRL0+3)) sr_clear_rx0
(.clk(dsp_clk),.rst(dsp_rst),
.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),
- .out(),.changed(clear_rx));
+ .out(),.changed(clear_rx0));
- vita_rx_control #(.BASE(SR_RX_CTRL), .WIDTH(32)) vita_rx_control
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
+ vita_rx_chain #(.BASE(SR_RX_CTRL0),.UNIT(0),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain0
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx0),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .vita_time(vita_time), .overrun(overrun),
- .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
- .sample_fifo_o(rx_data), .sample_fifo_dst_rdy_i(rx_dst_rdy), .sample_fifo_src_rdy_o(rx_src_rdy),
- .debug_rx(vrc_debug));
+ .vita_time(vita_time), .overrun(overrun0),
+ .sample(sample_rx0), .run(run_rx0), .strobe(strobe_rx0),
+ .rx_data_o(wr1_dat), .rx_src_rdy_o(wr1_ready_i), .rx_dst_rdy_i(wr1_ready_o),
+ .debug() );
- wire [3:0] vita_state;
+ // /////////////////////////////////////////////////////////////////////////
+ // DSP RX 1
+ wire [31:0] sample_rx1;
+ wire clear_rx1, strobe_rx1;
+
+ always @(posedge dsp_clk)
+ run_rx1_d1 <= run_rx1;
- vita_rx_framer #(.BASE(SR_RX_CTRL), .MAXCHAN(1)) vita_rx_framer
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
+ dsp_core_rx #(.BASE(SR_RX_DSP1)) dsp_core_rx1
+ (.clk(dsp_clk),.rst(dsp_rst),
.set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
- .sample_fifo_i(rx_data), .sample_fifo_dst_rdy_o(rx_dst_rdy), .sample_fifo_src_rdy_i(rx_src_rdy),
- .data_o(rx1_data), .dst_rdy_i(rx1_dst_rdy), .src_rdy_o(rx1_src_rdy),
- .fifo_occupied(), .fifo_full(), .fifo_empty(),
- .debug_rx(vita_state) );
+ .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
+ .sample(sample_rx1), .run(run_rx1_d1), .strobe(strobe_rx1),
+ .debug() );
- fifo_cascade #(.WIDTH(36), .SIZE(DSP_RX_FIFOSIZE)) rx_fifo_cascade
- (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx),
- .datain(rx1_data), .src_rdy_i(rx1_src_rdy), .dst_rdy_o(rx1_dst_rdy),
- .dataout({wr1_flags,wr1_dat}), .src_rdy_o(wr1_ready_i), .dst_rdy_i(wr1_ready_o));
+ setting_reg #(.my_addr(SR_RX_CTRL1+3)) sr_clear_rx1
+ (.clk(dsp_clk),.rst(dsp_rst),
+ .strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),
+ .out(),.changed(clear_rx1));
+
+ vita_rx_chain #(.BASE(SR_RX_CTRL1),.UNIT(2),.FIFOSIZE(DSP_RX_FIFOSIZE)) vita_rx_chain1
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(clear_rx1),
+ .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp),
+ .vita_time(vita_time), .overrun(overrun1),
+ .sample(sample_rx1), .run(run_rx1), .strobe(strobe_rx1),
+ .rx_data_o(wr3_dat), .rx_src_rdy_o(wr3_ready_i), .rx_dst_rdy_i(wr3_ready_o),
+ .debug() );
// ///////////////////////////////////////////////////////////////////////////////////
// DSP TX
@@ -678,10 +655,10 @@ module u2plus_core
.RAM_LDn(RAM_LDn),
.RAM_OEn(RAM_OEn),
.RAM_CE1n(RAM_CE1n),
- .datain({rd1_flags[3:2],rd1_dat[31:16],rd1_flags[1:0],rd1_dat[15:0]}),
+ .datain(rd1_dat),
.src_rdy_i(rd1_ready_o),
.dst_rdy_o(rd1_ready_i),
- .dataout({tx_data[35:34],tx_data[31:16],tx_data[33:32],tx_data[15:0]}),
+ .dataout(tx_data),
.src_rdy_o(tx_src_rdy),
.dst_rdy_i(tx_dst_rdy),
.debug(debug_extfifo),
@@ -701,17 +678,15 @@ module u2plus_core
.underrun(underrun), .run(run_tx),
.debug(debug_vt));
- assign dsp_rst = wb_rst;
-
// ///////////////////////////////////////////////////////////////////////////////////
// SERDES
serdes #(.TXFIFOSIZE(SERDES_TX_FIFOSIZE),.RXFIFOSIZE(SERDES_RX_FIFOSIZE)) serdes
(.clk(dsp_clk),.rst(dsp_rst),
.ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb),
- .rd_dat_i(rd0_dat),.rd_flags_i(rd0_flags),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o),
+ .rd_dat_i(rd0_dat[31:0]),.rd_flags_i(rd0_dat[35:32]),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o),
.ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb),
- .wr_dat_o(wr0_dat),.wr_flags_o(wr0_flags),.wr_ready_o(wr0_ready_i),.wr_ready_i(wr0_ready_o),
+ .wr_dat_o(wr0_dat[31:0]),.wr_flags_o(wr0_dat[35:32]),.wr_ready_o(wr0_ready_i),.wr_ready_i(wr0_ready_o),
.tx_occupied(ser_tx_occ),.tx_full(ser_tx_full),.tx_empty(ser_tx_empty),
.rx_occupied(ser_rx_occ),.rx_full(ser_rx_full),.rx_empty(ser_rx_empty),
.serdes_link_up(serdes_link_up),.debug0(debug_serdes0), .debug1(debug_serdes1) );
@@ -720,18 +695,18 @@ module u2plus_core
// VITA Timing
wire [31:0] debug_sync;
-
+
time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit
(.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
.pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int),
.exp_time_in(exp_time_in), .exp_time_out(exp_time_out),
.debug(debug_sync));
-
+
// /////////////////////////////////////////////////////////////////////////////////////////
// Debug Pins
assign debug_clk = 2'b00; // {dsp_clk, clk_to_mac};
- assign debug = 32'd0; // debug_extfifo;
+ assign debug = 32'd0;
assign debug_gpio_0 = 32'd0;
assign debug_gpio_1 = 32'd0;
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs
index aa1356d82..4851bc924 100644
--- a/fpga/usrp2/vrt/Makefile.srcs
+++ b/fpga/usrp2/vrt/Makefile.srcs
@@ -8,6 +8,7 @@
VRT_SRCS = $(abspath $(addprefix $(BASE_DIR)/../vrt/, \
vita_rx_control.v \
vita_rx_framer.v \
+vita_rx_chain.v \
vita_tx_control.v \
vita_tx_deframer.v \
vita_tx_chain.v \
diff --git a/fpga/usrp2/vrt/vita_rx_chain.v b/fpga/usrp2/vrt/vita_rx_chain.v
new file mode 100644
index 000000000..d7498286d
--- /dev/null
+++ b/fpga/usrp2/vrt/vita_rx_chain.v
@@ -0,0 +1,42 @@
+
+module vita_rx_chain
+ #(parameter BASE=0,
+ parameter UNIT=0,
+ parameter FIFOSIZE=10)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input [63:0] vita_time, output overrun,
+ input [31:0] sample, output run, input strobe,
+ output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i,
+ output [31:0] debug );
+
+ wire [100:0] sample_data;
+ wire sample_dst_rdy, sample_src_rdy;
+ wire [31:0] vrc_debug, vrf_debug;
+
+ wire [35:0] rx_data_int;
+ wire rx_src_rdy_int, rx_dst_rdy_in;
+
+ vita_rx_control #(.BASE(BASE), .WIDTH(32)) vita_rx_control
+ (.clk(clk), .reset(reset), .clear(clear),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .vita_time(vita_time), .overrun(overrun),
+ .sample(sample), .run(run), .strobe(strobe),
+ .sample_fifo_o(sample_data), .sample_fifo_dst_rdy_i(sample_dst_rdy), .sample_fifo_src_rdy_o(sample_src_rdy),
+ .debug_rx(vrc_debug));
+
+ vita_rx_framer #(.BASE(BASE), .MAXCHAN(1)) vita_rx_framer
+ (.clk(clk), .reset(reset), .clear(clear),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .sample_fifo_i(sample_data), .sample_fifo_dst_rdy_o(sample_dst_rdy), .sample_fifo_src_rdy_i(sample_src_rdy),
+ .data_o(rx_data_int), .src_rdy_o(rx_src_rdy_int), .dst_rdy_i(rx_dst_rdy_int),
+ .debug_rx(vrf_debug) );
+
+ dsp_framer36 #(.BUF_SIZE(FIFOSIZE), .PORT_SEL(UNIT)) dsp0_framer36
+ (.clk(clk), .reset(reset), .clear(clear),
+ .data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int),
+ .data_o(rx_data_o), .src_rdy_o(rx_src_rdy_o), .dst_rdy_i(rx_dst_rdy_i) );
+
+ assign debug = vrc_debug; // | vrf_debug;
+
+endmodule // vita_rx_chain
diff --git a/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v
index 0769f3a24..4c0cef50d 100644
--- a/fpga/usrp2/vrt/vita_rx_control.v
+++ b/fpga/usrp2/vrt/vita_rx_control.v
@@ -196,4 +196,4 @@ module vita_rx_control
{ go_now, too_late, run, strobe, read_ctrl, write_ctrl, 1'b0, ~not_empty_ctrl },
{ 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
+endmodule // vita_rx_control
diff --git a/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v
index bce8fe334..04b636778 100644
--- a/fpga/usrp2/vrt/vita_rx_framer.v
+++ b/fpga/usrp2/vrt/vita_rx_framer.v
@@ -15,11 +15,6 @@ module vita_rx_framer
input sample_fifo_src_rdy_i,
output sample_fifo_dst_rdy_o,
- // FIFO Levels
- output [15:0] fifo_occupied,
- output fifo_full,
- output fifo_empty,
-
output [31:0] debug_rx
);
@@ -200,8 +195,8 @@ module vita_rx_framer
(.clk(clk), .reset(reset), .clear(clear),
.datain(pkt_fifo_line), .src_rdy_i(req_write_pkt_fifo), .dst_rdy_o(pkt_fifo_rdy),
.dataout(data_o[33:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i),
- .space(),.occupied(fifo_occupied[4:0]) );
- assign fifo_occupied[15:5] = 0;
+ .space(),.occupied() );
+
assign data_o[35:34] = 2'b00; // Always write full lines
assign sample_fifo_dst_rdy_o = pkt_fifo_rdy &
( ((vita_state==VITA_PAYLOAD) &
@@ -211,4 +206,4 @@ module vita_rx_framer
assign debug_rx = vita_state;
-endmodule // rx_control
+endmodule // vita_rx_framer
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index e4f272a76..bbcf34373 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -61,10 +61,7 @@ IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release")
MESSAGE(STATUS "Build type not specified: defaulting to release.")
ENDIF(NOT CMAKE_BUILD_TYPE)
-
-#Creating a shared pointer itself has allocation overhead.
-#Define the quick allocator to reduce fast-path overhead.
-ADD_DEFINITIONS(-DBOOST_SP_USE_QUICK_ALLOCATOR)
+SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "")
IF(CMAKE_COMPILER_IS_GNUCXX)
ADD_DEFINITIONS(-Wall)
diff --git a/host/Modules/UHDPython.cmake b/host/Modules/UHDPython.cmake
index cad549ea4..345e0187d 100644
--- a/host/Modules/UHDPython.cmake
+++ b/host/Modules/UHDPython.cmake
@@ -31,7 +31,7 @@ ELSE(PYTHON_EXECUTABLE)
#and if that fails use the find program routine
IF(NOT PYTHONINTERP_FOUND)
- FIND_PROGRAM(PYTHON_EXECUTABLE python)
+ FIND_PROGRAM(PYTHON_EXECUTABLE NAMES python python2.7 python2.6)
IF(PYTHON_EXECUTABLE)
SET(PYTHONINTERP_FOUND TRUE)
ENDIF(PYTHON_EXECUTABLE)
diff --git a/host/apps/omap_debug/fetch-bin.sh b/host/apps/omap_debug/fetch-bin.sh
deleted file mode 100755
index 019ddaaf2..000000000
--- a/host/apps/omap_debug/fetch-bin.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ $GHQ ]; then
- scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u1e.bin /home/root
-else
- scp -P 8822 balister@192.168.1.10:src/git/fpgapriv/usrp2/top/u1e/build/u1e.bin /home/root
-fi
-sync
diff --git a/host/apps/omap_debug/fetch-kernel.sh b/host/apps/omap_debug/fetch-kernel.sh
deleted file mode 100755
index ce420f3d2..000000000
--- a/host/apps/omap_debug/fetch-kernel.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if [ $GHQ ]; then
- scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage
-else
- scp balister@192.168.1.10:src/git/kernel_usrp/arch/arm/boot/uImage /media/mmcblk0p1/uImage
-fi
-sync
-
diff --git a/host/apps/omap_debug/fetch-module.sh b/host/apps/omap_debug/fetch-module.sh
deleted file mode 100755
index ec28989bd..000000000
--- a/host/apps/omap_debug/fetch-module.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ $GHQ ]; then
- scp $GHQ_USER@astro:/workspace/usrp1-e-dev/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33/kernel/drivers/misc
-else
- scp balister@192.168.1.10:src/git/kernel_usrp/drivers/misc/usrp_e.ko /lib/modules/2.6.33/kernel/drivers/misc
-fi
-sync
diff --git a/host/apps/omap_debug/fetch-u-boot.sh b/host/apps/omap_debug/fetch-u-boot.sh
deleted file mode 100755
index 5309364b8..000000000
--- a/host/apps/omap_debug/fetch-u-boot.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if [ $GHQ ]; then
- scp $GHQ_USER@astro:/workspace/usrp1-e-dev/u-boot-overo/u-boot.bin /media/mmcblk0p1/
-else
- scp balister@192.168.1.167:src/git/u-boot/u-boot.bin /media/mmcblk0p1/
-fi
-sync
-
diff --git a/host/apps/omap_debug/read_board_id.sh b/host/apps/omap_debug/read_board_id.sh
deleted file mode 100755
index 96081f219..000000000
--- a/host/apps/omap_debug/read_board_id.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-i2cget -y 3 0x51 0x00 b
-i2cget -y 3 0x51 0x01 b
-i2cget -y 3 0x51 0x02 b
-i2cget -y 3 0x51 0x03 b
-i2cget -y 3 0x51 0x04 b
-i2cget -y 3 0x51 0x05 b
-
-
diff --git a/host/apps/omap_debug/reload-fpga.sh b/host/apps/omap_debug/reload-fpga.sh
deleted file mode 100755
index 2754718a4..000000000
--- a/host/apps/omap_debug/reload-fpga.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-rmmod usrp_e
-fpga-downloader /home/root/u1e.bin
-modprobe usrp_e
-usrp-e-debug-pins 1
-
diff --git a/host/apps/omap_debug/setup-board-id-eeprom.sh b/host/apps/omap_debug/setup-board-id-eeprom.sh
deleted file mode 100755
index 4dba1cce5..000000000
--- a/host/apps/omap_debug/setup-board-id-eeprom.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-i2cset -y 3 0x51 0x00 0x00
-i2cset -y 3 0x51 0x01 0x03
-i2cset -y 3 0x51 0x02 0x00
-i2cset -y 3 0x51 0x03 0x01
-i2cset -y 3 0x51 0x04 0x01
-i2cset -y 3 0x51 0x05 0x00
-i2cset -y 3 0x51 0x06 0x00
-
-i2cget -y 3 0x51 0 b
-i2cget -y 3 0x51 1 b
-i2cget -y 3 0x51 2 b
-i2cget -y 3 0x51 3 b
-i2cget -y 3 0x51 4 b
-i2cget -y 3 0x51 5 b
-i2cget -y 3 0x51 6 b
diff --git a/host/apps/omap_debug/write-eeprom.sh b/host/apps/omap_debug/write-eeprom.sh
deleted file mode 100755
index 301b06f07..000000000
--- a/host/apps/omap_debug/write-eeprom.sh
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/bash
-
-if [ $# -ne 3 ] && [ $# -ne 5 ];
-then
- echo "Usage:"
- echo ""
- echo "writeprom.sh deviceid rev fab_rev [envvar envsetting]"
- echo
- echo " deviceid - expansion board device number from table:"
- echo
- echo " Summit 0x01"
- echo " Tobi 0x02"
- echo " Tobi Duo 0x03"
- echo " Palo35 0x04"
- echo " Palo43 0x05"
- echo " Chestnut43 0x06"
- echo " Pinto 0x07"
- echo
- echo " rev - board revision (e.g. 0x00)"
- echo " fab_rev - revision marking from pcb (e.g. R2411)"
- echo " envvar - optional u-boot env variable name"
- echo " (e.g. dvimode)"
- echo " envsetting - optional u-boot env variable setting"
- echo " (e.g. 1024x768MR-16@60)"
- exit 1
-fi
-
-fabrevision=$3
-if [ ${#fabrevision} -ge 8 ]; then
- echo "Error: fab revision string must less than 8 characters"
- exit 1
-fi
-
-envvar=$4
-if [ ${#envar} -ge 16 ]; then
- echo "Error: environment variable name string must less than 16 characters"
- exit 1
-fi
-
-envsetting=$5
-if [ ${#ensetting} -ge 64 ]; then
- echo "Error: environment setting string must less than 64 characters"
- exit 1
-fi
-
-bus=3
-device=0x51
-vendorid=0x03
-
-i2cset -y $bus $device 0x00 0x00
-i2cset -y $bus $device 0x01 $vendorid
-i2cset -y $bus $device 0x02 0x00
-i2cset -y $bus $device 0x03 $1
-i2cset -y $bus $device 0x04 $2
-i2cset -y $bus $device 0x05 00
-
-let i=6
-hexdumpargs="'${#fabrevision}/1 \"0x%02x \"'"
-command="echo -n \"$fabrevision\" | hexdump -e $hexdumpargs"
-hex=$(eval $command)
-for character in $hex; do
- i2cset -y $bus $device $i $character
- let i=$i+1
-done
-i2cset -y $bus $device $i 0x00
-
-if [ $# -eq 5 ]
-then
- i2cset -y $bus $device 0x05 0x01
-
- let i=14
- hexdumpargs="'${#envvar}/1 \"0x%02x \"'"
- command="echo -n \"$envvar\" | hexdump -e $hexdumpargs"
- hex=$(eval $command)
- for character in $hex; do
- i2cset -y $bus $device $i $character
- let i=$i+1
- done
- i2cset -y $bus $device $i 0x00
-
- let i=30
- hexdumpargs="'${#envsetting}/1 \"0x%02x \"'"
- command="echo -n \"$envsetting\" | hexdump -e $hexdumpargs"
- hex=$(eval $command)
- for character in $hex; do
- i2cset -y $bus $device $i $character
- let i=$i+1
- done
- i2cset -y $bus $device $i 0x00
-fi
-
-
diff --git a/host/apps/omap_debug/write_board_id.sh b/host/apps/omap_debug/write_board_id.sh
deleted file mode 100755
index 067269c64..000000000
--- a/host/apps/omap_debug/write_board_id.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-i2cset -y 3 0x51 0x00 0x00
-i2cset -y 3 0x51 0x01 0x03
-i2cset -y 3 0x51 0x02 0x00
-i2cset -y 3 0x51 0x03 0x01
-i2cset -y 3 0x51 0x04 0x00
-i2cset -y 3 0x51 0x05 0x00
-
-
diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt
index b7a22cf0b..db755511e 100644
--- a/host/include/uhd/CMakeLists.txt
+++ b/host/include/uhd/CMakeLists.txt
@@ -25,6 +25,7 @@ INSTALL(FILES
config.hpp
convert.hpp
device.hpp
+ exception.hpp
version.hpp
wax.hpp
DESTINATION ${INCLUDE_DIR}/uhd
diff --git a/host/include/uhd/exception.hpp b/host/include/uhd/exception.hpp
new file mode 100644
index 000000000..e2a50bf1e
--- /dev/null
+++ b/host/include/uhd/exception.hpp
@@ -0,0 +1,133 @@
+//
+// Copyright 2010-2011 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_EXCEPTION_HPP
+#define INCLUDED_UHD_UTILS_EXCEPTION_HPP
+
+#include <uhd/config.hpp>
+#include <boost/current_function.hpp>
+#include <stdexcept>
+#include <string>
+
+/*!
+ * Define common exceptions used throughout the code:
+ *
+ * - The python built-in exceptions were used as inspiration.
+ * - Exceptions inherit from std::exception to provide what().
+ * - Exceptions inherit from uhd::exception to provide code().
+ *
+ * The code() provides an error code which allows the application
+ * the option of printing a cryptic error message from the 1990s.
+ */
+namespace uhd{
+
+ struct UHD_API exception : std::runtime_error{
+ exception(const std::string &what);
+ virtual unsigned code(void) const = 0;
+ };
+
+ struct UHD_API assertion_error : exception{
+ assertion_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API lookup_error : exception{
+ lookup_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API index_error : lookup_error{
+ index_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API key_error : lookup_error{
+ key_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API type_error : exception{
+ type_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API value_error : exception{
+ value_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API runtime_error : exception{
+ runtime_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API not_implemented_error : runtime_error{
+ not_implemented_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API environment_error : exception{
+ environment_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API io_error : environment_error{
+ io_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API os_error : environment_error{
+ os_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ struct UHD_API system_error : exception{
+ system_error(const std::string &what);
+ virtual unsigned code(void) const;
+ };
+
+ /*!
+ * Create a formated string with throw-site information.
+ * Fills in the function name, file name, and line number.
+ * \param what the std::exeption message
+ * \return the formatted exception message
+ */
+ #define UHD_THROW_SITE_INFO(what) std::string( \
+ std::string(what) + "\n" + \
+ " in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \
+ " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \
+ )
+
+ /*!
+ * Throws an invalid code path exception with throw-site information.
+ * Use this macro in places that code execution is not supposed to go.
+ */
+ #define UHD_THROW_INVALID_CODE_PATH() \
+ throw uhd::system_error(UHD_THROW_SITE_INFO("invalid code path"))
+
+ /*!
+ * Assert the result of the code evaluation.
+ * If the code evaluates to false, throw an assertion error.
+ * \param code the code that resolved to a boolean
+ */
+ #define UHD_ASSERT_THROW(code) if (not (code)) \
+ throw uhd::assertion_error(UHD_THROW_SITE_INFO(#code)); \
+ else void(0)
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_EXCEPTION_HPP */
diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp
index eb3394230..2c0841146 100644
--- a/host/include/uhd/types/device_addr.hpp
+++ b/host/include/uhd/types/device_addr.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -84,9 +84,15 @@ namespace uhd{
}
};
- //handy typedef for a vector of device addresses
+ //! A typedef for a vector of device addresses
typedef std::vector<device_addr_t> device_addrs_t;
+ //! Separate an indexed device address into a vector of device addresses
+ UHD_API device_addrs_t separate_device_addr(const device_addr_t &dev_addr);
+
+ //! Combine a vector of device addresses into an indexed device address
+ UHD_API device_addr_t combine_device_addrs(const device_addrs_t &dev_addrs);
+
} //namespace uhd
#endif /* INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP */
diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp
index 0c014474e..5e9cf97ad 100644
--- a/host/include/uhd/types/dict.ipp
+++ b/host/include/uhd/types/dict.ipp
@@ -18,18 +18,18 @@
#ifndef INCLUDED_UHD_TYPES_DICT_IPP
#define INCLUDED_UHD_TYPES_DICT_IPP
+#include <uhd/exception.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
-#include <stdexcept>
#include <typeinfo>
namespace uhd{
namespace /*anon*/{
template<typename Key, typename Val>
- struct key_not_found: std::out_of_range{
- key_not_found(const Key &key): std::out_of_range(
+ struct key_not_found: uhd::key_error{
+ key_not_found(const Key &key): uhd::key_error(
str(boost::format(
"key \"%s\" not found in dict(%s, %s)"
) % boost::lexical_cast<std::string>(key)
diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp
index c134725f5..5c6de162b 100644
--- a/host/include/uhd/types/serial.hpp
+++ b/host/include/uhd/types/serial.hpp
@@ -116,6 +116,59 @@ namespace uhd{
*/
spi_config_t(edge_t edge = EDGE_RISE);
};
+
+ /*!
+ * The SPI interface class.
+ * Provides routines to transact SPI and do other useful things which haven't been defined yet.
+ */
+ class UHD_API spi_iface{
+ public:
+ /*!
+ * Perform a spi transaction.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write
+ * \param num_bits how many bits in data
+ * \param readback true to readback a value
+ * \return spi data if readback set
+ */
+ virtual boost::uint32_t transact_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits,
+ bool readback
+ ) = 0;
+
+ /*!
+ * Read from the SPI bus.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write out (be sure to set write bit)
+ * \param num_bits how many bits in data
+ * \return spi data
+ */
+ virtual boost::uint32_t read_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint16_t data,
+ size_t num_bits
+ );
+
+ /*!
+ * Write to the SPI bus.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write
+ * \param num_bits how many bits in data
+ */
+ virtual void write_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint16_t data,
+ size_t num_bits
+ );
+ };
} //namespace uhd
diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt
index f60b35e59..59a1302af 100644
--- a/host/include/uhd/usrp/CMakeLists.txt
+++ b/host/include/uhd/usrp/CMakeLists.txt
@@ -43,6 +43,7 @@ INSTALL(FILES
### interfaces ###
single_usrp.hpp
multi_usrp.hpp
+ mboard_iface.hpp
DESTINATION ${INCLUDE_DIR}/uhd/usrp
)
diff --git a/host/include/uhd/usrp/dsp_props.hpp b/host/include/uhd/usrp/dsp_props.hpp
index 3e1690317..e68e11deb 100644
--- a/host/include/uhd/usrp/dsp_props.hpp
+++ b/host/include/uhd/usrp/dsp_props.hpp
@@ -39,8 +39,8 @@ namespace uhd{ namespace usrp{
enum dsp_prop_t{
DSP_PROP_NAME, //ro, std::string
DSP_PROP_OTHERS, //ro, prop_names_t
+ DSP_PROP_STREAM_CMD, //wo, stream_cmd_t
DSP_PROP_FREQ_SHIFT, //rw, double Hz
- DSP_PROP_FREQ_SHIFT_NAMES, //ro, prop_names_t
DSP_PROP_CODEC_RATE, //ro, double Sps
DSP_PROP_HOST_RATE //rw, double Sps
};
diff --git a/host/include/uhd/usrp/mboard_iface.hpp b/host/include/uhd/usrp/mboard_iface.hpp
new file mode 100644
index 000000000..784fbc7c5
--- /dev/null
+++ b/host/include/uhd/usrp/mboard_iface.hpp
@@ -0,0 +1,85 @@
+//
+// Copyright 2010-2011 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_MBOARD_IFACE_HPP
+#define INCLUDED_UHD_USRP_MBOARD_IFACE_HPP
+
+#include <uhd/types/serial.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <boost/cstdint.hpp>
+#include <utility>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+/*!
+ * The mboard interface class:
+ * Provides a set of functions to implementation layer.
+ * Including spi, peek, poke, control...
+ */
+class mboard_iface : public uhd::i2c_iface, public uhd::spi_iface {
+public:
+ typedef boost::shared_ptr<mboard_iface> sptr;
+ /*!
+ * Write a register (32 bits)
+ * \param addr the address
+ * \param data the 32bit data
+ */
+ virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0;
+
+ /*!
+ * Read a register (32 bits)
+ * \param addr the address
+ * \return the 32bit data
+ */
+ virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
+
+ /*!
+ * Write a register (16 bits)
+ * \param addr the address
+ * \param data the 16bit data
+ */
+ virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0;
+
+ /*!
+ * Read a register (16 bits)
+ * \param addr the address
+ * \return the 16bit data
+ */
+ virtual boost::uint16_t peek16(boost::uint32_t addr) = 0;
+
+ /*!
+ * Write to a serial port.
+ * \param dev which UART to write to
+ * \param buf the data to write
+ */
+ virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0;
+
+ /*!
+ * Read from a serial port.
+ * \param dev which UART to read from
+ * \return the data read from the serial port
+ */
+ virtual std::string read_uart(boost::uint8_t dev) = 0;
+
+};
+
+}}
+
+#endif //INCLUDED_UHD_USRP_DBOARD_IFACE_HPP
diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp
index 8855e2b75..a2580954e 100644
--- a/host/include/uhd/usrp/mboard_props.hpp
+++ b/host/include/uhd/usrp/mboard_props.hpp
@@ -47,8 +47,8 @@ namespace uhd{ namespace usrp{
MBOARD_PROP_CLOCK_CONFIG, //rw, clock_config_t
MBOARD_PROP_TIME_NOW, //rw, time_spec_t
MBOARD_PROP_TIME_PPS, //wo, time_spec_t
- MBOARD_PROP_STREAM_CMD, //wo, stream_cmd_t
- MBOARD_PROP_EEPROM_MAP //wr, mboard_eeprom_t
+ MBOARD_PROP_EEPROM_MAP, //wr, mboard_eeprom_t
+ MBOARD_PROP_IFACE, //ro, mboard_iface::sptr
};
}} //namespace
diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp
index 3c8dd5fac..b161d1278 100644
--- a/host/include/uhd/usrp/multi_usrp.hpp
+++ b/host/include/uhd/usrp/multi_usrp.hpp
@@ -28,6 +28,7 @@
#include <uhd/types/sensors.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <vector>
@@ -87,6 +88,9 @@ public:
//! A wildcard motherboard index
static const size_t ALL_MBOARDS = size_t(~0);
+ //! A wildcard channel index
+ static const size_t ALL_CHANS = size_t(~0);
+
//! A wildcard gain element name
static const std::string ALL_GAINS;
@@ -215,8 +219,9 @@ public:
* to ensure that the packets can be aligned by their time specs.
*
* \param stream_cmd the stream command to issue
+ * \param chan the channel index 0 to N-1
*/
- virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0;
+ virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan = ALL_CHANS) = 0;
/*!
* Set the clock configuration for the usrp device.
@@ -246,6 +251,12 @@ public:
* \return a vector of sensor names
*/
virtual std::vector<std::string> get_mboard_sensor_names(size_t mboard = 0) = 0;
+
+ /*!
+ * Get a handle to the mboard_iface object which controls peripheral access.
+ * \return a mboard_iface::sptr object
+ */
+ virtual mboard_iface::sptr get_mboard_iface(size_t mboard) = 0;
/*******************************************************************
* RX methods
@@ -282,16 +293,18 @@ public:
virtual std::string get_rx_subdev_name(size_t chan = 0) = 0;
/*!
- * Set the RX sample rate across all channels.
+ * Set the RX sample rate.
* \param rate the rate in Sps
+ * \param chan the channel index 0 to N-1
*/
- virtual void set_rx_rate(double rate) = 0;
+ virtual void set_rx_rate(double rate, size_t chan = ALL_CHANS) = 0;
/*!
- * Gets the RX sample rate for all channels.
+ * Gets the RX sample rate.
+ * \param chan the channel index 0 to N-1
* \return the rate in Sps
*/
- virtual double get_rx_rate(void) = 0;
+ virtual double get_rx_rate(size_t chan = 0) = 0;
/*!
* Set the RX center frequency.
@@ -480,16 +493,18 @@ public:
virtual std::string get_tx_subdev_name(size_t chan = 0) = 0;
/*!
- * Set the TX sample rate across all channels.
+ * Set the TX sample rate.
* \param rate the rate in Sps
+ * \param chan the channel index 0 to N-1
*/
- virtual void set_tx_rate(double rate) = 0;
+ virtual void set_tx_rate(double rate, size_t chan = ALL_CHANS) = 0;
/*!
- * Gets the TX sample rate for all channels.
+ * Gets the TX sample rate.
+ * \param chan the channel index 0 to N-1
* \return the rate in Sps
*/
- virtual double get_tx_rate(void) = 0;
+ virtual double get_tx_rate(size_t chan = 0) = 0;
/*!
* Set the TX center frequency.
diff --git a/host/include/uhd/usrp/tune_helper.hpp b/host/include/uhd/usrp/tune_helper.hpp
index db12241c1..e97ab0298 100644
--- a/host/include/uhd/usrp/tune_helper.hpp
+++ b/host/include/uhd/usrp/tune_helper.hpp
@@ -32,24 +32,21 @@ namespace uhd{ namespace usrp{
* The ddc cordic is setup to bring the IF down to baseband.
* \param subdev the dboard subdevice object with properties
* \param ddc the mboard dsp object with properties
- * \param chan the channel of the dsp to tune
* \param tune_request tune request instructions
* \return a tune result struct
*/
UHD_API tune_result_t tune_rx_subdev_and_dsp(
- wax::obj subdev, wax::obj ddc, size_t chan,
- const tune_request_t &tune_request
+ wax::obj subdev, wax::obj ddc, const tune_request_t &tune_request
);
/*!
* Calculate the overall frequency from the combination of dboard IF and DDC shift.
* \param subdev the dboard subdevice object with properties
* \param ddc the mboard dsp object with properties
- * \param chan the channel of the dsp to tune
* \return the overall tune frequency of the system in Hz
*/
UHD_API double derive_freq_from_rx_subdev_and_dsp(
- wax::obj subdev, wax::obj ddc, size_t chan
+ wax::obj subdev, wax::obj ddc
);
/*!
@@ -59,24 +56,21 @@ namespace uhd{ namespace usrp{
* The duc cordic is setup to bring the baseband up to IF.
* \param subdev the dboard subdevice object with properties
* \param duc the mboard dsp object with properties
- * \param chan the channel of the dsp to tune
* \param tune_request tune request instructions
* \return a tune result struct
*/
UHD_API tune_result_t tune_tx_subdev_and_dsp(
- wax::obj subdev, wax::obj duc, size_t chan,
- const tune_request_t &tune_request
+ wax::obj subdev, wax::obj duc, const tune_request_t &tune_request
);
/*!
* Calculate the overall frequency from the combination of dboard IF and DUC shift.
* \param subdev the dboard subdevice object with properties
* \param duc the mboard dsp object with properties
- * \param chan the channel of the dsp to tune
* \return the overall tune frequency of the system in Hz
*/
UHD_API double derive_freq_from_tx_subdev_and_dsp(
- wax::obj subdev, wax::obj duc, size_t chan
+ wax::obj subdev, wax::obj duc
);
}}
diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt
index 0dee310a8..70f724c2d 100644
--- a/host/include/uhd/utils/CMakeLists.txt
+++ b/host/include/uhd/utils/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2010 Ettus Research LLC
+# Copyright 2010-2011 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,11 +17,10 @@
INSTALL(FILES
algorithm.hpp
- assert.hpp
- assert.ipp
+ assert_has.hpp
+ assert_has.ipp
byteswap.hpp
byteswap.ipp
- exception.hpp
gain_group.hpp
images.hpp
pimpl.hpp
diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp
index d3a07db96..5598d862b 100644
--- a/host/include/uhd/utils/algorithm.hpp
+++ b/host/include/uhd/utils/algorithm.hpp
@@ -21,24 +21,12 @@
#include <algorithm>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
-#include <boost/range/size.hpp>
-/*! \file algorithm.hpp
+/*!
* Useful templated functions and classes that I like to pretend are part of stl.
* Many of the range wrapper functions come with recent versions of boost (1.43).
*/
-namespace std{
-
- /*!
- * A wrapper around std::sort that takes a range instead of an iterator.
- *
- * The elements are sorted into ascending order using the less-than operator.
- *
- * \param range the range of elements to be sorted
- */
- template<typename Range> inline void sort(Range &range){
- return std::sort(boost::begin(range), boost::end(range));
- }
+namespace uhd{
/*!
* A wrapper around std::sort that takes a range instead of an iterator.
@@ -51,18 +39,7 @@ namespace std{
* \return a new range with the elements sorted
*/
template<typename Range> inline Range sorted(const Range &range){
- Range srange(range); std::sort(srange); return srange;
- }
-
- /*!
- * 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));
+ Range r(range); std::sort(boost::begin(r), boost::end(r)); return r;
}
/*!
@@ -76,7 +53,7 @@ namespace std{
* \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;
+ Range r(range); std::reverse(boost::begin(r), boost::end(r)); return r;
}
/*!
@@ -94,35 +71,6 @@ namespace std{
}
/*!
- * Count the number of appearances of a value in a range.
- *
- * Uses std::count to count the appearances in the range.
- *
- * \param range the elements to iterate through
- * \param value the value to count in the range
- * \return the number of appearances of the value
- */
- template<typename Range, typename T> inline
- size_t count(const Range &range, const T &value){
- return std::count(boost::begin(range), boost::end(range), value);
- }
-
- /*!
- * Are the ranges equal (are their elements equivalent)?
- *
- * Uses std::equal to search the iterable for an element.
- *
- * \param range1 the first range of elements
- * \param range2 the second range of elements
- * \return true when the elements are equivalent
- */
- template<typename Range> inline
- bool equal(const Range &range1, const Range &range2){
- return (boost::size(range1) == boost::size(range2)) and
- std::equal(boost::begin(range1), boost::end(range1), boost::begin(range2));
- }
-
- /*!
* A templated clip implementation.
* \param val the value to clip between an upper and lower limit
* \param bound1 the upper or lower bound
@@ -137,6 +85,6 @@ namespace std{
return val;
}
-}//namespace std
+} //namespace uhd
#endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */
diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert_has.hpp
index 7f7b71cfb..eae7652ad 100644
--- a/host/include/uhd/utils/assert.hpp
+++ b/host/include/uhd/utils/assert_has.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -15,26 +15,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#ifndef INCLUDED_UHD_UTILS_ASSERT_HPP
-#define INCLUDED_UHD_UTILS_ASSERT_HPP
+#ifndef INCLUDED_UHD_UTILS_ASSERT_HAS_HPP
+#define INCLUDED_UHD_UTILS_ASSERT_HAS_HPP
#include <uhd/config.hpp>
-#include <uhd/utils/exception.hpp>
-#include <stdexcept>
#include <string>
namespace uhd{
- //! The exception to throw when assertions fail
- struct UHD_API assert_error : std::runtime_error{
- assert_error(const std::string &what);
- };
-
- //! Throw an assert error with throw-site information
- #define UHD_ASSERT_THROW(_x) if (not (_x)) throw uhd::assert_error( \
- UHD_THROW_SITE_INFO("assertion failed: " + std::string(#_x)) \
- ); else void(0)
-
/*!
* Check that an element is found in a container.
* If not, throw a meaningful assertion error.
@@ -54,6 +42,6 @@ namespace uhd{
}//namespace uhd
-#include <uhd/utils/assert.ipp>
+#include <uhd/utils/assert_has.ipp>
-#endif /* INCLUDED_UHD_UTILS_ASSERT_HPP */
+#endif /* INCLUDED_UHD_UTILS_ASSERT_HAS_HPP */
diff --git a/host/include/uhd/utils/assert.ipp b/host/include/uhd/utils/assert_has.ipp
index 6a8b3e417..7b3c88cb7 100644
--- a/host/include/uhd/utils/assert.ipp
+++ b/host/include/uhd/utils/assert_has.ipp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -15,10 +15,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#ifndef INCLUDED_UHD_UTILS_ASSERT_IPP
-#define INCLUDED_UHD_UTILS_ASSERT_IPP
+#ifndef INCLUDED_UHD_UTILS_ASSERT_HAS_IPP
+#define INCLUDED_UHD_UTILS_ASSERT_HAS_IPP
#include <uhd/utils/algorithm.hpp>
+#include <uhd/exception.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
@@ -30,14 +31,14 @@ namespace uhd{
const T &value,
const std::string &what
){
- if (std::has(range, value)) return;
+ if (uhd::has(range, value)) return;
std::string possible_values = "";
size_t i = 0;
BOOST_FOREACH(const T &v, range){
if (i++ > 0) possible_values += ", ";
possible_values += boost::lexical_cast<std::string>(v);
}
- throw uhd::assert_error(str(boost::format(
+ throw uhd::assertion_error(str(boost::format(
"assertion failed:\n"
" %s is not a valid %s.\n"
" possible values are: [%s].\n"
@@ -49,4 +50,4 @@ namespace uhd{
}//namespace uhd
-#endif /* INCLUDED_UHD_UTILS_ASSERT_IPP */
+#endif /* INCLUDED_UHD_UTILS_ASSERT_HAS_IPP */
diff --git a/host/include/uhd/utils/exception.hpp b/host/include/uhd/utils/exception.hpp
deleted file mode 100644
index e74c19b9c..000000000
--- a/host/include/uhd/utils/exception.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// 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_EXCEPTION_HPP
-#define INCLUDED_UHD_UTILS_EXCEPTION_HPP
-
-#include <uhd/config.hpp>
-#include <boost/current_function.hpp>
-#include <stdexcept>
-#include <string>
-
-/*!
- * Create a formated string with throw-site information.
- * Fills in the function name, file name, and line number.
- * \param what the std::exeption message
- * \return the formatted exception message
- */
-#define UHD_THROW_SITE_INFO(what) std::string( \
- std::string(what) + "\n" + \
- " in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \
- " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \
-)
-
-/*!
- * Throws an invalid code path exception with throw-site information.
- * Use this macro in places that code execution is not supposed to go.
- */
-#define UHD_THROW_INVALID_CODE_PATH() \
- throw std::runtime_error(UHD_THROW_SITE_INFO("invalid code path"))
-
-#endif /* INCLUDED_UHD_UTILS_EXCEPTION_HPP */
diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp
index fbca03019..81737423a 100644
--- a/host/include/uhd/utils/props.hpp
+++ b/host/include/uhd/utils/props.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -20,8 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/wax.hpp>
-#include <uhd/utils/exception.hpp>
-#include <stdexcept>
+#include <uhd/exception.hpp>
#include <vector>
#include <string>
@@ -68,14 +67,14 @@ namespace uhd{
* Throw-site information will be included with this error.
*/
#define UHD_THROW_PROP_GET_ERROR() \
- throw std::runtime_error(UHD_THROW_SITE_INFO("cannot get this property"))
+ throw uhd::key_error(UHD_THROW_SITE_INFO("cannot get this property"))
/*!
* Throw when setting a not-implemented or read-only property.
* Throw-site information will be included with this error.
*/
#define UHD_THROW_PROP_SET_ERROR() \
- throw std::runtime_error(UHD_THROW_SITE_INFO("cannot set this property"))
+ throw uhd::key_error(UHD_THROW_SITE_INFO("cannot set this property"))
} //namespace uhd
diff --git a/host/include/uhd/utils/safe_call.hpp b/host/include/uhd/utils/safe_call.hpp
index e23e508c8..6b2c210af 100644
--- a/host/include/uhd/utils/safe_call.hpp
+++ b/host/include/uhd/utils/safe_call.hpp
@@ -19,7 +19,7 @@
#define INCLUDED_UHD_UTILS_SAFE_CALL_HPP
#include <uhd/config.hpp>
-#include <uhd/utils/exception.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/warning.hpp>
//! helper macro for safe call to produce warnings
diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp
index 14e6734a5..6fd2b8652 100644
--- a/host/include/uhd/wax.hpp
+++ b/host/include/uhd/wax.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -19,7 +19,10 @@
#define INCLUDED_WAX_HPP
#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
#include <boost/any.hpp>
+#include <typeinfo>
+#include <string>
/*!
* WAX - it's a metaphor!
@@ -47,12 +50,6 @@
namespace wax{
/*!
- * The wax::bad cast will be thrown when
- * cast is called with the wrong typeid.
- */
- typedef boost::bad_any_cast bad_cast;
-
- /*!
* WAX object base class:
*
* A wax obj has two major purposes:
@@ -140,7 +137,12 @@ namespace wax{
* \throw wax::bad_cast when the cast fails
*/
template<class T> T as(void) const{
- return boost::any_cast<T>(resolve());
+ try{
+ return boost::any_cast<T>(resolve());
+ }
+ catch(const boost::bad_any_cast &e){
+ throw uhd::type_error(std::string("") + "Cannot wax cast " + type().name() + " to " + typeid(T).name() + " " + e.what());
+ }
}
private:
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index 8096c15d8..dbfa234b6 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -15,6 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+#Creating a shared pointer itself has allocation overhead.
+#Define the quick allocator to reduce fast-path overhead.
+ADD_DEFINITIONS(-DBOOST_SP_USE_QUICK_ALLOCATOR)
+
########################################################################
# Helpful Macros
########################################################################
@@ -97,6 +101,7 @@ 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}/exception.cpp
${CMAKE_CURRENT_SOURCE_DIR}/version.cpp
${CMAKE_CURRENT_SOURCE_DIR}/wax.cpp
)
diff --git a/host/lib/convert/convert_impl.cpp b/host/lib/convert/convert_impl.cpp
index 6a5a1465d..d43cecfec 100644
--- a/host/lib/convert/convert_impl.cpp
+++ b/host/lib/convert/convert_impl.cpp
@@ -17,7 +17,7 @@
#include <uhd/convert.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/exception.hpp>
+#include <uhd/exception.hpp>
#include <iostream>
using namespace uhd;
diff --git a/host/lib/convert/gen_convert_pred.py b/host/lib/convert/gen_convert_pred.py
index d2f90bf41..360fbcf44 100644
--- a/host/lib/convert/gen_convert_pred.py
+++ b/host/lib/convert/gen_convert_pred.py
@@ -21,11 +21,11 @@ TMPL_TEXT = """
/***********************************************************************
* This file was generated by $file on $time.strftime("%c")
**********************************************************************/
+\#include <uhd/exception.hpp>
\#include <boost/tokenizer.hpp>
\#include <boost/lexical_cast.hpp>
\#include <boost/detail/endian.hpp>
\#include <boost/cstdint.hpp>
-\#include <stdexcept>
\#include <string>
\#include <vector>
@@ -37,9 +37,10 @@ enum dir_type{
DIR_CPU_TO_OTW = 1
};
-struct pred_error : std::runtime_error{
- pred_error(const std::string &what)
- :std::runtime_error("convert::make_pred: " + what){
+struct pred_error : uhd::value_error{
+ pred_error(const std::string &what):
+ uhd::value_error("convert::make_pred: " + what)
+ {
/* NOP */
}
};
diff --git a/host/lib/device.cpp b/host/lib/device.cpp
index 386588a08..0002bee6e 100644
--- a/host/lib/device.cpp
+++ b/host/lib/device.cpp
@@ -17,7 +17,7 @@
#include <uhd/device.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/foreach.hpp>
@@ -25,7 +25,6 @@
#include <boost/weak_ptr.hpp>
#include <boost/functional/hash.hpp>
#include <boost/tuple/tuple.hpp>
-#include <stdexcept>
#include <iostream>
using namespace uhd;
@@ -44,7 +43,7 @@ static size_t hash_device_addr(
){
//combine the hashes of sorted keys/value pairs
size_t hash = 0;
- BOOST_FOREACH(const std::string &key, std::sorted(dev_addr.keys())){
+ BOOST_FOREACH(const std::string &key, uhd::sorted(dev_addr.keys())){
boost::hash_combine(hash, key);
boost::hash_combine(hash, dev_addr[key]);
}
@@ -106,14 +105,14 @@ device::sptr device::make(const device_addr_t &hint, size_t which){
//check that we found any devices
if (dev_addr_makers.size() == 0){
- throw std::runtime_error(str(
+ throw uhd::key_error(str(
boost::format("No devices found for ----->\n%s") % hint.to_pp_string()
));
}
//check that the which index is valid
if (dev_addr_makers.size() <= which){
- throw std::runtime_error(str(
+ throw uhd::index_error(str(
boost::format("No device at index %d for ----->\n%s") % which % hint.to_pp_string()
));
}
@@ -140,7 +139,7 @@ device::sptr device::make(const device_addr_t &hint, size_t which){
return hash_to_device[dev_hash].lock();
}
//create and register a new device
- catch(const uhd::assert_error &){
+ catch(const uhd::assertion_error &){
device::sptr dev = maker(dev_addr);
hash_to_device[dev_hash] = dev;
return dev;
diff --git a/host/lib/exception.cpp b/host/lib/exception.cpp
new file mode 100644
index 000000000..ecb1fe768
--- /dev/null
+++ b/host/lib/exception.cpp
@@ -0,0 +1,43 @@
+//
+// Copyright 2011 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/exception.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/format.hpp>
+
+using namespace uhd;
+
+exception::exception(const std::string &what):
+ std::runtime_error(what){/* NOP */}
+
+#define make_exception_impl(name, class, base) \
+ class::class(const std::string &what): \
+ base(str(boost::format("%s: %s") % name % what)){} \
+ unsigned class::code(void) const{return boost::hash<std::string>()(#class) & 0xfff;}
+
+make_exception_impl("AssertionError", assertion_error, exception)
+make_exception_impl("LookupError", lookup_error, exception)
+make_exception_impl("IndexError", index_error, lookup_error)
+make_exception_impl("KeyError", key_error, lookup_error)
+make_exception_impl("TypeError", type_error, exception)
+make_exception_impl("ValueError", value_error, exception)
+make_exception_impl("RuntimeError", runtime_error, exception)
+make_exception_impl("NotImplementedError", not_implemented_error, runtime_error)
+make_exception_impl("EnvironmentError", environment_error, exception)
+make_exception_impl("IOError", io_error, environment_error)
+make_exception_impl("OSError", os_error, environment_error)
+make_exception_impl("SystemError", system_error, exception)
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py
index 986093004..a509936b4 100644
--- a/host/lib/ic_reg_maps/common.py
+++ b/host/lib/ic_reg_maps/common.py
@@ -30,8 +30,8 @@ COMMON_TMPL = """\
\#define INCLUDED_$(name.upper())_HPP
\#include <uhd/config.hpp>
+\#include <uhd/exception.hpp>
\#include <boost/cstdint.hpp>
-\#include <stdexcept>
\#include <set>
class $(name)_t{
@@ -69,7 +69,7 @@ public:
}
template<typename T> std::set<T> get_changed_addrs(void){
- if (_state == NULL) throw std::runtime_error("no saved state");
+ if (_state == NULL) throw uhd::runtime_error("no saved state");
//check each register for changes
std::set<T> addrs;
#for $reg in $regs
diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py
index 427217eb6..8481932ed 100755
--- a/host/lib/transport/gen_vrt_if_packet.py
+++ b/host/lib/transport/gen_vrt_if_packet.py
@@ -31,10 +31,10 @@ TMPL_TEXT = """
* This file was generated by $file on $time.strftime("%c")
**********************************************************************/
+\#include <uhd/exception.hpp>
\#include <uhd/transport/vrt_if_packet.hpp>
\#include <uhd/utils/byteswap.hpp>
\#include <boost/detail/endian.hpp>
-\#include <stdexcept>
\#include <vector>
//define the endian macros to convert integers
@@ -157,7 +157,7 @@ void vrt::if_hdr_unpack_$(suffix)(
//failure case
if (if_packet_info.num_packet_words32 < packet_words32)
- throw std::runtime_error("bad vrt header or packet fragment");
+ throw uhd::value_error("bad vrt header or packet fragment");
*/
//Fix for short packets sent from the fpga:
// Use the num_packet_words32 passed in as input,
@@ -223,7 +223,7 @@ void vrt::if_hdr_unpack_$(suffix)(
########## Variables ##########
//another failure case
if (packet_words32 < $($num_header_words + $num_trailer_words))
- throw std::runtime_error("bad vrt header or invalid packet length");
+ throw uhd::value_error("bad vrt header or invalid packet length");
if_packet_info.num_header_words32 = $num_header_words;
if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
break;
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index cfa77d9ca..6d4df7875 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
//
#include "libusb1_base.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/types/dict.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/foreach.hpp>
@@ -93,7 +93,7 @@ public:
//allocate a new list of devices
libusb_device** dev_list;
ssize_t ret = libusb_get_device_list(sess->get_context(), &dev_list);
- if (ret < 0) throw std::runtime_error("cannot enumerate usb devices");
+ if (ret < 0) throw uhd::os_error("cannot enumerate usb devices");
//fill the vector of device references
for (size_t i = 0; i < size_t(ret); i++) _devs.push_back(
@@ -206,9 +206,9 @@ libusb::device_handle::sptr libusb::device_handle::get_cached_handle(device::spt
handles[dev->get()] = new_handle;
return new_handle;
}
- catch(const std::exception &e){
+ catch(const uhd::exception &e){
std::cerr << "USB open failed: see the application notes for your device." << std::endl;
- throw std::runtime_error(e.what());
+ throw;
}
}
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 87adece45..6dee69711 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -20,7 +20,7 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <uhd/transport/buffer_pool.hpp>
#include <uhd/utils/thread_priority.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/function.hpp>
#include <boost/foreach.hpp>
#include <boost/thread/thread.hpp>
@@ -33,6 +33,11 @@ using namespace uhd::transport;
static const size_t DEFAULT_NUM_XFERS = 16; //num xfers
static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
+//! helper function: handles all async callbacks
+static void libusb_async_cb(libusb_transfer *lut){
+ (*static_cast<boost::function<void()> *>(lut->user_data))();
+}
+
/***********************************************************************
* Reusable managed receiver buffer:
* - Associated with a particular libusb transfer struct.
@@ -79,7 +84,8 @@ public:
void commit(size_t len){
if (_expired) return;
_lut->length = len;
- UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
+ if(len == 0) libusb_async_cb(_lut);
+ else UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
_expired = true;
}
@@ -100,11 +106,6 @@ private:
bool _expired;
};
-//! helper function: handles all async callbacks
-static void libusb_async_cb(libusb_transfer *lut){
- (*static_cast<boost::function<void()> *>(lut->user_data))();
-}
-
/***********************************************************************
* USB zero_copy device class
**********************************************************************/
diff --git a/host/lib/transport/usb_dummy_impl.cpp b/host/lib/transport/usb_dummy_impl.cpp
index 8a9772e7f..930678405 100644
--- a/host/lib/transport/usb_dummy_impl.cpp
+++ b/host/lib/transport/usb_dummy_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -18,7 +18,7 @@
#include <uhd/transport/usb_device_handle.hpp>
#include <uhd/transport/usb_control.hpp>
#include <uhd/transport/usb_zero_copy.hpp>
-#include <uhd/utils/exception.hpp>
+#include <uhd/exception.hpp>
using namespace uhd;
using namespace uhd::transport;
@@ -28,12 +28,12 @@ std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(boost::u
}
usb_control::sptr usb_control::make(usb_device_handle::sptr){
- throw std::runtime_error("no usb support -> usb_control::make not implemented");
+ throw uhd::not_implemented_error("no usb support -> usb_control::make not implemented");
}
usb_zero_copy::sptr usb_zero_copy::make(
usb_device_handle::sptr,
size_t, size_t, const device_addr_t &
){
- throw std::runtime_error("no usb support -> usb_zero_copy::make not implemented");
+ throw uhd::not_implemented_error("no usb support -> usb_zero_copy::make not implemented");
}
diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp
index 6f3ac0421..d74b2c13c 100644
--- a/host/lib/transport/vrt_packet_handler.hpp
+++ b/host/lib/transport/vrt_packet_handler.hpp
@@ -20,7 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/device.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/types/io_type.hpp>
#include <uhd/types/otw_type.hpp>
@@ -300,18 +300,18 @@ template <typename T> UHD_INLINE T get_context_code(
typedef boost::function<bool(managed_send_buffs_t &)> get_send_buffs_t;
typedef boost::function<void(boost::uint32_t *, uhd::transport::vrt::if_packet_info_t &)> vrt_packer_t;
+ static const boost::uint64_t zeros = 0;
+
struct send_state{
//init the expected seq number
size_t next_packet_seq;
managed_send_buffs_t managed_buffs;
- const boost::uint64_t zeros;
std::vector<const void *> zero_buffs;
std::vector<const void *> io_buffs;
send_state(size_t width = 1):
next_packet_seq(0),
managed_buffs(width),
- zeros(0),
zero_buffs(width, &zeros),
io_buffs(0) //resized later
{
diff --git a/host/lib/types/device_addr.cpp b/host/lib/types/device_addr.cpp
index 14afaa24b..193f76f8c 100644
--- a/host/lib/types/device_addr.cpp
+++ b/host/lib/types/device_addr.cpp
@@ -16,10 +16,11 @@
//
#include <uhd/types/device_addr.hpp>
-#include <boost/algorithm/string.hpp> //for trim
+#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
+#include <boost/regex.hpp>
#include <stdexcept>
#include <sstream>
@@ -47,7 +48,7 @@ device_addr_t::device_addr_t(const std::string &args){
goto continue_next_arg;
}
}
- throw std::runtime_error("invalid args string: "+args);
+ throw uhd::value_error("invalid args string: "+args);
continue_next_arg: continue;
}
}
@@ -71,3 +72,51 @@ std::string device_addr_t::to_string(void) const{
}
return args_str;
}
+
+#include <uhd/utils/warning.hpp>
+
+device_addrs_t uhd::separate_device_addr(const device_addr_t &dev_addr){
+ //------------ support old deprecated way and print warning --------
+ if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){
+ std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" "));
+ if (addrs.size() > 1){
+ device_addr_t fixed_dev_addr = dev_addr;
+ fixed_dev_addr.pop("addr");
+ for (size_t i = 0; i < addrs.size(); i++){
+ fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i];
+ }
+ uhd::warning::post(
+ "addr = <space separated list of ip addresses> is deprecated.\n"
+ "To address a multi-device, use multiple <key><index> = <val>.\n"
+ "See the USRP-NXXX application notes. Two device example:\n"
+ " addr0 = 192.168.10.2\n"
+ " addr1 = 192.168.10.3\n"
+ );
+ return separate_device_addr(fixed_dev_addr);
+ }
+ }
+ //------------------------------------------------------------------
+ device_addrs_t dev_addrs;
+ BOOST_FOREACH(const std::string &key, dev_addr.keys()){
+ boost::cmatch matches;
+ if (not boost::regex_match(key.c_str(), matches, boost::regex("^(\\D+)(\\d*)$"))){
+ throw std::runtime_error("unknown key format: " + key);
+ }
+ std::string key_part(matches[1].first, matches[1].second);
+ std::string num_part(matches[2].first, matches[2].second);
+ size_t num = (num_part.empty())? 0 : boost::lexical_cast<size_t>(num_part);
+ dev_addrs.resize(std::max(num+1, dev_addrs.size()));
+ dev_addrs[num][key_part] = dev_addr[key];
+ }
+ return dev_addrs;
+}
+
+device_addr_t uhd::combine_device_addrs(const device_addrs_t &dev_addrs){
+ device_addr_t dev_addr;
+ for (size_t i = 0; i < dev_addrs.size(); i++){
+ BOOST_FOREACH(const std::string &key, dev_addrs[i].keys()){
+ dev_addr[str(boost::format("%s%d") % key % i)] = dev_addrs[i][key];
+ }
+ }
+ return dev_addr;
+}
diff --git a/host/lib/types/mac_addr.cpp b/host/lib/types/mac_addr.cpp
index cf3c3fa97..a5cb90f97 100644
--- a/host/lib/types/mac_addr.cpp
+++ b/host/lib/types/mac_addr.cpp
@@ -16,12 +16,11 @@
//
#include <uhd/types/mac_addr.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/cstdint.hpp>
-#include <stdexcept>
#include <sstream>
using namespace uhd;
@@ -40,7 +39,7 @@ mac_addr_t mac_addr_t::from_string(const std::string &mac_addr_str){
try{
if (mac_addr_str.size() != 17){
- throw std::runtime_error("expected exactly 17 characters");
+ throw uhd::value_error("expected exactly 17 characters");
}
//split the mac addr hex string at the colons
@@ -55,7 +54,7 @@ mac_addr_t mac_addr_t::from_string(const std::string &mac_addr_str){
}
catch(std::exception const& e){
- throw std::runtime_error(str(
+ throw uhd::value_error(str(
boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what()
));
}
diff --git a/host/lib/types/ranges.cpp b/host/lib/types/ranges.cpp
index 4a0d05d80..6e39bc688 100644
--- a/host/lib/types/ranges.cpp
+++ b/host/lib/types/ranges.cpp
@@ -16,10 +16,10 @@
//
#include <uhd/types/ranges.hpp>
+#include <uhd/exception.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
-#include <stdexcept>
#include <sstream>
using namespace uhd;
@@ -48,7 +48,7 @@ range_t::range_t(
_impl(UHD_PIMPL_MAKE(impl, (start, stop, step)))
{
if (stop < start){
- throw std::invalid_argument("cannot make range where stop < start");
+ throw uhd::value_error("cannot make range where stop < start");
}
}
@@ -78,11 +78,11 @@ const std::string range_t::to_pp_string(void) const{
**********************************************************************/
void check_meta_range_monotonic(const meta_range_t &mr){
if (mr.empty()){
- throw std::runtime_error("meta-range cannot be empty");
+ throw uhd::value_error("meta-range cannot be empty");
}
for (size_t i = 1; i < mr.size(); i++){
if (mr.at(i).start() < mr.at(i-1).stop()){
- throw std::runtime_error("meta-range is not monotonic");
+ throw uhd::value_error("meta-range is not monotonic");
}
}
}
diff --git a/host/lib/types/sensors.cpp b/host/lib/types/sensors.cpp
index dd8a170ea..52a63d14c 100644
--- a/host/lib/types/sensors.cpp
+++ b/host/lib/types/sensors.cpp
@@ -16,7 +16,7 @@
//
#include <uhd/types/sensors.hpp>
-#include <uhd/utils/exception.hpp>
+#include <uhd/exception.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
diff --git a/host/lib/types/serial.cpp b/host/lib/types/serial.cpp
index 9acf7156a..aa1133e72 100644
--- a/host/lib/types/serial.cpp
+++ b/host/lib/types/serial.cpp
@@ -54,3 +54,25 @@ byte_vector_t i2c_iface::read_eeprom(
}
return bytes;
}
+
+boost::uint32_t spi_iface::read_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint16_t data,
+ size_t num_bits
+){
+ return transact_spi(
+ which_slave, config, data, num_bits, true
+ );
+}
+
+void spi_iface::write_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint16_t data,
+ size_t num_bits
+){
+ transact_spi(
+ which_slave, config, data, num_bits, false
+ );
+}
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt
index 97a54a798..59dabbd58 100644
--- a/host/lib/usrp/CMakeLists.txt
+++ b/host/lib/usrp/CMakeLists.txt
@@ -31,7 +31,6 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/multi_usrp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/subdev_spec.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tune_helper.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/wrapper_utils.hpp
)
INCLUDE_SUBDIRECTORY(dboard)
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp
index b319289db..3fffeab0c 100644
--- a/host/lib/usrp/dboard/db_basic_and_lf.cpp
+++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp
@@ -18,7 +18,7 @@
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/usrp/dboard_base.hpp>
@@ -193,7 +193,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
case SUBDEV_PROP_ANTENNA:
if (val.as<std::string>().empty()) return;
- throw std::runtime_error("no selectable antennas on this board");
+ throw uhd::value_error("no selectable antennas on this board");
case SUBDEV_PROP_FREQ:
return; // it wont do you much good, but you can set it
@@ -300,7 +300,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){
case SUBDEV_PROP_ANTENNA:
if (val.as<std::string>().empty()) return;
- throw std::runtime_error("no selectable antennas on this board");
+ throw uhd::value_error("no selectable antennas on this board");
case SUBDEV_PROP_FREQ:
return; // it wont do you much good, but you can set it
diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp
index 98d9479fc..b984608ca 100644
--- a/host/lib/usrp/dboard/db_dbsrx.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx.cpp
@@ -21,7 +21,7 @@
#include "max2118_regs.hpp"
#include <uhd/utils/static.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/types/ranges.hpp>
@@ -83,8 +83,8 @@ private:
void set_bandwidth(double 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));
+ start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x5));
+ stop_reg = boost::uint8_t(uhd::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;
@@ -112,8 +112,8 @@ private:
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));
+ start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x1));
+ stop_reg = boost::uint8_t(uhd::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;
@@ -237,8 +237,8 @@ void dbsrx::set_lo_freq(double target_freq){
bool update_filter_settings = false;
//choose refclock
std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX);
- const double max_clock_rate = std::sorted(clock_rates).back();
- BOOST_FOREACH(ref_clock, std::reversed(std::sorted(clock_rates))){
+ const double max_clock_rate = uhd::sorted(clock_rates).back();
+ BOOST_FOREACH(ref_clock, uhd::reversed(uhd::sorted(clock_rates))){
if (ref_clock > 27.0e6) continue;
if (size_t(max_clock_rate/ref_clock)%2 == 1) continue; //reject asymmetric clocks (odd divisors)
@@ -485,14 +485,14 @@ void dbsrx::set_gain(double gain, const std::string &name){
**********************************************************************/
void dbsrx::set_bandwidth(double bandwidth){
//clip the input
- bandwidth = std::clip<double>(bandwidth, 4e6, 33e6);
+ bandwidth = uhd::clip<double>(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);
+ _max2118_write_regs.f_dac = uhd::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127);
//determine actual bandwidth
_bandwidth = double((ref_clock/(_max2118_write_regs.m_divider))*(4+0.145*_max2118_write_regs.f_dac));
diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp
index f4b797995..e7b42cb05 100644
--- a/host/lib/usrp/dboard/db_dbsrx2.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx2.cpp
@@ -19,7 +19,7 @@
#include "max2112_regs.hpp"
#include <uhd/utils/static.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/sensors.hpp>
@@ -79,8 +79,8 @@ private:
void set_bandwidth(double 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, 0xB));
- stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0xB));
+ start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0xB));
+ stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB));
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;
@@ -108,8 +108,8 @@ private:
void read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){
static const boost::uint8_t status_addr = 0xC;
- start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0xD));
- stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0xD));
+ start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0xD));
+ stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD));
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;
@@ -216,7 +216,7 @@ dbsrx2::~dbsrx2(void){
* Tuning
**********************************************************************/
void dbsrx2::set_lo_freq(double target_freq){
- //target_freq = std::clip(target_freq, dbsrx2_freq_range.min, dbsrx2_freq_range.max);
+ //target_freq = uhd::clip(target_freq, dbsrx2_freq_range.min, dbsrx2_freq_range.max);
//variables used in the calculation below
int scaler = target_freq > 1125e6 ? 2 : 4;
@@ -330,7 +330,7 @@ void dbsrx2::set_gain(double gain, const std::string &name){
**********************************************************************/
void dbsrx2::set_bandwidth(double bandwidth){
//clip the input
- bandwidth = std::clip<double>(bandwidth, 4e6, 40e6);
+ bandwidth = uhd::clip<double>(bandwidth, 4e6, 40e6);
_max2112_write_regs.lp = int((bandwidth/1e6 - 4)/0.29 + 12);
_bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29)*1e6;
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 3e3cf00f2..4d8222a52 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -37,7 +37,7 @@
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/sensors.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/warning.hpp>
@@ -245,7 +245,7 @@ static double rx_pga0_gain_to_dac_volts(double &gain, double range){
static const double slope = (max_volts-min_volts)/(range);
//calculate the voltage for the aux dac
- double dac_volts = std::clip<double>(gain*slope + min_volts, max_volts, min_volts);
+ double dac_volts = uhd::clip<double>(gain*slope + min_volts, max_volts, min_volts);
//the actual gain setting
gain = (dac_volts - min_volts)/slope;
diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp
index af025952e..d264c9ca4 100644
--- a/host/lib/usrp/dboard/db_tvrx.cpp
+++ b/host/lib/usrp/dboard/db_tvrx.cpp
@@ -28,7 +28,7 @@
//gain range: [0:1dB:115dB]
#include <uhd/utils/static.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/types/ranges.hpp>
@@ -241,7 +241,7 @@ static std::string get_band(double freq) {
static double gain_interp(double gain, boost::array<double, 17> db_vector, boost::array<double, 17> volts_vector) {
double volts;
- gain = std::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here
+ gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here
boost::uint8_t gain_step = 0;
//find which bin we're in
@@ -288,7 +288,7 @@ static double rf_gain_to_voltage(double gain, double lo_freq){
//this is the voltage at the USRP DAC output
double dac_volts = gain_volts / opamp_gain;
- dac_volts = std::clip<double>(dac_volts, 0.0, 3.3);
+ dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3);
if (tvrx_debug) std::cerr << boost::format(
"tvrx RF AGC gain: %f dB, dac_volts: %f V"
@@ -311,7 +311,7 @@ static double if_gain_to_voltage(double gain){
double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts);
double dac_volts = gain_volts / opamp_gain;
- dac_volts = std::clip<double>(dac_volts, 0.0, 3.3);
+ dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3);
if (tvrx_debug) std::cerr << boost::format(
"tvrx IF AGC gain: %f dB, dac_volts: %f V"
diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp
index f0a4c000e..cef4bee4a 100644
--- a/host/lib/usrp/dboard/db_unknown.cpp
+++ b/host/lib/usrp/dboard/db_unknown.cpp
@@ -17,7 +17,7 @@
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/types/ranges.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/usrp/dboard_base.hpp>
diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp
index 0bc2d0ca1..2e9a1edc8 100644
--- a/host/lib/usrp/dboard/db_wbx.cpp
+++ b/host/lib/usrp/dboard/db_wbx.cpp
@@ -69,7 +69,7 @@
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/sensors.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/warning.hpp>
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index f4f74eb86..9d25b30a5 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -49,7 +49,7 @@
#include "max2829_regs.hpp"
#include <uhd/utils/static.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/types/ranges.hpp>
@@ -358,7 +358,7 @@ void xcvr2450::set_rx_ant(const std::string &ant){
*/
static int gain_to_tx_vga_reg(double &gain){
//calculate the register value
- int reg = std::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63);
+ int reg = uhd::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63);
//calculate the actual gain value
if (reg < 4) gain = 0;
@@ -376,7 +376,7 @@ static int gain_to_tx_vga_reg(double &gain){
* \return gain enum value
*/
static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){
- int reg = std::clip(boost::math::iround(gain*3/5.0), 0, 3);
+ int reg = uhd::clip(boost::math::iround(gain*3/5.0), 0, 3);
switch(reg){
case 0:
gain = 0;
@@ -401,7 +401,7 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){
* \return 5 bit the register value
*/
static int gain_to_rx_vga_reg(double &gain){
- int reg = std::clip(boost::math::iround(gain/2.0), 0, 31);
+ int reg = uhd::clip(boost::math::iround(gain/2.0), 0, 31);
gain = double(reg*2);
return reg;
}
@@ -413,7 +413,7 @@ static int gain_to_rx_vga_reg(double &gain){
* \return 2 bit the register value
*/
static int gain_to_rx_lna_reg(double &gain){
- int reg = std::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3);
+ int reg = uhd::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3);
switch(reg){
case 0:
case 1: gain = 0; break;
@@ -456,7 +456,7 @@ void xcvr2450::set_rx_gain(double gain, const std::string &name){
* Bandwidth Handling
**********************************************************************/
static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double &bandwidth){
- int reg = std::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3);
+ int reg = uhd::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3);
switch(reg){
case 1: // bandwidth < 15MHz
@@ -473,7 +473,7 @@ static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double
}
static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &bandwidth, double requested_bandwidth){
- int reg = std::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22);
+ int reg = uhd::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22);
switch(reg){
case 18: // requested_bandwidth < 92.5%
@@ -496,7 +496,7 @@ static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &ba
}
static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg(double &bandwidth){
- int reg = std::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11);
+ int reg = uhd::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11);
switch(reg){
case 0: // bandwidth < 7.5MHz
diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp
index 6c4e29d9e..999dd9ffc 100644
--- a/host/lib/usrp/dboard_base.cpp
+++ b/host/lib/usrp/dboard_base.cpp
@@ -59,12 +59,12 @@ dboard_id_t dboard_base::get_tx_id(void){
**********************************************************************/
xcvr_dboard_base::xcvr_dboard_base(ctor_args_t args) : dboard_base(args){
if (get_rx_id() == dboard_id_t::none()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"cannot create xcvr board when the rx id is \"%s\""
) % dboard_id_t::none().to_pp_string()));
}
if (get_tx_id() == dboard_id_t::none()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"cannot create xcvr board when the tx id is \"%s\""
) % dboard_id_t::none().to_pp_string()));
}
@@ -79,7 +79,7 @@ xcvr_dboard_base::~xcvr_dboard_base(void){
**********************************************************************/
rx_dboard_base::rx_dboard_base(ctor_args_t args) : dboard_base(args){
if (get_tx_id() != dboard_id_t::none()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"cannot create rx board when the tx id is \"%s\""
" -> expected a tx id of \"%s\""
) % get_tx_id().to_pp_string() % dboard_id_t::none().to_pp_string()));
@@ -91,11 +91,11 @@ rx_dboard_base::~rx_dboard_base(void){
}
void rx_dboard_base::tx_get(const wax::obj &, wax::obj &){
- throw std::runtime_error("cannot call tx_get on a rx dboard");
+ throw uhd::runtime_error("cannot call tx_get on a rx dboard");
}
void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){
- throw std::runtime_error("cannot call tx_set on a rx dboard");
+ throw uhd::runtime_error("cannot call tx_set on a rx dboard");
}
/***********************************************************************
@@ -103,7 +103,7 @@ void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){
**********************************************************************/
tx_dboard_base::tx_dboard_base(ctor_args_t args) : dboard_base(args){
if (get_rx_id() != dboard_id_t::none()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"cannot create tx board when the rx id is \"%s\""
" -> expected a rx id of \"%s\""
) % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string()));
@@ -115,9 +115,9 @@ tx_dboard_base::~tx_dboard_base(void){
}
void tx_dboard_base::rx_get(const wax::obj &, wax::obj &){
- throw std::runtime_error("cannot call rx_get on a tx dboard");
+ throw uhd::runtime_error("cannot call rx_get on a tx dboard");
}
void tx_dboard_base::rx_set(const wax::obj &, const wax::obj &){
- throw std::runtime_error("cannot call rx_set on a tx dboard");
+ throw uhd::runtime_error("cannot call rx_set on a tx dboard");
}
diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp
index c47390bf8..c1e44fb74 100644
--- a/host/lib/usrp/dboard_eeprom.cpp
+++ b/host/lib/usrp/dboard_eeprom.cpp
@@ -16,7 +16,8 @@
//
#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
+#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <algorithm>
#include <iostream>
@@ -128,7 +129,7 @@ void dboard_eeprom_t::load(i2c_iface &iface, boost::uint8_t addr){
&bytes.at(DB_EEPROM_SERIAL+DB_EEPROM_SERIAL_LEN))
);
- }catch(const uhd::assert_error &){
+ }catch(const uhd::assertion_error &){
id = dboard_id_t::none();
serial = "";
}
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index 75594e670..9055905b1 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -20,7 +20,7 @@
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/types/dict.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/format.hpp>
@@ -50,7 +50,7 @@ void dboard_manager::register_dboard(
){
//std::cout << "registering: " << name << std::endl;
if (get_id_to_args_map().has_key(dboard_id)){
- throw std::runtime_error(str(boost::format(
+ throw uhd::key_error(str(boost::format(
"The dboard id %s is already registered to %s."
) % dboard_id.to_string() % dboard_id.to_pp_string()));
}
@@ -315,7 +315,7 @@ prop_names_t dboard_manager_impl::get_tx_subdev_names(void){
}
wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){
- if (not _rx_dboards.has_key(subdev_name)) throw std::invalid_argument(
+ if (not _rx_dboards.has_key(subdev_name)) throw uhd::key_error(
str(boost::format("Unknown rx subdev name %s") % subdev_name)
);
//get a link to the rx subdev proxy
@@ -323,7 +323,7 @@ wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){
}
wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){
- if (not _tx_dboards.has_key(subdev_name)) throw std::invalid_argument(
+ if (not _tx_dboards.has_key(subdev_name)) throw uhd::key_error(
str(boost::format("Unknown tx subdev name %s") % subdev_name)
);
//get a link to the tx subdev proxy
diff --git a/host/lib/usrp/dsp_utils.cpp b/host/lib/usrp/dsp_utils.cpp
index 576c4639f..a3a557060 100644
--- a/host/lib/usrp/dsp_utils.cpp
+++ b/host/lib/usrp/dsp_utils.cpp
@@ -17,7 +17,7 @@
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/math/special_functions/round.hpp>
@@ -44,7 +44,7 @@ boost::uint32_t dsp_type1::calc_rx_mux_word(subdev_conn_t subdev_conn){
case SUBDEV_CONN_COMPLEX_IQ: return (0x1 << 4) | (0x0 << 0); //DDC0Q=ADC0Q, DDC0I=ADC0I
case SUBDEV_CONN_COMPLEX_QI: return (0x0 << 4) | (0x1 << 0); //DDC0Q=ADC0I, DDC0I=ADC0Q
case SUBDEV_CONN_REAL_I: return (0xf << 4) | (0x0 << 0); //DDC0Q=ZERO, DDC0I=ADC0I
- case SUBDEV_CONN_REAL_Q: return (0x1 << 4) | (0xf << 0); //DDC0Q=ADC0Q, DDC0I=ZERO
+ case SUBDEV_CONN_REAL_Q: return (0xf << 4) | (0x1 << 0); //DDC0Q=ZERO, DDC0I=ADC0Q
default: UHD_THROW_INVALID_CODE_PATH();
}
}
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index b1062fa39..e0ab6de90 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -16,11 +16,10 @@
//
#include <uhd/usrp/gps_ctrl.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/cstdint.hpp>
-#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread.hpp>
+#include <boost/thread/thread.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
@@ -168,7 +167,7 @@ public:
break;
case GPS_TYPE_NONE:
default:
- throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n");
+ throw uhd::runtime_error("get_time(): Unsupported GPS or no GPS detected\n");
break;
}
return now;
diff --git a/host/lib/usrp/misc_utils.cpp b/host/lib/usrp/misc_utils.cpp
index 2bad83b3c..ddcad41cf 100644
--- a/host/lib/usrp/misc_utils.cpp
+++ b/host/lib/usrp/misc_utils.cpp
@@ -16,7 +16,7 @@
//
#include <uhd/usrp/misc_utils.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/gain_group.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
@@ -167,7 +167,7 @@ static void verify_xx_subdev_spec(
BOOST_FOREACH(subdev_spec_pair_t &pair, subdev_spec){
//empty db name means select dboard automatically
if (pair.db_name.empty()){
- if (dboard_names.size() != 1) throw std::runtime_error(
+ if (dboard_names.size() != 1) throw uhd::value_error(
"A daughterboard name must be provided for multi-slot motherboards: " + subdev_spec.to_string()
);
pair.db_name = dboard_names.front();
@@ -178,7 +178,7 @@ static void verify_xx_subdev_spec(
//empty sd name means select the subdev automatically
if (pair.sd_name.empty()){
- if (subdev_names.size() != 1) throw std::runtime_error(
+ if (subdev_names.size() != 1) throw uhd::value_error(
"A subdevice name must be provided for multi-subdev daughterboards: " + subdev_spec.to_string()
);
pair.sd_name = subdev_names.front();
@@ -186,7 +186,7 @@ static void verify_xx_subdev_spec(
uhd::assert_has(subdev_names, pair.sd_name, xx_type + " subdev name");
}
}catch(const std::exception &e){
- throw std::runtime_error(str(boost::format(
+ throw uhd::value_error(str(boost::format(
"Validate %s subdev spec failed: %s\n %s"
) % xx_type % subdev_spec.to_string() % e.what()));
}
@@ -196,11 +196,11 @@ static void verify_xx_subdev_spec(
wax::obj dboard = mboard[named_prop_t(dboard_prop, db_name)];
BOOST_FOREACH(const std::string &sd_name, dboard[DBOARD_PROP_SUBDEV_NAMES].as<prop_names_t>()){
try{
- bool enable = std::has(subdev_spec, subdev_spec_pair_t(db_name, sd_name));
+ bool enable = uhd::has(subdev_spec, subdev_spec_pair_t(db_name, sd_name));
dboard[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)][SUBDEV_PROP_ENABLED] = enable;
}
catch(const std::exception &e){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"Cannot set enabled property on subdevice %s:%s\n %s"
) % db_name % sd_name % e.what()));
}
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 73bac029d..83cbf339b 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -15,10 +15,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include "wrapper_utils.hpp"
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/usrp/tune_helper.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/warning.hpp>
#include <uhd/utils/gain_group.hpp>
#include <uhd/usrp/subdev_props.hpp>
@@ -29,8 +29,8 @@
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
-#include <stdexcept>
#include <iostream>
+#include <cmath>
using namespace uhd;
using namespace uhd::usrp;
@@ -38,7 +38,48 @@ using namespace uhd::usrp;
const std::string multi_usrp::ALL_GAINS = "";
/***********************************************************************
- * Simple USRP Implementation
+ * Helper methods
+ **********************************************************************/
+static inline uhd::freq_range_t add_dsp_shift(
+ const uhd::freq_range_t &range,
+ wax::obj dsp
+){
+ double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as<double>();
+ return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0);
+}
+
+static inline void do_samp_rate_warning_message(
+ double target_rate,
+ double actual_rate,
+ const std::string &xx
+){
+ static const double max_allowed_error = 1.0; //Sps
+ if (std::abs(target_rate - actual_rate) > max_allowed_error){
+ uhd::warning::post(str(boost::format(
+ "The hardware does not support the requested %s sample rate:\n"
+ "Target sample rate: %f MSps\n"
+ "Actual sample rate: %f MSps\n"
+ ) % xx % (target_rate/1e6) % (actual_rate/1e6)));
+ }
+}
+
+static inline void do_tune_freq_warning_message(
+ double target_freq,
+ double actual_freq,
+ const std::string &xx
+){
+ static const double max_allowed_error = 1.0; //Hz
+ if (std::abs(target_freq - actual_freq) > max_allowed_error){
+ uhd::warning::post(str(boost::format(
+ "The hardware does not support the requested %s frequency:\n"
+ "Target frequency: %f MHz\n"
+ "Actual frequency: %f MHz\n"
+ ) % xx % (target_freq/1e6) % (actual_freq/1e6)));
+ }
+}
+
+/***********************************************************************
+ * Multi USRP Implementation
**********************************************************************/
class multi_usrp_impl : public multi_usrp{
public:
@@ -85,17 +126,14 @@ public:
//----------- rx side of life ----------------------------------
for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){
- buff += str(boost::format(
- " RX DSP %d: %s\n"
- ) % m
- % _rx_dsp(m)[DSP_PROP_NAME].as<std::string>()
- );
for (; chan < (m + 1)*get_rx_subdev_spec(m).size(); chan++){
buff += str(boost::format(
" RX Channel: %u\n"
+ " RX DSP: %s\n"
" RX Dboard: %s\n"
" RX Subdev: %s\n"
) % chan
+ % _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>()
);
@@ -104,17 +142,14 @@ public:
//----------- tx side of life ----------------------------------
for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){
- buff += str(boost::format(
- " TX DSP %d: %s\n"
- ) % m
- % _tx_dsp(m)[DSP_PROP_NAME].as<std::string>()
- );
for (; chan < (m + 1)*get_tx_subdev_spec(m).size(); chan++){
buff += str(boost::format(
" TX Channel: %u\n"
+ " TX DSP: %s\n"
" TX Dboard: %s\n"
" TX Subdev: %s\n"
) % chan
+ % _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>()
);
@@ -159,7 +194,7 @@ public:
while(true){
if (get_time_last_pps() != time_start_last_pps) break;
if ((get_time_now() - time_start) > time_spec_t(1.1)){
- throw std::runtime_error(
+ throw uhd::runtime_error(
"Board 0 may not be getting a PPS signal!\n"
"No PPS detected within the time interval.\n"
"See the application notes for your device.\n"
@@ -194,9 +229,13 @@ public:
return true;
}
- void issue_stream_cmd(const stream_cmd_t &stream_cmd){
- for (size_t m = 0; m < get_num_mboards(); m++){
- _mboard(m)[MBOARD_PROP_STREAM_CMD] = stream_cmd;
+ void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan){
+ if (chan != ALL_CHANS){
+ _rx_dsp(chan)[DSP_PROP_STREAM_CMD] = stream_cmd;
+ return;
+ }
+ for (size_t c = 0; c < get_rx_num_channels(); c++){
+ issue_stream_cmd(stream_cmd, c);
}
}
@@ -221,6 +260,10 @@ public:
std::vector<std::string> get_mboard_sensor_names(size_t mboard){
return _mboard(mboard)[MBOARD_PROP_SENSOR_NAMES].as<prop_names_t>();
}
+
+ mboard_iface::sptr get_mboard_iface(size_t mboard){
+ return _mboard(mboard)[MBOARD_PROP_IFACE].as<mboard_iface::sptr>();
+ }
/*******************************************************************
* RX methods
@@ -240,36 +283,44 @@ public:
}
size_t get_rx_num_channels(void){
- return rx_cpm()*get_num_mboards(); //total num channels
+ size_t sum = 0;
+ for (size_t m = 0; m < get_num_mboards(); m++){
+ sum += get_rx_subdev_spec(m).size();
+ }
+ return sum;
}
std::string get_rx_subdev_name(size_t chan){
return _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>();
}
- void set_rx_rate(double rate){
- for (size_t m = 0; m < get_num_mboards(); m++){
- _rx_dsp(m)[DSP_PROP_HOST_RATE] = rate;
+ void set_rx_rate(double rate, size_t chan){
+ if (chan != ALL_CHANS){
+ _rx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ do_samp_rate_warning_message(rate, get_rx_rate(chan), "RX");
+ return;
+ }
+ for (size_t c = 0; c < get_rx_num_channels(); c++){
+ set_rx_rate(rate, c);
}
- do_samp_rate_warning_message(rate, get_rx_rate(), "RX");
}
- double get_rx_rate(void){
- return _rx_dsp(0)[DSP_PROP_HOST_RATE].as<double>();
+ double get_rx_rate(size_t chan){
+ return _rx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){
- tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan/rx_cpm()), chan%rx_cpm(), tune_request);
+ tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), tune_request);
do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX");
return r;
}
double get_rx_freq(size_t chan){
- return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan/rx_cpm()), chan%rx_cpm());
+ 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_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan/rx_cpm()));
+ return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan));
}
void set_rx_gain(double gain, const std::string &name, size_t chan){
@@ -342,32 +393,40 @@ public:
}
size_t get_tx_num_channels(void){
- return tx_cpm()*get_num_mboards(); //total num channels
+ size_t sum = 0;
+ for (size_t m = 0; m < get_num_mboards(); m++){
+ sum += get_tx_subdev_spec(m).size();
+ }
+ return sum;
}
- void set_tx_rate(double rate){
- for (size_t m = 0; m < get_num_mboards(); m++){
- _tx_dsp(m)[DSP_PROP_HOST_RATE] = rate;
+ void set_tx_rate(double rate, size_t chan){
+ if (chan != ALL_CHANS){
+ _tx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ do_samp_rate_warning_message(rate, get_tx_rate(chan), "TX");
+ return;
+ }
+ for (size_t c = 0; c < get_tx_num_channels(); c++){
+ set_tx_rate(rate, c);
}
- do_samp_rate_warning_message(rate, get_tx_rate(), "TX");
}
- double get_tx_rate(void){
- return _tx_dsp(0)[DSP_PROP_HOST_RATE].as<double>();
+ double get_tx_rate(size_t chan){
+ return _tx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){
- tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan/tx_cpm()), chan%tx_cpm(), tune_request);
+ tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), tune_request);
do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX");
return r;
}
double get_tx_freq(size_t chan){
- return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan/tx_cpm()), chan%tx_cpm());
+ 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_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan/tx_cpm()));
+ return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan));
}
void set_tx_gain(double gain, const std::string &name, size_t chan){
@@ -421,58 +480,75 @@ public:
private:
device::sptr _dev;
- size_t rx_cpm(void){ //channels per mboard
- size_t nchan = get_rx_subdev_spec(0).size();
- for (size_t m = 1; m < get_num_mboards(); m++){
- if (nchan != get_rx_subdev_spec(m).size()){
- throw std::runtime_error("rx subdev spec size inconsistent across all mboards");
- }
+ struct mboard_chan_pair{
+ size_t mboard, chan;
+ mboard_chan_pair(void): mboard(0), chan(0){}
+ };
+
+ mboard_chan_pair rx_chan_to_mcp(size_t chan){
+ mboard_chan_pair mcp;
+ mcp.chan = chan;
+ for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){
+ size_t sss = get_rx_subdev_spec(mcp.mboard).size();
+ if (mcp.chan < sss) break;
+ mcp.chan -= sss;
}
- return nchan;
+ return mcp;
}
- size_t tx_cpm(void){ //channels per mboard
- size_t nchan = get_tx_subdev_spec(0).size();
- for (size_t m = 1; m < get_num_mboards(); m++){
- if (nchan != get_tx_subdev_spec(m).size()){
- throw std::runtime_error("tx subdev spec size inconsistent across all mboards");
- }
+ mboard_chan_pair tx_chan_to_mcp(size_t chan){
+ mboard_chan_pair mcp;
+ mcp.chan = chan;
+ for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){
+ size_t sss = get_tx_subdev_spec(mcp.mboard).size();
+ if (mcp.chan < sss) break;
+ mcp.chan -= sss;
}
- return nchan;
+ return mcp;
}
wax::obj _mboard(size_t mboard){
std::string mb_name = (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>().at(mboard);
return (*_dev)[named_prop_t(DEVICE_PROP_MBOARD, mb_name)];
}
- wax::obj _rx_dsp(size_t mboard){
- return _mboard(mboard)[MBOARD_PROP_RX_DSP];
+ wax::obj _rx_dsp(size_t chan){
+ mboard_chan_pair mcp = rx_chan_to_mcp(chan);
+ prop_names_t dsp_names = _mboard(mcp.mboard)[MBOARD_PROP_RX_DSP_NAMES].as<prop_names_t>();
+ return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_RX_DSP, dsp_names.at(mcp.chan))];
}
- wax::obj _tx_dsp(size_t mboard){
- return _mboard(mboard)[MBOARD_PROP_TX_DSP];
+ wax::obj _tx_dsp(size_t chan){
+ mboard_chan_pair mcp = tx_chan_to_mcp(chan);
+ prop_names_t dsp_names = _mboard(mcp.mboard)[MBOARD_PROP_TX_DSP_NAMES].as<prop_names_t>();
+ return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_TX_DSP, dsp_names.at(mcp.chan))];
}
wax::obj _rx_dboard(size_t chan){
- std::string db_name = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).db_name;
- return _mboard(chan/rx_cpm())[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
+ mboard_chan_pair mcp = rx_chan_to_mcp(chan);
+ std::string db_name = get_rx_subdev_spec(mcp.mboard).at(mcp.chan).db_name;
+ return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
}
wax::obj _tx_dboard(size_t chan){
- std::string db_name = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).db_name;
- return _mboard(chan/tx_cpm())[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
+ mboard_chan_pair mcp = tx_chan_to_mcp(chan);
+ std::string db_name = get_tx_subdev_spec(mcp.mboard).at(mcp.chan).db_name;
+ return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
}
wax::obj _rx_subdev(size_t chan){
- std::string sd_name = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).sd_name;
+ mboard_chan_pair mcp = rx_chan_to_mcp(chan);
+ std::string sd_name = get_rx_subdev_spec(mcp.mboard).at(mcp.chan).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 = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).sd_name;
+ mboard_chan_pair mcp = tx_chan_to_mcp(chan);
+ std::string sd_name = get_tx_subdev_spec(mcp.mboard).at(mcp.chan).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 = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).sd_name;
+ mboard_chan_pair mcp = rx_chan_to_mcp(chan);
+ std::string sd_name = get_rx_subdev_spec(mcp.mboard).at(mcp.chan).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 = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).sd_name;
+ mboard_chan_pair mcp = tx_chan_to_mcp(chan);
+ std::string sd_name = get_tx_subdev_spec(mcp.mboard).at(mcp.chan).sd_name;
return _tx_dboard(chan)[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
index d5d950f1f..6912afec8 100644
--- a/host/lib/usrp/subdev_spec.cpp
+++ b/host/lib/usrp/subdev_spec.cpp
@@ -16,11 +16,11 @@
//
#include <uhd/usrp/subdev_spec.hpp>
+#include <uhd/exception.hpp>
#include <boost/algorithm/string.hpp> //for split
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
-#include <stdexcept>
#include <sstream>
#include <vector>
@@ -51,7 +51,7 @@ subdev_spec_t::subdev_spec_t(const std::string &markup){
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);
+ default: throw uhd::value_error("invalid subdev-spec markup string: "+markup);
}
}
}
diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp
index eccee7f4b..ced80c187 100644
--- a/host/lib/usrp/tune_helper.cpp
+++ b/host/lib/usrp/tune_helper.cpp
@@ -30,12 +30,11 @@ using namespace uhd::usrp;
**********************************************************************/
static tune_result_t tune_xx_subdev_and_dsp(
dboard_iface::unit_t unit,
- wax::obj subdev, wax::obj dsp, size_t chan,
+ wax::obj subdev, wax::obj dsp,
const tune_request_t &tune_request
){
wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ];
- std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as<prop_names_t>().at(chan);
- wax::obj dsp_freq_proxy = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)];
+ wax::obj dsp_freq_proxy = dsp[DSP_PROP_FREQ_SHIFT];
//------------------------------------------------------------------
//-- calculate the LO offset, only used with automatic policy
@@ -105,13 +104,11 @@ static tune_result_t tune_xx_subdev_and_dsp(
}
static double derive_freq_from_xx_subdev_and_dsp(
- dboard_iface::unit_t unit,
- wax::obj subdev, wax::obj dsp, size_t chan
+ dboard_iface::unit_t unit, wax::obj subdev, wax::obj dsp
){
//extract actual dsp and IF frequencies
double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as<double>();
- std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as<prop_names_t>().at(chan);
- double actual_dsp_freq = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)].as<double>();
+ double actual_dsp_freq = dsp[DSP_PROP_FREQ_SHIFT].as<double>();
//invert the sign on the dsp freq given the following conditions
if (unit == dboard_iface::UNIT_TX) actual_dsp_freq *= -1.0;
@@ -123,30 +120,28 @@ static double derive_freq_from_xx_subdev_and_dsp(
* RX Tune
**********************************************************************/
tune_result_t usrp::tune_rx_subdev_and_dsp(
- wax::obj subdev, wax::obj ddc, size_t chan,
- const tune_request_t &tune_request
+ wax::obj subdev, wax::obj ddc, const tune_request_t &tune_request
){
- return tune_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan, tune_request);
+ return tune_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, tune_request);
}
double usrp::derive_freq_from_rx_subdev_and_dsp(
- wax::obj subdev, wax::obj ddc, size_t chan
+ wax::obj subdev, wax::obj ddc
){
- return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan);
+ return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc);
}
/***********************************************************************
* TX Tune
**********************************************************************/
tune_result_t usrp::tune_tx_subdev_and_dsp(
- wax::obj subdev, wax::obj duc, size_t chan,
- const tune_request_t &tune_request
+ wax::obj subdev, wax::obj duc, const tune_request_t &tune_request
){
- return tune_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan, tune_request);
+ return tune_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, tune_request);
}
double usrp::derive_freq_from_tx_subdev_and_dsp(
- wax::obj subdev, wax::obj duc, size_t chan
+ wax::obj subdev, wax::obj duc
){
- return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan);
+ return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc);
}
diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp
index 156f2b0c4..df5353b54 100644
--- a/host/lib/usrp/usrp1/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp1/clock_ctrl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,13 +16,6 @@
//
#include "clock_ctrl.hpp"
-#include "fpga_regs_standard.h"
-#include <uhd/utils/assert.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/foreach.hpp>
-#include <utility>
-#include <iostream>
using namespace uhd;
diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp
index f3816b377..1b4411002 100644
--- a/host/lib/usrp/usrp1/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp1/codec_ctrl.cpp
@@ -20,7 +20,7 @@
#include "clock_ctrl.hpp"
#include "ad9862_regs.hpp"
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/byteswap.hpp>
#include <boost/cstdint.hpp>
@@ -162,7 +162,7 @@ static const int mtpgw = 255; //maximum tx pga gain word
void usrp1_codec_ctrl_impl::set_tx_pga_gain(double gain){
int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start()));
- _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw);
+ _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw);
this->send_reg(16);
}
@@ -174,7 +174,7 @@ static const int mrpgw = 0x14; //maximum rx pga gain word
void usrp1_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){
int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start()));
- gain_word = std::clip(gain_word, 0, mrpgw);
+ gain_word = uhd::clip(gain_word, 0, mrpgw);
switch(which){
case 'A':
_ad9862_regs.rx_pga_a = gain_word;
@@ -264,7 +264,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts)
{
//special case for aux dac d (aka sigma delta word)
if (which == AUX_DAC_D) {
- boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);
+ boost::uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);
_ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4);
_ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf);
this->send_reg(42);
@@ -273,7 +273,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts)
}
//calculate the dac word for aux dac a, b, c
- boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);
+ boost::uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);
//setup a lookup table for the aux dac params (reg ref, reg addr)
typedef boost::tuple<boost::uint8_t*, boost::uint8_t> dac_params_t;
@@ -303,8 +303,8 @@ void usrp1_codec_ctrl_impl::send_reg(boost::uint8_t addr)
std::cout << "codec control write reg: 0x";
std::cout << std::setw(8) << std::hex << reg << std::endl;
}
- _iface->transact_spi(_spi_slave,
- spi_config_t::EDGE_RISE, reg, 16, false);
+ _iface->write_spi(_spi_slave,
+ spi_config_t::EDGE_RISE, reg, 16);
}
void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr)
@@ -317,8 +317,8 @@ void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr)
std::cout << std::setw(8) << std::hex << reg << std::endl;
}
- boost::uint32_t ret = _iface->transact_spi(_spi_slave,
- spi_config_t::EDGE_RISE, reg, 16, true);
+ boost::uint32_t ret = _iface->read_spi(_spi_slave,
+ spi_config_t::EDGE_RISE, reg, 16);
if (codec_debug) {
std::cout.fill('0');
diff --git a/host/lib/usrp/usrp1/codec_impl.cpp b/host/lib/usrp/usrp1/codec_impl.cpp
index 14ecd2d2e..7e4032131 100644
--- a/host/lib/usrp/usrp1/codec_impl.cpp
+++ b/host/lib/usrp/usrp1/codec_impl.cpp
@@ -16,7 +16,7 @@
//
#include "usrp1_impl.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/codec_props.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index eec4a52db..3f3a98b7a 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -24,7 +24,7 @@
#include "codec_ctrl.hpp"
#include <uhd/usrp/dboard_iface.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <boost/assign/list_of.hpp>
#include <iostream>
@@ -329,7 +329,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit,
else
break;
}
- throw std::invalid_argument("unknown unit type");
+ UHD_THROW_INVALID_CODE_PATH();
}
void usrp1_dboard_iface::write_spi(unit_t unit,
@@ -337,8 +337,8 @@ void usrp1_dboard_iface::write_spi(unit_t unit,
boost::uint32_t data,
size_t num_bits)
{
- _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot),
- config, data, num_bits, false);
+ _iface->write_spi(unit_to_otw_spi_dev(unit, _dboard_slot),
+ config, data, num_bits);
}
boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit,
@@ -346,8 +346,8 @@ boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit,
boost::uint32_t data,
size_t num_bits)
{
- return _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot),
- config, data, num_bits, true);
+ return _iface->read_spi(unit_to_otw_spi_dev(unit, _dboard_slot),
+ config, data, num_bits);
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp1/dboard_impl.cpp b/host/lib/usrp/usrp1/dboard_impl.cpp
index 2130960fb..02906fc45 100644
--- a/host/lib/usrp/usrp1/dboard_impl.cpp
+++ b/host/lib/usrp/usrp1/dboard_impl.cpp
@@ -19,7 +19,7 @@
#include "usrp_i2c_addr.h"
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/usrp/misc_utils.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/dboard_props.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <boost/bind.hpp>
diff --git a/host/lib/usrp/usrp1/dsp_impl.cpp b/host/lib/usrp/usrp1/dsp_impl.cpp
index 370f4831f..8152c4e34 100644
--- a/host/lib/usrp/usrp1/dsp_impl.cpp
+++ b/host/lib/usrp/usrp1/dsp_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -34,23 +34,25 @@ using namespace uhd::usrp;
**********************************************************************/
void usrp1_impl::rx_dsp_init(void)
{
- _rx_dsp_proxy = wax_obj_proxy::make(
- boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2),
- boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2));
-
- rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16);
+ for (size_t i = 0; i < this->get_num_ddcs(); i++){
+ _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
+ boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2, i),
+ boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2, i)
+ );
+ rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i);
+ }
}
/***********************************************************************
* RX DDC Get
**********************************************************************/
-void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){
+void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()){
case DSP_PROP_NAME:
- val = str(boost::format("usrp1 ddc %uX %s")
- % this->get_num_ddcs()
+ val = str(boost::format("usrp1 ddc%d %s")
+ % which_dsp
% (this->has_rx_halfband()? "+ hb" : "")
);
return;
@@ -60,16 +62,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_FREQ_SHIFT:
- val = _rx_dsp_freqs[key.name];
- return;
-
- case DSP_PROP_FREQ_SHIFT_NAMES:{
- prop_names_t names;
- for(size_t i = 0; i < this->get_num_ddcs(); i++){
- names.push_back(boost::lexical_cast<std::string>(i));
- }
- val = names;
- }
+ val = _rx_dsp_freqs[which_dsp];
return;
case DSP_PROP_CODEC_RATE:
@@ -88,7 +81,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){
/***********************************************************************
* RX DDC Set
**********************************************************************/
-void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){
+void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()) {
@@ -97,16 +90,17 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){
boost::uint32_t reg_word = dsp_type1::calc_cordic_word_and_update(
new_freq, _clock_ctrl->get_master_clock_freq());
- static const uhd::dict<std::string, boost::uint32_t>
- freq_name_to_reg_val = boost::assign::map_list_of
- ("0", FR_RX_FREQ_0) ("1", FR_RX_FREQ_1)
- ("2", FR_RX_FREQ_2) ("3", FR_RX_FREQ_3)
- ;
- _iface->poke32(freq_name_to_reg_val[key.name], ~reg_word + 1);
- _rx_dsp_freqs[key.name] = new_freq;
+ static const boost::uint32_t dsp_index_to_reg_val[4] = {
+ FR_RX_FREQ_0, FR_RX_FREQ_1, FR_RX_FREQ_2, FR_RX_FREQ_3
+ };
+ _iface->poke32(dsp_index_to_reg_val[which_dsp], ~reg_word + 1);
+ _rx_dsp_freqs[which_dsp] = new_freq;
return;
}
- case DSP_PROP_HOST_RATE: {
+
+ case DSP_PROP_HOST_RATE:
+ if (which_dsp != 0) return; //only for dsp[0] as this is vectorized
+ {
size_t rate = size_t(_clock_ctrl->get_master_clock_freq() / val.as<double>());
if ((rate & 0x01) || (rate < 4) || (rate > 256)) {
@@ -123,6 +117,11 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){
}
return;
+ case DSP_PROP_STREAM_CMD:
+ if (which_dsp != 0) return; //only for dsp[0] as this is vectorized
+ _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>());
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
@@ -133,24 +132,25 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){
**********************************************************************/
void usrp1_impl::tx_dsp_init(void)
{
- _tx_dsp_proxy = wax_obj_proxy::make(
- boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2),
- boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2));
-
- //initial config and update
- tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() * 2 / 16);
+ for (size_t i = 0; i < this->get_num_ducs(); i++){
+ _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
+ boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2, i),
+ boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2, i)
+ );
+ tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i);
+ }
}
/***********************************************************************
* TX DUC Get
**********************************************************************/
-void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){
+void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()) {
case DSP_PROP_NAME:
- val = str(boost::format("usrp1 duc %uX %s")
- % this->get_num_ducs()
+ val = str(boost::format("usrp1 duc%d %s")
+ % which_dsp
% (this->has_tx_halfband()? "+ hb" : "")
);
return;
@@ -160,16 +160,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_FREQ_SHIFT:
- val = _tx_dsp_freqs[key.name];
- return;
-
- case DSP_PROP_FREQ_SHIFT_NAMES:{
- prop_names_t names;
- for(size_t i = 0; i < this->get_num_ducs(); i++){
- names.push_back(boost::lexical_cast<std::string>(i));
- }
- val = names;
- }
+ val = _tx_dsp_freqs[which_dsp];
return;
case DSP_PROP_CODEC_RATE:
@@ -188,7 +179,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){
/***********************************************************************
* TX DUC Set
**********************************************************************/
-void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){
+void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()) {
@@ -197,15 +188,17 @@ void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){
double new_freq = val.as<double>();
//map the freq shift key to a subdev spec to a particular codec chip
- std::string db_name = _tx_subdev_spec.at(boost::lexical_cast<size_t>(key.name)).db_name;
+ std::string db_name = _tx_subdev_spec.at(which_dsp).db_name;
if (db_name == "A") _codec_ctrls[DBOARD_SLOT_A]->set_duc_freq(new_freq);
if (db_name == "B") _codec_ctrls[DBOARD_SLOT_B]->set_duc_freq(new_freq);
- _tx_dsp_freqs[key.name] = new_freq;
+ _tx_dsp_freqs[which_dsp] = new_freq;
return;
}
- case DSP_PROP_HOST_RATE: {
+ case DSP_PROP_HOST_RATE:
+ if (which_dsp != 0) return; //only for dsp[0] as this is vectorized
+ {
size_t rate = size_t(_clock_ctrl->get_master_clock_freq() * 2 / val.as<double>());
if ((rate & 0x01) || (rate < 8) || (rate > 512)) {
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index 8beeccf8f..b3268298e 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -18,6 +18,7 @@
#include "../../transport/vrt_packet_handler.hpp"
#include "usrp_commands.h"
#include "usrp1_impl.hpp"
+#include <uhd/utils/safe_call.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/bind.hpp>
@@ -114,7 +115,7 @@ struct usrp1_impl::io_impl{
}
~io_impl(void){
- flush_send_buff();
+ UHD_SAFE_CALL(flush_send_buff();)
}
zero_copy_if::sptr data_transport;
diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp
index 6d5bf466d..4e2fad6e5 100644
--- a/host/lib/usrp/usrp1/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1/mboard_impl.cpp
@@ -25,7 +25,7 @@
#include <uhd/usrp/dboard_props.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/utils/warning.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/images.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
@@ -161,7 +161,7 @@ static boost::uint32_t calc_tx_mux(
//sanity check, only 1 channel per slot
slot_to_chan_count[pair.db_name]++;
if (slot_to_chan_count[pair.db_name] > 1){
- throw std::runtime_error(str(boost::format(
+ throw uhd::value_error(str(boost::format(
"dboard slot %s assigned to multiple channels in subdev spec %s"
) % pair.db_name % subdev_spec.to_string()));
}
@@ -280,21 +280,19 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)
return;
case MBOARD_PROP_RX_DSP:
- UHD_ASSERT_THROW(key.name == "");
- val = _rx_dsp_proxy->get_link();
+ val = _rx_dsp_proxies.get(key.name)->get_link();
return;
case MBOARD_PROP_RX_DSP_NAMES:
- val = prop_names_t(1, "");
+ val = _rx_dsp_proxies.keys();
return;
case MBOARD_PROP_TX_DSP:
- UHD_ASSERT_THROW(key.name == "");
- val = _tx_dsp_proxy->get_link();
+ val = _tx_dsp_proxies.get(key.name)->get_link();
return;
case MBOARD_PROP_TX_DSP_NAMES:
- val = prop_names_t(1, "");
+ val = _tx_dsp_proxies.keys();
return;
case MBOARD_PROP_CLOCK_CONFIG:
@@ -342,14 +340,10 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
- case MBOARD_PROP_STREAM_CMD:
- _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>());
- return;
-
case MBOARD_PROP_RX_SUBDEV_SPEC:
_rx_subdev_spec = val.as<subdev_spec_t>();
if (_rx_subdev_spec.size() > this->get_num_ddcs()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::value_error(str(boost::format(
"USRP1 suports up to %u RX channels.\n"
"However, this RX subdev spec requires %u channels\n"
) % this->get_num_ddcs() % _rx_subdev_spec.size()));
@@ -362,7 +356,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
case MBOARD_PROP_TX_SUBDEV_SPEC:
_tx_subdev_spec = val.as<subdev_spec_t>();
if (_tx_subdev_spec.size() > this->get_num_ducs()){
- throw std::runtime_error(str(boost::format(
+ throw uhd::value_error(str(boost::format(
"USRP1 suports up to %u TX channels.\n"
"However, this TX subdev spec requires %u channels\n"
) % this->get_num_ducs() % _tx_subdev_spec.size()));
diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
index 09f854813..3fa6cb8b7 100644
--- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
@@ -16,7 +16,8 @@
//
#include "usrp1_ctrl.hpp"
-#include "usrp_commands.h"
+#include "usrp_commands.h"
+#include <uhd/exception.hpp>
#include <uhd/transport/usb_control.hpp>
#include <boost/functional/hash.hpp>
#include <boost/thread/thread.hpp>
@@ -29,13 +30,6 @@
using namespace uhd;
-enum firmware_code {
- USRP_FPGA_LOAD_SUCCESS,
- USRP_FPGA_ALREADY_LOADED,
- USRP_FIRMWARE_LOAD_SUCCESS,
- USRP_FIRMWARE_ALREADY_LOADED
-};
-
#define FX2_FIRMWARE_LOAD 0xa0
static const bool load_img_msg = true;
@@ -45,15 +39,16 @@ static const bool load_img_msg = true;
**********************************************************************/
/*!
* Create a file hash
- * The hash will be used to identify the loaded firmware and fpga image
+ * The hash will be used to identify the loaded firmware and fpga image
* \param filename file used to generate hash value
* \return hash value in a size_t type
*/
static size_t generate_hash(const char *filename)
{
std::ifstream file(filename);
- if (!file)
- std::cerr << "error: cannot open input file " << filename << std::endl;
+ if (not file){
+ throw uhd::io_error(std::string("cannot open input file ") + filename);
+ }
size_t hash = 0;
@@ -62,18 +57,19 @@ static size_t generate_hash(const char *filename)
boost::hash_combine(hash, ch);
}
- if (!file.eof())
- std::cerr << "error: file error " << filename << std::endl;
+ if (not file.eof()){
+ throw uhd::io_error(std::string("file error ") + filename);
+ }
- file.close();
- return hash;
+ file.close();
+ return hash;
}
/*!
- * Verify checksum of a Intel HEX record
+ * Verify checksum of a Intel HEX record
* \param record a line from an Intel HEX file
- * \return true if record is valid, false otherwise
+ * \return true if record is valid, false otherwise
*/
static bool checksum(std::string *record)
{
@@ -123,7 +119,7 @@ bool parse_record(std::string *record, unsigned int &len,
for (i = 0; i < len; i++) {
std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val;
data[i] = (unsigned char) val;
- }
+ }
return true;
}
@@ -139,20 +135,15 @@ public:
_ctrl_transport = ctrl_transport;
}
- int usrp_load_firmware(std::string filestring, bool force)
+ void usrp_load_firmware(std::string filestring, bool force)
{
const char *filename = filestring.c_str();
size_t hash = generate_hash(filename);
- size_t loaded_hash;
- if (usrp_get_firmware_hash(loaded_hash) < 0) {
- std::cerr << "firmware hash retrieval failed" << std::endl;
- return -1;
- }
+ size_t loaded_hash; usrp_get_firmware_hash(loaded_hash);
- if (!force && (hash == loaded_hash))
- return USRP_FIRMWARE_ALREADY_LOADED;
+ if (not force and (hash == loaded_hash)) return;
//FIXME: verify types
unsigned int len;
@@ -160,13 +151,11 @@ public:
unsigned int type;
unsigned char data[512];
- int ret;
std::ifstream file;
file.open(filename, std::ifstream::in);
if (!file.good()) {
- std::cerr << "cannot open firmware input file" << std::endl;
- return -1;
+ throw uhd::io_error("usrp_load_firmware: cannot open firmware input file");
}
unsigned char reset_y = 1;
@@ -174,56 +163,41 @@ public:
//hit the reset line
if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush;
- usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
- &reset_y, 1);
-
+ usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1);
+
while (!file.eof()) {
std::string record;
file >> record;
-
- //check for valid record
- if (!checksum(&record) ||
- !parse_record(&record, len, addr, type, data)) {
- std::cerr << "error: bad record" << std::endl;
- file.close();
- return -1;
+
+ //check for valid record
+ if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) {
+ throw uhd::io_error("usrp_load_firmware: bad record checksum");
}
//type 0x00 is data
if (type == 0x00) {
- ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0,
- data, len);
- if (ret < 0) {
- std::cerr << "error: usrp_control_write failed: ";
- std::cerr << ret << std::endl;
- file.close();
- return -1;
- }
- }
- //type 0x01 is end
+ int ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, data, len);
+ if (ret < 0) throw uhd::io_error("usrp_load_firmware: usrp_control_write failed");
+ }
+ //type 0x01 is end
else if (type == 0x01) {
usrp_set_firmware_hash(hash); //set hash before reset
- usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
- &reset_n, 1);
+ usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1);
file.close();
//wait for things to settle
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
if (load_img_msg) std::cout << " done" << std::endl;
- return USRP_FIRMWARE_LOAD_SUCCESS;
+ return;
}
//type anything else is unhandled
else {
- std::cerr << "error: unsupported record" << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_firmware: unsupported record");
}
}
- //file did not end
- std::cerr << "error: bad record" << std::endl;
- file.close();
- return -1;
+ //file did not end
+ throw uhd::io_error("usrp_load_firmware: bad record");
}
void usrp_init(void){
@@ -241,64 +215,48 @@ public:
usrp_tx_enable(true);
}
- int usrp_load_fpga(std::string filestring)
+ void usrp_load_fpga(std::string filestring)
{
const char *filename = filestring.c_str();
size_t hash = generate_hash(filename);
- size_t loaded_hash;
- if (usrp_get_fpga_hash(loaded_hash) < 0) {
- std::cerr << "fpga hash retrieval failed" << std::endl;
- return -1;
- }
+ size_t loaded_hash; usrp_get_fpga_hash(loaded_hash);
- if (hash == loaded_hash)
- return USRP_FPGA_ALREADY_LOADED;
+ if (hash == loaded_hash) return;
const int ep0_size = 64;
unsigned char buf[ep0_size];
- int ret;
if (load_img_msg) std::cout << "Loading FPGA image: " << filestring << "..." << std::flush;
std::ifstream file;
file.open(filename, std::ios::in | std::ios::binary);
if (not file.good()) {
- std::cerr << "cannot open fpga input file" << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_fpga: cannot open fpga input file");
}
if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) {
- std::cerr << "fpga load error" << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_fpga: fpga load error");
}
while (not file.eof()) {
file.read((char *)buf, sizeof(buf));
size_t n = file.gcount();
- ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER,
- buf, n);
+ int ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, buf, n);
if (ret < 0 or size_t(ret) != n) {
- std::cerr << "fpga load error " << ret << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_fpga: fpga load error");
}
}
-
+
if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_END) < 0) {
- std::cerr << "fpga load error" << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_fpga: fpga load error");
}
usrp_set_fpga_hash(hash);
file.close();
if (load_img_msg) std::cout << " done" << std::endl;
- return 0;
}
- int usrp_load_eeprom(std::string filestring)
+ void usrp_load_eeprom(std::string filestring)
{
const char *filename = filestring.c_str();
const boost::uint16_t i2c_addr = 0x50;
@@ -309,100 +267,92 @@ public:
unsigned char data[256];
unsigned char sendbuf[17];
- int ret;
std::ifstream file;
file.open(filename, std::ifstream::in);
- if (!file.good()) {
- std::cerr << "cannot open EEPROM input file" << std::endl;
- return -1;
+ if (not file.good()) {
+ throw uhd::io_error("usrp_load_eeprom: cannot open EEPROM input file");
}
file.read((char *)data, 256);
len = file.gcount();
if(len == 256) {
- std::cerr << "error: image size too large" << std::endl;
- file.close();
- return -1;
+ throw uhd::io_error("usrp_load_eeprom: image size too large");
}
const int pagesize = 16;
addr = 0;
while(len > 0) {
- sendbuf[0] = addr;
- memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len);
- ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1);
- if (ret < 0) {
- std::cerr << "error: usrp_i2c_write failed: ";
- std::cerr << ret << std::endl;
- file.close();
- return -1;
- }
- addr += pagesize;
- len -= pagesize;
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ sendbuf[0] = addr;
+ memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len);
+ int ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1);
+ if (ret < 0) {
+ throw uhd::io_error("usrp_load_eeprom: usrp_i2c_write failed");
+ }
+ addr += pagesize;
+ len -= pagesize;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
file.close();
- return 0;
}
- int usrp_set_led(int led_num, bool on)
+ void usrp_set_led(int led_num, bool on)
{
- return usrp_control_write_cmd(VRQ_SET_LED, on, led_num);
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_SET_LED, on, led_num) >= 0);
}
- int usrp_get_firmware_hash(size_t &hash)
+ void usrp_get_firmware_hash(size_t &hash)
{
- return usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0,
- (unsigned char*) &hash, sizeof(size_t));
+ UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0,
+ (unsigned char*) &hash, sizeof(size_t)) >= 0);
}
- int usrp_set_firmware_hash(size_t hash)
+ void usrp_set_firmware_hash(size_t hash)
{
- return usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0,
- (unsigned char*) &hash, sizeof(size_t));
+ UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0,
+ (unsigned char*) &hash, sizeof(size_t)) >= 0);
}
- int usrp_get_fpga_hash(size_t &hash)
+ void usrp_get_fpga_hash(size_t &hash)
{
- return usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0,
- (unsigned char*) &hash, sizeof(size_t));
+ UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0,
+ (unsigned char*) &hash, sizeof(size_t)) >= 0);
}
- int usrp_set_fpga_hash(size_t hash)
+ void usrp_set_fpga_hash(size_t hash)
{
- return usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0,
- (unsigned char*) &hash, sizeof(size_t));
+ UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0,
+ (unsigned char*) &hash, sizeof(size_t)) >= 0);
}
- int usrp_tx_enable(bool on)
+ void usrp_tx_enable(bool on)
{
- return usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0);
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0) >= 0);
}
- int usrp_rx_enable(bool on)
+ void usrp_rx_enable(bool on)
{
- return usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0);
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0) >= 0);
}
- int usrp_tx_reset(bool on)
+ void usrp_tx_reset(bool on)
{
- return usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0);
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0) >= 0);
}
- int usrp_rx_reset(bool on)
+ void usrp_rx_reset(bool on)
{
- return usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0);
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0) >= 0);
}
@@ -417,7 +367,7 @@ public:
value, // wValue
index, // wIndex
buff, // data
- length); // wLength
+ length); // wLength
}
diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.hpp b/host/lib/usrp/usrp1/usrp1_ctrl.hpp
index 8ccfacab7..ee68f8401 100644
--- a/host/lib/usrp/usrp1/usrp1_ctrl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_ctrl.hpp
@@ -40,60 +40,21 @@ public:
* Load firmware in Intel HEX Format onto device
* \param filename name of firmware file
* \param force reload firmware if already loaded
- * \return 0 on success, error code otherwise
*/
- virtual int usrp_load_firmware(std::string filename,
+ virtual void usrp_load_firmware(std::string filename,
bool force = false) = 0;
/*!
* Load fpga file onto usrp
* \param filename name of fpga image
- * \return 0 on success, error code otherwise
*/
- virtual int usrp_load_fpga(std::string filename) = 0;
+ virtual void usrp_load_fpga(std::string filename) = 0;
/*!
* Load USB descriptor file in Intel HEX format into EEPROM
- * \param filename name of EEPROM image
- * \return 0 on success, error code otherwise
+ * \param filename name of EEPROM image
*/
- virtual int usrp_load_eeprom(std::string filestring) = 0;
-
- /*!
- * Set led usrp
- * \param led_num which LED to control (0 or 1)
- * \param on turn LED on or off
- * \return 0 on success, error code otherwise
- */
- virtual int usrp_set_led(int led_num, bool on) = 0;
-
- /*!
- * Get firmware hash
- * \param hash a size_t hash value
- * \return 0 on success, error code otherwise
- */
- virtual int usrp_get_firmware_hash(size_t &hash) = 0;
-
- /*!
- * Set firmware hash
- * \param hash a size_t hash value
- * \return 0 on success, error code otherwise
- */
- virtual int usrp_set_firmware_hash(size_t hash) = 0;
-
- /*!
- * Get fpga hash
- * \param hash a size_t hash value
- * \return 0 on success, error code otherwise
- */
- virtual int usrp_get_fpga_hash(size_t &hash) = 0;
-
- /*!
- * Set fpga hash
- * \param hash a size_t hash value
- * \return 0 on success, error code otherwise
- */
- virtual int usrp_set_fpga_hash(size_t hash) = 0;
+ virtual void usrp_load_eeprom(std::string filestring) = 0;
/*!
* Submit an IN transfer
diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp
index 63fcd5777..0c37610ce 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.cpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.cpp
@@ -17,7 +17,7 @@
#include "usrp1_iface.hpp"
#include "usrp_commands.h"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/byteswap.hpp>
#include <boost/format.hpp>
#include <stdexcept>
@@ -70,8 +70,7 @@ public:
(unsigned char*) &swapped,
sizeof(boost::uint32_t));
- if (ret < 0)
- std::cerr << "USRP: failed memory write: " << ret << std::endl;
+ if (ret < 0) throw uhd::io_error("USRP1: failed control write");
}
boost::uint32_t peek32(boost::uint32_t addr)
@@ -88,11 +87,27 @@ public:
(unsigned char*) &value_out,
sizeof(boost::uint32_t));
- if (ret < 0)
- std::cerr << "USRP: failed memory read: " << ret << std::endl;
+ if (ret < 0) throw uhd::io_error("USRP1: failed control read");
return uhd::ntohx(value_out);
}
+
+ void poke16(boost::uint32_t, boost::uint16_t) {
+ throw uhd::not_implemented_error("Unhandled command poke16()");
+ }
+
+ boost::uint16_t peek16(boost::uint32_t) {
+ throw uhd::not_implemented_error("Unhandled command peek16()");
+ return 0;
+ }
+
+ void write_uart(boost::uint8_t, const std::string &) {
+ throw uhd::not_implemented_error("Unhandled command write_uart()");
+ }
+
+ std::string read_uart(boost::uint8_t) {
+ throw uhd::not_implemented_error("Unhandled command read_uart()");
+ }
/*******************************************************************
* I2C
@@ -176,10 +191,7 @@ public:
buff,
(w_len_h << 8) | (w_len_l << 0));
- if (ret < 0) {
- std::cout << "USRP: failed SPI readback transaction: "
- << std::dec << ret << std::endl;
- }
+ if (ret < 0) throw uhd::io_error("USRP1: failed SPI readback transaction");
boost::uint32_t val = (((boost::uint32_t)buff[0]) << 0) |
(((boost::uint32_t)buff[1]) << 8) |
@@ -197,10 +209,7 @@ public:
(w_index_h << 8) | (w_index_l << 0),
buff, num_bytes);
- if (ret < 0) {
- std::cout << "USRP: failed SPI transaction: "
- << std::dec << ret << std::endl;
- }
+ if (ret < 0) throw uhd::io_error("USRP1: failed SPI transaction");
return 0;
}
@@ -234,8 +243,7 @@ public:
length);
}
- if (ret < 0)
- std::cerr << "USRP: failed firmware command: " << ret << std::endl;
+ if (ret < 0) throw uhd::io_error("USRP1: failed firmware command");
}
private:
diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp
index 34a2330b5..fdb7464ce 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.hpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.hpp
@@ -18,8 +18,7 @@
#ifndef INCLUDED_USRP1_IFACE_HPP
#define INCLUDED_USRP1_IFACE_HPP
-#include <uhd/usrp/mboard_eeprom.hpp>
-#include <uhd/types/serial.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include "usrp1_ctrl.hpp"
@@ -29,10 +28,13 @@
* Provides a set of functions to implementation layer.
* Including spi, peek, poke, control...
*/
-class usrp1_iface : boost::noncopyable, public uhd::i2c_iface{
+class usrp1_iface : public uhd::usrp::mboard_iface, boost::noncopyable{
public:
typedef boost::shared_ptr<usrp1_iface> sptr;
+ //motherboard eeprom map structure
+ uhd::usrp::mboard_eeprom_t mb_eeprom;
+
/*!
* Make a new usrp1 interface with the control transport.
* \param ctrl_transport the usrp controller object
@@ -41,35 +43,6 @@ public:
static sptr make(usrp_ctrl::sptr ctrl_transport);
/*!
- * Write a register (32 bits)
- * \param addr the address
- * \param data the 32bit data
- */
- virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0;
-
- /*!
- * Read a register (32 bits)
- * \param addr the address
- * \return the 32bit data
- */
- virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
-
- /*!
- * Perform an spi transaction.
- * \param which_slave the slave device number
- * \param config spi config args
- * \param data the bits to write
- * \param num_bits how many bits in data
- * \param readback true to readback a value
- * \return spi data if readback set
- */
- virtual boost::uint32_t transact_spi(int which_slave,
- const uhd::spi_config_t &config,
- boost::uint32_t data,
- size_t num_bits,
- bool readback) = 0;
-
- /*!
* Perform a general USB firmware OUT operation
* \param request
* \param value
@@ -82,8 +55,6 @@ public:
boost::uint16_t index,
unsigned char* buff,
boost::uint16_t length) = 0;
-
- uhd::usrp::mboard_eeprom_t mb_eeprom;
};
#endif /* INCLUDED_USRP1_IFACE_HPP */
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 918032037..7005c59f2 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -19,11 +19,12 @@
#include "usrp1_ctrl.hpp"
#include "fpga_regs_standard.h"
#include "usrp_spi_defs.h"
+#include <uhd/utils/safe_call.hpp>
#include <uhd/transport/usb_control.hpp>
#include <uhd/usrp/device_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
#include <uhd/utils/warning.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/images.hpp>
#include <boost/format.hpp>
@@ -199,7 +200,16 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,
}
usrp1_impl::~usrp1_impl(void){
- /* NOP */
+ //Safely destruct all RAII objects in a device.
+ //This prevents the mboard deconstructor from throwing,
+ //which allows the device to be safely deconstructed.
+ BOOST_FOREACH(dboard_slot_t slot, _dboard_slots){
+ UHD_SAFE_CALL(_dboard_managers[slot].reset();)
+ UHD_SAFE_CALL(_dboard_ifaces[slot].reset();)
+ UHD_SAFE_CALL(_codec_ctrls[slot].reset();)
+ }
+ UHD_SAFE_CALL(_clock_ctrl.reset();)
+ UHD_SAFE_CALL(_io_impl.reset();)
}
bool usrp1_impl::recv_async_msg(uhd::async_metadata_t &, double timeout){
diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp
index 1d9f6709f..9755c466d 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.hpp
@@ -182,19 +182,19 @@ private:
//rx dsp functions and settings
void rx_dsp_init(void);
- void rx_dsp_get(const wax::obj &, wax::obj &);
- void rx_dsp_set(const wax::obj &, const wax::obj &);
- uhd::dict<std::string, double> _rx_dsp_freqs;
+ void rx_dsp_get(const wax::obj &, wax::obj &, size_t);
+ void rx_dsp_set(const wax::obj &, const wax::obj &, size_t);
+ uhd::dict<size_t, double> _rx_dsp_freqs;
size_t _rx_dsp_decim;
- wax_obj_proxy::sptr _rx_dsp_proxy;
+ uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsp_proxies;
//tx dsp functions and settings
void tx_dsp_init(void);
- void tx_dsp_get(const wax::obj &, wax::obj &);
- void tx_dsp_set(const wax::obj &, const wax::obj &);
- uhd::dict<std::string, double> _tx_dsp_freqs;
+ void tx_dsp_get(const wax::obj &, wax::obj &, size_t);
+ void tx_dsp_set(const wax::obj &, const wax::obj &, size_t);
+ uhd::dict<size_t, double> _tx_dsp_freqs;
size_t _tx_dsp_interp;
- wax_obj_proxy::sptr _tx_dsp_proxy;
+ uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsp_proxies;
//transports
uhd::transport::usb_zero_copy::sptr _data_transport;
diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp
index 27ccefb2b..abda53bf2 100644
--- a/host/lib/usrp/usrp2/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp2/clock_ctrl.cpp
@@ -19,7 +19,7 @@
#include "ad9510_regs.hpp"
#include "usrp2_regs.hpp" //spi slave constants
#include "usrp2_clk_regs.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <boost/cstdint.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/math/special_functions/round.hpp>
@@ -305,7 +305,7 @@ private:
*/
void write_reg(boost::uint8_t addr){
boost::uint32_t data = _ad9510_regs.get_write_reg(addr);
- _iface->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/);
+ _iface->write_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24);
}
/*!
diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp
index 890969b5a..0fdcedf62 100644
--- a/host/lib/usrp/usrp2/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp2/codec_ctrl.cpp
@@ -19,10 +19,10 @@
#include "ad9777_regs.hpp"
#include "ads62p44_regs.hpp"
#include "usrp2_regs.hpp"
+#include <uhd/exception.hpp>
#include <boost/cstdint.hpp>
#include <boost/foreach.hpp>
#include <iostream>
-#include <uhd/utils/exception.hpp>
static const bool codec_ctrl_debug = false;
@@ -118,7 +118,7 @@ public:
case 2: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_2; break;
case 4: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_4; break;
case 8: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_8; break;
- default: throw std::runtime_error("unknown modulation mode for ad9777");
+ default: throw uhd::value_error("unknown modulation mode for ad9777");
}
this->send_ad9777_reg(0x01); //set the register
@@ -168,17 +168,17 @@ private:
void send_ad9777_reg(boost::uint8_t addr){
boost::uint16_t reg = _ad9777_regs.get_write_reg(addr);
if (codec_ctrl_debug) std::cout << "send_ad9777_reg: " << std::hex << reg << std::endl;
- _iface->transact_spi(
+ _iface->write_spi(
SPI_SS_AD9777, spi_config_t::EDGE_RISE,
- reg, 16, false /*no rb*/
+ reg, 16
);
}
void send_ads62p44_reg(boost::uint8_t addr) {
boost::uint16_t reg = _ads62p44_regs.get_write_reg(addr);
- _iface->transact_spi(
+ _iface->write_spi(
SPI_SS_ADS62P44, spi_config_t::EDGE_FALL,
- reg, 16, false /*no rb*/
+ reg, 16
);
}
};
diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp
index 09bec6db2..50320773f 100644
--- a/host/lib/usrp/usrp2/codec_impl.cpp
+++ b/host/lib/usrp/usrp2/codec_impl.cpp
@@ -16,13 +16,13 @@
//
#include "usrp2_impl.hpp"
+#include <uhd/utils/assert_has.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/codec_props.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
#include <boost/bind.hpp>
#include <boost/assign/list_of.hpp>
-#include <uhd/utils/assert.hpp>
-#include <uhd/utils/exception.hpp>
using namespace uhd;
using namespace uhd::usrp;
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index c539b0058..924a6e901 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -20,7 +20,7 @@
#include "usrp2_regs.hpp" //wishbone address constants
#include <uhd/usrp/dboard_iface.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/asio.hpp> //htonl and ntohl
@@ -257,7 +257,7 @@ void usrp2_dboard_iface::write_spi(
boost::uint32_t data,
size_t num_bits
){
- _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, false /*no rb*/);
+ _iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
boost::uint32_t usrp2_dboard_iface::read_write_spi(
@@ -266,7 +266,7 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(
boost::uint32_t data,
size_t num_bits
){
- return _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, true /*rb*/);
+ return _iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);
}
/***********************************************************************
@@ -288,9 +288,9 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){
(UNIT_RX, SPI_SS_RX_DAC)
(UNIT_TX, SPI_SS_TX_DAC)
;
- _iface->transact_spi(
+ _iface->write_spi(
unit_to_spi_dac[unit], spi_config_t::EDGE_FALL,
- _dac_regs[unit].get_reg(), 24, false /*no rb*/
+ _dac_regs[unit].get_reg(), 24
);
}
@@ -336,13 +336,13 @@ double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){
} ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn
//write and read spi
- _iface->transact_spi(
+ _iface->write_spi(
unit_to_spi_adc[unit], config,
- ad7922_regs.get_reg(), 16, false /*no rb*/
+ ad7922_regs.get_reg(), 16
);
- ad7922_regs.set_reg(boost::uint16_t(_iface->transact_spi(
+ ad7922_regs.set_reg(boost::uint16_t(_iface->read_spi(
unit_to_spi_adc[unit], config,
- ad7922_regs.get_reg(), 16, true /*rb*/
+ ad7922_regs.get_reg(), 16
)));
//convert to voltage and return
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 4f1dcc46b..3f41cddcf 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -22,7 +22,7 @@
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/dboard_props.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp> //htonl and ntohl
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 8340f7cdd..cdd559e94 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -28,12 +28,79 @@
using namespace uhd;
using namespace uhd::usrp;
-static const size_t default_decim = 16;
-static const size_t default_interp = 16;
-
/***********************************************************************
- * DDC Helper Methods
+ * DSP impl and methods
**********************************************************************/
+struct usrp2_mboard_impl::dsp_impl{
+ uhd::dict<size_t, size_t> ddc_decim;
+ uhd::dict<size_t, double> ddc_freq;
+ uhd::dict<size_t, size_t> duc_interp;
+ uhd::dict<size_t, double> duc_freq;
+ std::vector<size_t> decim_and_interp_rates;
+ uhd::dict<size_t, bool> continuous_streaming;
+};
+
+void usrp2_mboard_impl::dsp_init(void){
+ //create new dsp impl
+ _dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ());
+
+ //load the allowed decim/interp rates
+ //range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
+ for (size_t i = 4; i <= 128; i+=1){
+ _dsp_impl->decim_and_interp_rates.push_back(i);
+ }
+ for (size_t i = 130; i <= 256; i+=2){
+ _dsp_impl->decim_and_interp_rates.push_back(i);
+ }
+ for (size_t i = 260; i <= 512; i+=4){
+ _dsp_impl->decim_and_interp_rates.push_back(i);
+ }
+
+ //bind and initialize the rx dsps
+ for (size_t i = 0; i < NUM_RX_DSPS; i++){
+ _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
+ boost::bind(&usrp2_mboard_impl::ddc_get, this, _1, _2, i),
+ boost::bind(&usrp2_mboard_impl::ddc_set, this, _1, _2, i)
+ );
+
+ //initial config and update
+ ddc_set(DSP_PROP_FREQ_SHIFT, double(0), i);
+ ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i);
+
+ //setup the rx control registers
+ _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //reset
+ _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, _device.get_max_recv_samps_per_packet());
+ _iface->poke32(_iface->regs.rx_ctrl[i].nchannels, 1);
+ _iface->poke32(_iface->regs.rx_ctrl[i].vrt_header, 0
+ | (0x1 << 28) //if data with stream id
+ | (0x1 << 26) //has trailer
+ | (0x3 << 22) //integer time other
+ | (0x1 << 20) //fractional time sample count
+ );
+ _iface->poke32(_iface->regs.rx_ctrl[i].vrt_stream_id, usrp2_impl::RECV_SID);
+ _iface->poke32(_iface->regs.rx_ctrl[i].vrt_trailer, 0);
+ _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq()));
+ }
+
+ //bind and initialize the tx dsps
+ for (size_t i = 0; i < NUM_TX_DSPS; i++){
+ _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
+ boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2, i),
+ boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2, i)
+ );
+
+ //initial config and update
+ duc_set(DSP_PROP_FREQ_SHIFT, double(0), i);
+ duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i);
+
+ //init the tx control registers
+ _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset
+ _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel
+ _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID);
+ _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET);
+ }
+}
+
template <typename rate_type>
static rate_type pick_closest_rate(double exact_rate, const std::vector<rate_type> &rates){
unsigned closest_match = rates.front();
@@ -44,27 +111,28 @@ static rate_type pick_closest_rate(double exact_rate, const std::vector<rate_typ
return closest_match;
}
-void usrp2_mboard_impl::init_ddc_config(void){
- //create the ddc in the rx dsp dict
- _rx_dsp_proxy = wax_obj_proxy::make(
- boost::bind(&usrp2_mboard_impl::ddc_get, this, _1, _2),
- boost::bind(&usrp2_mboard_impl::ddc_set, this, _1, _2)
- );
+void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd, size_t which_dsp){
+ _dsp_impl->continuous_streaming[which_dsp] = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
+ _iface->poke32(_iface->regs.rx_ctrl[which_dsp].stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd));
+ _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs()));
+ _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));
+}
- //initial config and update
- ddc_set(DSP_PROP_FREQ_SHIFT, double(0));
- ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_decim));
+void usrp2_mboard_impl::handle_overflow(size_t which_dsp){
+ if (_dsp_impl->continuous_streaming[which_dsp]){ //re-issue the stream command if already continuous
+ this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS, which_dsp);
+ }
}
/***********************************************************************
* DDC Properties
**********************************************************************/
-void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){
+void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()){
case DSP_PROP_NAME:
- val = _iface->get_cname() + " ddc0";
+ val = str(boost::format("%s ddc%d") % _iface->get_cname() % which_dsp);
return;
case DSP_PROP_OTHERS:
@@ -72,11 +140,7 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_FREQ_SHIFT:
- val = _ddc_freq;
- return;
-
- case DSP_PROP_FREQ_SHIFT_NAMES:
- val = prop_names_t(1, "");
+ val = _dsp_impl->ddc_freq[which_dsp];
return;
case DSP_PROP_CODEC_RATE:
@@ -84,37 +148,41 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_HOST_RATE:
- val = get_master_clock_freq()/_ddc_decim;
+ val = get_master_clock_freq()/_dsp_impl->ddc_decim[which_dsp];
return;
default: UHD_THROW_PROP_GET_ERROR();
}
}
-void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){
+void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()){
+ case DSP_PROP_STREAM_CMD:
+ issue_ddc_stream_cmd(val.as<stream_cmd_t>(), which_dsp);
+ return;
+
case DSP_PROP_FREQ_SHIFT:{
double new_freq = val.as<double>();
- _iface->poke32(_iface->regs.dsp_rx_freq,
+ _iface->poke32(_iface->regs.dsp_rx[which_dsp].freq,
dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq())
);
- _ddc_freq = new_freq; //shadow
+ _dsp_impl->ddc_freq[which_dsp] = new_freq; //shadow
}
return;
case DSP_PROP_HOST_RATE:{
double extact_rate = get_master_clock_freq()/val.as<double>();
- _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates);
+ _dsp_impl->ddc_decim[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates);
//set the decimation
- _iface->poke32(_iface->regs.dsp_rx_decim_rate, dsp_type1::calc_cic_filter_word(_ddc_decim));
+ _iface->poke32(_iface->regs.dsp_rx[which_dsp].decim_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->ddc_decim[which_dsp]));
//set the scaling
static const boost::int16_t default_rx_scale_iq = 1024;
- _iface->poke32(_iface->regs.dsp_rx_scale_iq,
+ _iface->poke32(_iface->regs.dsp_rx[which_dsp].scale_iq,
dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
);
}
@@ -125,29 +193,14 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){
}
/***********************************************************************
- * DUC Helper Methods
- **********************************************************************/
-void usrp2_mboard_impl::init_duc_config(void){
- //create the duc in the tx dsp dict
- _tx_dsp_proxy = wax_obj_proxy::make(
- boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2),
- boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2)
- );
-
- //initial config and update
- duc_set(DSP_PROP_FREQ_SHIFT, double(0));
- duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_interp));
-}
-
-/***********************************************************************
* DUC Properties
**********************************************************************/
-void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){
+void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()){
case DSP_PROP_NAME:
- val = _iface->get_cname() + " duc0";
+ val = str(boost::format("%s duc%d") % _iface->get_cname() % which_dsp);
return;
case DSP_PROP_OTHERS:
@@ -155,11 +208,7 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_FREQ_SHIFT:
- val = _duc_freq;
- return;
-
- case DSP_PROP_FREQ_SHIFT_NAMES:
- val = prop_names_t(1, "");
+ val = _dsp_impl->duc_freq[which_dsp];
return;
case DSP_PROP_CODEC_RATE:
@@ -167,14 +216,14 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){
return;
case DSP_PROP_HOST_RATE:
- val = get_master_clock_freq()/_duc_interp;
+ val = get_master_clock_freq()/_dsp_impl->duc_interp[which_dsp];
return;
default: UHD_THROW_PROP_GET_ERROR();
}
}
-void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){
+void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
named_prop_t key = named_prop_t::extract(key_);
switch(key.as<dsp_prop_t>()){
@@ -196,19 +245,19 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){
_iface->poke32(_iface->regs.dsp_tx_freq,
dsp_type1::calc_cordic_word_and_update(new_freq, codec_rate)
);
- _duc_freq = new_freq + dac_shift; //shadow
+ _dsp_impl->duc_freq[which_dsp] = new_freq + dac_shift; //shadow
}
return;
case DSP_PROP_HOST_RATE:{
double extact_rate = get_master_clock_freq()/val.as<double>();
- _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates);
+ _dsp_impl->duc_interp[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates);
//set the interpolation
- _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_duc_interp));
+ _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->duc_interp[which_dsp]));
//set the scaling
- _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_duc_interp));
+ _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_dsp_impl->duc_interp[which_dsp]));
}
return;
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index a22f805e1..68c49cafc 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -30,8 +30,8 @@ extern "C" {
#endif
//fpga and firmware compatibility numbers
-#define USRP2_FPGA_COMPAT_NUM 4
-#define USRP2_FW_COMPAT_NUM 8
+#define USRP2_FPGA_COMPAT_NUM 5
+#define USRP2_FW_COMPAT_NUM 9
//used to differentiate control packets over data port
#define USRP2_INVALID_VRT_HEADER 0
@@ -40,8 +40,9 @@ extern "C" {
// Dynamic and/or private ports: 49152-65535
#define USRP2_UDP_CTRL_PORT 49152
//#define USRP2_UDP_UPDATE_PORT 49154
-#define USRP2_UDP_DATA_PORT 49156
+#define USRP2_UDP_DSP0_PORT 49156
#define USRP2_UDP_ERR0_PORT 49157
+#define USRP2_UDP_DSP1_PORT 49158
////////////////////////////////////////////////////////////////////////
// I2C addresses
@@ -88,6 +89,9 @@ typedef enum{
USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v',
USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V',
+ USRP2_CTRL_ID_HOLLER_AT_ME_BRO = 'l',
+ USRP2_CTRL_ID_HOLLER_BACK_DUDE = 'L',
+
USRP2_CTRL_ID_PEACE_OUT = '~'
} usrp2_ctrl_id_t;
@@ -132,6 +136,9 @@ typedef struct{
uint8_t bytes;
uint8_t data[20];
} uart_args;
+ struct {
+ uint32_t len;
+ } echo_args;
} data;
} usrp2_ctrl_data_t;
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index a22482271..340e9d155 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -18,6 +18,8 @@
#include "../../transport/vrt_packet_handler.hpp"
#include "usrp2_impl.hpp"
#include "usrp2_regs.hpp"
+#include <uhd/exception.hpp>
+#include <uhd/usrp/mboard_props.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/transport/bounded_buffer.hpp>
@@ -136,27 +138,26 @@ private: size_t _indexes;
**********************************************************************/
struct usrp2_impl::io_impl{
- io_impl(size_t send_frame_size, const std::vector<zero_copy_if::sptr> &xports):
- xports(xports),
+ io_impl(std::vector<zero_copy_if::sptr> &dsp_xports):
+ dsp_xports(dsp_xports), //the assumption is that all data transports should be identical
get_recv_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_recv_buffs, this, _1)),
get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)),
- packet_handler_recv_state(xports.size()),
- packet_handler_send_state(xports.size()),
async_msg_fifo(100/*messages deep*/)
{
- for (size_t i = 0; i < xports.size(); i++){
- fc_mons.push_back(flow_control_monitor::sptr(
- new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size)
- ));
- //init empty packet infos
- vrt::if_packet_info_t packet_info;
- packet_info.packet_count = 0xf;
- packet_info.has_tsi = true;
- packet_info.tsi = 0;
- packet_info.has_tsf = true;
- packet_info.tsf = 0;
- prev_infos.push_back(packet_info);
+ for (size_t i = 0; i < dsp_xports.size(); i++){
+ fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor(
+ usrp2_impl::sram_bytes/dsp_xports.front()->get_send_frame_size()
+ )));;
}
+
+ //init empty packet infos
+ vrt::if_packet_info_t packet_info = vrt::if_packet_info_t();
+ packet_info.packet_count = 0xf;
+ packet_info.has_tsi = true;
+ packet_info.tsi = 0;
+ packet_info.has_tsf = true;
+ packet_info.tsf = 0;
+ prev_infos.resize(dsp_xports.size(), packet_info);
}
~io_impl(void){
@@ -166,15 +167,15 @@ struct usrp2_impl::io_impl{
}
bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){
- UHD_ASSERT_THROW(xports.size() == buffs.size());
+ UHD_ASSERT_THROW(send_map.size() == buffs.size());
//calculate the flow control word
const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq;
//grab a managed buffer for each index
for (size_t i = 0; i < buffs.size(); i++){
- if (not fc_mons[i]->check_fc_condition(fc_word32, send_timeout)) return false;
- buffs[i] = xports[i]->get_send_buff(send_timeout);
+ if (not fc_mons[send_map[i]]->check_fc_condition(fc_word32, send_timeout)) return false;
+ buffs[i] = dsp_xports[send_map[i]]->get_send_buff(send_timeout);
if (not buffs[i].get()) return false;
buffs[i]->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_word32);
}
@@ -182,9 +183,13 @@ struct usrp2_impl::io_impl{
}
alignment_indexes indexes_to_do; //used in alignment logic
+ time_spec_t expected_time; //used in alignment logic
bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs);
- const std::vector<zero_copy_if::sptr> &xports;
+ std::vector<zero_copy_if::sptr> &dsp_xports;
+
+ //mappings from channel index to dsp xport
+ std::vector<size_t> send_map, recv_map;
//timeouts set on calls to recv/send (passed into get buffs methods)
double recv_timeout, send_timeout;
@@ -204,7 +209,7 @@ struct usrp2_impl::io_impl{
vrt_packet_handler::send_state packet_handler_send_state;
//methods and variables for the pirate crew
- void recv_pirate_loop(zero_copy_if::sptr, usrp2_mboard_impl::sptr, size_t);
+ void recv_pirate_loop(usrp2_mboard_impl::sptr, zero_copy_if::sptr, size_t);
boost::thread_group recv_pirate_crew;
bool recv_pirate_crew_raiding;
bounded_buffer<async_metadata_t> async_msg_fifo;
@@ -218,17 +223,18 @@ struct usrp2_impl::io_impl{
* - put async message packets into queue
**********************************************************************/
void usrp2_impl::io_impl::recv_pirate_loop(
- zero_copy_if::sptr zc_if_err0,
- usrp2_mboard_impl::sptr mboard,
- size_t index
+ usrp2_mboard_impl::sptr mboard, zero_copy_if::sptr err_xport, size_t index
){
set_thread_priority_safe();
recv_pirate_crew_raiding = true;
spawn_mutex.unlock();
+ //store a reference to the flow control monitor (offset by max dsps)
+ flow_control_monitor &fc_mon = *(this->fc_mons[index*usrp2_mboard_impl::MAX_NUM_DSPS]);
+
while(recv_pirate_crew_raiding){
- managed_recv_buffer::sptr buff = zc_if_err0->get_recv_buff();
+ managed_recv_buffer::sptr buff = err_xport->get_recv_buff();
if (not buff.get()) continue; //ignore timeout/error buffers
try{
@@ -253,7 +259,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
//catch the flow control packets and react
if (metadata.event_code == 0){
boost::uint32_t fc_word32 = (vrt_hdr + if_packet_info.num_header_words32)[1];
- this->fc_mons[index]->update_fc_condition(uhd::ntohx(fc_word32));
+ fc_mon.update_fc_condition(uhd::ntohx(fc_word32));
continue;
}
@@ -276,27 +282,52 @@ void usrp2_impl::io_impl::recv_pirate_loop(
**********************************************************************/
void usrp2_impl::io_init(void){
- //the assumption is that all data transports should be identical
- const size_t send_frame_size = _data_transports.front()->get_send_frame_size();
-
//create new io impl
- _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports));
+ _io_impl = UHD_PIMPL_MAKE(io_impl, (dsp_xports));
//create a new pirate thread for each zc if (yarr!!)
- for (size_t i = 0; i < _data_transports.size(); i++){
+ for (size_t i = 0; i < _mboards.size(); i++){
//lock the unlocked mutex (non-blocking)
_io_impl->spawn_mutex.lock();
//spawn a new pirate to plunder the recv booty
_io_impl->recv_pirate_crew.create_thread(boost::bind(
&usrp2_impl::io_impl::recv_pirate_loop,
- _io_impl.get(), _err0_transports.at(i),
- _mboards.at(i), i
+ _io_impl.get(), _mboards.at(i), err_xports.at(i), i
));
//block here until the spawned thread unlocks
_io_impl->spawn_mutex.lock();
//exit loop iteration in an unlocked condition
_io_impl->spawn_mutex.unlock();
}
+
+ //update mapping here since it didnt b4 when io init not called first
+ update_xport_channel_mapping();
+}
+
+void usrp2_impl::update_xport_channel_mapping(void){
+ if (_io_impl.get() == NULL) return; //not inited yet
+
+ _io_impl->recv_map.clear();
+ _io_impl->send_map.clear();
+
+ for (size_t i = 0; i < _mboards.size(); i++){
+
+ subdev_spec_t rx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>();
+ for (size_t j = 0; j < rx_subdev_spec.size(); j++){
+ _io_impl->recv_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j);
+ //std::cout << "recv_map.back() " << _io_impl->recv_map.back() << std::endl;
+ }
+
+ subdev_spec_t tx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>();
+ for (size_t j = 0; j < tx_subdev_spec.size(); j++){
+ _io_impl->send_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j);
+ //std::cout << "send_map.back() " << _io_impl->send_map.back() << std::endl;
+ }
+
+ }
+
+ _io_impl->packet_handler_recv_state = vrt_packet_handler::recv_state(_io_impl->recv_map.size());
+ _io_impl->packet_handler_send_state = vrt_packet_handler::send_state(_io_impl->send_map.size());
}
/***********************************************************************
@@ -318,7 +349,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{
+ vrt_send_header_offset_words32*sizeof(boost::uint32_t)
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
;
- const size_t bpp = _data_transports.front()->get_send_frame_size() - hdr_size;
+ const size_t bpp = dsp_xports.front()->get_send_frame_size() - hdr_size;
return bpp/_tx_otw_type.get_sample_size();
}
@@ -388,49 +419,50 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(
vrt_packet_handler::managed_recv_buffs_t &buffs
){
if (buffs.size() == 1){
- buffs[0] = xports[0]->get_recv_buff(recv_timeout);
+ buffs[0] = dsp_xports[recv_map[0]]->get_recv_buff(recv_timeout);
if (buffs[0].get() == NULL) return false;
bool clear, msg; time_spec_t time; //unused variables
//call extract_packet_info to handle printing the overflows
- extract_packet_info(buffs[0], this->prev_infos[0], time, clear, msg);
+ extract_packet_info(buffs[0], this->prev_infos[recv_map[0]], time, clear, msg);
return true;
}
//-------------------- begin alignment logic ---------------------//
+ UHD_ASSERT_THROW(recv_map.size() == buffs.size());
boost::system_time exit_time = boost::get_system_time() + to_time_dur(recv_timeout);
managed_recv_buffer::sptr buff_tmp;
bool clear, msg;
- time_spec_t expected_time;
+ size_t index;
//If we did not enter this routine with an empty indexes set,
//jump to after the clear so we can preserve the previous state.
//This saves buffers from being lost when using non-blocking recv.
- if (not indexes_to_do.empty()) goto skip_reset;
+ if (not indexes_to_do.empty()) goto skip_pop_initial;
//respond to a clear by starting from scratch
got_clear:
indexes_to_do.reset(buffs.size());
- skip_reset:
clear = false;
//do an initial pop to load an initial sequence id
- size_t index = indexes_to_do.front();
- buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
+ index = indexes_to_do.front();
+ buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
if (buff_tmp.get() == NULL) return false;
- extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg);
+ extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], expected_time, clear, msg);
if (clear) goto got_clear;
buffs[index] = buff_tmp;
if (msg) return handle_msg_packet(buffs, index);
indexes_to_do.remove(index);
+ skip_pop_initial:
//get an aligned set of elements from the buffers:
while(not indexes_to_do.empty()){
//pop an element off for this index
index = indexes_to_do.front();
- buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
+ buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));
if (buff_tmp.get() == NULL) return false;
time_spec_t this_time;
- extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg);
+ extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], this_time, clear, msg);
if (clear) goto got_clear;
buffs[index] = buff_tmp;
if (msg) return handle_msg_packet(buffs, index);
@@ -468,13 +500,14 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
+ sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
;
- const size_t bpp = _data_transports.front()->get_recv_frame_size() - hdr_size;
+ const size_t bpp = dsp_xports.front()->get_recv_frame_size() - hdr_size;
return bpp/_rx_otw_type.get_sample_size();
}
-static void handle_overflow(std::vector<usrp2_mboard_impl::sptr> &mboards, size_t chan){
+void usrp2_impl::handle_overflow(size_t chan){
std::cerr << "O" << std::flush;
- mboards.at(chan/mboards.size())->handle_overflow();
+ ldiv_t indexes = ldiv(chan, usrp2_mboard_impl::NUM_RX_DSPS);
+ _mboards.at(indexes.quot)->handle_overflow(indexes.rem);
}
size_t usrp2_impl::recv(
@@ -491,6 +524,6 @@ size_t usrp2_impl::recv(
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_be,
_io_impl->get_recv_buffs_fcn,
- boost::bind(&handle_overflow, boost::ref(_mboards), _1)
+ boost::bind(&usrp2_impl::handle_overflow, this, _1)
);
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 92a7b2f93..40fc5098b 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -19,11 +19,11 @@
#include "usrp2_regs.hpp"
#include "fw_common.h"
#include <uhd/utils/safe_call.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/gps_ctrl.hpp>
#include <uhd/usrp/misc_utils.hpp>
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/usrp/mboard_props.hpp>
-#include <uhd/utils/assert.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/bind.hpp>
@@ -35,35 +35,55 @@ static const size_t mimo_clock_sync_delay_cycles = 137;
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::transport;
/***********************************************************************
- * Structors
+ * Helpers
**********************************************************************/
-usrp2_mboard_impl::usrp2_mboard_impl(
- size_t index,
- transport::udp_simple::sptr ctrl_transport,
- transport::zero_copy_if::sptr data_transport,
- transport::zero_copy_if::sptr err0_transport,
- const device_addr_t &device_args,
- size_t recv_samps_per_packet
-):
- _index(index),
- _iface(usrp2_iface::make(ctrl_transport))
-{
+static void init_xport(zero_copy_if::sptr xport){
//Send a small data packet so the usrp2 knows the udp source port.
//This setup must happen before further initialization occurs
//or the async update packets will cause ICMP destination unreachable.
- transport::managed_send_buffer::sptr send_buff;
static const boost::uint32_t data[2] = {
uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),
uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))
};
- send_buff = data_transport->get_send_buff();
- std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
- send_buff->commit(sizeof(data));
- send_buff = err0_transport->get_send_buff();
+
+ transport::managed_send_buffer::sptr send_buff = xport->get_send_buff();
std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
send_buff->commit(sizeof(data));
+}
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+usrp2_mboard_impl::usrp2_mboard_impl(
+ const device_addr_t &device_addr,
+ size_t index, usrp2_impl &device
+):
+ _index(index), _device(device),
+ _iface(usrp2_iface::make(udp_simple::make_connected(
+ device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)
+ )))
+{
+ //construct transports for dsp and async errors
+ std::cout << "Making transport for DSP0..." << std::endl;
+ device.dsp_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP0_PORT), device_addr
+ ));
+ init_xport(device.dsp_xports.back());
+
+ std::cout << "Making transport for DSP1..." << std::endl;
+ device.dsp_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP1_PORT), device_addr
+ ));
+ init_xport(device.dsp_xports.back());
+
+ std::cout << "Making transport for ERR0..." << std::endl;
+ device.err_xports.push_back(udp_zero_copy::make(
+ device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_ERR0_PORT), device_addr_t()
+ ));
+ init_xport(device.err_xports.back());
//contruct the interfaces to mboard perifs
_clock_ctrl = usrp2_clock_ctrl::make(_iface);
@@ -74,69 +94,33 @@ usrp2_mboard_impl::usrp2_mboard_impl(
//if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl;
- //TODO move to dsp impl...
- //load the allowed decim/interp rates
- //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
- _allowed_decim_and_interp_rates.clear();
- for (size_t i = 4; i <= 128; i+=1){
- _allowed_decim_and_interp_rates.push_back(i);
- }
- for (size_t i = 130; i <= 256; i+=2){
- _allowed_decim_and_interp_rates.push_back(i);
- }
- for (size_t i = 260; i <= 512; i+=4){
- _allowed_decim_and_interp_rates.push_back(i);
- }
-
- //setup the vrt rx registers
- _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset
- _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, recv_samps_per_packet);
- _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1);
- _iface->poke32(_iface->regs.rx_ctrl_vrt_header, 0
- | (0x1 << 28) //if data with stream id
- | (0x1 << 26) //has trailer
- | (0x3 << 22) //integer time other
- | (0x1 << 20) //fractional time sample count
- );
- _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, usrp2_impl::RECV_SID);
- _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0);
- _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq()));
-
- //init the tx control registers
- _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset
- _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel
- _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID);
- _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET);
+ //init the dsp stuff (before setting update packets)
+ dsp_init();
//setting the cycles per update (disabled by default)
- const double ups_per_sec = device_args.cast<double>("ups_per_sec", 0.0);
+ const double ups_per_sec = device_addr.cast<double>("ups_per_sec", 0.0);
if (ups_per_sec > 0.0){
const size_t cycles_per_up = size_t(_clock_ctrl->get_master_clock_rate()/ups_per_sec);
_iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, U2_FLAG_TX_CTRL_UP_ENB | cycles_per_up);
}
//setting the packets per update (enabled by default)
- const double ups_per_fifo = device_args.cast<double>("ups_per_fifo", 8.0);
+ size_t send_frame_size = device.dsp_xports[0]->get_send_frame_size();
+ const double ups_per_fifo = device_addr.cast<double>("ups_per_fifo", 8.0);
if (ups_per_fifo > 0.0){
- const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size());
+ const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/send_frame_size);
_iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up);
}
- //init the ddc
- init_ddc_config();
-
- //init the duc
- init_duc_config();
-
//initialize the clock configuration
- if (device_args.has_key("mimo_mode")){
- if (device_args["mimo_mode"] == "master"){
+ if (device_addr.has_key("mimo_mode")){
+ if (device_addr["mimo_mode"] == "master"){
_mimo_clocking_mode_is_master = true;
}
- else if (device_args["mimo_mode"] == "slave"){
+ else if (device_addr["mimo_mode"] == "slave"){
_mimo_clocking_mode_is_master = false;
}
- else throw std::runtime_error(
+ else throw uhd::value_error(
"mimo_mode must be set to master or slave"
);
}
@@ -160,13 +144,18 @@ usrp2_mboard_impl::usrp2_mboard_impl(
(*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t();
(*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t();
+ //------------------------------------------------------------------
//This is a hack/fix for the lingering packet problem.
stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
- stream_cmd.num_samps = 1;
- this->issue_ddc_stream_cmd(stream_cmd);
- data_transport->get_recv_buff().get(); //recv with timeout for lingering
- data_transport->get_recv_buff().get(); //recv with timeout for expected
- _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //resets sequence
+ for (size_t i = 0; i < NUM_RX_DSPS; i++){
+ size_t index = device.dsp_xports.size() - NUM_RX_DSPS + i;
+ stream_cmd.num_samps = 1;
+ this->issue_ddc_stream_cmd(stream_cmd, i);
+ device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for lingering
+ device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for expected
+ _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence
+ }
+ //------------------------------------------------------------------
}
usrp2_mboard_impl::~usrp2_mboard_impl(void){
@@ -191,14 +180,14 @@ void usrp2_mboard_impl::update_clock_config(void){
//translate pps source enums
switch(_clock_config.pps_source){
case clock_config_t::PPS_SMA: pps_flags |= U2_FLAG_TIME64_PPS_SMA; break;
- default: throw std::runtime_error("unhandled clock configuration pps source");
+ default: throw uhd::value_error("unhandled clock configuration pps source");
}
//translate pps polarity enums
switch(_clock_config.pps_polarity){
case clock_config_t::PPS_POS: pps_flags |= U2_FLAG_TIME64_PPS_POSEDGE; break;
case clock_config_t::PPS_NEG: pps_flags |= U2_FLAG_TIME64_PPS_NEGEDGE; break;
- default: throw std::runtime_error("unhandled clock configuration pps polarity");
+ default: throw uhd::value_error("unhandled clock configuration pps polarity");
}
//set the pps flags
@@ -211,7 +200,7 @@ void usrp2_mboard_impl::update_clock_config(void){
switch(_clock_config.ref_source){
case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break;
case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break;
- default: throw std::runtime_error("unhandled clock configuration reference source");
+ default: throw uhd::value_error("unhandled clock configuration reference source");
}
_clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO
break;
@@ -221,7 +210,7 @@ void usrp2_mboard_impl::update_clock_config(void){
switch(_clock_config.ref_source){
case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break;
case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break;
- default: throw std::runtime_error("unhandled clock configuration reference source");
+ default: throw uhd::value_error("unhandled clock configuration reference source");
}
_clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT);
break;
@@ -275,19 +264,6 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){
_iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs()));
}
-void usrp2_mboard_impl::handle_overflow(void){
- if (_continuous_streaming){ //re-issue the stream command if already continuous
- this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
- }
-}
-
-void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
- _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
- _iface->poke32(_iface->regs.rx_ctrl_stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd));
- _iface->poke32(_iface->regs.rx_ctrl_time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs()));
- _iface->poke32(_iface->regs.rx_ctrl_time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));
-}
-
/***********************************************************************
* MBoard Get Properties
**********************************************************************/
@@ -324,21 +300,19 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
return;
case MBOARD_PROP_RX_DSP:
- UHD_ASSERT_THROW(key.name == "");
- val = _rx_dsp_proxy->get_link();
+ val = _rx_dsp_proxies[key.name]->get_link();
return;
case MBOARD_PROP_RX_DSP_NAMES:
- val = prop_names_t(1, "");
+ val = _rx_dsp_proxies.keys();
return;
case MBOARD_PROP_TX_DSP:
- UHD_ASSERT_THROW(key.name == "");
- val = _tx_dsp_proxy->get_link();
+ val = _tx_dsp_proxies[key.name]->get_link();
return;
case MBOARD_PROP_TX_DSP_NAMES:
- val = prop_names_t(1, "");
+ val = _tx_dsp_proxies.keys();
return;
case MBOARD_PROP_CLOCK_CONFIG:
@@ -401,30 +375,32 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
set_time_spec(val.as<time_spec_t>(), false);
return;
- case MBOARD_PROP_STREAM_CMD:
- issue_ddc_stream_cmd(val.as<stream_cmd_t>());
- return;
-
case MBOARD_PROP_RX_SUBDEV_SPEC:
_rx_subdev_spec = val.as<subdev_spec_t>();
verify_rx_subdev_spec(_rx_subdev_spec, this->get_link());
//sanity check
- UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1);
+ UHD_ASSERT_THROW(_rx_subdev_spec.size() <= NUM_RX_DSPS);
//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>()
- ));
+ for (size_t i = 0; i < _rx_subdev_spec.size(); i++){
+ if (_rx_subdev_spec.size() >= 1) _iface->poke32(_iface->regs.dsp_rx[i].mux, dsp_type1::calc_rx_mux_word(
+ _dboard_manager->get_rx_subdev(_rx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ }
+ _device.update_xport_channel_mapping();
return;
case MBOARD_PROP_TX_SUBDEV_SPEC:
_tx_subdev_spec = val.as<subdev_spec_t>();
verify_tx_subdev_spec(_tx_subdev_spec, this->get_link());
//sanity check
- UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1);
+ UHD_ASSERT_THROW(_tx_subdev_spec.size() <= NUM_TX_DSPS);
//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>()
- ));
+ for (size_t i = 0; i < _rx_subdev_spec.size(); i++){
+ _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word(
+ _dboard_manager->get_tx_subdev(_tx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ }
+ _device.update_xport_channel_mapping();
return;
case MBOARD_PROP_EEPROM_MAP:
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index bd1f5ccb5..e3827233b 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -18,8 +18,7 @@
#include "usrp2_regs.hpp"
#include "fw_common.h"
#include "usrp2_iface.hpp"
-#include <uhd/utils/exception.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/types/dict.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
@@ -27,7 +26,6 @@
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
-#include <stdexcept>
#include <algorithm>
using namespace uhd;
@@ -65,17 +63,13 @@ public:
//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(
+ throw uhd::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){
- /* NOP */
- }
-
/***********************************************************************
* Peek and Poke
**********************************************************************/
@@ -247,7 +241,7 @@ public:
while(true){
size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CTRL_RECV_TIMEOUT);
if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){
- throw std::runtime_error(str(boost::format(
+ throw uhd::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)));
@@ -258,7 +252,7 @@ public:
if (len == 0) break; //timeout
//didnt get seq or bad packet, continue looking...
}
- throw std::runtime_error("no control response");
+ throw uhd::runtime_error("no control response");
}
rev_type get_rev(void){
diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp
index ea42d019f..df53ec66a 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.hpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.hpp
@@ -19,8 +19,7 @@
#define INCLUDED_USRP2_IFACE_HPP
#include <uhd/transport/udp_simple.hpp>
-#include <uhd/types/serial.hpp>
-#include <uhd/usrp/mboard_eeprom.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/cstdint.hpp>
@@ -39,10 +38,9 @@ typedef boost::function<std::string(void)> gps_recv_fn_t;
* Provides a set of functions to implementation layer.
* Including spi, peek, poke, control...
*/
-class usrp2_iface : public uhd::i2c_iface, boost::noncopyable{
+class usrp2_iface : public uhd::usrp::mboard_iface, boost::noncopyable{
public:
typedef boost::shared_ptr<usrp2_iface> sptr;
-
/*!
* Make a new usrp2 interface with the control transport.
* \param ctrl_transport the udp transport object
@@ -50,55 +48,6 @@ public:
*/
static sptr make(uhd::transport::udp_simple::sptr ctrl_transport);
- /*!
- * Write a register (32 bits)
- * \param addr the address
- * \param data the 32bit data
- */
- virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0;
-
- /*!
- * Read a register (32 bits)
- * \param addr the address
- * \return the 32bit data
- */
- virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
-
- /*!
- * Write a register (16 bits)
- * \param addr the address
- * \param data the 16bit data
- */
- virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0;
-
- /*!
- * Read a register (16 bits)
- * \param addr the address
- * \return the 16bit data
- */
- virtual boost::uint16_t peek16(boost::uint32_t addr) = 0;
-
- /*!
- * Perform an spi transaction.
- * \param which_slave the slave device number
- * \param config spi config args
- * \param data the bits to write
- * \param num_bits how many bits in data
- * \param readback true to readback a value
- * \return spi data if readback set
- */
- virtual boost::uint32_t transact_spi(
- int which_slave,
- const uhd::spi_config_t &config,
- boost::uint32_t data,
- size_t num_bits,
- bool readback
- ) = 0;
-
- virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0;
-
- virtual std::string read_uart(boost::uint8_t dev) = 0;
-
virtual gps_recv_fn_t get_gps_read_fn(void) = 0;
virtual gps_send_fn_t get_gps_write_fn(void) = 0;
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 8fd88e01d..96552929a 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -17,20 +17,21 @@
#include "usrp2_impl.hpp"
#include "fw_common.h"
+#include <uhd/exception.hpp>
#include <uhd/transport/if_addrs.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/usrp/device_props.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/warning.hpp>
-#include <boost/algorithm/string.hpp> //for split
+#include <uhd/utils/byteswap.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/regex.hpp>
#include <boost/bind.hpp>
-#include <boost/asio.hpp> //htonl and ntohl
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio.hpp> //used for htonl and ntohl
#include <iostream>
#include <vector>
@@ -40,76 +41,21 @@ using namespace uhd::transport;
namespace asio = boost::asio;
/***********************************************************************
- * Helper Functions
- **********************************************************************/
-template <class T> std::string num2str(T num){
- return boost::lexical_cast<std::string>(num);
-}
-
-//! separate indexed device addresses into a vector of device addresses
-device_addrs_t sep_indexed_dev_addrs(const device_addr_t &dev_addr){
- //------------ support old deprecated way and print warning --------
- if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){
- std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" "));
- if (addrs.size() > 1){
- device_addr_t fixed_dev_addr = dev_addr;
- fixed_dev_addr.pop("addr");
- for (size_t i = 0; i < addrs.size(); i++){
- fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i];
- }
- uhd::warning::post(
- "addr = <space separated list of ip addresses> is deprecated.\n"
- "To address a multi-device, use multiple <key><index> = <val>.\n"
- "See the USRP-NXXX application notes. Two device example:\n"
- " addr0 = 192.168.10.2\n"
- " addr1 = 192.168.10.3\n"
- );
- return sep_indexed_dev_addrs(fixed_dev_addr);
- }
- }
- //------------------------------------------------------------------
- device_addrs_t dev_addrs;
- BOOST_FOREACH(const std::string &key, dev_addr.keys()){
- boost::cmatch matches;
- if (not boost::regex_match(key.c_str(), matches, boost::regex("^(\\D+)(\\d*)$"))){
- throw std::runtime_error("unknown key format: " + key);
- }
- std::string key_part(matches[1].first, matches[1].second);
- std::string num_part(matches[2].first, matches[2].second);
- size_t num = (num_part.empty())? 0 : boost::lexical_cast<size_t>(num_part);
- dev_addrs.resize(std::max(num+1, dev_addrs.size()));
- dev_addrs[num][key_part] = dev_addr[key];
- }
- return dev_addrs;
-}
-
-//! combine a vector in device addresses into an indexed device address
-device_addr_t combine_dev_addr_vector(const device_addrs_t &dev_addrs){
- device_addr_t dev_addr;
- for (size_t i = 0; i < dev_addrs.size(); i++){
- BOOST_FOREACH(const std::string &key, dev_addrs[i].keys()){
- dev_addr[str(boost::format("%s%d") % key % i)] = dev_addrs[i][key];
- }
- }
- return dev_addr;
-}
-
-/***********************************************************************
* Discovery over the udp transport
**********************************************************************/
static device_addrs_t usrp2_find(const device_addr_t &hint_){
//handle the multi-device discovery
- device_addrs_t hints = sep_indexed_dev_addrs(hint_);
+ device_addrs_t hints = separate_device_addr(hint_);
if (hints.size() > 1){
device_addrs_t found_devices;
BOOST_FOREACH(const device_addr_t &hint_i, hints){
device_addrs_t found_devices_i = usrp2_find(hint_i);
- if (found_devices_i.size() != 1) throw std::runtime_error(str(boost::format(
+ if (found_devices_i.size() != 1) throw uhd::value_error(str(boost::format(
"Could not resolve device hint \"%s\" to a single device."
) % hint_i.to_string()));
found_devices.push_back(found_devices_i[0]);
}
- return device_addrs_t(1, combine_dev_addr_vector(found_devices));
+ return device_addrs_t(1, combine_device_addrs(found_devices));
}
//initialize the hint for a single device case
@@ -148,8 +94,8 @@ static 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_FW_COMPAT_NUM);
- ctrl_data_out.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO);
+ ctrl_data_out.proto_ver = uhd::htonx<boost::uint32_t>(USRP2_FW_COMPAT_NUM);
+ ctrl_data_out.id = uhd::htonx<boost::uint32_t>(USRP2_CTRL_ID_WAZZUP_BRO);
udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out)));
//loop and recieve until the timeout
@@ -168,9 +114,9 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){
//This operation can throw due to compatibility mismatch.
//In this case, the discovered device will be ignored.
try{
- mboard_eeprom_t mb_eeprom = usrp2_iface::make(
- udp_simple::make_connected(new_addr["addr"], num2str(USRP2_UDP_CTRL_PORT))
- )->mb_eeprom;
+ mboard_eeprom_t mb_eeprom = usrp2_iface::make(udp_simple::make_connected(
+ new_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT)
+ ))->mb_eeprom;
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = mb_eeprom["serial"];
if (
@@ -199,57 +145,111 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){
* Make
**********************************************************************/
static device::sptr usrp2_make(const device_addr_t &device_addr){
+ return device::sptr(new usrp2_impl(device_addr));
+}
- //setup the dsp transport hints (default to a large recv buff)
- device_addr_t dsp_xport_hints = device_addr;
- if (not dsp_xport_hints.has_key("recv_buff_size")){
- //only enable on platforms that are happy with the large buffer resize
- #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)
- //set to half-a-second of buffering at max rate
- dsp_xport_hints["recv_buff_size"] = "50e6";
- #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/
- }
+UHD_STATIC_BLOCK(register_usrp2_device){
+ device::register_device(&usrp2_find, &usrp2_make);
+}
- //create a ctrl and data transport for each address
- std::vector<udp_simple::sptr> ctrl_transports;
- std::vector<zero_copy_if::sptr> data_transports;
- std::vector<zero_copy_if::sptr> err0_transports;
- const device_addrs_t device_addrs = sep_indexed_dev_addrs(device_addr);
+/***********************************************************************
+ * MTU Discovery
+ **********************************************************************/
+struct mtu_result_t{
+ size_t recv_mtu, send_mtu;
+};
+
+static mtu_result_t determine_mtu(const std::string &addr){
+ udp_simple::sptr udp_sock = udp_simple::make_connected(
+ addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)
+ );
+
+ //The FPGA offers 4K buffers, and the user may manually request this.
+ //However, multiple simultaneous receives (2DSP slave + 2DSP master),
+ //require that buffering to be used internally, and this is a safe setting.
+ boost::uint8_t buffer[2000];
+ usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(buffer);
+ static const double echo_timeout = 0.020; //20 ms
+
+ size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = sizeof(buffer);
+ size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = sizeof(buffer);
+
+ while (min_recv_mtu < max_recv_mtu){
+
+ size_t test_mtu = (max_recv_mtu/2 + min_recv_mtu/2 + 3) & ~3;
+ //std::cout << "recv_mtu " << mtu.recv_mtu << std::endl;
+
+ ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO);
+ ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM);
+ ctrl_data->data.echo_args.len = htonl(test_mtu);
+ udp_sock->send(boost::asio::buffer(buffer, sizeof(usrp2_ctrl_data_t)));
+
+ size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout);
+
+ if (len >= test_mtu) min_recv_mtu = test_mtu;
+ else max_recv_mtu = test_mtu - 4;
- BOOST_FOREACH(const device_addr_t &dev_addr_i, device_addrs){
- ctrl_transports.push_back(udp_simple::make_connected(
- dev_addr_i["addr"], num2str(USRP2_UDP_CTRL_PORT)
- ));
- data_transports.push_back(udp_zero_copy::make(
- dev_addr_i["addr"], num2str(USRP2_UDP_DATA_PORT), dsp_xport_hints
- ));
- err0_transports.push_back(udp_zero_copy::make(
- dev_addr_i["addr"], num2str(USRP2_UDP_ERR0_PORT), device_addr_t()
- ));
}
- //create the usrp2 implementation guts
- return device::sptr(new usrp2_impl(
- ctrl_transports, data_transports, err0_transports, device_addrs
- ));
-}
+ while (min_send_mtu < max_send_mtu){
-UHD_STATIC_BLOCK(register_usrp2_device){
- device::register_device(&usrp2_find, &usrp2_make);
+ size_t test_mtu = (max_send_mtu/2 + min_send_mtu/2 + 3) & ~3;
+ //std::cout << "send_mtu " << mtu.send_mtu << std::endl;
+
+ ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO);
+ ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM);
+ ctrl_data->data.echo_args.len = htonl(sizeof(usrp2_ctrl_data_t));
+ udp_sock->send(boost::asio::buffer(buffer, test_mtu));
+
+ size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout);
+ if (len >= sizeof(usrp2_ctrl_data_t)) len = ntohl(ctrl_data->data.echo_args.len);
+
+ if (len >= test_mtu) min_send_mtu = test_mtu;
+ else max_send_mtu = test_mtu - 4;
+ }
+
+ mtu_result_t mtu;
+ mtu.recv_mtu = min_recv_mtu;
+ mtu.send_mtu = min_send_mtu;
+ return mtu;
}
/***********************************************************************
* Structors
**********************************************************************/
-usrp2_impl::usrp2_impl(
- std::vector<udp_simple::sptr> ctrl_transports,
- std::vector<zero_copy_if::sptr> data_transports,
- std::vector<zero_copy_if::sptr> err0_transports,
- const device_addrs_t &device_args
-):
- _data_transports(data_transports),
- _err0_transports(err0_transports)
-{
+usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
+ device_addr_t device_addr = _device_addr;
+
+ //setup the dsp transport hints (default to a large recv buff)
+ if (not device_addr.has_key("recv_buff_size")){
+ #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD)
+ //limit buffer resize on macos or it will error
+ device_addr["recv_buff_size"] = "1e6";
+ #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)
+ //set to half-a-second of buffering at max rate
+ device_addr["recv_buff_size"] = "50e6";
+ #endif
+ }
+
+ device_addrs_t device_args = separate_device_addr(device_addr);
+
+ //calculate the minimum send and recv mtu of all devices
+ mtu_result_t mtu = determine_mtu(device_args[0]["addr"]);
+ for (size_t i = 1; i < device_args.size(); i++){
+ mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"]);
+ mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu);
+ mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu);
+ }
+
+ std::cout << "mtu recv bytes " << mtu.recv_mtu << std::endl;
+ std::cout << "mtu send bytes " << mtu.send_mtu << std::endl;
+
+ //use the discovered mtu if not specified by the user
+ if (not device_addr.has_key("recv_frame_size"))
+ device_addr["recv_frame_size"] = boost::lexical_cast<std::string>(mtu.recv_mtu);
+ if (not device_addr.has_key("send_frame_size"))
+ device_addr["send_frame_size"] = boost::lexical_cast<std::string>(mtu.send_mtu);
+
//setup rx otw type
_rx_otw_type.width = 16;
_rx_otw_type.shift = 0;
@@ -264,13 +264,16 @@ usrp2_impl::usrp2_impl(
//create a new mboard handler for each control transport
for(size_t i = 0; i < device_args.size(); i++){
- _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl(
- i, ctrl_transports[i], data_transports[i],
- err0_transports[i], device_args[i],
- this->get_max_recv_samps_per_packet()
- )));
+ device_addr_t dev_addr_i = device_args[i];
+ BOOST_FOREACH(const std::string &key, device_addr.keys()){
+ if (dev_addr_i.has_key(key)) continue;
+ dev_addr_i[key] = device_addr[key];
+ }
+ _mboards.push_back(usrp2_mboard_impl::sptr(
+ new usrp2_mboard_impl(dev_addr_i, i, *this)
+ ));
//use an empty name when there is only one mboard
- std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : "";
+ std::string name = (device_args.size() > 1)? boost::lexical_cast<std::string>(i) : "";
_mboard_dict[name] = _mboards.back();
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 337f842d6..0676cecf2 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -71,6 +71,8 @@ private:
void set(const wax::obj &key, const wax::obj &val){return _set(key, val);}
};
+class usrp2_impl;
+
/*!
* USRP2 mboard implementation guts:
* The implementation details are encapsulated here.
@@ -80,14 +82,14 @@ class usrp2_mboard_impl : public wax::obj{
public:
typedef boost::shared_ptr<usrp2_mboard_impl> sptr;
+ static const size_t NUM_RX_DSPS = 2;
+ static const size_t NUM_TX_DSPS = 1;
+ static const size_t MAX_NUM_DSPS = 2;
+
//structors
usrp2_mboard_impl(
- size_t index,
- uhd::transport::udp_simple::sptr,
- uhd::transport::zero_copy_if::sptr,
- uhd::transport::zero_copy_if::sptr,
- const uhd::device_addr_t &device_args,
- size_t recv_samps_per_packet
+ const uhd::device_addr_t &device_addr,
+ size_t index, usrp2_impl &device
);
~usrp2_mboard_impl(void);
@@ -95,11 +97,11 @@ public:
return _clock_ctrl->get_master_clock_rate();
}
- void handle_overflow(void);
+ void handle_overflow(size_t);
private:
size_t _index;
- bool _continuous_streaming;
+ usrp2_impl &_device;
bool _mimo_clocking_mode_is_master;
//interfaces
@@ -147,27 +149,20 @@ private:
wax_obj_proxy::sptr _tx_dboard_proxy;
uhd::usrp::dboard_eeprom_t _tx_db_eeprom;
- //methods and shadows for the ddc dsp
- std::vector<size_t> _allowed_decim_and_interp_rates;
- size_t _ddc_decim;
- double _ddc_freq;
- void init_ddc_config(void);
- void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd);
-
- //methods and shadows for the duc dsp
- size_t _duc_interp;
- double _duc_freq;
- void init_duc_config(void);
+ //methods and shadows for the dsps
+ UHD_PIMPL_DECL(dsp_impl) _dsp_impl;
+ void dsp_init(void);
+ void issue_ddc_stream_cmd(const uhd::stream_cmd_t &, size_t);
//properties interface for ddc
- void ddc_get(const wax::obj &, wax::obj &);
- void ddc_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy::sptr _rx_dsp_proxy;
+ void ddc_get(const wax::obj &, wax::obj &, size_t);
+ void ddc_set(const wax::obj &, const wax::obj &, size_t);
+ uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsp_proxies;
//properties interface for duc
- void duc_get(const wax::obj &, wax::obj &);
- void duc_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy::sptr _tx_dsp_proxy;
+ void duc_get(const wax::obj &, wax::obj &, size_t);
+ void duc_set(const wax::obj &, const wax::obj &, size_t);
+ uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsp_proxies;
};
@@ -182,19 +177,7 @@ public:
static const boost::uint32_t RECV_SID = 1;
static const boost::uint32_t ASYNC_SID = 2;
- /*!
- * Create a new usrp2 impl base.
- * \param ctrl_transports the udp transports for control
- * \param data_transports the udp transports for data
- * \param err0_transports the udp transports for error
- * \param device_args optional misc device parameters
- */
- usrp2_impl(
- std::vector<uhd::transport::udp_simple::sptr> ctrl_transports,
- std::vector<uhd::transport::zero_copy_if::sptr> data_transports,
- std::vector<uhd::transport::zero_copy_if::sptr> err0_transports,
- const uhd::device_addrs_t &device_args
- );
+ usrp2_impl(const uhd::device_addr_t &);
~usrp2_impl(void);
@@ -213,6 +196,14 @@ public:
size_t get_max_recv_samps_per_packet(void) const;
bool recv_async_msg(uhd::async_metadata_t &, double);
+ void update_xport_channel_mapping(void);
+
+ //public frame sizes, set by mboard, used by io impl
+ size_t recv_frame_size, send_frame_size;
+
+ std::vector<uhd::transport::zero_copy_if::sptr> dsp_xports;
+ std::vector<uhd::transport::zero_copy_if::sptr> err_xports;
+
private:
//device properties interface
void get(const wax::obj &, wax::obj &);
@@ -223,11 +214,10 @@ private:
uhd::dict<std::string, usrp2_mboard_impl::sptr> _mboard_dict;
//io impl methods and members
- std::vector<uhd::transport::zero_copy_if::sptr> _data_transports;
- std::vector<uhd::transport::zero_copy_if::sptr> _err0_transports;
uhd::otw_type_t _rx_otw_type, _tx_otw_type;
UHD_PIMPL_DECL(io_impl) _io_impl;
void io_init(void);
+ void handle_overflow(size_t);
};
#endif /* INCLUDED_USRP2_IMPL_HPP */
diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp
index 84907c32e..66c3ac137 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.cpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.cpp
@@ -38,8 +38,10 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {
x.sr_udp_sm = 96;
x.sr_tx_dsp = 208;
x.sr_tx_ctrl = 224;
- x.sr_rx_dsp = 160;
- x.sr_rx_ctrl = 176;
+ x.sr_rx_dsp0 = 160;
+ x.sr_rx_ctrl0 = 176;
+ x.sr_rx_dsp1 = 240;
+ x.sr_rx_ctrl1 = 32;
x.sr_time64 = 192;
x.sr_simtimer = 198;
x.sr_last = 255;
@@ -68,12 +70,18 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {
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);
x.dsp_tx_mux = sr_addr(misc_output_base, x.sr_tx_dsp + 4);
- x.dsp_rx_freq = sr_addr(misc_output_base, x.sr_rx_dsp + 0);
- x.dsp_rx_scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp + 1);
- x.dsp_rx_decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp + 2);
- x.dsp_rx_dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp + 3);
- x.dsp_rx_dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp + 4);
- x.dsp_rx_mux = sr_addr(misc_output_base, x.sr_rx_dsp + 5);
+ x.dsp_rx[0].freq = sr_addr(misc_output_base, x.sr_rx_dsp0 + 0);
+ x.dsp_rx[0].scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp0 + 1);
+ x.dsp_rx[0].decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp0 + 2);
+ x.dsp_rx[0].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp0 + 3);
+ x.dsp_rx[0].dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp0 + 4);
+ x.dsp_rx[0].mux = sr_addr(misc_output_base, x.sr_rx_dsp0 + 5);
+ x.dsp_rx[1].freq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 0);
+ x.dsp_rx[1].scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 1);
+ x.dsp_rx[1].decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp1 + 2);
+ x.dsp_rx[1].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp1 + 3);
+ x.dsp_rx[1].dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp1 + 4);
+ x.dsp_rx[1].mux = sr_addr(misc_output_base, x.sr_rx_dsp1 + 5);
x.gpio_io = gpio_base + 0;
x.gpio_ddr = gpio_base + 4;
x.gpio_tx_sel = gpio_base + 8;
@@ -86,15 +94,24 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {
x.atr_inrx_rxside = atr_base + 10;
x.atr_full_txside = atr_base + 12;
x.atr_full_rxside = atr_base + 14;
- x.rx_ctrl_stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl + 0);
- x.rx_ctrl_time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl + 1);
- x.rx_ctrl_time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl + 2);
- x.rx_ctrl_clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl + 3);
- x.rx_ctrl_vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl + 4);
- x.rx_ctrl_vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl + 5);
- x.rx_ctrl_vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl + 6);
- x.rx_ctrl_nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl + 7);
- x.rx_ctrl_nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl + 8);
+ x.rx_ctrl[0].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 0);
+ x.rx_ctrl[0].time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 1);
+ x.rx_ctrl[0].time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 2);
+ x.rx_ctrl[0].clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 3);
+ x.rx_ctrl[0].vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 4);
+ x.rx_ctrl[0].vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 5);
+ x.rx_ctrl[0].vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 6);
+ x.rx_ctrl[0].nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 7);
+ x.rx_ctrl[0].nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 8);
+ x.rx_ctrl[1].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 0);
+ x.rx_ctrl[1].time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 1);
+ x.rx_ctrl[1].time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 2);
+ x.rx_ctrl[1].clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 3);
+ x.rx_ctrl[1].vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 4);
+ x.rx_ctrl[1].vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 5);
+ x.rx_ctrl[1].vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 6);
+ x.rx_ctrl[1].nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 7);
+ x.rx_ctrl[1].nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 8);
x.tx_ctrl_num_chan = sr_addr(misc_output_base, x.sr_tx_ctrl + 0);
x.tx_ctrl_clear_state = sr_addr(misc_output_base, x.sr_tx_ctrl + 1);
x.tx_ctrl_report_sid = sr_addr(misc_output_base, x.sr_tx_ctrl + 2);
diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp
index 977b342cb..01f5ee65a 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.hpp
@@ -38,8 +38,10 @@ typedef struct {
int sr_udp_sm;
int sr_tx_dsp;
int sr_tx_ctrl;
- int sr_rx_dsp;
- int sr_rx_ctrl;
+ int sr_rx_dsp0;
+ int sr_rx_ctrl0;
+ int sr_rx_dsp1;
+ int sr_rx_ctrl1;
int sr_time64;
int sr_simtimer;
int sr_last;
@@ -68,12 +70,14 @@ typedef struct {
int dsp_tx_scale_iq;
int dsp_tx_interp_rate;
int dsp_tx_mux;
- int dsp_rx_freq;
- int dsp_rx_scale_iq;
- int dsp_rx_decim_rate;
- int dsp_rx_dcoffset_i;
- int dsp_rx_dcoffset_q;
- int dsp_rx_mux;
+ struct{
+ int freq;
+ int scale_iq;
+ int decim_rate;
+ int dcoffset_i;
+ int dcoffset_q;
+ int mux;
+ } dsp_rx[2];
int gpio_base;
int gpio_io;
int gpio_ddr;
@@ -88,15 +92,17 @@ typedef struct {
int atr_inrx_rxside;
int atr_full_txside;
int atr_full_rxside;
- int rx_ctrl_stream_cmd;
- int rx_ctrl_time_secs;
- int rx_ctrl_time_ticks;
- int rx_ctrl_clear_overrun;
- int rx_ctrl_vrt_header;
- int rx_ctrl_vrt_stream_id;
- int rx_ctrl_vrt_trailer;
- int rx_ctrl_nsamps_per_pkt;
- int rx_ctrl_nchannels;
+ struct{
+ int stream_cmd;
+ int time_secs;
+ int time_ticks;
+ int clear_overrun;
+ int vrt_header;
+ int vrt_stream_id;
+ int vrt_trailer;
+ int nsamps_per_pkt;
+ int nchannels;
+ } rx_ctrl[2];
int tx_ctrl_num_chan;
int tx_ctrl_clear_state;
int tx_ctrl_report_sid;
diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
index e29fe18ce..aba630d88 100644
--- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
@@ -17,7 +17,7 @@
#include "clock_ctrl.hpp"
#include "ad9522_regs.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <boost/cstdint.hpp>
#include "usrp_e100_regs.hpp" //spi slave constants
#include <boost/assign/list_of.hpp>
@@ -158,7 +158,7 @@ static clock_settings_type get_clock_settings(double rate){
}
}
- throw std::runtime_error(str(boost::format(
+ throw uhd::value_error(str(boost::format(
"USRP-E100 clock control: could not calculate settings for clock rate %fMHz"
) % (rate/1e6)));
}
@@ -302,7 +302,7 @@ public:
_ad9522_regs.out4_cmos_configuration = (enb)?
ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON :
ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF;
- this->send_reg(0x0F0);
+ this->send_reg(0x0F4);
this->latch_regs();
}
@@ -409,10 +409,10 @@ private:
void send_reg(boost::uint16_t addr){
boost::uint32_t reg = _ad9522_regs.get_write_reg(addr);
//std::cout << "clock control write reg: " << std::hex << reg << std::endl;
- _iface->transact_spi(
+ _iface->write_spi(
UE_SPI_SS_AD9522,
spi_config_t::EDGE_RISE,
- reg, 24, false /*no rb*/
+ reg, 24
);
}
@@ -427,9 +427,9 @@ private:
//wait for calibration done:
static const boost::uint8_t addr = 0x01F;
for (size_t ms10 = 0; ms10 < 100; ms10++){
- boost::uint32_t reg = _iface->transact_spi(
+ boost::uint32_t reg = _iface->read_spi(
UE_SPI_SS_AD9522, spi_config_t::EDGE_RISE,
- _ad9522_regs.get_read_reg(addr), 24, true /*rb*/
+ _ad9522_regs.get_read_reg(addr), 24
);
_ad9522_regs.set_reg(addr, reg);
if (_ad9522_regs.vco_calibration_finished) return;
diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.cpp b/host/lib/usrp/usrp_e100/codec_ctrl.cpp
index b33c8ae65..50442546a 100644
--- a/host/lib/usrp/usrp_e100/codec_ctrl.cpp
+++ b/host/lib/usrp/usrp_e100/codec_ctrl.cpp
@@ -18,7 +18,7 @@
#include "codec_ctrl.hpp"
#include "ad9862_regs.hpp"
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/cstdint.hpp>
#include <boost/tuple/tuple.hpp>
@@ -137,7 +137,7 @@ static const int mtpgw = 255; //maximum tx pga gain word
void usrp_e100_codec_ctrl_impl::set_tx_pga_gain(double gain){
int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start()));
- _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw);
+ _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw);
this->send_reg(16);
}
@@ -149,7 +149,7 @@ static const int mrpgw = 0x14; //maximum rx pga gain word
void usrp_e100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){
int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start()));
- gain_word = std::clip(gain_word, 0, mrpgw);
+ gain_word = uhd::clip(gain_word, 0, mrpgw);
switch(which){
case 'A':
_ad9862_regs.rx_pga_a = gain_word;
@@ -227,7 +227,7 @@ double usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){
case AUX_ADC_B1: return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0);
case AUX_ADC_B2: return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0);
}
- UHD_ASSERT_THROW(false);
+ UHD_THROW_INVALID_CODE_PATH();
}
/***********************************************************************
@@ -236,7 +236,7 @@ double usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){
void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){
//special case for aux dac d (aka sigma delta word)
if (which == AUX_DAC_D){
- boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);
+ boost::uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);
_ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4);
_ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf);
this->send_reg(42);
@@ -245,7 +245,7 @@ void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){
}
//calculate the dac word for aux dac a, b, c
- boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);
+ boost::uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);
//setup a lookup table for the aux dac params (reg ref, reg addr)
typedef boost::tuple<boost::uint8_t*, boost::uint8_t> dac_params_t;
@@ -269,20 +269,20 @@ void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){
void usrp_e100_codec_ctrl_impl::send_reg(boost::uint8_t addr){
boost::uint32_t reg = _ad9862_regs.get_write_reg(addr);
if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl;
- _iface->transact_spi(
+ _iface->write_spi(
UE_SPI_SS_AD9862,
spi_config_t::EDGE_RISE,
- reg, 16, false /*no rb*/
+ reg, 16
);
}
void usrp_e100_codec_ctrl_impl::recv_reg(boost::uint8_t addr){
boost::uint32_t reg = _ad9862_regs.get_read_reg(addr);
if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl;
- boost::uint32_t ret = _iface->transact_spi(
+ boost::uint32_t ret = _iface->read_spi(
UE_SPI_SS_AD9862,
spi_config_t::EDGE_RISE,
- reg, 16, true /*rb*/
+ reg, 16
);
if (codec_debug) std::cout << "codec control read ret: " << std::hex << ret << std::endl;
_ad9862_regs.set_reg(addr, boost::uint16_t(ret));
diff --git a/host/lib/usrp/usrp_e100/codec_impl.cpp b/host/lib/usrp/usrp_e100/codec_impl.cpp
index 0d91fb42c..ae198aaa5 100644
--- a/host/lib/usrp/usrp_e100/codec_impl.cpp
+++ b/host/lib/usrp/usrp_e100/codec_impl.cpp
@@ -16,7 +16,7 @@
//
#include "usrp_e100_impl.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/codec_props.hpp>
#include <boost/bind.hpp>
diff --git a/host/lib/usrp/usrp_e100/dboard_iface.cpp b/host/lib/usrp/usrp_e100/dboard_iface.cpp
index e4c3856c9..4ee354486 100644
--- a/host/lib/usrp/usrp_e100/dboard_iface.cpp
+++ b/host/lib/usrp/usrp_e100/dboard_iface.cpp
@@ -21,7 +21,7 @@
#include "codec_ctrl.hpp"
#include <uhd/usrp/dboard_iface.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/assign/list_of.hpp>
#include <linux/usrp_e.h> //i2c and spi constants
@@ -235,7 +235,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){
case dboard_iface::UNIT_TX: return UE_SPI_SS_TX_DB;
case dboard_iface::UNIT_RX: return UE_SPI_SS_RX_DB;
}
- throw std::invalid_argument("unknown unit type");
+ UHD_THROW_INVALID_CODE_PATH();
}
void usrp_e100_dboard_iface::write_spi(
@@ -244,7 +244,7 @@ void usrp_e100_dboard_iface::write_spi(
boost::uint32_t data,
size_t num_bits
){
- _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/);
+ _iface->write_spi(unit_to_otw_spi_dev(unit), config, data, num_bits);
}
boost::uint32_t usrp_e100_dboard_iface::read_write_spi(
@@ -253,7 +253,7 @@ boost::uint32_t usrp_e100_dboard_iface::read_write_spi(
boost::uint32_t data,
size_t num_bits
){
- return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/);
+ return _iface->read_spi(unit_to_otw_spi_dev(unit), config, data, num_bits);
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp
index b533c2657..0b89fed9f 100644
--- a/host/lib/usrp/usrp_e100/dboard_impl.cpp
+++ b/host/lib/usrp/usrp_e100/dboard_impl.cpp
@@ -17,7 +17,7 @@
#include "usrp_e100_impl.hpp"
#include "usrp_e100_regs.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/usrp/dboard_props.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/misc_utils.hpp>
diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp
index 7d358a607..8d084f066 100644
--- a/host/lib/usrp/usrp_e100/dsp_impl.cpp
+++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -60,10 +60,6 @@ void usrp_e100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){
val = _ddc_freq;
return;
- case DSP_PROP_FREQ_SHIFT_NAMES:
- val = prop_names_t(1, "");
- return;
-
case DSP_PROP_CODEC_RATE:
val = _clock_ctrl->get_fpga_clock_rate();
return;
@@ -84,6 +80,10 @@ void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){
switch(key.as<dsp_prop_t>()){
+ case DSP_PROP_STREAM_CMD:
+ issue_stream_cmd(val.as<stream_cmd_t>());
+ return;
+
case DSP_PROP_FREQ_SHIFT:{
double new_freq = val.as<double>();
_iface->poke32(UE_REG_DSP_RX_FREQ,
@@ -143,10 +143,6 @@ void usrp_e100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){
val = _duc_freq;
return;
- case DSP_PROP_FREQ_SHIFT_NAMES:
- val = prop_names_t(1, "");
- return;
-
case DSP_PROP_CODEC_RATE:
val = _clock_ctrl->get_fpga_clock_rate();
return;
diff --git a/host/lib/usrp/usrp_e100/fpga_downloader.cpp b/host/lib/usrp/usrp_e100/fpga_downloader.cpp
index c0013fcbd..018a120d6 100644
--- a/host/lib/usrp/usrp_e100/fpga_downloader.cpp
+++ b/host/lib/usrp/usrp_e100/fpga_downloader.cpp
@@ -16,14 +16,21 @@
//
#include <uhd/config.hpp>
-#include <uhd/utils/assert.hpp>
+#ifdef UHD_DLL_EXPORTS
+#include <uhd/exception.hpp>
+#else //special case when this file is externally included
+#include <stdexcept>
+namespace uhd{
+ typedef std::runtime_error os_error;
+ typedef std::runtime_error io_error;
+}
+#endif
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
-#include <stdexcept>
#include <fcntl.h>
#include <sys/types.h>
@@ -88,7 +95,7 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction)
std::fstream export_file;
export_file.open("/sys/class/gpio/export", std::ios::out);
- if (not export_file.is_open()) throw std::runtime_error(
+ if (not export_file.is_open()) throw uhd::os_error(
"Failed to open gpio export file."
);
@@ -212,7 +219,7 @@ static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &d
std::ifstream bitstream;
bitstream.open(file_name.c_str(), std::ios::binary);
- if (!bitstream.is_open()) throw std::runtime_error(
+ if (!bitstream.is_open()) throw uhd::os_error(
"Coult not open the file: " + file_name
);
diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp
index 0e08cd435..cec4fd0ad 100644
--- a/host/lib/usrp/usrp_e100/mboard_impl.cpp
+++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp
@@ -17,9 +17,9 @@
#include "usrp_e100_impl.hpp"
#include "usrp_e100_regs.hpp"
+#include <uhd/exception.hpp>
#include <uhd/usrp/dsp_utils.hpp>
#include <uhd/usrp/misc_utils.hpp>
-#include <uhd/utils/assert.hpp>
#include <uhd/usrp/mboard_props.hpp>
#include <boost/bind.hpp>
#include <iostream>
@@ -53,7 +53,7 @@ void usrp_e100_impl::update_clock_config(void){
switch(_clock_config.pps_polarity){
case clock_config_t::PPS_POS: pps_flags |= UE_FLAG_TIME64_PPS_POSEDGE; break;
case clock_config_t::PPS_NEG: pps_flags |= UE_FLAG_TIME64_PPS_NEGEDGE; break;
- default: throw std::runtime_error("unhandled clock configuration pps polarity");
+ default: throw uhd::value_error("unhandled clock configuration pps polarity");
}
//set the pps flags
@@ -64,7 +64,7 @@ void usrp_e100_impl::update_clock_config(void){
case clock_config_t::REF_AUTO: _clock_ctrl->use_auto_ref(); break;
case clock_config_t::REF_INT: _clock_ctrl->use_internal_ref(); break;
case clock_config_t::REF_SMA: _clock_ctrl->use_auto_ref(); break;
- default: throw std::runtime_error("unhandled clock configuration ref source");
+ default: throw uhd::value_error("unhandled clock configuration ref source");
}
}
@@ -167,10 +167,6 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){
//handle the get request conditioned on the key
switch(key.as<mboard_prop_t>()){
- case MBOARD_PROP_STREAM_CMD:
- issue_stream_cmd(val.as<stream_cmd_t>());
- return;
-
case MBOARD_PROP_TIME_NOW:
case MBOARD_PROP_TIME_PPS:{
time_spec_t time_spec = val.as<time_spec_t>();
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
index c13e880f3..ec0baf490 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
@@ -17,7 +17,7 @@
#include "usrp_e100_iface.hpp"
#include "usrp_e100_regs.hpp"
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <sys/ioctl.h> //ioctl
#include <fcntl.h> //open, close
#include <linux/usrp_e.h> //ioctl structures and constants
@@ -37,7 +37,7 @@ class i2c_dev_iface : public i2c_iface{
public:
i2c_dev_iface(const std::string &node){
if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){
- throw std::runtime_error("Failed to open " + node);
+ throw uhd::io_error("Failed to open " + node);
}
}
@@ -106,12 +106,9 @@ public:
{
//open the device node and check file descriptor
if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){
- throw std::runtime_error("Failed to open " + node);
+ throw uhd::io_error("Failed to open " + node);
}
- //very first thing, reset all the wishbone, always do first!
- //disabled for now: this->poke32(UE_REG_CLEAR_GLOBAL, 0);
-
mb_eeprom = mboard_eeprom_t(get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100);
}
@@ -127,7 +124,7 @@ public:
boost::mutex::scoped_lock lock(_ctrl_mutex);
if (::ioctl(_node_fd, request, mem) < 0){
- throw std::runtime_error(str(
+ throw uhd::os_error(str(
boost::format("ioctl failed with request %d") % request
));
}
@@ -257,6 +254,14 @@ public:
//unload the data
return data.data;
}
+
+ void write_uart(boost::uint8_t, const std::string &) {
+ throw uhd::not_implemented_error("Unhandled command write_uart()");
+ }
+
+ std::string read_uart(boost::uint8_t) {
+ throw uhd::not_implemented_error("Unhandled command read_uart()");
+ }
private:
int _node_fd;
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
index 12283fb52..cb0ca2dd4 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
@@ -24,6 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/cstdint.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
////////////////////////////////////////////////////////////////////////
// I2C addresses
@@ -39,7 +40,7 @@
* Provides a set of functions to implementation layer.
* Including spi, peek, poke, control...
*/
-class usrp_e100_iface : boost::noncopyable, public uhd::i2c_iface{
+class usrp_e100_iface : boost::noncopyable, public uhd::usrp::mboard_iface{
public:
typedef boost::shared_ptr<usrp_e100_iface> sptr;
@@ -67,51 +68,6 @@ public:
//! Get the I2C interface for the I2C device node
virtual uhd::i2c_iface &get_i2c_dev_iface(void) = 0;
- /*!
- * Write a register (32 bits)
- * \param addr the address
- * \param data the 32bit data
- */
- virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0;
-
- /*!
- * Read a register (32 bits)
- * \param addr the address
- * \return the 32bit data
- */
- virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
-
- /*!
- * Write a register (16 bits)
- * \param addr the address
- * \param data the 16bit data
- */
- virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0;
-
- /*!
- * Read a register (16 bits)
- * \param addr the address
- * \return the 16bit data
- */
- virtual boost::uint16_t peek16(boost::uint32_t addr) = 0;
-
- /*!
- * Perform an spi transaction.
- * \param which_slave the slave device number
- * \param config spi config args
- * \param data the bits to write
- * \param num_bits how many bits in data
- * \param readback true to readback a value
- * \return spi data if readback set
- */
- virtual boost::uint32_t transact_spi(
- int which_slave,
- const uhd::spi_config_t &config,
- boost::uint32_t data,
- size_t num_bits,
- bool readback
- ) = 0;
-
//motherboard eeprom map structure
uhd::usrp::mboard_eeprom_t mb_eeprom;
};
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
index f430090f0..a120c3303 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
#include "usrp_e100_regs.hpp"
#include <uhd/usrp/device_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/images.hpp>
#include <uhd/utils/warning.hpp>
@@ -103,7 +103,7 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){
size_t fpga_hash = 0;
{
std::ifstream file(usrp_e100_fpga_image.c_str());
- if (not file.good()) throw std::runtime_error(
+ if (not file.good()) throw uhd::io_error(
"cannot open fpga file for read: " + usrp_e100_fpga_image
);
do{
@@ -132,7 +132,7 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){
//check that the compatibility is correct
fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT);
if (fpga_compat_num != USRP_E_COMPAT_NUM){
- throw std::runtime_error(str(boost::format(
+ throw uhd::runtime_error(str(boost::format(
"Expected fpga compatibility number 0x%x, but got 0x%x:\n"
"The fpga build is not compatible with the host code build."
) % USRP_E_COMPAT_NUM % fpga_compat_num));
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp
index c155d426a..f4274dc5a 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp
@@ -17,7 +17,7 @@
#include "usrp_e100_iface.hpp"
#include <uhd/transport/zero_copy.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <linux/usrp_e.h>
#include <sys/mman.h> //mmap
#include <unistd.h> //getpagesize
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp
index a030462d0..1bcae64c7 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp
@@ -131,7 +131,6 @@
#define UE_REG_CLEAR_ADDR(n) (UE_REG_SETTINGS_BASE_ADDR(48) + (4*(n)))
#define UE_REG_CLEAR_RX UE_REG_CLEAR_ADDR(0)
#define UE_REG_CLEAR_TX UE_REG_CLEAR_ADDR(1)
-#define UE_REG_CLEAR_GLOBAL UE_REG_CLEAR_ADDR(2)
/////////////////////////////////////////////////
// DSP RX Regs
diff --git a/host/lib/usrp/wrapper_utils.hpp b/host/lib/usrp/wrapper_utils.hpp
deleted file mode 100644
index a7b5c5da6..000000000
--- a/host/lib/usrp/wrapper_utils.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// 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_USRP_WRAPPER_UTILS_HPP
-#define INCLUDED_LIBUHD_USRP_WRAPPER_UTILS_HPP
-
-#include <uhd/wax.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/usrp/dsp_props.hpp>
-#include <uhd/utils/warning.hpp>
-#include <boost/format.hpp>
-#include <cmath>
-
-static inline uhd::freq_range_t add_dsp_shift(
- const uhd::freq_range_t &range,
- wax::obj dsp
-){
- double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as<double>();
- return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0);
-}
-
-static inline void do_samp_rate_warning_message(
- double target_rate,
- double actual_rate,
- const std::string &xx
-){
- static const double max_allowed_error = 1.0; //Sps
- if (std::abs(target_rate - actual_rate) > max_allowed_error){
- uhd::warning::post(str(boost::format(
- "The hardware does not support the requested %s sample rate:\n"
- "Target sample rate: %f MSps\n"
- "Actual sample rate: %f MSps\n"
- ) % xx % (target_rate/1e6) % (actual_rate/1e6)));
- }
-}
-
-static inline void do_tune_freq_warning_message(
- double target_freq,
- double actual_freq,
- const std::string &xx
-){
- static const double max_allowed_error = 1.0; //Hz
- if (std::abs(target_freq - actual_freq) > max_allowed_error){
- uhd::warning::post(str(boost::format(
- "The hardware does not support the requested %s frequency:\n"
- "Target frequency: %f MHz\n"
- "Actual frequency: %f MHz\n"
- ) % xx % (target_freq/1e6) % (actual_freq/1e6)));
- }
-}
-
-#endif /* INCLUDED_LIBUHD_USRP_WRAPPER_UTILS_HPP */
diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt
index a4d3b2db2..c0d99b37e 100644
--- a/host/lib/utils/CMakeLists.txt
+++ b/host/lib/utils/CMakeLists.txt
@@ -110,7 +110,6 @@ SET_SOURCE_FILES_PROPERTIES(
# Append sources
########################################################################
LIBUHD_APPEND_SOURCES(
- ${CMAKE_CURRENT_SOURCE_DIR}/assert.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp
${CMAKE_CURRENT_SOURCE_DIR}/images.cpp
${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp
diff --git a/host/lib/utils/assert.cpp b/host/lib/utils/assert.cpp
deleted file mode 100644
index 7ace9024c..000000000
--- a/host/lib/utils/assert.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// 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
index 07aa21115..3af8a543d 100644
--- a/host/lib/utils/gain_group.cpp
+++ b/host/lib/utils/gain_group.cpp
@@ -18,7 +18,7 @@
#include <uhd/utils/gain_group.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/utils/algorithm.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <algorithm>
@@ -107,7 +107,7 @@ public:
double 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(floor_step(std::clip(
+ gain_bucket.push_back(floor_step(uhd::clip(
gain_left_to_distribute, range.start(), range.stop()
), max_step));
gain_left_to_distribute -= gain_bucket.back();
@@ -131,7 +131,7 @@ public:
//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();
- double additional_gain = floor_step(std::clip(
+ double additional_gain = floor_step(uhd::clip(
gain_bucket.at(i) + gain_left_to_distribute, range.start(), range.stop()
), range.step()) - gain_bucket.at(i);
gain_bucket.at(i) += additional_gain;
@@ -167,7 +167,7 @@ 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())){
+ BOOST_FOREACH(size_t key, uhd::sorted(_registry.keys())){
const std::vector<gain_fcns_t> &fcns = _registry[key];
all_fcns.insert(all_fcns.begin(), fcns.begin(), fcns.end());
}
diff --git a/host/lib/utils/images.cpp b/host/lib/utils/images.cpp
index 24a599322..2b6c02772 100644
--- a/host/lib/utils/images.cpp
+++ b/host/lib/utils/images.cpp
@@ -16,9 +16,9 @@
//
#include <uhd/utils/images.hpp>
+#include <uhd/exception.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
-#include <stdexcept>
#include <vector>
namespace fs = boost::filesystem;
@@ -36,5 +36,5 @@ std::string uhd::find_image_path(const std::string &image_name){
fs::path image_path = path / image_name;
if (fs::exists(image_path)) return image_path.string();
}
- throw std::runtime_error("Could not find path for image: " + image_name);
+ throw uhd::io_error("Could not find path for image: " + image_name);
}
diff --git a/host/lib/utils/load_modules.cpp b/host/lib/utils/load_modules.cpp
index 33152855a..bee0d5304 100644
--- a/host/lib/utils/load_modules.cpp
+++ b/host/lib/utils/load_modules.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,11 +16,11 @@
//
#include <uhd/utils/static.hpp>
+#include <uhd/exception.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
-#include <stdexcept>
#include <string>
#include <vector>
@@ -33,7 +33,7 @@ namespace fs = boost::filesystem;
#include <dlfcn.h>
static void load_module(const std::string &file_name){
if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){
- throw std::runtime_error(str(
+ throw uhd::os_error(str(
boost::format("dlopen failed to load \"%s\"") % file_name
));
}
@@ -45,7 +45,7 @@ static void load_module(const std::string &file_name){
#include <windows.h>
static void load_module(const std::string &file_name){
if (LoadLibrary(file_name.c_str()) == NULL){
- throw std::runtime_error(str(
+ throw uhd::os_error(str(
boost::format("LoadLibrary failed to load \"%s\"") % file_name
));
}
@@ -55,7 +55,7 @@ static void load_module(const std::string &file_name){
#ifdef HAVE_LOAD_MODULES_DUMMY
static void load_module(const std::string &file_name){
- throw std::runtime_error(str(
+ throw uhd::not_implemented_error(str(
boost::format("Module loading not supported: Cannot load \"%s\"") % file_name
));
}
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
index 8d604d849..329695873 100644
--- a/host/lib/utils/paths.cpp
+++ b/host/lib/utils/paths.cpp
@@ -22,7 +22,6 @@
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-#include <stdexcept>
#include <string>
#include <vector>
diff --git a/host/lib/utils/thread_priority.cpp b/host/lib/utils/thread_priority.cpp
index 18f372ec0..bd34055e8 100644
--- a/host/lib/utils/thread_priority.cpp
+++ b/host/lib/utils/thread_priority.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -17,8 +17,8 @@
#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/warning.hpp>
+#include <uhd/exception.hpp>
#include <boost/format.hpp>
-#include <stdexcept>
#include <iostream>
bool uhd::set_thread_priority_safe(float priority, bool realtime){
@@ -59,13 +59,13 @@ static void check_priority_range(float priority){
//get the priority bounds for the selected policy
int min_pri = sched_get_priority_min(policy);
int max_pri = sched_get_priority_max(policy);
- if (min_pri == -1 or max_pri == -1) throw std::runtime_error("error in sched_get_priority_min/max");
+ if (min_pri == -1 or max_pri == -1) throw uhd::os_error("error in sched_get_priority_min/max");
//set the new priority and policy
sched_param sp;
sp.sched_priority = int(priority*(max_pri - min_pri)) + min_pri;
int ret = pthread_setschedparam(pthread_self(), policy, &sp);
- if (ret != 0) throw std::runtime_error("error in pthread_setschedparam");
+ if (ret != 0) throw uhd::os_error("error in pthread_setschedparam");
}
#endif /* HAVE_PTHREAD_SETSCHEDPARAM */
@@ -81,7 +81,7 @@ static void check_priority_range(float priority){
//set the priority class on the process
int pri_class = (realtime)? REALTIME_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0)
- throw std::runtime_error("error in SetPriorityClass");
+ throw uhd::os_error("error in SetPriorityClass");
//scale the priority value to the constants
int priorities[] = {
@@ -92,7 +92,7 @@ static void check_priority_range(float priority){
//set the thread priority on the thread
if (SetThreadPriority(GetCurrentThread(), priorities[pri_index]) == 0)
- throw std::runtime_error("error in SetThreadPriority");
+ throw uhd::os_error("error in SetThreadPriority");
}
#endif /* HAVE_WIN_SETTHREADPRIORITY */
@@ -101,7 +101,7 @@ static void check_priority_range(float priority){
**********************************************************************/
#ifdef HAVE_LOAD_MODULES_DUMMY
void uhd::set_thread_priority(float, bool){
- throw std::runtime_error("set thread priority not implemented");
+ throw uhd::not_implemented_error("set thread priority not implemented");
}
#endif /* HAVE_LOAD_MODULES_DUMMY */
diff --git a/host/lib/utils/warning.cpp b/host/lib/utils/warning.cpp
index bc4c79b6e..6a94a0a2c 100644
--- a/host/lib/utils/warning.cpp
+++ b/host/lib/utils/warning.cpp
@@ -16,12 +16,12 @@
//
#include <uhd/utils/warning.hpp>
+#include <uhd/exception.hpp>
#include <boost/tokenizer.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/types/dict.hpp>
#include <boost/foreach.hpp>
#include <sstream>
-#include <stdexcept>
#include <iostream>
#include <vector>
@@ -76,7 +76,7 @@ void warning::register_handler(
}
warning::handler_t warning::unregister_handler(const std::string &name){
- if (not get_registry().has_key(name)) throw std::runtime_error(
+ if (not get_registry().has_key(name)) throw uhd::key_error(
"The warning registry does not have a handler registered to " + name
);
return get_registry().pop(name);
diff --git a/host/lib/wax.cpp b/host/lib/wax.cpp
index 0e2e82a3a..5f658acd8 100644
--- a/host/lib/wax.cpp
+++ b/host/lib/wax.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
//
#include <uhd/wax.hpp>
+#include <uhd/exception.hpp>
#include <boost/format.hpp>
#include <stdexcept>
@@ -97,7 +98,7 @@ wax::obj wax::obj::operator[](const obj &key){
return val.as<link_args_t>()()[key];
}
//unknown obj
- throw std::runtime_error("cannot use [] on non wax::obj link");
+ throw uhd::type_error("cannot use [] on non wax::obj link");
}
else{
return proxy_args_t(this, key);
@@ -142,9 +143,9 @@ boost::any wax::obj::resolve(void) const{
}
void wax::obj::get(const obj &, obj &){
- throw std::runtime_error("Cannot call get on wax obj base class");
+ throw uhd::type_error("Cannot call get on wax obj base class");
}
void wax::obj::set(const obj &, const obj &){
- throw std::runtime_error("Cannot call set on wax obj base class");
+ throw uhd::type_error("Cannot call set on wax obj base class");
}
diff --git a/host/tests/error_test.cpp b/host/tests/error_test.cpp
index c76a15ab7..983f0150c 100644
--- a/host/tests/error_test.cpp
+++ b/host/tests/error_test.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,19 +16,30 @@
//
#include <boost/test/unit_test.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <vector>
#include <iostream>
+BOOST_AUTO_TEST_CASE(test_exception_methods){
+ try{
+ throw uhd::assertion_error("your assertion failed: 1 != 2");
+ }
+ catch(const uhd::exception &e){
+ std::cout << "what: " << e.what() << std::endl;
+ std::cout << "code: " << e.code() << std::endl;
+ }
+}
+
BOOST_AUTO_TEST_CASE(test_assert_has){
std::vector<int> vec;
vec.push_back(2);
vec.push_back(3);
vec.push_back(5);
- //verify the std::has utility
- BOOST_CHECK(std::has(vec, 2));
- BOOST_CHECK(not std::has(vec, 1));
+ //verify the uhd::has utility
+ BOOST_CHECK(uhd::has(vec, 2));
+ BOOST_CHECK(not uhd::has(vec, 1));
std::cout << "The output of the assert_has error:" << std::endl;
try{
diff --git a/host/tests/tune_helper_test.cpp b/host/tests/tune_helper_test.cpp
index 735e7e948..aabaaaf6e 100644
--- a/host/tests/tune_helper_test.cpp
+++ b/host/tests/tune_helper_test.cpp
@@ -153,10 +153,6 @@ private:
val = _freq_shift;
return;
- case DSP_PROP_FREQ_SHIFT_NAMES:
- val = prop_names_t(1, "");
- return;
-
default: UHD_THROW_PROP_GET_ERROR();
}
}
@@ -190,12 +186,12 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx){
dummy_dsp dsp(100e6);
std::cout << "Testing tune helper RX automatic IF offset" << std::endl;
- tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9);
+ tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.3451e9);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance);
BOOST_CHECK_CLOSE(tr.actual_dsp_freq, -100e3, tolerance);
- double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0);
+ double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link());
BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance);
}
@@ -204,12 +200,12 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_tx){
dummy_dsp dsp(100e6);
std::cout << "Testing tune helper TX automatic IF offset" << std::endl;
- tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9);
+ tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.3451e9);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance);
BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 100e3, tolerance);
- double freq_derived = derive_freq_from_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0);
+ double freq_derived = derive_freq_from_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link());
BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance);
}
@@ -218,12 +214,12 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx_nyquist){
dummy_dsp dsp(100e6);
std::cout << "Testing tune helper RX dummy basic board" << std::endl;
- tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 55e6);
+ tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 55e6);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 0.0, tolerance);
BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 45e6, tolerance);
- double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0);
+ double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link());
BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance);
}
@@ -235,21 +231,21 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx_lo_off){
std::cout << "Testing tune helper RX automatic LO offset B >> fs" << std::endl;
subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6);
dsp[DSP_PROP_HOST_RATE] = double(4e6);
- tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9);
+ tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.45e9);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+4e6/2, tolerance);
std::cout << "Testing tune helper RX automatic LO offset B > fs" << std::endl;
subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6);
dsp[DSP_PROP_HOST_RATE] = double(25e6);
- tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9);
+ tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.45e9);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+(40e6-25e6)/2, tolerance);
std::cout << "Testing tune helper RX automatic LO offset B < fs" << std::endl;
subdev[SUBDEV_PROP_BANDWIDTH] = double(20e6);
dsp[DSP_PROP_HOST_RATE] = double(25e6);
- tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9);
+ tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.45e9);
std::cout << tr.to_pp_string() << std::endl;
BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9, tolerance);
}
diff --git a/host/tests/wax_test.cpp b/host/tests/wax_test.cpp
index 731f470ed..18730e0c2 100644
--- a/host/tests/wax_test.cpp
+++ b/host/tests/wax_test.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010-2011 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
@@ -25,7 +25,7 @@ enum opt_b_t{OPTION_B_0, OPTION_B_1};
BOOST_AUTO_TEST_CASE(test_enums){
wax::obj opta = OPTION_A_0;
- BOOST_CHECK_THROW(opta.as<opt_b_t>(), wax::bad_cast);
+ BOOST_CHECK_THROW(opta.as<opt_b_t>(), std::exception);
BOOST_CHECK_EQUAL(opta.as<opt_a_t>(), OPTION_A_0);
}
diff --git a/host/usrp_e_utils/CMakeLists.txt b/host/usrp_e_utils/CMakeLists.txt
index 1ecd2ac46..f3537e542 100644
--- a/host/usrp_e_utils/CMakeLists.txt
+++ b/host/usrp_e_utils/CMakeLists.txt
@@ -37,6 +37,7 @@ IF(ENABLE_USRP_E_UTILS)
usrp-e-timed.c
usrp-e-wb-test.cpp
usrp-e-debug-pins.c
+ usrp-e-gpio.c
usrp-e-i2c.c
usrp-e-spi.c
)
diff --git a/host/apps/omap_debug/usrp-e-gpio.c b/host/usrp_e_utils/usrp-e-gpio.c
index adef877d3..7e4bc4e13 100644
--- a/host/apps/omap_debug/usrp-e-gpio.c
+++ b/host/usrp_e_utils/usrp-e-gpio.c
@@ -6,8 +6,8 @@
#include <string.h>
#include <sys/ioctl.h>
-#include "usrp_e.h"
-#include "usrp_e_regs.hpp"
+#include "linux/usrp_e.h"
+#include "usrp_e100_regs.hpp"
// Usage: usrp_e_gpio <string>
diff --git a/host/usrp_e_utils/usrp-e-loopback.c b/host/usrp_e_utils/usrp-e-loopback.c
index a63882475..0bd3d3100 100644
--- a/host/usrp_e_utils/usrp-e-loopback.c
+++ b/host/usrp_e_utils/usrp-e-loopback.c
@@ -38,11 +38,15 @@ static int calc_checksum(struct pkt *p)
i = 0;
sum = 0;
- for (i=0; i < p->len; i++)
- sum += p->data[i];
-
- sum += p->seq_num;
- sum += p->len;
+ if (p->len < 1016) {
+ for (i=0; i < p->len; i++)
+ sum += p->data[i];
+
+ sum += p->seq_num;
+ sum += p->len;
+ } else {
+ printf("Bad packet length = %d received.\n", p->len);
+ }
return sum;
}
@@ -212,6 +216,11 @@ int main(int argc, char *argv[])
packet_data_length = atoi(argv[1]);
+ if (packet_data_length > 1016) {
+ packet_data_length = 1016;
+ printf("Max data length = 1016, clamping.\n");
+ }
+
fp = open("/dev/usrp_e0", O_RDWR);
printf("fp = %d\n", fp);
diff --git a/host/utils/usrp_burn_db_eeprom.cpp b/host/utils/usrp_burn_db_eeprom.cpp
index ac5608f22..617417e09 100644
--- a/host/utils/usrp_burn_db_eeprom.cpp
+++ b/host/utils/usrp_burn_db_eeprom.cpp
@@ -19,7 +19,7 @@
#include <uhd/utils/safe_main.hpp>
#include <uhd/device.hpp>
#include <uhd/types/dict.hpp>
-#include <uhd/utils/assert.hpp>
+#include <uhd/utils/assert_has.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/device_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
diff --git a/images/CMakeLists.txt b/images/CMakeLists.txt
index 705153baf..baac333ea 100644
--- a/images/CMakeLists.txt
+++ b/images/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2010 Ettus Research LLC
+# Copyright 2010-2011 Ettus Research LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@ 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})
+SET(CPACK_PACKAGE_FILE_NAME "UHD-images-${UHD_VERSION_MAJOR}-${UHD_VERSION_MINOR}-${UHD_VERSION_PATCH}")
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "all")
INCLUDE(CPack) #include after setting vars
MESSAGE(STATUS "Version: ${CPACK_PACKAGE_VERSION}")