diff options
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}")  | 
