summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-06-15 14:50:02 -0700
committerJosh Blum <josh@joshknows.com>2011-06-15 14:50:02 -0700
commit0cef788d3d34a298c975e32c488e800a5c65ccce (patch)
tree14b7f4242a28927b1701a73a3e8ec0df3fa04811
parent7951170c6161d9266726ec19e8c009500cf11f75 (diff)
parent27f1622d439ceb787e7dada733d0eb82270c5532 (diff)
downloaduhd-0cef788d3d34a298c975e32c488e800a5c65ccce.tar.gz
uhd-0cef788d3d34a298c975e32c488e800a5c65ccce.tar.bz2
uhd-0cef788d3d34a298c975e32c488e800a5c65ccce.zip
Merge branch 'next'
-rw-r--r--firmware/fx2/CMakeLists.txt2
-rw-r--r--firmware/fx2/b100/.gitignore19
-rw-r--r--firmware/fx2/b100/CMakeLists.txt88
-rw-r--r--firmware/fx2/b100/board_specific.c70
-rw-r--r--firmware/fx2/b100/eeprom_io.c65
-rw-r--r--firmware/fx2/b100/eeprom_io.h38
-rw-r--r--firmware/fx2/b100/fpga_load.c193
-rw-r--r--firmware/fx2/b100/fpga_rev2.c51
-rw-r--r--firmware/fx2/b100/fpga_rev2.h44
-rw-r--r--firmware/fx2/b100/gpif.c292
-rw-r--r--firmware/fx2/b100/usb_descriptors.a51499
-rw-r--r--firmware/fx2/b100/usrp_common.c108
-rw-r--r--firmware/fx2/b100/usrp_main.c394
-rw-r--r--firmware/fx2/b100/usrp_regs.h126
-rw-r--r--firmware/fx2/common/fx2regs.h4
-rw-r--r--firmware/fx2/common/usrp_commands.h6
-rwxr-xr-xfirmware/fx2/utils/build_eeprom.py12
-rwxr-xr-xfirmware/fx2/utils/edit-gpif-b100.py120
-rw-r--r--fpga/usrp2/control_lib/Makefile.srcs1
-rw-r--r--fpga/usrp2/control_lib/atr_controller.v17
-rw-r--r--fpga/usrp2/control_lib/atr_controller16.v17
-rw-r--r--fpga/usrp2/control_lib/bin2gray.v17
-rw-r--r--fpga/usrp2/control_lib/bootram.v17
-rw-r--r--fpga/usrp2/control_lib/clock_bootstrap_rom.v17
-rw-r--r--fpga/usrp2/control_lib/clock_control.v17
-rw-r--r--fpga/usrp2/control_lib/clock_control_tb.v17
-rw-r--r--fpga/usrp2/control_lib/dcache.v17
-rw-r--r--fpga/usrp2/control_lib/decoder_3_8.v17
-rw-r--r--fpga/usrp2/control_lib/dpram32.v17
-rw-r--r--fpga/usrp2/control_lib/fifo_tb.v151
-rw-r--r--fpga/usrp2/control_lib/fifo_to_wb.v183
-rw-r--r--fpga/usrp2/control_lib/fifo_to_wb_tb.v136
-rw-r--r--fpga/usrp2/control_lib/gray2bin.v17
-rw-r--r--fpga/usrp2/control_lib/gray_send.v17
-rw-r--r--fpga/usrp2/control_lib/icache.v17
-rw-r--r--fpga/usrp2/control_lib/longfifo.v17
-rw-r--r--fpga/usrp2/control_lib/medfifo.v17
-rw-r--r--fpga/usrp2/control_lib/mux4.v17
-rw-r--r--fpga/usrp2/control_lib/mux8.v17
-rw-r--r--fpga/usrp2/control_lib/mux_32_4.v17
-rw-r--r--fpga/usrp2/control_lib/oneshot_2clk.v17
-rw-r--r--fpga/usrp2/control_lib/priority_enc.v17
-rw-r--r--fpga/usrp2/control_lib/quad_uart.v17
-rw-r--r--fpga/usrp2/control_lib/ram_2port.v17
-rw-r--r--fpga/usrp2/control_lib/ram_2port_mixed_width.v17
-rw-r--r--fpga/usrp2/control_lib/ram_harv_cache.v17
-rw-r--r--fpga/usrp2/control_lib/ram_harvard.v17
-rw-r--r--fpga/usrp2/control_lib/ram_harvard2.v17
-rw-r--r--fpga/usrp2/control_lib/ram_loader.v17
-rw-r--r--fpga/usrp2/control_lib/ram_wb_harvard.v17
-rw-r--r--fpga/usrp2/control_lib/reset_sync.v17
-rw-r--r--fpga/usrp2/control_lib/s3a_icap_wb.v17
-rw-r--r--fpga/usrp2/control_lib/sd_spi.v17
-rw-r--r--fpga/usrp2/control_lib/sd_spi_tb.v17
-rw-r--r--fpga/usrp2/control_lib/sd_spi_wb.v17
-rw-r--r--fpga/usrp2/control_lib/setting_reg.v17
-rw-r--r--fpga/usrp2/control_lib/settings_bus.v17
-rw-r--r--fpga/usrp2/control_lib/settings_bus_16LE.v17
-rw-r--r--fpga/usrp2/control_lib/settings_bus_crossclock.v17
-rw-r--r--fpga/usrp2/control_lib/shortfifo.v17
-rw-r--r--fpga/usrp2/control_lib/simple_uart.v17
-rw-r--r--fpga/usrp2/control_lib/simple_uart_rx.v17
-rw-r--r--fpga/usrp2/control_lib/simple_uart_tx.v17
-rw-r--r--fpga/usrp2/control_lib/spi.v17
-rw-r--r--fpga/usrp2/control_lib/srl.v17
-rw-r--r--fpga/usrp2/control_lib/ss_rcvr.v17
-rw-r--r--fpga/usrp2/control_lib/system_control.v17
-rw-r--r--fpga/usrp2/control_lib/system_control_tb.v17
-rw-r--r--fpga/usrp2/control_lib/traffic_cop.v17
-rw-r--r--fpga/usrp2/control_lib/v5icap_wb.v17
-rw-r--r--fpga/usrp2/control_lib/wb_bridge_16_32.v17
-rw-r--r--fpga/usrp2/control_lib/wb_bus_writer.v17
-rw-r--r--fpga/usrp2/control_lib/wb_output_pins32.v17
-rw-r--r--fpga/usrp2/control_lib/wb_ram_block.v17
-rw-r--r--fpga/usrp2/control_lib/wb_ram_dist.v17
-rw-r--r--fpga/usrp2/control_lib/wb_readback_mux.v17
-rw-r--r--fpga/usrp2/control_lib/wb_readback_mux_16LE.v17
-rw-r--r--fpga/usrp2/control_lib/wb_regfile_2clock.v17
-rw-r--r--fpga/usrp2/control_lib/wb_semaphore.v17
-rw-r--r--fpga/usrp2/control_lib/wb_sim.v17
-rw-r--r--fpga/usrp2/extramfifo/ext_fifo.v17
-rw-r--r--fpga/usrp2/extramfifo/ext_fifo_tb.v17
-rw-r--r--fpga/usrp2/extramfifo/nobl_fifo.v17
-rw-r--r--fpga/usrp2/extramfifo/nobl_if.v17
-rw-r--r--fpga/usrp2/extramfifo/refill_randomizer.v17
-rw-r--r--fpga/usrp2/extramfifo/test_sram_if.v17
-rw-r--r--fpga/usrp2/fifo/Makefile.srcs2
-rw-r--r--fpga/usrp2/fifo/buffer_int.v17
-rw-r--r--fpga/usrp2/fifo/buffer_int2.v17
-rw-r--r--fpga/usrp2/fifo/buffer_int_tb.v17
-rw-r--r--fpga/usrp2/fifo/buffer_pool.v17
-rw-r--r--fpga/usrp2/fifo/buffer_pool_tb.v17
-rw-r--r--fpga/usrp2/fifo/crossbar36.v17
-rw-r--r--fpga/usrp2/fifo/dsp_framer36.v17
-rw-r--r--fpga/usrp2/fifo/fifo19_mux.v94
-rw-r--r--fpga/usrp2/fifo/fifo19_pad.v83
-rw-r--r--fpga/usrp2/fifo/fifo19_to_fifo36.v17
-rw-r--r--fpga/usrp2/fifo/fifo19_to_ll8.v17
-rw-r--r--fpga/usrp2/fifo/fifo36_demux.v17
-rw-r--r--fpga/usrp2/fifo/fifo36_mux.v17
-rw-r--r--fpga/usrp2/fifo/fifo36_to_fifo19.v17
-rw-r--r--fpga/usrp2/fifo/fifo36_to_fifo72.v17
-rw-r--r--fpga/usrp2/fifo/fifo36_to_ll8.v17
-rw-r--r--fpga/usrp2/fifo/fifo72_to_fifo36.v17
-rw-r--r--fpga/usrp2/fifo/fifo_19to36_tb.v17
-rw-r--r--fpga/usrp2/fifo/fifo_2clock.v36
-rw-r--r--fpga/usrp2/fifo/fifo_2clock_cascade.v17
-rw-r--r--fpga/usrp2/fifo/fifo_cascade.v17
-rw-r--r--fpga/usrp2/fifo/fifo_long.v17
-rw-r--r--fpga/usrp2/fifo/fifo_pacer.v17
-rw-r--r--fpga/usrp2/fifo/fifo_short.v17
-rw-r--r--fpga/usrp2/fifo/fifo_tb.v17
-rw-r--r--fpga/usrp2/fifo/ll8_shortfifo.v17
-rw-r--r--fpga/usrp2/fifo/ll8_to_fifo19.v17
-rw-r--r--fpga/usrp2/fifo/ll8_to_fifo36.v17
-rw-r--r--fpga/usrp2/fifo/packet32_tb.v17
-rw-r--r--fpga/usrp2/fifo/packet_generator.v17
-rw-r--r--fpga/usrp2/fifo/packet_generator32.v17
-rw-r--r--fpga/usrp2/fifo/packet_router.v17
-rw-r--r--fpga/usrp2/fifo/packet_tb.v17
-rw-r--r--fpga/usrp2/fifo/packet_verifier.v17
-rw-r--r--fpga/usrp2/fifo/packet_verifier32.v17
-rw-r--r--fpga/usrp2/fifo/splitter36.v17
-rw-r--r--fpga/usrp2/fifo/valve36.v17
-rw-r--r--fpga/usrp2/gpif/Makefile.srcs14
-rw-r--r--fpga/usrp2/gpif/gpif.v257
-rw-r--r--fpga/usrp2/gpif/gpif_rd.v111
-rw-r--r--fpga/usrp2/gpif/gpif_tb.v142
-rw-r--r--fpga/usrp2/gpif/gpif_wr.v95
-rw-r--r--fpga/usrp2/gpif/gpif_wr_tb.v110
-rw-r--r--fpga/usrp2/gpif/packet_reframer.v79
-rw-r--r--fpga/usrp2/gpif/packet_splitter.v123
-rw-r--r--fpga/usrp2/gpif/packet_splitter_tb.v137
-rw-r--r--fpga/usrp2/gpmc/dbsm.v17
-rw-r--r--fpga/usrp2/gpmc/edge_sync.v17
-rw-r--r--fpga/usrp2/gpmc/fifo_to_gpmc_async.v17
-rw-r--r--fpga/usrp2/gpmc/fifo_to_gpmc_sync.v17
-rw-r--r--fpga/usrp2/gpmc/fifo_watcher.v17
-rw-r--r--fpga/usrp2/gpmc/gpmc_async.v17
-rw-r--r--fpga/usrp2/gpmc/gpmc_sync.v17
-rw-r--r--fpga/usrp2/gpmc/gpmc_to_fifo_async.v17
-rw-r--r--fpga/usrp2/gpmc/gpmc_to_fifo_sync.v17
-rw-r--r--fpga/usrp2/gpmc/gpmc_wb.v17
-rw-r--r--fpga/usrp2/gpmc/ram_to_fifo.v17
-rw-r--r--fpga/usrp2/models/CY7C1356C/cy1356.v17
-rw-r--r--fpga/usrp2/models/CY7C1356C/testbench.v17
-rw-r--r--fpga/usrp2/models/FIFO_GENERATOR_V6_1.v4575
-rw-r--r--fpga/usrp2/models/M24LC024B.v17
-rw-r--r--fpga/usrp2/models/M24LC02B.v17
-rw-r--r--fpga/usrp2/models/MULT18X18S.v17
-rw-r--r--fpga/usrp2/models/adc_model.v17
-rw-r--r--fpga/usrp2/models/cpld_model.v17
-rw-r--r--fpga/usrp2/models/gpmc_model_async.v17
-rw-r--r--fpga/usrp2/models/gpmc_model_sync.v17
-rw-r--r--fpga/usrp2/models/math_real.v17
-rw-r--r--fpga/usrp2/models/miim_model.v17
-rw-r--r--fpga/usrp2/models/serdes_model.v17
-rw-r--r--fpga/usrp2/models/uart_rx.v17
-rw-r--r--fpga/usrp2/models/xlnx_glbl.v17
-rw-r--r--fpga/usrp2/sdr_lib/acc.v17
-rw-r--r--fpga/usrp2/sdr_lib/add2.v17
-rw-r--r--fpga/usrp2/sdr_lib/add2_and_round.v17
-rw-r--r--fpga/usrp2/sdr_lib/add2_and_round_reg.v17
-rw-r--r--fpga/usrp2/sdr_lib/add2_reg.v17
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_rx.v17
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_rx_old.v17
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_rx_udp.v17
-rw-r--r--fpga/usrp2/sdr_lib/dsp_core_tx.v17
-rw-r--r--fpga/usrp2/sdr_lib/dummy_rx.v17
-rw-r--r--fpga/usrp2/sdr_lib/halfband_ideal.v17
-rw-r--r--fpga/usrp2/sdr_lib/halfband_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/acc.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/coeff_ram.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/coeff_rom.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/halfband_interp.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/hbd_tb/test_hbd.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/mac.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/mult.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/ram16_2port.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/ram16_2sum.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb/ram32_2sum.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb_dec.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb_dec_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb_interp.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb_interp_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/hb_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/integrate.v17
-rw-r--r--fpga/usrp2/sdr_lib/med_hb_int.v17
-rw-r--r--fpga/usrp2/sdr_lib/rssi.v17
-rw-r--r--fpga/usrp2/sdr_lib/rx_control.v17
-rw-r--r--fpga/usrp2/sdr_lib/rx_dcoffset.v17
-rw-r--r--fpga/usrp2/sdr_lib/rx_dcoffset_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/small_hb_dec.v17
-rw-r--r--fpga/usrp2/sdr_lib/small_hb_dec_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/small_hb_int.v17
-rw-r--r--fpga/usrp2/sdr_lib/small_hb_int_tb.v17
-rw-r--r--fpga/usrp2/sdr_lib/tx_control.v17
-rw-r--r--fpga/usrp2/serdes/serdes.v17
-rw-r--r--fpga/usrp2/serdes/serdes_fc_rx.v17
-rw-r--r--fpga/usrp2/serdes/serdes_fc_tx.v17
-rw-r--r--fpga/usrp2/serdes/serdes_rx.v17
-rw-r--r--fpga/usrp2/serdes/serdes_tb.v17
-rw-r--r--fpga/usrp2/serdes/serdes_tx.v17
-rw-r--r--fpga/usrp2/simple_gemac/address_filter.v17
-rw-r--r--fpga/usrp2/simple_gemac/address_filter_promisc.v17
-rw-r--r--fpga/usrp2/simple_gemac/crc.v17
-rw-r--r--fpga/usrp2/simple_gemac/delay_line.v17
-rw-r--r--fpga/usrp2/simple_gemac/eth_tasks.v17
-rw-r--r--fpga/usrp2/simple_gemac/eth_tasks_f19.v17
-rw-r--r--fpga/usrp2/simple_gemac/eth_tasks_f36.v17
-rw-r--r--fpga/usrp2/simple_gemac/ethrx_realign.v17
-rw-r--r--fpga/usrp2/simple_gemac/ethtx_realign.v17
-rw-r--r--fpga/usrp2/simple_gemac/flow_ctrl_rx.v17
-rw-r--r--fpga/usrp2/simple_gemac/flow_ctrl_tx.v17
-rw-r--r--fpga/usrp2/simple_gemac/ll8_to_txmac.v17
-rw-r--r--fpga/usrp2/simple_gemac/rxmac_to_ll8.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_rx.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_tb.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_tx.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wb.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper_f36_tb.v17
-rw-r--r--fpga/usrp2/simple_gemac/simple_gemac_wrapper_tb.v17
-rw-r--r--fpga/usrp2/testbench/single_u2_sim.v (renamed from fpga/usrp2/top/single_u2_sim/single_u2_sim.v)17
-rw-r--r--fpga/usrp2/timing/simple_timer.v17
-rw-r--r--fpga/usrp2/timing/time_64bit.v17
-rw-r--r--fpga/usrp2/timing/time_compare.v17
-rw-r--r--fpga/usrp2/timing/time_receiver.v17
-rw-r--r--fpga/usrp2/timing/time_sender.v17
-rw-r--r--fpga/usrp2/timing/time_sync.v17
-rw-r--r--fpga/usrp2/timing/time_transfer_tb.v17
-rw-r--r--fpga/usrp2/timing/timer.v17
-rw-r--r--fpga/usrp2/top/B100/.gitignore (renamed from fpga/usrp2/top/u1e_passthru/.gitignore)0
-rw-r--r--fpga/usrp2/top/B100/Makefile97
-rwxr-xr-xfpga/usrp2/top/B100/core_compile1
-rw-r--r--fpga/usrp2/top/B100/timing.ucf5
-rw-r--r--fpga/usrp2/top/B100/u1plus.ucf203
-rw-r--r--fpga/usrp2/top/B100/u1plus.v173
-rw-r--r--fpga/usrp2/top/B100/u1plus_core.v409
-rw-r--r--fpga/usrp2/top/E1x0/.gitignore (renamed from fpga/usrp2/top/u1e/.gitignore)0
-rw-r--r--fpga/usrp2/top/E1x0/Makefile (renamed from fpga/usrp2/top/u1e/Makefile)0
-rw-r--r--fpga/usrp2/top/E1x0/Makefile.passthru (renamed from fpga/usrp2/top/u1e_passthru/Makefile)0
-rw-r--r--fpga/usrp2/top/E1x0/README (renamed from fpga/usrp2/top/u1e/README)0
-rw-r--r--fpga/usrp2/top/E1x0/cmdfile (renamed from fpga/usrp2/top/u1e/cmdfile)0
-rwxr-xr-xfpga/usrp2/top/E1x0/core_compile (renamed from fpga/usrp2/top/u1e/core_compile)0
-rw-r--r--fpga/usrp2/top/E1x0/make.sim (renamed from fpga/usrp2/top/u1e/make.sim)0
-rw-r--r--fpga/usrp2/top/E1x0/passthru.ucf (renamed from fpga/usrp2/top/u1e_passthru/passthru.ucf)0
-rw-r--r--fpga/usrp2/top/E1x0/passthru.v35
-rw-r--r--fpga/usrp2/top/E1x0/tb_u1e.v (renamed from fpga/usrp2/top/u1e/tb_u1e.v)17
-rw-r--r--fpga/usrp2/top/E1x0/timing.ucf (renamed from fpga/usrp2/top/u1e/timing.ucf)0
-rw-r--r--fpga/usrp2/top/E1x0/u1e.ucf (renamed from fpga/usrp2/top/u1e/u1e.ucf)0
-rw-r--r--fpga/usrp2/top/E1x0/u1e.v (renamed from fpga/usrp2/top/u1e/u1e.v)17
-rw-r--r--fpga/usrp2/top/E1x0/u1e_core.v (renamed from fpga/usrp2/top/u1e/u1e_core.v)17
-rw-r--r--fpga/usrp2/top/N2x0/.gitignore (renamed from fpga/usrp2/top/u2plus/.gitignore)0
-rw-r--r--fpga/usrp2/top/N2x0/Makefile.N200R3 (renamed from fpga/usrp2/top/u2plus/Makefile.N200)2
-rw-r--r--fpga/usrp2/top/N2x0/Makefile.N200R4 (renamed from fpga/usrp2/top/u1e_ethdebug/Makefile)37
-rw-r--r--fpga/usrp2/top/N2x0/Makefile.N210R3 (renamed from fpga/usrp2/top/u2plus/Makefile)2
-rw-r--r--fpga/usrp2/top/N2x0/Makefile.N210R4100
-rw-r--r--fpga/usrp2/top/N2x0/bootloader.rmi (renamed from fpga/usrp2/top/u2plus/bootloader.rmi)0
-rw-r--r--fpga/usrp2/top/N2x0/capture_ddrlvds.v55
-rwxr-xr-xfpga/usrp2/top/N2x0/u2plus.ucf (renamed from fpga/usrp2/top/u2plus/u2plus.ucf)0
-rw-r--r--fpga/usrp2/top/N2x0/u2plus.v (renamed from fpga/usrp2/top/u2plus/u2plus.v)18
-rw-r--r--fpga/usrp2/top/N2x0/u2plus_core.v (renamed from fpga/usrp2/top/u2plus/u2plus_core.v)17
-rw-r--r--fpga/usrp2/top/USRP2/.gitignore (renamed from fpga/usrp2/top/u2_rev3/.gitignore)0
-rw-r--r--fpga/usrp2/top/USRP2/Makefile (renamed from fpga/usrp2/top/u2_rev3/Makefile)0
-rw-r--r--fpga/usrp2/top/USRP2/u2_core.v (renamed from fpga/usrp2/top/u2_rev3/u2_core.v)17
-rw-r--r--fpga/usrp2/top/USRP2/u2_rev3.ucf (renamed from fpga/usrp2/top/u2_rev3/u2_rev3.ucf)0
-rw-r--r--fpga/usrp2/top/USRP2/u2_rev3.v (renamed from fpga/usrp2/top/u2_rev3/u2_rev3.v)17
-rw-r--r--fpga/usrp2/top/eth_test/.gitignore43
-rw-r--r--fpga/usrp2/top/eth_test/eth_sim_top.v437
-rw-r--r--fpga/usrp2/top/eth_test/eth_tb.v257
-rw-r--r--fpga/usrp2/top/safe_u2plus/.gitignore2
-rw-r--r--fpga/usrp2/top/safe_u2plus/Makefile245
-rw-r--r--fpga/usrp2/top/safe_u2plus/safe_u2plus.v23
-rwxr-xr-xfpga/usrp2/top/safe_u2plus/u2plus.ucf401
-rw-r--r--fpga/usrp2/top/tcl/ise_helper.tcl2
-rw-r--r--fpga/usrp2/top/u1e_ethdebug/.gitignore6
-rw-r--r--fpga/usrp2/top/u1e_ethdebug/u1e.ucf88
-rw-r--r--fpga/usrp2/top/u1e_ethdebug/u1e.v28
-rw-r--r--fpga/usrp2/top/u1e_passthru/passthru.v18
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/Makefile253
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/README32
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/cmdfile4
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_rx.v212
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.sav106
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.v233
-rw-r--r--fpga/usrp2/top/u2_rev3_2rx_iad/impulse.v68
-rwxr-xr-xfpga/usrp2/top/u2_rev3_2rx_iad/u2_core.v789
-rwxr-xr-xfpga/usrp2/top/u2_rev3_2rx_iad/wave.sh3
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/.gitignore4
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/Makefile253
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/cmdfile4
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/dsp_core_rx.v158
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.sav61
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.v196
-rw-r--r--fpga/usrp2/top/u2_rev3_iad/impulse.v63
-rwxr-xr-xfpga/usrp2/top/u2_rev3_iad/wave.sh3
-rw-r--r--fpga/usrp2/top/u2plus/capture_ddrlvds.v39
-rw-r--r--fpga/usrp2/udp/add_onescomp.v17
-rw-r--r--fpga/usrp2/udp/fifo19_rxrealign.v17
-rw-r--r--fpga/usrp2/udp/prot_eng_rx.v17
-rw-r--r--fpga/usrp2/udp/prot_eng_tx.v17
-rw-r--r--fpga/usrp2/udp/prot_eng_tx_tb.v17
-rw-r--r--fpga/usrp2/udp/udp_wrapper.v17
-rw-r--r--fpga/usrp2/vrt/Makefile.srcs1
-rw-r--r--fpga/usrp2/vrt/gen_context_pkt.v17
-rw-r--r--fpga/usrp2/vrt/trigger_context_pkt.v17
-rw-r--r--fpga/usrp2/vrt/vita_pkt_gen.v59
-rw-r--r--fpga/usrp2/vrt/vita_rx_chain.v17
-rw-r--r--fpga/usrp2/vrt/vita_rx_control.v17
-rw-r--r--fpga/usrp2/vrt/vita_rx_framer.v17
-rw-r--r--fpga/usrp2/vrt/vita_rx_tb.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_chain.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_control.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_deframer.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_tb.v17
-rw-r--r--host/docs/CMakeLists.txt1
-rw-r--r--host/docs/general.rst54
-rw-r--r--host/docs/index.rst1
-rw-r--r--host/docs/usrp_b1xx.rst76
-rw-r--r--host/include/uhd/convert.hpp2
-rw-r--r--host/include/uhd/transport/usb_zero_copy.hpp21
-rw-r--r--host/lib/convert/CMakeLists.txt46
-rw-r--r--host/lib/convert/convert_common.hpp40
-rw-r--r--host/lib/convert/convert_orc.orc63
-rw-r--r--host/lib/convert/convert_with_neon.cpp8
-rw-r--r--host/lib/convert/convert_with_orc.cpp54
-rw-r--r--host/lib/convert/convert_with_sse2.cpp16
-rw-r--r--host/lib/convert/gen_convert_general.py8
-rw-r--r--host/lib/transport/CMakeLists.txt2
-rwxr-xr-xhost/lib/transport/gen_vrt_if_packet.py44
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp33
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp638
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp287
-rw-r--r--host/lib/transport/usb_zero_copy_wrapper.cpp202
-rw-r--r--host/lib/transport/vrt_packet_handler.hpp470
-rw-r--r--host/lib/usrp/CMakeLists.txt1
-rw-r--r--host/lib/usrp/b100/CMakeLists.txt47
-rw-r--r--host/lib/usrp/b100/b100_ctrl.cpp245
-rw-r--r--host/lib/usrp/b100/b100_ctrl.hpp69
-rw-r--r--host/lib/usrp/b100/b100_iface.cpp336
-rw-r--r--host/lib/usrp/b100/b100_iface.hpp73
-rw-r--r--host/lib/usrp/b100/b100_impl.cpp280
-rw-r--r--host/lib/usrp/b100/b100_impl.hpp204
-rw-r--r--host/lib/usrp/b100/b100_regs.hpp264
-rw-r--r--host/lib/usrp/b100/clock_ctrl.cpp525
-rw-r--r--host/lib/usrp/b100/clock_ctrl.hpp118
-rw-r--r--host/lib/usrp/b100/codec_ctrl.cpp283
-rw-r--r--host/lib/usrp/b100/codec_ctrl.hpp90
-rw-r--r--host/lib/usrp/b100/codec_impl.cpp149
-rw-r--r--host/lib/usrp/b100/ctrl_packet.hpp75
-rw-r--r--host/lib/usrp/b100/dboard_iface.cpp298
-rw-r--r--host/lib/usrp/b100/dboard_impl.cpp185
-rw-r--r--host/lib/usrp/b100/dsp_impl.cpp189
-rw-r--r--host/lib/usrp/b100/io_impl.cpp210
-rw-r--r--host/lib/usrp/b100/mboard_impl.cpp246
-rw-r--r--host/lib/usrp/dboard/db_basic_and_lf.cpp2
-rw-r--r--host/lib/usrp/fx2/fx2_ctrl.hpp2
-rw-r--r--host/lib/usrp/usrp1/dsp_impl.cpp5
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp180
-rw-r--r--host/lib/usrp/usrp1/mboard_impl.cpp3
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp6
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.hpp3
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp286
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp1
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp1
-rw-r--r--host/lib/usrp/usrp_e100/dsp_impl.cpp2
-rw-r--r--host/lib/usrp/usrp_e100/io_impl.cpp110
-rw-r--r--host/lib/usrp/usrp_e100/mboard_impl.cpp1
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_impl.cpp9
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_impl.hpp1
-rw-r--r--host/tests/CMakeLists.txt2
-rw-r--r--host/tests/convert_test.cpp14
-rw-r--r--host/tests/sph_recv_test.cpp715
-rw-r--r--host/tests/sph_send_test.cpp204
-rw-r--r--host/usrp_e_utils/usrp-e-loopback.c27
-rw-r--r--host/usrp_e_utils/usrp-e-timed.c2
-rw-r--r--images/Makefile118
382 files changed, 19940 insertions, 5160 deletions
diff --git a/firmware/fx2/CMakeLists.txt b/firmware/fx2/CMakeLists.txt
index 80f16363f..f7f6e96ca 100644
--- a/firmware/fx2/CMakeLists.txt
+++ b/firmware/fx2/CMakeLists.txt
@@ -39,9 +39,11 @@ set(CMAKE_C_FLAGS "--no-xinit-opt")
########################################################################
set(REG_GENERATOR ${CMAKE_SOURCE_DIR}/utils/generate_regs.py)
set(EDIT_GPIF_USRP1 ${CMAKE_SOURCE_DIR}/utils/edit-gpif.py)
+set(EDIT_GPIF_B100 ${CMAKE_SOURCE_DIR}/utils/edit-gpif-b100.py)
set(BUILD_EEPROM ${CMAKE_SOURCE_DIR}/utils/build_eeprom.py)
########################################################################
# Add the subdirectories
########################################################################
ADD_SUBDIRECTORY(usrp1)
+ADD_SUBDIRECTORY(b100)
diff --git a/firmware/fx2/b100/.gitignore b/firmware/fx2/b100/.gitignore
new file mode 100644
index 000000000..e27ec2046
--- /dev/null
+++ b/firmware/fx2/b100/.gitignore
@@ -0,0 +1,19 @@
+/*.ihx
+/*.lnk
+/*.lst
+/*.map
+/*.mem
+/*.rel
+/*.rst
+/*.sym
+/blink_leds.asm
+/usrp_common.asm
+/command_loop.asm
+/fpga.asm
+/*.asm
+/Makefile
+/Makefile.in
+/usrp_gpif.c
+/usrp_gpif_inline.h
+/Makefile.in
+/burn-usrp1p-eeprom
diff --git a/firmware/fx2/b100/CMakeLists.txt b/firmware/fx2/b100/CMakeLists.txt
new file mode 100644
index 000000000..438aa9207
--- /dev/null
+++ b/firmware/fx2/b100/CMakeLists.txt
@@ -0,0 +1,88 @@
+#
+# 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_directories(${CMAKE_SOURCE_DIR}/common)
+
+#for usrp_common.h and the regs files...
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+#now make a lib to link against
+set(libb100_sources
+ ${CMAKE_SOURCE_DIR}/common/delay.c
+ ${CMAKE_SOURCE_DIR}/common/fx2utils.c
+ ${CMAKE_SOURCE_DIR}/common/i2c.c
+ ${CMAKE_SOURCE_DIR}/common/init_gpif.c
+ ${CMAKE_SOURCE_DIR}/common/isr.c
+ ${CMAKE_SOURCE_DIR}/common/timer.c
+ ${CMAKE_SOURCE_DIR}/common/usb_common.c
+# ${CMAKE_SOURCE_DIR}/common/spi.c
+)
+
+#file(GLOB libb100_c_sources ${CMAKE_SOURCE_DIR}/common/*.c)
+#file(GLOB libb100_a51_sources ${CMAKE_SOURCE_DIR}/common/*.a51)
+#list(APPEND libb100_sources ${libb100_c_sources} ${libb100_a51_sources})
+
+add_library(libb100 STATIC ${libb100_sources})
+
+# edit-gpif hacks up gpif.c for our purposes. no major surgery, just moving stuff around.
+set(GPIF_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/gpif.c)
+set(GPIF_SOURCE_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/usrp_gpif.c)
+set(GPIF_HEADER_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/usrp_gpif_inline.h)
+
+add_custom_command(
+ OUTPUT ${GPIF_SOURCE_OUTPUT}
+ DEPENDS ${EDIT_GPIF_B100}
+ COMMAND ${PYTHON_EXECUTABLE} ${EDIT_GPIF_B100} ${GPIF_SOURCE} ${GPIF_SOURCE_OUTPUT} ${GPIF_HEADER_OUTPUT}
+ COMMENT "Generating ${GPIF_SOURCE_OUTPUT}"
+)
+
+#file(GLOB b100_sources *.c)
+set(b100_sources
+ ${CMAKE_SOURCE_DIR}/common/vectors.a51
+ usrp_main.c
+ usrp_common.c
+ board_specific.c
+ fpga_load.c
+ fpga_rev2.c
+ usrp_gpif.c
+ usb_descriptors.a51
+ eeprom_io.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+
+set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/usrp_main.c
+ PROPERTIES COMPILE_FLAGS "--std-sdcc99 --opt-code-speed --fommit-frame-pointer"
+)
+
+add_executable(b100_fw ${b100_sources})
+target_link_libraries(b100_fw libb100)
+
+set(eeprom1p_sources
+ ${CMAKE_SOURCE_DIR}/common/eeprom_boot.a51
+ ${CMAKE_SOURCE_DIR}/common/eeprom_init.c
+ ${CMAKE_SOURCE_DIR}/common/_startup.a51
+)
+
+add_custom_target(b100_eeprom ALL
+ DEPENDS b100_boot
+ COMMAND objcopy -I ihex -O binary b100_boot.ihx b100_boot.bin
+ COMMAND ${PYTHON_EXECUTABLE} ${BUILD_EEPROM} -r2 b100_boot.bin b100_eeprom.bin
+)
+
+add_executable(b100_boot ${eeprom1p_sources})
+target_link_libraries(b100_boot libb100)
diff --git a/firmware/fx2/b100/board_specific.c b/firmware/fx2/b100/board_specific.c
new file mode 100644
index 000000000..993d925b3
--- /dev/null
+++ b/firmware/fx2/b100/board_specific.c
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "usrp_common.h"
+
+void
+set_led_0 (unsigned char on)
+{
+ if (!on) // active low
+ USRP_PC |= bmPC_LED0;
+ else
+ USRP_PC &= ~bmPC_LED0;
+}
+
+void
+set_led_1 (unsigned char on)
+{
+ if (!on) // active low
+ USRP_PC |= bmPC_LED1;
+ else
+ USRP_PC &= ~bmPC_LED1;
+}
+
+void
+toggle_led_0 (void)
+{
+ USRP_PC ^= bmPC_LED0;
+}
+
+void
+toggle_led_1 (void)
+{
+ USRP_PC ^= bmPC_LED1;
+}
+
+void
+set_sleep_bits (unsigned char bits, unsigned char mask)
+{
+ // NOP on usrp1
+}
+
+static xdata unsigned char xbuf[1];
+
+void
+init_board (void)
+{
+ //init_spi ();
+
+ //USRP_PC &= ~bmPC_nRESET; // active low reset
+ //USRP_PC |= bmPC_nRESET;
+}
diff --git a/firmware/fx2/b100/eeprom_io.c b/firmware/fx2/b100/eeprom_io.c
new file mode 100644
index 000000000..9eeb53636
--- /dev/null
+++ b/firmware/fx2/b100/eeprom_io.c
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "eeprom_io.h"
+#include "i2c.h"
+#include "delay.h"
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+ xdata unsigned char *buf, unsigned char len)
+{
+ // We setup a random read by first doing a "zero byte write".
+ // Writes carry an address. Reads use an implicit address.
+
+ static xdata unsigned char cmd[1];
+ cmd[0] = eeprom_offset;
+ if (!i2c_write(i2c_addr, cmd, 1))
+ return 0;
+
+ return i2c_read(i2c_addr, buf, len);
+}
+
+
+#if 0
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+ const xdata unsigned char *buf, unsigned char len)
+{
+ static xdata unsigned char cmd[2];
+ unsigned char ok;
+
+ while (len-- > 0){
+ cmd[0] = eeprom_offset++;
+ cmd[1] = *buf++;
+ ok = i2c_write(i2c_addr, cmd, 2);
+ mdelay(10); // delay 10ms worst case write time
+ if (!ok)
+ return 0;
+ }
+ return 1;
+}
+
+#endif
diff --git a/firmware/fx2/b100/eeprom_io.h b/firmware/fx2/b100/eeprom_io.h
new file mode 100644
index 000000000..558017b12
--- /dev/null
+++ b/firmware/fx2/b100/eeprom_io.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_EEPROM_IO_H
+#define INCLUDED_EEPROM_IO_H
+
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+ xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+ const xdata unsigned char *buf, unsigned char len);
+
+
+#endif /* INCLUDED_EEPROM_IO_H */
diff --git a/firmware/fx2/b100/fpga_load.c b/firmware/fx2/b100/fpga_load.c
new file mode 100644
index 000000000..54ef54ab3
--- /dev/null
+++ b/firmware/fx2/b100/fpga_load.c
@@ -0,0 +1,193 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#include "usrp_common.h"
+#include "fpga_load.h"
+#include "delay.h"
+
+/*
+ * setup altera FPGA serial load (PS).
+ *
+ * On entry:
+ * don't care
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_begin (void)
+{
+ USRP_ALTERA_CONFIG &= ~bmALTERA_BITS; // clear all bits (NCONFIG low)
+ udelay (40); // wait 40 us
+ USRP_ALTERA_CONFIG |= bmALTERA_NCONFIG; // set NCONFIG high
+
+ if (UC_BOARD_HAS_FPGA){
+ // FIXME should really cap this loop with a counter so we
+ // don't hang forever on a hardware failure.
+ while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
+ ;
+ }
+
+ // ready to xfer now
+
+ return 1;
+}
+
+/*
+ * clock out the low bit of bits.
+ *
+ * On entry:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+
+
+#if 0
+
+static void
+clock_out_config_byte (unsigned char bits)
+{
+ unsigned char i;
+
+ // clock out configuration byte, least significant bit first
+
+ for (i = 0; i < 8; i++){
+
+ USRP_ALTERA_CONFIG = ((USRP_ALTERA_CONFIG & ~bmALTERA_DATA0) | ((bits & 1) ? bmALTERA_DATA0 : 0));
+ USRP_ALTERA_CONFIG |= bmALTERA_DCLK; /* set DCLK to 1 */
+ USRP_ALTERA_CONFIG &= ~bmALTERA_DCLK; /* set DCLK to 0 */
+
+ bits = bits >> 1;
+ }
+}
+
+#else
+
+static void
+clock_out_config_byte (unsigned char bits) _naked
+{
+ _asm
+ mov a, dpl
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ rlc a
+ mov _bitALTERA_DATA0,c
+ setb _bitALTERA_DCLK
+ clr _bitALTERA_DCLK
+
+ ret
+
+ _endasm;
+}
+
+#endif
+
+static void
+clock_out_bytes (unsigned char bytecount,
+ unsigned char xdata *p)
+{
+ while (bytecount-- > 0)
+ clock_out_config_byte (*p++);
+}
+
+/*
+ * Transfer block of bytes from packet to FPGA serial configuration port
+ *
+ * On entry:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ * ALTERA_DCLK = 0
+ * ALTERA_NCONFIG = 1
+ * ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_xfer (xdata unsigned char *p, unsigned char bytecount)
+{
+ clock_out_bytes (bytecount, p);
+ return 1;
+}
+
+/*
+ * check for successful load...
+ */
+unsigned char
+fpga_load_end (void)
+{
+ unsigned char status = USRP_ALTERA_CONFIG;
+
+ if (!UC_BOARD_HAS_FPGA) // always true if we don't have FPGA
+ return 1;
+
+ if ((status & bmALTERA_NSTATUS) == 0) // failed to program
+ return 0;
+
+ if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
+ return 1; // everything's cool
+
+ // I don't think this should happen. It indicates that
+ // programming is still in progress.
+
+ return 0;
+}
diff --git a/firmware/fx2/b100/fpga_rev2.c b/firmware/fx2/b100/fpga_rev2.c
new file mode 100644
index 000000000..326a01732
--- /dev/null
+++ b/firmware/fx2/b100/fpga_rev2.c
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "fpga.h"
+#include "fpga_regs_common.h"
+#include "usrp_common.h"
+#include "usrp_globals.h"
+
+unsigned char g_tx_reset = 0;
+unsigned char g_rx_reset = 0;
+
+void
+fpga_write_reg (unsigned char regno, const xdata unsigned char *regval)
+{
+ //nop
+}
+
+
+static xdata unsigned char regval[4] = {0, 0, 0, 0};
+
+// Resets both AD9862's and the FPGA serial bus interface.
+
+void
+fpga_set_reset (unsigned char on)
+{
+ on &= 0x1;
+
+ if (on){
+ }
+ else
+ ;
+}
diff --git a/firmware/fx2/b100/fpga_rev2.h b/firmware/fx2/b100/fpga_rev2.h
new file mode 100644
index 000000000..0773d1cd7
--- /dev/null
+++ b/firmware/fx2/b100/fpga_rev2.h
@@ -0,0 +1,44 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#ifndef INCLUDED_FPGA_REV1_H
+#define INCLUDED_FPGA_REV1_H
+
+/*
+ * return TRUE if FPGA internal fifo has room for a single packet
+ */
+#define fpga_has_room_for_data_packet() (!(GPIFREADYSTAT & bmDATA_FIFO_FULL))
+#define fpga_has_room_for_ctrl_packet() (!(GPIFREADYSTAT & bmCTRL_FIFO_FULL))
+
+/*
+ * return TRUE if FPGA internal fifo has at least one packet available
+ */
+#define fpga_has_data_packet_avail() (!(GPIFREADYSTAT & bmDATA_EMPTY))
+#define fpga_has_ctrl_packet_avail() (!(GPIFREADYSTAT & bmCTRL_EMPTY))
+
+#define fx2_has_ctrl_packet_avail() (!(EP24FIFOFLGS & EP4FIFOEMPTY))
+#define fx2_has_data_packet_avail() (!(EP24FIFOFLGS & EP2FIFOEMPTY))
+
+#define fx2_has_room_for_ctrl_packet() (!(EP8CS & bmEPFULL))
+#define fx2_has_room_for_data_packet() (!(EP6CS & bmEPFULL))
+
+#define fx2_gpif_is_idle() (GPIFTRIG & bmGPIF_IDLE)
+
+#endif /* INCLUDED_FPGA_REV1_H */
diff --git a/firmware/fx2/b100/gpif.c b/firmware/fx2/b100/gpif.c
new file mode 100644
index 000000000..b499e4fcf
--- /dev/null
+++ b/firmware/fx2/b100/gpif.c
@@ -0,0 +1,292 @@
+// This program configures the General Programmable Interface (GPIF) for FX2.
+// Please do not modify sections of text which are marked as "DO NOT EDIT ...".
+//
+// DO NOT EDIT ...
+// GPIF Initialization
+// Interface Timing Async
+// Internal Ready Init IntRdy=1
+// CTL Out Tristate-able Binary
+// SingleWrite WF Select 1
+// SingleRead WF Select 0
+// FifoWrite WF Select 3
+// FifoRead WF Select 2
+// Data Bus Idle Drive Tristate
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+// GPIF Wave Names
+// Wave 0 = singlerd
+// Wave 1 = singlewr
+// Wave 2 = FIFORd
+// Wave 3 = FIFOWr
+
+// GPIF Ctrl Outputs Level
+// CTL 0 = WEN# CMOS
+// CTL 1 = REN# CMOS
+// CTL 2 = OE# CMOS
+// CTL 3 = EP CMOS
+// CTL 4 = unused CMOS
+// CTL 5 = unused CMOS
+
+// GPIF Rdy Inputs
+// RDY0 = EF#
+// RDY1 = FF#
+// RDY2 = DRDY
+// RDY3 = CRDY
+// RDY4 = unused
+// RDY5 = TCXpire
+// FIFOFlag = FIFOFlag
+// IntReady = IntReady
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 0: singlerd
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data NO Data NO Data NO Data NO Data NO Data NO Data
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A
+// LFunc
+// Term B
+// Branch1
+// Branch0
+// Re-Exec
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 1: singlewr
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode Activate Activate Activate Activate Activate Activate Activate
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A EF#
+// LFunc AND
+// Term B EF#
+// Branch1 ThenIdle
+// Branch0 ElseIdle
+// Re-Exec No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 1 1 1 1 1 1 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 2: FIFORd
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data Activate NO Data NO Data NO Data NO Data NO Data
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 IF Wait 1 Wait 1 Wait 1
+// Term A TCXpire TCXpire
+// LFunc AND AND
+// Term B TCXpire TCXpire
+// Branch1 Then 2 ThenIdle
+// Branch0 Else 1 ElseIdle
+// Re-Exec No No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 1 0 0 0 0 0 0 0
+// OE# 1 1 1 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+// DO NOT EDIT ...
+//
+// GPIF Waveform 3: FIFOWr
+//
+// Interval 0 1 2 3 4 5 6 Idle (7)
+// _________ _________ _________ _________ _________ _________ _________ _________
+//
+// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
+// DataMode NO Data Activate Activate Activate Activate Activate Activate
+// NextData SameData SameData SameData SameData SameData SameData SameData
+// Int Trig No Int No Int No Int No Int No Int No Int No Int
+// IF/Wait Wait 1 IF Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
+// Term A TCXpire
+// LFunc AND
+// Term B TCXpire
+// Branch1 ThenIdle
+// Branch0 Else 1
+// Re-Exec No
+// Sngl/CRC Default Default Default Default Default Default Default
+// WEN# 0 0 0 0 0 0 0 0
+// REN# 0 0 0 0 0 0 0 0
+// OE# 0 0 0 0 0 0 0 0
+// CLRST 0 0 0 0 0 0 0 0
+// unused 0 0 0 0 0 0 0 0
+// BOGUS 0 0 0 0 0 0 0 0
+//
+// END DO NOT EDIT
+
+// GPIF Program Code
+
+// DO NOT EDIT ...
+#include "fx2.h"
+#include "fx2regs.h"
+#include "fx2sdly.h" // SYNCDELAY macro
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata WaveData[128] =
+{
+// Wave 0
+/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* Output*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+// Wave 1
+/* LenBr */ 0x01, 0x3F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x22, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
+/* Output*/ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+// Wave 2
+/* LenBr */ 0x01, 0x11, 0x01, 0x3F, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+/* Output*/ 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x2D, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
+// Wave 3
+/* LenBr */ 0x01, 0x39, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
+/* Opcode*/ 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
+/* Output*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* LFun */ 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+};
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata FlowStates[36] =
+{
+/* Wave 0 FlowStates */ 0x81,0x2D,0x0E,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 1 FlowStates */ 0x81,0x2D,0x09,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x06,0x00,0x00,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x01,0x00,0x00,0x04,0x03,0x02,0x00,
+};
+// END DO NOT EDIT
+
+// DO NOT EDIT ...
+const char xdata InitData[7] =
+{
+/* Regs */ 0xA0,0x00,0x00,0x00,0xEE,0x4E,0x00
+};
+// END DO NOT EDIT
+
+// TO DO: You may add additional code below.
+
+void GpifInit( void )
+{
+ BYTE i;
+
+ // Registers which require a synchronization delay, see section 15.14
+ // FIFORESET FIFOPINPOLAR
+ // INPKTEND OUTPKTEND
+ // EPxBCH:L REVCTL
+ // GPIFTCB3 GPIFTCB2
+ // GPIFTCB1 GPIFTCB0
+ // EPxFIFOPFH:L EPxAUTOINLENH:L
+ // EPxFIFOCFG EPxGPIFFLGSEL
+ // PINFLAGSxx EPxFIFOIRQ
+ // EPxFIFOIE GPIFIRQ
+ // GPIFIE GPIFADRH:L
+ // UDMACRCH:L EPxGPIFTRIG
+ // GPIFTRIG
+
+ // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
+ // ...these have been replaced by GPIFTC[B3:B0] registers
+
+ // 8051 doesn't have access to waveform memories 'til
+ // the part is in GPIF mode.
+
+ IFCONFIG = 0xEE;
+ // IFCLKSRC=1 , FIFOs executes on internal clk source
+ // xMHz=1 , 48MHz internal clk rate
+ // IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
+ // IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
+ // ASYNC=1 , master samples asynchronous
+ // GSTATE=1 , Drive GPIF states out on PORTE[2:0], debug WF
+ // IFCFG[1:0]=10, FX2 in GPIF master mode
+
+ GPIFABORT = 0xFF; // abort any waveforms pending
+
+ GPIFREADYCFG = InitData[ 0 ];
+ GPIFCTLCFG = InitData[ 1 ];
+ GPIFIDLECS = InitData[ 2 ];
+ GPIFIDLECTL = InitData[ 3 ];
+ GPIFWFSELECT = InitData[ 5 ];
+ GPIFREADYSTAT = InitData[ 6 ];
+
+ // use dual autopointer feature...
+ AUTOPTRSETUP = 0x07; // inc both pointers,
+ // ...warning: this introduces pdata hole(s)
+ // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
+
+ // source
+ AUTOPTRH1 = MSB( &WaveData );
+ AUTOPTRL1 = LSB( &WaveData );
+
+ // destination
+ AUTOPTRH2 = 0xE4;
+ AUTOPTRL2 = 0x00;
+
+ // transfer
+ for ( i = 0x00; i < 128; i++ )
+ {
+ EXTAUTODAT2 = EXTAUTODAT1;
+ }
+
+// Configure GPIF Address pins, output initial value,
+ PORTCCFG = 0xFF; // [7:0] as alt. func. GPIFADR[7:0]
+ OEC = 0xFF; // and as outputs
+ PORTECFG |= 0x80; // [8] as alt. func. GPIFADR[8]
+ OEE |= 0x80; // and as output
+
+// ...OR... tri-state GPIFADR[8:0] pins
+// PORTCCFG = 0x00; // [7:0] as port I/O
+// OEC = 0x00; // and as inputs
+// PORTECFG &= 0x7F; // [8] as port I/O
+// OEE &= 0x7F; // and as input
+
+// GPIF address pins update when GPIFADRH/L written
+ SYNCDELAY; //
+ GPIFADRH = 0x00; // bits[7:1] always 0
+ SYNCDELAY; //
+ GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
+
+// Configure GPIF FlowStates registers for Wave 0 of WaveData
+ FLOWSTATE = FlowStates[ 0 ];
+ FLOWLOGIC = FlowStates[ 1 ];
+ FLOWEQ0CTL = FlowStates[ 2 ];
+ FLOWEQ1CTL = FlowStates[ 3 ];
+ FLOWHOLDOFF = FlowStates[ 4 ];
+ FLOWSTB = FlowStates[ 5 ];
+ FLOWSTBEDGE = FlowStates[ 6 ];
+ FLOWSTBHPERIOD = FlowStates[ 7 ];
+}
+
diff --git a/firmware/fx2/b100/usb_descriptors.a51 b/firmware/fx2/b100/usb_descriptors.a51
new file mode 100644
index 000000000..cc71833fe
--- /dev/null
+++ b/firmware/fx2/b100/usb_descriptors.a51
@@ -0,0 +1,499 @@
+;;; -*- asm -*-
+;;;
+;;; Copyright 2003 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 GNU Radio; see the file COPYING. If not, write to
+;;; the Free Software Foundation, Inc., 51 Franklin Street,
+;;; Boston, MA 02110-1301, USA.
+;;;
+
+;;; USB Descriptor table for the B100
+;;;
+;;; We're a high-speed only device (480 Mb/sec) with 1 configuration
+;;; and 5 interfaces.
+;;;
+;;; interface 0: command and status (ep0 COMMAND)
+;;; interface 1: Transmit path (ep2 OUT BULK)
+;;; interface 2: Receive path (ep6 IN BULK)
+
+;;; interface 3: Command transmit path (ep4 OUT BULK) for FPGA comms
+;;; interface 4: Command receive path (ep8 IN BULK) for FPGA comms
+
+ .module usb_descriptors
+
+ VID_FREE = 0x2500 ; Free Software Folks
+ PID_USRP = 0x0001 ; B100
+
+ ;; We distinguish configured from unconfigured USRPs using the Device ID.
+ ;; If the MSB of the DID is 0, the device is unconfigured.
+ ;; The LSB of the DID is reserved for hardware revs.
+
+ DID_USRP = 0x0100 ; Device ID (bcd)
+
+
+ DSCR_DEVICE = 1 ; Descriptor type: Device
+ DSCR_CONFIG = 2 ; Descriptor type: Configuration
+ DSCR_STRING = 3 ; Descriptor type: String
+ DSCR_INTRFC = 4 ; Descriptor type: Interface
+ DSCR_ENDPNT = 5 ; Descriptor type: Endpoint
+ DSCR_DEVQUAL = 6 ; Descriptor type: Device Qualifier
+
+ DSCR_DEVICE_LEN = 18
+ DSCR_CONFIG_LEN = 9
+ DSCR_INTRFC_LEN = 9
+ DSCR_ENDPNT_LEN = 7
+ DSCR_DEVQUAL_LEN = 10
+
+ ET_CONTROL = 0 ; Endpoint type: Control
+ ET_ISO = 1 ; Endpoint type: Isochronous
+ ET_BULK = 2 ; Endpoint type: Bulk
+ ET_INT = 3 ; Endpoint type: Interrupt
+
+
+ ;; configuration attributes
+ bmSELF_POWERED = 1 << 6
+
+;;; --------------------------------------------------------
+;;; external ram data
+;;;--------------------------------------------------------
+
+ .area USBDESCSEG (XDATA)
+
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at high speed (480Mb/sec)
+;;; ----------------------------------------------------------------
+
+ .even ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work
+
+ ;; The .even directive isn't really honored by the linker. Bummer!
+ ;; (There's no way to specify an alignment requirement for a given area,
+ ;; hence when they're concatenated together, even doesn't work.)
+ ;;
+ ;; We work around this by telling the linker to put USBDESCSEG
+ ;; at 0xE000 absolute. This means that the maximimum length of this
+ ;; segment is 480 bytes, leaving room for the two hash slots
+ ;; at 0xE1EO to 0xE1FF.
+ ;;
+ ;; As of July 7, 2004, this segment is 326 bytes long
+ ;; As of Sept 2, 2010, this segment is 416 bytes long
+
+_high_speed_device_descr::
+ .db DSCR_DEVICE_LEN
+ .db DSCR_DEVICE
+ .db <0x0200 ; Specification version (LSB)
+ .db >0x0200 ; Specification version (MSB)
+ .db 0xff ; device class (vendor specific)
+ .db 0xff ; device subclass (vendor specific)
+ .db 0xff ; device protocol (vendor specific)
+ .db 64 ; bMaxPacketSize0 for endpoint 0
+ .db <VID_FREE ; idVendor
+ .db >VID_FREE ; idVendor
+ .db <PID_USRP ; idProduct
+ .db >PID_USRP ; idProduct
+_usb_desc_hw_rev_binary_patch_location_0::
+ .db <DID_USRP ; bcdDevice
+ .db >DID_USRP ; bcdDevice
+ .db SI_VENDOR ; iManufacturer (string index)
+ .db SI_PRODUCT ; iProduct (string index)
+ .db SI_SERIAL ; iSerial number (string index)
+ .db 1 ; bNumConfigurations
+
+;;; describes the other speed (12Mb/sec)
+ .even
+_high_speed_devqual_descr::
+ .db DSCR_DEVQUAL_LEN
+ .db DSCR_DEVQUAL
+ .db <0x0200 ; bcdUSB (LSB)
+ .db >0x0200 ; bcdUSB (MSB)
+ .db 0xff ; bDeviceClass
+ .db 0xff ; bDeviceSubClass
+ .db 0xff ; bDeviceProtocol
+ .db 64 ; bMaxPacketSize0
+ .db 1 ; bNumConfigurations (one config at 12Mb/sec)
+ .db 0 ; bReserved
+
+ .even
+_high_speed_config_descr::
+ .db DSCR_CONFIG_LEN
+ .db DSCR_CONFIG
+ .db <(_high_speed_config_descr_end - _high_speed_config_descr) ; LSB
+ .db >(_high_speed_config_descr_end - _high_speed_config_descr) ; MSB
+ .db 5 ; bNumInterfaces
+ .db 1 ; bConfigurationValue
+ .db 0 ; iConfiguration
+ .db 0x80 | bmSELF_POWERED ; bmAttributes
+ .db 0 ; bMaxPower
+
+ ;; interface descriptor 0 (command & status, ep0 COMMAND)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 0 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 0 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_COMMAND_AND_STATUS ; iInterface (description)
+
+ ;; interface descriptor 1 (transmit path, ep2 OUT BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 1 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_TX_PATH ; iInterface (description)
+
+ ;; interface 1's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x02 ; bEndpointAddress (ep 2 OUT)
+ .db ET_BULK ; bmAttributes
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 2 (receive path, ep6 IN BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 2 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_RX_PATH ; iInterface (description)
+
+ ;; interface 2's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x86 ; bEndpointAddress (ep 6 IN)
+ .db ET_BULK ; bmAttributes
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 3 (FPGA command OUT path, ep4 OUT BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 3 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_FPGA_COMMAND_OUT_PATH ; iInterface (description)
+
+ ;; interface 3's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x04 ; bEndpointAddress (ep 4 OUT)
+ .db ET_BULK ; bmAttributes
+ .db <32 ; wMaxPacketSize (LSB)
+ .db >32 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+ ;; interface descriptor 4 (FPGA command IN path, ep8 IN BULK)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 4 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 1 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_FPGA_COMMAND_IN_PATH ; iInterface (description)
+
+ ;; interface 4's end point
+
+ .db DSCR_ENDPNT_LEN
+ .db DSCR_ENDPNT
+ .db 0x88 ; bEndpointAddress (ep 8 IN)
+ .db ET_BULK ; bmAttributes
+ .db <32 ; wMaxPacketSize (LSB)
+ .db >32 ; wMaxPacketSize (MSB)
+ .db 0 ; bInterval (iso only)
+
+
+_high_speed_config_descr_end:
+
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at full speed (12Mb/sec)
+;;; ----------------------------------------------------------------
+
+ .even
+_full_speed_device_descr::
+ .db DSCR_DEVICE_LEN
+ .db DSCR_DEVICE
+ .db <0x0200 ; Specification version (LSB)
+ .db >0x0200 ; Specification version (MSB)
+ .db 0xff ; device class (vendor specific)
+ .db 0xff ; device subclass (vendor specific)
+ .db 0xff ; device protocol (vendor specific)
+ .db 64 ; bMaxPacketSize0 for endpoint 0
+ .db <VID_FREE ; idVendor
+ .db >VID_FREE ; idVendor
+ .db <PID_USRP ; idProduct
+ .db >PID_USRP ; idProduct
+_usb_desc_hw_rev_binary_patch_location_1::
+ .db <DID_USRP ; bcdDevice
+ .db >DID_USRP ; bcdDevice
+ .db SI_VENDOR ; iManufacturer (string index)
+ .db SI_PRODUCT ; iProduct (string index)
+ .db SI_NONE ; iSerial number (None)
+ .db 1 ; bNumConfigurations
+
+
+;;; describes the other speed (480Mb/sec)
+ .even
+_full_speed_devqual_descr::
+ .db DSCR_DEVQUAL_LEN
+ .db DSCR_DEVQUAL
+ .db <0x0200 ; bcdUSB
+ .db >0x0200 ; bcdUSB
+ .db 0xff ; bDeviceClass
+ .db 0xff ; bDeviceSubClass
+ .db 0xff ; bDeviceProtocol
+ .db 64 ; bMaxPacketSize0
+ .db 1 ; bNumConfigurations (one config at 480Mb/sec)
+ .db 0 ; bReserved
+
+ .even
+_full_speed_config_descr::
+ .db DSCR_CONFIG_LEN
+ .db DSCR_CONFIG
+ .db <(_full_speed_config_descr_end - _full_speed_config_descr) ; LSB
+ .db >(_full_speed_config_descr_end - _full_speed_config_descr) ; MSB
+ .db 1 ; bNumInterfaces
+ .db 1 ; bConfigurationValue
+ .db 0 ; iConfiguration
+ .db 0x80 | bmSELF_POWERED ; bmAttributes
+ .db 0 ; bMaxPower
+
+ ;; interface descriptor 0 (command & status, ep0 COMMAND)
+
+ .db DSCR_INTRFC_LEN
+ .db DSCR_INTRFC
+ .db 0 ; bInterfaceNumber (zero based)
+ .db 0 ; bAlternateSetting
+ .db 0 ; bNumEndpoints
+ .db 0xff ; bInterfaceClass (vendor specific)
+ .db 0xff ; bInterfaceSubClass (vendor specific)
+ .db 0xff ; bInterfaceProtocol (vendor specific)
+ .db SI_COMMAND_AND_STATUS ; iInterface (description)
+
+_full_speed_config_descr_end:
+
+;;; ----------------------------------------------------------------
+;;; string descriptors
+;;; ----------------------------------------------------------------
+
+_nstring_descriptors::
+ .db (_string_descriptors_end - _string_descriptors) / 2
+
+_string_descriptors::
+ .db <str0, >str0
+ .db <str1, >str1
+ .db <str2, >str2
+ .db <str3, >str3
+ .db <str4, >str4
+ .db <str5, >str5
+ .db <str6, >str6
+ .db <str7, >str7
+ .db <str8, >str8
+_string_descriptors_end:
+
+ SI_NONE = 0
+ ;; str0 contains the language ID's.
+ .even
+str0: .db str0_end - str0
+ .db DSCR_STRING
+ .db 0
+ .db 0
+ .db <0x0409 ; magic code for US English (LSB)
+ .db >0x0409 ; magic code for US English (MSB)
+str0_end:
+
+ SI_VENDOR = 1
+ .even
+str1: .db str1_end - str1
+ .db DSCR_STRING
+ .db 'F, 0 ; 16-bit unicode
+ .db 'r, 0
+ .db 'e, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'S, 0
+ .db 'o, 0
+ .db 'f, 0
+ .db 't, 0
+ .db 'w, 0
+ .db 'a, 0
+ .db 'r, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'F, 0
+ .db 'o, 0
+ .db 'l, 0
+ .db 'k, 0
+ .db 's, 0
+str1_end:
+
+ SI_PRODUCT = 2
+ .even
+str2: .db str2_end - str2
+ .db DSCR_STRING
+ .db 'U, 0
+ .db 'S, 0
+ .db 'R, 0
+ .db 'P, 0
+ .db '1, 0
+ .db 'P, 0
+ .db ' , 0
+ .db 'R, 0
+ .db 'e, 0
+ .db 'v, 0
+ .db ' , 0
+_usb_desc_hw_rev_ascii_patch_location_0::
+ .db '?, 0
+str2_end:
+
+ SI_COMMAND_AND_STATUS = 3
+ .even
+str3: .db str3_end - str3
+ .db DSCR_STRING
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db '&, 0
+ .db ' , 0
+ .db 'S, 0
+ .db 't, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'u, 0
+ .db 's, 0
+str3_end:
+
+ SI_TX_PATH = 4
+ .even
+str4: .db str4_end - str4
+ .db DSCR_STRING
+ .db 'T, 0
+ .db 'r, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 's, 0
+ .db 'm, 0
+ .db 'i, 0
+ .db 't, 0
+ .db ' , 0
+ .db 'P, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'h, 0
+str4_end:
+
+ SI_RX_PATH = 5
+ .even
+str5: .db str5_end - str5
+ .db DSCR_STRING
+ .db 'R, 0
+ .db 'e, 0
+ .db 'c, 0
+ .db 'e, 0
+ .db 'i, 0
+ .db 'v, 0
+ .db 'e, 0
+ .db ' , 0
+ .db 'P, 0
+ .db 'a, 0
+ .db 't, 0
+ .db 'h, 0
+str5_end:
+
+ SI_SERIAL = 6
+ .even
+str6: .db str6_end - str6
+ .db DSCR_STRING
+_usb_desc_serial_number_ascii::
+ .db '3, 0
+ .db '., 0
+ .db '1, 0
+ .db '4, 0
+ .db '1, 0
+ .db '5, 0
+ .db '9, 0
+ .db '3, 0
+str6_end:
+
+ SI_FPGA_COMMAND_OUT_PATH = 7
+ .even
+str7: .db str7_end - str7
+ .db DSCR_STRING
+ .db 'F, 0
+ .db 'P, 0
+ .db 'G, 0
+ .db 'A, 0
+ .db ' , 0
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db 'O, 0
+ .db 'u, 0
+ .db 't, 0
+str7_end:
+
+ SI_FPGA_COMMAND_IN_PATH = 8
+ .even
+str8: .db str8_end - str8
+ .db DSCR_STRING
+ .db 'F, 0
+ .db 'P, 0
+ .db 'G, 0
+ .db 'A, 0
+ .db ' , 0
+ .db 'C, 0
+ .db 'o, 0
+ .db 'm, 0
+ .db 'm, 0
+ .db 'a, 0
+ .db 'n, 0
+ .db 'd, 0
+ .db ' , 0
+ .db 'I, 0
+ .db 'n, 0
+str8_end:
diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c
new file mode 100644
index 000000000..4b6dde881
--- /dev/null
+++ b/firmware/fx2/b100/usrp_common.c
@@ -0,0 +1,108 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * common code for USRP
+ */
+
+#include "usrp_common.h"
+
+void init_board (void);
+
+void
+init_usrp (void)
+{
+ CPUCS = bmCLKSPD1; // CPU runs @ 48 MHz
+ CKCON = 0; // MOVX takes 2 cycles
+
+ // IFCLK is generated internally and runs at 48 MHz; GPIF "master mode"
+
+ IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFCLKPOL | bmIFGPIF;
+ SYNCDELAY;
+
+ // configure IO ports (B and D are used by GPIF)
+
+ IOA = bmPORT_A_INITIAL; // Port A initial state
+ OEA = bmPORT_A_OUTPUTS; // Port A direction register
+
+ IOC = bmPORT_C_INITIAL; // Port C initial state
+ OEC = bmPORT_C_OUTPUTS; // Port C direction register
+
+ IOE = bmPORT_E_INITIAL; // Port E initial state
+ OEE = bmPORT_E_OUTPUTS; // Port E direction register
+
+
+ //REVCTL = bmDYN_OUT | bmENH_PKT; // highly recommended by docs
+ // SYNCDELAY;
+
+ // configure end points
+
+ EP1OUTCFG = bmVALID | bmBULK; SYNCDELAY;
+ EP1INCFG = bmVALID | bmBULK | bmIN; SYNCDELAY;
+
+ EP2CFG = bmVALID | bmBULK | bmDOUBLEBUF; SYNCDELAY; // 512 dbl bulk OUT
+ EP4CFG = bmVALID | bmBULK | bmDOUBLEBUF; SYNCDELAY; // 512 dbl bulk OUT
+ EP6CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN
+ EP8CFG = bmVALID | bmBULK | bmDOUBLEBUF | bmIN; SYNCDELAY; // 512 dbl bulk IN
+
+ // reset FIFOs
+
+ FIFORESET = bmNAKALL; SYNCDELAY;
+ FIFORESET = 2; SYNCDELAY;
+ FIFORESET = 4; SYNCDELAY;
+ FIFORESET = 6; SYNCDELAY;
+ FIFORESET = 8; SYNCDELAY;
+ FIFORESET = 0; SYNCDELAY;
+
+ // configure end point FIFOs
+
+ // let core see 0 to 1 transistion of autoout bit
+
+ EP2FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY;
+ EP6FIFOCFG = bmZEROLENIN | bmWORDWIDE; SYNCDELAY;
+ //EP6FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP4FIFOCFG = bmWORDWIDE; SYNCDELAY;
+ EP4FIFOCFG = bmAUTOOUT | bmWORDWIDE; SYNCDELAY;
+ EP8FIFOCFG = bmAUTOIN | bmWORDWIDE; SYNCDELAY;
+
+ EP0BCH = 0; SYNCDELAY;
+
+ // arm EP1OUT so we can receive "out" packets (TRM pg 8-8)
+
+ EP1OUTBC = 0; SYNCDELAY;
+
+ EP2GPIFFLGSEL = 0x00; SYNCDELAY; // For EP2OUT, GPIF uses EF flag
+ EP6GPIFFLGSEL = 0x00; SYNCDELAY; // For EP6IN, GPIF uses FF flag
+ EP4GPIFFLGSEL = 0x00; SYNCDELAY;
+ EP8GPIFFLGSEL = 0x00; SYNCDELAY;
+
+ // set autoin length for EP6
+ // FIXME should be f(enumeration)
+
+ EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed
+ EP6AUTOINLENL = (512) & 0xff; SYNCDELAY;
+
+ EP8AUTOINLENH = (32) >> 8; SYNCDELAY;
+ EP8AUTOINLENL = (32) & 0xff; SYNCDELAY;
+
+ init_board ();
+}
+
diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c
new file mode 100644
index 000000000..7558fadb8
--- /dev/null
+++ b/firmware/fx2/b100/usrp_main.c
@@ -0,0 +1,394 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2004 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+#include "usrp_common.h"
+#include "usrp_commands.h"
+#include "fpga.h"
+#include "usrp_gpif_inline.h"
+#include "timer.h"
+#include "i2c.h"
+#include "isr.h"
+#include "usb_common.h"
+#include "fx2utils.h"
+#include "usrp_globals.h"
+#include "usrp_i2c_addr.h"
+#include <string.h>
+#include "eeprom_io.h"
+#include "usb_descriptors.h"
+
+/*
+ * offsets into boot eeprom for configuration values
+ */
+#define HW_REV_OFFSET 5
+#define SERIAL_NO_OFFSET 248
+#define SERIAL_NO_LEN 8
+
+
+#define bRequestType SETUPDAT[0]
+#define bRequest SETUPDAT[1]
+#define wValueL SETUPDAT[2]
+#define wValueH SETUPDAT[3]
+#define wIndexL SETUPDAT[4]
+#define wIndexH SETUPDAT[5]
+#define wLengthL SETUPDAT[6]
+#define wLengthH SETUPDAT[7]
+
+
+unsigned char g_tx_enable = 0;
+unsigned char g_rx_enable = 0;
+unsigned char g_rx_overrun = 0;
+unsigned char g_tx_underrun = 0;
+bit enable_gpif = 0;
+
+/*
+ * the host side fpga loader code pushes an MD5 hash of the bitstream
+ * into hash1.
+ */
+#define USRP_HASH_SIZE 16
+xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE];
+
+void clear_fpga_data_fifo(void);
+
+static void
+get_ep0_data (void)
+{
+ EP0BCL = 0; // arm EP0 for OUT xfer. This sets the busy bit
+
+ while (EP0CS & bmEPBUSY) // wait for busy to clear
+ ;
+}
+
+static void initialize_gpif_buffer(int ep) {
+ //clear the GPIF buffers on startup to keep crap out of the data path
+ FIFORESET = 0x80; SYNCDELAY; //activate NAKALL
+ FIFORESET = ep; SYNCDELAY;
+ FIFORESET = 0x00; SYNCDELAY;
+}
+
+/*
+ * Handle our "Vendor Extension" commands on endpoint 0.
+ * If we handle this one, return non-zero.
+ */
+unsigned char
+app_vendor_cmd (void)
+{
+ if (bRequestType == VRT_VENDOR_IN){
+
+ /////////////////////////////////
+ // handle the IN requests
+ /////////////////////////////////
+
+ switch (bRequest){
+
+ case VRQ_GET_STATUS: //this is no longer done via FX2 -- the FPGA will be queried instead
+ return 0;
+ break;
+
+ case VRQ_I2C_READ:
+ if (!i2c_read (wValueL, EP0BUF, wLengthL)) return 0;
+ EP0BCH = 0;
+ EP0BCL = wLengthL;
+ break;
+
+ case VRQ_SPI_READ:
+ return 0;
+
+ case VRQ_FW_COMPAT:
+ EP0BCH = 0;
+ EP0BCL = 2;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ else if (bRequestType == VRT_VENDOR_OUT){
+
+ /////////////////////////////////
+ // handle the OUT requests
+ /////////////////////////////////
+
+ switch (bRequest){
+
+ case VRQ_SET_LED:
+ switch (wIndexL){
+ case 0:
+ set_led_0 (wValueL);
+ break;
+
+ case 1:
+ set_led_1 (wValueL);
+ break;
+
+ default:
+ return 0;
+ }
+ break;
+
+ case VRQ_FPGA_LOAD:
+ switch (wIndexL){ // sub-command
+ case FL_BEGIN:
+ return fpga_load_begin ();
+
+ case FL_XFER:
+ get_ep0_data ();
+ return fpga_load_xfer (EP0BUF, EP0BCL);
+
+ case FL_END:
+ return fpga_load_end ();
+
+ default:
+ return 0;
+ }
+ break;
+
+ case VRQ_FPGA_SET_RESET:
+ //fpga_set_reset (wValueL);
+ break;
+
+ case VRQ_I2C_WRITE:
+ get_ep0_data ();
+ if (!i2c_write (wValueL, EP0BUF, EP0BCL)) return 0;
+ //USRP_LED_REG ^= bmLED1;
+ break;
+
+ case VRQ_RESET_GPIF:
+ initialize_gpif_buffer(wValueL);
+ break;
+
+ case VRQ_ENABLE_GPIF:
+ enable_gpif = (wValueL != 0) ? 1 : 0;
+ set_led_1(enable_gpif);
+ break;
+
+ case VRQ_CLEAR_FPGA_FIFO:
+ clear_fpga_data_fifo();
+ break;
+
+ default:
+ return 0;
+ }
+
+ }
+ else
+ return 0; // invalid bRequestType
+
+ return 1;
+}
+
+static int short_pkt_state = 0;
+#define SHORT_PACKET_DETECTED (short_pkt_state != bitSHORT_PACKET_SIGNAL)
+
+//yes, this is a little opaque
+//basically this is necessary because while all the logic to inform the FPGA
+//of what we're trying to do via the CTL pins is contained within the flowstates,
+//we need to assert the endpoint select pin one clock cycle before the flowstate starts.
+//this is the job of the wave descriptor. rather than switch between waves, since that
+//involves a little more setup, we just modify the wave table on the fly.
+inline static void setup_wave_data_read(void) {
+ GPIF_WAVE_DATA[80] = 0x06;
+ GPIF_WAVE_DATA[81] = 0x06;
+}
+
+inline static void setup_wave_ctrl_read(void) {
+ GPIF_WAVE_DATA[80] = 0x0E;
+ GPIF_WAVE_DATA[81] = 0x0E;
+}
+
+inline static void setup_wave_data_write(void) {
+ GPIF_WAVE_DATA[112] = 0x00;
+ GPIF_WAVE_DATA[113] = 0x00;
+}
+
+inline static void setup_wave_ctrl_write(void) {
+ GPIF_WAVE_DATA[112] = 0x08;
+ GPIF_WAVE_DATA[113] = 0x08;
+}
+
+inline static void handle_data_write(void) {
+ GPIFTCB1 = 0x01; //SYNCDELAY;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_write ();
+ setup_wave_data_write();
+ GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+}
+
+inline static void handle_ctrl_write(void) {
+ GPIFTCB1 = 0x00;
+ GPIFTCB0 = 0x10;
+ setup_flowstate_ctrl_write ();
+ setup_wave_ctrl_write();
+ GPIFTRIG = bmGPIF_EP4_START | bmGPIF_WRITE; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+}
+
+inline static void handle_data_read(void) {
+ GPIFTCB1 = 0x01;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_read ();
+ setup_wave_data_read();
+ short_pkt_state = bitSHORT_PACKET_SIGNAL;
+ GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ INPKTEND = 0x06; // tell USB we filled buffer (6 is our endpoint num)
+ SYNCDELAY;
+ if(SHORT_PACKET_DETECTED) {
+ while(!(EP6CS & bmEPEMPTY)); //wait for packet to send
+ INPKTEND = 0x06; //send a ZLP
+ //toggle_led_1(); //FIXME DEBUG
+ }
+}
+
+inline static void handle_ctrl_read(void) {
+ GPIFTCB1 = 0x00;
+ GPIFTCB0 = 0x10;
+ setup_flowstate_ctrl_read ();
+ setup_wave_ctrl_read();
+ GPIFTRIG = bmGPIF_EP8_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ INPKTEND = 8; // tell USB we filled buffer (8 is our endpoint num)
+}
+
+//clear the FPGA datapath by reading but not submitting, instead clearing the FIFO after each transaction
+void clear_fpga_data_fifo(void) {
+ while(fpga_has_data_packet_avail()) {
+ GPIFTCB1 = 0x01;
+ GPIFTCB0 = 0x00;
+ setup_flowstate_data_read ();
+ setup_wave_data_read();
+ GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
+ SYNCDELAY;
+ while (!(GPIFTRIG & bmGPIF_IDLE));
+ initialize_gpif_buffer(6); //reset the FIFO instead of committing it
+ }
+}
+
+static void
+main_loop (void)
+{
+ while (1){
+ if (usb_setup_packet_avail ())
+ usb_handle_setup_packet ();
+
+ if(enable_gpif){
+ if (fx2_has_ctrl_packet_avail() && fpga_has_room_for_ctrl_packet()) handle_ctrl_write();
+ if (fx2_has_room_for_ctrl_packet() && fpga_has_ctrl_packet_avail()) handle_ctrl_read();
+
+ //we do this
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //five times so that
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //we can piggyback
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //data transfers
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ //without loop overhead
+ if (fx2_has_data_packet_avail() && fpga_has_room_for_data_packet()) handle_data_write();
+ if (fx2_has_room_for_data_packet() && fpga_has_data_packet_avail()) handle_data_read();
+ }
+ }
+}
+
+/*
+ * called at 100 Hz from timer2 interrupt
+ *
+ * Toggle led 0
+ */
+void
+isr_tick (void) interrupt
+{
+ static unsigned char count = 1;
+
+ if (--count == 0){
+ count = 50;
+ USRP_LED_REG ^= bmLED0;
+ }
+
+ clear_timer_irq ();
+}
+
+/*
+ * Read h/w rev code and serial number out of boot eeprom and
+ * patch the usb descriptors with the values.
+ */
+void
+patch_usb_descriptors(void)
+{
+ static xdata unsigned char hw_rev;
+ static xdata unsigned char serial_no[8];
+ unsigned char i;
+
+ eeprom_read(I2C_ADDR_BOOT, HW_REV_OFFSET, &hw_rev, 1); // LSB of device id
+ usb_desc_hw_rev_binary_patch_location_0[0] = hw_rev;
+ usb_desc_hw_rev_binary_patch_location_1[0] = hw_rev;
+ usb_desc_hw_rev_ascii_patch_location_0[0] = hw_rev + '0'; // FIXME if we get > 9
+
+ eeprom_read(I2C_ADDR_BOOT, SERIAL_NO_OFFSET, serial_no, SERIAL_NO_LEN);
+
+ for (i = 0; i < SERIAL_NO_LEN; i++){
+ unsigned char ch = serial_no[i];
+ if (ch == 0xff) // make unprogrammed EEPROM default to '0'
+ ch = '0';
+ usb_desc_serial_number_ascii[i << 1] = ch;
+ }
+}
+
+void
+main (void)
+{
+ enable_gpif = 0;
+
+ memset (hash1, 0, USRP_HASH_SIZE); // zero fpga bitstream hash. This forces reload
+
+ init_usrp ();
+ init_gpif ();
+
+ // if (UC_START_WITH_GSTATE_OUTPUT_ENABLED)
+ //IFCONFIG |= bmGSTATE; // no conflict, start with it on
+
+ set_led_0 (0);
+ set_led_1 (0);
+
+ EA = 0; // disable all interrupts
+
+ patch_usb_descriptors();
+
+ setup_autovectors ();
+ usb_install_handlers ();
+ //hook_timer_tick ((unsigned short) isr_tick);
+
+ EIEX4 = 1; // disable INT4 FIXME
+ EA = 1; // global interrupt enable
+
+ fx2_renumerate (); // simulates disconnect / reconnect
+
+ setup_flowstate_common();
+ main_loop ();
+}
diff --git a/firmware/fx2/b100/usrp_regs.h b/firmware/fx2/b100/usrp_regs.h
new file mode 100644
index 000000000..775b5dfd3
--- /dev/null
+++ b/firmware/fx2/b100/usrp_regs.h
@@ -0,0 +1,126 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * These are the register definitions for the Rev 1 USRP prototype
+ * The Rev 1 is the version with the AD9862's and daughterboards
+ */
+
+#ifndef _B100_REGS_H_
+#define _B100_REGS_H_
+
+#include "fx2regs.h"
+
+/*
+ * Port A (bit addressable):
+ */
+
+#define USRP_PA IOA // Port A
+#define USRP_PA_OE OEA // Port A direction register
+
+#define USRP_ALTERA_CONFIG USRP_PA // Now on port A, not C
+
+#define bmALTERA_DCLK bmBIT0
+#define bmALTERA_NCONFIG bmBIT1
+#define bmALTERA_DATA0 bmBIT3
+#define bmALTERA_NSTATUS bmBIT4
+#define bmALTERA_CONF_DONE bmBIT5
+#define bmRESET_FPGA_FIFOS bmBIT7
+
+
+#define bmALTERA_BITS (bmALTERA_DCLK \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DATA0 \
+ | bmALTERA_NSTATUS \
+ | bmALTERA_CONF_DONE \
+ )
+
+
+#define bmPORT_A_OUTPUTS (bmALTERA_DCLK \
+ | bmALTERA_NCONFIG \
+ | bmALTERA_DATA0 \
+ )
+
+#define bmPORT_A_INITIAL 0
+
+sbit at 0x80+0 bitALTERA_DCLK; // 0x80 is the bit address of PORT A
+sbit at 0x80+2 bitSHORT_PACKET_SIGNAL;
+sbit at 0x80+3 bitALTERA_DATA0;
+
+
+/* Port B: GPIF FD[7:0] */
+
+/*
+ * Port C (bit addressable):
+ * 5:1 FPGA configuration
+ */
+
+#define USRP_PC IOC // Port C
+#define USRP_PC_OE OEC // Port C direction register
+
+#define bmPC_nRESET 0 //bmBIT0 // reset line to codecs (active low)
+#define bmPC_LED0 bmBIT0 // active low
+#define bmPC_LED1 bmBIT1 // active low
+
+#define bmPORT_C_OUTPUTS (bmPC_LED0 | bmPC_LED1)
+#define bmPORT_C_INITIAL (bmPC_LED0 | bmPC_LED1)
+
+
+#define USRP_LED_REG USRP_PC
+#define bmLED0 bmPC_LED0
+#define bmLED1 bmPC_LED1
+
+
+/* Port D: GPIF FD[15:8] */
+
+/* Port E: not bit addressible */
+
+#define USRP_PE IOE // Port E
+#define USRP_PE_OE OEE // Port E direction register
+
+#define bmPORT_E_OUTPUTS (0)
+#define bmPORT_E_INITIAL (0)
+
+/*
+ * FPGA output lines that are tied to FX2 RDYx inputs.
+ * These are readable using GPIFREADYSTAT.
+ */
+//#define bmFPGA_HAS_SPACE bmBIT0 // usbrdy[0] has room for 512 byte packet
+//#define bmFPGA_PKT_AVAIL bmBIT1 // usbrdy[1] has >= 512 bytes available
+
+#define bmDATA_EMPTY bmBIT0 //data output FIFO has no data ready
+#define bmDATA_FIFO_FULL bmBIT1 //data input FIFO is full
+#define bmCTRL_EMPTY bmBIT2 //control output FIFO has no data ready
+#define bmCTRL_FIFO_FULL bmBIT3 //control input FIFO is full
+
+// #define bmTX_UNDERRUN bmBIT2 // usbrdy[2] D/A ran out of data
+// #define bmRX_OVERRUN bmBIT3 // usbrdy[3] A/D ran out of buffer
+
+/*
+ * FPGA input lines that are tied to the FX2 CTLx outputs.
+ *
+ * These are controlled by the GPIF microprogram...
+ */
+// WE bmBIT0 // usbctl[0] write enable
+// RE bmBIT1 // usbctl[1] read enable
+// OE bmBIT2 // usbctl[2] output enable
+// EP bmBIT3 // usbctl[3] endpoint select (data/ctrl)
+
+#endif /* _USRP_REV1_REGS_H_ */
diff --git a/firmware/fx2/common/fx2regs.h b/firmware/fx2/common/fx2regs.h
index 2f210f567..aa44791d0 100644
--- a/firmware/fx2/common/fx2regs.h
+++ b/firmware/fx2/common/fx2regs.h
@@ -664,6 +664,10 @@ sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
// must be zero bmBIT1
#define bmWORDWIDE bmBIT0
+/* EP 24 FIFO Flag bits (EP24FIFOFLGS) */
+#define EP2FIFOEMPTY bmBIT1
+#define EP4FIFOEMPTY bmBIT5
+
/*
* Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specific features
*/
diff --git a/firmware/fx2/common/usrp_commands.h b/firmware/fx2/common/usrp_commands.h
index 20c28e264..2466729b2 100644
--- a/firmware/fx2/common/usrp_commands.h
+++ b/firmware/fx2/common/usrp_commands.h
@@ -54,6 +54,8 @@
// wIndexL: format
// len: how much to read
+#define VRQ_FW_COMPAT 0x83 //low 16 bits
+
// OUT commands
#define VRQ_SET_LED 0x01 // wValueL off/on {0,1}; wIndexL: which {0,1}
@@ -87,6 +89,10 @@
#define VRQ_FPGA_SET_TX_RESET 0x0a // wValueL: {0, 1}
#define VRQ_FPGA_SET_RX_RESET 0x0b // wValueL: {0, 1}
+#define VRQ_RESET_GPIF 0x0c
+#define VRQ_ENABLE_GPIF 0x0d
+#define VRQ_CLEAR_FPGA_FIFO 0x0e
+
// -------------------------------------------------------------------
// we store the hashes at fixed addresses in the FX2 internal memory
diff --git a/firmware/fx2/utils/build_eeprom.py b/firmware/fx2/utils/build_eeprom.py
index 298ccc00c..af425554a 100755
--- a/firmware/fx2/utils/build_eeprom.py
+++ b/firmware/fx2/utils/build_eeprom.py
@@ -27,8 +27,10 @@ from optparse import OptionParser
# USB Vendor and Product ID's
-VID = 0xfffe # Free Software Folks
-
+USRP1VID = 0xfffe # Free Software Folks
+USRP1PID = 0x0002
+USRP1PVID= 0x2500 # Ettus Research
+USRP1PPID= 0x0001
def msb (x):
return (x >> 8) & 0xff
@@ -50,9 +52,11 @@ def build_eeprom_image (filename, rev):
start_addr = 0 #prove me wrong
if(rev == 1):
- PID = 0x0002 #USRP1
+ VID = USRP1VID
+ PID = USRP1PPID
else:
- PID = 0x0003 #USRP1P
+ VID = USRP1PVID
+ PID = USRP1PPID
rom_header = [
0xC2, # boot from EEPROM
diff --git a/firmware/fx2/utils/edit-gpif-b100.py b/firmware/fx2/utils/edit-gpif-b100.py
new file mode 100755
index 000000000..fd949cd8a
--- /dev/null
+++ b/firmware/fx2/utils/edit-gpif-b100.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# -*- Python -*-
+#
+# Copyright 2003 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+
+# Edit the gpif.c file generated by the Cypress GPIF Designer Tool and
+# produce usrp_gpif.c, and usrp_gpif_inline.h, files suitable for our
+# uses.
+
+import re
+import string
+import sys
+
+def check_flow_state (line, flow_state_dict):
+ mo = re.match (r'/\* Wave (\d) FlowStates \*/ (.*),', line)
+ if mo:
+ wave = int (mo.group (1))
+ data = mo.group (2)
+ split = data.split (',', 8)
+ v = map (lambda x : int (x, 16), split)
+ # print "%s, %s" % (wave, data)
+ # print "split: ", split
+ # print "v : ", v
+ flow_state_dict[wave] = v
+
+
+def delta (xseq, yseq):
+ # set subtraction
+ z = []
+ for x in xseq:
+ if x not in yseq:
+ z.append (x)
+ return z
+
+
+def write_define (output, name, pairs):
+ output.write ('#define %s()\t\\\n' % name)
+ output.write ('do {\t\t\t\t\t\\\n')
+ for reg, val in pairs:
+ output.write ('%14s = 0x%02x;\t\t\t\\\n' % (reg, val))
+ output.write ('} while (0)\n\n')
+
+def write_inlines (output, dict):
+ regs = ['FLOWSTATE', 'FLOWLOGIC', 'FLOWEQ0CTL', 'FLOWEQ1CTL', 'FLOWHOLDOFF',
+ 'FLOWSTB', 'FLOWSTBEDGE', 'FLOWSTBHPERIOD', 'GPIFHOLDAMOUNT']
+
+ READ_CTRL_FLOW_STATE = 0
+ WRITE_CTRL_FLOW_STATE = 1
+ READ_DATA_FLOW_STATE = 2
+ WRITE_DATA_FLOW_STATE = 3
+
+ read_data_info = zip (regs, dict[READ_DATA_FLOW_STATE])
+ write_data_info = zip (regs, dict[WRITE_DATA_FLOW_STATE])
+ read_ctrl_info = zip (regs, dict[READ_CTRL_FLOW_STATE])
+ write_ctrl_info = zip (regs, dict[WRITE_CTRL_FLOW_STATE])
+
+ output.write ('''/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+''')
+ write_define (output, 'setup_flowstate_common', read_data_info) #assumes that the same registers will change, this isn't really good
+ write_define (output, 'setup_flowstate_data_read', delta (read_data_info, write_data_info))
+ write_define (output, 'setup_flowstate_data_write', delta (write_data_info, read_data_info))
+ write_define (output, 'setup_flowstate_ctrl_read', delta (read_ctrl_info, write_ctrl_info))
+ write_define (output, 'setup_flowstate_ctrl_write', delta (write_ctrl_info, read_ctrl_info))
+
+
+def edit_gpif (input_name, output_name, inline_name):
+ input = open (input_name, 'r')
+ output = open (output_name, 'w')
+ inline = open (inline_name, 'w')
+ flow_state_dict = {}
+
+ output.write ('''/*
+ * Machine generated by "edit-gpif". Do not edit by hand.
+ */
+
+''')
+
+ while 1:
+ line = input.readline ()
+ line = string.replace (line, '\r','')
+ line = re.sub (r' *$', r'', line)
+
+ check_flow_state (line, flow_state_dict)
+
+ line = re.sub (r'#include', r'// #include', line)
+ line = re.sub (r'xdata ', r'', line)
+ if re.search (r'GpifInit', line):
+ break
+
+ output.write (line)
+
+ output.close ()
+ write_inlines (inline, flow_state_dict)
+ inline.close ()
+
+
+# gpif.c usrp_gpif.c usrp_gpif_inline.h
+edit_gpif (sys.argv[1], sys.argv[2], sys.argv[3])
diff --git a/fpga/usrp2/control_lib/Makefile.srcs b/fpga/usrp2/control_lib/Makefile.srcs
index 751b40828..a1c11c026 100644
--- a/fpga/usrp2/control_lib/Makefile.srcs
+++ b/fpga/usrp2/control_lib/Makefile.srcs
@@ -50,4 +50,5 @@ bootram.v \
nsgpio16LE.v \
settings_bus_16LE.v \
atr_controller16.v \
+fifo_to_wb.v \
))
diff --git a/fpga/usrp2/control_lib/atr_controller.v b/fpga/usrp2/control_lib/atr_controller.v
index a161b5e00..2cef8ba2b 100644
--- a/fpga/usrp2/control_lib/atr_controller.v
+++ b/fpga/usrp2/control_lib/atr_controller.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Automatic transmit/receive switching of control pins to daughterboards
// Store everything in registers for now, but could use a RAM for more
diff --git a/fpga/usrp2/control_lib/atr_controller16.v b/fpga/usrp2/control_lib/atr_controller16.v
index 74ce30a54..ff4f634c7 100644
--- a/fpga/usrp2/control_lib/atr_controller16.v
+++ b/fpga/usrp2/control_lib/atr_controller16.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Automatic transmit/receive switching of control pins to daughterboards
// Store everything in registers for now, but could use a RAM for more
diff --git a/fpga/usrp2/control_lib/bin2gray.v b/fpga/usrp2/control_lib/bin2gray.v
index 513402163..8336a5afc 100644
--- a/fpga/usrp2/control_lib/bin2gray.v
+++ b/fpga/usrp2/control_lib/bin2gray.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module bin2gray
diff --git a/fpga/usrp2/control_lib/bootram.v b/fpga/usrp2/control_lib/bootram.v
index 29d21ab5a..249a09814 100644
--- a/fpga/usrp2/control_lib/bootram.v
+++ b/fpga/usrp2/control_lib/bootram.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Boot RAM for S3A, 8KB, dual port
diff --git a/fpga/usrp2/control_lib/clock_bootstrap_rom.v b/fpga/usrp2/control_lib/clock_bootstrap_rom.v
index 46563db65..542f49380 100644
--- a/fpga/usrp2/control_lib/clock_bootstrap_rom.v
+++ b/fpga/usrp2/control_lib/clock_bootstrap_rom.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module clock_bootstrap_rom(input [15:0] addr, output [47:0] data);
diff --git a/fpga/usrp2/control_lib/clock_control.v b/fpga/usrp2/control_lib/clock_control.v
index 1bbe6bd75..000eaf1fb 100644
--- a/fpga/usrp2/control_lib/clock_control.v
+++ b/fpga/usrp2/control_lib/clock_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// AD9510 Register Map (from datasheet Rev. A)
diff --git a/fpga/usrp2/control_lib/clock_control_tb.v b/fpga/usrp2/control_lib/clock_control_tb.v
index 4e705cf23..9760efbe3 100644
--- a/fpga/usrp2/control_lib/clock_control_tb.v
+++ b/fpga/usrp2/control_lib/clock_control_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module clock_control_tb();
diff --git a/fpga/usrp2/control_lib/dcache.v b/fpga/usrp2/control_lib/dcache.v
index 9063bf02a..384c5a149 100644
--- a/fpga/usrp2/control_lib/dcache.v
+++ b/fpga/usrp2/control_lib/dcache.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module dcache
#(parameter AWIDTH=14,
diff --git a/fpga/usrp2/control_lib/decoder_3_8.v b/fpga/usrp2/control_lib/decoder_3_8.v
index 729b45d18..8f91d8263 100644
--- a/fpga/usrp2/control_lib/decoder_3_8.v
+++ b/fpga/usrp2/control_lib/decoder_3_8.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module decoder_3_8
(input [2:0] sel,
diff --git a/fpga/usrp2/control_lib/dpram32.v b/fpga/usrp2/control_lib/dpram32.v
index 4da621823..386435e70 100644
--- a/fpga/usrp2/control_lib/dpram32.v
+++ b/fpga/usrp2/control_lib/dpram32.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Dual ported RAM
// Addresses are byte-oriented, so botton 2 address bits are ignored.
diff --git a/fpga/usrp2/control_lib/fifo_tb.v b/fpga/usrp2/control_lib/fifo_tb.v
deleted file mode 100644
index 616fe4ee7..000000000
--- a/fpga/usrp2/control_lib/fifo_tb.v
+++ /dev/null
@@ -1,151 +0,0 @@
-module fifo_tb();
-
- reg clk, rst;
- wire short_full, short_empty, long_full, long_empty;
- wire casc2_full, casc2_empty;
- reg read, write;
-
- wire [7:0] short_do, long_do;
- wire [7:0] casc2_do;
- reg [7:0] di;
-
- reg clear = 0;
-
- shortfifo #(.WIDTH(8)) shortfifo
- (.clk(clk),.rst(rst),.datain(di),.dataout(short_do),.clear(clear),
- .read(read),.write(write),.full(short_full),.empty(short_empty));
-
- longfifo #(.WIDTH(8), .SIZE(4)) longfifo
- (.clk(clk),.rst(rst),.datain(di),.dataout(long_do),.clear(clear),
- .read(read),.write(write),.full(long_full),.empty(long_empty));
-
- cascadefifo2 #(.WIDTH(8), .SIZE(4)) cascadefifo2
- (.clk(clk),.rst(rst),.datain(di),.dataout(casc2_do),.clear(clear),
- .read(read),.write(write),.full(casc2_full),.empty(casc2_empty));
-
- initial rst = 1;
- initial #1000 rst = 0;
- initial clk = 0;
- always #50 clk = ~clk;
-
- initial di = 8'hAE;
- initial read = 0;
- initial write = 0;
-
- always @(posedge clk)
- if(write)
- di <= di + 1;
-
- always @(posedge clk)
- begin
- if(short_full != long_full)
- $display("Error: FULL mismatch");
- if(short_empty != long_empty)
- $display("Note: EMPTY mismatch, usually not a problem (longfifo has 2 cycle latency)");
- if(read & (short_do != long_do))
- $display("Error: DATA mismatch");
- end
-
- initial $dumpfile("fifo_tb.vcd");
- initial $dumpvars(0,fifo_tb);
-
- initial
- begin
- @(negedge rst);
- @(posedge clk);
- repeat (10)
- @(posedge clk);
- write <= 1;
- @(posedge clk);
- write <= 0;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- read <= 1;
- @(posedge clk);
- read <= 0;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
-
- repeat(10)
- begin
- write <= 1;
- @(posedge clk);
- write <= 0;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- read <= 1;
- @(posedge clk);
- read <= 0;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- end // repeat (10)
-
- write <= 1;
- repeat (4)
- @(posedge clk);
- write <= 0;
- @(posedge clk);
- read <= 1;
- repeat (4)
- @(posedge clk);
- read <= 0;
- @(posedge clk);
-
-
- write <= 1;
- repeat (4)
- @(posedge clk);
- write <= 0;
- @(posedge clk);
- repeat (4)
- begin
- read <= 1;
- @(posedge clk);
- read <= 0;
- @(posedge clk);
- end
-
- write <= 1;
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- @(posedge clk);
- read <= 1;
- repeat (5)
- @(posedge clk);
- write <= 0;
- @(posedge clk);
- @(posedge clk);
- read <= 0;
- @(posedge clk);
-
- write <= 1;
- repeat (16)
- @(posedge clk);
- write <= 0;
- @(posedge clk);
-
- read <= 1;
- repeat (16)
- @(posedge clk);
- read <= 0;
- @(posedge clk);
-
- repeat (10)
- @(posedge clk);
- $finish;
- end
-endmodule // longfifo_tb
diff --git a/fpga/usrp2/control_lib/fifo_to_wb.v b/fpga/usrp2/control_lib/fifo_to_wb.v
new file mode 100644
index 000000000..9b6b5e804
--- /dev/null
+++ b/fpga/usrp2/control_lib/fifo_to_wb.v
@@ -0,0 +1,183 @@
+//
+// 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/>.
+//
+
+
+module fifo_to_wb
+ #(parameter PKT_LEN = 16)
+ (input clk, input reset, input clear,
+ input [18:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [18:0] data_o, output src_rdy_o, input dst_rdy_i,
+ output reg [15:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso,
+ output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i,
+ input [7:0] triggers,
+ output [31:0] debug0, output [31:0] debug1);
+
+ wire [18:0] ctrl_data;
+ reg [18:0] resp_data;
+ wire ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy;
+
+ fifo_short #(.WIDTH(19)) ctrl_sfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data_i), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o),
+ .dataout(ctrl_data), .src_rdy_o(ctrl_src_rdy), .dst_rdy_i(ctrl_dst_rdy));
+
+ fifo_short #(.WIDTH(19)) resp_sfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(resp_data), .src_rdy_i(resp_src_rdy), .dst_rdy_o(resp_dst_rdy),
+ .dataout(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i));
+
+ // Need a programmable state machine here. The program is the fifo contents.
+ // All words are 16 bits wide
+ // Word 0 Command { Read, Write, Triggers[5:0], Seqno [7:0] }
+ // Word 1 Length
+ // Word 2 Address LSW
+ // Word 3 Address MSW (should all be 0)
+
+ localparam RESP_IDLE = 0;
+ localparam RESP_LEN = 1;
+ localparam RESP_ADDR_LSW = 2;
+ localparam RESP_ADDR_MSW = 3;
+ localparam RESP_WRITE = 4;
+ localparam RESP_DUMP = 5;
+ localparam RESP_WAIT_READ = 6;
+ localparam RESP_RCMD = 7;
+ localparam RESP_RLEN = 8;
+ localparam RESP_RADDR_LSW = 9;
+ localparam RESP_RADDR_MSW = 10;
+ localparam RESP_READ = 11;
+
+ reg [3:0] resp_state;
+ reg rd, wr;
+ reg [15:0] base_addr;
+ reg [15:0] length;
+ reg [15:0] count;
+ reg [7:0] seqnum;
+ reg [5:0] which_trig;
+
+ always @(posedge clk)
+ if(reset | clear)
+ resp_state <= RESP_IDLE;
+ else
+ case(resp_state)
+ RESP_IDLE :
+ if(ctrl_src_rdy)
+ begin
+ { rd, wr, which_trig[5:0], seqnum[7:0] } <= ctrl_data[15:0];
+ if(ctrl_data[16]) // WAIT for start of packet, clean out otherwise
+ resp_state <= RESP_LEN;
+ end
+ RESP_LEN :
+ if(ctrl_src_rdy)
+ begin
+ length <= ctrl_data[15:0];
+ count <= ctrl_data[15:0];
+ resp_state <= RESP_ADDR_LSW;
+ end
+ RESP_ADDR_LSW :
+ if(ctrl_src_rdy)
+ begin
+ base_addr <= ctrl_data[15:0];
+ wb_adr_o <= ctrl_data[15:0];
+ resp_state <= RESP_ADDR_MSW;
+ end
+ RESP_ADDR_MSW :
+ if(ctrl_src_rdy)
+ if(wr)
+ resp_state <= RESP_WRITE;
+ else
+ resp_state <= RESP_DUMP;
+ RESP_WRITE :
+ if(ctrl_src_rdy & wb_ack_i)
+ if(count==1)
+ if(ctrl_data[17]) //eof
+ resp_state <= RESP_IDLE;
+ else // clean out padding
+ resp_state <= RESP_DUMP;
+ else
+ begin
+ wb_adr_o <= wb_adr_o + 2;
+ count <= count - 1;
+ end
+ RESP_DUMP :
+ if(ctrl_src_rdy & ctrl_data[17])
+ if(rd)
+ resp_state <= RESP_WAIT_READ;
+ else
+ resp_state <= RESP_IDLE;
+ RESP_WAIT_READ :
+ begin
+ wb_adr_o <= base_addr;
+ count <= length;
+ if( &(triggers | ~which_trig) )
+ resp_state <= RESP_RCMD;
+ end
+ RESP_RCMD :
+ if(resp_dst_rdy)
+ resp_state <= RESP_RLEN;
+ RESP_RLEN :
+ if(resp_dst_rdy)
+ resp_state <= RESP_RADDR_LSW;
+ RESP_RADDR_LSW :
+ if(resp_dst_rdy)
+ resp_state <= RESP_RADDR_MSW;
+ RESP_RADDR_MSW :
+ if(resp_dst_rdy)
+ resp_state <= RESP_READ;
+ RESP_READ :
+ if(resp_dst_rdy & wb_ack_i)
+ if(count==1)
+ resp_state <= RESP_IDLE;
+ else
+ begin
+ wb_adr_o <= wb_adr_o + 2;
+ count <= count - 1;
+ end
+ endcase // case (resp_state)
+
+ always @*
+ case(resp_state)
+ RESP_RCMD : resp_data <= { 3'b001, 8'hAA, seqnum };
+ RESP_RLEN : resp_data <= { 3'b000, length };
+ RESP_RADDR_LSW : resp_data <= { 3'b000, base_addr };
+ RESP_RADDR_MSW : resp_data <= { 3'b000, 16'd0 };
+ default : resp_data <= { 1'b0, (count==1), 1'b0, wb_dat_miso };
+ endcase // case (resp_state)
+
+ assign ctrl_dst_rdy = (resp_state == RESP_IDLE) |
+ (resp_state == RESP_LEN) |
+ (resp_state == RESP_ADDR_LSW) |
+ (resp_state == RESP_ADDR_MSW) |
+ ((resp_state == RESP_WRITE) & wb_ack_i) |
+ (resp_state == RESP_DUMP);
+
+ assign resp_src_rdy = (resp_state == RESP_RCMD) |
+ (resp_state == RESP_RLEN) |
+ (resp_state == RESP_RADDR_LSW) |
+ (resp_state == RESP_RADDR_MSW) |
+ ((resp_state == RESP_READ) & wb_ack_i);
+
+ assign wb_dat_mosi = ctrl_data[15:0];
+ assign wb_we_o = (resp_state == RESP_WRITE);
+ assign wb_cyc_o = wb_stb_o;
+ assign wb_sel_o = 2'b11;
+ assign wb_stb_o = (ctrl_src_rdy & (resp_state == RESP_WRITE)) | (resp_dst_rdy & (resp_state == RESP_READ));
+
+
+ assign debug0 = { 14'd0, ctrl_data[17:0] };
+ assign debug1 = { ctrl_src_rdy, ctrl_dst_rdy, resp_src_rdy, resp_dst_rdy, 2'b00, ctrl_data[17:16] };
+
+endmodule // fifo_to_wb
diff --git a/fpga/usrp2/control_lib/fifo_to_wb_tb.v b/fpga/usrp2/control_lib/fifo_to_wb_tb.v
new file mode 100644
index 000000000..37459e2c2
--- /dev/null
+++ b/fpga/usrp2/control_lib/fifo_to_wb_tb.v
@@ -0,0 +1,136 @@
+//
+// 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/>.
+//
+
+module fifo_to_wb_tb();
+
+ reg clk = 0;
+ reg rst = 1;
+ reg clear = 0;
+ initial #1000 rst = 0;
+ always #50 clk = ~clk;
+
+ reg trigger = 0;
+ initial #10000 trigger = 1;
+
+ wire wb_cyc, wb_stb, wb_we, wb_ack;
+ wire [15:0] wb_adr;
+ wire [15:0] wb_dat_miso, wb_dat_mosi;
+
+ reg cmd_src_rdy;
+ wire cmd_dst_rdy, resp_src_rdy, resp_dst_rdy;
+ reg [17:0] cmd;
+ wire [17:0] resp;
+
+ wire [17:0] resp_int;
+ wire resp_src_rdy_int, resp_dst_rdy_int;
+
+ fifo_to_wb fifo_to_wb
+ (.clk(clk), .reset(rst), .clear(clear),
+ .data_i(cmd), .src_rdy_i(cmd_src_rdy), .dst_rdy_o(cmd_dst_rdy),
+ .data_o(resp_int), .src_rdy_o(resp_src_rdy_int), .dst_rdy_i(resp_dst_rdy_int),
+
+ .wb_adr_o(wb_adr), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso),
+ .wb_sel_o(), .wb_cyc_o(wb_cyc), .wb_stb_o(wb_stb),
+ .wb_we_o(wb_we), .wb_ack_i(wb_ack),
+ .triggers());
+
+ assign wb_dat_miso = {wb_adr[7:0],8'hBF};
+
+ fifo19_pad #(.LENGTH(16)) fifo19_pad
+ (.clk(clk), .reset(rst), .clear(clear),
+ .data_i(resp_int), .src_rdy_i(resp_src_rdy_int), .dst_rdy_o(resp_dst_rdy_int),
+ .data_o(resp), .src_rdy_o(resp_src_rdy), .dst_rdy_i(resp_dst_rdy));
+
+
+ // Set up monitors
+ always @(posedge clk)
+ if(wb_cyc & wb_stb & wb_ack)
+ if(wb_we)
+ $display("WB-WRITE ADDR:%h DATA:%h",wb_adr, wb_dat_mosi);
+ else
+ $display("WB-READ ADDR:%h DATA:%h",wb_adr, wb_dat_miso);
+
+ always @(posedge clk)
+ if(cmd_src_rdy & cmd_dst_rdy)
+ $display("CMD-WRITE SOF:%b EOF:%b DATA:%h",cmd[16],cmd[17],cmd[15:0]);
+
+ always @(posedge clk)
+ if(resp_src_rdy & resp_dst_rdy)
+ $display("RESP-READ SOF:%b EOF:%b DATA:%h",resp[16],resp[17],resp[15:0]);
+
+ assign wb_ack = wb_stb;
+ assign resp_dst_rdy = 1;
+
+ task InsertRW;
+ input [15:0] data_start;
+ input [5:0] triggers;
+ input [7:0] seqno;
+ input [15:0] len;
+ input [15:0] addr;
+ reg [15:0] data_val;
+
+ begin
+ data_val <= data_start;
+ @(posedge clk);
+ cmd <= {2'b01,2'b11,triggers,seqno};
+ cmd_src_rdy <= 1;
+ @(posedge clk);
+ cmd <= {2'b00,len};
+ @(posedge clk);
+ cmd <= {2'b00,addr};
+ @(posedge clk);
+ cmd <= {2'b00,16'd0};
+ @(posedge clk);
+ repeat (len)
+ begin
+ cmd <= {2'b00,data_val};
+ data_val <= data_val + 1;
+ @(posedge clk);
+ end
+ repeat (12-len-1)
+ begin
+ cmd <= {2'b00,16'hBEEF};
+ @(posedge clk);
+ end
+ cmd <= {2'b10, 16'hDEAD};
+ @(posedge clk);
+ cmd_src_rdy <= 0;
+ end
+ endtask // InsertRead
+
+ initial $dumpfile("fifo_to_wb_tb.vcd");
+ initial $dumpvars(0,fifo_to_wb_tb);
+
+ initial
+ begin
+ @(negedge rst);
+ //#10000;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ InsertRW(16'hF00D, 6'd0, 8'hB5, 16'd7, 16'h1234);
+ #20000;
+ InsertRW(16'h9876, 6'd0, 8'h43, 16'd8, 16'hBEEF);
+ #20000;
+ InsertRW(16'h1000, 6'd0, 8'h96, 16'd4, 16'hF00D);
+ #20000;
+ InsertRW(16'h3000, 6'd0, 8'h12, 16'd10,16'hDEAD);
+ #20000 $finish;
+ end
+
+endmodule // fifo_to_wb_tb
diff --git a/fpga/usrp2/control_lib/gray2bin.v b/fpga/usrp2/control_lib/gray2bin.v
index 5df40bd52..399d5bba0 100644
--- a/fpga/usrp2/control_lib/gray2bin.v
+++ b/fpga/usrp2/control_lib/gray2bin.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module gray2bin
diff --git a/fpga/usrp2/control_lib/gray_send.v b/fpga/usrp2/control_lib/gray_send.v
index 7fc07d40c..62402f8d3 100644
--- a/fpga/usrp2/control_lib/gray_send.v
+++ b/fpga/usrp2/control_lib/gray_send.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
diff --git a/fpga/usrp2/control_lib/icache.v b/fpga/usrp2/control_lib/icache.v
index bd21f47cc..810b5fa64 100644
--- a/fpga/usrp2/control_lib/icache.v
+++ b/fpga/usrp2/control_lib/icache.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module icache
#(parameter AWIDTH=14,
diff --git a/fpga/usrp2/control_lib/longfifo.v b/fpga/usrp2/control_lib/longfifo.v
index bf3338e0b..c77f2dcb1 100644
--- a/fpga/usrp2/control_lib/longfifo.v
+++ b/fpga/usrp2/control_lib/longfifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIFO intended to be interchangeable with shortfifo, but
// based on block ram instead of SRL16's
diff --git a/fpga/usrp2/control_lib/medfifo.v b/fpga/usrp2/control_lib/medfifo.v
index 5a77e8c16..0f66f6597 100644
--- a/fpga/usrp2/control_lib/medfifo.v
+++ b/fpga/usrp2/control_lib/medfifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module medfifo
#(parameter WIDTH=32,
diff --git a/fpga/usrp2/control_lib/mux4.v b/fpga/usrp2/control_lib/mux4.v
index 31c85c832..b1878f011 100644
--- a/fpga/usrp2/control_lib/mux4.v
+++ b/fpga/usrp2/control_lib/mux4.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module mux4
diff --git a/fpga/usrp2/control_lib/mux8.v b/fpga/usrp2/control_lib/mux8.v
index 9db96a60f..bdb015dc3 100644
--- a/fpga/usrp2/control_lib/mux8.v
+++ b/fpga/usrp2/control_lib/mux8.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module mux8
diff --git a/fpga/usrp2/control_lib/mux_32_4.v b/fpga/usrp2/control_lib/mux_32_4.v
index fef5812e9..4a1244933 100644
--- a/fpga/usrp2/control_lib/mux_32_4.v
+++ b/fpga/usrp2/control_lib/mux_32_4.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module mux_32_4
diff --git a/fpga/usrp2/control_lib/oneshot_2clk.v b/fpga/usrp2/control_lib/oneshot_2clk.v
index 72f16a4b3..7ed5bc8f6 100644
--- a/fpga/usrp2/control_lib/oneshot_2clk.v
+++ b/fpga/usrp2/control_lib/oneshot_2clk.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Retime a single bit from one clock domain to another
// Guarantees that no matter what the relative clock rates, if the in signal is high for at least
diff --git a/fpga/usrp2/control_lib/priority_enc.v b/fpga/usrp2/control_lib/priority_enc.v
index 916192445..d30870be9 100644
--- a/fpga/usrp2/control_lib/priority_enc.v
+++ b/fpga/usrp2/control_lib/priority_enc.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module priority_enc
(input [31:0] in,
diff --git a/fpga/usrp2/control_lib/quad_uart.v b/fpga/usrp2/control_lib/quad_uart.v
index afa6fae1d..39998150d 100644
--- a/fpga/usrp2/control_lib/quad_uart.v
+++ b/fpga/usrp2/control_lib/quad_uart.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module quad_uart
#(parameter TXDEPTH = 1,
diff --git a/fpga/usrp2/control_lib/ram_2port.v b/fpga/usrp2/control_lib/ram_2port.v
index 3716a7c8a..86d7e4703 100644
--- a/fpga/usrp2/control_lib/ram_2port.v
+++ b/fpga/usrp2/control_lib/ram_2port.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram_2port
diff --git a/fpga/usrp2/control_lib/ram_2port_mixed_width.v b/fpga/usrp2/control_lib/ram_2port_mixed_width.v
index fae7d8de3..2910d4041 100644
--- a/fpga/usrp2/control_lib/ram_2port_mixed_width.v
+++ b/fpga/usrp2/control_lib/ram_2port_mixed_width.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram_2port_mixed_width
(input clk16,
diff --git a/fpga/usrp2/control_lib/ram_harv_cache.v b/fpga/usrp2/control_lib/ram_harv_cache.v
index 29fdebf7a..e68ed7f68 100644
--- a/fpga/usrp2/control_lib/ram_harv_cache.v
+++ b/fpga/usrp2/control_lib/ram_harv_cache.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Dual ported, Harvard architecture, cached ram
diff --git a/fpga/usrp2/control_lib/ram_harvard.v b/fpga/usrp2/control_lib/ram_harvard.v
index a190e20fd..00ffb1984 100644
--- a/fpga/usrp2/control_lib/ram_harvard.v
+++ b/fpga/usrp2/control_lib/ram_harvard.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Dual ported, Harvard architecture, cached ram
diff --git a/fpga/usrp2/control_lib/ram_harvard2.v b/fpga/usrp2/control_lib/ram_harvard2.v
index 67777af2a..d8fe472f5 100644
--- a/fpga/usrp2/control_lib/ram_harvard2.v
+++ b/fpga/usrp2/control_lib/ram_harvard2.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Dual ported, Harvard architecture
diff --git a/fpga/usrp2/control_lib/ram_loader.v b/fpga/usrp2/control_lib/ram_loader.v
index c53ea7aa7..85ccf91b4 100644
--- a/fpga/usrp2/control_lib/ram_loader.v
+++ b/fpga/usrp2/control_lib/ram_loader.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram_loader
#(parameter AWIDTH=16, RAM_SIZE=16384)
(
diff --git a/fpga/usrp2/control_lib/ram_wb_harvard.v b/fpga/usrp2/control_lib/ram_wb_harvard.v
index c3efc12e0..8d5a45247 100644
--- a/fpga/usrp2/control_lib/ram_wb_harvard.v
+++ b/fpga/usrp2/control_lib/ram_wb_harvard.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Dual ported RAM for Harvard architecture processors
// Does no forwarding
diff --git a/fpga/usrp2/control_lib/reset_sync.v b/fpga/usrp2/control_lib/reset_sync.v
index 94d966840..304aba106 100644
--- a/fpga/usrp2/control_lib/reset_sync.v
+++ b/fpga/usrp2/control_lib/reset_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module reset_sync
diff --git a/fpga/usrp2/control_lib/s3a_icap_wb.v b/fpga/usrp2/control_lib/s3a_icap_wb.v
index 83d9f775e..e49b56cff 100644
--- a/fpga/usrp2/control_lib/s3a_icap_wb.v
+++ b/fpga/usrp2/control_lib/s3a_icap_wb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module s3a_icap_wb
diff --git a/fpga/usrp2/control_lib/sd_spi.v b/fpga/usrp2/control_lib/sd_spi.v
index 3f4d7f46a..fa998d19a 100644
--- a/fpga/usrp2/control_lib/sd_spi.v
+++ b/fpga/usrp2/control_lib/sd_spi.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module sd_spi
(input clk,
input rst,
diff --git a/fpga/usrp2/control_lib/sd_spi_tb.v b/fpga/usrp2/control_lib/sd_spi_tb.v
index e30a5bdf6..2b5ae083f 100644
--- a/fpga/usrp2/control_lib/sd_spi_tb.v
+++ b/fpga/usrp2/control_lib/sd_spi_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module sd_spi_tb;
diff --git a/fpga/usrp2/control_lib/sd_spi_wb.v b/fpga/usrp2/control_lib/sd_spi_wb.v
index 7a6258b56..b09debd70 100644
--- a/fpga/usrp2/control_lib/sd_spi_wb.v
+++ b/fpga/usrp2/control_lib/sd_spi_wb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Wishbone module for spi communications with an SD Card
// The programming interface is simple --
diff --git a/fpga/usrp2/control_lib/setting_reg.v b/fpga/usrp2/control_lib/setting_reg.v
index 3d3bb65e5..e4c84d910 100644
--- a/fpga/usrp2/control_lib/setting_reg.v
+++ b/fpga/usrp2/control_lib/setting_reg.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module setting_reg
diff --git a/fpga/usrp2/control_lib/settings_bus.v b/fpga/usrp2/control_lib/settings_bus.v
index aec179516..e2ea7e44b 100644
--- a/fpga/usrp2/control_lib/settings_bus.v
+++ b/fpga/usrp2/control_lib/settings_bus.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Grab settings off the wishbone bus, send them out to our simpler bus on the fast clock
diff --git a/fpga/usrp2/control_lib/settings_bus_16LE.v b/fpga/usrp2/control_lib/settings_bus_16LE.v
index 76061e9e0..7c42a0870 100644
--- a/fpga/usrp2/control_lib/settings_bus_16LE.v
+++ b/fpga/usrp2/control_lib/settings_bus_16LE.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Grab settings off the wishbone bus, send them out to settings bus
// 16 bits little endian, but all registers need to be written 32 bits at a time.
diff --git a/fpga/usrp2/control_lib/settings_bus_crossclock.v b/fpga/usrp2/control_lib/settings_bus_crossclock.v
index b043aa0ad..9c5912042 100644
--- a/fpga/usrp2/control_lib/settings_bus_crossclock.v
+++ b/fpga/usrp2/control_lib/settings_bus_crossclock.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// This module takes the settings bus on one clock domain and crosses it over to another domain
diff --git a/fpga/usrp2/control_lib/shortfifo.v b/fpga/usrp2/control_lib/shortfifo.v
index d8ce1428e..c7c916375 100644
--- a/fpga/usrp2/control_lib/shortfifo.v
+++ b/fpga/usrp2/control_lib/shortfifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module shortfifo
#(parameter WIDTH=32)
diff --git a/fpga/usrp2/control_lib/simple_uart.v b/fpga/usrp2/control_lib/simple_uart.v
index 0dd58b5f5..f44a719f4 100644
--- a/fpga/usrp2/control_lib/simple_uart.v
+++ b/fpga/usrp2/control_lib/simple_uart.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_uart
#(parameter TXDEPTH = 1,
diff --git a/fpga/usrp2/control_lib/simple_uart_rx.v b/fpga/usrp2/control_lib/simple_uart_rx.v
index debdd618b..5f7646e03 100644
--- a/fpga/usrp2/control_lib/simple_uart_rx.v
+++ b/fpga/usrp2/control_lib/simple_uart_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_uart_rx
diff --git a/fpga/usrp2/control_lib/simple_uart_tx.v b/fpga/usrp2/control_lib/simple_uart_tx.v
index e11a347ed..f38460bd4 100644
--- a/fpga/usrp2/control_lib/simple_uart_tx.v
+++ b/fpga/usrp2/control_lib/simple_uart_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_uart_tx
#(parameter DEPTH=0)
diff --git a/fpga/usrp2/control_lib/spi.v b/fpga/usrp2/control_lib/spi.v
index a80c488e9..1abebee1c 100644
--- a/fpga/usrp2/control_lib/spi.v
+++ b/fpga/usrp2/control_lib/spi.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// AD9510 Register Map (from datasheet Rev. A)
diff --git a/fpga/usrp2/control_lib/srl.v b/fpga/usrp2/control_lib/srl.v
index fa28c7669..bdef30058 100644
--- a/fpga/usrp2/control_lib/srl.v
+++ b/fpga/usrp2/control_lib/srl.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module srl
#(parameter WIDTH=18)
diff --git a/fpga/usrp2/control_lib/ss_rcvr.v b/fpga/usrp2/control_lib/ss_rcvr.v
index 8e650d21b..4fb732c23 100644
--- a/fpga/usrp2/control_lib/ss_rcvr.v
+++ b/fpga/usrp2/control_lib/ss_rcvr.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Source-synchronous receiver
diff --git a/fpga/usrp2/control_lib/system_control.v b/fpga/usrp2/control_lib/system_control.v
index 5d89f13db..7e7b71f3c 100644
--- a/fpga/usrp2/control_lib/system_control.v
+++ b/fpga/usrp2/control_lib/system_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// System bootup order:
// 0 - Internal POR to reset this block. Maybe control it from CPLD in the future?
// 1 - Everything in reset
diff --git a/fpga/usrp2/control_lib/system_control_tb.v b/fpga/usrp2/control_lib/system_control_tb.v
index a8eff4811..8fecfd1f0 100644
--- a/fpga/usrp2/control_lib/system_control_tb.v
+++ b/fpga/usrp2/control_lib/system_control_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module system_control_tb();
diff --git a/fpga/usrp2/control_lib/traffic_cop.v b/fpga/usrp2/control_lib/traffic_cop.v
index e7579656a..874e4c2d9 100644
--- a/fpga/usrp2/control_lib/traffic_cop.v
+++ b/fpga/usrp2/control_lib/traffic_cop.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module traffic_cop();
diff --git a/fpga/usrp2/control_lib/v5icap_wb.v b/fpga/usrp2/control_lib/v5icap_wb.v
index c8800285a..92a6769e5 100644
--- a/fpga/usrp2/control_lib/v5icap_wb.v
+++ b/fpga/usrp2/control_lib/v5icap_wb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module v5icap_wb
diff --git a/fpga/usrp2/control_lib/wb_bridge_16_32.v b/fpga/usrp2/control_lib/wb_bridge_16_32.v
index 405e25c3c..7c62c9cbd 100644
--- a/fpga/usrp2/control_lib/wb_bridge_16_32.v
+++ b/fpga/usrp2/control_lib/wb_bridge_16_32.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module wb_bridge_16_32
diff --git a/fpga/usrp2/control_lib/wb_bus_writer.v b/fpga/usrp2/control_lib/wb_bus_writer.v
index fc148a0ff..08e641d37 100644
--- a/fpga/usrp2/control_lib/wb_bus_writer.v
+++ b/fpga/usrp2/control_lib/wb_bus_writer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// wb_bus_writer
//
diff --git a/fpga/usrp2/control_lib/wb_output_pins32.v b/fpga/usrp2/control_lib/wb_output_pins32.v
index 1517f2066..43e239797 100644
--- a/fpga/usrp2/control_lib/wb_output_pins32.v
+++ b/fpga/usrp2/control_lib/wb_output_pins32.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Simple 32-bit Wishbone compatible slave output port
diff --git a/fpga/usrp2/control_lib/wb_ram_block.v b/fpga/usrp2/control_lib/wb_ram_block.v
index 044d34ca4..da6c610d3 100644
--- a/fpga/usrp2/control_lib/wb_ram_block.v
+++ b/fpga/usrp2/control_lib/wb_ram_block.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Since this is a block ram, there are no byte-selects and there is a 1-cycle read latency
diff --git a/fpga/usrp2/control_lib/wb_ram_dist.v b/fpga/usrp2/control_lib/wb_ram_dist.v
index cffc2f423..491a6ae11 100644
--- a/fpga/usrp2/control_lib/wb_ram_dist.v
+++ b/fpga/usrp2/control_lib/wb_ram_dist.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module wb_ram_dist
diff --git a/fpga/usrp2/control_lib/wb_readback_mux.v b/fpga/usrp2/control_lib/wb_readback_mux.v
index 3922b03e3..a5bf224b8 100644
--- a/fpga/usrp2/control_lib/wb_readback_mux.v
+++ b/fpga/usrp2/control_lib/wb_readback_mux.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Note -- clocks must be synchronous (derived from the same source)
diff --git a/fpga/usrp2/control_lib/wb_readback_mux_16LE.v b/fpga/usrp2/control_lib/wb_readback_mux_16LE.v
index 2b01898c1..aceec601b 100644
--- a/fpga/usrp2/control_lib/wb_readback_mux_16LE.v
+++ b/fpga/usrp2/control_lib/wb_readback_mux_16LE.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Note -- clocks must be synchronous (derived from the same source)
diff --git a/fpga/usrp2/control_lib/wb_regfile_2clock.v b/fpga/usrp2/control_lib/wb_regfile_2clock.v
index e248e5161..ce93ab3f4 100644
--- a/fpga/usrp2/control_lib/wb_regfile_2clock.v
+++ b/fpga/usrp2/control_lib/wb_regfile_2clock.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module wb_regfile_2clock
(input wb_clk_i,
diff --git a/fpga/usrp2/control_lib/wb_semaphore.v b/fpga/usrp2/control_lib/wb_semaphore.v
index a9208e6a1..e90950509 100644
--- a/fpga/usrp2/control_lib/wb_semaphore.v
+++ b/fpga/usrp2/control_lib/wb_semaphore.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// up to 8 semaphores
diff --git a/fpga/usrp2/control_lib/wb_sim.v b/fpga/usrp2/control_lib/wb_sim.v
index b324e1457..9f2fbea54 100644
--- a/fpga/usrp2/control_lib/wb_sim.v
+++ b/fpga/usrp2/control_lib/wb_sim.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module wb_sim();
diff --git a/fpga/usrp2/extramfifo/ext_fifo.v b/fpga/usrp2/extramfifo/ext_fifo.v
index 80f82fc63..620f4dddd 100644
--- a/fpga/usrp2/extramfifo/ext_fifo.v
+++ b/fpga/usrp2/extramfifo/ext_fifo.v
@@ -1,4 +1,21 @@
//
+// 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/>.
+//
+
+//
// FIFO backed by an off chip ZBT/NoBL SRAM.
//
// This module and its sub-hierarchy implment a FIFO capable of sustaining
diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.v b/fpga/usrp2/extramfifo/ext_fifo_tb.v
index 395ad2884..f6fe47297 100644
--- a/fpga/usrp2/extramfifo/ext_fifo_tb.v
+++ b/fpga/usrp2/extramfifo/ext_fifo_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
`define USRP2
//`define USRP2PLUS
diff --git a/fpga/usrp2/extramfifo/nobl_fifo.v b/fpga/usrp2/extramfifo/nobl_fifo.v
index 0b63768fc..469e3eab5 100644
--- a/fpga/usrp2/extramfifo/nobl_fifo.v
+++ b/fpga/usrp2/extramfifo/nobl_fifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Since this FIFO uses a ZBT/NoBL SRAM for its storage which is a since port
// device it can only sustain data throughput at half the RAM clock rate.
// Fair arbitration to ensure this occurs is included in this logic and
diff --git a/fpga/usrp2/extramfifo/nobl_if.v b/fpga/usrp2/extramfifo/nobl_if.v
index b5ebe9c6b..0a64d3857 100644
--- a/fpga/usrp2/extramfifo/nobl_if.v
+++ b/fpga/usrp2/extramfifo/nobl_if.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Tested against an IDT 71v65603s150 in simulation and a Cypress 7C1356C in the real world.
module nobl_if
diff --git a/fpga/usrp2/extramfifo/refill_randomizer.v b/fpga/usrp2/extramfifo/refill_randomizer.v
index 0b30f4049..09728b8c0 100644
--- a/fpga/usrp2/extramfifo/refill_randomizer.v
+++ b/fpga/usrp2/extramfifo/refill_randomizer.v
@@ -1,4 +1,21 @@
//
+// 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/>.
+//
+
+//
// EMI mitigation.
// Process FULL flag from FIFO so that de-assertion
// (FIFO now not FULL) is delayed by a pseudo random
diff --git a/fpga/usrp2/extramfifo/test_sram_if.v b/fpga/usrp2/extramfifo/test_sram_if.v
index 0e74b49eb..dcb881a92 100644
--- a/fpga/usrp2/extramfifo/test_sram_if.v
+++ b/fpga/usrp2/extramfifo/test_sram_if.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Instantiate this block at the core level to conduct closed
// loop testing of the AC performance of the USRP2 SRAM interface
diff --git a/fpga/usrp2/fifo/Makefile.srcs b/fpga/usrp2/fifo/Makefile.srcs
index 31b1f505a..02c567049 100644
--- a/fpga/usrp2/fifo/Makefile.srcs
+++ b/fpga/usrp2/fifo/Makefile.srcs
@@ -23,6 +23,7 @@ fifo19_to_ll8.v \
ll8_to_fifo19.v \
fifo36_to_fifo19.v \
fifo19_to_fifo36.v \
+fifo19_mux.v \
fifo36_mux.v \
fifo36_demux.v \
packet_router.v \
@@ -34,4 +35,5 @@ packet_generator32.v \
packet_generator.v \
packet_verifier32.v \
packet_verifier.v \
+fifo19_pad.v \
))
diff --git a/fpga/usrp2/fifo/buffer_int.v b/fpga/usrp2/fifo/buffer_int.v
index 49ded8c8d..c068226ec 100644
--- a/fpga/usrp2/fifo/buffer_int.v
+++ b/fpga/usrp2/fifo/buffer_int.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIFO Interface to the 2K buffer RAMs
// Read port is read-acknowledge
diff --git a/fpga/usrp2/fifo/buffer_int2.v b/fpga/usrp2/fifo/buffer_int2.v
index 532980aa2..7dd528dd5 100644
--- a/fpga/usrp2/fifo/buffer_int2.v
+++ b/fpga/usrp2/fifo/buffer_int2.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIFO Interface to the 2K buffer RAMs
// Read port is read-acknowledge
diff --git a/fpga/usrp2/fifo/buffer_int_tb.v b/fpga/usrp2/fifo/buffer_int_tb.v
index df54dcc0b..44f8be0a0 100644
--- a/fpga/usrp2/fifo/buffer_int_tb.v
+++ b/fpga/usrp2/fifo/buffer_int_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module buffer_int_tb ();
diff --git a/fpga/usrp2/fifo/buffer_pool.v b/fpga/usrp2/fifo/buffer_pool.v
index 41ac1deb3..48f5bd69c 100644
--- a/fpga/usrp2/fifo/buffer_pool.v
+++ b/fpga/usrp2/fifo/buffer_pool.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Buffer pool. Contains 8 buffers, each 2K (512 by 32). Each buffer
// is a dual-ported RAM. Port A on each of them is indirectly connected
diff --git a/fpga/usrp2/fifo/buffer_pool_tb.v b/fpga/usrp2/fifo/buffer_pool_tb.v
index 91a01d268..0ee76689e 100644
--- a/fpga/usrp2/fifo/buffer_pool_tb.v
+++ b/fpga/usrp2/fifo/buffer_pool_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module buffer_pool_tb();
diff --git a/fpga/usrp2/fifo/crossbar36.v b/fpga/usrp2/fifo/crossbar36.v
index 2a046d8bf..4e2aed7ce 100644
--- a/fpga/usrp2/fifo/crossbar36.v
+++ b/fpga/usrp2/fifo/crossbar36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module crossbar36
diff --git a/fpga/usrp2/fifo/dsp_framer36.v b/fpga/usrp2/fifo/dsp_framer36.v
index 58455cee1..ef7395551 100644
--- a/fpga/usrp2/fifo/dsp_framer36.v
+++ b/fpga/usrp2/fifo/dsp_framer36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// This has 3 functions:
// Correct the VITA packet length
diff --git a/fpga/usrp2/fifo/fifo19_mux.v b/fpga/usrp2/fifo/fifo19_mux.v
new file mode 100644
index 000000000..a23ac2bb4
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo19_mux.v
@@ -0,0 +1,94 @@
+//
+// 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/>.
+//
+
+
+// Mux packets from multiple FIFO interfaces onto a single one.
+// Can alternate or give priority to one port (port 0)
+// In prio mode, port 1 will never get access if port 0 is always busy
+
+module fifo19_mux
+ #(parameter prio = 0)
+ (input clk, input reset, input clear,
+ input [18:0] data0_i, input src0_rdy_i, output dst0_rdy_o,
+ input [18:0] data1_i, input src1_rdy_i, output dst1_rdy_o,
+ output [18:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ wire [18:0] data0_int, data1_int;
+ wire src0_rdy_int, dst0_rdy_int, src1_rdy_int, dst1_rdy_int;
+
+ fifo_short #(.WIDTH(19)) 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(19)) 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;
+ localparam MUX_DATA1 = 3;
+
+ reg [1:0] state;
+
+ wire eof0 = data0_int[17];
+ wire eof1 = data1_int[17];
+
+ wire [18:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= MUX_IDLE0;
+ else
+ case(state)
+ MUX_IDLE0 :
+ if(src0_rdy_int)
+ state <= MUX_DATA0;
+ else if(src1_rdy_int)
+ state <= MUX_DATA1;
+
+ MUX_DATA0 :
+ if(src0_rdy_int & dst_rdy_int & eof0)
+ state <= prio ? MUX_IDLE0 : MUX_IDLE1;
+
+ MUX_IDLE1 :
+ if(src1_rdy_int)
+ state <= MUX_DATA1;
+ else if(src0_rdy_int)
+ state <= MUX_DATA0;
+
+ MUX_DATA1 :
+ if(src1_rdy_int & dst_rdy_int & eof1)
+ state <= MUX_IDLE0;
+
+ default :
+ state <= MUX_IDLE0;
+ endcase // case (state)
+
+ 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(19)) mux_fifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int),
+ .dataout(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i));
+endmodule // fifo19_mux
diff --git a/fpga/usrp2/fifo/fifo19_pad.v b/fpga/usrp2/fifo/fifo19_pad.v
new file mode 100644
index 000000000..bb6e1fa92
--- /dev/null
+++ b/fpga/usrp2/fifo/fifo19_pad.v
@@ -0,0 +1,83 @@
+//
+// 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/>.
+//
+
+
+// Pads a packet out to the minimum length
+// Packets already longer than min length are unchanged
+
+
+module fifo19_pad
+ #(parameter LENGTH=16,
+ parameter PAD_VALUE=0)
+ (input clk, input reset, input clear,
+ input [18:0] data_i,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [18:0] data_o,
+ output src_rdy_o,
+ input dst_rdy_i);
+
+ reg [15:0] count;
+ reg [1:0] pad_state;
+ localparam PAD_IDLE = 0;
+ localparam PAD_TOOSHORT = 1;
+ localparam PAD_LONGENOUGH = 2;
+ localparam PAD_PADDING = 3;
+
+ always @(posedge clk)
+ if(reset | clear)
+ pad_state <= PAD_IDLE;
+ else
+ case(pad_state)
+ PAD_IDLE :
+ begin
+ count <= 1;
+ pad_state <= PAD_TOOSHORT;
+ end
+ PAD_TOOSHORT :
+ if(src_rdy_i & dst_rdy_i)
+ begin
+ count <= count + 1;
+ if(data_i[17])
+ pad_state <= PAD_PADDING;
+ else if(count == (LENGTH-1))
+ pad_state <= PAD_LONGENOUGH;
+ end
+ PAD_PADDING :
+ if(dst_rdy_i)
+ begin
+ count <= count + 1;
+ if(count == LENGTH)
+ pad_state <= PAD_IDLE;
+ end
+ PAD_LONGENOUGH :
+ if(src_rdy_i & dst_rdy_i & data_i[17])
+ pad_state <= PAD_IDLE;
+ endcase // case (pad_state)
+
+ wire passthru = (pad_state == PAD_TOOSHORT) | (pad_state == PAD_LONGENOUGH);
+
+ assign dst_rdy_o = passthru ? dst_rdy_i : 1'b0;
+ assign src_rdy_o = passthru ? src_rdy_i : (pad_state == PAD_PADDING);
+
+ assign data_o[15:0] = (pad_state == PAD_PADDING) ? PAD_VALUE : data_i[15:0];
+ assign data_o[16] = (count == 1);
+ assign data_o[17] = (pad_state == PAD_LONGENOUGH) ? data_i[17] : (count == LENGTH);
+ assign data_o[18] = (pad_state == PAD_LONGENOUGH) ? data_i[18] : 1'b0;
+
+
+endmodule // fifo19_pad
diff --git a/fpga/usrp2/fifo/fifo19_to_fifo36.v b/fpga/usrp2/fifo/fifo19_to_fifo36.v
index 502821435..32734405a 100644
--- a/fpga/usrp2/fifo/fifo19_to_fifo36.v
+++ b/fpga/usrp2/fifo/fifo19_to_fifo36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Parameter LE tells us if we are little-endian.
// Little-endian means send lower 16 bits first.
diff --git a/fpga/usrp2/fifo/fifo19_to_ll8.v b/fpga/usrp2/fifo/fifo19_to_ll8.v
index 4707f7523..1ebb140c2 100644
--- a/fpga/usrp2/fifo/fifo19_to_ll8.v
+++ b/fpga/usrp2/fifo/fifo19_to_ll8.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo19_to_ll8
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/fifo/fifo36_demux.v b/fpga/usrp2/fifo/fifo36_demux.v
index a54759d4d..6f516691a 100644
--- a/fpga/usrp2/fifo/fifo36_demux.v
+++ b/fpga/usrp2/fifo/fifo36_demux.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Demux packets from a fifo based on the contents of the first line
// If first line matches the parameter and mask, send to data1, otherwise send to data0
diff --git a/fpga/usrp2/fifo/fifo36_mux.v b/fpga/usrp2/fifo/fifo36_mux.v
index 7f0f803ff..cf7b2b4d1 100644
--- a/fpga/usrp2/fifo/fifo36_mux.v
+++ b/fpga/usrp2/fifo/fifo36_mux.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Mux packets from multiple FIFO interfaces onto a single one.
// Can alternate or give priority to one port (port 0)
diff --git a/fpga/usrp2/fifo/fifo36_to_fifo19.v b/fpga/usrp2/fifo/fifo36_to_fifo19.v
index 0e9b2d442..cb93e10ad 100644
--- a/fpga/usrp2/fifo/fifo36_to_fifo19.v
+++ b/fpga/usrp2/fifo/fifo36_to_fifo19.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Parameter LE tells us if we are little-endian.
// Little-endian means send lower 16 bits first.
diff --git a/fpga/usrp2/fifo/fifo36_to_fifo72.v b/fpga/usrp2/fifo/fifo36_to_fifo72.v
index 038eda9e9..237149cc2 100644
--- a/fpga/usrp2/fifo/fifo36_to_fifo72.v
+++ b/fpga/usrp2/fifo/fifo36_to_fifo72.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Parameter LE tells us if we are little-endian.
// Little-endian means send lower 16 bits first.
diff --git a/fpga/usrp2/fifo/fifo36_to_ll8.v b/fpga/usrp2/fifo/fifo36_to_ll8.v
index 390e49962..5c2da812f 100644
--- a/fpga/usrp2/fifo/fifo36_to_ll8.v
+++ b/fpga/usrp2/fifo/fifo36_to_ll8.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo36_to_ll8
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/fifo/fifo72_to_fifo36.v b/fpga/usrp2/fifo/fifo72_to_fifo36.v
index 1b3bc3ab7..c365f0196 100644
--- a/fpga/usrp2/fifo/fifo72_to_fifo36.v
+++ b/fpga/usrp2/fifo/fifo72_to_fifo36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Parameter LE tells us if we are little-endian.
// Little-endian means send lower 16 bits first.
diff --git a/fpga/usrp2/fifo/fifo_19to36_tb.v b/fpga/usrp2/fifo/fifo_19to36_tb.v
index c585392c3..143b92b1b 100644
--- a/fpga/usrp2/fifo/fifo_19to36_tb.v
+++ b/fpga/usrp2/fifo/fifo_19to36_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_tb();
reg clk = 0;
diff --git a/fpga/usrp2/fifo/fifo_2clock.v b/fpga/usrp2/fifo/fifo_2clock.v
index 34c85ccb4..756ad508f 100644
--- a/fpga/usrp2/fifo/fifo_2clock.v
+++ b/fpga/usrp2/fifo/fifo_2clock.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIXME ignores the AWIDTH (fifo size) parameter
@@ -14,7 +31,8 @@ module fifo_2clock
assign src_rdy_o = ~empty;
assign write = src_rdy_i & dst_rdy_o;
assign read = src_rdy_o & dst_rdy_i;
-
+ wire dummy;
+
generate
if(WIDTH==36)
if(SIZE==9)
@@ -37,12 +55,16 @@ module fifo_2clock
(.rst(arst),
.wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
.rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
- else if((WIDTH==19)|(WIDTH==18))
- if(SIZE==4)
- fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
- (.rst(arst),
- .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
- .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else if((WIDTH==19) & (SIZE==4))
+ fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
+ else if((WIDTH==18) & (SIZE==4))
+ fifo_xlnx_16x19_2clk fifo_xlnx_16x19_2clk
+ (.rst(arst),
+ .wr_clk(wclk),.din({1'b0,datain}),.full(full),.wr_en(write),.wr_data_count(level_wclk),
+ .rd_clk(rclk),.dout({dummy,dataout}),.empty(empty),.rd_en(read),.rd_data_count(level_rclk) );
endgenerate
assign occupied = {{(16-SIZE-1){1'b0}},level_rclk};
diff --git a/fpga/usrp2/fifo/fifo_2clock_cascade.v b/fpga/usrp2/fifo/fifo_2clock_cascade.v
index 4e8c244c2..49cac7097 100644
--- a/fpga/usrp2/fifo/fifo_2clock_cascade.v
+++ b/fpga/usrp2/fifo/fifo_2clock_cascade.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_2clock_cascade
#(parameter WIDTH=32, SIZE=9)
diff --git a/fpga/usrp2/fifo/fifo_cascade.v b/fpga/usrp2/fifo/fifo_cascade.v
index fdd8449bc..5a79c4090 100644
--- a/fpga/usrp2/fifo/fifo_cascade.v
+++ b/fpga/usrp2/fifo/fifo_cascade.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// This FIFO exists to provide an intermediate point for the data on its
diff --git a/fpga/usrp2/fifo/fifo_long.v b/fpga/usrp2/fifo/fifo_long.v
index 0426779f6..e9739ad94 100644
--- a/fpga/usrp2/fifo/fifo_long.v
+++ b/fpga/usrp2/fifo/fifo_long.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIFO intended to be interchangeable with shortfifo, but
// based on block ram instead of SRL16's
diff --git a/fpga/usrp2/fifo/fifo_pacer.v b/fpga/usrp2/fifo/fifo_pacer.v
index 1bf03ab6e..3e3fbf8b8 100644
--- a/fpga/usrp2/fifo/fifo_pacer.v
+++ b/fpga/usrp2/fifo/fifo_pacer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_pacer
diff --git a/fpga/usrp2/fifo/fifo_short.v b/fpga/usrp2/fifo/fifo_short.v
index 53a7603c7..32f26beef 100644
--- a/fpga/usrp2/fifo/fifo_short.v
+++ b/fpga/usrp2/fifo/fifo_short.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_short
#(parameter WIDTH=32)
diff --git a/fpga/usrp2/fifo/fifo_tb.v b/fpga/usrp2/fifo/fifo_tb.v
index 3e2862a70..c63c201d0 100644
--- a/fpga/usrp2/fifo/fifo_tb.v
+++ b/fpga/usrp2/fifo/fifo_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_tb();
reg clk = 0;
diff --git a/fpga/usrp2/fifo/ll8_shortfifo.v b/fpga/usrp2/fifo/ll8_shortfifo.v
index 39ada9a4f..49b3a3139 100644
--- a/fpga/usrp2/fifo/ll8_shortfifo.v
+++ b/fpga/usrp2/fifo/ll8_shortfifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ll8_shortfifo
diff --git a/fpga/usrp2/fifo/ll8_to_fifo19.v b/fpga/usrp2/fifo/ll8_to_fifo19.v
index ac8ac19a6..4503d0c3d 100644
--- a/fpga/usrp2/fifo/ll8_to_fifo19.v
+++ b/fpga/usrp2/fifo/ll8_to_fifo19.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ll8_to_fifo19
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/fifo/ll8_to_fifo36.v b/fpga/usrp2/fifo/ll8_to_fifo36.v
index 108daa903..b26f745d2 100644
--- a/fpga/usrp2/fifo/ll8_to_fifo36.v
+++ b/fpga/usrp2/fifo/ll8_to_fifo36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ll8_to_fifo36
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/fifo/packet32_tb.v b/fpga/usrp2/fifo/packet32_tb.v
index 82bb09c29..8a7cfcec5 100644
--- a/fpga/usrp2/fifo/packet32_tb.v
+++ b/fpga/usrp2/fifo/packet32_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet32_tb();
diff --git a/fpga/usrp2/fifo/packet_generator.v b/fpga/usrp2/fifo/packet_generator.v
index 2ae911e24..5e9d3c2ab 100644
--- a/fpga/usrp2/fifo/packet_generator.v
+++ b/fpga/usrp2/fifo/packet_generator.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet_generator
diff --git a/fpga/usrp2/fifo/packet_generator32.v b/fpga/usrp2/fifo/packet_generator32.v
index 1dc57191d..7b4e3bd57 100644
--- a/fpga/usrp2/fifo/packet_generator32.v
+++ b/fpga/usrp2/fifo/packet_generator32.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet_generator32
diff --git a/fpga/usrp2/fifo/packet_router.v b/fpga/usrp2/fifo/packet_router.v
index 04c17b647..7bfa6893d 100644
--- a/fpga/usrp2/fifo/packet_router.v
+++ b/fpga/usrp2/fifo/packet_router.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet_router
#(
parameter BUF_SIZE = 9,
diff --git a/fpga/usrp2/fifo/packet_tb.v b/fpga/usrp2/fifo/packet_tb.v
index 3c423d2ba..ec0665e0a 100644
--- a/fpga/usrp2/fifo/packet_tb.v
+++ b/fpga/usrp2/fifo/packet_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet_tb();
diff --git a/fpga/usrp2/fifo/packet_verifier.v b/fpga/usrp2/fifo/packet_verifier.v
index 21a4c136e..3cc7b0a04 100644
--- a/fpga/usrp2/fifo/packet_verifier.v
+++ b/fpga/usrp2/fifo/packet_verifier.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Packet format --
diff --git a/fpga/usrp2/fifo/packet_verifier32.v b/fpga/usrp2/fifo/packet_verifier32.v
index ec08e657d..3579a9bcf 100644
--- a/fpga/usrp2/fifo/packet_verifier32.v
+++ b/fpga/usrp2/fifo/packet_verifier32.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module packet_verifier32
diff --git a/fpga/usrp2/fifo/splitter36.v b/fpga/usrp2/fifo/splitter36.v
index ed998b4f5..d002d7afd 100644
--- a/fpga/usrp2/fifo/splitter36.v
+++ b/fpga/usrp2/fifo/splitter36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Split packets from a fifo based interface so it goes out identically on two interfaces
diff --git a/fpga/usrp2/fifo/valve36.v b/fpga/usrp2/fifo/valve36.v
index d45eee497..795fe511e 100644
--- a/fpga/usrp2/fifo/valve36.v
+++ b/fpga/usrp2/fifo/valve36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module valve36
diff --git a/fpga/usrp2/gpif/Makefile.srcs b/fpga/usrp2/gpif/Makefile.srcs
new file mode 100644
index 000000000..bf2b7f74d
--- /dev/null
+++ b/fpga/usrp2/gpif/Makefile.srcs
@@ -0,0 +1,14 @@
+#
+# Copyright 2010 Ettus Research LLC
+#
+
+##################################################
+# SERDES Sources
+##################################################
+GPIF_SRCS = $(abspath $(addprefix $(BASE_DIR)/../gpif/, \
+gpif.v \
+gpif_wr.v \
+gpif_rd.v \
+packet_reframer.v \
+packet_splitter.v \
+))
diff --git a/fpga/usrp2/gpif/gpif.v b/fpga/usrp2/gpif/gpif.v
new file mode 100644
index 000000000..51d6e8ba9
--- /dev/null
+++ b/fpga/usrp2/gpif/gpif.v
@@ -0,0 +1,257 @@
+//
+// 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/>.
+//
+
+//////////////////////////////////////////////////////////////////////////////////
+
+module gpif
+ #(parameter TXFIFOSIZE = 11, parameter RXFIFOSIZE = 11)
+ (// GPIF signals
+ input gpif_clk, input gpif_rst,
+ inout [15:0] gpif_d, input [3:0] gpif_ctl, output [3:0] gpif_rdy,
+ output [2:0] gpif_misc,
+
+ // Wishbone signals
+ input wb_clk, input wb_rst,
+ output [15:0] wb_adr_o, output [15:0] wb_dat_mosi, input [15:0] wb_dat_miso,
+ output [1:0] wb_sel_o, output wb_cyc_o, output wb_stb_o, output wb_we_o, input wb_ack_i,
+ input [7:0] triggers,
+
+ // FIFO interface
+ input fifo_clk, input fifo_rst, input clear_tx, input clear_rx,
+ output [35:0] tx_data_o, output tx_src_rdy_o, input tx_dst_rdy_i,
+ input [35:0] rx_data_i, input rx_src_rdy_i, output rx_dst_rdy_o,
+ input [35:0] tx_err_data_i, input tx_err_src_rdy_i, output tx_err_dst_rdy_o,
+
+ output tx_underrun, output rx_overrun,
+ input [7:0] frames_per_packet, input [15:0] test_len, input [7:0] test_rate, input [3:0] test_ctrl,
+ output [31:0] debug0, output [31:0] debug1
+ );
+
+ wire WR = gpif_ctl[0];
+ wire RD = gpif_ctl[1];
+ wire OE = gpif_ctl[2];
+ wire EP = gpif_ctl[3];
+
+ wire CF, CE, DF, DE;
+
+ assign gpif_rdy = { CF, CE, DF, DE };
+
+ wire [15:0] gpif_d_out;
+ assign gpif_d = OE ? gpif_d_out : 16'bz;
+
+ wire [15:0] gpif_d_copy = gpif_d;
+
+ wire [31:0] debug_rd, debug_wr, debug_split0, debug_split1;
+
+ // ////////////////////////////////////////////////////////////////////
+ // TX Data Path
+
+ wire [18:0] tx19_data;
+ wire tx19_src_rdy, tx19_dst_rdy;
+ wire [35:0] tx36_data, tx_data;
+ wire tx36_src_rdy, tx36_dst_rdy, tx_src_rdy, tx_dst_rdy;
+
+ wire [18:0] ctrl_data;
+ wire ctrl_src_rdy, ctrl_dst_rdy;
+
+ gpif_wr gpif_wr
+ (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst),
+ .gpif_data(gpif_d), .gpif_wr(WR), .gpif_ep(EP),
+ .gpif_full_d(DF), .gpif_full_c(CF),
+
+ .sys_clk(fifo_clk), .sys_rst(fifo_rst),
+ .data_o(tx19_data), .src_rdy_o(tx19_src_rdy), .dst_rdy_i(tx19_dst_rdy),
+ .ctrl_o(ctrl_data), .ctrl_src_rdy_o(ctrl_src_rdy), .ctrl_dst_rdy_i(ctrl_dst_rdy),
+ .debug(debug_wr) );
+
+ // join vita packets which are longer than one frame, drop frame padding
+ wire [18:0] refr_data;
+ wire refr_src_rdy, refr_dst_rdy;
+
+ packet_reframer tx_packet_reframer
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_tx),
+ .data_i(tx19_data), .src_rdy_i(tx19_src_rdy), .dst_rdy_o(tx19_dst_rdy),
+ .data_o(refr_data), .src_rdy_o(refr_src_rdy), .dst_rdy_i(refr_dst_rdy));
+
+ fifo19_to_fifo36 #(.LE(1)) f19_to_f36
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .f19_datain(refr_data), .f19_src_rdy_i(refr_src_rdy), .f19_dst_rdy_o(refr_dst_rdy),
+ .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(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), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy));
+
+ // ////////////////////////////////////////////
+ // RX Data Path
+
+ wire [35:0] rx36_data, rx_data;
+ wire rx36_src_rdy, rx36_dst_rdy, rx_src_rdy, rx_dst_rdy;
+ wire [18:0] rx19_data, splt_data;
+ wire rx19_src_rdy, rx19_dst_rdy, splt_src_rdy, splt_dst_rdy;
+ wire [18:0] resp_data, resp_int1, resp_int2;
+ wire resp_src_rdy, resp_dst_rdy;
+ wire resp_src_rdy_int1, resp_dst_rdy_int1, resp_src_rdy_int2, resp_dst_rdy_int2;
+
+ fifo_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_fifo36
+ (.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
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .f36_datain(rx36_data), .f36_src_rdy_i(rx36_src_rdy), .f36_dst_rdy_o(rx36_dst_rdy),
+ .f19_dataout(rx19_data), .f19_src_rdy_o(rx19_src_rdy), .f19_dst_rdy_i(rx19_dst_rdy) );
+
+ packet_splitter #(.FRAME_LEN(256)) packet_splitter
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .frames_per_packet(frames_per_packet),
+ .data_i(rx19_data), .src_rdy_i(rx19_src_rdy), .dst_rdy_o(rx19_dst_rdy),
+ .data_o(splt_data), .src_rdy_o(splt_src_rdy), .dst_rdy_i(splt_dst_rdy),
+ .debug0(debug_split0), .debug1(debug_split1));
+
+ gpif_rd gpif_rd
+ (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst),
+ .gpif_data(gpif_d_out), .gpif_rd(RD), .gpif_ep(EP),
+ .gpif_empty_d(DE), .gpif_empty_c(CE), .gpif_flush(gpif_misc[0]),
+
+ .sys_clk(fifo_clk), .sys_rst(fifo_rst),
+ .data_i(splt_data), .src_rdy_i(splt_src_rdy), .dst_rdy_o(splt_dst_rdy),
+ .resp_i(resp_data), .resp_src_rdy_i(resp_src_rdy), .resp_dst_rdy_o(resp_dst_rdy),
+ .debug(debug_rd) );
+
+ // ////////////////////////////////////////////////////////////////////
+ // FIFO to Wishbone interface
+
+ fifo_to_wb fifo_to_wb
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .data_i(ctrl_data), .src_rdy_i(ctrl_src_rdy), .dst_rdy_o(ctrl_dst_rdy),
+ .data_o(resp_int1), .src_rdy_o(resp_src_rdy_int1), .dst_rdy_i(resp_dst_rdy_int1),
+ .wb_adr_o(wb_adr_o), .wb_dat_mosi(wb_dat_mosi), .wb_dat_miso(wb_dat_miso), .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),
+ .triggers(triggers),
+ .debug0(), .debug1());
+
+ wire [18:0] tx_err19_data;
+ wire tx_err19_src_rdy, tx_err19_dst_rdy;
+
+ fifo36_to_fifo19 #(.LE(1)) f36_to_f19_txerr
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .f36_datain(tx_err_data_i), .f36_src_rdy_i(tx_err_src_rdy_i), .f36_dst_rdy_o(tx_err_dst_rdy_o),
+ .f19_dataout(tx_err19_data), .f19_src_rdy_o(tx_err19_src_rdy), .f19_dst_rdy_i(tx_err19_dst_rdy) );
+
+ fifo19_mux #(.prio(0)) mux_err_stream
+ (.clk(wb_clk), .reset(wb_rst), .clear(0),
+ .data0_i(resp_int1), .src0_rdy_i(resp_src_rdy_int1), .dst0_rdy_o(resp_dst_rdy_int1),
+ .data1_i(tx_err19_data), .src1_rdy_i(tx_err19_src_rdy), .dst1_rdy_o(tx_err19_dst_rdy),
+ .data_o(resp_int2), .src_rdy_o(resp_src_rdy_int2), .dst_rdy_i(resp_dst_rdy_int2));
+
+ fifo19_pad #(.LENGTH(16)) fifo19_pad
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .data_i(resp_int2), .src_rdy_i(resp_src_rdy_int2), .dst_rdy_o(resp_dst_rdy_int2),
+ .data_o(resp_data), .src_rdy_o(resp_src_rdy), .dst_rdy_i(resp_dst_rdy));
+
+ // ////////////////////////////////////////////////////////////////////
+ // Debug support, timed and loopback
+ // 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
+ vita_pkt_gen pktgen
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(clear_rx),
+ .len(test_len),
+ .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));
+
+ // ////////////////////////////////////////////
+ // DEBUG
+
+ //assign debug0 = { rx19_src_rdy, rx19_dst_rdy, resp_src_rdy, resp_dst_rdy, gpif_ctl[3:0], gpif_rdy[3:0],
+ // gpif_d_copy[15:0] };
+
+ //assign debug1 = { { debug_rd[15:8] },
+ // { debug_rd[7:0] },
+ // { rx_src_rdy_i, rx_dst_rdy_o, rx36_src_rdy, rx36_dst_rdy, rx19_src_rdy, rx19_dst_rdy, resp_src_rdy, resp_dst_rdy},
+ // { tx_src_rdy_o, tx_dst_rdy_i, tx19_src_rdy, tx19_dst_rdy, tx36_src_rdy, tx36_dst_rdy, ctrl_src_rdy, ctrl_dst_rdy} };
+
+ assign debug0 = { gpif_ctl[3:0], gpif_rdy[3:0], debug_split0[23:0] };
+ assign debug1 = { gpif_misc[0], debug_rd[14:0], debug_split1[15:8], debug_split1[7:0] };
+endmodule // gpif
diff --git a/fpga/usrp2/gpif/gpif_rd.v b/fpga/usrp2/gpif/gpif_rd.v
new file mode 100644
index 000000000..b05c3cfb6
--- /dev/null
+++ b/fpga/usrp2/gpif/gpif_rd.v
@@ -0,0 +1,111 @@
+//
+// 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/>.
+//
+
+
+module gpif_rd
+ (input gpif_clk, input gpif_rst,
+ output [15:0] gpif_data, input gpif_rd, input gpif_ep,
+ output reg gpif_empty_d, output reg gpif_empty_c,
+ output reg gpif_flush,
+
+ input sys_clk, input sys_rst,
+ input [18:0] data_i, input src_rdy_i, output dst_rdy_o,
+ input [18:0] resp_i, input resp_src_rdy_i, output resp_dst_rdy_o,
+ output [31:0] debug
+ );
+
+ wire [18:0] data_o; // occ bit indicates flush
+ wire [17:0] resp_o; // no occ bit
+ wire final_rdy_data, final_rdy_resp;
+
+ // 33/257 Bug Fix
+ reg [8:0] read_count;
+ always @(negedge gpif_clk)
+ if(gpif_rst)
+ read_count <= 0;
+ else if(gpif_rd)
+ read_count <= read_count + 1;
+ else
+ read_count <= 0;
+
+ // Data Path
+ wire [18:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+ fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) rd_fifo_2clk
+ (.wclk(sys_clk), .datain(data_i[18:0]), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), .space(),
+ .rclk(~gpif_clk), .dataout(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int), .occupied(),
+ .arst(sys_rst));
+
+ reg [7:0] packet_count;
+ wire consume_data_line = gpif_rd & ~gpif_ep & ~read_count[8];
+ wire produce_eop = src_rdy_int & dst_rdy_int & data_int[17];
+ wire consume_sop = consume_data_line & final_rdy_data & data_o[16];
+ wire consume_eop = consume_data_line & final_rdy_data & data_o[17];
+
+ fifo_cascade #(.WIDTH(19), .SIZE(10)) rd_fifo
+ (.clk(~gpif_clk), .reset(gpif_rst), .clear(0),
+ .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int), .space(),
+ .dataout(data_o), .src_rdy_o(final_rdy_data), .dst_rdy_i(consume_data_line), .occupied());
+
+ always @(negedge gpif_clk)
+ if(gpif_rst)
+ packet_count <= 0;
+ else
+ if(produce_eop & ~consume_sop)
+ packet_count <= packet_count + 1;
+ else if(consume_sop & ~produce_eop)
+ packet_count <= packet_count - 1;
+
+ always @(negedge gpif_clk)
+ if(gpif_rst)
+ gpif_empty_d <= 1;
+ else
+ gpif_empty_d <= ~|packet_count;
+
+ // Use occ bit to signal a gpif flush
+ always @(negedge gpif_clk)
+ if(gpif_rst)
+ gpif_flush <= 0;
+ else if(consume_eop & data_o[18])
+ gpif_flush <= ~gpif_flush;
+
+ // Response Path
+ wire [15:0] resp_fifolevel;
+ wire consume_resp_line = gpif_rd & gpif_ep & ~read_count[4];
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) resp_fifo_2clk
+ (.wclk(sys_clk), .datain(resp_i[17:0]), .src_rdy_i(resp_src_rdy_i), .dst_rdy_o(resp_dst_rdy_o), .space(),
+ .rclk(~gpif_clk), .dataout(resp_o),
+ .src_rdy_o(final_rdy_resp), .dst_rdy_i(consume_resp_line), .occupied(resp_fifolevel),
+ .arst(sys_rst));
+
+ // FIXME -- handle short packets
+
+ always @(negedge gpif_clk)
+ if(gpif_rst)
+ gpif_empty_c <= 1;
+ else
+ gpif_empty_c <= resp_fifolevel < 16;
+
+ // Output Mux
+ assign gpif_data = gpif_ep ? resp_o[15:0] : data_o[15:0];
+
+ assign debug = { { 16'd0 },
+ { data_int[17:16], data_o[17:16], packet_count[3:0] },
+ { consume_sop, consume_eop, final_rdy_data, data_o[18], consume_data_line, consume_resp_line, src_rdy_int, dst_rdy_int} };
+
+endmodule // gpif_rd
diff --git a/fpga/usrp2/gpif/gpif_tb.v b/fpga/usrp2/gpif/gpif_tb.v
new file mode 100644
index 000000000..686284c2b
--- /dev/null
+++ b/fpga/usrp2/gpif/gpif_tb.v
@@ -0,0 +1,142 @@
+//
+// 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/>.
+//
+
+
+module gpif_tb();
+
+ reg sys_clk = 0;
+ reg sys_rst = 1;
+ reg gpif_clk = 0;
+ reg gpif_rst = 1;
+
+ reg [15:0] gpif_data;
+ reg WR = 0, EP = 0;
+
+ wire CF, DF;
+
+ wire gpif_full_d, gpif_full_c;
+ wire [18:0] data_o, ctrl_o, data_splt;
+ wire src_rdy, dst_rdy, src_rdy_splt, dst_rdy_splt;
+ wire ctrl_src_rdy, ctrl_dst_rdy;
+
+ assign ctrl_dst_rdy = 1;
+
+ initial $dumpfile("gpif_tb.vcd");
+ initial $dumpvars(0,gpif_tb);
+
+ initial #1000 gpif_rst = 0;
+ initial #1000 sys_rst = 0;
+ always #64 gpif_clk <= ~gpif_clk;
+ always #47.9 sys_clk <= ~sys_clk;
+
+ wire [18:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+
+ assign dst_rdy_splt = 1;
+
+ gpif_wr gpif_write
+ (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst),
+ .gpif_data(gpif_data), .gpif_wr(WR), .gpif_ep(EP),
+ .gpif_full_d(DF), .gpif_full_c(CF),
+
+ .sys_clk(sys_clk), .sys_rst(sys_rst),
+ .data_o(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int),
+ .ctrl_o(ctrl_o), .ctrl_src_rdy_o(ctrl_src_rdy), .ctrl_dst_rdy_i(ctrl_dst_rdy) );
+
+ packet_reframer tx_packet_reframer
+ (.clk(sys_clk), .reset(sys_rst), .clear(0),
+ .data_i(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int),
+ .data_o(data_o), .src_rdy_o(src_rdy), .dst_rdy_i(dst_rdy));
+
+ packet_splitter #(.FRAME_LEN(256)) rx_packet_splitter
+ (.clk(sys_clk), .reset(sys_rst), .clear(0),
+ .frames_per_packet(2),
+ .data_i(data_o), .src_rdy_i(src_rdy), .dst_rdy_o(dst_rdy),
+ .data_o(data_splt), .src_rdy_o(src_rdy_splt), .dst_rdy_i(dst_rdy_splt));
+
+ always @(posedge sys_clk)
+ if(ctrl_src_rdy & ctrl_dst_rdy)
+ $display("CTRL: %x",ctrl_o);
+
+ always @(posedge sys_clk)
+ if(src_rdy_splt & dst_rdy_splt)
+ begin
+ if(data_splt[16])
+ $display("<-------- DATA SOF--------->");
+ $display("DATA: %x",data_splt);
+ if(data_splt[17])
+ $display("<-------- DATA EOF--------->");
+ end
+
+ initial
+ begin
+ #10000;
+ repeat (1)
+ begin
+ @(posedge gpif_clk);
+
+ WR <= 1;
+ gpif_data <= 256; // Length
+ @(posedge gpif_clk);
+ gpif_data <= 16'h00;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data + 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+
+ while(DF)
+ @(posedge gpif_clk);
+ repeat (16)
+ @(posedge gpif_clk);
+
+ WR <= 1;
+ repeat(256)
+ begin
+ gpif_data <= gpif_data - 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+
+
+/*
+ while(DF)
+ @(posedge gpif_clk);
+
+ repeat (20)
+ @(posedge gpif_clk);
+ WR <= 1;
+ gpif_data <= 16'h5;
+ @(posedge gpif_clk);
+ gpif_data <= 16'h00;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data - 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+ */
+ end
+ end // initial begin
+
+ initial #200000 $finish;
+
+
+endmodule // gpif_tb
diff --git a/fpga/usrp2/gpif/gpif_wr.v b/fpga/usrp2/gpif/gpif_wr.v
new file mode 100644
index 000000000..89fae282e
--- /dev/null
+++ b/fpga/usrp2/gpif/gpif_wr.v
@@ -0,0 +1,95 @@
+//
+// 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/>.
+//
+
+
+module gpif_wr
+ (input gpif_clk, input gpif_rst,
+ input [15:0] gpif_data, input gpif_wr, input gpif_ep,
+ output reg gpif_full_d, output reg gpif_full_c,
+
+ input sys_clk, input sys_rst,
+ output [18:0] data_o, output src_rdy_o, input dst_rdy_i,
+ output [18:0] ctrl_o, output ctrl_src_rdy_o, input ctrl_dst_rdy_i,
+ output [31:0] debug );
+
+ reg wr_reg, ep_reg;
+ reg [15:0] gpif_data_reg;
+
+ always @(posedge gpif_clk)
+ begin
+ ep_reg <= gpif_ep;
+ wr_reg <= gpif_wr;
+ gpif_data_reg <= gpif_data;
+ end
+
+ reg [9:0] write_count;
+
+ always @(posedge gpif_clk)
+ if(gpif_rst)
+ write_count <= 0;
+ else if(wr_reg)
+ write_count <= write_count + 1;
+ else
+ write_count <= 0;
+
+ reg sop;
+ wire eop = (write_count == 255);
+ wire eop_ctrl = (write_count == 15);
+
+ always @(posedge gpif_clk)
+ sop <= gpif_wr & ~wr_reg;
+
+ // Data Path
+ wire [15:0] fifo_space;
+ always @(posedge gpif_clk)
+ if(gpif_rst)
+ gpif_full_d <= 1;
+ else
+ gpif_full_d <= fifo_space < 256;
+
+ wire [17:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+
+ fifo_cascade #(.WIDTH(18), .SIZE(10)) wr_fifo
+ (.clk(gpif_clk), .reset(gpif_rst), .clear(0),
+ .datain({eop,sop,gpif_data_reg}), .src_rdy_i(~ep_reg & wr_reg & ~write_count[8]), .dst_rdy_o(), .space(fifo_space),
+ .dataout(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int), .occupied());
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) wr_fifo_2clk
+ (.wclk(gpif_clk), .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int), .space(),
+ .rclk(sys_clk), .dataout(data_o[17:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i), .occupied(),
+ .arst(sys_rst));
+ assign data_o[18] = 1'b0;
+
+ // Control Path
+ wire [15:0] ctrl_fifo_space;
+ always @(posedge gpif_clk)
+ if(gpif_rst)
+ gpif_full_c <= 1;
+ else
+ gpif_full_c <= ctrl_fifo_space < 16;
+
+ fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) ctrl_fifo_2clk
+ (.wclk(gpif_clk), .datain({1'b0,eop_ctrl,sop,gpif_data_reg}),
+ .src_rdy_i(ep_reg & wr_reg & ~write_count[4]), .dst_rdy_o(), .space(ctrl_fifo_space),
+ .rclk(sys_clk), .dataout(ctrl_o[18:0]),
+ .src_rdy_o(ctrl_src_rdy_o), .dst_rdy_i(ctrl_dst_rdy_i), .occupied(),
+ .arst(sys_rst));
+
+ assign debug = { 16'd0, ep_reg, wr_reg, eop, sop, (~ep_reg & wr_reg & ~write_count[8]), src_rdy_int, dst_rdy_int, write_count[8:0]};
+
+endmodule // gpif_wr
diff --git a/fpga/usrp2/gpif/gpif_wr_tb.v b/fpga/usrp2/gpif/gpif_wr_tb.v
new file mode 100644
index 000000000..171bb96a1
--- /dev/null
+++ b/fpga/usrp2/gpif/gpif_wr_tb.v
@@ -0,0 +1,110 @@
+//
+// 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/>.
+//
+
+
+module gpif_wr_tb();
+
+ reg sys_clk = 0;
+ reg sys_rst = 1;
+ reg gpif_clk = 0;
+ reg gpif_rst = 1;
+
+ reg [15:0] gpif_data;
+ reg WR = 0, EP = 0;
+
+ wire CF, DF;
+
+ wire gpif_full_d, gpif_full_c;
+ wire [18:0] data_o, ctrl_o;
+ wire src_rdy, dst_rdy;
+ wire ctrl_src_rdy, ctrl_dst_rdy;
+
+ assign ctrl_dst_rdy = 1;
+ assign dst_rdy = 1;
+
+ initial $dumpfile("gpif_wr_tb.vcd");
+ initial $dumpvars(0,gpif_wr_tb);
+
+ initial #1000 gpif_rst = 0;
+ initial #1000 sys_rst = 0;
+ always #64 gpif_clk <= ~gpif_clk;
+ always #47.9 sys_clk <= ~sys_clk;
+
+ wire [18:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+
+ gpif_wr gpif_write
+ (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst),
+ .gpif_data(gpif_data), .gpif_wr(WR), .gpif_ep(EP),
+ .gpif_full_d(DF), .gpif_full_c(CF),
+
+ .sys_clk(sys_clk), .sys_rst(sys_rst),
+ .data_o(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int),
+ .ctrl_o(ctrl_o), .ctrl_src_rdy_o(ctrl_src_rdy), .ctrl_dst_rdy_i(ctrl_dst_rdy) );
+
+ packet_reframer tx_packet_reframer
+ (.clk(sys_clk), .reset(sys_rst), .clear(0),
+ .data_i(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int),
+ .data_o(data_o), .src_rdy_o(src_rdy), .dst_rdy_i(dst_rdy));
+
+ always @(posedge sys_clk)
+ if(ctrl_src_rdy & ctrl_dst_rdy)
+ $display("CTRL: %x",ctrl_o);
+
+ always @(posedge sys_clk)
+ if(src_rdy & dst_rdy)
+ begin
+ if(data_o[16])
+ $display("<-------- DATA SOF--------->");
+ $display("DATA: %x",data_o);
+ if(data_o[17])
+ $display("<-------- DATA EOF--------->");
+ end
+
+ initial
+ begin
+ #10000;
+ repeat (1)
+ begin
+ WR <= 1;
+ gpif_data <= 10; // Length
+ @(posedge gpif_clk);
+ gpif_data <= 16'h00;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data + 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+ repeat (20)
+ @(posedge gpif_clk);
+ WR <= 1;
+ gpif_data <= 16'h5;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data - 1;
+ @(posedge gpif_clk);
+ end
+ end
+ end // initial begin
+
+ initial #100000 $finish;
+
+
+endmodule // gpif_wr_tb
diff --git a/fpga/usrp2/gpif/packet_reframer.v b/fpga/usrp2/gpif/packet_reframer.v
new file mode 100644
index 000000000..923d499ae
--- /dev/null
+++ b/fpga/usrp2/gpif/packet_reframer.v
@@ -0,0 +1,79 @@
+//
+// 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/>.
+//
+
+
+// Join vita packets longer than one GPIF frame, drop padding on short frames
+
+module packet_reframer
+ (input clk, input reset, input clear,
+ input [18:0] data_i,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [18:0] data_o,
+ output src_rdy_o,
+ input dst_rdy_i);
+
+ reg [1:0] state;
+ reg [15:0] length;
+
+ localparam RF_IDLE = 0;
+ localparam RF_PKT = 1;
+ localparam RF_DUMP = 2;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= 0;
+ else
+ if(src_rdy_i & dst_rdy_i)
+ case(state)
+ RF_IDLE :
+ begin
+ length <= {data_i[14:0],1'b0};
+ state <= RF_PKT;
+ end
+ RF_PKT :
+ begin
+ if(length == 2)
+ if(data_i[17])
+ state <= RF_IDLE;
+ else
+ state <= RF_DUMP;
+ else
+ length <= length - 1;
+ end
+ RF_DUMP :
+ if(data_i[17])
+ state <= RF_IDLE;
+ default :
+ state<= RF_IDLE;
+ endcase // case (state)
+
+ assign dst_rdy_o = dst_rdy_i; // this is a little pessimistic but ok
+ assign src_rdy_o = src_rdy_i & (state != RF_DUMP);
+
+ wire occ_out = 0;
+ wire eof_out = (state == RF_PKT) & (length == 2);
+ wire sof_out = (state == RF_IDLE);
+ wire [15:0] data_out = data_i[15:0];
+ assign data_o = {occ_out, eof_out, sof_out, data_out};
+
+
+endmodule // packet_reframer
+
+
+
+
diff --git a/fpga/usrp2/gpif/packet_splitter.v b/fpga/usrp2/gpif/packet_splitter.v
new file mode 100644
index 000000000..ba4c8cded
--- /dev/null
+++ b/fpga/usrp2/gpif/packet_splitter.v
@@ -0,0 +1,123 @@
+//
+// 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/>.
+//
+
+
+// Split vita packets longer than one GPIF frame, add padding on short frames
+
+module packet_splitter
+ #(parameter FRAME_LEN=256)
+ (input clk, input reset, input clear,
+ input [7:0] frames_per_packet,
+ input [18:0] data_i,
+ input src_rdy_i,
+ output dst_rdy_o,
+ output [18:0] data_o,
+ output src_rdy_o,
+ input dst_rdy_i,
+ output [31:0] debug0,
+ output [31:0] debug1);
+
+ reg [1:0] state;
+ reg [15:0] length;
+ reg [15:0] frame_len;
+ reg [7:0] frame_count;
+
+ localparam PS_IDLE = 0;
+ localparam PS_FRAME = 1;
+ localparam PS_NEW_FRAME = 2;
+ localparam PS_PAD = 3;
+
+ wire eof_i = data_i[17];
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ state <= PS_IDLE;
+ frame_count <= 0;
+ end
+ else
+ case(state)
+ PS_IDLE :
+ if(src_rdy_i & dst_rdy_i)
+ begin
+ length <= { data_i[14:0],1'b0};
+ frame_len <= FRAME_LEN;
+ state <= PS_FRAME;
+ frame_count <= 1;
+ end
+ PS_FRAME :
+ if(src_rdy_i & dst_rdy_i)
+ if((frame_len == 2) & ((length == 2) | eof_i))
+ state <= PS_IDLE;
+ else if(frame_len == 2)
+ begin
+ length <= length - 1;
+ state <= PS_NEW_FRAME;
+ frame_count <= frame_count + 1;
+ end
+ else if((length == 2)|eof_i)
+ begin
+ frame_len <= frame_len - 1;
+ state <= PS_PAD;
+ end
+ else
+ begin
+ frame_len <= frame_len - 1;
+ length <= length - 1;
+ end
+ PS_NEW_FRAME :
+ if(src_rdy_i & dst_rdy_i)
+ begin
+ frame_len <= FRAME_LEN;
+ if((length == 2)|eof_i)
+ state <= PS_PAD;
+ else
+ begin
+ state <= PS_FRAME;
+ length <= length - 1;
+ end // else: !if((length == 2)|eof_i)
+ end // if (src_rdy_i & dst_rdy_i)
+
+ PS_PAD :
+ if(dst_rdy_i)
+ if(frame_len == 2)
+ state <= PS_IDLE;
+ else
+ frame_len <= frame_len - 1;
+
+ endcase // case (state)
+
+ wire next_state_is_idle = dst_rdy_i & (frame_len==2) &
+ ( (state==PS_PAD) | ( (state==PS_FRAME) & src_rdy_i & ((length==2)|eof_i) ) );
+
+
+
+
+ assign dst_rdy_o = dst_rdy_i & (state != PS_PAD);
+ assign src_rdy_o = src_rdy_i | (state == PS_PAD);
+
+ wire eof_out = (frame_len == 2) & (state != PS_IDLE) & (state != PS_NEW_FRAME);
+ wire sof_out = (state == PS_IDLE) | (state == PS_NEW_FRAME);
+ wire occ_out = eof_out & next_state_is_idle & (frames_per_packet != frame_count);
+
+ wire [15:0] data_out = data_i[15:0];
+ assign data_o = {occ_out, eof_out, sof_out, data_out};
+
+ assign debug0 = { 8'd0, dst_rdy_o, src_rdy_o, next_state_is_idle, eof_out, sof_out, occ_out, state[1:0], frame_count[7:0], frames_per_packet[7:0] };
+ assign debug1 = { length[15:0], frame_len[15:0] };
+
+endmodule // packet_splitter
diff --git a/fpga/usrp2/gpif/packet_splitter_tb.v b/fpga/usrp2/gpif/packet_splitter_tb.v
new file mode 100644
index 000000000..329b58e0d
--- /dev/null
+++ b/fpga/usrp2/gpif/packet_splitter_tb.v
@@ -0,0 +1,137 @@
+//
+// 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/>.
+//
+
+
+module packet_splitter_tb();
+
+ reg sys_clk = 0;
+ reg sys_rst = 1;
+ reg gpif_clk = 0;
+ reg gpif_rst = 1;
+
+ reg [15:0] gpif_data;
+ reg WR = 0, EP = 0;
+
+ wire CF, DF;
+
+ wire gpif_full_d, gpif_full_c;
+ wire [18:0] data_o, ctrl_o, data_splt;
+ wire src_rdy, dst_rdy, src_rdy_splt, dst_rdy_splt;
+ wire ctrl_src_rdy, ctrl_dst_rdy;
+
+ assign ctrl_dst_rdy = 1;
+
+ initial $dumpfile("packet_splitter_tb.vcd");
+ initial $dumpvars(0,packet_splitter_tb);
+
+ initial #1000 gpif_rst = 0;
+ initial #1000 sys_rst = 0;
+ always #64 gpif_clk <= ~gpif_clk;
+ always #47.9 sys_clk <= ~sys_clk;
+
+ wire [35:0] data_int;
+ wire src_rdy_int, dst_rdy_int;
+
+ assign dst_rdy_splt = 1;
+
+ vita_pkt_gen vita_pkt_gen
+ (.clk(sys_clk), .reset(sys_rst) , .clear(0),
+ .len(512),.data_o(data_int), .src_rdy_o(src_rdy_int), .dst_rdy_i(dst_rdy_int));
+
+ fifo36_to_fifo19 #(.LE(1)) f36_to_f19
+ (.clk(sys_clk), .reset(sys_rst), .clear(0),
+ .f36_datain(data_int), .f36_src_rdy_i(src_rdy_int), .f36_dst_rdy_o(dst_rdy_int),
+ .f19_dataout(data_o), .f19_src_rdy_o(src_rdy), .f19_dst_rdy_i(dst_rdy));
+
+ packet_splitter #(.FRAME_LEN(13)) rx_packet_splitter
+ (.clk(sys_clk), .reset(sys_rst), .clear(0),
+ .frames_per_packet(4),
+ .data_i(data_o), .src_rdy_i(src_rdy), .dst_rdy_o(dst_rdy),
+ .data_o(data_splt), .src_rdy_o(src_rdy_splt), .dst_rdy_i(dst_rdy_splt));
+
+ always @(posedge sys_clk)
+ if(ctrl_src_rdy & ctrl_dst_rdy)
+ $display("CTRL: %x",ctrl_o);
+
+ always @(posedge sys_clk)
+ if(src_rdy_splt & dst_rdy_splt)
+ begin
+ if(data_splt[16])
+ $display("<-------- DATA SOF--------->");
+ $display("DATA: %x",data_splt);
+ if(data_splt[17])
+ $display("<-------- DATA EOF--------->");
+ end
+
+ initial
+ begin
+ #10000;
+ repeat (1)
+ begin
+ @(posedge gpif_clk);
+
+ WR <= 1;
+ gpif_data <= 256; // Length
+ @(posedge gpif_clk);
+ gpif_data <= 16'h00;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data + 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+
+ while(DF)
+ @(posedge gpif_clk);
+ repeat (16)
+ @(posedge gpif_clk);
+
+ WR <= 1;
+ repeat(256)
+ begin
+ gpif_data <= gpif_data - 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+
+
+/*
+ while(DF)
+ @(posedge gpif_clk);
+
+ repeat (20)
+ @(posedge gpif_clk);
+ WR <= 1;
+ gpif_data <= 16'h5;
+ @(posedge gpif_clk);
+ gpif_data <= 16'h00;
+ @(posedge gpif_clk);
+ repeat(254)
+ begin
+ gpif_data <= gpif_data - 1;
+ @(posedge gpif_clk);
+ end
+ WR <= 0;
+ */
+ end
+ end // initial begin
+
+ initial #200000 $finish;
+
+
+endmodule // packet_splitter_tb
diff --git a/fpga/usrp2/gpmc/dbsm.v b/fpga/usrp2/gpmc/dbsm.v
index 530af7205..1ee250738 100644
--- a/fpga/usrp2/gpmc/dbsm.v
+++ b/fpga/usrp2/gpmc/dbsm.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module bsm
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/gpmc/edge_sync.v b/fpga/usrp2/gpmc/edge_sync.v
index 5d9417c08..74f1a2f1c 100644
--- a/fpga/usrp2/gpmc/edge_sync.v
+++ b/fpga/usrp2/gpmc/edge_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module edge_sync
diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v b/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
index 9a8e37ce9..bb4c58ec4 100644
--- a/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
+++ b/fpga/usrp2/gpmc/fifo_to_gpmc_async.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_to_gpmc_async
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v b/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v
index ef59d7137..9da9caf86 100644
--- a/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v
+++ b/fpga/usrp2/gpmc/fifo_to_gpmc_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Assumes a GPMC cycle with GPMC clock, as in the timing diagrams
// If a packet bigger or smaller than we are told is sent, behavior is undefined.
diff --git a/fpga/usrp2/gpmc/fifo_watcher.v b/fpga/usrp2/gpmc/fifo_watcher.v
index fe4e35de3..b139f5143 100644
--- a/fpga/usrp2/gpmc/fifo_watcher.v
+++ b/fpga/usrp2/gpmc/fifo_watcher.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module fifo_watcher
diff --git a/fpga/usrp2/gpmc/gpmc_async.v b/fpga/usrp2/gpmc/gpmc_async.v
index 02bf45b8a..c0bec683a 100644
--- a/fpga/usrp2/gpmc/gpmc_async.v
+++ b/fpga/usrp2/gpmc/gpmc_async.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
//////////////////////////////////////////////////////////////////////////////////
module gpmc_async
diff --git a/fpga/usrp2/gpmc/gpmc_sync.v b/fpga/usrp2/gpmc/gpmc_sync.v
index 61c54a793..ba7251c8d 100644
--- a/fpga/usrp2/gpmc/gpmc_sync.v
+++ b/fpga/usrp2/gpmc/gpmc_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
//////////////////////////////////////////////////////////////////////////////////
module gpmc_sync
diff --git a/fpga/usrp2/gpmc/gpmc_to_fifo_async.v b/fpga/usrp2/gpmc/gpmc_to_fifo_async.v
index 55c0cef50..aa93e52af 100644
--- a/fpga/usrp2/gpmc/gpmc_to_fifo_async.v
+++ b/fpga/usrp2/gpmc/gpmc_to_fifo_async.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module gpmc_to_fifo_async
(input [15:0] EM_D, input [1:0] EM_NBE, input EM_NCS, input EM_NWE,
diff --git a/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v b/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v
index 688de0e17..7ff7afdc2 100644
--- a/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v
+++ b/fpga/usrp2/gpmc/gpmc_to_fifo_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Assumes a GPMC cycle with GPMC clock, as in the timing diagrams
// If a packet bigger or smaller than we are told is sent, behavior is undefined.
diff --git a/fpga/usrp2/gpmc/gpmc_wb.v b/fpga/usrp2/gpmc/gpmc_wb.v
index db6fbc6e9..645201ef7 100644
--- a/fpga/usrp2/gpmc/gpmc_wb.v
+++ b/fpga/usrp2/gpmc/gpmc_wb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module gpmc_wb
diff --git a/fpga/usrp2/gpmc/ram_to_fifo.v b/fpga/usrp2/gpmc/ram_to_fifo.v
index 8549dcc35..958c88b0f 100644
--- a/fpga/usrp2/gpmc/ram_to_fifo.v
+++ b/fpga/usrp2/gpmc/ram_to_fifo.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram_to_fifo
diff --git a/fpga/usrp2/models/CY7C1356C/cy1356.v b/fpga/usrp2/models/CY7C1356C/cy1356.v
index 9197eea6d..ab7ace610 100644
--- a/fpga/usrp2/models/CY7C1356C/cy1356.v
+++ b/fpga/usrp2/models/CY7C1356C/cy1356.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`define sb200
//************************************************************************
//************************************************************************
diff --git a/fpga/usrp2/models/CY7C1356C/testbench.v b/fpga/usrp2/models/CY7C1356C/testbench.v
index 5dde89e6c..01e0cbe00 100644
--- a/fpga/usrp2/models/CY7C1356C/testbench.v
+++ b/fpga/usrp2/models/CY7C1356C/testbench.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 10ps
diff --git a/fpga/usrp2/models/FIFO_GENERATOR_V6_1.v b/fpga/usrp2/models/FIFO_GENERATOR_V6_1.v
new file mode 100644
index 000000000..65bbac447
--- /dev/null
+++ b/fpga/usrp2/models/FIFO_GENERATOR_V6_1.v
@@ -0,0 +1,4575 @@
+/*
+ *******************************************************************************
+ *
+ * FIFO Generator - Verilog Behavioral Model
+ *
+ *******************************************************************************
+ *
+ * (c) Copyright 1995 - 2009 Xilinx, Inc. All rights reserved.
+ *
+ * This file contains confidential and proprietary information
+ * of Xilinx, Inc. and is protected under U.S. and
+ * international copyright and other intellectual property
+ * laws.
+ *
+ * DISCLAIMER
+ * This disclaimer is not a license and does not grant any
+ * rights to the materials distributed herewith. Except as
+ * otherwise provided in a valid license issued to you by
+ * Xilinx, and to the maximum extent permitted by applicable
+ * law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
+ * WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
+ * AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
+ * BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
+ * INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
+ * (2) Xilinx shall not be liable (whether in contract or tort,
+ * including negligence, or under any other theory of
+ * liability) for any loss or damage of any kind or nature
+ * related to, arising under or in connection with these
+ * materials, including for any direct, or any indirect,
+ * special, incidental, or consequential loss or damage
+ * (including loss of data, profits, goodwill, or any type of
+ * loss or damage suffered as a result of any action brought
+ * by a third party) even if such damage or loss was
+ * reasonably foreseeable or Xilinx had been advised of the
+ * possibility of the same.
+ *
+ * CRITICAL APPLICATIONS
+ * Xilinx products are not designed or intended to be fail-
+ * safe, or for use in any application requiring fail-safe
+ * performance, such as life-support or safety devices or
+ * systems, Class III medical devices, nuclear facilities,
+ * applications related to the deployment of airbags, or any
+ * other applications that could lead to death, personal
+ * injury, or severe property or environmental damage
+ * (individually and collectively, "Critical
+ * Applications"). Customer assumes the sole risk and
+ * liability of any use of Xilinx products in Critical
+ * Applications, subject only to applicable laws and
+ * regulations governing limitations on product liability.
+ *
+ * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
+ * PART OF THIS FILE AT ALL TIMES.
+ *
+ *******************************************************************************
+ *******************************************************************************
+ *
+ * Filename: FIFO_GENERATOR_V6_1.v
+ *
+ * Author : Xilinx
+ *
+ *******************************************************************************
+ * Structure:
+ *
+ * fifo_generator_v6_1.vhd
+ * |
+ * +-fifo_generator_v6_1_bhv_ver_as
+ * |
+ * +-fifo_generator_v6_1_bhv_ver_ss
+ * |
+ * +-fifo_generator_v6_1_bhv_ver_preload0
+ *
+ *******************************************************************************
+ * Description:
+ *
+ * The Verilog behavioral model for the FIFO Generator.
+ *
+ * The behavioral model has three parts:
+ * - The behavioral model for independent clocks FIFOs (_as)
+ * - The behavioral model for common clock FIFOs (_ss)
+ * - The "preload logic" block which implements First-word Fall-through
+ *
+ *******************************************************************************
+ * Description:
+ * The verilog behavioral model for the FIFO generator core.
+ *
+ *******************************************************************************
+ */
+
+`timescale 1ps/1ps
+`ifndef TCQ
+ `define TCQ 100
+`endif
+
+
+/*******************************************************************************
+ * Declaration of top-level module
+ ******************************************************************************/
+module FIFO_GENERATOR_V6_1
+ #(
+ parameter C_COMMON_CLOCK = 0,
+ parameter C_COUNT_TYPE = 0,
+ parameter C_DATA_COUNT_WIDTH = 2,
+ parameter C_DEFAULT_VALUE = "",
+ parameter C_DIN_WIDTH = 8,
+ parameter C_DOUT_RST_VAL = "",
+ parameter C_DOUT_WIDTH = 8,
+ parameter C_ENABLE_RLOCS = 0,
+ parameter C_FAMILY = "virtex6", //Not allowed in Verilog model
+ parameter C_FULL_FLAGS_RST_VAL = 1,
+ parameter C_HAS_ALMOST_EMPTY = 0,
+ parameter C_HAS_ALMOST_FULL = 0,
+ parameter C_HAS_BACKUP = 0,
+ parameter C_HAS_DATA_COUNT = 0,
+ parameter C_HAS_INT_CLK = 0,
+ parameter C_HAS_MEMINIT_FILE = 0,
+ parameter C_HAS_OVERFLOW = 0,
+ parameter C_HAS_RD_DATA_COUNT = 0,
+ parameter C_HAS_RD_RST = 0,
+ parameter C_HAS_RST = 0,
+ parameter C_HAS_SRST = 0,
+ parameter C_HAS_UNDERFLOW = 0,
+ parameter C_HAS_VALID = 0,
+ parameter C_HAS_WR_ACK = 0,
+ parameter C_HAS_WR_DATA_COUNT = 0,
+ parameter C_HAS_WR_RST = 0,
+ parameter C_IMPLEMENTATION_TYPE = 0,
+ parameter C_INIT_WR_PNTR_VAL = 0,
+ parameter C_MEMORY_TYPE = 1,
+ parameter C_MIF_FILE_NAME = "",
+ parameter C_OPTIMIZATION_MODE = 0,
+ parameter C_OVERFLOW_LOW = 0,
+ parameter C_PRELOAD_LATENCY = 1,
+ parameter C_PRELOAD_REGS = 0,
+ parameter C_PRIM_FIFO_TYPE = "",
+ parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_EMPTY_TYPE = 0,
+ parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_FULL_TYPE = 0,
+ parameter C_RD_DATA_COUNT_WIDTH = 2,
+ parameter C_RD_DEPTH = 256,
+ parameter C_RD_FREQ = 1,
+ parameter C_RD_PNTR_WIDTH = 8,
+ parameter C_UNDERFLOW_LOW = 0,
+ parameter C_USE_DOUT_RST = 0,
+ parameter C_USE_ECC = 0,
+ parameter C_USE_EMBEDDED_REG = 0,
+ parameter C_USE_FIFO16_FLAGS = 0,
+ parameter C_USE_FWFT_DATA_COUNT = 0,
+ parameter C_VALID_LOW = 0,
+ parameter C_WR_ACK_LOW = 0,
+ parameter C_WR_DATA_COUNT_WIDTH = 2,
+ parameter C_WR_DEPTH = 256,
+ parameter C_WR_FREQ = 1,
+ parameter C_WR_PNTR_WIDTH = 8,
+ parameter C_WR_RESPONSE_LATENCY = 1,
+ parameter C_MSGON_VAL = 1,
+ parameter C_ENABLE_RST_SYNC = 1,
+ parameter C_ERROR_INJECTION_TYPE = 0
+ )
+
+ (
+ input BACKUP,
+ input BACKUP_MARKER,
+ input CLK,
+ input RST,
+ input SRST,
+ input WR_CLK,
+ input WR_RST,
+ input RD_CLK,
+ input RD_RST,
+ input [C_DIN_WIDTH-1:0] DIN,
+ input WR_EN,
+ input RD_EN,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE,
+ input INT_CLK,
+ input INJECTDBITERR,
+ input INJECTSBITERR,
+
+ output [C_DOUT_WIDTH-1:0] DOUT,
+ output FULL,
+ output ALMOST_FULL,
+ output WR_ACK,
+ output OVERFLOW,
+ output EMPTY,
+ output ALMOST_EMPTY,
+ output VALID,
+ output UNDERFLOW,
+ output [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT,
+ output [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT,
+ output [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT,
+ output PROG_FULL,
+ output PROG_EMPTY,
+ output SBITERR,
+ output DBITERR
+ );
+
+/*
+ ******************************************************************************
+ * Definition of Parameters
+ ******************************************************************************
+ * C_COMMON_CLOCK : Common Clock (1), Independent Clocks (0)
+ * C_COUNT_TYPE : *not used
+ * C_DATA_COUNT_WIDTH : Width of DATA_COUNT bus
+ * C_DEFAULT_VALUE : *not used
+ * C_DIN_WIDTH : Width of DIN bus
+ * C_DOUT_RST_VAL : Reset value of DOUT
+ * C_DOUT_WIDTH : Width of DOUT bus
+ * C_ENABLE_RLOCS : *not used
+ * C_FAMILY : not used in bhv model
+ * C_FULL_FLAGS_RST_VAL : Full flags rst val (0 or 1)
+ * C_HAS_ALMOST_EMPTY : 1=Core has ALMOST_EMPTY flag
+ * C_HAS_ALMOST_FULL : 1=Core has ALMOST_FULL flag
+ * C_HAS_BACKUP : *not used
+ * C_HAS_DATA_COUNT : 1=Core has DATA_COUNT bus
+ * C_HAS_INT_CLK : not used in bhv model
+ * C_HAS_MEMINIT_FILE : *not used
+ * C_HAS_OVERFLOW : 1=Core has OVERFLOW flag
+ * C_HAS_RD_DATA_COUNT : 1=Core has RD_DATA_COUNT bus
+ * C_HAS_RD_RST : *not used
+ * C_HAS_RST : 1=Core has Async Rst
+ * C_HAS_SRST : 1=Core has Sync Rst
+ * C_HAS_UNDERFLOW : 1=Core has UNDERFLOW flag
+ * C_HAS_VALID : 1=Core has VALID flag
+ * C_HAS_WR_ACK : 1=Core has WR_ACK flag
+ * C_HAS_WR_DATA_COUNT : 1=Core has WR_DATA_COUNT bus
+ * C_HAS_WR_RST : *not used
+ * C_IMPLEMENTATION_TYPE : 0=Common-Clock Bram/Dram
+ * 1=Common-Clock ShiftRam
+ * 2=Indep. Clocks Bram/Dram
+ * 3=Virtex-4 Built-in
+ * 4=Virtex-5 Built-in
+ * C_INIT_WR_PNTR_VAL : *not used
+ * C_MEMORY_TYPE : 1=Block RAM
+ * 2=Distributed RAM
+ * 3=Shift RAM
+ * 4=Built-in FIFO
+ * C_MIF_FILE_NAME : *not used
+ * C_OPTIMIZATION_MODE : *not used
+ * C_OVERFLOW_LOW : 1=OVERFLOW active low
+ * C_PRELOAD_LATENCY : Latency of read: 0, 1, 2
+ * C_PRELOAD_REGS : 1=Use output registers
+ * C_PRIM_FIFO_TYPE : not used in bhv model
+ * C_PROG_EMPTY_THRESH_ASSERT_VAL: PROG_EMPTY assert threshold
+ * C_PROG_EMPTY_THRESH_NEGATE_VAL: PROG_EMPTY negate threshold
+ * C_PROG_EMPTY_TYPE : 0=No programmable empty
+ * 1=Single prog empty thresh constant
+ * 2=Multiple prog empty thresh constants
+ * 3=Single prog empty thresh input
+ * 4=Multiple prog empty thresh inputs
+ * C_PROG_FULL_THRESH_ASSERT_VAL : PROG_FULL assert threshold
+ * C_PROG_FULL_THRESH_NEGATE_VAL : PROG_FULL negate threshold
+ * C_PROG_FULL_TYPE : 0=No prog full
+ * 1=Single prog full thresh constant
+ * 2=Multiple prog full thresh constants
+ * 3=Single prog full thresh input
+ * 4=Multiple prog full thresh inputs
+ * C_RD_DATA_COUNT_WIDTH : Width of RD_DATA_COUNT bus
+ * C_RD_DEPTH : Depth of read interface (2^N)
+ * C_RD_FREQ : not used in bhv model
+ * C_RD_PNTR_WIDTH : always log2(C_RD_DEPTH)
+ * C_UNDERFLOW_LOW : 1=UNDERFLOW active low
+ * C_USE_DOUT_RST : 1=Resets DOUT on RST
+ * C_USE_ECC : Used for error injection purpose
+ * C_USE_EMBEDDED_REG : 1=Use BRAM embedded output register
+ * C_USE_FIFO16_FLAGS : not used in bhv model
+ * C_USE_FWFT_DATA_COUNT : 1=Use extra logic for FWFT data count
+ * C_VALID_LOW : 1=VALID active low
+ * C_WR_ACK_LOW : 1=WR_ACK active low
+ * C_WR_DATA_COUNT_WIDTH : Width of WR_DATA_COUNT bus
+ * C_WR_DEPTH : Depth of write interface (2^N)
+ * C_WR_FREQ : not used in bhv model
+ * C_WR_PNTR_WIDTH : always log2(C_WR_DEPTH)
+ * C_WR_RESPONSE_LATENCY : *not used
+ * C_MSGON_VAL : *not used by bhv model
+ * C_ENABLE_RST_SYNC : 0 = Use WR_RST & RD_RST
+ * 1 = Use RST
+ * C_ERROR_INJECTION_TYPE : 0 = No error injection
+ * 1 = Single bit error injection only
+ * 2 = Double bit error injection only
+ * 3 = Single and double bit error injection
+ ******************************************************************************
+ * Definition of Ports
+ ******************************************************************************
+ * BACKUP : Not used
+ * BACKUP_MARKER: Not used
+ * CLK : Clock
+ * DIN : Input data bus
+ * PROG_EMPTY_THRESH : Threshold for Programmable Empty Flag
+ * PROG_EMPTY_THRESH_ASSERT: Threshold for Programmable Empty Flag
+ * PROG_EMPTY_THRESH_NEGATE: Threshold for Programmable Empty Flag
+ * PROG_FULL_THRESH : Threshold for Programmable Full Flag
+ * PROG_FULL_THRESH_ASSERT : Threshold for Programmable Full Flag
+ * PROG_FULL_THRESH_NEGATE : Threshold for Programmable Full Flag
+ * RD_CLK : Read Domain Clock
+ * RD_EN : Read enable
+ * RD_RST : Read Reset
+ * RST : Asynchronous Reset
+ * SRST : Synchronous Reset
+ * WR_CLK : Write Domain Clock
+ * WR_EN : Write enable
+ * WR_RST : Write Reset
+ * INT_CLK : Internal Clock
+ * INJECTSBITERR: Inject Signle bit error
+ * INJECTDBITERR: Inject Double bit error
+ * ALMOST_EMPTY : One word remaining in FIFO
+ * ALMOST_FULL : One empty space remaining in FIFO
+ * DATA_COUNT : Number of data words in fifo( synchronous to CLK)
+ * DOUT : Output data bus
+ * EMPTY : Empty flag
+ * FULL : Full flag
+ * OVERFLOW : Last write rejected
+ * PROG_EMPTY : Programmable Empty Flag
+ * PROG_FULL : Programmable Full Flag
+ * RD_DATA_COUNT: Number of data words in fifo (synchronous to RD_CLK)
+ * UNDERFLOW : Last read rejected
+ * VALID : Last read acknowledged, DOUT bus VALID
+ * WR_ACK : Last write acknowledged
+ * WR_DATA_COUNT: Number of data words in fifo (synchronous to WR_CLK)
+ * SBITERR : Single Bit ECC Error Detected
+ * DBITERR : Double Bit ECC Error Detected
+ ******************************************************************************
+ */
+
+
+ /*****************************************************************************
+ * Derived parameters
+ ****************************************************************************/
+ //There are 2 Verilog behavioral models
+ // 0 = Common-Clock FIFO/ShiftRam FIFO
+ // 1 = Independent Clocks FIFO
+ parameter C_VERILOG_IMPL = (C_IMPLEMENTATION_TYPE == 2) ? 1 : 0;
+
+ //Internal reset signals
+ reg rd_rst_asreg = 0;
+ reg rd_rst_asreg_d1 = 0;
+ reg rd_rst_asreg_d2 = 0;
+ reg rd_rst_reg = 0;
+ wire rd_rst_comb;
+ reg rd_rst_d1 = 0;
+ reg wr_rst_asreg = 0;
+ reg wr_rst_asreg_d1 = 0;
+ reg wr_rst_asreg_d2 = 0;
+ reg wr_rst_reg = 0;
+ wire wr_rst_comb;
+ wire wr_rst_i;
+ wire rd_rst_i;
+ wire rst_i;
+
+ //Internal reset signals
+ reg rst_asreg = 0;
+ reg rst_asreg_d1 = 0;
+ reg rst_asreg_d2 = 0;
+ reg rst_reg = 0;
+ wire rst_comb;
+ wire rst_full_gen_i;
+ wire rst_full_ff_i;
+
+ wire RD_CLK_P0_IN;
+ wire RST_P0_IN;
+ wire RD_EN_FIFO_IN;
+ wire RD_EN_P0_IN;
+
+ wire ALMOST_EMPTY_FIFO_OUT;
+ wire ALMOST_FULL_FIFO_OUT;
+ wire [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT_FIFO_OUT;
+ wire [C_DOUT_WIDTH-1:0] DOUT_FIFO_OUT;
+ wire EMPTY_FIFO_OUT;
+ wire FULL_FIFO_OUT;
+ wire OVERFLOW_FIFO_OUT;
+ wire PROG_EMPTY_FIFO_OUT;
+ wire PROG_FULL_FIFO_OUT;
+ wire VALID_FIFO_OUT;
+ wire [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT_FIFO_OUT;
+ wire UNDERFLOW_FIFO_OUT;
+ wire WR_ACK_FIFO_OUT;
+ wire [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT_FIFO_OUT;
+
+
+ //***************************************************************************
+ // Internal Signals
+ // The core uses either the internal_ wires or the preload0_ wires depending
+ // on whether the core uses Preload0 or not.
+ // When using preload0, the internal signals connect the internal core to
+ // the preload logic, and the external core's interfaces are tied to the
+ // preload0 signals from the preload logic.
+ //***************************************************************************
+ wire [C_DOUT_WIDTH-1:0] DATA_P0_OUT;
+ wire VALID_P0_OUT;
+ wire EMPTY_P0_OUT;
+ wire ALMOSTEMPTY_P0_OUT;
+ reg EMPTY_P0_OUT_Q;
+ reg ALMOSTEMPTY_P0_OUT_Q;
+ wire UNDERFLOW_P0_OUT;
+ wire RDEN_P0_OUT;
+ wire [C_DOUT_WIDTH-1:0] DATA_P0_IN;
+ wire EMPTY_P0_IN;
+ reg [31:0] DATA_COUNT_FWFT;
+ reg SS_FWFT_WR ;
+ reg SS_FWFT_RD ;
+
+ wire sbiterr_fifo_out;
+ wire dbiterr_fifo_out;
+
+ // Assign 0 if not selected to avoid 'X' propogation to S/DBITERR.
+ assign inject_sbit_err = ((C_ERROR_INJECTION_TYPE == 1) || (C_ERROR_INJECTION_TYPE == 3)) ?
+ INJECTSBITERR : 0;
+ assign inject_dbit_err = ((C_ERROR_INJECTION_TYPE == 2) || (C_ERROR_INJECTION_TYPE == 3)) ?
+ INJECTDBITERR : 0;
+
+
+// Choose the behavioral model to instantiate based on the C_VERILOG_IMPL
+// parameter (1=Independent Clocks, 0=Common Clock)
+
+ localparam FULL_FLAGS_RST_VAL = (C_HAS_SRST == 1) ? 0 : C_FULL_FLAGS_RST_VAL;
+generate
+case (C_VERILOG_IMPL)
+0 : begin : block1
+ //Common Clock Behavioral Model
+ fifo_generator_v6_1_bhv_ver_ss
+ #(
+ C_DATA_COUNT_WIDTH,
+ C_DIN_WIDTH,
+ C_DOUT_RST_VAL,
+ C_DOUT_WIDTH,
+// C_FULL_FLAGS_RST_VAL,
+ FULL_FLAGS_RST_VAL,
+ C_HAS_ALMOST_EMPTY,
+ C_HAS_ALMOST_FULL,
+ C_HAS_DATA_COUNT,
+ C_HAS_OVERFLOW,
+ C_HAS_RD_DATA_COUNT,
+ C_HAS_RST,
+ C_HAS_SRST,
+ C_HAS_UNDERFLOW,
+ C_HAS_VALID,
+ C_HAS_WR_ACK,
+ C_HAS_WR_DATA_COUNT,
+ C_IMPLEMENTATION_TYPE,
+ C_MEMORY_TYPE,
+ C_OVERFLOW_LOW,
+ C_PRELOAD_LATENCY,
+ C_PRELOAD_REGS,
+ C_PROG_EMPTY_THRESH_ASSERT_VAL,
+ C_PROG_EMPTY_THRESH_NEGATE_VAL,
+ C_PROG_EMPTY_TYPE,
+ C_PROG_FULL_THRESH_ASSERT_VAL,
+ C_PROG_FULL_THRESH_NEGATE_VAL,
+ C_PROG_FULL_TYPE,
+ C_RD_DATA_COUNT_WIDTH,
+ C_RD_DEPTH,
+ C_RD_PNTR_WIDTH,
+ C_UNDERFLOW_LOW,
+ C_USE_DOUT_RST,
+ C_USE_EMBEDDED_REG,
+ C_USE_FWFT_DATA_COUNT,
+ C_VALID_LOW,
+ C_WR_ACK_LOW,
+ C_WR_DATA_COUNT_WIDTH,
+ C_WR_DEPTH,
+ C_WR_PNTR_WIDTH,
+ C_USE_ECC,
+ C_ENABLE_RST_SYNC,
+ C_ERROR_INJECTION_TYPE
+ )
+ gen_ss
+ (
+ .CLK (CLK),
+ .RST (rst_i),
+ .SRST (SRST),
+ .RST_FULL_GEN (rst_full_gen_i),
+ .RST_FULL_FF (rst_full_ff_i),
+ .DIN (DIN),
+ .WR_EN (WR_EN),
+ .RD_EN (RD_EN_FIFO_IN),
+ .PROG_EMPTY_THRESH (PROG_EMPTY_THRESH),
+ .PROG_EMPTY_THRESH_ASSERT (PROG_EMPTY_THRESH_ASSERT),
+ .PROG_EMPTY_THRESH_NEGATE (PROG_EMPTY_THRESH_NEGATE),
+ .PROG_FULL_THRESH (PROG_FULL_THRESH),
+ .PROG_FULL_THRESH_ASSERT (PROG_FULL_THRESH_ASSERT),
+ .PROG_FULL_THRESH_NEGATE (PROG_FULL_THRESH_NEGATE),
+ .INJECTSBITERR (inject_sbit_err),
+ .INJECTDBITERR (inject_dbit_err),
+ .DOUT (DOUT_FIFO_OUT),
+ .FULL (FULL_FIFO_OUT),
+ .ALMOST_FULL (ALMOST_FULL_FIFO_OUT),
+ .WR_ACK (WR_ACK_FIFO_OUT),
+ .OVERFLOW (OVERFLOW_FIFO_OUT),
+ .EMPTY (EMPTY_FIFO_OUT),
+ .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT),
+ .VALID (VALID_FIFO_OUT),
+ .UNDERFLOW (UNDERFLOW_FIFO_OUT),
+ .DATA_COUNT (DATA_COUNT_FIFO_OUT),
+ .PROG_FULL (PROG_FULL_FIFO_OUT),
+ .PROG_EMPTY (PROG_EMPTY_FIFO_OUT),
+ .SBITERR (sbiterr_fifo_out),
+ .DBITERR (dbiterr_fifo_out)
+ );
+end
+1 : begin : block1
+ //Independent Clocks Behavioral Model
+ fifo_generator_v6_1_bhv_ver_as
+ #(
+ C_DATA_COUNT_WIDTH,
+ C_DIN_WIDTH,
+ C_DOUT_RST_VAL,
+ C_DOUT_WIDTH,
+ C_FULL_FLAGS_RST_VAL,
+ C_HAS_ALMOST_EMPTY,
+ C_HAS_ALMOST_FULL,
+ C_HAS_DATA_COUNT,
+ C_HAS_OVERFLOW,
+ C_HAS_RD_DATA_COUNT,
+ C_HAS_RST,
+ C_HAS_UNDERFLOW,
+ C_HAS_VALID,
+ C_HAS_WR_ACK,
+ C_HAS_WR_DATA_COUNT,
+ C_IMPLEMENTATION_TYPE,
+ C_MEMORY_TYPE,
+ C_OVERFLOW_LOW,
+ C_PRELOAD_LATENCY,
+ C_PRELOAD_REGS,
+ C_PROG_EMPTY_THRESH_ASSERT_VAL,
+ C_PROG_EMPTY_THRESH_NEGATE_VAL,
+ C_PROG_EMPTY_TYPE,
+ C_PROG_FULL_THRESH_ASSERT_VAL,
+ C_PROG_FULL_THRESH_NEGATE_VAL,
+ C_PROG_FULL_TYPE,
+ C_RD_DATA_COUNT_WIDTH,
+ C_RD_DEPTH,
+ C_RD_PNTR_WIDTH,
+ C_UNDERFLOW_LOW,
+ C_USE_DOUT_RST,
+ C_USE_EMBEDDED_REG,
+ C_USE_FWFT_DATA_COUNT,
+ C_VALID_LOW,
+ C_WR_ACK_LOW,
+ C_WR_DATA_COUNT_WIDTH,
+ C_WR_DEPTH,
+ C_WR_PNTR_WIDTH,
+ C_USE_ECC,
+ C_ENABLE_RST_SYNC,
+ C_ERROR_INJECTION_TYPE
+ )
+ gen_as
+ (
+ .WR_CLK (WR_CLK),
+ .RD_CLK (RD_CLK),
+ .RST (rst_i),
+ .RST_FULL_GEN (rst_full_gen_i),
+ .RST_FULL_FF (rst_full_ff_i),
+ .WR_RST (wr_rst_i),
+ .RD_RST (rd_rst_i),
+ .DIN (DIN),
+ .WR_EN (WR_EN),
+ .RD_EN (RD_EN_FIFO_IN),
+ .RD_EN_USER (RD_EN),
+ .PROG_EMPTY_THRESH (PROG_EMPTY_THRESH),
+ .PROG_EMPTY_THRESH_ASSERT (PROG_EMPTY_THRESH_ASSERT),
+ .PROG_EMPTY_THRESH_NEGATE (PROG_EMPTY_THRESH_NEGATE),
+ .PROG_FULL_THRESH (PROG_FULL_THRESH),
+ .PROG_FULL_THRESH_ASSERT (PROG_FULL_THRESH_ASSERT),
+ .PROG_FULL_THRESH_NEGATE (PROG_FULL_THRESH_NEGATE),
+ .INJECTSBITERR (inject_sbit_err),
+ .INJECTDBITERR (inject_dbit_err),
+ .USER_EMPTY_FB (EMPTY_P0_OUT),
+ .DOUT (DOUT_FIFO_OUT),
+ .FULL (FULL_FIFO_OUT),
+ .ALMOST_FULL (ALMOST_FULL_FIFO_OUT),
+ .WR_ACK (WR_ACK_FIFO_OUT),
+ .OVERFLOW (OVERFLOW_FIFO_OUT),
+ .EMPTY (EMPTY_FIFO_OUT),
+ .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT),
+ .VALID (VALID_FIFO_OUT),
+ .UNDERFLOW (UNDERFLOW_FIFO_OUT),
+ .RD_DATA_COUNT (RD_DATA_COUNT_FIFO_OUT),
+ .WR_DATA_COUNT (WR_DATA_COUNT_FIFO_OUT),
+ .PROG_FULL (PROG_FULL_FIFO_OUT),
+ .PROG_EMPTY (PROG_EMPTY_FIFO_OUT),
+ .SBITERR (sbiterr_fifo_out),
+ .DBITERR (dbiterr_fifo_out)
+ );
+end
+
+default : begin : block1
+ //Independent Clocks Behavioral Model
+ fifo_generator_v6_1_bhv_ver_as
+ #(
+ C_DATA_COUNT_WIDTH,
+ C_DIN_WIDTH,
+ C_DOUT_RST_VAL,
+ C_DOUT_WIDTH,
+ C_FULL_FLAGS_RST_VAL,
+ C_HAS_ALMOST_EMPTY,
+ C_HAS_ALMOST_FULL,
+ C_HAS_DATA_COUNT,
+ C_HAS_OVERFLOW,
+ C_HAS_RD_DATA_COUNT,
+ C_HAS_RST,
+ C_HAS_UNDERFLOW,
+ C_HAS_VALID,
+ C_HAS_WR_ACK,
+ C_HAS_WR_DATA_COUNT,
+ C_IMPLEMENTATION_TYPE,
+ C_MEMORY_TYPE,
+ C_OVERFLOW_LOW,
+ C_PRELOAD_LATENCY,
+ C_PRELOAD_REGS,
+ C_PROG_EMPTY_THRESH_ASSERT_VAL,
+ C_PROG_EMPTY_THRESH_NEGATE_VAL,
+ C_PROG_EMPTY_TYPE,
+ C_PROG_FULL_THRESH_ASSERT_VAL,
+ C_PROG_FULL_THRESH_NEGATE_VAL,
+ C_PROG_FULL_TYPE,
+ C_RD_DATA_COUNT_WIDTH,
+ C_RD_DEPTH,
+ C_RD_PNTR_WIDTH,
+ C_UNDERFLOW_LOW,
+ C_USE_DOUT_RST,
+ C_USE_EMBEDDED_REG,
+ C_USE_FWFT_DATA_COUNT,
+ C_VALID_LOW,
+ C_WR_ACK_LOW,
+ C_WR_DATA_COUNT_WIDTH,
+ C_WR_DEPTH,
+ C_WR_PNTR_WIDTH,
+ C_USE_ECC,
+ C_ENABLE_RST_SYNC,
+ C_ERROR_INJECTION_TYPE
+ )
+ gen_as
+ (
+ .WR_CLK (WR_CLK),
+ .RD_CLK (RD_CLK),
+ .RST (rst_i),
+ .RST_FULL_GEN (rst_full_gen_i),
+ .RST_FULL_FF (rst_full_ff_i),
+ .WR_RST (wr_rst_i),
+ .RD_RST (rd_rst_i),
+ .DIN (DIN),
+ .WR_EN (WR_EN),
+ .RD_EN (RD_EN_FIFO_IN),
+ .RD_EN_USER (RD_EN),
+ .PROG_EMPTY_THRESH (PROG_EMPTY_THRESH),
+ .PROG_EMPTY_THRESH_ASSERT (PROG_EMPTY_THRESH_ASSERT),
+ .PROG_EMPTY_THRESH_NEGATE (PROG_EMPTY_THRESH_NEGATE),
+ .PROG_FULL_THRESH (PROG_FULL_THRESH),
+ .PROG_FULL_THRESH_ASSERT (PROG_FULL_THRESH_ASSERT),
+ .PROG_FULL_THRESH_NEGATE (PROG_FULL_THRESH_NEGATE),
+ .INJECTSBITERR (inject_sbit_err),
+ .INJECTDBITERR (inject_dbit_err),
+ .USER_EMPTY_FB (EMPTY_P0_OUT),
+ .DOUT (DOUT_FIFO_OUT),
+ .FULL (FULL_FIFO_OUT),
+ .ALMOST_FULL (ALMOST_FULL_FIFO_OUT),
+ .WR_ACK (WR_ACK_FIFO_OUT),
+ .OVERFLOW (OVERFLOW_FIFO_OUT),
+ .EMPTY (EMPTY_FIFO_OUT),
+ .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT),
+ .VALID (VALID_FIFO_OUT),
+ .UNDERFLOW (UNDERFLOW_FIFO_OUT),
+ .RD_DATA_COUNT (RD_DATA_COUNT_FIFO_OUT),
+ .WR_DATA_COUNT (WR_DATA_COUNT_FIFO_OUT),
+ .PROG_FULL (PROG_FULL_FIFO_OUT),
+ .PROG_EMPTY (PROG_EMPTY_FIFO_OUT),
+ .SBITERR (sbiterr_fifo_out),
+ .DBITERR (dbiterr_fifo_out)
+ );
+end
+
+endcase
+endgenerate
+
+
+ //**************************************************************************
+ // Connect Internal Signals
+ // (Signals labeled internal_*)
+ // In the normal case, these signals tie directly to the FIFO's inputs and
+ // outputs.
+ // In the case of Preload Latency 0 or 1, there are intermediate
+ // signals between the internal FIFO and the preload logic.
+ //**************************************************************************
+
+
+ //***********************************************
+ // If First-Word Fall-Through, instantiate
+ // the preload0 (FWFT) module
+ //***********************************************
+ generate
+ if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin : block2
+
+
+ fifo_generator_v6_1_bhv_ver_preload0
+ #(
+ C_DOUT_RST_VAL,
+ C_DOUT_WIDTH,
+ C_HAS_RST,
+ C_ENABLE_RST_SYNC,
+ C_HAS_SRST,
+ C_USE_DOUT_RST,
+ C_USE_ECC,
+ C_VALID_LOW,
+ C_UNDERFLOW_LOW,
+ C_MEMORY_TYPE
+ )
+ fgpl0
+ (
+ .RD_CLK (RD_CLK_P0_IN),
+ .RD_RST (RST_P0_IN),
+ .SRST (SRST),
+ .RD_EN (RD_EN_P0_IN),
+ .FIFOEMPTY (EMPTY_P0_IN),
+ .FIFODATA (DATA_P0_IN),
+ .FIFOSBITERR (sbiterr_fifo_out),
+ .FIFODBITERR (dbiterr_fifo_out),
+ .USERDATA (DATA_P0_OUT),
+ .USERVALID (VALID_P0_OUT),
+ .USEREMPTY (EMPTY_P0_OUT),
+ .USERALMOSTEMPTY (ALMOSTEMPTY_P0_OUT),
+ .USERUNDERFLOW (UNDERFLOW_P0_OUT),
+ .RAMVALID (RAMVALID_P0_OUT),
+ .FIFORDEN (RDEN_P0_OUT),
+ .USERSBITERR (SBITERR),
+ .USERDBITERR (DBITERR)
+ );
+
+
+ //***********************************************
+ // Connect inputs to preload (FWFT) module
+ //***********************************************
+ //Connect the RD_CLK of the Preload (FWFT) module to CLK if we
+ // have a common-clock FIFO, or RD_CLK if we have an
+ // independent clock FIFO
+ assign RD_CLK_P0_IN = ((C_VERILOG_IMPL == 0) ? CLK : RD_CLK);
+ assign RST_P0_IN = (C_COMMON_CLOCK == 0) ? rd_rst_i : (C_HAS_RST == 1) ? rst_i : 0;
+ assign RD_EN_P0_IN = RD_EN;
+ assign EMPTY_P0_IN = EMPTY_FIFO_OUT;
+ assign DATA_P0_IN = DOUT_FIFO_OUT;
+
+ //***********************************************
+ // Connect outputs from preload (FWFT) module
+ //***********************************************
+ assign DOUT = DATA_P0_OUT;
+ assign VALID = VALID_P0_OUT ;
+ assign EMPTY = EMPTY_P0_OUT;
+ assign ALMOST_EMPTY = ALMOSTEMPTY_P0_OUT;
+ assign UNDERFLOW = UNDERFLOW_P0_OUT ;
+
+ assign RD_EN_FIFO_IN = RDEN_P0_OUT;
+
+
+ //***********************************************
+ // Create DATA_COUNT from First-Word Fall-Through
+ // data count
+ //***********************************************
+ assign DATA_COUNT = (C_USE_FWFT_DATA_COUNT == 0)? DATA_COUNT_FIFO_OUT:
+ (C_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ? DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:0] :
+ DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_DATA_COUNT_WIDTH+1];
+
+ //***********************************************
+ // Create DATA_COUNT from First-Word Fall-Through
+ // data count
+ //***********************************************
+ always @ (posedge RD_CLK or posedge RST_P0_IN) begin
+ if (RST_P0_IN) begin
+ EMPTY_P0_OUT_Q <= #`TCQ 1;
+ ALMOSTEMPTY_P0_OUT_Q <= #`TCQ 1;
+ end else begin
+ EMPTY_P0_OUT_Q <= #`TCQ EMPTY_P0_OUT;
+ ALMOSTEMPTY_P0_OUT_Q <= #`TCQ ALMOSTEMPTY_P0_OUT;
+ end
+ end //always
+
+
+ //***********************************************
+ // logic for common-clock data count when FWFT is selected
+ //***********************************************
+ initial begin
+ SS_FWFT_RD = 1'b0;
+ DATA_COUNT_FWFT = 0 ;
+ SS_FWFT_WR = 1'b0 ;
+ end //initial
+
+
+ //***********************************************
+ // common-clock data count is implemented as an
+ // up-down counter. SS_FWFT_WR and SS_FWFT_RD
+ // are the up/down enables for the counter.
+ //***********************************************
+ always @ (RD_EN or VALID_P0_OUT or WR_EN or FULL_FIFO_OUT) begin
+ if (C_VALID_LOW == 1) begin
+ SS_FWFT_RD = RD_EN && ~VALID_P0_OUT ;
+ end else begin
+ SS_FWFT_RD = RD_EN && VALID_P0_OUT ;
+ end
+ SS_FWFT_WR = (WR_EN && (~FULL_FIFO_OUT)) ;
+ end
+
+ //***********************************************
+ // common-clock data count is implemented as an
+ // up-down counter for FWFT. This always block
+ // calculates the counter.
+ //***********************************************
+ always @ (posedge RD_CLK_P0_IN or posedge RST_P0_IN) begin
+ if (RST_P0_IN) begin
+ DATA_COUNT_FWFT <= #`TCQ 0;
+ end else begin
+ if (SRST && (C_HAS_SRST == 1) ) begin
+ DATA_COUNT_FWFT <= #`TCQ 0;
+ end else begin
+ case ( {SS_FWFT_WR, SS_FWFT_RD})
+ 2'b00: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ;
+ 2'b01: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT - 1 ;
+ 2'b10: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT + 1 ;
+ 2'b11: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ;
+ endcase
+ end //if SRST
+ end //IF RST
+ end //always
+
+
+ end else begin : block2 //if !(C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0)
+
+ //***********************************************
+ // If NOT First-Word Fall-Through, wire the outputs
+ // of the internal _ss or _as FIFO directly to the
+ // output, and do not instantiate the preload0
+ // module.
+ //***********************************************
+
+ assign RD_CLK_P0_IN = 0;
+ assign RST_P0_IN = 0;
+ assign RD_EN_P0_IN = 0;
+
+ assign RD_EN_FIFO_IN = RD_EN;
+
+ assign DOUT = DOUT_FIFO_OUT;
+ assign DATA_P0_IN = 0;
+ assign VALID = VALID_FIFO_OUT;
+ assign EMPTY = EMPTY_FIFO_OUT;
+ assign ALMOST_EMPTY = ALMOST_EMPTY_FIFO_OUT;
+ assign EMPTY_P0_IN = 0;
+ assign UNDERFLOW = UNDERFLOW_FIFO_OUT;
+ assign DATA_COUNT = DATA_COUNT_FIFO_OUT;
+ assign SBITERR = sbiterr_fifo_out;
+ assign DBITERR = dbiterr_fifo_out;
+
+ end //if !(C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0)
+ endgenerate
+
+
+ //***********************************************
+ // Connect user flags to internal signals
+ //***********************************************
+
+ //If we are using extra logic for the FWFT data count, then override the
+ //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY.
+ //RD_DATA_COUNT is 0 when EMPTY and 1 when ALMOST_EMPTY.
+ generate
+ if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ) begin : block3
+ assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 1 : RD_DATA_COUNT_FIFO_OUT);
+ end //block3
+ endgenerate
+
+ //If we are using extra logic for the FWFT data count, then override the
+ //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY.
+ //Due to asymmetric ports, RD_DATA_COUNT is 0 when EMPTY or ALMOST_EMPTY.
+ generate
+ if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH <=C_RD_PNTR_WIDTH) ) begin : block30
+ assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 0 : RD_DATA_COUNT_FIFO_OUT);
+ end //block30
+ endgenerate
+
+ //If we are not using extra logic for the FWFT data count,
+ //then connect RD_DATA_COUNT to the RD_DATA_COUNT from the
+ //internal FIFO instance
+ generate
+ if (C_USE_FWFT_DATA_COUNT==0 ) begin : block31
+ assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT;
+ end
+ endgenerate
+
+ //Always connect WR_DATA_COUNT to the WR_DATA_COUNT from the internal
+ //FIFO instance
+ generate
+ if (C_USE_FWFT_DATA_COUNT==1) begin : block4
+ assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT;
+ end
+ else begin : block4
+ assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT;
+ end
+ endgenerate
+
+
+ //Connect other flags to the internal FIFO instance
+ assign FULL = FULL_FIFO_OUT;
+ assign ALMOST_FULL = ALMOST_FULL_FIFO_OUT;
+ assign WR_ACK = WR_ACK_FIFO_OUT;
+ assign OVERFLOW = OVERFLOW_FIFO_OUT;
+ assign PROG_FULL = PROG_FULL_FIFO_OUT;
+ assign PROG_EMPTY = PROG_EMPTY_FIFO_OUT;
+
+
+ // if an asynchronous FIFO has been selected, display a message that the FIFO
+ // will not be cycle-accurate in simulation
+ initial begin
+ if (C_IMPLEMENTATION_TYPE == 2) begin
+ $display("WARNING: Behavioral models for independent clock FIFO configurations are not cycle-accurate. You may wish to choose the structural simulation model instead of the behavioral model. This will ensure accurate behavior and latencies during simulation. You can enable this from CORE Generator by selecting Project -> Project Options -> Generation tab -> Structural Simulation. See the FIFO Generator User Guide for more information.");
+ end else if (C_MEMORY_TYPE == 4) begin
+ $display("FAILURE : Behavioral models for Virtex-4, Virtex-5 and Virtex-6 built-in FIFO configurations is currently not supported. Please select the structural simulation model option in CORE Generator. You can enable this in CORE Generator by selecting Project -> Project Options -> Generation tab -> Structural Simulation. See the FIFO Generator User Guide for more information.");
+ $finish;
+ end
+ end //initial
+
+ /**************************************************************************
+ * Internal reset logic
+ **************************************************************************/
+ assign wr_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? wr_rst_reg : 0;
+ assign rd_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? rd_rst_reg : 0;
+ assign rst_i = C_HAS_RST ? rst_reg : 0;
+
+ wire rst_2_sync;
+ wire clk_2_sync = (C_COMMON_CLOCK == 1) ? CLK : WR_CLK;
+ generate
+ if (C_ENABLE_RST_SYNC == 0) begin : gnrst_sync
+ always @* begin
+ wr_rst_reg <= WR_RST;
+ rd_rst_reg <= RD_RST;
+ rst_reg <= 1'b0;
+ end
+ assign rst_2_sync = WR_RST;
+ end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 0) begin : gic_rst
+ assign wr_rst_comb = !wr_rst_asreg_d2 && wr_rst_asreg;
+ assign rd_rst_comb = !rd_rst_asreg_d2 && rd_rst_asreg;
+ assign rst_2_sync = RST;
+
+ always @(posedge WR_CLK or posedge RST) begin
+ if (RST == 1'b1) begin
+ wr_rst_asreg <= #`TCQ 1'b1;
+ end else begin
+ if (wr_rst_asreg_d1 == 1'b1) begin
+ wr_rst_asreg <= #`TCQ 1'b0;
+ end else begin
+ wr_rst_asreg <= #`TCQ wr_rst_asreg;
+ end
+ end
+ end
+
+ always @(posedge WR_CLK) begin
+ wr_rst_asreg_d1 <= #`TCQ wr_rst_asreg;
+ wr_rst_asreg_d2 <= #`TCQ wr_rst_asreg_d1;
+ end
+
+ always @(posedge WR_CLK or posedge wr_rst_comb) begin
+ if (wr_rst_comb == 1'b1) begin
+ wr_rst_reg <= #`TCQ 1'b1;
+ end else begin
+ wr_rst_reg <= #`TCQ 1'b0;
+ end
+ end
+
+ always @(posedge RD_CLK or posedge RST) begin
+ if (RST == 1'b1) begin
+ rd_rst_asreg <= #`TCQ 1'b1;
+ end else begin
+ if (rd_rst_asreg_d1 == 1'b1) begin
+ rd_rst_asreg <= #`TCQ 1'b0;
+ end else begin
+ rd_rst_asreg <= #`TCQ rd_rst_asreg;
+ end
+ end
+ end
+
+ always @(posedge RD_CLK) begin
+ rd_rst_asreg_d1 <= #`TCQ rd_rst_asreg;
+ rd_rst_asreg_d2 <= #`TCQ rd_rst_asreg_d1;
+ end
+
+ always @(posedge RD_CLK or posedge rd_rst_comb) begin
+ if (rd_rst_comb == 1'b1) begin
+ rd_rst_reg <= #`TCQ 1'b1;
+ end else begin
+ rd_rst_reg <= #`TCQ 1'b0;
+ end
+ end
+ end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 1) begin : gcc_rst
+ assign rst_comb = !rst_asreg_d2 && rst_asreg;
+ assign rst_2_sync = RST;
+
+ always @(posedge CLK or posedge RST) begin
+ if (RST == 1'b1) begin
+ rst_asreg <= #`TCQ 1'b1;
+ end else begin
+ if (rst_asreg_d1 == 1'b1) begin
+ rst_asreg <= #`TCQ 1'b0;
+ end else begin
+ rst_asreg <= #`TCQ rst_asreg;
+ end
+ end
+ end
+
+ always @(posedge CLK) begin
+ rst_asreg_d1 <= #`TCQ rst_asreg;
+ rst_asreg_d2 <= #`TCQ rst_asreg_d1;
+ end
+
+ always @(posedge CLK or posedge rst_comb) begin
+ if (rst_comb == 1'b1) begin
+ rst_reg <= #`TCQ 1'b1;
+ end else begin
+ rst_reg <= #`TCQ 1'b0;
+ end
+ end
+ end
+ endgenerate
+
+ reg rst_d1 = 1'b0;
+ reg rst_d2 = 1'b0;
+ reg rst_d3 = 1'b0;
+ reg rst_d4 = 1'b0;
+ generate
+ if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 1) begin : grstd1
+ // RST_FULL_GEN replaces the reset falling edge detection used to de-assert
+ // FULL, ALMOST_FULL & PROG_FULL flags if C_FULL_FLAGS_RST_VAL = 1.
+
+ // RST_FULL_FF goes to the reset pin of the final flop of FULL, ALMOST_FULL &
+ // PROG_FULL
+
+ always @ (posedge rst_2_sync or posedge clk_2_sync) begin
+ if (rst_2_sync) begin
+ rst_d1 <= 1'b1;
+ rst_d2 <= 1'b1;
+ rst_d3 <= 1'b1;
+ rst_d4 <= 1'b0;
+ end else begin
+ if (SRST) begin
+ rst_d1 <= #`TCQ 1'b1;
+ rst_d2 <= #`TCQ 1'b1;
+ rst_d3 <= #`TCQ 1'b1;
+ rst_d4 <= #`TCQ 1'b0;
+ end else begin
+ rst_d1 <= #`TCQ 1'b0;
+ rst_d2 <= #`TCQ rst_d1;
+ rst_d3 <= #`TCQ rst_d2;
+ rst_d4 <= #`TCQ rst_d3;
+ end
+ end
+ end
+ assign rst_full_ff_i = (C_HAS_SRST == 0) ? rst_d2 : 1'b0 ;
+ assign rst_full_gen_i = rst_d4;
+
+ end else if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 0) begin : gnrst_full
+ assign rst_full_gen_i = 1'b0;
+ assign rst_full_ff_i = (C_COMMON_CLOCK == 0) ? wr_rst_i : rst_i;
+ end
+ endgenerate
+
+endmodule //FIFO_GENERATOR_V6_1
+
+
+
+/*******************************************************************************
+ * Declaration of Independent-Clocks FIFO Module
+ ******************************************************************************/
+module fifo_generator_v6_1_bhv_ver_as
+
+ /***************************************************************************
+ * Declare user parameters and their defaults
+ ***************************************************************************/
+ #(
+ parameter C_DATA_COUNT_WIDTH = 2,
+ parameter C_DIN_WIDTH = 8,
+ parameter C_DOUT_RST_VAL = "",
+ parameter C_DOUT_WIDTH = 8,
+ parameter C_FULL_FLAGS_RST_VAL = 1,
+ parameter C_HAS_ALMOST_EMPTY = 0,
+ parameter C_HAS_ALMOST_FULL = 0,
+ parameter C_HAS_DATA_COUNT = 0,
+ parameter C_HAS_OVERFLOW = 0,
+ parameter C_HAS_RD_DATA_COUNT = 0,
+ parameter C_HAS_RST = 0,
+ parameter C_HAS_UNDERFLOW = 0,
+ parameter C_HAS_VALID = 0,
+ parameter C_HAS_WR_ACK = 0,
+ parameter C_HAS_WR_DATA_COUNT = 0,
+ parameter C_IMPLEMENTATION_TYPE = 0,
+ parameter C_MEMORY_TYPE = 1,
+ parameter C_OVERFLOW_LOW = 0,
+ parameter C_PRELOAD_LATENCY = 1,
+ parameter C_PRELOAD_REGS = 0,
+ parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_EMPTY_TYPE = 0,
+ parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_FULL_TYPE = 0,
+ parameter C_RD_DATA_COUNT_WIDTH = 2,
+ parameter C_RD_DEPTH = 256,
+ parameter C_RD_PNTR_WIDTH = 8,
+ parameter C_UNDERFLOW_LOW = 0,
+ parameter C_USE_DOUT_RST = 0,
+ parameter C_USE_EMBEDDED_REG = 0,
+ parameter C_USE_FWFT_DATA_COUNT = 0,
+ parameter C_VALID_LOW = 0,
+ parameter C_WR_ACK_LOW = 0,
+ parameter C_WR_DATA_COUNT_WIDTH = 2,
+ parameter C_WR_DEPTH = 256,
+ parameter C_WR_PNTR_WIDTH = 8,
+ parameter C_USE_ECC = 0,
+ parameter C_ENABLE_RST_SYNC = 1,
+ parameter C_ERROR_INJECTION_TYPE = 0
+ )
+
+ /***************************************************************************
+ * Declare Input and Output Ports
+ ***************************************************************************/
+ (
+ input [C_DIN_WIDTH-1:0] DIN,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE,
+ input RD_CLK,
+ input RD_EN,
+ input RD_EN_USER,
+ input RST,
+ input RST_FULL_GEN,
+ input RST_FULL_FF,
+ input WR_RST,
+ input RD_RST,
+ input WR_CLK,
+ input WR_EN,
+ input INJECTDBITERR,
+ input INJECTSBITERR,
+ input USER_EMPTY_FB,
+ output reg ALMOST_EMPTY = 1'b1,
+ output reg ALMOST_FULL = C_FULL_FLAGS_RST_VAL,
+ output [C_DOUT_WIDTH-1:0] DOUT,
+ output reg EMPTY = 1'b1,
+ output reg FULL = C_FULL_FLAGS_RST_VAL,
+ output OVERFLOW,
+ output PROG_EMPTY,
+ output PROG_FULL,
+ output VALID,
+ output [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT,
+ output UNDERFLOW,
+ output WR_ACK,
+ output [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT,
+ output SBITERR,
+ output DBITERR
+ );
+
+ reg [C_RD_PNTR_WIDTH:0] rd_data_count_int = 0;
+ reg [C_WR_PNTR_WIDTH:0] wr_data_count_int = 0;
+ reg [C_WR_PNTR_WIDTH:0] wdc_fwft_ext_as = 0;
+
+
+ /***************************************************************************
+ * Parameters used as constants
+ **************************************************************************/
+ //When RST is present, set FULL reset value to '1'.
+ //If core has no RST, make sure FULL powers-on as '0'.
+ parameter C_DEPTH_RATIO_WR =
+ (C_WR_DEPTH>C_RD_DEPTH) ? (C_WR_DEPTH/C_RD_DEPTH) : 1;
+ parameter C_DEPTH_RATIO_RD =
+ (C_RD_DEPTH>C_WR_DEPTH) ? (C_RD_DEPTH/C_WR_DEPTH) : 1;
+ parameter C_FIFO_WR_DEPTH = C_WR_DEPTH - 1;
+ parameter C_FIFO_RD_DEPTH = C_RD_DEPTH - 1;
+
+ // C_DEPTH_RATIO_WR | C_DEPTH_RATIO_RD | C_PNTR_WIDTH | EXTRA_WORDS_DC
+ // -----------------|------------------|-----------------|---------------
+ // 1 | 8 | C_RD_PNTR_WIDTH | 2
+ // 1 | 4 | C_RD_PNTR_WIDTH | 2
+ // 1 | 2 | C_RD_PNTR_WIDTH | 2
+ // 1 | 1 | C_WR_PNTR_WIDTH | 2
+ // 2 | 1 | C_WR_PNTR_WIDTH | 4
+ // 4 | 1 | C_WR_PNTR_WIDTH | 8
+ // 8 | 1 | C_WR_PNTR_WIDTH | 16
+
+ localparam C_PNTR_WIDTH = (C_WR_PNTR_WIDTH>=C_RD_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH;
+ wire [C_PNTR_WIDTH:0] EXTRA_WORDS_DC = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD);
+
+ parameter [31:0] reads_per_write = C_DIN_WIDTH/C_DOUT_WIDTH;
+
+ parameter [31:0] log2_reads_per_write = log2_val(reads_per_write);
+
+ parameter [31:0] writes_per_read = C_DOUT_WIDTH/C_DIN_WIDTH;
+
+ parameter [31:0] log2_writes_per_read = log2_val(writes_per_read);
+
+
+
+ /**************************************************************************
+ * FIFO Contents Tracking and Data Count Calculations
+ *************************************************************************/
+
+ // Memory which will be used to simulate a FIFO
+ reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0];
+ // Local parameters used to determine whether to inject ECC error or not
+ localparam SYMMETRIC_PORT = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 1 : 0;
+ localparam ERR_INJECTION = (C_ERROR_INJECTION_TYPE != 0) ? 1 : 0;
+ localparam ENABLE_ERR_INJECTION = C_USE_ECC && SYMMETRIC_PORT && ERR_INJECTION;
+ // Array that holds the error injection type (single/double bit error) on
+ // a specific write operation, which is returned on read to corrupt the
+ // output data.
+ reg [1:0] ecc_err[C_WR_DEPTH-1:0];
+
+ //The amount of data stored in the FIFO at any time is given
+ // by num_wr_bits (in the WR_CLK domain) and num_rd_bits (in the RD_CLK
+ // domain.
+ //num_wr_bits is calculated by considering the total words in the FIFO,
+ // and the state of the read pointer (which may not have yet crossed clock
+ // domains.)
+ //num_rd_bits is calculated by considering the total words in the FIFO,
+ // and the state of the write pointer (which may not have yet crossed clock
+ // domains.)
+ reg [31:0] num_wr_bits;
+ reg [31:0] num_rd_bits;
+ reg [31:0] next_num_wr_bits;
+ reg [31:0] next_num_rd_bits;
+
+ //The write pointer - tracks write operations
+ // (Works opposite to core: wr_ptr is a DOWN counter)
+ reg [31:0] wr_ptr;
+ reg [C_WR_PNTR_WIDTH-1:0] wr_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value.
+ reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd1 = 0;
+ reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd2 = 0;
+ reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd3 = 0;
+ wire [C_RD_PNTR_WIDTH-1:0] adj_wr_pntr_rd;
+ reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd = 0;
+ wire wr_rst_i = WR_RST;
+ reg wr_rst_d1 =0;
+
+ //The read pointer - tracks read operations
+ // (rd_ptr Works opposite to core: rd_ptr is a DOWN counter)
+ reg [31:0] rd_ptr;
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value.
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr1 = 0;
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr2 = 0;
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr3 = 0;
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr4 = 0;
+ wire [C_WR_PNTR_WIDTH-1:0] adj_rd_pntr_wr;
+ reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr = 0;
+ wire rd_rst_i = RD_RST;
+ wire ram_rd_en;
+ reg ram_rd_en_d1 = 1'b0;
+
+
+ // Delayed ram_rd_en is needed only for STD Embedded register option
+ generate
+ if (C_PRELOAD_LATENCY == 2) begin : grd_d
+ always @ (posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i)
+ ram_rd_en_d1 <= #`TCQ 1'b0;
+ else
+ ram_rd_en_d1 <= #`TCQ ram_rd_en;
+ end
+ end
+ endgenerate
+
+ // Write pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation
+ generate
+ if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin : rdg // Read depth greater than write depth
+ assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd;
+ assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1:0] = 0;
+ end else begin : rdl // Read depth lesser than or equal to write depth
+ assign adj_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];
+ end
+ endgenerate
+
+ // Generate Empty and Almost Empty
+ // ram_rd_en used to determine EMPTY should depend on the EMPTY.
+ assign ram_rd_en = RD_EN & !EMPTY;
+ assign empty_int = ((adj_wr_pntr_rd == rd_pntr) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+1'h1))));
+ assign almost_empty_int = ((adj_wr_pntr_rd == (rd_pntr+1'h1)) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+2'h2))));
+
+ // Register Empty and Almost Empty
+ always @ (posedge RD_CLK or posedge rd_rst_i)
+ begin
+ if (rd_rst_i) begin
+ EMPTY <= #`TCQ 1'b1;
+ ALMOST_EMPTY <= #`TCQ 1'b1;
+ rd_data_count_int <= #`TCQ {C_RD_PNTR_WIDTH-1{1'b0}};
+ end else begin
+ rd_data_count_int <= #`TCQ {(adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:0] - rd_pntr[C_RD_PNTR_WIDTH-1:0]), 1'b0};
+
+ if (empty_int)
+ EMPTY <= #`TCQ 1'b1;
+ else
+ EMPTY <= #`TCQ 1'b0;
+
+ if (!EMPTY) begin
+ if (almost_empty_int)
+ ALMOST_EMPTY <= #`TCQ 1'b1;
+ else
+ ALMOST_EMPTY <= #`TCQ 1'b0;
+ end
+ end // rd_rst_i
+ end // always
+
+ // Read pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation
+ generate
+ if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : wdg // Write depth greater than read depth
+ assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr;
+ assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1:0] = 0;
+ end else begin : wdl // Write depth lesser than or equal to read depth
+ assign adj_rd_pntr_wr = rd_pntr_wr[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];
+ end
+ endgenerate
+
+ // Generate FULL and ALMOST_FULL
+ // ram_wr_en used to determine FULL should depend on the FULL.
+ assign ram_wr_en = WR_EN & !FULL;
+ assign full_int = ((adj_rd_pntr_wr == (wr_pntr+1'h1)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+2'h2))));
+ assign almost_full_int = ((adj_rd_pntr_wr == (wr_pntr+2'h2)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+3'h3))));
+
+ // Register FULL and ALMOST_FULL Empty
+ always @ (posedge WR_CLK or posedge RST_FULL_FF)
+ begin
+ if (RST_FULL_FF) begin
+ FULL <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ ALMOST_FULL <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ wr_data_count_int <= #`TCQ {C_WR_DATA_COUNT_WIDTH-1{1'b0}};
+ end else begin
+ wr_data_count_int <= #`TCQ {(wr_pntr[C_WR_PNTR_WIDTH-1:0] - adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:0]), 1'b0};
+ if (full_int) begin
+ FULL <= #`TCQ 1'b1;
+ end else begin
+ FULL <= #`TCQ 1'b0;
+ end
+
+ if (RST_FULL_GEN) begin
+ ALMOST_FULL <= #`TCQ 1'b0;
+ end else if (!FULL) begin
+ if (almost_full_int)
+ ALMOST_FULL <= #`TCQ 1'b1;
+ else
+ ALMOST_FULL <= #`TCQ 1'b0;
+ end
+ end // wr_rst_i
+ end // always
+
+ // Determine which stage in FWFT registers are valid
+ reg stage1_valid = 0;
+ reg stage2_valid = 0;
+ generate
+ if (C_PRELOAD_LATENCY == 0) begin : grd_fwft_proc
+ always @ (posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i) begin
+ stage1_valid <= #`TCQ 0;
+ stage2_valid <= #`TCQ 0;
+ end else begin
+
+ if (!stage1_valid && !stage2_valid) begin
+ if (!EMPTY)
+ stage1_valid <= #`TCQ 1'b1;
+ else
+ stage1_valid <= #`TCQ 1'b0;
+ end else if (stage1_valid && !stage2_valid) begin
+ if (EMPTY) begin
+ stage1_valid <= #`TCQ 1'b0;
+ stage2_valid <= #`TCQ 1'b1;
+ end else begin
+ stage1_valid <= #`TCQ 1'b1;
+ stage2_valid <= #`TCQ 1'b1;
+ end
+ end else if (!stage1_valid && stage2_valid) begin
+ if (EMPTY && RD_EN_USER) begin
+ stage1_valid <= #`TCQ 1'b0;
+ stage2_valid <= #`TCQ 1'b0;
+ end else if (!EMPTY && RD_EN_USER) begin
+ stage1_valid <= #`TCQ 1'b1;
+ stage2_valid <= #`TCQ 1'b0;
+ end else if (!EMPTY && !RD_EN_USER) begin
+ stage1_valid <= #`TCQ 1'b1;
+ stage2_valid <= #`TCQ 1'b1;
+ end else begin
+ stage1_valid <= #`TCQ 1'b0;
+ stage2_valid <= #`TCQ 1'b1;
+ end
+ end else if (stage1_valid && stage2_valid) begin
+ if (EMPTY && RD_EN_USER) begin
+ stage1_valid <= #`TCQ 1'b0;
+ stage2_valid <= #`TCQ 1'b1;
+ end else begin
+ stage1_valid <= #`TCQ 1'b1;
+ stage2_valid <= #`TCQ 1'b1;
+ end
+ end else begin
+ stage1_valid <= #`TCQ 1'b0;
+ stage2_valid <= #`TCQ 1'b0;
+ end
+ end // rd_rst_i
+ end // always
+ end
+ endgenerate
+
+ //Pointers passed into opposite clock domain
+ reg [31:0] wr_ptr_rdclk;
+ reg [31:0] wr_ptr_rdclk_next;
+ reg [31:0] rd_ptr_wrclk;
+ reg [31:0] rd_ptr_wrclk_next;
+
+ //Amount of data stored in the FIFO scaled to the narrowest (deepest) port
+ // (Do not include data in FWFT stages)
+ //Used to calculate PROG_EMPTY.
+ wire [31:0] num_read_words_pe =
+ num_rd_bits/(C_DOUT_WIDTH/C_DEPTH_RATIO_WR);
+
+ //Amount of data stored in the FIFO scaled to the narrowest (deepest) port
+ // (Do not include data in FWFT stages)
+ //Used to calculate PROG_FULL.
+ wire [31:0] num_write_words_pf =
+ num_wr_bits/(C_DIN_WIDTH/C_DEPTH_RATIO_RD);
+
+ /**************************
+ * Read Data Count
+ *************************/
+
+ reg [31:0] num_read_words_dc;
+ reg [C_RD_DATA_COUNT_WIDTH-1:0] num_read_words_sized_i;
+
+ always @(num_rd_bits) begin
+ if (C_USE_FWFT_DATA_COUNT) begin
+
+ //If using extra logic for FWFT Data Counts,
+ // then scale FIFO contents to read domain,
+ // and add two read words for FWFT stages
+ //This value is only a temporary value and not used in the code.
+ num_read_words_dc = (num_rd_bits/C_DOUT_WIDTH+2);
+
+ //Trim the read words for use with RD_DATA_COUNT
+ num_read_words_sized_i =
+ num_read_words_dc[C_RD_PNTR_WIDTH : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH+1];
+
+ end else begin
+
+ //If not using extra logic for FWFT Data Counts,
+ // then scale FIFO contents to read domain.
+ //This value is only a temporary value and not used in the code.
+ num_read_words_dc = num_rd_bits/C_DOUT_WIDTH;
+
+ //Trim the read words for use with RD_DATA_COUNT
+ num_read_words_sized_i =
+ num_read_words_dc[C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH];
+
+ end //if (C_USE_FWFT_DATA_COUNT)
+ end //always
+
+
+ /**************************
+ * Write Data Count
+ *************************/
+
+ reg [31:0] num_write_words_dc;
+ reg [C_WR_DATA_COUNT_WIDTH-1:0] num_write_words_sized_i;
+
+ always @(num_wr_bits) begin
+ if (C_USE_FWFT_DATA_COUNT) begin
+
+ //Calculate the Data Count value for the number of write words,
+ // when using First-Word Fall-Through with extra logic for Data
+ // Counts. This takes into consideration the number of words that
+ // are expected to be stored in the FWFT register stages (it always
+ // assumes they are filled).
+ //This value is scaled to the Write Domain.
+ //The expression (((A-1)/B))+1 divides A/B, but takes the
+ // ceiling of the result.
+ //When num_wr_bits==0, set the result manually to prevent
+ // division errors.
+ //EXTRA_WORDS_DC is the number of words added to write_words
+ // due to FWFT.
+ //This value is only a temporary value and not used in the code.
+ num_write_words_dc = (num_wr_bits==0) ? EXTRA_WORDS_DC : (((num_wr_bits-1)/C_DIN_WIDTH)+1) + EXTRA_WORDS_DC ;
+
+ //Trim the write words for use with WR_DATA_COUNT
+ num_write_words_sized_i =
+ num_write_words_dc[C_WR_PNTR_WIDTH : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH+1];
+
+ end else begin
+
+ //Calculate the Data Count value for the number of write words, when NOT
+ // using First-Word Fall-Through with extra logic for Data Counts. This
+ // calculates only the number of words in the internal FIFO.
+ //The expression (((A-1)/B))+1 divides A/B, but takes the
+ // ceiling of the result.
+ //This value is scaled to the Write Domain.
+ //When num_wr_bits==0, set the result manually to prevent
+ // division errors.
+ //This value is only a temporary value and not used in the code.
+ num_write_words_dc = (num_wr_bits==0) ? 0 : ((num_wr_bits-1)/C_DIN_WIDTH)+1;
+
+ //Trim the read words for use with RD_DATA_COUNT
+ num_write_words_sized_i =
+ num_write_words_dc[C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH];
+
+ end //if (C_USE_FWFT_DATA_COUNT)
+ end //always
+
+
+
+ /***************************************************************************
+ * Internal registers and wires
+ **************************************************************************/
+
+ //Temporary signals used for calculating the model's outputs. These
+ //are only used in the assign statements immediately following wire,
+ //parameter, and function declarations.
+ wire [C_DOUT_WIDTH-1:0] ideal_dout_out;
+ wire valid_i;
+ wire valid_out;
+ wire underflow_i;
+
+ //Ideal FIFO signals. These are the raw output of the behavioral model,
+ //which behaves like an ideal FIFO.
+ reg [1:0] err_type = 0;
+ reg [1:0] err_type_d1 = 0;
+ reg [C_DOUT_WIDTH-1:0] ideal_dout = 0;
+ reg [C_DOUT_WIDTH-1:0] ideal_dout_d1 = 0;
+ reg ideal_wr_ack = 0;
+ reg ideal_valid = 0;
+ reg ideal_overflow = 0;
+ reg ideal_underflow = 0;
+ reg ideal_prog_full = 0;
+ reg ideal_prog_empty = 1;
+ reg [C_WR_DATA_COUNT_WIDTH-1 : 0] ideal_wr_count = 0;
+ reg [C_RD_DATA_COUNT_WIDTH-1 : 0] ideal_rd_count = 0;
+
+ //Assorted reg values for delayed versions of signals
+ reg valid_d1 = 0;
+
+
+ //user specified value for reseting the size of the fifo
+ reg [C_DOUT_WIDTH-1:0] dout_reset_val = 0;
+
+ //temporary registers for WR_RESPONSE_LATENCY feature
+
+ integer tmp_wr_listsize;
+ integer tmp_rd_listsize;
+
+ //Signal for registered version of prog full and empty
+
+ //Threshold values for Programmable Flags
+ integer prog_empty_actual_thresh_assert;
+ integer prog_empty_actual_thresh_negate;
+ integer prog_full_actual_thresh_assert;
+ integer prog_full_actual_thresh_negate;
+
+
+ /****************************************************************************
+ * Function Declarations
+ ***************************************************************************/
+
+ /**************************************************************************
+ * write_fifo
+ * This task writes a word to the FIFO memory and updates the
+ * write pointer.
+ * FIFO size is relative to write domain.
+ ***************************************************************************/
+ task write_fifo;
+ begin
+ memory[wr_ptr] <= DIN;
+ wr_pntr <= #`TCQ wr_pntr + 1;
+ // Store the type of error injection (double/single) on write
+ case (C_ERROR_INJECTION_TYPE)
+ 3: ecc_err[wr_ptr] <= {INJECTDBITERR,INJECTSBITERR};
+ 2: ecc_err[wr_ptr] <= {INJECTDBITERR,1'b0};
+ 1: ecc_err[wr_ptr] <= {1'b0,INJECTSBITERR};
+ default: ecc_err[wr_ptr] <= 0;
+ endcase
+ // (Works opposite to core: wr_ptr is a DOWN counter)
+ if (wr_ptr == 0) begin
+ wr_ptr <= C_WR_DEPTH - 1;
+ end else begin
+ wr_ptr <= wr_ptr - 1;
+ end
+ end
+ endtask // write_fifo
+
+ /**************************************************************************
+ * read_fifo
+ * This task reads a word from the FIFO memory and updates the read
+ * pointer. It's output is the ideal_dout bus.
+ * FIFO size is relative to write domain.
+ ***************************************************************************/
+ task read_fifo;
+ integer i;
+ reg [C_DOUT_WIDTH-1:0] tmp_dout;
+ reg [C_DIN_WIDTH-1:0] memory_read;
+ reg [31:0] tmp_rd_ptr;
+ reg [31:0] rd_ptr_high;
+ reg [31:0] rd_ptr_low;
+ reg [1:0] tmp_ecc_err;
+ begin
+ rd_pntr <= #`TCQ rd_pntr + 1;
+ // output is wider than input
+ if (reads_per_write == 0) begin
+ tmp_dout = 0;
+ tmp_rd_ptr = (rd_ptr << log2_writes_per_read)+(writes_per_read-1);
+ for (i = writes_per_read - 1; i >= 0; i = i - 1) begin
+ tmp_dout = tmp_dout << C_DIN_WIDTH;
+ tmp_dout = tmp_dout | memory[tmp_rd_ptr];
+
+ // (Works opposite to core: rd_ptr is a DOWN counter)
+ if (tmp_rd_ptr == 0) begin
+ tmp_rd_ptr = C_WR_DEPTH - 1;
+ end else begin
+ tmp_rd_ptr = tmp_rd_ptr - 1;
+ end
+ end
+
+ // output is symmetric
+ end else if (reads_per_write == 1) begin
+ tmp_dout = memory[rd_ptr][C_DIN_WIDTH-1:0];
+ // Retreive the error injection type. Based on the error injection type
+ // corrupt the output data.
+ tmp_ecc_err = ecc_err[rd_ptr];
+ if (ENABLE_ERR_INJECTION && C_DIN_WIDTH == C_DOUT_WIDTH) begin
+ if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error
+ if (C_DOUT_WIDTH == 1)
+ tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
+ else if (C_DOUT_WIDTH == 2)
+ tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]};
+ else
+ tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)};
+ end else begin
+ tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
+ end
+ err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]};
+ end else begin
+ err_type <= 0;
+ end
+
+ // input is wider than output
+ end else begin
+ rd_ptr_high = rd_ptr >> log2_reads_per_write;
+ rd_ptr_low = rd_ptr & (reads_per_write - 1);
+ memory_read = memory[rd_ptr_high];
+ tmp_dout = memory_read >> (rd_ptr_low*C_DOUT_WIDTH);
+ end
+ ideal_dout <= tmp_dout;
+
+ // (Works opposite to core: rd_ptr is a DOWN counter)
+ if (rd_ptr == 0) begin
+ rd_ptr <= C_RD_DEPTH - 1;
+ end else begin
+ rd_ptr <= rd_ptr - 1;
+ end
+ end
+ endtask
+
+ /**************************************************************************
+ * log2_val
+ * Returns the 'log2' value for the input value for the supported ratios
+ ***************************************************************************/
+ function [31:0] log2_val;
+ input [31:0] binary_val;
+
+ begin
+ if (binary_val == 8) begin
+ log2_val = 3;
+ end else if (binary_val == 4) begin
+ log2_val = 2;
+ end else begin
+ log2_val = 1;
+ end
+ end
+ endfunction
+
+ /***********************************************************************
+ * hexstr_conv
+ * Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
+ ***********************************************************************/
+ function [C_DOUT_WIDTH-1:0] hexstr_conv;
+ input [(C_DOUT_WIDTH*8)-1:0] def_data;
+
+ integer index,i,j;
+ reg [3:0] bin;
+
+ begin
+ index = 0;
+ hexstr_conv = 'b0;
+ for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 )
+ begin
+ case (def_data[7:0])
+ 8'b00000000 :
+ begin
+ bin = 4'b0000;
+ i = -1;
+ end
+ 8'b00110000 : bin = 4'b0000;
+ 8'b00110001 : bin = 4'b0001;
+ 8'b00110010 : bin = 4'b0010;
+ 8'b00110011 : bin = 4'b0011;
+ 8'b00110100 : bin = 4'b0100;
+ 8'b00110101 : bin = 4'b0101;
+ 8'b00110110 : bin = 4'b0110;
+ 8'b00110111 : bin = 4'b0111;
+ 8'b00111000 : bin = 4'b1000;
+ 8'b00111001 : bin = 4'b1001;
+ 8'b01000001 : bin = 4'b1010;
+ 8'b01000010 : bin = 4'b1011;
+ 8'b01000011 : bin = 4'b1100;
+ 8'b01000100 : bin = 4'b1101;
+ 8'b01000101 : bin = 4'b1110;
+ 8'b01000110 : bin = 4'b1111;
+ 8'b01100001 : bin = 4'b1010;
+ 8'b01100010 : bin = 4'b1011;
+ 8'b01100011 : bin = 4'b1100;
+ 8'b01100100 : bin = 4'b1101;
+ 8'b01100101 : bin = 4'b1110;
+ 8'b01100110 : bin = 4'b1111;
+ default :
+ begin
+ bin = 4'bx;
+ end
+ endcase
+ for( j=0; j<4; j=j+1)
+ begin
+ if ((index*4)+j < C_DOUT_WIDTH)
+ begin
+ hexstr_conv[(index*4)+j] = bin[j];
+ end
+ end
+ index = index + 1;
+ def_data = def_data >> 8;
+ end
+ end
+ endfunction
+
+ /*************************************************************************
+ * Initialize Signals for clean power-on simulation
+ *************************************************************************/
+ initial begin
+ num_wr_bits = 0;
+ num_rd_bits = 0;
+ next_num_wr_bits = 0;
+ next_num_rd_bits = 0;
+ rd_ptr = C_RD_DEPTH - 1;
+ wr_ptr = C_WR_DEPTH - 1;
+ wr_pntr = 0;
+ rd_pntr = 0;
+ rd_ptr_wrclk = rd_ptr;
+ wr_ptr_rdclk = wr_ptr;
+ dout_reset_val = hexstr_conv(C_DOUT_RST_VAL);
+ ideal_dout = dout_reset_val;
+ err_type = 0;
+ ideal_dout_d1 = dout_reset_val;
+ ideal_wr_ack = 1'b0;
+ ideal_valid = 1'b0;
+ valid_d1 = 1'b0;
+ ideal_overflow = 1'b0;
+ ideal_underflow = 1'b0;
+ ideal_wr_count = 0;
+ ideal_rd_count = 0;
+ ideal_prog_full = 1'b0;
+ ideal_prog_empty = 1'b1;
+ end
+
+
+ /*************************************************************************
+ * Connect the module inputs and outputs to the internal signals of the
+ * behavioral model.
+ *************************************************************************/
+ //Inputs
+ /*
+ wire [C_DIN_WIDTH-1:0] DIN;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE;
+ wire RD_CLK;
+ wire RD_EN;
+ wire RST;
+ wire WR_CLK;
+ wire WR_EN;
+ */
+
+ //***************************************************************************
+ // Dout may change behavior based on latency
+ //***************************************************************************
+ assign ideal_dout_out[C_DOUT_WIDTH-1:0] = (C_PRELOAD_LATENCY==2 &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
+ ideal_dout_d1: ideal_dout;
+ assign DOUT[C_DOUT_WIDTH-1:0] = ideal_dout_out;
+
+ //***************************************************************************
+ // Assign SBITERR and DBITERR based on latency
+ //***************************************************************************
+ assign SBITERR = (C_ERROR_INJECTION_TYPE == 1 || C_ERROR_INJECTION_TYPE == 3) &&
+ (C_PRELOAD_LATENCY == 2 &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
+ err_type_d1[0]: err_type[0];
+ assign DBITERR = (C_ERROR_INJECTION_TYPE == 2 || C_ERROR_INJECTION_TYPE == 3) &&
+ (C_PRELOAD_LATENCY==2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
+ err_type_d1[1]: err_type[1];
+
+
+ //***************************************************************************
+ // Overflow may be active-low
+ //***************************************************************************
+ generate
+ if (C_HAS_OVERFLOW==1) begin : blockOF1
+ assign OVERFLOW = ideal_overflow ? !C_OVERFLOW_LOW : C_OVERFLOW_LOW;
+ end
+ endgenerate
+
+ assign PROG_EMPTY = ideal_prog_empty;
+ assign PROG_FULL = ideal_prog_full;
+
+ //***************************************************************************
+ // Valid may change behavior based on latency or active-low
+ //***************************************************************************
+ generate
+ if (C_HAS_VALID==1) begin : blockVL1
+ assign valid_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & ~EMPTY) : ideal_valid;
+ assign valid_out = (C_PRELOAD_LATENCY==2 &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
+ valid_d1: valid_i;
+ assign VALID = valid_out ? !C_VALID_LOW : C_VALID_LOW;
+ end
+ endgenerate
+
+
+ //***************************************************************************
+ // Underflow may change behavior based on latency or active-low
+ //***************************************************************************
+ generate
+ if (C_HAS_UNDERFLOW==1) begin : blockUF1
+ assign underflow_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & EMPTY) : ideal_underflow;
+ assign UNDERFLOW = underflow_i ? !C_UNDERFLOW_LOW : C_UNDERFLOW_LOW;
+ end
+ endgenerate
+
+ //***************************************************************************
+ // Write acknowledge may be active low
+ //***************************************************************************
+ generate
+ if (C_HAS_WR_ACK==1) begin : blockWK1
+ assign WR_ACK = ideal_wr_ack ? !C_WR_ACK_LOW : C_WR_ACK_LOW;
+ end
+ endgenerate
+
+
+ //***************************************************************************
+ // Generate RD_DATA_COUNT if Use Extra Logic option is selected
+ //***************************************************************************
+ generate
+ if (C_HAS_WR_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : wdc_fwft_ext
+
+ reg [C_PNTR_WIDTH-1:0] adjusted_wr_pntr = 0;
+ reg [C_PNTR_WIDTH-1:0] adjusted_rd_pntr = 0;
+ wire [C_PNTR_WIDTH-1:0] diff_wr_rd_tmp;
+ wire [C_PNTR_WIDTH:0] diff_wr_rd;
+ reg [C_PNTR_WIDTH:0] wr_data_count_i = 0;
+ always @* begin
+ if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin
+ adjusted_wr_pntr = wr_pntr;
+ adjusted_rd_pntr = 0;
+ adjusted_rd_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr;
+ end else if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin
+ adjusted_rd_pntr = rd_pntr_wr;
+ adjusted_wr_pntr = 0;
+ adjusted_wr_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr;
+ end else begin
+ adjusted_wr_pntr = wr_pntr;
+ adjusted_rd_pntr = rd_pntr_wr;
+ end
+ end // always @*
+
+ assign diff_wr_rd_tmp = adjusted_wr_pntr - adjusted_rd_pntr;
+ assign diff_wr_rd = {1'b0,diff_wr_rd_tmp};
+
+ always @ (posedge wr_rst_i or posedge WR_CLK)
+ begin
+ if (wr_rst_i)
+ wr_data_count_i <= #`TCQ 0;
+ else
+ wr_data_count_i <= #`TCQ diff_wr_rd + EXTRA_WORDS_DC;
+ end // always @ (posedge WR_CLK or posedge WR_CLK)
+
+ always @* begin
+ if (C_WR_PNTR_WIDTH >= C_RD_PNTR_WIDTH)
+ wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:0];
+ else
+ wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];
+ end // always @*
+ end // wdc_fwft_ext
+ endgenerate
+
+ //***************************************************************************
+ // Generate RD_DATA_COUNT if Use Extra Logic option is selected
+ //***************************************************************************
+ reg [C_RD_PNTR_WIDTH:0] rdc_fwft_ext_as = 0;
+
+ generate
+ if (C_HAS_RD_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : rdc_fwft_ext
+ reg [C_RD_PNTR_WIDTH-1:0] adjusted_wr_pntr_rd = 0;
+ wire [C_RD_PNTR_WIDTH-1:0] diff_rd_wr_tmp;
+ wire [C_RD_PNTR_WIDTH:0] diff_rd_wr;
+ always @* begin
+ if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin
+ adjusted_wr_pntr_rd = 0;
+ adjusted_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd;
+ end else begin
+ adjusted_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];
+ end
+ end // always @*
+
+ assign diff_rd_wr_tmp = adjusted_wr_pntr_rd - rd_pntr;
+ assign diff_rd_wr = {1'b0,diff_rd_wr_tmp};
+
+ always @ (posedge rd_rst_i or posedge RD_CLK)
+ begin
+ if (rd_rst_i) begin
+ rdc_fwft_ext_as <= #`TCQ 0;
+ end else begin
+ if (!stage2_valid)
+ rdc_fwft_ext_as <= #`TCQ 0;
+ else if (!stage1_valid && stage2_valid)
+ rdc_fwft_ext_as <= #`TCQ 1;
+ else
+ rdc_fwft_ext_as <= #`TCQ diff_rd_wr + 2'h2;
+ end
+ end // always @ (posedge WR_CLK or posedge WR_CLK)
+ end // rdc_fwft_ext
+ endgenerate
+
+ //***************************************************************************
+ // Assign the read data count value only if it is selected,
+ // otherwise output zeros.
+ //***************************************************************************
+ generate
+ if (C_HAS_RD_DATA_COUNT == 1) begin : grdc
+ assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = C_USE_FWFT_DATA_COUNT ?
+ rdc_fwft_ext_as[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH] :
+ rd_data_count_int[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH];
+ end
+ endgenerate
+
+ generate
+ if (C_HAS_RD_DATA_COUNT == 0) begin : gnrdc
+ assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = {C_RD_DATA_COUNT_WIDTH-1{1'b0}};
+ end
+ endgenerate
+
+ //***************************************************************************
+ // Assign the write data count value only if it is selected,
+ // otherwise output zeros
+ //***************************************************************************
+ generate
+ if (C_HAS_WR_DATA_COUNT == 1) begin : gwdc
+ assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = (C_USE_FWFT_DATA_COUNT == 1) ?
+ wdc_fwft_ext_as[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH] :
+ wr_data_count_int[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH];
+ end
+ endgenerate
+
+ generate
+ if (C_HAS_WR_DATA_COUNT == 0) begin : gnwdc
+ assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = {C_WR_DATA_COUNT_WIDTH-1{1'b0}};
+ end
+ endgenerate
+
+
+ /**************************************************************************
+ * Assorted registers for delayed versions of signals
+ **************************************************************************/
+ //Capture delayed version of valid
+ generate
+ if (C_HAS_VALID==1) begin : blockVL2
+ always @(posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i == 1'b1) begin
+ valid_d1 <= #`TCQ 1'b0;
+ end else begin
+ valid_d1 <= #`TCQ valid_i;
+ end
+ end
+ end
+ endgenerate
+
+ //Capture delayed version of dout
+ always @(posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i == 1'b1) begin
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0)
+ err_type_d1 <= #`TCQ 0;
+ end else if (ram_rd_en_d1) begin
+ ideal_dout_d1 <= #`TCQ ideal_dout;
+ err_type_d1 <= #`TCQ err_type;
+ end
+ end
+
+ /**************************************************************************
+ * Overflow and Underflow Flag calculation
+ * (handled separately because they don't support rst)
+ **************************************************************************/
+ generate
+ if (C_HAS_OVERFLOW==1) begin : blockOF2
+ always @(posedge WR_CLK) begin
+ ideal_overflow <= #`TCQ WR_EN & FULL;
+ end
+ end
+ endgenerate
+
+ generate
+ if (C_HAS_UNDERFLOW==1) begin : blockUF2
+ always @(posedge RD_CLK) begin
+ ideal_underflow <= #`TCQ EMPTY & RD_EN;
+ end
+ end
+ endgenerate
+
+ /**************************************************************************
+ * Write Domain Logic
+ **************************************************************************/
+ reg [C_WR_PNTR_WIDTH-1:0] diff_pntr = 0;
+ always @(posedge WR_CLK or posedge wr_rst_i) begin : gen_fifo_w
+
+ /****** Reset fifo (case 1)***************************************/
+ if (wr_rst_i == 1'b1) begin
+ num_wr_bits <= #`TCQ 0;
+ next_num_wr_bits = #`TCQ 0;
+ wr_ptr <= #`TCQ C_WR_DEPTH - 1;
+ rd_ptr_wrclk <= #`TCQ C_RD_DEPTH - 1;
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_wr_count <= #`TCQ 0;
+ tmp_wr_listsize = #`TCQ 0;
+ rd_ptr_wrclk_next <= #`TCQ 0;
+ wr_pntr <= #`TCQ 0;
+ wr_pntr_rd1 <= #`TCQ 0;
+ rd_pntr_wr2 <= #`TCQ 0;
+ rd_pntr_wr3 <= #`TCQ 0;
+ rd_pntr_wr4 <= #`TCQ 0;
+ rd_pntr_wr <= #`TCQ 0;
+
+
+ end else begin //wr_rst_i==0
+
+ wr_pntr_rd1 <= #`TCQ wr_pntr;
+
+ // Synchronize the rd_pntr in read domain
+ rd_pntr_wr2 <= #`TCQ rd_pntr_wr1;
+ rd_pntr_wr3 <= #`TCQ rd_pntr_wr2;
+ rd_pntr_wr4 <= #`TCQ rd_pntr_wr2;
+ rd_pntr_wr <= #`TCQ rd_pntr_wr4;
+
+
+
+ //Determine the current number of words in the FIFO
+ tmp_wr_listsize = (C_DEPTH_RATIO_RD > 1) ? num_wr_bits/C_DOUT_WIDTH :
+ num_wr_bits/C_DIN_WIDTH;
+ rd_ptr_wrclk_next = rd_ptr;
+ if (rd_ptr_wrclk < rd_ptr_wrclk_next) begin
+ next_num_wr_bits = num_wr_bits -
+ C_DOUT_WIDTH*(rd_ptr_wrclk + C_RD_DEPTH
+ - rd_ptr_wrclk_next);
+ end else begin
+ next_num_wr_bits = num_wr_bits -
+ C_DOUT_WIDTH*(rd_ptr_wrclk - rd_ptr_wrclk_next);
+ end
+
+ //If this is a write, handle the write by adding the value
+ // to the linked list, and updating all outputs appropriately
+ if (WR_EN == 1'b1) begin
+ if (FULL == 1'b1) begin
+
+ //If the FIFO is full, do NOT perform the write,
+ // update flags accordingly
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD
+ >= C_FIFO_WR_DEPTH) begin
+ //write unsuccessful - do not change contents
+
+ //Do not acknowledge the write
+ ideal_wr_ack <= #`TCQ 0;
+ //Reminder that FIFO is still full
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+
+ //If the FIFO is one from full, but reporting full
+ end else
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD ==
+ C_FIFO_WR_DEPTH-1) begin
+ //No change to FIFO
+
+ //Write not successful
+ ideal_wr_ack <= #`TCQ 0;
+ //With DEPTH-1 words in the FIFO, it is almost_full
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+
+
+ //If the FIFO is completely empty, but it is
+ // reporting FULL for some reason (like reset)
+ end else
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <=
+ C_FIFO_WR_DEPTH-2) begin
+ //No change to FIFO
+
+ //Write not successful
+ ideal_wr_ack <= #`TCQ 0;
+ //FIFO is really not close to full, so change flag status.
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+ end //(tmp_wr_listsize == 0)
+
+ end else begin
+
+ //If the FIFO is full, do NOT perform the write,
+ // update flags accordingly
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD >=
+ C_FIFO_WR_DEPTH) begin
+ //write unsuccessful - do not change contents
+
+ //Do not acknowledge the write
+ ideal_wr_ack <= #`TCQ 0;
+ //Reminder that FIFO is still full
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+
+ //If the FIFO is one from full
+ end else
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD ==
+ C_FIFO_WR_DEPTH-1) begin
+ //Add value on DIN port to FIFO
+ write_fifo;
+ next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH;
+
+ //Write successful, so issue acknowledge
+ // and no error
+ ideal_wr_ack <= #`TCQ 1;
+ //This write is CAUSING the FIFO to go full
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+
+ //If the FIFO is 2 from full
+ end else
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD ==
+ C_FIFO_WR_DEPTH-2) begin
+ //Add value on DIN port to FIFO
+ write_fifo;
+ next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH;
+ //Write successful, so issue acknowledge
+ // and no error
+ ideal_wr_ack <= #`TCQ 1;
+ //Still 2 from full
+
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+
+ //If the FIFO is not close to being full
+ end else
+ if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <
+ C_FIFO_WR_DEPTH-2) begin
+ //Add value on DIN port to FIFO
+ write_fifo;
+ next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH;
+ //Write successful, so issue acknowledge
+ // and no error
+ ideal_wr_ack <= #`TCQ 1;
+ //Not even close to full.
+
+ ideal_wr_count <= num_write_words_sized_i;
+
+ end
+
+ end
+
+ end else begin //(WR_EN == 1'b1)
+
+ //If user did not attempt a write, then do not
+ // give ack or err
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_wr_count <= #`TCQ num_write_words_sized_i;
+ end
+ num_wr_bits <= #`TCQ next_num_wr_bits;
+ rd_ptr_wrclk <= #`TCQ rd_ptr;
+
+ end //wr_rst_i==0
+ end // write always
+
+
+ /***************************************************************************
+ * Programmable FULL flags
+ ***************************************************************************/
+
+ always @(posedge WR_CLK or posedge RST_FULL_FF) begin : gen_pf
+
+ if (RST_FULL_FF == 1'b1) begin
+ diff_pntr <= 0;
+ ideal_prog_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ end else begin
+ if (ram_wr_en)
+ diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr + 2'h1);
+ else if (!ram_wr_en)
+ diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr);
+
+ if (RST_FULL_GEN)
+ ideal_prog_full <= #`TCQ 0;
+ //Single Programmable Full Constant Threshold
+ else if (C_PROG_FULL_TYPE == 1) begin
+ if (FULL == 0) begin
+ if (diff_pntr >= C_PROG_FULL_THRESH_ASSERT_VAL)
+ ideal_prog_full <= #`TCQ 1;
+ else
+ ideal_prog_full <= #`TCQ 0;
+ end else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ //Two Programmable Full Constant Thresholds
+ end else if (C_PROG_FULL_TYPE == 2) begin
+ if (FULL == 0) begin
+ if (diff_pntr >= C_PROG_FULL_THRESH_ASSERT_VAL)
+ ideal_prog_full <= #`TCQ 1;
+ else if (diff_pntr < C_PROG_FULL_THRESH_NEGATE_VAL)
+ ideal_prog_full <= #`TCQ 0;
+ else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ end else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ //Single Programmable Full Threshold Input
+ end else if (C_PROG_FULL_TYPE == 3) begin
+ if (FULL == 0) begin
+ if (diff_pntr >= PROG_FULL_THRESH)
+ ideal_prog_full <= #`TCQ 1;
+ else
+ ideal_prog_full <= #`TCQ 0;
+ end else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ //Two Programmable Full Threshold Inputs
+ end else if (C_PROG_FULL_TYPE == 4) begin
+ if (FULL == 0) begin
+ if (diff_pntr >= PROG_FULL_THRESH_ASSERT)
+ ideal_prog_full <= #`TCQ 1;
+ else if (diff_pntr < PROG_FULL_THRESH_NEGATE)
+ ideal_prog_full <= #`TCQ 0;
+ else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ end else
+ ideal_prog_full <= #`TCQ ideal_prog_full;
+ end // C_PROG_FULL_TYPE
+
+ end //wr_rst_i==0
+ end //
+
+
+ /**************************************************************************
+ * Read Domain Logic
+ **************************************************************************/
+
+
+ /*********************************************************
+ * Programmable EMPTY flags
+ *********************************************************/
+ //Determine the Assert and Negate thresholds for Programmable Empty
+
+ reg [C_RD_PNTR_WIDTH-1:0] pe_thr_assert_val = 0;
+ reg [C_RD_PNTR_WIDTH-1:0] pe_thr_negate_val = 0;
+ reg [C_RD_PNTR_WIDTH-1:0] diff_pntr_rd = 0;
+ always @* begin
+
+ if (C_PROG_EMPTY_TYPE == 3) begin
+
+ // If empty input threshold is selected, then subtract 2 for FWFT to
+ // compensate the FWFT stage, otherwise assign the input value.
+ if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) // FWFT
+ pe_thr_assert_val <= PROG_EMPTY_THRESH - 2'h2;
+ else
+ pe_thr_assert_val <= PROG_EMPTY_THRESH;
+
+ end else if (C_PROG_EMPTY_TYPE == 4) begin
+
+ // If empty input threshold is selected, then subtract 2 for FWFT to
+ // compensate the FWFT stage, otherwise assign the input value.
+ if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT
+ pe_thr_assert_val <= PROG_EMPTY_THRESH_ASSERT - 2'h2;
+ pe_thr_negate_val <= PROG_EMPTY_THRESH_NEGATE - 2'h2;
+ end else begin
+ pe_thr_assert_val <= PROG_EMPTY_THRESH_ASSERT;
+ pe_thr_negate_val <= PROG_EMPTY_THRESH_NEGATE;
+ end
+ end else begin
+
+ if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT
+ pe_thr_assert_val <= C_PROG_EMPTY_THRESH_ASSERT_VAL - 2;
+ pe_thr_negate_val <= C_PROG_EMPTY_THRESH_NEGATE_VAL - 2;
+ end else begin
+ pe_thr_assert_val <= C_PROG_EMPTY_THRESH_ASSERT_VAL;
+ pe_thr_negate_val <= C_PROG_EMPTY_THRESH_NEGATE_VAL;
+ end
+ end
+ end // always @*
+
+ always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_pe
+
+ if (rd_rst_i) begin
+ diff_pntr_rd <= #`TCQ 0;
+ ideal_prog_empty <= #`TCQ 1'b1;
+ end else begin
+ if (ram_rd_en)
+ diff_pntr_rd <= #`TCQ (adj_wr_pntr_rd - rd_pntr) - 1'h1;
+ else if (!ram_rd_en)
+ diff_pntr_rd <= #`TCQ (adj_wr_pntr_rd - rd_pntr);
+ else
+ diff_pntr_rd <= #`TCQ diff_pntr_rd;
+
+ if (C_PROG_EMPTY_TYPE == 1) begin
+ if (EMPTY == 0) begin
+ if (diff_pntr_rd <= pe_thr_assert_val)
+ ideal_prog_empty <= #`TCQ 1;
+ else
+ ideal_prog_empty <= #`TCQ 0;
+ end else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end else if (C_PROG_EMPTY_TYPE == 2) begin
+ if (EMPTY == 0) begin
+ if (diff_pntr_rd <= pe_thr_assert_val)
+ ideal_prog_empty <= #`TCQ 1;
+ else if (diff_pntr_rd > pe_thr_negate_val)
+ ideal_prog_empty <= #`TCQ 0;
+ else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end else if (C_PROG_EMPTY_TYPE == 3) begin
+ if (EMPTY == 0) begin
+ if (diff_pntr_rd <= pe_thr_assert_val)
+ ideal_prog_empty <= #`TCQ 1;
+ else
+ ideal_prog_empty <= #`TCQ 0;
+ end else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end else if (C_PROG_EMPTY_TYPE == 4) begin
+ if (EMPTY == 0) begin
+ if (diff_pntr_rd >= pe_thr_assert_val)
+ ideal_prog_empty <= #`TCQ 1;
+ else if (diff_pntr_rd > pe_thr_negate_val)
+ ideal_prog_empty <= #`TCQ 0;
+ else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end else
+ ideal_prog_empty <= #`TCQ ideal_prog_empty;
+ end //C_PROG_EMPTY_TYPE
+ end
+ end
+
+ // block memory has a synchronous reset
+ always @(posedge RD_CLK) begin : gen_fifo_blkmemdout
+ // make it consistent with the core.
+ if (rd_rst_i) begin
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0 && C_MEMORY_TYPE < 2)
+ err_type <= #`TCQ 0;
+
+ // BRAM resets synchronously
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) begin
+ ideal_dout <= #`TCQ dout_reset_val;
+ ideal_dout_d1 <= #`TCQ dout_reset_val;
+ end
+ end
+ end //always
+
+ always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_fifo_r
+
+ /****** Reset fifo (case 1)***************************************/
+ if (rd_rst_i) begin
+ num_rd_bits <= #`TCQ 0;
+ next_num_rd_bits = #`TCQ 0;
+ rd_ptr <= #`TCQ C_RD_DEPTH -1;
+ rd_pntr <= #`TCQ 0;
+ rd_pntr_wr1 <= #`TCQ 0;
+ wr_pntr_rd2 <= #`TCQ 0;
+ wr_pntr_rd3 <= #`TCQ 0;
+ wr_pntr_rd <= #`TCQ 0;
+ wr_ptr_rdclk <= #`TCQ C_WR_DEPTH -1;
+
+ // DRAM resets asynchronously
+ if (C_MEMORY_TYPE == 2 && C_USE_DOUT_RST == 1)
+ ideal_dout <= #`TCQ dout_reset_val;
+
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0)
+ err_type <= #`TCQ 0;
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_rd_count <= #`TCQ 0;
+
+ end else begin //rd_rst_i==0
+
+ rd_pntr_wr1 <= #`TCQ rd_pntr;
+
+ // Synchronize the wr_pntr in read domain
+ wr_pntr_rd2 <= #`TCQ wr_pntr_rd1;
+ wr_pntr_rd3 <= #`TCQ wr_pntr_rd2;
+ wr_pntr_rd <= #`TCQ wr_pntr_rd3;
+
+
+
+ //Determine the current number of words in the FIFO
+ tmp_rd_listsize = (C_DEPTH_RATIO_WR > 1) ? num_rd_bits/C_DIN_WIDTH :
+ num_rd_bits/C_DOUT_WIDTH;
+ wr_ptr_rdclk_next = wr_ptr;
+
+ if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin
+ next_num_rd_bits = num_rd_bits +
+ C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH
+ - wr_ptr_rdclk_next);
+ end else begin
+ next_num_rd_bits = num_rd_bits +
+ C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next);
+ end
+
+ /*****************************************************************/
+ // Read Operation - Read Latency 1
+ /*****************************************************************/
+ if (C_PRELOAD_LATENCY==1 || C_PRELOAD_LATENCY==2) begin
+ ideal_valid <= #`TCQ 1'b0;
+
+ if (ram_rd_en == 1'b1) begin
+
+ if (EMPTY == 1'b1) begin
+
+ //If the FIFO is completely empty, and is reporting empty
+ if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0)
+ begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Reminder that FIFO is still empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+ end // if (tmp_rd_listsize <= 0)
+
+ //If the FIFO is one from empty, but it is reporting empty
+ else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1)
+ begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Note that FIFO is no longer empty, but is almost empty (has one word left)
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize == 1)
+
+ //If the FIFO is two from empty, and is reporting empty
+ else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2)
+ begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Fifo has two words, so is neither empty or almost empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize == 2)
+
+ //If the FIFO is not close to empty, but is reporting that it is
+ // Treat the FIFO as empty this time, but unset EMPTY flags.
+ if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH))
+ begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Note that the FIFO is No Longer Empty or Almost Empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))
+ end // else: if(ideal_empty == 1'b1)
+
+ else //if (ideal_empty == 1'b0)
+ begin
+
+ //If the FIFO is completely full, and we are successfully reading from it
+ if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH)
+ begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Not close to empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize == C_FIFO_RD_DEPTH)
+
+ //If the FIFO is not close to being empty
+ else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH))
+ begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Not close to empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))
+
+ //If the FIFO is two from empty
+ else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2)
+ begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Fifo is not yet empty. It is going almost_empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize == 2)
+
+ //If the FIFO is one from empty
+ else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR == 1))
+ begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Note that FIFO is GOING empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize == 1)
+
+
+ //If the FIFO is completely empty
+ else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0)
+ begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize <= 0)
+
+ end // if (ideal_empty == 1'b0)
+
+ end //(RD_EN == 1'b1)
+
+ else //if (RD_EN == 1'b0)
+ begin
+ //If user did not attempt a read, do not give an ack or err
+ ideal_valid <= #`TCQ 1'b0;
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // else: !if(RD_EN == 1'b1)
+
+ /*****************************************************************/
+ // Read Operation - Read Latency 0
+ /*****************************************************************/
+ end else if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin
+ ideal_valid <= #`TCQ 1'b0;
+ if (ram_rd_en == 1'b1) begin
+
+ if (EMPTY == 1'b1) begin
+
+ //If the FIFO is completely empty, and is reporting empty
+ if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Reminder that FIFO is still empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is one from empty, but it is reporting empty
+ end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Note that FIFO is no longer empty, but is almost empty (has one word left)
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is two from empty, and is reporting empty
+ end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Fifo has two words, so is neither empty or almost empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is not close to empty, but is reporting that it is
+ // Treat the FIFO as empty this time, but unset EMPTY flags.
+ end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) &&
+ (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH)) begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Note that the FIFO is No Longer Empty or Almost Empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))
+
+ end else begin
+
+ //If the FIFO is completely full, and we are successfully reading from it
+ if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH) begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Not close to empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is not close to being empty
+ end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) &&
+ (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH)) begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Not close to empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is two from empty
+ end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Fifo is not yet empty. It is going almost_empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is one from empty
+ end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin
+ //Read the value from the FIFO
+ read_fifo;
+ next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;
+
+ //Acknowledge the read from the FIFO, no error
+ ideal_valid <= #`TCQ 1'b1;
+ //Note that FIFO is GOING empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ //If the FIFO is completely empty
+ end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin
+ //Do not change the contents of the FIFO
+
+ //Do not acknowledge the read from empty FIFO
+ ideal_valid <= #`TCQ 1'b0;
+ //Reminder that FIFO is still empty
+
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // if (tmp_rd_listsize <= 0)
+
+ end // if (ideal_empty == 1'b0)
+
+ end else begin//(RD_EN == 1'b0)
+
+
+ //If user did not attempt a read, do not give an ack or err
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_rd_count <= #`TCQ num_read_words_sized_i;
+
+ end // else: !if(RD_EN == 1'b1)
+ end //if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0)
+
+ num_rd_bits <= #`TCQ next_num_rd_bits;
+ wr_ptr_rdclk <= #`TCQ wr_ptr;
+ end //rd_rst_i==0
+ end //always
+
+endmodule // fifo_generator_v6_1_bhv_ver_as
+
+
+/*******************************************************************************
+ * Declaration of top-level module
+ ******************************************************************************/
+module fifo_generator_v6_1_bhv_ver_ss
+
+ /**************************************************************************
+ * Declare user parameters and their defaults
+ *************************************************************************/
+ #(
+ parameter C_DATA_COUNT_WIDTH = 2,
+ parameter C_DIN_WIDTH = 8,
+ parameter C_DOUT_RST_VAL = "",
+ parameter C_DOUT_WIDTH = 8,
+ parameter C_FULL_FLAGS_RST_VAL = 1,
+ parameter C_HAS_ALMOST_EMPTY = 0,
+ parameter C_HAS_ALMOST_FULL = 0,
+ parameter C_HAS_DATA_COUNT = 0,
+ parameter C_HAS_OVERFLOW = 0,
+ parameter C_HAS_RD_DATA_COUNT = 0,
+ parameter C_HAS_RST = 0,
+ parameter C_HAS_SRST = 0,
+ parameter C_HAS_UNDERFLOW = 0,
+ parameter C_HAS_VALID = 0,
+ parameter C_HAS_WR_ACK = 0,
+ parameter C_HAS_WR_DATA_COUNT = 0,
+ parameter C_IMPLEMENTATION_TYPE = 0,
+ parameter C_MEMORY_TYPE = 1,
+ parameter C_OVERFLOW_LOW = 0,
+ parameter C_PRELOAD_LATENCY = 1,
+ parameter C_PRELOAD_REGS = 0,
+ parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_EMPTY_TYPE = 0,
+ parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0,
+ parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0,
+ parameter C_PROG_FULL_TYPE = 0,
+ parameter C_RD_DATA_COUNT_WIDTH = 2,
+ parameter C_RD_DEPTH = 256,
+ parameter C_RD_PNTR_WIDTH = 8,
+ parameter C_UNDERFLOW_LOW = 0,
+ parameter C_USE_DOUT_RST = 0,
+ parameter C_USE_EMBEDDED_REG = 0,
+ parameter C_USE_FWFT_DATA_COUNT = 0,
+ parameter C_VALID_LOW = 0,
+ parameter C_WR_ACK_LOW = 0,
+ parameter C_WR_DATA_COUNT_WIDTH = 2,
+ parameter C_WR_DEPTH = 256,
+ parameter C_WR_PNTR_WIDTH = 8,
+ parameter C_USE_ECC = 0,
+ parameter C_ENABLE_RST_SYNC = 1,
+ parameter C_ERROR_INJECTION_TYPE = 0
+ )
+
+ /**************************************************************************
+ * Declare Input and Output Ports
+ *************************************************************************/
+ (
+ //Inputs
+ input CLK,
+ input [C_DIN_WIDTH-1:0] DIN,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT,
+ input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT,
+ input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE,
+ input RD_EN,
+ input RST,
+ input RST_FULL_GEN,
+ input RST_FULL_FF,
+ input SRST,
+ input WR_EN,
+ input INJECTDBITERR,
+ input INJECTSBITERR,
+
+ //Outputs
+ output ALMOST_EMPTY,
+ output ALMOST_FULL,
+ output reg [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT,
+ output [C_DOUT_WIDTH-1:0] DOUT,
+ output EMPTY,
+ output FULL,
+ output OVERFLOW,
+ output PROG_EMPTY,
+ output PROG_FULL,
+ output VALID,
+ output UNDERFLOW,
+ output WR_ACK,
+ output SBITERR,
+ output DBITERR
+ );
+
+
+ /***************************************************************************
+ * Parameters used as constants
+ **************************************************************************/
+ //When RST is present, set FULL reset value to '1'.
+ //If core has no RST, make sure FULL powers-on as '0'.
+ //The reset value assignments for FULL, ALMOST_FULL, and PROG_FULL are not
+ //changed for v3.2(IP2_Im). When the core has Sync Reset, C_HAS_SRST=1 and C_HAS_RST=0.
+ // Therefore, during SRST, all the FULL flags reset to 0.
+ parameter C_HAS_FAST_FIFO = 0;
+ parameter C_FIFO_WR_DEPTH = C_WR_DEPTH;
+ parameter C_FIFO_RD_DEPTH = C_RD_DEPTH;
+
+ /**************************************************************************
+ * FIFO Contents Tracking and Data Count Calculations
+ *************************************************************************/
+ // Memory which will be used to simulate a FIFO
+ reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0];
+ // Local parameters used to determine whether to inject ECC error or not
+ localparam SYMMETRIC_PORT = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 1 : 0;
+ localparam ERR_INJECTION = (C_ERROR_INJECTION_TYPE != 0) ? 1 : 0;
+ localparam ENABLE_ERR_INJECTION = C_USE_ECC && SYMMETRIC_PORT && ERR_INJECTION;
+ // Array that holds the error injection type (single/double bit error) on
+ // a specific write operation, which is returned on read to corrupt the
+ // output data.
+ reg [1:0] ecc_err[C_WR_DEPTH-1:0];
+
+ //The amount of data stored in the FIFO at any time is given
+ // by num_bits.
+ //num_bits is calculated by from the total words in the FIFO.
+ reg [31:0] num_bits;
+
+ //The write pointer - tracks write operations
+ // (Works opposite to core: wr_ptr is a DOWN counter)
+ reg [31:0] wr_ptr;
+
+ //The write pointer - tracks read operations
+ // (Works opposite to core: rd_ptr is a DOWN counter)
+ reg [31:0] rd_ptr;
+
+ /**************************
+ * Data Count
+ *************************/
+ //Amount of data stored in the FIFO scaled to read words
+ wire [31:0] num_read_words = num_bits/C_DOUT_WIDTH;
+ //num_read_words delayed 1 clock cycle
+ reg [31:0] num_read_words_q;
+
+ //Amount of data stored in the FIFO scaled to write words
+ wire [31:0] num_write_words = num_bits/C_DIN_WIDTH;
+ //num_write_words delayed 1 clock cycle
+ reg [31:0] num_write_words_q;
+
+
+ /**************************************************************************
+ * Internal Registers and wires
+ *************************************************************************/
+
+ //Temporary signals used for calculating the model's outputs. These
+ //are only used in the assign statements immediately following wire,
+ //parameter, and function declarations.
+ wire underflow_i;
+ wire valid_i;
+ wire valid_out;
+
+ //Ideal FIFO signals. These are the raw output of the behavioral model,
+ //which behaves like an ideal FIFO.
+ reg [1:0] err_type = 0;
+ reg [1:0] err_type_d1 = 0;
+ reg [C_DOUT_WIDTH-1:0] ideal_dout = 0;
+ reg [C_DOUT_WIDTH-1:0] ideal_dout_d1 = 0;
+ wire [C_DOUT_WIDTH-1:0] ideal_dout_out;
+ wire fwft_enabled;
+ reg ideal_wr_ack = 0;
+ reg ideal_valid = 0;
+ reg ideal_overflow = 0;
+ reg ideal_underflow = 0;
+ reg ideal_full = 0;
+ reg ideal_empty = 1;
+ reg ideal_almost_full = 0;
+ reg ideal_almost_empty = 1;
+ reg ideal_prog_full = 0;
+ reg ideal_prog_empty = 1;
+
+ //Assorted reg values for delayed versions of signals
+ reg valid_d1 = 0;
+ reg prog_full_d = 0;
+ reg prog_empty_d = 1;
+
+ wire rst_i;
+ wire srst_i;
+
+ //Delayed version of RST
+ reg rst_q;
+ reg rst_qq;
+
+ //user specified value for reseting the size of the fifo
+ reg [C_DOUT_WIDTH-1:0] dout_reset_val = 0;
+
+
+ /****************************************************************************
+ * Function Declarations
+ ***************************************************************************/
+
+ /**************************************************************************
+ * write_fifo
+ * This task writes a word to the FIFO memory and updates the
+ * write pointer.
+ * FIFO size is relative to write domain.
+ ***************************************************************************/
+ task write_fifo;
+ reg [1:0] corrupted_data;
+ begin
+ memory[wr_ptr] <= DIN;
+ // Store the type of error injection (double/single) on write
+ case (C_ERROR_INJECTION_TYPE)
+ 3: ecc_err[wr_ptr] <= {INJECTDBITERR,INJECTSBITERR};
+ 2: ecc_err[wr_ptr] <= {INJECTDBITERR,1'b0};
+ 1: ecc_err[wr_ptr] <= {1'b0,INJECTSBITERR};
+ default: ecc_err[wr_ptr] <= 0;
+ endcase
+ if (wr_ptr == 0) begin
+ wr_ptr <= C_WR_DEPTH - 1;
+ end else begin
+ wr_ptr <= wr_ptr - 1;
+ end
+ end
+ endtask // write_fifo
+
+ /**************************************************************************
+ * read_fifo
+ * This task reads a word from the FIFO memory and updates the read
+ * pointer. It's output is the ideal_dout bus.
+ * FIFO size is relative to write domain.
+ ***************************************************************************/
+ task read_fifo;
+ reg [C_DOUT_WIDTH-1:0] tmp_dout;
+ reg [1:0] tmp_ecc_err;
+ begin
+ tmp_dout = memory[rd_ptr][C_DOUT_WIDTH-1:0];
+ // Retreive the error injection type. Based on the error injection type
+ // corrupt the output data.
+ tmp_ecc_err = ecc_err[rd_ptr];
+ if (ENABLE_ERR_INJECTION) begin
+ if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error
+ if (C_DOUT_WIDTH == 1)
+ tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
+ else if (C_DOUT_WIDTH == 2)
+ tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]};
+ else
+ tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)};
+ end else begin
+ tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
+ end
+ err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]};
+ end else begin
+ err_type <= 0;
+ end
+ ideal_dout <= tmp_dout;
+
+ if (rd_ptr == 0) begin
+ rd_ptr <= C_RD_DEPTH - 1;
+ end else begin
+ rd_ptr <= rd_ptr - 1;
+ end
+ end
+ endtask
+
+ /****************************************************************************
+ * log2_val
+ * Returns the 'log2' value for the input value for the supported ratios
+ ***************************************************************************/
+ function [31:0] log2_val;
+ input [31:0] binary_val;
+
+ begin
+ if (binary_val == 8) begin
+ log2_val = 3;
+ end else if (binary_val == 4) begin
+ log2_val = 2;
+ end else begin
+ log2_val = 1;
+ end
+ end
+ endfunction
+
+ /****************************************************************************
+ * hexstr_conv
+ * Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
+ ***************************************************************************/
+ function [C_DOUT_WIDTH-1:0] hexstr_conv;
+ input [(C_DOUT_WIDTH*8)-1:0] def_data;
+
+ integer index,i,j;
+ reg [3:0] bin;
+
+ begin
+ index = 0;
+ hexstr_conv = 'b0;
+ for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 )
+ begin
+ case (def_data[7:0])
+ 8'b00000000 :
+ begin
+ bin = 4'b0000;
+ i = -1;
+ end
+ 8'b00110000 : bin = 4'b0000;
+ 8'b00110001 : bin = 4'b0001;
+ 8'b00110010 : bin = 4'b0010;
+ 8'b00110011 : bin = 4'b0011;
+ 8'b00110100 : bin = 4'b0100;
+ 8'b00110101 : bin = 4'b0101;
+ 8'b00110110 : bin = 4'b0110;
+ 8'b00110111 : bin = 4'b0111;
+ 8'b00111000 : bin = 4'b1000;
+ 8'b00111001 : bin = 4'b1001;
+ 8'b01000001 : bin = 4'b1010;
+ 8'b01000010 : bin = 4'b1011;
+ 8'b01000011 : bin = 4'b1100;
+ 8'b01000100 : bin = 4'b1101;
+ 8'b01000101 : bin = 4'b1110;
+ 8'b01000110 : bin = 4'b1111;
+ 8'b01100001 : bin = 4'b1010;
+ 8'b01100010 : bin = 4'b1011;
+ 8'b01100011 : bin = 4'b1100;
+ 8'b01100100 : bin = 4'b1101;
+ 8'b01100101 : bin = 4'b1110;
+ 8'b01100110 : bin = 4'b1111;
+ default :
+ begin
+ bin = 4'bx;
+ end
+ endcase
+ for( j=0; j<4; j=j+1)
+ begin
+ if ((index*4)+j < C_DOUT_WIDTH)
+ begin
+ hexstr_conv[(index*4)+j] = bin[j];
+ end
+ end
+ index = index + 1;
+ def_data = def_data >> 8;
+ end
+ end
+ endfunction
+
+
+ /*************************************************************************
+ * Initialize Signals for clean power-on simulation
+ *************************************************************************/
+ initial begin
+ num_bits = 0;
+ num_read_words_q = 0;
+ num_write_words_q = 0;
+ rd_ptr = C_RD_DEPTH -1;
+ wr_ptr = C_WR_DEPTH -1;
+ dout_reset_val = hexstr_conv(C_DOUT_RST_VAL);
+ ideal_dout = dout_reset_val;
+ err_type = 0;
+ ideal_wr_ack = 1'b0;
+ ideal_valid = 1'b0;
+ valid_d1 = 1'b0;
+ ideal_overflow = 1'b0;
+ ideal_underflow = 1'b0;
+ ideal_full = 1'b0;
+ ideal_empty = 1'b1;
+ ideal_almost_full = 1'b0;
+ ideal_almost_empty = 1'b1;
+ ideal_prog_full = 1'b0;
+ ideal_prog_empty = 1'b1;
+ prog_full_d = 1'b0;
+ prog_empty_d = 1'b1;
+ rst_q = 1'b0;
+ rst_qq = 1'b0;
+ end
+
+
+ /*************************************************************************
+ * Connect the module inputs and outputs to the internal signals of the
+ * behavioral model.
+ *************************************************************************/
+ //Inputs
+ /*
+ wire CLK;
+ wire [C_DIN_WIDTH-1:0] DIN;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT;
+ wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT;
+ wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE;
+ wire RD_EN;
+ wire RST;
+ wire WR_EN;
+ */
+
+ //Outputs
+ generate
+ if (C_HAS_ALMOST_EMPTY==1) begin : blockAE10
+ assign ALMOST_EMPTY = ideal_almost_empty;
+ end
+ endgenerate
+
+ generate
+ if (C_HAS_ALMOST_FULL==1) begin : blockAF10
+ assign ALMOST_FULL = ideal_almost_full;
+ end
+ endgenerate
+
+ //Dout may change behavior based on latency
+ assign fwft_enabled = (C_PRELOAD_LATENCY == 0 && C_PRELOAD_REGS == 1)?
+ 1: 0;
+ assign ideal_dout_out= ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
+ ideal_dout_d1: ideal_dout;
+ assign DOUT = ideal_dout_out;
+
+ // Assign SBITERR and DBITERR based on latency
+ assign SBITERR = (C_ERROR_INJECTION_TYPE == 1 || C_ERROR_INJECTION_TYPE == 3) &&
+ ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
+ err_type_d1[0]: err_type[0];
+ assign DBITERR = (C_ERROR_INJECTION_TYPE == 2 || C_ERROR_INJECTION_TYPE == 3) &&
+ ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
+ err_type_d1[1]: err_type[1];
+
+ assign EMPTY = ideal_empty;
+ assign FULL = ideal_full;
+
+ //Overflow may be active-low
+ generate
+ if (C_HAS_OVERFLOW==1) begin : blockOF10
+ assign OVERFLOW = ideal_overflow ? !C_OVERFLOW_LOW : C_OVERFLOW_LOW;
+ end
+ endgenerate
+
+ assign PROG_EMPTY = ideal_prog_empty;
+ assign PROG_FULL = ideal_prog_full;
+
+ //Valid may change behavior based on latency or active-low
+ generate
+ if (C_HAS_VALID==1) begin : blockVL10
+ assign valid_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & ~EMPTY) : ideal_valid;
+ assign valid_out = (C_PRELOAD_LATENCY==2 &&
+ (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
+ valid_d1: valid_i;
+ assign VALID = valid_out ? !C_VALID_LOW : C_VALID_LOW;
+ end
+ endgenerate
+
+ //Trim data count differently depending on set widths
+ generate
+ if ((C_HAS_DATA_COUNT == 1) &&
+ (C_DATA_COUNT_WIDTH > C_RD_PNTR_WIDTH)) begin : blockDC1
+ always @(num_read_words)
+ DATA_COUNT = num_read_words[C_RD_PNTR_WIDTH:0];
+ end else if (C_HAS_DATA_COUNT == 1) begin : blockDC2
+ always @(num_read_words)
+ DATA_COUNT = num_read_words[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_DATA_COUNT_WIDTH];
+ end //if
+ endgenerate
+
+ //Underflow may change behavior based on latency or active-low
+ generate
+ if (C_HAS_UNDERFLOW==1) begin : blockUF10
+ assign underflow_i = ideal_underflow;
+ assign UNDERFLOW = underflow_i ? !C_UNDERFLOW_LOW : C_UNDERFLOW_LOW;
+ end
+ endgenerate
+
+
+ //Write acknowledge may be active low
+ generate
+ if (C_HAS_WR_ACK==1) begin : blockWK10
+ assign WR_ACK = ideal_wr_ack ? !C_WR_ACK_LOW : C_WR_ACK_LOW;
+ end
+ endgenerate
+
+
+ /*****************************************************************************
+ * Internal reset logic
+ ****************************************************************************/
+ assign srst_i = C_HAS_SRST ? SRST : 0;
+ assign rst_i = C_HAS_RST ? RST : 0;
+
+ /**************************************************************************
+ * Assorted registers for delayed versions of signals
+ **************************************************************************/
+ //Capture delayed version of valid
+ generate
+ if (C_HAS_VALID==1) begin : blockVL20
+ always @(posedge CLK or posedge rst_i) begin
+ if (rst_i == 1'b1) begin
+ valid_d1 <= #`TCQ 1'b0;
+ end else begin
+ if (srst_i) begin
+ valid_d1 <= #`TCQ 1'b0;
+ end else begin
+ valid_d1 <= #`TCQ valid_i;
+ end
+ end
+ end // always @ (posedge CLK or posedge rst_i)
+ end
+ endgenerate
+
+
+ // block memory has a synchronous reset
+ always @(posedge CLK) begin : gen_fifo_blkmemdout_emb
+ // make it consistent with the core.
+ if (rst_i || srst_i) begin
+ // BRAM resets synchronously
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) begin
+ ideal_dout_d1 <= #`TCQ dout_reset_val;
+ end
+ end
+ end //always
+
+ reg ram_rd_en_d1 = 1'b0;
+ //Capture delayed version of dout
+ always @(posedge CLK or posedge rst_i) begin
+ if (rst_i == 1'b1) begin
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0)
+ err_type_d1 <= #`TCQ 0;
+
+ // DRAM and SRAM reset asynchronously
+ if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1)
+ ideal_dout_d1 <= #`TCQ dout_reset_val;
+
+ ram_rd_en_d1 <= #`TCQ 1'b0;
+ end else begin
+ ram_rd_en_d1 <= #`TCQ RD_EN & !EMPTY;
+ if (srst_i) begin
+ ram_rd_en_d1 <= #`TCQ 1'b0;
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0)
+ err_type_d1 <= #`TCQ 0;
+ // Reset DRAM and SRAM based FIFO, BRAM based FIFO is reset above
+ if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1)
+ ideal_dout_d1 <= #`TCQ dout_reset_val;
+ end else if (ram_rd_en_d1) begin
+ ideal_dout_d1 <= #`TCQ ideal_dout;
+ err_type_d1 <= #`TCQ err_type;
+ end
+ end
+ end
+
+ /**************************************************************************
+ * Overflow and Underflow Flag calculation
+ * (handled separately because they don't support rst)
+ **************************************************************************/
+ generate
+ if (C_HAS_OVERFLOW==1) begin : blockOF20
+ always @(posedge CLK) begin
+ ideal_overflow <= #`TCQ WR_EN & ideal_full;
+ end
+ end
+ endgenerate
+
+ generate
+ if (C_HAS_UNDERFLOW==1) begin : blockUF20
+ always @(posedge CLK) begin
+ ideal_underflow <= #`TCQ ideal_empty & RD_EN;
+ end
+ end
+ endgenerate
+
+ /*************************************************************************
+ * Write and Read Logic
+ ************************************************************************/
+ always @(posedge CLK or posedge rst_i)
+ begin : gen_wr_ack_resp
+
+ //Register reset
+ rst_q <= #`TCQ rst_i;
+ rst_qq <= #`TCQ rst_q;
+
+ end // block: gen_wr_ack_resp
+
+ // block memory has a synchronous reset
+ always @(posedge CLK) begin : gen_fifo_blkmemdout
+ //Changed the latency of during async reset to '1' instead of '2' to
+ // make it consistent with the core.
+ if (rst_i || rst_q || srst_i) begin
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0 && C_MEMORY_TYPE == 1)
+ err_type <= #`TCQ 0;
+ /******Initialize Read Domain Signals*********************************/
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) begin
+ ideal_dout <= #`TCQ dout_reset_val;
+ end
+ end
+ end //always
+
+ // FULL_FLAG_RESET value given for SRST as well.
+ reg srst_i_d1 = 0;
+ reg srst_i_d2 = 0;
+ always @(posedge CLK or posedge RST_FULL_FF) begin : gen_fifo
+
+ /****** Reset fifo - Asynchronous Reset**********************************/
+ //Changed the latency of during async reset to '1' instead of '2' to
+ // make it consistent with the core.
+ if (RST_FULL_FF) begin //v3.2
+ /******Initialize Generic FIFO constructs*****************************/
+ num_bits <= #`TCQ 0;
+ wr_ptr <= #`TCQ C_WR_DEPTH - 1;
+ rd_ptr <= #`TCQ C_RD_DEPTH - 1;
+ num_read_words_q <= #`TCQ 0;
+ num_write_words_q <= #`TCQ 0;
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0 && C_MEMORY_TYPE != 1)
+ err_type <= #`TCQ 0;
+
+
+ /******Initialize Write Domain Signals********************************/
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ ideal_almost_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+
+ /******Initialize Read Domain Signals*********************************/
+ // DRAM and SRAM reset asynchronously
+ if (C_USE_DOUT_RST == 1 && (C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3)) begin
+ ideal_dout <= #`TCQ dout_reset_val;
+ end
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ end else begin
+ // Register SRST twice to be consistant with RST behavior
+ srst_i_d1 <= #`TCQ srst_i;
+ srst_i_d2 <= #`TCQ srst_i_d1;
+ if (srst_i) begin
+ // SRST is available only for Sync BRAM, DRAM and SRAM.
+ if (C_MEMORY_TYPE == 1 || C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) begin
+ /******Initialize Generic FIFO constructs***********************/
+ num_bits <= #`TCQ 0;
+ wr_ptr <= #`TCQ C_WR_DEPTH - 1;
+ rd_ptr <= #`TCQ C_RD_DEPTH - 1;
+ num_read_words_q <= #`TCQ 0;
+ num_write_words_q <= #`TCQ 0;
+ // Reset err_type only if ECC is not selected
+ if (C_USE_ECC == 0)
+ err_type <= #`TCQ 0;
+
+ /******Initialize Write Domain Signals**************************/
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ ideal_almost_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+
+ /******Initialize Read Domain Signals***************************/
+ //Reset DOUT of Sync DRAM/Shift RAM. Sync BRAM DOUT was reset in the
+ // above always block.
+ if (C_USE_DOUT_RST == 1 && (C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3)) begin
+ ideal_dout <= #`TCQ dout_reset_val;
+ end
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+ end
+
+ end else if ((srst_i_d1 || srst_i_d2) && (C_FULL_FLAGS_RST_VAL == 1)) begin //Hold full flag reset value set during RST/SRST
+ ideal_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ ideal_almost_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ end else begin //normal operating conditions
+ /********************************************************************/
+ // Synchronous FIFO Condition #1 : Writing and not reading
+ /********************************************************************/
+ ideal_valid <= #`TCQ 1'b0;
+ if (WR_EN & ~RD_EN) begin
+
+ /*********************************/
+ //If the FIFO is full, do NOT perform the write,
+ // update flags accordingly
+ /*********************************/
+ if (num_write_words >= C_FIFO_WR_DEPTH) begin
+ ideal_wr_ack <= #`TCQ 0;
+
+ //still full
+ ideal_full <= #`TCQ 1'b1;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //write unsuccessful - do not change contents
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+
+ /*********************************/
+ //If the FIFO is reporting FULL
+ // (Startup condition)
+ /*********************************/
+ end else if ((num_write_words < C_FIFO_WR_DEPTH) && (ideal_full == 1'b1)) begin
+ ideal_wr_ack <= #`TCQ 0;
+
+ //still full
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //write unsuccessful - do not change contents
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //FIFO EMPTY in this state can not be determined
+ //ideal_empty <= 1'b0;
+ //ideal_almost_empty <= 1'b0;
+
+
+ /*********************************/
+ //If the FIFO is one from full
+ /*********************************/
+ end else if (num_write_words == C_FIFO_WR_DEPTH-1) begin
+ //good write
+ ideal_wr_ack <= #`TCQ 1;
+
+ //FIFO is one from FULL and going FULL
+ ideal_full <= #`TCQ 1'b1;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //Add input data
+ write_fifo;
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ num_bits <= num_bits + C_DIN_WIDTH;
+
+ /*********************************/
+ //If the FIFO is 2 from full
+ /*********************************/
+ end else if (num_write_words == C_FIFO_WR_DEPTH-2) begin
+ //good write
+ ideal_wr_ack <= #`TCQ 1;
+
+ //2 from full, and writing, so set almost_full
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //Add input data
+ write_fifo;
+
+ //no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH;
+
+ /*********************************/
+ //If the FIFO is ALMOST EMPTY
+ /*********************************/
+ end else if (num_read_words == 1) begin
+ //good write
+ ideal_wr_ack <= #`TCQ 1;
+
+ //Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Add input data
+ write_fifo;
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Leaving ALMOST_EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH;
+
+ /*********************************/
+ //If the FIFO is EMPTY
+ /*********************************/
+ end else if (num_read_words == 0) begin
+ // good write
+ ideal_wr_ack <= #`TCQ 1;
+
+ //Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Add input data
+ write_fifo;
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Leaving EMPTY (still ALMOST_EMPTY)
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH;
+
+ /*********************************/
+ //If the FIFO is not near EMPTY or FULL
+ /*********************************/
+ end else begin
+ // good write
+ ideal_wr_ack <= #`TCQ 1;
+
+ //Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Add input data
+ write_fifo;
+
+ // no read attempted
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Not near EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH;
+
+ end // average case
+
+
+ /******************************************************************/
+ // Synchronous FIFO Condition #2 : Reading and not writing
+ /******************************************************************/
+ end else if (~WR_EN & RD_EN) begin
+
+ /*********************************/
+ //If the FIFO is EMPTY
+ /*********************************/
+ if ((num_read_words == 0) || (ideal_empty == 1'b1)) begin
+ //no write attemped
+ ideal_wr_ack <= #`TCQ 0;
+
+ //FIFO is not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read will fail
+ ideal_valid <= #`TCQ 1'b0;
+
+ //FIFO is still empty
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //No read
+
+ /*********************************/
+ //If the FIFO is ALMOST EMPTY
+ /*********************************/
+ end else if (num_read_words == 1) begin
+ //no write attempted
+ ideal_wr_ack <= #`TCQ 0;
+
+ //FIFO is not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //This read will make FIFO go empty
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //Get the data from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DIN_WIDTH;
+
+
+ /*********************************/
+ //If the FIFO is 2 from EMPTY
+ /*********************************/
+ end else if (num_read_words == 2) begin
+
+ //no write attempted
+ ideal_wr_ack <= #`TCQ 0;
+
+ //FIFO is not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //FIFO is going ALMOST_EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //Get the data from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DOUT_WIDTH;
+
+
+
+ /*********************************/
+ //If the FIFO is one from full
+ /*********************************/
+ end else if (num_write_words == C_FIFO_WR_DEPTH-1) begin
+
+ //no write attempted
+ ideal_wr_ack <= #`TCQ 0;
+
+ //FIFO is leaving ALMOST FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DOUT_WIDTH;
+
+
+ /*********************************/
+ // FIFO is FULL
+ /*********************************/
+ end else if (num_write_words >= C_FIFO_WR_DEPTH)
+ begin
+ //no write attempted
+ ideal_wr_ack <= #`TCQ 0;
+
+ //FIFO is leaving FULL, but is still ALMOST_FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DOUT_WIDTH;
+
+ /*********************************/
+ //If the FIFO is not near EMPTY or FULL
+ /*********************************/
+ end else begin
+ //no write attemped
+ ideal_wr_ack <= #`TCQ 0;
+
+ //Not near empty
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DOUT_WIDTH;
+
+
+ end // average read
+
+
+ /******************************************************************/
+ // Synchronous FIFO Condition #3 : Reading and writing
+ /******************************************************************/
+ end else if (WR_EN & RD_EN) begin
+
+ /*********************************/
+ // FIFO is FULL
+ /*********************************/
+ if (num_write_words >= C_FIFO_WR_DEPTH) begin
+
+ ideal_wr_ack <= #`TCQ 0;
+
+ //Read will be successful, so FIFO will leave FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits - C_DOUT_WIDTH;
+
+
+ /*********************************/
+ // FIFO is reporting FULL, but it is empty
+ // (This is a special case, when coming out of RST
+ /*********************************/
+ end else if ((num_write_words == 0) && (ideal_full == 1'b1)) begin
+
+ ideal_wr_ack <= #`TCQ 0;
+
+ //Read will be successful, so FIFO will leave FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //Read unsuccessful
+ ideal_valid <= #`TCQ 1'b0;
+
+ //Report empty condition
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //Do not read from empty FIFO
+ // Read from the FIFO
+
+
+ /*********************************/
+ //If the FIFO is one from full
+ /*********************************/
+ end else if (num_write_words == C_FIFO_WR_DEPTH-1) begin
+
+ //Write successful
+ ideal_wr_ack <= #`TCQ 1;
+
+ //FIFO will remain ALMOST_FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ // put the data into the FIFO
+ write_fifo;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //Not near empty
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH - C_DOUT_WIDTH;
+
+ /*********************************/
+ //If the FIFO is ALMOST EMPTY
+ /*********************************/
+ end else if (num_read_words == 1) begin
+
+ //Write successful
+ ideal_wr_ack <= #`TCQ 1;
+
+ // Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ // put the data into the FIFO
+ write_fifo;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ //FIFO will stay ALMOST_EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH - C_DOUT_WIDTH;
+
+
+ /*********************************/
+ //If the FIFO is EMPTY
+ /*********************************/
+ end else if (num_read_words == 0) begin
+
+ //Write successful
+ ideal_wr_ack <= #`TCQ 1;
+
+ // Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ // put the data into the FIFO
+ write_fifo;
+
+ //Read will fail
+ ideal_valid <= #`TCQ 1'b0;
+
+ //FIFO will leave EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ // No read
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH;
+
+
+ /*********************************/
+ //If the FIFO is not near EMPTY or FULL
+ /*********************************/
+ end else begin
+
+ //Write successful
+ ideal_wr_ack <= #`TCQ 1;
+
+ // Not near FULL
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ // put the data into the FIFO
+ write_fifo;
+
+ //Read successful
+ ideal_valid <= #`TCQ 1'b1;
+
+ // Not near EMPTY
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //Read from the FIFO
+ read_fifo;
+ num_bits <= #`TCQ num_bits + C_DIN_WIDTH - C_DOUT_WIDTH;
+
+ end // average case
+
+ /******************************************************************/
+ // Synchronous FIFO Condition #4 : Not reading or writing
+ /******************************************************************/
+ end else begin
+
+ /*********************************/
+ // FIFO is FULL
+ /*********************************/
+ if (num_write_words >= C_FIFO_WR_DEPTH) begin
+
+ //No write
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ 1'b1;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //No read
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //No change to memory
+
+ /*********************************/
+ //If the FIFO is one from full
+ /*********************************/
+ end else if (num_write_words == C_FIFO_WR_DEPTH-1) begin
+
+ //No write
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b1;
+
+ //No read
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //No change to memory
+
+ /*********************************/
+ //If the FIFO is ALMOST EMPTY
+ /*********************************/
+ end else if (num_read_words == 1) begin
+ //No write
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //No read
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //No change to memory
+
+ end // almost empty
+
+
+ /*********************************/
+ //If the FIFO is EMPTY
+ /*********************************/
+ else if (num_read_words == 0)
+ begin
+ //No write
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //No read
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b1;
+ ideal_almost_empty <= #`TCQ 1'b1;
+
+ //No change to memory
+
+ /*********************************/
+ //If the FIFO is not near EMPTY or FULL
+ /*********************************/
+ end else begin
+
+ //No write
+ ideal_wr_ack <= #`TCQ 0;
+ ideal_full <= #`TCQ 1'b0;
+ ideal_almost_full <= #`TCQ 1'b0;
+
+ //No read
+ ideal_valid <= #`TCQ 1'b0;
+ ideal_empty <= #`TCQ 1'b0;
+ ideal_almost_empty <= #`TCQ 1'b0;
+
+ //No change to memory
+
+ end // average case
+
+ end // neither reading or writing
+
+ num_read_words_q <= #`TCQ num_read_words;
+ num_write_words_q <= #`TCQ num_write_words;
+
+ end //normal operating conditions
+ end
+
+ end // block: gen_fifo
+
+
+ always @(posedge CLK or posedge RST_FULL_FF) begin : gen_fifo_p
+
+ /****** Reset fifo - Async Reset****************************************/
+ //The latency of de-assertion of the flags is reduced by 1 to be
+ // consistent with the core.
+ if (RST_FULL_FF) begin
+ ideal_prog_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ ideal_prog_empty <= #`TCQ 1'b1;
+ prog_full_d <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ prog_empty_d <= #`TCQ 1'b1;
+
+ end else begin
+ if (srst_i) begin
+ //SRST is available only for Sync BRAM and Sync DRAM. Not for SSHFT.
+ if (C_MEMORY_TYPE == 1 || C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) begin
+ ideal_prog_empty <= #`TCQ 1'b1;
+ prog_empty_d <= #`TCQ 1'b1;
+ ideal_prog_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ prog_full_d <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ end
+ end else if ((srst_i_d1 || srst_i_d2) && (C_FULL_FLAGS_RST_VAL == 1)) begin
+ ideal_prog_full <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ prog_full_d <= #`TCQ C_FULL_FLAGS_RST_VAL;
+ end else begin
+
+ /***************************************************************
+ * Programmable FULL flags
+ ****************************************************************/
+ //calculation for standard fifo and latency =2
+ if (! (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) ) begin
+ //Single constant threshold
+ if (C_PROG_FULL_TYPE == 1) begin
+ if ((num_write_words >= C_PROG_FULL_THRESH_ASSERT_VAL-1)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (((num_write_words == C_PROG_FULL_THRESH_ASSERT_VAL)
+ && RD_EN && !WR_EN) || (RST_FULL_GEN)) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Dual constant thresholds
+ end else if (C_PROG_FULL_TYPE == 2) begin
+ if ((num_write_words == C_PROG_FULL_THRESH_ASSERT_VAL-1)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == C_PROG_FULL_THRESH_NEGATE_VAL)
+ && RD_EN && !WR_EN) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Single input threshold
+ end else if (C_PROG_FULL_TYPE == 3) begin
+ if ((num_write_words == PROG_FULL_THRESH-1)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == PROG_FULL_THRESH)
+ && !WR_EN && RD_EN) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end else if (num_write_words >= PROG_FULL_THRESH) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (num_write_words < PROG_FULL_THRESH) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Dual input thresholds
+ end else begin
+ if ((num_write_words == PROG_FULL_THRESH_ASSERT-1)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == PROG_FULL_THRESH_NEGATE)
+ && !WR_EN && RD_EN)begin
+ prog_full_d <= #`TCQ 1'b0;
+ end else if (num_write_words >= PROG_FULL_THRESH_ASSERT) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (num_write_words < PROG_FULL_THRESH_NEGATE) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+ end
+ end // (~ (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) )
+
+
+ //calculation for FWFT fifo
+ if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin
+ if (C_PROG_FULL_TYPE == 1) begin
+ if ((num_write_words >= C_PROG_FULL_THRESH_ASSERT_VAL-1 - 2)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (((num_write_words == C_PROG_FULL_THRESH_ASSERT_VAL - 2)
+ && RD_EN && !WR_EN) || (RST_FULL_GEN)) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Dual constant thresholds
+ end else if (C_PROG_FULL_TYPE == 2) begin
+ if ((num_write_words == C_PROG_FULL_THRESH_ASSERT_VAL-1 - 2)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == C_PROG_FULL_THRESH_NEGATE_VAL - 2)
+ && RD_EN && !WR_EN) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Single input threshold
+ end else if (C_PROG_FULL_TYPE == 3) begin
+ if ((num_write_words == PROG_FULL_THRESH-1 - 2)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == PROG_FULL_THRESH - 2)
+ && !WR_EN && RD_EN) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end else if (num_write_words >= PROG_FULL_THRESH - 2) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (num_write_words < PROG_FULL_THRESH - 2) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+
+ //Dual input thresholds
+ end else begin
+ if ((num_write_words == PROG_FULL_THRESH_ASSERT-1 - 2)
+ && WR_EN && !RD_EN) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if ((num_write_words == PROG_FULL_THRESH_NEGATE - 2)
+ && !WR_EN && RD_EN)begin
+ prog_full_d <= #`TCQ 1'b0;
+ end else if (num_write_words >= PROG_FULL_THRESH_ASSERT - 2) begin
+ prog_full_d <= #`TCQ 1'b1;
+ end else if (num_write_words < PROG_FULL_THRESH_NEGATE - 2) begin
+ prog_full_d <= #`TCQ 1'b0;
+ end
+ end
+ end // (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0)
+
+ /*****************************************************************
+ * Programmable EMPTY flags
+ ****************************************************************/
+ //calculation for standard fifo and latency = 2
+ if (! (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) ) begin
+ //Single constant threshold
+ if (C_PROG_EMPTY_TYPE == 1) begin
+ if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL+1)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL)
+ && WR_EN && !RD_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+ //Dual constant thresholds
+ end else if (C_PROG_EMPTY_TYPE == 2) begin
+ if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL+1)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == C_PROG_EMPTY_THRESH_NEGATE_VAL)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+
+ //Single input threshold
+ end else if (C_PROG_EMPTY_TYPE == 3) begin
+ if ((num_read_words == PROG_EMPTY_THRESH+1)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == PROG_EMPTY_THRESH)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end else if (num_read_words <= PROG_EMPTY_THRESH) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if (num_read_words > PROG_EMPTY_THRESH)begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+
+ //Dual input thresholds
+ end else begin
+ if (num_read_words <= PROG_EMPTY_THRESH_ASSERT) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == PROG_EMPTY_THRESH_ASSERT+1)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if (num_read_words > PROG_EMPTY_THRESH_NEGATE)begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end else if ((num_read_words == PROG_EMPTY_THRESH_NEGATE)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+ end
+ end // (~ (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) )
+
+ //calculation for FWFT fifo
+ if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin
+ //Single constant threshold
+ if (C_PROG_EMPTY_TYPE == 1) begin
+ if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL+1 - 2)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL - 2)
+ && WR_EN && !RD_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+ //Dual constant thresholds
+ end else if (C_PROG_EMPTY_TYPE == 2) begin
+ if ((num_read_words == C_PROG_EMPTY_THRESH_ASSERT_VAL+1 - 2)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == C_PROG_EMPTY_THRESH_NEGATE_VAL - 2)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+
+ //Single input threshold
+ end else if (C_PROG_EMPTY_TYPE == 3) begin
+ if ((num_read_words == PROG_EMPTY_THRESH+1 - 2)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == PROG_EMPTY_THRESH - 2)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end else if (num_read_words <= PROG_EMPTY_THRESH - 2) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if (num_read_words > PROG_EMPTY_THRESH - 2)begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+
+ //Dual input thresholds
+ end else begin
+ if (num_read_words <= PROG_EMPTY_THRESH_ASSERT - 2) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if ((num_read_words == PROG_EMPTY_THRESH_ASSERT+1 - 2)
+ && RD_EN && !WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b1;
+ end else if (num_read_words > PROG_EMPTY_THRESH_NEGATE - 2)begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end else if ((num_read_words == PROG_EMPTY_THRESH_NEGATE - 2)
+ && !RD_EN && WR_EN) begin
+ prog_empty_d <= #`TCQ 1'b0;
+ end
+ end
+ end // (~ (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) )
+
+ ideal_prog_empty <= prog_empty_d;
+ if (RST_FULL_GEN) begin
+ ideal_prog_full <= #`TCQ 1'b0;
+ prog_full_d <= #`TCQ 1'b0;
+ end else begin
+ ideal_prog_full <= #`TCQ prog_full_d;
+ end
+
+ end //if (srst_i) begin
+ end //if (rst_i) begin
+ end //always @(posedge CLK or posedge rst_i) begin : gen_fifo_p
+endmodule // fifo_generator_v6_1_bhv_ver_ss
+
+
+
+/**************************************************************************
+ * First-Word Fall-Through module (preload 0)
+ **************************************************************************/
+module fifo_generator_v6_1_bhv_ver_preload0
+ (
+ RD_CLK,
+ RD_RST,
+ SRST,
+ RD_EN,
+ FIFOEMPTY,
+ FIFODATA,
+ FIFOSBITERR,
+ FIFODBITERR,
+ USERDATA,
+ USERVALID,
+ USERUNDERFLOW,
+ USEREMPTY,
+ USERALMOSTEMPTY,
+ RAMVALID,
+ FIFORDEN,
+ USERSBITERR,
+ USERDBITERR
+ );
+
+ parameter C_DOUT_RST_VAL = "";
+ parameter C_DOUT_WIDTH = 8;
+ parameter C_HAS_RST = 0;
+ parameter C_ENABLE_RST_SYNC = 0;
+ parameter C_HAS_SRST = 0;
+ parameter C_USE_DOUT_RST = 0;
+ parameter C_USE_ECC = 0;
+ parameter C_USERVALID_LOW = 0;
+ parameter C_USERUNDERFLOW_LOW = 0;
+ parameter C_MEMORY_TYPE = 0;
+
+ //Inputs
+ input RD_CLK;
+ input RD_RST;
+ input SRST;
+ input RD_EN;
+ input FIFOEMPTY;
+ input [C_DOUT_WIDTH-1:0] FIFODATA;
+ input FIFOSBITERR;
+ input FIFODBITERR;
+
+ //Outputs
+ output [C_DOUT_WIDTH-1:0] USERDATA;
+ output USERVALID;
+ output USERUNDERFLOW;
+ output USEREMPTY;
+ output USERALMOSTEMPTY;
+ output RAMVALID;
+ output FIFORDEN;
+ output USERSBITERR;
+ output USERDBITERR;
+
+ //Inputs
+ wire RD_CLK;
+ wire RD_RST;
+ wire RD_EN;
+ wire FIFOEMPTY;
+ wire [C_DOUT_WIDTH-1:0] FIFODATA;
+ wire FIFOSBITERR;
+ wire FIFODBITERR;
+
+ //Outputs
+ reg [C_DOUT_WIDTH-1:0] USERDATA;
+ wire USERVALID;
+ wire USERUNDERFLOW;
+ wire USEREMPTY;
+ wire USERALMOSTEMPTY;
+ wire RAMVALID;
+ wire FIFORDEN;
+ reg USERSBITERR;
+ reg USERDBITERR;
+
+ //Internal signals
+ wire preloadstage1;
+ wire preloadstage2;
+ reg ram_valid_i;
+ reg read_data_valid_i;
+ wire ram_regout_en;
+ wire ram_rd_en;
+ reg empty_i = 1'b1;
+ reg empty_q = 1'b1;
+ reg rd_en_q = 1'b0;
+ reg almost_empty_i = 1'b1;
+ reg almost_empty_q = 1'b1;
+ wire rd_rst_i;
+ wire srst_i;
+
+
+/*************************************************************************
+* FUNCTIONS
+*************************************************************************/
+
+ /*************************************************************************
+ * hexstr_conv
+ * Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
+ ***********************************************************************/
+ function [C_DOUT_WIDTH-1:0] hexstr_conv;
+ input [(C_DOUT_WIDTH*8)-1:0] def_data;
+
+ integer index,i,j;
+ reg [3:0] bin;
+
+ begin
+ index = 0;
+ hexstr_conv = 'b0;
+ for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 )
+ begin
+ case (def_data[7:0])
+ 8'b00000000 :
+ begin
+ bin = 4'b0000;
+ i = -1;
+ end
+ 8'b00110000 : bin = 4'b0000;
+ 8'b00110001 : bin = 4'b0001;
+ 8'b00110010 : bin = 4'b0010;
+ 8'b00110011 : bin = 4'b0011;
+ 8'b00110100 : bin = 4'b0100;
+ 8'b00110101 : bin = 4'b0101;
+ 8'b00110110 : bin = 4'b0110;
+ 8'b00110111 : bin = 4'b0111;
+ 8'b00111000 : bin = 4'b1000;
+ 8'b00111001 : bin = 4'b1001;
+ 8'b01000001 : bin = 4'b1010;
+ 8'b01000010 : bin = 4'b1011;
+ 8'b01000011 : bin = 4'b1100;
+ 8'b01000100 : bin = 4'b1101;
+ 8'b01000101 : bin = 4'b1110;
+ 8'b01000110 : bin = 4'b1111;
+ 8'b01100001 : bin = 4'b1010;
+ 8'b01100010 : bin = 4'b1011;
+ 8'b01100011 : bin = 4'b1100;
+ 8'b01100100 : bin = 4'b1101;
+ 8'b01100101 : bin = 4'b1110;
+ 8'b01100110 : bin = 4'b1111;
+ default :
+ begin
+ bin = 4'bx;
+ end
+ endcase
+ for( j=0; j<4; j=j+1)
+ begin
+ if ((index*4)+j < C_DOUT_WIDTH)
+ begin
+ hexstr_conv[(index*4)+j] = bin[j];
+ end
+ end
+ index = index + 1;
+ def_data = def_data >> 8;
+ end
+ end
+ endfunction
+
+
+ //*************************************************************************
+ // Set power-on states for regs
+ //*************************************************************************
+ initial begin
+ ram_valid_i = 1'b0;
+ read_data_valid_i = 1'b0;
+ USERDATA = hexstr_conv(C_DOUT_RST_VAL);
+ USERSBITERR = 1'b0;
+ USERDBITERR = 1'b0;
+ end //initial
+
+ //***************************************************************************
+ // connect up optional reset
+ //***************************************************************************
+ assign rd_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? RD_RST : 0;
+ assign srst_i = C_HAS_SRST ? SRST : 0;
+
+
+ //***************************************************************************
+ // preloadstage2 indicates that stage2 needs to be updated. This is true
+ // whenever read_data_valid is false, and RAM_valid is true.
+ //***************************************************************************
+ assign preloadstage2 = ram_valid_i & (~read_data_valid_i | RD_EN);
+
+ //***************************************************************************
+ // preloadstage1 indicates that stage1 needs to be updated. This is true
+ // whenever the RAM has data (RAM_EMPTY is false), and either RAM_Valid is
+ // false (indicating that Stage1 needs updating), or preloadstage2 is active
+ // (indicating that Stage2 is going to update, so Stage1, therefore, must
+ // also be updated to keep it valid.
+ //***************************************************************************
+ assign preloadstage1 = ((~ram_valid_i | preloadstage2) & ~FIFOEMPTY);
+
+ //***************************************************************************
+ // Calculate RAM_REGOUT_EN
+ // The output registers are controlled by the ram_regout_en signal.
+ // These registers should be updated either when the output in Stage2 is
+ // invalid (preloadstage2), OR when the user is reading, in which case the
+ // Stage2 value will go invalid unless it is replenished.
+ //***************************************************************************
+ assign ram_regout_en = preloadstage2;
+
+ //***************************************************************************
+ // Calculate RAM_RD_EN
+ // RAM_RD_EN will be asserted whenever the RAM needs to be read in order to
+ // update the value in Stage1.
+ // One case when this happens is when preloadstage1=true, which indicates
+ // that the data in Stage1 or Stage2 is invalid, and needs to automatically
+ // be updated.
+ // The other case is when the user is reading from the FIFO, which
+ // guarantees that Stage1 or Stage2 will be invalid on the next clock
+ // cycle, unless it is replinished by data from the memory. So, as long
+ // as the RAM has data in it, a read of the RAM should occur.
+ //***************************************************************************
+ assign ram_rd_en = (RD_EN & ~FIFOEMPTY) | preloadstage1;
+
+ //***************************************************************************
+ // Calculate RAMVALID_P0_OUT
+ // RAMVALID_P0_OUT indicates that the data in Stage1 is valid.
+ //
+ // If the RAM is being read from on this clock cycle (ram_rd_en=1), then
+ // RAMVALID_P0_OUT is certainly going to be true.
+ // If the RAM is not being read from, but the output registers are being
+ // updated to fill Stage2 (ram_regout_en=1), then Stage1 will be emptying,
+ // therefore causing RAMVALID_P0_OUT to be false.
+ // Otherwise, RAMVALID_P0_OUT will remain unchanged.
+ //***************************************************************************
+ // PROCESS regout_valid
+ always @ (posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i) begin
+ // asynchronous reset (active high)
+ ram_valid_i <= #`TCQ 1'b0;
+ end else begin
+ if (srst_i) begin
+ // synchronous reset (active high)
+ ram_valid_i <= #`TCQ 1'b0;
+ end else begin
+ if (ram_rd_en == 1'b1) begin
+ ram_valid_i <= #`TCQ 1'b1;
+ end else begin
+ if (ram_regout_en == 1'b1)
+ ram_valid_i <= #`TCQ 1'b0;
+ else
+ ram_valid_i <= #`TCQ ram_valid_i;
+ end
+ end //srst_i
+ end //rd_rst_i
+ end //always
+
+ //***************************************************************************
+ // Calculate READ_DATA_VALID
+ // READ_DATA_VALID indicates whether the value in Stage2 is valid or not.
+ // Stage2 has valid data whenever Stage1 had valid data and
+ // ram_regout_en_i=1, such that the data in Stage1 is propogated
+ // into Stage2.
+ //***************************************************************************
+ always @ (posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i)
+ read_data_valid_i <= #`TCQ 1'b0;
+ else if (srst_i)
+ read_data_valid_i <= #`TCQ 1'b0;
+ else
+ read_data_valid_i <= #`TCQ ram_valid_i | (read_data_valid_i & ~RD_EN);
+ end //always
+
+
+ //**************************************************************************
+ // Calculate EMPTY
+ // Defined as the inverse of READ_DATA_VALID
+ //
+ // Description:
+ //
+ // If read_data_valid_i indicates that the output is not valid,
+ // and there is no valid data on the output of the ram to preload it
+ // with, then we will report empty.
+ //
+ // If there is no valid data on the output of the ram and we are
+ // reading, then the FIFO will go empty.
+ //
+ //**************************************************************************
+ always @ (posedge RD_CLK or posedge rd_rst_i) begin
+ if (rd_rst_i) begin
+ // asynchronous reset (active high)
+ empty_i <= #`TCQ 1'b1;
+ end else begin
+ if (srst_i) begin
+ // synchronous reset (active high)
+ empty_i <= #`TCQ 1'b1;
+ end else begin
+ // rising clock edge
+ empty_i <= #`TCQ (~ram_valid_i & ~read_data_valid_i) | (~ram_valid_i & RD_EN);
+ end
+ end
+ end //always
+
+ // Register RD_EN from user to calculate USERUNDERFLOW.
+ // Register empty_i to calculate USERUNDERFLOW.
+ always @ (posedge RD_CLK) begin
+ rd_en_q <= #`TCQ RD_EN;
+ empty_q <= #`TCQ empty_i;
+ end //always
+
+
+ //***************************************************************************
+ // Calculate user_almost_empty
+ // user_almost_empty is defined such that, unless more words are written
+ // to the FIFO, the next read will cause the FIFO to go EMPTY.
+ //
+ // In most cases, whenever the output registers are updated (due to a user
+ // read or a preload condition), then user_almost_empty will update to
+ // whatever RAM_EMPTY is.
+ //
+ // The exception is when the output is valid, the user is not reading, and
+ // Stage1 is not empty. In this condition, Stage1 will be preloaded from the
+ // memory, so we need to make sure user_almost_empty deasserts properly under
+ // this condition.
+ //***************************************************************************
+ always @ (posedge RD_CLK or posedge rd_rst_i)
+ begin
+ if (rd_rst_i) begin // asynchronous reset (active high)
+ almost_empty_i <= #`TCQ 1'b1;
+ almost_empty_q <= #`TCQ 1'b1;
+ end else begin // rising clock edge
+ if (srst_i) begin // synchronous reset (active high)
+ almost_empty_i <= #`TCQ 1'b1;
+ almost_empty_q <= #`TCQ 1'b1;
+ end else begin
+ if ((ram_regout_en) | (~FIFOEMPTY & read_data_valid_i & ~RD_EN)) begin
+ almost_empty_i <= #`TCQ FIFOEMPTY;
+ end
+ almost_empty_q <= #`TCQ empty_i;
+ end
+ end
+ end //always
+
+
+ assign USEREMPTY = empty_i;
+ assign USERALMOSTEMPTY = almost_empty_i;
+ assign FIFORDEN = ram_rd_en;
+ assign RAMVALID = ram_valid_i;
+ assign USERVALID = C_USERVALID_LOW ? ~read_data_valid_i : read_data_valid_i;
+ assign USERUNDERFLOW = C_USERUNDERFLOW_LOW ? ~(empty_q & rd_en_q) : empty_q & rd_en_q;
+
+ // BRAM resets synchronously
+ always @ (posedge RD_CLK)
+ begin
+ if (rd_rst_i || srst_i) begin
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2)
+ USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
+ end
+ end //always
+
+
+ always @ (posedge RD_CLK or posedge rd_rst_i)
+ begin
+ if (rd_rst_i) begin //asynchronous reset (active high)
+ if (C_USE_ECC == 0) begin // Reset S/DBITERR only if ECC is OFF
+ USERSBITERR <= #`TCQ 0;
+ USERDBITERR <= #`TCQ 0;
+ end
+ // DRAM resets asynchronously
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2) //asynchronous reset (active high)
+ USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
+ end else begin // rising clock edge
+ if (srst_i) begin
+ if (C_USE_ECC == 0) begin // Reset S/DBITERR only if ECC is OFF
+ USERSBITERR <= #`TCQ 0;
+ USERDBITERR <= #`TCQ 0;
+ end
+ if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2)
+ USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
+ end else begin
+ if (ram_regout_en) begin
+ USERDATA <= #`TCQ FIFODATA;
+ USERSBITERR <= #`TCQ FIFOSBITERR;
+ USERDBITERR <= #`TCQ FIFODBITERR;
+ end
+ end
+ end
+ end //always
+
+endmodule
+
diff --git a/fpga/usrp2/models/M24LC024B.v b/fpga/usrp2/models/M24LC024B.v
index 45e04b450..5531f80fc 100644
--- a/fpga/usrp2/models/M24LC024B.v
+++ b/fpga/usrp2/models/M24LC024B.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Modified 11/14/07 to simulate the 24lc024, which responds to the address pins
// *******************************************************************************************************
diff --git a/fpga/usrp2/models/M24LC02B.v b/fpga/usrp2/models/M24LC02B.v
index 4d9e2c6e2..00ed6f44a 100644
--- a/fpga/usrp2/models/M24LC02B.v
+++ b/fpga/usrp2/models/M24LC02B.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// *******************************************************************************************************
// ** **
// ** M24LC02B.v - 24LC02B 2K-BIT I2C SERIAL EEPROM (VCC = +2.5V TO +5.5V) **
diff --git a/fpga/usrp2/models/MULT18X18S.v b/fpga/usrp2/models/MULT18X18S.v
index 5d39eeaa6..3ce2a267a 100644
--- a/fpga/usrp2/models/MULT18X18S.v
+++ b/fpga/usrp2/models/MULT18X18S.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Model of the Xilinx mult18x18s for signed 18x18 bit multiplies,
// As in the Spartan 3 series
diff --git a/fpga/usrp2/models/adc_model.v b/fpga/usrp2/models/adc_model.v
index e5a3ee0d8..1d1f1c929 100644
--- a/fpga/usrp2/models/adc_model.v
+++ b/fpga/usrp2/models/adc_model.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module adc_model
(input clk, input rst,
diff --git a/fpga/usrp2/models/cpld_model.v b/fpga/usrp2/models/cpld_model.v
index c886433ae..900577852 100644
--- a/fpga/usrp2/models/cpld_model.v
+++ b/fpga/usrp2/models/cpld_model.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module cpld_model
(input aux_clk, input start, input mode, input done,
diff --git a/fpga/usrp2/models/gpmc_model_async.v b/fpga/usrp2/models/gpmc_model_async.v
index beeaee028..22b3cdf9f 100644
--- a/fpga/usrp2/models/gpmc_model_async.v
+++ b/fpga/usrp2/models/gpmc_model_async.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ps/1ps
module gpmc_model_async
diff --git a/fpga/usrp2/models/gpmc_model_sync.v b/fpga/usrp2/models/gpmc_model_sync.v
index 641720c15..0f66961e7 100644
--- a/fpga/usrp2/models/gpmc_model_sync.v
+++ b/fpga/usrp2/models/gpmc_model_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module gpmc_model_sync
diff --git a/fpga/usrp2/models/math_real.v b/fpga/usrp2/models/math_real.v
index e30f68ee7..d88f72669 100644
--- a/fpga/usrp2/models/math_real.v
+++ b/fpga/usrp2/models/math_real.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
/*
* This is a general recreation of the VHDL ieee.math_real package.
*/
diff --git a/fpga/usrp2/models/miim_model.v b/fpga/usrp2/models/miim_model.v
index 936d99a80..8eb8e571d 100644
--- a/fpga/usrp2/models/miim_model.v
+++ b/fpga/usrp2/models/miim_model.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Skeleton PHY interface simulator
diff --git a/fpga/usrp2/models/serdes_model.v b/fpga/usrp2/models/serdes_model.v
index f10e55554..5e1602163 100644
--- a/fpga/usrp2/models/serdes_model.v
+++ b/fpga/usrp2/models/serdes_model.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module serdes_model
(input ser_tx_clk,
diff --git a/fpga/usrp2/models/uart_rx.v b/fpga/usrp2/models/uart_rx.v
index f698a50fe..738ffb45b 100644
--- a/fpga/usrp2/models/uart_rx.v
+++ b/fpga/usrp2/models/uart_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Simple printout of characters from the UART
diff --git a/fpga/usrp2/models/xlnx_glbl.v b/fpga/usrp2/models/xlnx_glbl.v
index 662a60e35..62e29fef4 100644
--- a/fpga/usrp2/models/xlnx_glbl.v
+++ b/fpga/usrp2/models/xlnx_glbl.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module xlnx_glbl
(
GSR,
diff --git a/fpga/usrp2/sdr_lib/acc.v b/fpga/usrp2/sdr_lib/acc.v
index a2da9c86d..d5fc4b910 100644
--- a/fpga/usrp2/sdr_lib/acc.v
+++ b/fpga/usrp2/sdr_lib/acc.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module acc
#(parameter IWIDTH=16, OWIDTH=30)
diff --git a/fpga/usrp2/sdr_lib/add2.v b/fpga/usrp2/sdr_lib/add2.v
index 13fff803e..dcca84fd3 100644
--- a/fpga/usrp2/sdr_lib/add2.v
+++ b/fpga/usrp2/sdr_lib/add2.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module add2
#(parameter WIDTH=16)
diff --git a/fpga/usrp2/sdr_lib/add2_and_round.v b/fpga/usrp2/sdr_lib/add2_and_round.v
index 146af28da..7c347527c 100644
--- a/fpga/usrp2/sdr_lib/add2_and_round.v
+++ b/fpga/usrp2/sdr_lib/add2_and_round.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module add2_and_round
#(parameter WIDTH=16)
diff --git a/fpga/usrp2/sdr_lib/add2_and_round_reg.v b/fpga/usrp2/sdr_lib/add2_and_round_reg.v
index e7fcbf1a1..5c783bda3 100644
--- a/fpga/usrp2/sdr_lib/add2_and_round_reg.v
+++ b/fpga/usrp2/sdr_lib/add2_and_round_reg.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module add2_and_round_reg
#(parameter WIDTH=16)
diff --git a/fpga/usrp2/sdr_lib/add2_reg.v b/fpga/usrp2/sdr_lib/add2_reg.v
index 456cf315b..58d822a61 100644
--- a/fpga/usrp2/sdr_lib/add2_reg.v
+++ b/fpga/usrp2/sdr_lib/add2_reg.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module add2_reg
#(parameter WIDTH=16)
diff --git a/fpga/usrp2/sdr_lib/dsp_core_rx.v b/fpga/usrp2/sdr_lib/dsp_core_rx.v
index a315234cf..0e69e53f7 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_rx.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module dsp_core_rx
#(parameter BASE = 160)
diff --git a/fpga/usrp2/sdr_lib/dsp_core_rx_old.v b/fpga/usrp2/sdr_lib/dsp_core_rx_old.v
index ba301e91b..90d5d839f 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_rx_old.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_rx_old.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`define DSP_CORE_RX_BASE 160
module dsp_core_rx_old
diff --git a/fpga/usrp2/sdr_lib/dsp_core_rx_udp.v b/fpga/usrp2/sdr_lib/dsp_core_rx_udp.v
index 1e689fc7f..08dab37e6 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_rx_udp.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_rx_udp.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module dsp_core_rx
#(parameter BASE = 160)
diff --git a/fpga/usrp2/sdr_lib/dsp_core_tx.v b/fpga/usrp2/sdr_lib/dsp_core_tx.v
index 79d92c9b3..58bd82f6e 100644
--- a/fpga/usrp2/sdr_lib/dsp_core_tx.v
+++ b/fpga/usrp2/sdr_lib/dsp_core_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module dsp_core_tx
#(parameter BASE=0)
diff --git a/fpga/usrp2/sdr_lib/dummy_rx.v b/fpga/usrp2/sdr_lib/dummy_rx.v
index 99290ecec..b22d5f896 100644
--- a/fpga/usrp2/sdr_lib/dummy_rx.v
+++ b/fpga/usrp2/sdr_lib/dummy_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`define DSP_CORE_RX_BASE 160
module dummy_rx
diff --git a/fpga/usrp2/sdr_lib/halfband_ideal.v b/fpga/usrp2/sdr_lib/halfband_ideal.v
index 484cfff2a..e0b04cf86 100644
--- a/fpga/usrp2/sdr_lib/halfband_ideal.v
+++ b/fpga/usrp2/sdr_lib/halfband_ideal.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module halfband_ideal (
input clock,
input reset,
diff --git a/fpga/usrp2/sdr_lib/halfband_tb.v b/fpga/usrp2/sdr_lib/halfband_tb.v
index 231dd00d7..80f46fe36 100644
--- a/fpga/usrp2/sdr_lib/halfband_tb.v
+++ b/fpga/usrp2/sdr_lib/halfband_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module halfband_tb( ) ;
// Parameters for instantiation
diff --git a/fpga/usrp2/sdr_lib/hb/acc.v b/fpga/usrp2/sdr_lib/hb/acc.v
index 195d5ea94..d7be895c6 100644
--- a/fpga/usrp2/sdr_lib/hb/acc.v
+++ b/fpga/usrp2/sdr_lib/hb/acc.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module acc (input clock, input reset, input clear, input enable_in, output reg enable_out,
diff --git a/fpga/usrp2/sdr_lib/hb/coeff_ram.v b/fpga/usrp2/sdr_lib/hb/coeff_ram.v
index 65460822f..525c22abc 100644
--- a/fpga/usrp2/sdr_lib/hb/coeff_ram.v
+++ b/fpga/usrp2/sdr_lib/hb/coeff_ram.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module coeff_ram (input clock, input [3:0] rd_addr, output reg [15:0] rd_data);
diff --git a/fpga/usrp2/sdr_lib/hb/coeff_rom.v b/fpga/usrp2/sdr_lib/hb/coeff_rom.v
index 7f8886b4e..a43c8391a 100644
--- a/fpga/usrp2/sdr_lib/hb/coeff_rom.v
+++ b/fpga/usrp2/sdr_lib/hb/coeff_rom.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module coeff_rom (input clock, input [2:0] addr, output reg [15:0] data);
diff --git a/fpga/usrp2/sdr_lib/hb/halfband_interp.v b/fpga/usrp2/sdr_lib/hb/halfband_interp.v
index cdb11c1f6..83bdc9fad 100644
--- a/fpga/usrp2/sdr_lib/hb/halfband_interp.v
+++ b/fpga/usrp2/sdr_lib/hb/halfband_interp.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module halfband_interp
diff --git a/fpga/usrp2/sdr_lib/hb/hbd_tb/test_hbd.v b/fpga/usrp2/sdr_lib/hb/hbd_tb/test_hbd.v
index 01ab5e7e0..450f90e66 100644
--- a/fpga/usrp2/sdr_lib/hb/hbd_tb/test_hbd.v
+++ b/fpga/usrp2/sdr_lib/hb/hbd_tb/test_hbd.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module test_hbd();
diff --git a/fpga/usrp2/sdr_lib/hb/mac.v b/fpga/usrp2/sdr_lib/hb/mac.v
index 5a270bc73..8058a6db4 100644
--- a/fpga/usrp2/sdr_lib/hb/mac.v
+++ b/fpga/usrp2/sdr_lib/hb/mac.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module mac (input clock, input reset, input enable, input clear,
diff --git a/fpga/usrp2/sdr_lib/hb/mult.v b/fpga/usrp2/sdr_lib/hb/mult.v
index a8d4cb1b7..a50ae69e2 100644
--- a/fpga/usrp2/sdr_lib/hb/mult.v
+++ b/fpga/usrp2/sdr_lib/hb/mult.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module mult (input clock, input signed [15:0] x, input signed [15:0] y, output reg signed [30:0] product,
diff --git a/fpga/usrp2/sdr_lib/hb/ram16_2port.v b/fpga/usrp2/sdr_lib/hb/ram16_2port.v
index e1761a926..631cf5a41 100644
--- a/fpga/usrp2/sdr_lib/hb/ram16_2port.v
+++ b/fpga/usrp2/sdr_lib/hb/ram16_2port.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram16_2port (input clock, input write,
diff --git a/fpga/usrp2/sdr_lib/hb/ram16_2sum.v b/fpga/usrp2/sdr_lib/hb/ram16_2sum.v
index 559b06fd5..f9ec1837e 100644
--- a/fpga/usrp2/sdr_lib/hb/ram16_2sum.v
+++ b/fpga/usrp2/sdr_lib/hb/ram16_2sum.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram16_2sum (input clock, input write,
diff --git a/fpga/usrp2/sdr_lib/hb/ram32_2sum.v b/fpga/usrp2/sdr_lib/hb/ram32_2sum.v
index d1f55b7d0..f7032835e 100644
--- a/fpga/usrp2/sdr_lib/hb/ram32_2sum.v
+++ b/fpga/usrp2/sdr_lib/hb/ram32_2sum.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ram32_2sum (input clock, input write,
diff --git a/fpga/usrp2/sdr_lib/hb_dec.v b/fpga/usrp2/sdr_lib/hb_dec.v
index 8fb5ba222..9747f0adb 100644
--- a/fpga/usrp2/sdr_lib/hb_dec.v
+++ b/fpga/usrp2/sdr_lib/hb_dec.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Final halfband decimator
// Implements impulse responses of the form [A 0 B 0 C .. 0 H 0.5 H 0 .. C 0 B 0 A]
// Strobe in cannot come faster than every 2nd clock cycle
diff --git a/fpga/usrp2/sdr_lib/hb_dec_tb.v b/fpga/usrp2/sdr_lib/hb_dec_tb.v
index 3e5faa80a..256f6085d 100644
--- a/fpga/usrp2/sdr_lib/hb_dec_tb.v
+++ b/fpga/usrp2/sdr_lib/hb_dec_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module hb_dec_tb( ) ;
// Parameters for instantiation
diff --git a/fpga/usrp2/sdr_lib/hb_interp.v b/fpga/usrp2/sdr_lib/hb_interp.v
index d16807e15..deb4fe056 100644
--- a/fpga/usrp2/sdr_lib/hb_interp.v
+++ b/fpga/usrp2/sdr_lib/hb_interp.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// First halfband iterpolator
// Implements impulse responses of the form [A 0 B 0 C .. 0 H 0.5 H 0 .. C 0 B 0 A]
// Strobe in cannot come faster than every 4th clock cycle,
diff --git a/fpga/usrp2/sdr_lib/hb_interp_tb.v b/fpga/usrp2/sdr_lib/hb_interp_tb.v
index 52f137f28..239412155 100644
--- a/fpga/usrp2/sdr_lib/hb_interp_tb.v
+++ b/fpga/usrp2/sdr_lib/hb_interp_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module hb_interp_tb( ) ;
// Parameters for instantiation
diff --git a/fpga/usrp2/sdr_lib/hb_tb.v b/fpga/usrp2/sdr_lib/hb_tb.v
index 7e960fd13..3260ac738 100644
--- a/fpga/usrp2/sdr_lib/hb_tb.v
+++ b/fpga/usrp2/sdr_lib/hb_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module hb_tb();
diff --git a/fpga/usrp2/sdr_lib/integrate.v b/fpga/usrp2/sdr_lib/integrate.v
index db33de979..ce674d470 100644
--- a/fpga/usrp2/sdr_lib/integrate.v
+++ b/fpga/usrp2/sdr_lib/integrate.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module integrate
#(parameter INPUTW = 16,
parameter ACCUMW = 32,
diff --git a/fpga/usrp2/sdr_lib/med_hb_int.v b/fpga/usrp2/sdr_lib/med_hb_int.v
index bc8066509..f619dc81b 100644
--- a/fpga/usrp2/sdr_lib/med_hb_int.v
+++ b/fpga/usrp2/sdr_lib/med_hb_int.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Medium halfband decimator (intended to be followed by another stage)
// Implements impulse responses of the form [A 0 B 0 C 0 D 0.5 D 0 C 0 B 0 A]
//
diff --git a/fpga/usrp2/sdr_lib/rssi.v b/fpga/usrp2/sdr_lib/rssi.v
index e45e2148c..e931ff865 100644
--- a/fpga/usrp2/sdr_lib/rssi.v
+++ b/fpga/usrp2/sdr_lib/rssi.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module rssi (input clock, input reset, input enable,
diff --git a/fpga/usrp2/sdr_lib/rx_control.v b/fpga/usrp2/sdr_lib/rx_control.v
index 0adeb0794..12f411ffe 100644
--- a/fpga/usrp2/sdr_lib/rx_control.v
+++ b/fpga/usrp2/sdr_lib/rx_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`define DSP_CORE_RX_BASE 160
diff --git a/fpga/usrp2/sdr_lib/rx_dcoffset.v b/fpga/usrp2/sdr_lib/rx_dcoffset.v
index bedbd40e6..64ff4110d 100644
--- a/fpga/usrp2/sdr_lib/rx_dcoffset.v
+++ b/fpga/usrp2/sdr_lib/rx_dcoffset.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module rx_dcoffset
diff --git a/fpga/usrp2/sdr_lib/rx_dcoffset_tb.v b/fpga/usrp2/sdr_lib/rx_dcoffset_tb.v
index a8b4ec20f..b0dd8cb05 100644
--- a/fpga/usrp2/sdr_lib/rx_dcoffset_tb.v
+++ b/fpga/usrp2/sdr_lib/rx_dcoffset_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns/1ns
module rx_dcoffset_tb();
diff --git a/fpga/usrp2/sdr_lib/small_hb_dec.v b/fpga/usrp2/sdr_lib/small_hb_dec.v
index 8519b628a..151b8c287 100644
--- a/fpga/usrp2/sdr_lib/small_hb_dec.v
+++ b/fpga/usrp2/sdr_lib/small_hb_dec.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Short halfband decimator (intended to be followed by another stage)
// Implements impulse responses of the form [A 0 B 0.5 B 0 A]
//
diff --git a/fpga/usrp2/sdr_lib/small_hb_dec_tb.v b/fpga/usrp2/sdr_lib/small_hb_dec_tb.v
index 0d6a0689e..1e713321a 100644
--- a/fpga/usrp2/sdr_lib/small_hb_dec_tb.v
+++ b/fpga/usrp2/sdr_lib/small_hb_dec_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module hb_dec_tb( ) ;
// Parameters for instantiation
diff --git a/fpga/usrp2/sdr_lib/small_hb_int.v b/fpga/usrp2/sdr_lib/small_hb_int.v
index f80d3cac3..387f9e1cb 100644
--- a/fpga/usrp2/sdr_lib/small_hb_int.v
+++ b/fpga/usrp2/sdr_lib/small_hb_int.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Short halfband decimator (intended to be followed by another stage)
// Implements impulse responses of the form [A 0 B 0.5 B 0 A]
//
diff --git a/fpga/usrp2/sdr_lib/small_hb_int_tb.v b/fpga/usrp2/sdr_lib/small_hb_int_tb.v
index 71d77f0a8..fe1e1a7dd 100644
--- a/fpga/usrp2/sdr_lib/small_hb_int_tb.v
+++ b/fpga/usrp2/sdr_lib/small_hb_int_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module small_hb_int_tb( ) ;
// Parameters for instantiation
diff --git a/fpga/usrp2/sdr_lib/tx_control.v b/fpga/usrp2/sdr_lib/tx_control.v
index e5fed0b93..e6866a40c 100644
--- a/fpga/usrp2/sdr_lib/tx_control.v
+++ b/fpga/usrp2/sdr_lib/tx_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`define DSP_CORE_TX_BASE 128
diff --git a/fpga/usrp2/serdes/serdes.v b/fpga/usrp2/serdes/serdes.v
index 17049bfe6..edbc46419 100644
--- a/fpga/usrp2/serdes/serdes.v
+++ b/fpga/usrp2/serdes/serdes.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// SERDES TX and RX along with all flow control logic
diff --git a/fpga/usrp2/serdes/serdes_fc_rx.v b/fpga/usrp2/serdes/serdes_fc_rx.v
index 4dd46e27f..9ea32cf8d 100644
--- a/fpga/usrp2/serdes/serdes_fc_rx.v
+++ b/fpga/usrp2/serdes/serdes_fc_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module serdes_fc_rx
diff --git a/fpga/usrp2/serdes/serdes_fc_tx.v b/fpga/usrp2/serdes/serdes_fc_tx.v
index 2fe967c8d..0a62ae2e5 100644
--- a/fpga/usrp2/serdes/serdes_fc_tx.v
+++ b/fpga/usrp2/serdes/serdes_fc_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module serdes_fc_tx
diff --git a/fpga/usrp2/serdes/serdes_rx.v b/fpga/usrp2/serdes/serdes_rx.v
index b6688e858..1950d4e2a 100644
--- a/fpga/usrp2/serdes/serdes_rx.v
+++ b/fpga/usrp2/serdes/serdes_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// SERDES Interface
diff --git a/fpga/usrp2/serdes/serdes_tb.v b/fpga/usrp2/serdes/serdes_tb.v
index eb8e019fc..685a8580d 100644
--- a/fpga/usrp2/serdes/serdes_tb.v
+++ b/fpga/usrp2/serdes/serdes_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// FIXME need to add flow control
diff --git a/fpga/usrp2/serdes/serdes_tx.v b/fpga/usrp2/serdes/serdes_tx.v
index 2e5e3bd80..0cd077e5c 100644
--- a/fpga/usrp2/serdes/serdes_tx.v
+++ b/fpga/usrp2/serdes/serdes_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// SERDES Interface
diff --git a/fpga/usrp2/simple_gemac/address_filter.v b/fpga/usrp2/simple_gemac/address_filter.v
index 50a52b954..bf6194600 100644
--- a/fpga/usrp2/simple_gemac/address_filter.v
+++ b/fpga/usrp2/simple_gemac/address_filter.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module address_filter
diff --git a/fpga/usrp2/simple_gemac/address_filter_promisc.v b/fpga/usrp2/simple_gemac/address_filter_promisc.v
index 6047e7c93..3ff05fbe1 100644
--- a/fpga/usrp2/simple_gemac/address_filter_promisc.v
+++ b/fpga/usrp2/simple_gemac/address_filter_promisc.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module address_filter_promisc
diff --git a/fpga/usrp2/simple_gemac/crc.v b/fpga/usrp2/simple_gemac/crc.v
index ac019083a..ef62f8ff8 100644
--- a/fpga/usrp2/simple_gemac/crc.v
+++ b/fpga/usrp2/simple_gemac/crc.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module crc
(input clk,
diff --git a/fpga/usrp2/simple_gemac/delay_line.v b/fpga/usrp2/simple_gemac/delay_line.v
index d371bb9c5..5a559a504 100644
--- a/fpga/usrp2/simple_gemac/delay_line.v
+++ b/fpga/usrp2/simple_gemac/delay_line.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module delay_line
diff --git a/fpga/usrp2/simple_gemac/eth_tasks.v b/fpga/usrp2/simple_gemac/eth_tasks.v
index d49f30e24..731fd6d52 100644
--- a/fpga/usrp2/simple_gemac/eth_tasks.v
+++ b/fpga/usrp2/simple_gemac/eth_tasks.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
task SendFlowCtrl;
diff --git a/fpga/usrp2/simple_gemac/eth_tasks_f19.v b/fpga/usrp2/simple_gemac/eth_tasks_f19.v
index ff3ae5407..3ff23a413 100644
--- a/fpga/usrp2/simple_gemac/eth_tasks_f19.v
+++ b/fpga/usrp2/simple_gemac/eth_tasks_f19.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
task SendFlowCtrl;
diff --git a/fpga/usrp2/simple_gemac/eth_tasks_f36.v b/fpga/usrp2/simple_gemac/eth_tasks_f36.v
index dc64971d4..dee651d80 100644
--- a/fpga/usrp2/simple_gemac/eth_tasks_f36.v
+++ b/fpga/usrp2/simple_gemac/eth_tasks_f36.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
task SendFlowCtrl;
diff --git a/fpga/usrp2/simple_gemac/ethrx_realign.v b/fpga/usrp2/simple_gemac/ethrx_realign.v
index 0a369c914..a08feb91e 100644
--- a/fpga/usrp2/simple_gemac/ethrx_realign.v
+++ b/fpga/usrp2/simple_gemac/ethrx_realign.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// NOTE: Will not work with single-line frames
diff --git a/fpga/usrp2/simple_gemac/ethtx_realign.v b/fpga/usrp2/simple_gemac/ethtx_realign.v
index be53abf4c..236b2d4e1 100644
--- a/fpga/usrp2/simple_gemac/ethtx_realign.v
+++ b/fpga/usrp2/simple_gemac/ethtx_realign.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
////////////////////////////////////////////////////////////////////////
// Ethernet TX - Realign
diff --git a/fpga/usrp2/simple_gemac/flow_ctrl_rx.v b/fpga/usrp2/simple_gemac/flow_ctrl_rx.v
index d09bf377f..aa12875f2 100644
--- a/fpga/usrp2/simple_gemac/flow_ctrl_rx.v
+++ b/fpga/usrp2/simple_gemac/flow_ctrl_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// RX side of flow control -- when we are running out of RX space, send a PAUSE
diff --git a/fpga/usrp2/simple_gemac/flow_ctrl_tx.v b/fpga/usrp2/simple_gemac/flow_ctrl_tx.v
index f80f5a76d..bdc1e4701 100644
--- a/fpga/usrp2/simple_gemac/flow_ctrl_tx.v
+++ b/fpga/usrp2/simple_gemac/flow_ctrl_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// TX side of flow control -- when other side sends PAUSE, we wait
diff --git a/fpga/usrp2/simple_gemac/ll8_to_txmac.v b/fpga/usrp2/simple_gemac/ll8_to_txmac.v
index 3530a0c59..ac81afa63 100644
--- a/fpga/usrp2/simple_gemac/ll8_to_txmac.v
+++ b/fpga/usrp2/simple_gemac/ll8_to_txmac.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module ll8_to_txmac
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/simple_gemac/rxmac_to_ll8.v b/fpga/usrp2/simple_gemac/rxmac_to_ll8.v
index 5ec233d95..5acb08bb7 100644
--- a/fpga/usrp2/simple_gemac/rxmac_to_ll8.v
+++ b/fpga/usrp2/simple_gemac/rxmac_to_ll8.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module rxmac_to_ll8
(input clk, input reset, input clear,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac.v b/fpga/usrp2/simple_gemac/simple_gemac.v
index 2dd8deb99..ec13d3c96 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac
(input clk125, input reset,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_rx.v b/fpga/usrp2/simple_gemac/simple_gemac_rx.v
index 32f517bb3..e6c0424bd 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_rx.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_rx
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_tb.v b/fpga/usrp2/simple_gemac/simple_gemac_tb.v
index 6091751a7..ed7d796dc 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_tb.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_tb;
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_tx.v b/fpga/usrp2/simple_gemac/simple_gemac_tx.v
index dd870d04d..ecabc3dad 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_tx.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_tx
(input clk125, input reset,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wb.v b/fpga/usrp2/simple_gemac/simple_gemac_wb.v
index 1ef38be11..bcf18f9a8 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wb.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module wb_reg
#(parameter ADDR=0,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
index 8390eb2c6..9763578b9 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_wrapper
#(parameter RXFIFOSIZE=9,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
index 2ac8b9be1..3e1793d82 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_wrapper19
#(parameter RXFIFOSIZE=9,
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v
index b61d60d30..78f525fd7 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_wrapper19_tb;
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper_f36_tb.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper_f36_tb.v
index 804fa8748..2904e38d4 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper_f36_tb.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper_f36_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_wrapper_f36_tb;
diff --git a/fpga/usrp2/simple_gemac/simple_gemac_wrapper_tb.v b/fpga/usrp2/simple_gemac/simple_gemac_wrapper_tb.v
index 0aadc7e93..5a3f3f832 100644
--- a/fpga/usrp2/simple_gemac/simple_gemac_wrapper_tb.v
+++ b/fpga/usrp2/simple_gemac/simple_gemac_wrapper_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_gemac_wrapper_tb;
diff --git a/fpga/usrp2/top/single_u2_sim/single_u2_sim.v b/fpga/usrp2/testbench/single_u2_sim.v
index 2a7b24849..f25374613 100644
--- a/fpga/usrp2/top/single_u2_sim/single_u2_sim.v
+++ b/fpga/usrp2/testbench/single_u2_sim.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/timing/simple_timer.v b/fpga/usrp2/timing/simple_timer.v
index 17c7f1c36..56ba8ffe8 100644
--- a/fpga/usrp2/timing/simple_timer.v
+++ b/fpga/usrp2/timing/simple_timer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module simple_timer
diff --git a/fpga/usrp2/timing/time_64bit.v b/fpga/usrp2/timing/time_64bit.v
index 8122cc6ea..d32f4220b 100644
--- a/fpga/usrp2/timing/time_64bit.v
+++ b/fpga/usrp2/timing/time_64bit.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module time_64bit
diff --git a/fpga/usrp2/timing/time_compare.v b/fpga/usrp2/timing/time_compare.v
index cb2b6d860..54ea000d6 100644
--- a/fpga/usrp2/timing/time_compare.v
+++ b/fpga/usrp2/timing/time_compare.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Top 32 bits are integer seconds, bottom 32 are clock ticks within a second
diff --git a/fpga/usrp2/timing/time_receiver.v b/fpga/usrp2/timing/time_receiver.v
index 897f71186..a03337552 100644
--- a/fpga/usrp2/timing/time_receiver.v
+++ b/fpga/usrp2/timing/time_receiver.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module time_receiver
(input clk, input rst,
diff --git a/fpga/usrp2/timing/time_sender.v b/fpga/usrp2/timing/time_sender.v
index f4ee5226a..fdf6b1240 100644
--- a/fpga/usrp2/timing/time_sender.v
+++ b/fpga/usrp2/timing/time_sender.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module time_sender
diff --git a/fpga/usrp2/timing/time_sync.v b/fpga/usrp2/timing/time_sync.v
index c0c8e195f..a823e9e1b 100644
--- a/fpga/usrp2/timing/time_sync.v
+++ b/fpga/usrp2/timing/time_sync.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module time_sync
diff --git a/fpga/usrp2/timing/time_transfer_tb.v b/fpga/usrp2/timing/time_transfer_tb.v
index 0c164f82c..288540702 100644
--- a/fpga/usrp2/timing/time_transfer_tb.v
+++ b/fpga/usrp2/timing/time_transfer_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
diff --git a/fpga/usrp2/timing/timer.v b/fpga/usrp2/timing/timer.v
index 70c9746be..216a9294c 100644
--- a/fpga/usrp2/timing/timer.v
+++ b/fpga/usrp2/timing/timer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module timer
diff --git a/fpga/usrp2/top/u1e_passthru/.gitignore b/fpga/usrp2/top/B100/.gitignore
index 1b2211df0..1b2211df0 100644
--- a/fpga/usrp2/top/u1e_passthru/.gitignore
+++ b/fpga/usrp2/top/B100/.gitignore
diff --git a/fpga/usrp2/top/B100/Makefile b/fpga/usrp2/top/B100/Makefile
new file mode 100644
index 000000000..ca6ec9320
--- /dev/null
+++ b/fpga/usrp2/top/B100/Makefile
@@ -0,0 +1,97 @@
+#
+# Copyright 2008 Ettus Research LLC
+#
+
+##################################################
+# Project Setup
+##################################################
+BUILD_DIR := build/
+export TOP_MODULE := u1plus
+export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
+
+include ../Makefile.common
+include ../../fifo/Makefile.srcs
+include ../../control_lib/Makefile.srcs
+include ../../sdr_lib/Makefile.srcs
+include ../../serdes/Makefile.srcs
+include ../../simple_gemac/Makefile.srcs
+include ../../timing/Makefile.srcs
+include ../../opencores/Makefile.srcs
+include ../../vrt/Makefile.srcs
+include ../../udp/Makefile.srcs
+include ../../coregen/Makefile.srcs
+include ../../gpif/Makefile.srcs
+
+##################################################
+# Project Properties
+##################################################
+export PROJECT_PROPERTIES := \
+family "Spartan3A" \
+device XC3S1400A \
+package ft256 \
+speed -4 \
+top_level_module_type "HDL" \
+synthesis_tool "XST (VHDL/Verilog)" \
+simulator "ISE Simulator (VHDL/Verilog)" \
+"Preferred Language" "Verilog" \
+"Enable Message Filtering" FALSE \
+"Display Incremental Messages" FALSE
+
+##################################################
+# Sources
+##################################################
+TOP_SRCS = \
+u1plus.v \
+u1plus_core.v \
+u1plus.ucf \
+timing.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) \
+$(GPIF_SRCS)
+
+##################################################
+# Process Properties
+##################################################
+SYNTHESIZE_PROPERTIES = \
+"Number of Clock Buffers" 8 \
+"Pack I/O Registers into IOBs" Yes \
+"Optimization Effort" High \
+"Optimize Instantiated Primitives" TRUE \
+"Register Balancing" Yes \
+"Use Clock Enable" Auto \
+"Use Synchronous Reset" Auto \
+"Use Synchronous Set" Auto
+
+TRANSLATE_PROPERTIES = \
+"Macro Search Path" "$(shell pwd)/../../coregen/"
+
+MAP_PROPERTIES = \
+"Allow Logic Optimization Across Hierarchy" TRUE \
+"Map to Input Functions" 4 \
+"Optimization Strategy (Cover Mode)" Speed \
+"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \
+"Perform Timing-Driven Packing and Placement" TRUE \
+"Map Effort Level" High \
+"Extra Effort" Normal \
+"Combinatorial Logic Optimization" TRUE \
+"Register Duplication" TRUE
+
+PLACE_ROUTE_PROPERTIES = \
+"Place & Route Effort Level (Overall)" High
+
+STATIC_TIMING_PROPERTIES = \
+"Number of Paths in Error/Verbose Report" 10 \
+"Report Type" "Error Report"
+
+GEN_PROG_FILE_PROPERTIES = \
+"Configuration Rate" 6 \
+"Create Binary Configuration File" TRUE \
+"Done (Output Events)" 5 \
+"Enable Bitstream Compression" TRUE \
+"Enable Outputs (Output Events)" 6 \
+"Unused IOB Pins" "Pull Up"
+
+SIM_MODEL_PROPERTIES = ""
diff --git a/fpga/usrp2/top/B100/core_compile b/fpga/usrp2/top/B100/core_compile
new file mode 100755
index 000000000..b2ccc8b49
--- /dev/null
+++ b/fpga/usrp2/top/B100/core_compile
@@ -0,0 +1 @@
+iverilog -Wall -y. -y ../../control_lib/ -y ../../fifo/ -y ../../gpif/ -y ../../models/ -y ../../sdr_lib/ -y ../../coregen/ -y ../../vrt/ -y ../../opencores/i2c/rtl/verilog/ -y ../../opencores/spi/rtl/verilog/ -y ../../timing/ -y ../../opencores/8b10b/ -I ../../opencores/spi/rtl/verilog/ -I ../../opencores/i2c/rtl/verilog/ -y ../../simple_gemac u1plus_core.v 2>&1 | grep -v timescale | grep -v coregen | grep -v models
diff --git a/fpga/usrp2/top/B100/timing.ucf b/fpga/usrp2/top/B100/timing.ucf
new file mode 100644
index 000000000..b2a455f6d
--- /dev/null
+++ b/fpga/usrp2/top/B100/timing.ucf
@@ -0,0 +1,5 @@
+NET "CLK_FPGA_P" TNM_NET = "CLK_FPGA_P";
+TIMESPEC "TS_CLK_FPGA_P" = PERIOD "CLK_FPGA_P" 15625 ps HIGH 50 %;
+
+NET "IFCLK" TNM_NET = "IFCLK";
+TIMESPEC "TS_IFCLK" = PERIOD "IFCLK" 20833 ps HIGH 50 %;
diff --git a/fpga/usrp2/top/B100/u1plus.ucf b/fpga/usrp2/top/B100/u1plus.ucf
new file mode 100644
index 000000000..cd89878e3
--- /dev/null
+++ b/fpga/usrp2/top/B100/u1plus.ucf
@@ -0,0 +1,203 @@
+## Main Clock
+NET "CLK_FPGA_P" LOC = "R7" ;
+NET "CLK_FPGA_N" LOC = "T7" ;
+
+## UART
+NET "FPGA_TXD" LOC = "H16" ;
+NET "FPGA_RXD" LOC = "H12" ;
+
+## I2C
+NET "SDA_FPGA" LOC = "T13" ;
+NET "SCL_FPGA" LOC = "R13" ;
+
+## CGEN
+NET "cgen_st_ld" LOC = "M13" ;
+NET "cgen_st_refmon" LOC = "J14" ;
+NET "cgen_st_status" LOC = "P6" ;
+NET "cgen_ref_sel" LOC = "T2" ;
+NET "cgen_sync_b" LOC = "H15" ;
+
+## FPGA Config
+#NET "fpga_cfg_din" LOC = "T14" ;
+#NET "fpga_cfg_cclk" LOC = "R14" ;
+#NET "fpga_cfg_init_b" LOC = "T12" ;
+
+## MISC
+#NET "mystery_bus<2>" LOC = "T11" ;
+#NET "mystery_bus<1>" LOC = "C4" ;
+#NET "mystery_bus<0>" LOC = "E7" ;
+NET "reset_n" LOC = "D5" ;
+NET "PPS_IN" LOC = "M14" ;
+NET "reset_codec" LOC = "B14" ;
+
+## GPIF
+NET "GPIF_D<15>" LOC = "P7" ;
+NET "GPIF_D<14>" LOC = "N8" ;
+NET "GPIF_D<13>" LOC = "T5" ;
+NET "GPIF_D<12>" LOC = "T6" ;
+NET "GPIF_D<11>" LOC = "N6" ;
+NET "GPIF_D<10>" LOC = "P5" ;
+NET "GPIF_D<9>" LOC = "R3" ;
+NET "GPIF_D<8>" LOC = "T3" ;
+NET "GPIF_D<7>" LOC = "N12" ;
+NET "GPIF_D<6>" LOC = "P13" ;
+NET "GPIF_D<5>" LOC = "P11" ;
+NET "GPIF_D<4>" LOC = "R9" ;
+NET "GPIF_D<3>" LOC = "T9" ;
+NET "GPIF_D<2>" LOC = "N9" ;
+NET "GPIF_D<1>" LOC = "P9" ;
+NET "GPIF_D<0>" LOC = "P8" ;
+
+NET "GPIF_CTL<3>" LOC = "N5" ;
+NET "GPIF_CTL<2>" LOC = "M11" ;
+NET "GPIF_CTL<1>" LOC = "M9" ;
+NET "GPIF_CTL<0>" LOC = "M7" ;
+
+NET "GPIF_RDY<3>" LOC = "N11" ;
+NET "GPIF_RDY<2>" LOC = "T10" ;
+NET "GPIF_RDY<1>" LOC = "T4" ;
+NET "GPIF_RDY<0>" LOC = "R5" ;
+
+NET "FX2_PA7_FLAGD" LOC = "P12" ;
+NET "FX2_PA6_PKTEND" LOC = "R11" ;
+NET "FX2_PA2_SLOE" LOC = "P10" ;
+
+NET "IFCLK" LOC = "T8" ;
+
+## LEDs
+NET "debug_led<2>" LOC = "R2" ;
+NET "debug_led<1>" LOC = "N4" ;
+NET "debug_led<0>" LOC = "P4" ;
+
+## Debug bus
+NET "debug_clk<0>" LOC = "K15" ;
+NET "debug_clk<1>" LOC = "K14" ;
+NET "debug<0>" LOC = "K16" ;
+NET "debug<1>" LOC = "J16" ;
+NET "debug<2>" LOC = "C16" ;
+NET "debug<3>" LOC = "C15" ;
+NET "debug<4>" LOC = "E13" ;
+NET "debug<5>" LOC = "D14" ;
+NET "debug<6>" LOC = "D16" ;
+NET "debug<7>" LOC = "D15" ;
+NET "debug<8>" LOC = "E14" ;
+NET "debug<9>" LOC = "F13" ;
+NET "debug<10>" LOC = "G13" ;
+NET "debug<11>" LOC = "F14" ;
+NET "debug<12>" LOC = "E16" ;
+NET "debug<13>" LOC = "F15" ;
+NET "debug<14>" LOC = "H13" ;
+NET "debug<15>" LOC = "G14" ;
+NET "debug<16>" LOC = "G16" ;
+NET "debug<17>" LOC = "F16" ;
+NET "debug<18>" LOC = "J12" ;
+NET "debug<19>" LOC = "J13" ;
+NET "debug<20>" LOC = "L14" ;
+NET "debug<21>" LOC = "L16" ;
+NET "debug<22>" LOC = "M15" ;
+NET "debug<23>" LOC = "M16" ;
+NET "debug<24>" LOC = "L13" ;
+NET "debug<25>" LOC = "K13" ;
+NET "debug<26>" LOC = "P16" ;
+NET "debug<27>" LOC = "N16" ;
+NET "debug<28>" LOC = "R15" ;
+NET "debug<29>" LOC = "P15" ;
+NET "debug<30>" LOC = "N13" ;
+NET "debug<31>" LOC = "N14" ;
+
+## ADC
+NET "adc<11>" LOC = "B15" ;
+NET "adc<10>" LOC = "A8" ;
+NET "adc<9>" LOC = "B8" ;
+NET "adc<8>" LOC = "C8" ;
+NET "adc<7>" LOC = "D8" ;
+NET "adc<6>" LOC = "C9" ;
+NET "adc<5>" LOC = "A9" ;
+NET "adc<4>" LOC = "C10" ;
+NET "adc<3>" LOC = "D9" ;
+NET "adc<2>" LOC = "A3" ;
+NET "adc<1>" LOC = "B3" ;
+NET "adc<0>" LOC = "A4" ;
+NET "RXSYNC" LOC = "D10" ;
+
+## DAC
+NET "TXBLANK" LOC = "K1" ;
+NET "TXSYNC" LOC = "J2" ;
+NET "dac<0>" LOC = "J1" ;
+NET "dac<1>" LOC = "H3" ;
+NET "dac<2>" LOC = "J3" ;
+NET "dac<3>" LOC = "G2" ;
+NET "dac<4>" LOC = "H1" ;
+NET "dac<5>" LOC = "N3" ;
+NET "dac<6>" LOC = "M4" ;
+NET "dac<7>" LOC = "R1" ;
+NET "dac<8>" LOC = "P2" ;
+NET "dac<9>" LOC = "P1" ;
+NET "dac<10>" LOC = "M1" ;
+NET "dac<11>" LOC = "N1" ;
+NET "dac<12>" LOC = "M3" ;
+NET "dac<13>" LOC = "L4" ;
+
+## TX DB
+NET "io_tx<0>" LOC = "K4" ;
+NET "io_tx<1>" LOC = "L3" ;
+NET "io_tx<2>" LOC = "L2" ;
+NET "io_tx<3>" LOC = "F1" ;
+NET "io_tx<4>" LOC = "F3" ;
+NET "io_tx<5>" LOC = "G3" ;
+NET "io_tx<6>" LOC = "E3" ;
+NET "io_tx<7>" LOC = "E2" ;
+NET "io_tx<8>" LOC = "E4" ;
+NET "io_tx<9>" LOC = "F4" ;
+NET "io_tx<10>" LOC = "D1" ;
+NET "io_tx<11>" LOC = "E1" ;
+NET "io_tx<12>" LOC = "D4" ;
+NET "io_tx<13>" LOC = "D3" ;
+NET "io_tx<14>" LOC = "C2" ;
+NET "io_tx<15>" LOC = "C1" ;
+
+## RX DB
+NET "io_rx<0>" LOC = "D7" ;
+NET "io_rx<1>" LOC = "C6" ;
+NET "io_rx<2>" LOC = "A6" ;
+NET "io_rx<3>" LOC = "B6" ;
+NET "io_rx<4>" LOC = "E9" ;
+NET "io_rx<5>" LOC = "A7" ;
+NET "io_rx<6>" LOC = "C7" ;
+NET "io_rx<7>" LOC = "B10" ;
+NET "io_rx<8>" LOC = "A10" ;
+NET "io_rx<9>" LOC = "C11" ;
+NET "io_rx<10>" LOC = "A11" ;
+NET "io_rx<11>" LOC = "D11" ;
+NET "io_rx<12>" LOC = "B12" ;
+NET "io_rx<13>" LOC = "A12" ;
+NET "io_rx<14>" LOC = "A14" ;
+NET "io_rx<15>" LOC = "A13" ;
+
+## SPI
+#NET "SEN_AUX" LOC = "C12" ;
+#NET "SCLK_AUX" LOC = "D12" ;
+#NET "MISO_AUX" LOC = "J5" ;
+NET "SCLK_CODEC" LOC = "K3" ;
+NET "SEN_CODEC" LOC = "D13" ;
+NET "MOSI_CODEC" LOC = "C13" ;
+NET "MISO_CODEC" LOC = "G4" ;
+
+NET "MISO_RX_DB" LOC = "E6" ;
+NET "SEN_RX_DB" LOC = "B4" ;
+NET "MOSI_RX_DB" LOC = "A5" ;
+NET "SCLK_RX_DB" LOC = "C5" ;
+
+NET "MISO_TX_DB" LOC = "J4" ;
+NET "SEN_TX_DB" LOC = "N2" ;
+NET "MOSI_TX_DB" LOC = "L1" ;
+NET "SCLK_TX_DB" LOC = "G1" ;
+
+## Dedicated pins
+#NET "TMS" LOC = "B2" ;
+#NET "TDO" LOC = "B16" ;
+#NET "TDI" LOC = "B1" ;
+#NET "TCK" LOC = "A15" ;
+
+##NET "fpga_cfg_prog_b" LOC = "A2" ;
+##NET "fpga_cfg_done" LOC = "T15" ;
diff --git a/fpga/usrp2/top/B100/u1plus.v b/fpga/usrp2/top/B100/u1plus.v
new file mode 100644
index 000000000..5e3200580
--- /dev/null
+++ b/fpga/usrp2/top/B100/u1plus.v
@@ -0,0 +1,173 @@
+//
+// 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/>.
+//
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+
+module u1plus
+ (input CLK_FPGA_P, input CLK_FPGA_N, // Diff
+ output [2:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
+ output FPGA_TXD, input FPGA_RXD,
+
+ // GPIF
+ inout [15:0] GPIF_D, input [3:0] GPIF_CTL, output [3:0] GPIF_RDY,
+ output FX2_PA7_FLAGD, output FX2_PA6_PKTEND, output FX2_PA2_SLOE,
+ input IFCLK,
+
+ inout SDA_FPGA, inout SCL_FPGA, // I2C
+
+ output SCLK_TX_DB, output SEN_TX_DB, output MOSI_TX_DB, input MISO_TX_DB, // DB TX SPI
+ output SCLK_RX_DB, output SEN_RX_DB, output MOSI_RX_DB, input MISO_RX_DB, // DB TX SPI
+ output SCLK_CODEC, output SEN_CODEC, output MOSI_CODEC, input MISO_CODEC, // AD9862 main SPI
+
+ input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel,
+
+ inout [15:0] io_tx, inout [15:0] io_rx,
+
+ output [13:0] dac, output TXSYNC, output TXBLANK,
+ input [11:0] adc, input RXSYNC,
+
+ input PPS_IN,
+ input reset_n, output reset_codec
+ );
+
+ assign reset_codec = 1; // Believed to be active low
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Clocking
+ wire clk_fpga, clk_fpga_in, reset;
+
+ IBUFGDS #(.IOSTANDARD("LVDS_33"), .DIFF_TERM("TRUE"))
+ clk_fpga_pin (.O(clk_fpga_in),.I(CLK_FPGA_P),.IB(CLK_FPGA_N));
+
+ BUFG clk_fpga_BUFG (.I(clk_fpga_in), .O(clk_fpga));
+
+ reset_sync reset_sync(.clk(clk_fpga), .reset_in(~reset_n), .reset_out(reset));
+
+ // /////////////////////////////////////////////////////////////////////////
+ // SPI
+ wire mosi, sclk, miso;
+ assign { SCLK_TX_DB, MOSI_TX_DB } = ~SEN_TX_DB ? {sclk,mosi} : 2'b0;
+ assign { SCLK_RX_DB, MOSI_RX_DB } = ~SEN_RX_DB ? {sclk,mosi} : 2'b0;
+ assign { SCLK_CODEC, MOSI_CODEC } = ~SEN_CODEC ? {sclk,mosi} : 2'b0;
+ assign miso = (~SEN_TX_DB & MISO_TX_DB) | (~SEN_RX_DB & MISO_RX_DB) |
+ (~SEN_CODEC & MISO_CODEC);
+
+ // /////////////////////////////////////////////////////////////////////////
+ // TX DAC -- handle the interleaved data bus to DAC, with clock doubling DLL
+
+ assign TXBLANK = 0;
+ wire [13:0] tx_i, tx_q;
+
+ genvar i;
+ generate
+ for(i=0;i<14;i=i+1)
+ begin : gen_dacout
+ ODDR2 #(.DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1"
+ .INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
+ .SRTYPE("SYNC")) // Specifies "SYNC" or "ASYNC" set/reset
+ ODDR2_inst (.Q(dac[i]), // 1-bit DDR output data
+ .C0(clk_fpga), // 1-bit clock input
+ .C1(~clk_fpga), // 1-bit clock input
+ .CE(1'b1), // 1-bit clock enable input
+ .D0(tx_i[i]), // 1-bit data input (associated with C0)
+ .D1(tx_q[i]), // 1-bit data input (associated with C1)
+ .R(1'b0), // 1-bit reset input
+ .S(1'b0)); // 1-bit set input
+ end // block: gen_dacout
+ endgenerate
+ ODDR2 #(.DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1"
+ .INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
+ .SRTYPE("SYNC")) // Specifies "SYNC" or "ASYNC" set/reset
+ ODDR2_txsnc (.Q(TXSYNC), // 1-bit DDR output data
+ .C0(clk_fpga), // 1-bit clock input
+ .C1(~clk_fpga), // 1-bit clock input
+ .CE(1'b1), // 1-bit clock enable input
+ .D0(1'b0), // 1-bit data input (associated with C0)
+ .D1(1'b1), // 1-bit data input (associated with C1)
+ .R(1'b0), // 1-bit reset input
+ .S(1'b0)); // 1-bit set input
+
+ // /////////////////////////////////////////////////////////////////////////
+ // RX ADC -- handles deinterleaving
+
+ reg [11:0] rx_i, rx_q;
+ wire [11:0] rx_a, rx_b;
+
+ genvar j;
+ generate
+ for(j=0;j<12;j=j+1)
+ begin : gen_adcin
+ IDDR2 #(.DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1"
+ .INIT_Q0(1'b0), // Sets initial state of the Q0 output to 1’b0 or 1’b1
+ .INIT_Q1(1'b0), // Sets initial state of the Q1 output to 1’b0 or 1’b1
+ .SRTYPE("SYNC")) // Specifies "SYNC" or "ASYNC" set/reset
+ IDDR2_inst (.Q0(rx_a[j]), // 1-bit output captured with C0 clock
+ .Q1(rx_b[j]), // 1-bit output captured with C1 clock
+ .C0(clk_fpga), // 1-bit clock input
+ .C1(~clk_fpga), // 1-bit clock input
+ .CE(1'b1), // 1-bit clock enable input
+ .D(adc[j]), // 1-bit DDR data input
+ .R(1'b0), // 1-bit reset input
+ .S(1'b0)); // 1-bit set input
+ end // block: gen_adcin
+ endgenerate
+
+ IDDR2 #(.DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1"
+ .INIT_Q0(1'b0), // Sets initial state of the Q0 output to 1’b0 or 1’b1
+ .INIT_Q1(1'b0), // Sets initial state of the Q1 output to 1’b0 or 1’b1
+ .SRTYPE("SYNC")) // Specifies "SYNC" or "ASYNC" set/reset
+ IDDR2_sync (.Q0(rxsync_0), // 1-bit output captured with C0 clock
+ .Q1(rxsync_1), // 1-bit output captured with C1 clock
+ .C0(clk_fpga), // 1-bit clock input
+ .C1(~clk_fpga), // 1-bit clock input
+ .CE(1'b1), // 1-bit clock enable input
+ .D(RXSYNC), // 1-bit DDR data input
+ .R(1'b0), // 1-bit reset input
+ .S(1'b0)); // 1-bit set input
+
+ always @(posedge clk_fpga)
+ if(rxsync_0)
+ begin
+ rx_i <= rx_b;
+ rx_q <= rx_a;
+ end
+ else
+ begin
+ rx_i <= rx_a;
+ rx_q <= rx_b;
+ end
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Main U1E Core
+ u1plus_core u1p_c(.clk_fpga(clk_fpga), .rst_fpga(reset),
+ .debug_led(debug_led), .debug(debug), .debug_clk(debug_clk),
+ .debug_txd(FPGA_TXD), .debug_rxd(FPGA_RXD),
+ .gpif_d(GPIF_D), .gpif_ctl(GPIF_CTL), .gpif_rdy(GPIF_RDY),
+ .gpif_misc({FX2_PA7_FLAGD,FX2_PA6_PKTEND,FX2_PA2_SLOE}),
+ .gpif_clk(IFCLK),
+
+ .db_sda(SDA_FPGA), .db_scl(SCL_FPGA),
+ .sclk(sclk), .sen({SEN_CODEC,SEN_TX_DB,SEN_RX_DB}), .mosi(mosi), .miso(miso),
+ .cgen_st_status(cgen_st_status), .cgen_st_ld(cgen_st_ld),.cgen_st_refmon(cgen_st_refmon),
+ .cgen_sync_b(cgen_sync_b), .cgen_ref_sel(cgen_ref_sel),
+ .io_tx(io_tx), .io_rx(io_rx),
+ .tx_i(tx_i), .tx_q(tx_q),
+ .rx_i(rx_i), .rx_q(rx_q),
+ .pps_in(PPS_IN) );
+
+endmodule // u1plus
diff --git a/fpga/usrp2/top/B100/u1plus_core.v b/fpga/usrp2/top/B100/u1plus_core.v
new file mode 100644
index 000000000..8a02f0fb8
--- /dev/null
+++ b/fpga/usrp2/top/B100/u1plus_core.v
@@ -0,0 +1,409 @@
+//
+// 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/>.
+//
+
+
+
+module u1plus_core
+ (input clk_fpga, input rst_fpga,
+ output [2:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
+ output debug_txd, input debug_rxd,
+
+ // GPIF
+ inout [15:0] gpif_d, input [3:0] gpif_ctl, output [3:0] gpif_rdy,
+ output [2:0] gpif_misc, input gpif_clk,
+
+ inout db_sda, inout db_scl,
+ output sclk, output [15:0] sen, output mosi, input miso,
+
+ input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel,
+ output tx_underrun, output rx_overrun,
+ inout [15:0] io_tx, inout [15:0] io_rx,
+ output [13:0] tx_i, output [13:0] tx_q,
+ input [11:0] rx_i, input [11:0] rx_q,
+ input pps_in
+ );
+
+ localparam TXFIFOSIZE = 11;
+ localparam RXFIFOSIZE = 11;
+
+ // 64 total regs in address space
+ localparam SR_RX_CTRL = 0; // 9 regs (+0 to +8)
+ localparam SR_RX_DSP = 16; // 7 regs (+0 to +6)
+ localparam SR_TX_CTRL = 24; // 6 regs (+0 to +5)
+ localparam SR_TX_DSP = 32; // 5 regs (+0 to +4)
+ localparam SR_TIME64 = 40; // 6 regs (+0 to +5)
+ localparam SR_CLEAR_RX_FIFO = 48; // 1 reg
+ localparam SR_CLEAR_TX_FIFO = 49; // 1 reg
+ localparam SR_GLOBAL_RESET = 50; // 1 reg
+ localparam SR_REG_TEST32 = 52; // 1 reg
+
+ wire [7:0] COMPAT_NUM = 8'd3;
+
+ wire wb_clk = clk_fpga;
+ wire wb_rst, global_reset;
+
+ 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] debug0;
+ wire [31:0] debug1;
+
+ wire [31:0] debug_vt;
+ wire gpif_rst;
+
+ wire rx_overrun_dsp, rx_overrun_gpmc, tx_underrun_dsp, tx_underrun_gpmc;
+ reg [7:0] frames_per_packet;
+
+ 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));
+
+ reset_sync reset_sync_wb(.clk(wb_clk), .reset_in(rst_fpga | global_reset), .reset_out(wb_rst));
+ reset_sync reset_sync_gp(.clk(wb_clk), .reset_in(rst_fpga | global_reset), .reset_out(gpif_rst));
+ wire [15:0] test_len;
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // GPIF Slave to Wishbone Master
+ localparam dw = 16;
+ localparam aw = 11;
+ localparam sw = 2;
+
+ wire [dw-1:0] m0_dat_mosi, m0_dat_miso;
+ wire [aw-1:0] m0_adr;
+ wire [sw-1:0] m0_sel;
+ wire m0_cyc, m0_stb, m0_we, m0_ack, m0_err, m0_rty;
+
+ wire [31:0] debug_gpmc;
+
+ wire [35:0] tx_data, rx_data, tx_err_data;
+ wire tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy,
+ tx_err_src_rdy, tx_err_dst_rdy;
+
+ wire bus_error;
+ wire clear_tx, clear_rx;
+
+ setting_reg #(.my_addr(SR_CLEAR_RX_FIFO), .width(1)) sr_clear_rx
+ (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear_rx));
+
+ setting_reg #(.my_addr(SR_CLEAR_TX_FIFO), .width(1)) sr_clear_tx
+ (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear_tx));
+
+ gpif #(.TXFIFOSIZE(TXFIFOSIZE), .RXFIFOSIZE(RXFIFOSIZE))
+ gpif (.gpif_clk(gpif_clk), .gpif_rst(gpif_rst), .gpif_d(gpif_d),
+ .gpif_ctl(gpif_ctl), .gpif_rdy(gpif_rdy), .gpif_misc(gpif_misc),
+
+ .wb_clk(wb_clk), .wb_rst(wb_rst),
+ .wb_adr_o(m0_adr), .wb_dat_mosi(m0_dat_mosi), .wb_dat_miso(m0_dat_miso),
+ .wb_sel_o(m0_sel), .wb_cyc_o(m0_cyc), .wb_stb_o(m0_stb), .wb_we_o(m0_we),
+ .wb_ack_i(m0_ack), .triggers(8'd0),
+
+ .fifo_clk(wb_clk), .fifo_rst(wb_rst), .clear_tx(clear_tx), .clear_rx(clear_rx),
+ .tx_data_o(tx_data), .tx_src_rdy_o(tx_src_rdy), .tx_dst_rdy_i(tx_dst_rdy),
+ .rx_data_i(rx_data), .rx_src_rdy_i(rx_src_rdy), .rx_dst_rdy_o(rx_dst_rdy),
+ .tx_err_data_i(tx_err_data), .tx_err_src_rdy_i(tx_err_src_rdy), .tx_err_dst_rdy_o(tx_err_dst_rdy),
+
+ .tx_underrun(tx_underrun_gpmc), .rx_overrun(rx_overrun_gpmc),
+
+ .frames_per_packet(frames_per_packet), .test_len(test_len), .test_rate(test_rate), .test_ctrl(test_ctrl),
+ .debug0(debug0), .debug1(debug1));
+
+ // /////////////////////////////////////////////////////////////////////////
+ // DSP RX
+ wire [31:0] sample_rx;
+ wire strobe_rx, run_rx;
+ wire [31:0] debug_rx_dsp, vr_debug;
+
+ dsp_core_rx #(.BASE(SR_RX_DSP)) dsp_core_rx
+ (.clk(wb_clk),.rst(wb_rst),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .adc_a({rx_i,2'b0}),.adc_ovf_a(0),.adc_b({rx_q,2'b0}),.adc_ovf_b(0),
+ .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
+ .debug(debug_rx_dsp) );
+
+ vita_rx_chain #(.BASE(SR_RX_CTRL), .UNIT(0), .FIFOSIZE(9), .PROT_ENG_FLAGS(0)) vita_rx_chain
+ (.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_dsp),
+ .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
+ .rx_data_o(rx_data), .rx_dst_rdy_i(rx_dst_rdy), .rx_src_rdy_o(rx_src_rdy),
+ .debug(vr_debug) );
+
+ // ///////////////////////////////////////////////////////////////////////////////////
+ // DSP TX
+
+ wire [15:0] tx_i_int, tx_q_int;
+ wire run_tx;
+
+ vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP),
+ .REPORT_ERROR(1), .DO_FLOW_CONTROL(0),
+ .PROT_ENG_FLAGS(0), .USE_TRANS_HEADER(0),
+ .DSP_NUMBER(0))
+ vita_tx_chain
+ (.clk(wb_clk), .reset(wb_rst),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .vita_time(vita_time),
+ .tx_data_i(tx_data), .tx_src_rdy_i(tx_src_rdy), .tx_dst_rdy_o(tx_dst_rdy),
+ .err_data_o(tx_err_data), .err_src_rdy_o(tx_err_src_rdy), .err_dst_rdy_i(tx_err_dst_rdy),
+ .dac_a(tx_i_int),.dac_b(tx_q_int),
+ .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];
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // 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,
+ s4_dat_mosi, s5_dat_mosi, s4_dat_miso, s5_dat_miso, s6_dat_mosi, s7_dat_mosi, s6_dat_miso, s7_dat_miso,
+ s8_dat_mosi, s9_dat_mosi, s8_dat_miso, s9_dat_miso, sa_dat_mosi, sb_dat_mosi, sa_dat_miso, sb_dat_miso,
+ sc_dat_mosi, sd_dat_mosi, sc_dat_miso, sd_dat_miso, se_dat_mosi, sf_dat_mosi, se_dat_miso, sf_dat_miso;
+ wire [aw-1:0] s0_adr,s1_adr,s2_adr,s3_adr,s4_adr,s5_adr,s6_adr,s7_adr;
+ wire [aw-1:0] s8_adr,s9_adr,sa_adr,sb_adr,sc_adr, sd_adr, se_adr, sf_adr;
+ wire [sw-1:0] s0_sel,s1_sel,s2_sel,s3_sel,s4_sel,s5_sel,s6_sel,s7_sel;
+ wire [sw-1:0] s8_sel,s9_sel,sa_sel,sb_sel,sc_sel, sd_sel, se_sel, sf_sel;
+ wire s0_ack,s1_ack,s2_ack,s3_ack,s4_ack,s5_ack,s6_ack,s7_ack;
+ wire s8_ack,s9_ack,sa_ack,sb_ack,sc_ack, sd_ack, se_ack, sf_ack;
+ wire s0_stb,s1_stb,s2_stb,s3_stb,s4_stb,s5_stb,s6_stb,s7_stb;
+ wire s8_stb,s9_stb,sa_stb,sb_stb,sc_stb, sd_stb, se_stb, sf_stb;
+ wire s0_cyc,s1_cyc,s2_cyc,s3_cyc,s4_cyc,s5_cyc,s6_cyc,s7_cyc;
+ wire s8_cyc,s9_cyc,sa_cyc,sb_cyc,sc_cyc, sd_cyc, se_cyc, sf_cyc;
+ wire s0_we,s1_we,s2_we,s3_we,s4_we,s5_we,s6_we,s7_we;
+ wire s8_we,s9_we,sa_we,sb_we,sc_we,sd_we, se_we, sf_we;
+
+ wb_1master #(.dw(dw), .aw(aw), .sw(sw), .decode_w(4),
+ .s0_addr(4'h0), .s0_mask(4'hF), .s1_addr(4'h1), .s1_mask(4'hF),
+ .s2_addr(4'h2), .s2_mask(4'hF), .s3_addr(4'h3), .s3_mask(4'hF),
+ .s4_addr(4'h4), .s4_mask(4'hF), .s5_addr(4'h5), .s5_mask(4'hF),
+ .s6_addr(4'h6), .s6_mask(4'hF), .s7_addr(4'h7), .s7_mask(4'hF),
+ .s8_addr(4'h8), .s8_mask(4'hE), .s9_addr(4'hf), .s9_mask(4'hF), // slave 8 is double wide
+ .sa_addr(4'ha), .sa_mask(4'hF), .sb_addr(4'hb), .sb_mask(4'hF),
+ .sc_addr(4'hc), .sc_mask(4'hF), .sd_addr(4'hd), .sd_mask(4'hF),
+ .se_addr(4'he), .se_mask(4'hF), .sf_addr(4'hf), .sf_mask(4'hF))
+ wb_1master
+ (.clk_i(wb_clk),.rst_i(wb_rst),
+ .m0_dat_o(m0_dat_miso),.m0_ack_o(m0_ack),.m0_err_o(m0_err),.m0_rty_o(m0_rty),.m0_dat_i(m0_dat_mosi),
+ .m0_adr_i(m0_adr),.m0_sel_i(m0_sel),.m0_we_i(m0_we),.m0_cyc_i(m0_cyc),.m0_stb_i(m0_stb),
+ .s0_dat_o(s0_dat_mosi),.s0_adr_o(s0_adr),.s0_sel_o(s0_sel),.s0_we_o(s0_we),.s0_cyc_o(s0_cyc),.s0_stb_o(s0_stb),
+ .s0_dat_i(s0_dat_miso),.s0_ack_i(s0_ack),.s0_err_i(0),.s0_rty_i(0),
+ .s1_dat_o(s1_dat_mosi),.s1_adr_o(s1_adr),.s1_sel_o(s1_sel),.s1_we_o(s1_we),.s1_cyc_o(s1_cyc),.s1_stb_o(s1_stb),
+ .s1_dat_i(s1_dat_miso),.s1_ack_i(s1_ack),.s1_err_i(0),.s1_rty_i(0),
+ .s2_dat_o(s2_dat_mosi),.s2_adr_o(s2_adr),.s2_sel_o(s2_sel),.s2_we_o(s2_we),.s2_cyc_o(s2_cyc),.s2_stb_o(s2_stb),
+ .s2_dat_i(s2_dat_miso),.s2_ack_i(s2_ack),.s2_err_i(0),.s2_rty_i(0),
+ .s3_dat_o(s3_dat_mosi),.s3_adr_o(s3_adr),.s3_sel_o(s3_sel),.s3_we_o(s3_we),.s3_cyc_o(s3_cyc),.s3_stb_o(s3_stb),
+ .s3_dat_i(s3_dat_miso),.s3_ack_i(s3_ack),.s3_err_i(0),.s3_rty_i(0),
+ .s4_dat_o(s4_dat_mosi),.s4_adr_o(s4_adr),.s4_sel_o(s4_sel),.s4_we_o(s4_we),.s4_cyc_o(s4_cyc),.s4_stb_o(s4_stb),
+ .s4_dat_i(s4_dat_miso),.s4_ack_i(s4_ack),.s4_err_i(0),.s4_rty_i(0),
+ .s5_dat_o(s5_dat_mosi),.s5_adr_o(s5_adr),.s5_sel_o(s5_sel),.s5_we_o(s5_we),.s5_cyc_o(s5_cyc),.s5_stb_o(s5_stb),
+ .s5_dat_i(s5_dat_miso),.s5_ack_i(s5_ack),.s5_err_i(0),.s5_rty_i(0),
+ .s6_dat_o(s6_dat_mosi),.s6_adr_o(s6_adr),.s6_sel_o(s6_sel),.s6_we_o(s6_we),.s6_cyc_o(s6_cyc),.s6_stb_o(s6_stb),
+ .s6_dat_i(s6_dat_miso),.s6_ack_i(s6_ack),.s6_err_i(0),.s6_rty_i(0),
+ .s7_dat_o(s7_dat_mosi),.s7_adr_o(s7_adr),.s7_sel_o(s7_sel),.s7_we_o(s7_we),.s7_cyc_o(s7_cyc),.s7_stb_o(s7_stb),
+ .s7_dat_i(s7_dat_miso),.s7_ack_i(s7_ack),.s7_err_i(0),.s7_rty_i(0),
+ .s8_dat_o(s8_dat_mosi),.s8_adr_o(s8_adr),.s8_sel_o(s8_sel),.s8_we_o(s8_we),.s8_cyc_o(s8_cyc),.s8_stb_o(s8_stb),
+ .s8_dat_i(s8_dat_miso),.s8_ack_i(s8_ack),.s8_err_i(0),.s8_rty_i(0),
+ .s9_dat_o(s9_dat_mosi),.s9_adr_o(s9_adr),.s9_sel_o(s9_sel),.s9_we_o(s9_we),.s9_cyc_o(s9_cyc),.s9_stb_o(s9_stb),
+ .s9_dat_i(s9_dat_miso),.s9_ack_i(s9_ack),.s9_err_i(0),.s9_rty_i(0),
+ .sa_dat_o(sa_dat_mosi),.sa_adr_o(sa_adr),.sa_sel_o(sa_sel),.sa_we_o(sa_we),.sa_cyc_o(sa_cyc),.sa_stb_o(sa_stb),
+ .sa_dat_i(sa_dat_miso),.sa_ack_i(sa_ack),.sa_err_i(0),.sa_rty_i(0),
+ .sb_dat_o(sb_dat_mosi),.sb_adr_o(sb_adr),.sb_sel_o(sb_sel),.sb_we_o(sb_we),.sb_cyc_o(sb_cyc),.sb_stb_o(sb_stb),
+ .sb_dat_i(sb_dat_miso),.sb_ack_i(sb_ack),.sb_err_i(0),.sb_rty_i(0),
+ .sc_dat_o(sc_dat_mosi),.sc_adr_o(sc_adr),.sc_sel_o(sc_sel),.sc_we_o(sc_we),.sc_cyc_o(sc_cyc),.sc_stb_o(sc_stb),
+ .sc_dat_i(sc_dat_miso),.sc_ack_i(sc_ack),.sc_err_i(0),.sc_rty_i(0),
+ .sd_dat_o(sd_dat_mosi),.sd_adr_o(sd_adr),.sd_sel_o(sd_sel),.sd_we_o(sd_we),.sd_cyc_o(sd_cyc),.sd_stb_o(sd_stb),
+ .sd_dat_i(sd_dat_miso),.sd_ack_i(sd_ack),.sd_err_i(0),.sd_rty_i(0),
+ .se_dat_o(se_dat_mosi),.se_adr_o(se_adr),.se_sel_o(se_sel),.se_we_o(se_we),.se_cyc_o(se_cyc),.se_stb_o(se_stb),
+ .se_dat_i(se_dat_miso),.se_ack_i(se_ack),.se_err_i(0),.se_rty_i(0),
+ .sf_dat_o(sf_dat_mosi),.sf_adr_o(sf_adr),.sf_sel_o(sf_sel),.sf_we_o(sf_we),.sf_cyc_o(sf_cyc),.sf_stb_o(sf_stb),
+ .sf_dat_i(sf_dat_miso),.sf_ack_i(sf_ack),.sf_err_i(0),.sf_rty_i(0) );
+
+ assign s5_ack = 0; assign s9_ack = 0; assign sa_ack = 0; assign sb_ack = 0;
+ assign sc_ack = 0; assign sd_ack = 0; assign se_ack = 0; assign sf_ack = 0;
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // Slave 0, Misc LEDs, Switches, controls
+
+ localparam REG_LEDS = 7'd0; // out
+ localparam REG_CGEN_CTRL = 7'd4; // out
+ localparam REG_CGEN_ST = 7'd6; // in
+ localparam REG_TEST = 7'd8; // out
+ localparam REG_RX_FRAMELEN = 7'd10; // in
+ localparam REG_TX_FRAMELEN = 7'd12; // out
+ localparam REG_XFER_RATE = 7'd14; // out
+ localparam REG_COMPAT = 7'd16; // in
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ begin
+ reg_leds <= 0;
+ reg_cgen_ctrl <= 2'b11;
+ reg_test <= 0;
+ xfer_rate <= 0;
+ frames_per_packet <= 0;
+ end
+ else
+ if(s0_cyc & s0_stb & s0_we)
+ case(s0_adr[6:0])
+ REG_LEDS :
+ reg_leds <= s0_dat_mosi;
+ REG_CGEN_CTRL :
+ reg_cgen_ctrl <= s0_dat_mosi;
+ REG_TEST :
+ reg_test <= s0_dat_mosi;
+ REG_RX_FRAMELEN :
+ frames_per_packet <= s0_dat_mosi[7:0];
+ REG_XFER_RATE :
+ xfer_rate <= s0_dat_mosi;
+ endcase // case (s0_adr[6:0])
+
+ assign test_ctrl = xfer_rate[11:8];
+ assign test_rate = xfer_rate[7:0];
+ assign test_len = reg_test[15:0];
+
+ assign { debug_led[2],debug_led[0],debug_led[1] } = reg_leds; // LEDs are arranged funny on board
+ 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_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_COMPAT) ? { 8'd0, COMPAT_NUM } :
+ 16'hBEEF;
+
+ assign s0_ack = s0_stb & s0_cyc;
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // Slave 1, UART
+ // depth of 3 is 128 entries, clkdiv of 278 gives 230.4k with a 64 MHz system clock
+
+ simple_uart #(.TXDEPTH(3),.RXDEPTH(3), .CLKDIV_DEFAULT(278)) uart
+ (.clk_i(wb_clk),.rst_i(wb_rst),
+ .we_i(s1_we),.stb_i(s1_stb),.cyc_i(s1_cyc),.ack_o(s1_ack),
+ .adr_i(s1_adr[3:1]),.dat_i({16'd0,s1_dat_mosi}),.dat_o(s1_dat_miso),
+ .rx_int_o(),.tx_int_o(),
+ .tx_o(debug_txd),.rx_i(debug_rxd),.baud_o());
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // Slave 2, SPI
+
+ spi_top16 shared_spi
+ (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.wb_adr_i(s2_adr[4:0]),.wb_dat_i(s2_dat_mosi),
+ .wb_dat_o(s2_dat_miso),.wb_sel_i(s2_sel),.wb_we_i(s2_we),.wb_stb_i(s2_stb),
+ .wb_cyc_i(s2_cyc),.wb_ack_o(s2_ack),.wb_err_o(),.wb_int_o(),
+ .ss_pad_o(sen), .sclk_pad_o(sclk), .mosi_pad_o(mosi), .miso_pad_i(miso) );
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Slave 3, I2C
+
+ wire scl_pad_i, scl_pad_o, scl_pad_oen_o, sda_pad_i, sda_pad_o, sda_pad_oen_o;
+ i2c_master_top #(.ARST_LVL(1)) i2c
+ (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.arst_i(1'b0),
+ .wb_adr_i(s3_adr[3:1]),.wb_dat_i(s3_dat_mosi[7:0]),.wb_dat_o(s3_dat_miso[7:0]),
+ .wb_we_i(s3_we),.wb_stb_i(s3_stb),.wb_cyc_i(s3_cyc),
+ .wb_ack_o(s3_ack),.wb_inta_o(),
+ .scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_pad_oen_o),
+ .sda_pad_i(sda_pad_i),.sda_pad_o(sda_pad_o),.sda_padoen_o(sda_pad_oen_o) );
+
+ assign s3_dat_miso[15:8] = 8'd0;
+
+ // I2C -- Don't use external transistors for open drain, the FPGA implements this
+ IOBUF scl_pin(.O(scl_pad_i), .IO(db_scl), .I(scl_pad_o), .T(scl_pad_oen_o));
+ IOBUF sda_pin(.O(sda_pad_i), .IO(db_sda), .I(sda_pad_o), .T(sda_pad_oen_o));
+
+ // /////////////////////////////////////////////////////////////////////////
+ // GPIOs -- Slave #4
+
+ wire [31:0] atr_lines;
+ wire [31:0] debug_gpio_0, debug_gpio_1;
+
+ nsgpio16LE
+ nsgpio16LE(.clk_i(wb_clk),.rst_i(wb_rst),
+ .cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we),
+ .dat_i(s4_dat_mosi),.dat_o(s4_dat_miso),.ack_o(s4_ack),
+ .atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1),
+ .gpio( {io_tx,io_rx} ) );
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Settings Bus -- Slave #8 + 9
+
+ // only have 64 regs, 32 bits each with current setup...
+ settings_bus_16LE #(.AWIDTH(11),.RWIDTH(6)) settings_bus_16LE
+ (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s8_adr[10:0]),.wb_dat_i(s8_dat_mosi),
+ .wb_stb_i(s8_stb),.wb_we_i(s8_we),.wb_ack_o(s8_ack),
+ .strobe(set_stb),.addr(set_addr),.data(set_data) );
+
+ // /////////////////////////////////////////////////////////////////////////
+ // ATR Controller -- Slave #6
+
+ atr_controller16 atr_controller16
+ (.clk_i(wb_clk), .rst_i(wb_rst),
+ .adr_i(s6_adr[5:0]), .sel_i(s6_sel), .dat_i(s6_dat_mosi), .dat_o(s6_dat_miso),
+ .we_i(s6_we), .stb_i(s6_stb), .cyc_i(s6_cyc), .ack_o(s6_ack),
+ .run_rx(run_rx), .run_tx(run_tx), .ctrl_lines(atr_lines));
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Readback mux 32 -- Slave #7
+
+ wire [31:0] reg_test32;
+
+ setting_reg #(.my_addr(SR_REG_TEST32)) sr_reg_test32
+ (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(reg_test32),.changed());
+
+ wb_readback_mux_16LE readback_mux_32
+ (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s7_stb),
+ .wb_adr_i({5'b0,s7_adr}), .wb_dat_o(s7_dat_miso), .wb_ack_o(s7_ack),
+
+ .word00(vita_time[63:32]), .word01(vita_time[31:0]),
+ .word02(vita_time_pps[63:32]), .word03(vita_time_pps[31:0]),
+ .word04(reg_test32), .word05(32'b0),
+ .word06(32'b0), .word07(32'b0),
+ .word08(32'b0), .word09(32'b0),
+ .word10(32'b0), .word11(32'b0),
+ .word12(32'b0), .word13(32'b0),
+ .word14(32'b0), .word15(32'b0)
+ );
+
+ // /////////////////////////////////////////////////////////////////////////
+ // VITA Timing
+
+ time_64bit #(.TICKS_PER_SEC(32'd64000000),.BASE(SR_TIME64)) time_64bit
+ (.clk(wb_clk), .rst(wb_rst), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .pps(pps_in), .vita_time(vita_time), .vita_time_pps(vita_time_pps), .pps_int(pps_int),
+ .exp_time_in(0));
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // Debug circuitry
+
+ assign debug_clk = { gpif_clk, clk_fpga };
+ assign debug = debug0;
+ assign debug_gpio_0 = 0;
+ assign debug_gpio_1 = 0;
+ //assign {io_tx,io_rx} = {debug1};
+
+endmodule // u1plus_core
diff --git a/fpga/usrp2/top/u1e/.gitignore b/fpga/usrp2/top/E1x0/.gitignore
index 8d872713e..8d872713e 100644
--- a/fpga/usrp2/top/u1e/.gitignore
+++ b/fpga/usrp2/top/E1x0/.gitignore
diff --git a/fpga/usrp2/top/u1e/Makefile b/fpga/usrp2/top/E1x0/Makefile
index 5d721979b..5d721979b 100644
--- a/fpga/usrp2/top/u1e/Makefile
+++ b/fpga/usrp2/top/E1x0/Makefile
diff --git a/fpga/usrp2/top/u1e_passthru/Makefile b/fpga/usrp2/top/E1x0/Makefile.passthru
index f2d835608..f2d835608 100644
--- a/fpga/usrp2/top/u1e_passthru/Makefile
+++ b/fpga/usrp2/top/E1x0/Makefile.passthru
diff --git a/fpga/usrp2/top/u1e/README b/fpga/usrp2/top/E1x0/README
index 14c7a4955..14c7a4955 100644
--- a/fpga/usrp2/top/u1e/README
+++ b/fpga/usrp2/top/E1x0/README
diff --git a/fpga/usrp2/top/u1e/cmdfile b/fpga/usrp2/top/E1x0/cmdfile
index 291c723b8..291c723b8 100644
--- a/fpga/usrp2/top/u1e/cmdfile
+++ b/fpga/usrp2/top/E1x0/cmdfile
diff --git a/fpga/usrp2/top/u1e/core_compile b/fpga/usrp2/top/E1x0/core_compile
index dc0cd081e..dc0cd081e 100755
--- a/fpga/usrp2/top/u1e/core_compile
+++ b/fpga/usrp2/top/E1x0/core_compile
diff --git a/fpga/usrp2/top/u1e/make.sim b/fpga/usrp2/top/E1x0/make.sim
index 1c163884c..1c163884c 100644
--- a/fpga/usrp2/top/u1e/make.sim
+++ b/fpga/usrp2/top/E1x0/make.sim
diff --git a/fpga/usrp2/top/u1e_passthru/passthru.ucf b/fpga/usrp2/top/E1x0/passthru.ucf
index 64e6f0440..64e6f0440 100644
--- a/fpga/usrp2/top/u1e_passthru/passthru.ucf
+++ b/fpga/usrp2/top/E1x0/passthru.ucf
diff --git a/fpga/usrp2/top/E1x0/passthru.v b/fpga/usrp2/top/E1x0/passthru.v
new file mode 100644
index 000000000..486257366
--- /dev/null
+++ b/fpga/usrp2/top/E1x0/passthru.v
@@ -0,0 +1,35 @@
+//
+// 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/>.
+//
+
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+
+module passthru
+ (input overo_gpio145,
+ output cgen_sclk,
+ output cgen_sen_b,
+ output cgen_mosi,
+ input fpga_cfg_din,
+ input fpga_cfg_cclk
+ );
+
+ assign cgen_sclk = fpga_cfg_cclk;
+ assign cgen_sen_b = overo_gpio145;
+ assign cgen_mosi = fpga_cfg_din;
+
+
+endmodule // passthru
diff --git a/fpga/usrp2/top/u1e/tb_u1e.v b/fpga/usrp2/top/E1x0/tb_u1e.v
index 5fc8134fb..188190f04 100644
--- a/fpga/usrp2/top/u1e/tb_u1e.v
+++ b/fpga/usrp2/top/E1x0/tb_u1e.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ps / 1ps
//////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/u1e/timing.ucf b/fpga/usrp2/top/E1x0/timing.ucf
index 8df28c9d3..8df28c9d3 100644
--- a/fpga/usrp2/top/u1e/timing.ucf
+++ b/fpga/usrp2/top/E1x0/timing.ucf
diff --git a/fpga/usrp2/top/u1e/u1e.ucf b/fpga/usrp2/top/E1x0/u1e.ucf
index 0c487a601..0c487a601 100644
--- a/fpga/usrp2/top/u1e/u1e.ucf
+++ b/fpga/usrp2/top/E1x0/u1e.ucf
diff --git a/fpga/usrp2/top/u1e/u1e.v b/fpga/usrp2/top/E1x0/u1e.v
index 445b14a03..adf42fd07 100644
--- a/fpga/usrp2/top/u1e/u1e.v
+++ b/fpga/usrp2/top/E1x0/u1e.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/u1e/u1e_core.v b/fpga/usrp2/top/E1x0/u1e_core.v
index d10a3ab30..4c513587b 100644
--- a/fpga/usrp2/top/u1e/u1e_core.v
+++ b/fpga/usrp2/top/E1x0/u1e_core.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module u1e_core
diff --git a/fpga/usrp2/top/u2plus/.gitignore b/fpga/usrp2/top/N2x0/.gitignore
index 1b2211df0..1b2211df0 100644
--- a/fpga/usrp2/top/u2plus/.gitignore
+++ b/fpga/usrp2/top/N2x0/.gitignore
diff --git a/fpga/usrp2/top/u2plus/Makefile.N200 b/fpga/usrp2/top/N2x0/Makefile.N200R3
index 9175f9304..a525836ed 100644
--- a/fpga/usrp2/top/u2plus/Makefile.N200
+++ b/fpga/usrp2/top/N2x0/Makefile.N200R3
@@ -6,7 +6,7 @@
# Project Setup
##################################################
TOP_MODULE = u2plus
-BUILD_DIR = $(abspath build$(ISE)-N200)
+BUILD_DIR = $(abspath build$(ISE)-N200R3)
##################################################
# Include other makefiles
diff --git a/fpga/usrp2/top/u1e_ethdebug/Makefile b/fpga/usrp2/top/N2x0/Makefile.N200R4
index 751b52970..0ca40e1bd 100644
--- a/fpga/usrp2/top/u1e_ethdebug/Makefile
+++ b/fpga/usrp2/top/N2x0/Makefile.N200R4
@@ -5,14 +5,26 @@
##################################################
# Project Setup
##################################################
-TOP_MODULE = u1e
-BUILD_DIR = $(abspath build$(ISE))
+TOP_MODULE = u2plus
+BUILD_DIR = $(abspath build$(ISE)-N200R4)
##################################################
# Include other makefiles
##################################################
include ../Makefile.common
+include ../../fifo/Makefile.srcs
+include ../../control_lib/Makefile.srcs
+include ../../sdr_lib/Makefile.srcs
+include ../../serdes/Makefile.srcs
+include ../../simple_gemac/Makefile.srcs
+include ../../timing/Makefile.srcs
+include ../../opencores/Makefile.srcs
+include ../../vrt/Makefile.srcs
+include ../../udp/Makefile.srcs
+include ../../coregen/Makefile.srcs
+include ../../extramfifo/Makefile.srcs
+
##################################################
# Project Properties
@@ -20,8 +32,8 @@ include ../Makefile.common
export PROJECT_PROPERTIES := \
family "Spartan-3A DSP" \
device xc3sd1800a \
-package cs484 \
-speed -4 \
+package fg676 \
+speed -5 \
top_level_module_type "HDL" \
synthesis_tool "XST (VHDL/Verilog)" \
simulator "ISE Simulator (VHDL/Verilog)" \
@@ -33,10 +45,15 @@ simulator "ISE Simulator (VHDL/Verilog)" \
# Sources
##################################################
TOP_SRCS = \
-u1e.v \
-u1e.ucf
+capture_ddrlvds.v \
+u2plus_core.v \
+u2plus.v \
+u2plus.ucf
-SOURCES = $(abspath $(TOP_SRCS))
+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)
##################################################
# Process Properties
@@ -49,7 +66,8 @@ SYNTHESIZE_PROPERTIES = \
"Register Balancing" Yes \
"Use Clock Enable" Auto \
"Use Synchronous Reset" Auto \
-"Use Synchronous Set" Auto
+"Use Synchronous Set" Auto \
+"Verilog Macros" "LVDS=1"
TRANSLATE_PROPERTIES = \
"Macro Search Path" "$(shell pwd)/../../coregen/"
@@ -77,7 +95,6 @@ GEN_PROG_FILE_PROPERTIES = \
"Create Binary Configuration File" TRUE \
"Done (Output Events)" 5 \
"Enable Bitstream Compression" TRUE \
-"Enable Outputs (Output Events)" 6 \
-"Unused IOB Pins" "Pull Up"
+"Enable Outputs (Output Events)" 6
SIM_MODEL_PROPERTIES = ""
diff --git a/fpga/usrp2/top/u2plus/Makefile b/fpga/usrp2/top/N2x0/Makefile.N210R3
index 38400ce62..e29251e1c 100644
--- a/fpga/usrp2/top/u2plus/Makefile
+++ b/fpga/usrp2/top/N2x0/Makefile.N210R3
@@ -6,7 +6,7 @@
# Project Setup
##################################################
TOP_MODULE = u2plus
-BUILD_DIR = $(abspath build$(ISE))
+BUILD_DIR = $(abspath build$(ISE)-N210R3)
##################################################
# Include other makefiles
diff --git a/fpga/usrp2/top/N2x0/Makefile.N210R4 b/fpga/usrp2/top/N2x0/Makefile.N210R4
new file mode 100644
index 000000000..01a9e19fd
--- /dev/null
+++ b/fpga/usrp2/top/N2x0/Makefile.N210R4
@@ -0,0 +1,100 @@
+#
+# Copyright 2008 Ettus Research LLC
+#
+
+##################################################
+# Project Setup
+##################################################
+TOP_MODULE = u2plus
+BUILD_DIR = $(abspath build$(ISE)-N210R4)
+
+##################################################
+# Include other makefiles
+##################################################
+
+include ../Makefile.common
+include ../../fifo/Makefile.srcs
+include ../../control_lib/Makefile.srcs
+include ../../sdr_lib/Makefile.srcs
+include ../../serdes/Makefile.srcs
+include ../../simple_gemac/Makefile.srcs
+include ../../timing/Makefile.srcs
+include ../../opencores/Makefile.srcs
+include ../../vrt/Makefile.srcs
+include ../../udp/Makefile.srcs
+include ../../coregen/Makefile.srcs
+include ../../extramfifo/Makefile.srcs
+
+
+##################################################
+# Project Properties
+##################################################
+export PROJECT_PROPERTIES := \
+family "Spartan-3A DSP" \
+device xc3sd3400a \
+package fg676 \
+speed -5 \
+top_level_module_type "HDL" \
+synthesis_tool "XST (VHDL/Verilog)" \
+simulator "ISE Simulator (VHDL/Verilog)" \
+"Preferred Language" "Verilog" \
+"Enable Message Filtering" FALSE \
+"Display Incremental Messages" FALSE
+
+##################################################
+# Sources
+##################################################
+TOP_SRCS = \
+capture_ddrlvds.v \
+u2plus_core.v \
+u2plus.v \
+u2plus.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)
+
+##################################################
+# Process Properties
+##################################################
+SYNTHESIZE_PROPERTIES = \
+"Number of Clock Buffers" 8 \
+"Pack I/O Registers into IOBs" Yes \
+"Optimization Effort" High \
+"Optimize Instantiated Primitives" TRUE \
+"Register Balancing" Yes \
+"Use Clock Enable" Auto \
+"Use Synchronous Reset" Auto \
+"Use Synchronous Set" Auto \
+"Verilog Macros" "LVDS=1"
+
+TRANSLATE_PROPERTIES = \
+"Macro Search Path" "$(shell pwd)/../../coregen/"
+
+MAP_PROPERTIES = \
+"Allow Logic Optimization Across Hierarchy" TRUE \
+"Map to Input Functions" 4 \
+"Optimization Strategy (Cover Mode)" Speed \
+"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \
+"Perform Timing-Driven Packing and Placement" TRUE \
+"Map Effort Level" High \
+"Extra Effort" Normal \
+"Combinatorial Logic Optimization" TRUE \
+"Register Duplication" TRUE
+
+PLACE_ROUTE_PROPERTIES = \
+"Place & Route Effort Level (Overall)" High
+
+STATIC_TIMING_PROPERTIES = \
+"Number of Paths in Error/Verbose Report" 10 \
+"Report Type" "Error Report"
+
+GEN_PROG_FILE_PROPERTIES = \
+"Configuration Rate" 6 \
+"Create Binary Configuration File" TRUE \
+"Done (Output Events)" 5 \
+"Enable Bitstream Compression" TRUE \
+"Enable Outputs (Output Events)" 6
+
+SIM_MODEL_PROPERTIES = ""
diff --git a/fpga/usrp2/top/u2plus/bootloader.rmi b/fpga/usrp2/top/N2x0/bootloader.rmi
index e5be670fb..e5be670fb 100644
--- a/fpga/usrp2/top/u2plus/bootloader.rmi
+++ b/fpga/usrp2/top/N2x0/bootloader.rmi
diff --git a/fpga/usrp2/top/N2x0/capture_ddrlvds.v b/fpga/usrp2/top/N2x0/capture_ddrlvds.v
new file mode 100644
index 000000000..e261dcbe8
--- /dev/null
+++ b/fpga/usrp2/top/N2x0/capture_ddrlvds.v
@@ -0,0 +1,55 @@
+//
+// 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/>.
+//
+
+
+
+module capture_ddrlvds
+ #(parameter WIDTH=7)
+ (input clk,
+ input ssclk_p,
+ input ssclk_n,
+ input [WIDTH-1:0] in_p,
+ input [WIDTH-1:0] in_n,
+ output reg [(2*WIDTH)-1:0] out);
+
+ wire [WIDTH-1:0] ddr_dat;
+ wire ssclk;
+ wire [(2*WIDTH)-1:0] out_pre1;
+ reg [(2*WIDTH)-1:0] out_pre2;
+
+ IBUFGDS #(.IOSTANDARD("LVDS_33"), .DIFF_TERM("TRUE"))
+ clkbuf (.O(ssclk), .I(ssclk_p), .IB(ssclk_n));
+
+ genvar i;
+ generate
+ for(i = 0; i < WIDTH; i = i + 1)
+ begin : gen_lvds_pins
+ IBUFDS #(.IOSTANDARD("LVDS_33"),.DIFF_TERM("FALSE")) ibufds
+ (.O(ddr_dat[i]), .I(in_p[i]), .IB(in_n[i]) );
+ IDDR2 #(.DDR_ALIGNMENT("C1")) iddr2
+ (.Q0(out_pre1[2*i]), .Q1(out_pre1[(2*i)+1]), .C0(ssclk), .C1(~ssclk),
+ .CE(1'b1), .D(ddr_dat[i]), .R(1'b0), .S(1'b0));
+ end
+ endgenerate
+
+ always @(posedge clk)
+ out_pre2 <= out_pre1;
+
+ always @(posedge clk)
+ out <= out_pre2;
+
+endmodule // capture_ddrlvds
diff --git a/fpga/usrp2/top/u2plus/u2plus.ucf b/fpga/usrp2/top/N2x0/u2plus.ucf
index 5fbe55c26..5fbe55c26 100755
--- a/fpga/usrp2/top/u2plus/u2plus.ucf
+++ b/fpga/usrp2/top/N2x0/u2plus.ucf
diff --git a/fpga/usrp2/top/u2plus/u2plus.v b/fpga/usrp2/top/N2x0/u2plus.v
index 7c2270df6..be6cdeeca 100644
--- a/fpga/usrp2/top/u2plus/u2plus.v
+++ b/fpga/usrp2/top/N2x0/u2plus.v
@@ -1,4 +1,22 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
+//`define LVDS 1
//`define DCM_FOR_RAMCLK
//////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/u2plus/u2plus_core.v b/fpga/usrp2/top/N2x0/u2plus_core.v
index ee5d7efcd..8a7c6ddee 100644
--- a/fpga/usrp2/top/u2plus/u2plus_core.v
+++ b/fpga/usrp2/top/N2x0/u2plus_core.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// ////////////////////////////////////////////////////////////////////////////////
// Module Name: u2_core
// ////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/u2_rev3/.gitignore b/fpga/usrp2/top/USRP2/.gitignore
index f50a2b7e5..f50a2b7e5 100644
--- a/fpga/usrp2/top/u2_rev3/.gitignore
+++ b/fpga/usrp2/top/USRP2/.gitignore
diff --git a/fpga/usrp2/top/u2_rev3/Makefile b/fpga/usrp2/top/USRP2/Makefile
index e9b43491a..e9b43491a 100644
--- a/fpga/usrp2/top/u2_rev3/Makefile
+++ b/fpga/usrp2/top/USRP2/Makefile
diff --git a/fpga/usrp2/top/u2_rev3/u2_core.v b/fpga/usrp2/top/USRP2/u2_core.v
index 0e6120ec6..ca9762ac5 100644
--- a/fpga/usrp2/top/u2_rev3/u2_core.v
+++ b/fpga/usrp2/top/USRP2/u2_core.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// ////////////////////////////////////////////////////////////////////////////////
// Module Name: u2_core
// ////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/u2_rev3/u2_rev3.ucf b/fpga/usrp2/top/USRP2/u2_rev3.ucf
index 8017f61ff..8017f61ff 100644
--- a/fpga/usrp2/top/u2_rev3/u2_rev3.ucf
+++ b/fpga/usrp2/top/USRP2/u2_rev3.ucf
diff --git a/fpga/usrp2/top/u2_rev3/u2_rev3.v b/fpga/usrp2/top/USRP2/u2_rev3.v
index bc7ae5f16..4b0bb5541 100644
--- a/fpga/usrp2/top/u2_rev3/u2_rev3.v
+++ b/fpga/usrp2/top/USRP2/u2_rev3.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
diff --git a/fpga/usrp2/top/eth_test/.gitignore b/fpga/usrp2/top/eth_test/.gitignore
deleted file mode 100644
index b30397081..000000000
--- a/fpga/usrp2/top/eth_test/.gitignore
+++ /dev/null
@@ -1,43 +0,0 @@
-/xst
-/_ngo
-/_xmsgs
-/*.stx
-/*.tspec
-/*.xml
-/*.gyd
-/*.ngr
-/*.tim
-/*.err
-/*.lso
-/*.bld
-/*.cmd_log
-/*.ise_ISE_Backup
-/*.mfd
-/*.vm6
-/*.syr
-/*.xst
-/*.csv
-/*.html
-/*.jed
-/*.pad
-/*.ng*
-/*.pnx
-/*.rpt
-/*.prj
-/*_html
-/*_log
-/*.lfp
-/*.bit
-/*.bin
-/*.vcd
-/*.unroutes
-/*.drc
-/*_map.*
-/*_guide.*
-/*.twr
-/*.twx
-/a.out
-/*.xpi
-/*_pad.txt
-/*.bgn
-/*.par
diff --git a/fpga/usrp2/top/eth_test/eth_sim_top.v b/fpga/usrp2/top/eth_test/eth_sim_top.v
deleted file mode 100644
index 640a4e60f..000000000
--- a/fpga/usrp2/top/eth_test/eth_sim_top.v
+++ /dev/null
@@ -1,437 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// Module Name: u2_basic
-//////////////////////////////////////////////////////////////////////////////////
-
-module eth_sim_top
- (// Clocks
- input dsp_clk,
- input wb_clk,
- output clock_ready,
- input clk_to_mac,
- input pps_in,
-
- // Misc, debug
- output led1,
- output led2,
- output [31:0] debug,
- output [1:0] debug_clk,
-
- // Expansion
- input exp_pps_in,
- output exp_pps_out,
-
- // GMII
- // GMII-CTRL
- input GMII_COL,
- input GMII_CRS,
-
- // GMII-TX
- output [7:0] GMII_TXD,
- output GMII_TX_EN,
- output GMII_TX_ER,
- output GMII_GTX_CLK,
- input GMII_TX_CLK, // 100mbps clk
-
- // GMII-RX
- input [7:0] GMII_RXD,
- input GMII_RX_CLK,
- input GMII_RX_DV,
- input GMII_RX_ER,
-
- // GMII-Management
- inout MDIO,
- output MDC,
- input PHY_INTn, // open drain
- input PHY_RESETn,
- input PHY_CLK, // possibly use on-board osc
-
- // SERDES
- output ser_enable,
- output ser_prbsen,
- output ser_loopen,
- output ser_rx_en,
-
- output ser_tx_clk,
- output [15:0] ser_t,
- output ser_tklsb,
- output ser_tkmsb,
-
- input ser_rx_clk,
- input [15:0] ser_r,
- input ser_rklsb,
- input ser_rkmsb,
-
- // CPLD interface
- output cpld_start,
- output cpld_mode,
- output cpld_done,
- input cpld_din,
- input cpld_clk,
- input cpld_detached,
-
- // ADC
- input [13:0] adc_a,
- input adc_ovf_a,
- output adc_oen_a,
- output adc_pdn_a,
-
- input [13:0] adc_b,
- input adc_ovf_b,
- output adc_oen_b,
- output adc_pdn_b,
-
- // DAC
- output [15:0] dac_a,
- output [15:0] dac_b,
-
- // I2C
- input scl_pad_i,
- output scl_pad_o,
- output scl_pad_oen_o,
- input sda_pad_i,
- output sda_pad_o,
- output sda_pad_oen_o,
-
- // Clock Gen Control
- output [1:0] clk_en,
- output [1:0] clk_sel,
- input clk_func, // FIXME is an input to control the 9510
- input clk_status,
-
- // Generic SPI
- output sclk,
- output mosi,
- input miso,
- output sen_clk,
- output sen_dac,
- output sen_tx_db,
- output sen_tx_adc,
- output sen_tx_dac,
- output sen_rx_db,
- output sen_rx_adc,
- output sen_rx_dac,
-
- // GPIO to DBoards
- inout [15:0] io_tx,
- inout [15:0] io_rx
- );
-
- wire [7:0] set_addr;
- wire [31:0] set_data;
- wire set_stb;
-
- wire ram_loader_done;
- wire ram_loader_rst, wb_rst, dsp_rst;
-
- wire [31:0] ser_debug;
-
- //////////////////////////////////////////////////////////////////////////////////////////////////
- // Wishbone Single Master INTERCON
- parameter dw = 32; // Data bus width
- parameter aw = 16; // Address bus width, for byte addressibility, 16 = 64K byte memory space
- parameter sw = 4; // Select width -- 32-bit data bus with 8-bit granularity.
-
- wire [dw-1:0] m0_dat_o, m1_dat_o, m0_dat_i, m1_dat_i;
- wire [dw-1:0] s0_dat_o, s1_dat_o, s0_dat_i, s1_dat_i, s2_dat_o, s3_dat_o, s2_dat_i, s3_dat_i,
- s4_dat_o, s5_dat_o, s4_dat_i, s5_dat_i, s6_dat_o, s7_dat_o, s6_dat_i, s7_dat_i;
- wire [aw-1:0] m0_adr, m1_adr, s0_adr,s1_adr,s2_adr,s3_adr,s4_adr,s5_adr,s6_adr,s7_adr;
- wire [sw-1:0] m0_sel, m1_sel, s0_sel, s1_sel, s2_sel, s3_sel, s4_sel, s5_sel, s6_sel, s7_sel;
- wire m0_ack, m1_ack, s0_ack, s1_ack, s2_ack, s3_ack, s4_ack, s5_ack, s6_ack, s7_ack;
- wire m0_stb, m1_stb, s0_stb, s1_stb, s2_stb, s3_stb, s4_stb, s5_stb, s6_stb, s7_stb;
- wire m0_cyc, m1_cyc, s0_cyc, s1_cyc, s2_cyc, s3_cyc, s4_cyc, s5_cyc, s6_cyc, s7_cyc;
- wire m0_err, m1_err, s0_err, s1_err, s2_err, s3_err, s4_err, s5_err, s6_err, s7_err;
- wire m0_rty, m1_rty, s0_rty, s1_rty, s2_rty, s3_rty, s4_rty, s5_rty, s6_rty, s7_rty;
- wire m0_we, m1_we, s0_we, s1_we, s2_we, s3_we, s4_we, s5_we, s6_we, s7_we;
-
- wb_1master #(.s0_addr_w(2),.s0_addr(2'b00),.s1_addr_w(2),.s1_addr(2'b01),
- .s27_addr_w(4),.s2_addr(4'b1000),.s3_addr(4'b1001),.s4_addr(4'b1010),
- .s5_addr(4'b1011),.s6_addr(4'b1100),.s7_addr(4'b1101),
- .dw(dw),.aw(aw),.sw(sw)) wb_1master
- (.clk_i(wb_clk),.rst_i(wb_rst),
-
- .m0_dat_o(m0_dat_o),.m0_ack_o(m0_ack),.m0_err_o(m0_err),.m0_rty_o(m0_rty),.m0_dat_i(m0_dat_i),
- .m0_adr_i(m0_adr),.m0_sel_i(m0_sel),.m0_we_i(m0_we),.m0_cyc_i(m0_cyc),.m0_stb_i(m0_stb),
- .s0_dat_o(s0_dat_o),.s0_adr_o(s0_adr),.s0_sel_o(s0_sel),.s0_we_o (s0_we),.s0_cyc_o(s0_cyc),.s0_stb_o(s0_stb),
- .s0_dat_i(s0_dat_i),.s0_ack_i(s0_ack),.s0_err_i(s0_err),.s0_rty_i(s0_rty),
- .s1_dat_o(s1_dat_o),.s1_adr_o(s1_adr),.s1_sel_o(s1_sel),.s1_we_o (s1_we),.s1_cyc_o(s1_cyc),.s1_stb_o(s1_stb),
- .s1_dat_i(s1_dat_i),.s1_ack_i(s1_ack),.s1_err_i(s1_err),.s1_rty_i(s1_rty),
- .s2_dat_o(s2_dat_o),.s2_adr_o(s2_adr),.s2_sel_o(s2_sel),.s2_we_o (s2_we),.s2_cyc_o(s2_cyc),.s2_stb_o(s2_stb),
- .s2_dat_i(s2_dat_i),.s2_ack_i(s2_ack),.s2_err_i(s2_err),.s2_rty_i(s2_rty),
- .s3_dat_o(s3_dat_o),.s3_adr_o(s3_adr),.s3_sel_o(s3_sel),.s3_we_o (s3_we),.s3_cyc_o(s3_cyc),.s3_stb_o(s3_stb),
- .s3_dat_i(s3_dat_i),.s3_ack_i(s3_ack),.s3_err_i(s3_err),.s3_rty_i(s3_rty),
- .s4_dat_o(s4_dat_o),.s4_adr_o(s4_adr),.s4_sel_o(s4_sel),.s4_we_o (s4_we),.s4_cyc_o(s4_cyc),.s4_stb_o(s4_stb),
- .s4_dat_i(s4_dat_i),.s4_ack_i(s4_ack),.s4_err_i(s4_err),.s4_rty_i(s4_rty),
- .s5_dat_o(s5_dat_o),.s5_adr_o(s5_adr),.s5_sel_o(s5_sel),.s5_we_o (s5_we),.s5_cyc_o(s5_cyc),.s5_stb_o(s5_stb),
- .s5_dat_i(s5_dat_i),.s5_ack_i(s5_ack),.s5_err_i(s5_err),.s5_rty_i(s5_rty),
- .s6_dat_o(s6_dat_o),.s6_adr_o(s6_adr),.s6_sel_o(s6_sel),.s6_we_o (s6_we),.s6_cyc_o(s6_cyc),.s6_stb_o(s6_stb),
- .s6_dat_i(s6_dat_i),.s6_ack_i(s6_ack),.s6_err_i(s6_err),.s6_rty_i(s6_rty),
- .s7_dat_o(s7_dat_o),.s7_adr_o(s7_adr),.s7_sel_o(s7_sel),.s7_we_o (s7_we),.s7_cyc_o(s7_cyc),.s7_stb_o(s7_stb),
- .s7_dat_i(s7_dat_i),.s7_ack_i(s7_ack),.s7_err_i(s7_err),.s7_rty_i(s7_rty)
- );
-
- //////////////////////////////////////////////////////////////////////////////////////////
- // Reset Controller
- system_control sysctrl (.wb_clk_i(wb_clk),
- .ram_loader_rst_o(ram_loader_rst),
- .wb_rst_o(wb_rst),
- .ram_loader_done_i(ram_loader_done));
-
- // ///////////////////////////////////////////////////////////////////
- // RAM Loader
- wire iram_wr_stb, iram_rd_stb, iram_wr_ack, iram_rd_ack, iram_ack, iram_wr_we;
- wire [3:0] iram_wr_sel;
- wire [aw-1:0] iram_wr_adr, iram_rd_adr;
- wire [dw-1:0] iram_wr_dat, iram_rd_dat;
-
- wire bus_error, proc_int;
-
- assign iram_rd_ack = ram_loader_done ? iram_ack : 1'b0;
- assign iram_wr_ack = ram_loader_done ? 1'b0 : iram_ack;
-
- ram_loader #(.AWIDTH(16))
- ram_loader (.clk_i(wb_clk),.rst_i(ram_loader_rst),
- // CPLD Interface
- .cfg_clk_i(cpld_clk),
- .cfg_data_i(cpld_din),
- .start_o(cpld_start),
- .mode_o(cpld_mode),
- .done_o(cpld_done),
- .detached_i(cpld_detached),
- // Wishbone Interface
- .wb_dat_o(iram_wr_dat),.wb_adr_o(iram_wr_adr),
- .wb_stb_o(iram_wr_stb),.wb_cyc_o(),.wb_sel_o(iram_wr_sel),
- .wb_we_o(iram_wr_we),.wb_ack_i(iram_wr_ack),
- .ram_loader_done_o(ram_loader_done));
-
- // Processor
- aeMB_core_BE #(.ISIZ(16),.DSIZ(16))
- aeMB (.sys_clk_i(wb_clk), .sys_rst_i(wb_rst),
- // Instruction Wishbone bus to I-RAM
- .iwb_stb_o(iram_rd_stb),.iwb_adr_o(iram_rd_adr),
- .iwb_dat_i(iram_rd_dat),.iwb_ack_i(iram_rd_ack),
- // Data Wishbone bus to system bus fabric
- .dwb_we_o(m0_we),.dwb_stb_o(m0_stb),.dwb_dat_o(m0_dat_i),.dwb_adr_o(m0_adr),
- .dwb_dat_i(m0_dat_o),.dwb_ack_i(m0_ack),.dwb_sel_o(m0_sel),.dwb_cyc_o(m0_cyc),
- // Interrupts and exceptions
- .sys_int_i(proc_int),.sys_exc_i(bus_error) );
-
- assign bus_error = m0_err | m0_rty;
- assign proc_int = 1'b0;
-
- // Dual Ported RAM -- D-Port is Slave #0 on main Wishbone
- // I-port connects directly to processor and ram loader
-
- ram_wb_harvard #(.AWIDTH(14))
- ID_ram (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
-
- .iwb_adr_i(ram_loader_done ? iram_rd_adr : iram_wr_adr),.iwb_dat_i(iram_wr_dat),.iwb_dat_o(iram_rd_dat),
- .iwb_we_i(iram_wr_we),.iwb_ack_o(iram_ack),.iwb_stb_i(ram_loader_done ? iram_rd_stb : iram_wr_stb),
- .iwb_sel_i(ram_loader_done ? 4'b1111 : iram_wr_sel),
-
- .dwb_adr_i(s0_adr),.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));
-
- assign s0_err = 1'b0;
- assign s0_rty = 1'b0;
-
- // Buffer Pool, slave #1
- wire rd0_read, rd0_ready, rd0_done, rd0_empty;
- wire rd1_read, rd1_ready, rd1_done, rd1_empty;
- wire rd2_read, rd2_ready, rd2_done, rd2_empty;
- wire rd3_read, rd3_ready, rd3_done, rd3_empty;
- wire [31:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
-
- wire wr0_write, wr0_done, wr0_ready, wr0_full;
- wire wr1_write, wr1_done, wr1_ready, wr1_full;
- wire wr2_write, wr2_done, wr2_ready, wr2_full;
- wire wr3_write, wr3_done, wr3_ready, wr3_full;
- wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
-
-/*
- buffer_pool buffer_pool
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
- .wb_we_i(s1_we),.wb_stb_i(s1_stb),.wb_adr_i(s1_adr),.wb_dat_i(s1_dat_o),
- .wb_dat_o(s1_dat_i),.wb_ack_o(s1_ack),.wb_err_o(s1_err),.wb_rty_o(s1_rty),
-
- .stream_clk(dsp_clk),.stream_rst(dsp_rst),
- // Write Interfaces
- .wr0_dat_i(),.wr0_write_i(),.wr0_done_i(),.wr0_ready_o(),.wr0_full_o(),
- .wr1_dat_i(),.wr1_write_i(),.wr1_done_i(),.wr1_ready_o(),.wr1_full_o(),
- .wr2_dat_i(),.wr2_write_i(),.wr2_done_i(),.wr2_ready_o(),.wr2_full_o(),
- .wr3_dat_i(),.wr3_write_i(),.wr3_done_i(),.wr3_ready_o(),.wr3_full_o(),
- // Read Interfaces
- .rd0_dat_o(rd0_dat),.rd0_read_i(rd0_read),.rd0_done_i(),.rd0_ready_o(rd0_ready),.rd0_empty_o(rd0_empty),
- .rd1_dat_o(rd1_dat),.rd1_read_i(rd1_read),.rd1_done_i(),.rd1_ready_o(rd1_ready),.rd1_empty_o(rd1_empty),
- .rd2_dat_o(rd2_dat),.rd2_read_i(rd2_read),.rd2_done_i(),.rd2_ready_o(rd2_ready),.rd2_empty_o(rd2_empty),
- .rd3_dat_o(rd3_dat),.rd3_read_i(rd3_read),.rd3_done_i(),.rd3_ready_o(rd3_ready),.rd3_empty_o(rd3_empty)
- );
-*/
- // SPI -- Slave #2
- spi_top shared_spi
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.wb_adr_i(s2_adr),.wb_dat_i(s2_dat_o),.wb_dat_o(s2_dat_i),
- .wb_sel_i(s2_sel),.wb_we_i(s2_we),.wb_stb_i(s2_stb),.wb_cyc_i(s2_cyc),.wb_ack_o(s2_ack),
-
- .wb_err_o(s2_err),.wb_int_o(s2_int),
- .ss_pad_o({sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
- .sclk_pad_o(sclk),.mosi_pad_o(mosi),.miso_pad_i(miso) );
-
- assign s2_rty = 1'b0;
-
- // I2C -- Slave #3
- i2c_master_top #(.ARST_LVL(1))
- i2c (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.arst_i(1'b0),
- .wb_adr_i(s3_adr),.wb_dat_i(s3_dat_o),.wb_dat_o(s3_dat_i),
- .wb_we_i(s3_we),.wb_stb_i(s3_stb),.wb_cyc_i(s3_cyc),
- .wb_ack_o(s3_ack),.wb_inta_o(st_int),
- .scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_pad_oen_o),
- .sda_pad_i(sda_pad_i),.sda_pad_o(sda_pad_o),.sda_padoen_o(sda_pad_oen_o) );
-
- assign s3_err = 1'b0;
- assign s3_rty = 1'b0;
-
- // GPIOs -- Slave #4
- wire s4_ack_a, s4_ack_b, s4_ack_c, s4_ack_d;
- assign s4_ack = s4_ack_a | s4_ack_b | s4_ack_c | s4_ack_d;
-
- simple_gpio gpio_a(.clk_i(wb_clk),.rst_i(~wb_rst),
- .cyc_i(s4_cyc),.stb_i(s4_stb&s4_sel[0]),.adr_i(s4_adr[2]),.we_i(s4_we),
- .dat_i(s4_dat_o[7:0]),.dat_o(s4_dat_i[7:0]),.ack_o(s4_ack_a),
- .gpio(/* io_tx[7:0]*/) );
-
- simple_gpio gpio_b(.clk_i(wb_clk),.rst_i(~wb_rst),
- .cyc_i(s4_cyc),.stb_i(s4_stb&s4_sel[1]),.adr_i(s4_adr[2]),.we_i(s4_we),
- .dat_i(s4_dat_o[15:8]),.dat_o(s4_dat_i[15:8]),.ack_o(s4_ack_b),
- .gpio(/* io_tx[15:8] */) );
-
- simple_gpio gpio_c(.clk_i(wb_clk),.rst_i(~wb_rst),
- .cyc_i(s4_cyc),.stb_i(s4_stb&s4_sel[2]),.adr_i(s4_adr[2]),.we_i(s4_we),
- .dat_i(s4_dat_o[23:16]),.dat_o(s4_dat_i[23:16]),.ack_o(s4_ack_c),
- .gpio(/* io_rx[7:0] */) );
-
- simple_gpio gpio_d(.clk_i(wb_clk),.rst_i(~wb_rst),
- .cyc_i(s4_cyc),.stb_i(s4_stb&s4_sel[3]),.adr_i(s4_adr[2]),.we_i(s4_we),
- .dat_i(s4_dat_o[31:24]),.dat_o(s4_dat_i[31:24]),.ack_o(s4_ack_d),
- .gpio(/* io_rx[15:8]*/) );
-
- assign s4_err = 1'b0;
- assign s4_rty = 1'b0;
-
- // Output control lines, SLAVE #5
- wire [7:0] clock_outs, serdes_outs, adc_outs, misc_outs;
- assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0];
- assign {ser_enable, ser_prbsen, ser_loopen, ser_rx_en} = serdes_outs[3:0];
- assign { adc_oen_a, adc_pdn_a, adc_oen_b, adc_pdn_b } = adc_outs[3:0];
- assign {led2, led1} = misc_outs[1:0];
-
- wb_output_pins32 control_lines
- (.wb_rst_i(wb_rst),.wb_clk_i(wb_clk),.wb_dat_i(s5_dat_o),.wb_dat_o(s5_dat_i),
- .wb_we_i(s5_we),.wb_sel_i(s5_sel),.wb_stb_i(s5_stb),.wb_ack_o(s5_ack),.wb_cyc_i(s5_cyc),
- .port_output( {clock_outs,serdes_outs,adc_outs,misc_outs} ) );
-
- assign s5_err = 1'b0;
- assign s5_rty = 1'b0;
-
- // Ethernet slave, #6
- eth_wrapper eth_wrapper
- (.Reset(wb_rst),.Clk_125M(),.Clk_user(stream_clk),.Clk_reg(wb_clk),.Speed(),
- .Gtx_clk(GMII_GTX_CLK),.Rx_clk(GMII_RX_CLK),.Tx_clk(GMII_TX_CLK),//used only in MII mode
- .Tx_er(GMII_TX_ER),.Tx_en(GMII_TX_EN),.Txd(GMII_TXD),.Rx_er(GMII_RX_ER),
- .Rx_dv(GMII_RX_DV),.Rxd(GMII_RXD),.Crs(GMII_CRS),.Col(GMII_COL),
- .Mdio(MDIO),.Mdc(MDC),
- // FIFO Interfaces
- .wr_dat_o(),.wr_write_o(),.wr_done_o(),.wr_ready_i(),.wr_full_i(),
- .rd_dat_i(),.rd_read_o(),.rd_done_o(),.rd_ready_i(),.rd_empty_i(),
- // Wishbone
- .wb_dat_i(s6_dat_o),.wb_dat_o(s6_dat_i),.wb_adr_i(s6_adr),.wb_stb_i(s6_stb),.wb_we_i(s6_we),.wb_ack_o(s6_ack)
- );
-
- assign s6_err = 1'b0;
- assign s6_rty = 1'b0;
-
- // Settings Bus -- Slave #7
- settings_bus settings_bus
- (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s7_adr),.wb_dat_i(s7_dat_o),
- .wb_stb_i(s7_stb),.wb_we_i(s7_we),.wb_ack_o(s7_ack),
- .sys_clk(dsp_clk),.strobe(set_stb),.addr(set_addr),.data(set_data));
-
- assign s7_err = 1'b0;
- assign s7_rty = 1'b0;
- assign s7_dat_i = 32'd0;
-
- ///////////////////////////////////////////////////////////////////////////
- // DSP
- reg [13:0] adc_a_reg1, adc_b_reg1, adc_a_reg2, adc_b_reg2;
- reg adc_ovf_a_reg1, adc_ovf_a_reg2, adc_ovf_b_reg1, adc_ovf_b_reg2;
-
- always @(posedge dsp_clk)
- begin
- adc_a_reg1 <= adc_a;
- adc_a_reg2 <= adc_a_reg1;
- adc_b_reg1 <= adc_b;
- adc_b_reg2 <= adc_b_reg1;
- adc_ovf_a_reg1 <= adc_ovf_a;
- adc_ovf_a_reg2 <= adc_ovf_a_reg1;
- adc_ovf_b_reg1 <= adc_ovf_b;
- adc_ovf_b_reg2 <= adc_ovf_b_reg1;
- end // always @ (posedge dsp_clk)
-
- dsp_core_rx dsp_core_rx
- (.clk(dsp_clk),.rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .rx_dat_o(wr1_dat),.rx_write_o(wr1_write),.rx_done_o(wr1_done),
- .rx_ready_i(wr1_ready),.rx_full_i(wr1_full),
- .overrun() );
-
- dsp_core_tx dsp_core_tx
- (.clk(dsp_clk),.rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .dac_a(dac_a),.dac_b(dac_b),
- .tx_dat_i(rd1_dat),.tx_read_o(rd1_read),.tx_done_o(rd1_done),
- .tx_ready_i(rd1_ready),.tx_empty_i(rd1_empty),
- .underrun() );
-
- assign dsp_rst = wb_rst;
-
- /////////////////////////////////////////////////////////////////////////////////////
- // SERDES
- serdes_tx serdes_tx
- (.clk(dsp_clk),.rst(dsp_rst),
- .ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb),
- .fifo_data_i(rd0_dat),.fifo_read_o(rd0_read),.fifo_done_o(rd0_done),
- .fifo_ready_i(rd0_ready),.fifo_empty_i(rd0_empty)
- );
-
- serdes_rx serdes_rx
- (.clk(dsp_clk),.rst(dsp_rst),
- .ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb),
- .fifo_data_o(wr0_dat),.fifo_wr_o(wr0_write),.fifo_ready_i(wr0_ready),.fifo_done_i(wr0_done)
- );
-
- // Debug Pins
- wire [31:0] debug1={{1'b0,ram_loader_done,clock_ready,dsp_clk,wb_clk,ram_loader_rst,wb_rst,dsp_rst},
- {1'b0,cpld_start,cpld_mode,cpld_done,1'b0,cpld_din,cpld_clk,cpld_detached},
- {8'hAF},
- {2'b0, clk_status, sen_dac, sen_clk, sclk, mosi, miso}};
-
- wire [31:0] debug_wb={{iram_wr_we,ram_loader_done,clock_ready,iram_wr_ack,iram_wr_stb,ram_loader_rst,wb_rst,dsp_rst},
- {iram_rd_adr[15:8]},
- {iram_rd_adr[7:0]},
- {serdes_outs}};
-
- assign io_rx = ser_debug[31:16];
- assign io_tx = ser_debug[15:0];
-
- assign debug = debug_wb;
-
- assign debug_clk[0] = wb_clk;
- assign debug_clk[1] = dsp_clk;
-
-endmodule // eth_test
-
-
-// Local Variables:
-// verilog-library-directories:("." "subdir" "subdir2")
-// verilog-library-files:("/home/matt/u2f/opencores/wb_conbus/rtl/verilog/wb_conbus_top.v")
-// verilog-library-extensions:(".v" ".h")
-// End:
diff --git a/fpga/usrp2/top/eth_test/eth_tb.v b/fpga/usrp2/top/eth_test/eth_tb.v
deleted file mode 100644
index 451ce1e7e..000000000
--- a/fpga/usrp2/top/eth_test/eth_tb.v
+++ /dev/null
@@ -1,257 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-
-// Nearly everything is an input
-
-module eth_tb();
- // Misc, debug
- wire led1;
- wire led2;
- wire [31:0] debug;
- wire [1:0] debug_clk;
-
- // Expansion
- wire exp_pps_in;
- wire exp_pps_out;
-
- // GMII
- // GMII-CTRL
- wire GMII_COL;
- wire GMII_CRS;
-
- // GMII-TX
- wire [7:0] GMII_TXD;
- wire GMII_TX_EN;
- wire GMII_TX_ER;
- wire GMII_GTX_CLK;
- wire GMII_TX_CLK; // 100mbps clk
-
- // GMII-RX
- wire [7:0] GMII_RXD;
- wire GMII_RX_CLK;
- wire GMII_RX_DV;
- wire GMII_RX_ER;
-
- // GMII-Management
- wire MDIO;
- wire MDC;
- wire PHY_INTn; // open drain
- wire PHY_RESETn;
- wire PHY_CLK; // possibly use on-board osc
-
- // RAM
- wire [17:0] RAM_D;
- wire [18:0] RAM_A;
- wire RAM_CE1n;
- wire RAM_CENn;
- wire RAM_CLK;
- wire RAM_WEn;
- wire RAM_OEn;
- wire RAM_LDn;
-
- // SERDES
- wire ser_enable;
- wire ser_prbsen;
- wire ser_loopen;
- wire ser_rx_en;
-
- wire ser_tx_clk;
- wire [15:0] ser_t;
- wire ser_tklsb;
- wire ser_tkmsb;
-
- wire ser_rx_clk;
- wire [15:0] ser_r;
- wire ser_rklsb;
- wire ser_rkmsb;
-
- // CPLD interface
- wire cpld_din, cpld_clk, cpld_detached, cpld_start, cpld_mode, cpld_done;
-
- // ADC
- wire [13:0] adc_a;
- wire adc_ovf_a;
- wire adc_oen_a;
- wire adc_pdn_a;
-
- wire [13:0] adc_b;
- wire adc_ovf_b;
- wire adc_oen_b;
- wire adc_pdn_b;
-
- // DAC
- wire [15:0] dac_a;
- wire [15:0] dac_b;
-
- // I2C
- wire SCL;
- wire SDA;
-
- // Clock Gen Control
- wire [1:0] clk_en;
- wire [1:0] clk_sel;
- wire clk_func; // FIXME is an input to control the 9510
- wire clk_status;
-
- // Clocks
- reg clk_fpga;
- wire clk_to_mac;
- wire pps_in;
-
- // Generic SPI
- wire sclk, mosi, miso;
- wire sen_clk;
- wire sen_dac;
- wire sen_tx_db;
- wire sen_tx_adc;
- wire sen_tx_dac;
- wire sen_rx_db;
- wire sen_rx_adc;
- wire sen_rx_dac;
-
- // GPIO to DBoards
- wire [15:0] io_tx;
- wire [15:0] io_rx;
-
- wire wb_clk, wb_rst;
- wire start, clock_ready;
-
- reg aux_clk;
-
- initial aux_clk= 1'b0;
- always #25 aux_clk = ~aux_clk;
-
- initial clk_fpga = 1'bx;
- initial #3007 clk_fpga = 1'b0;
- always #7 clk_fpga = ~clk_fpga;
-
-
- wire div_clk;
- reg [2:0] div_ctr = 0;
-
- always @(posedge clk_fpga or negedge clk_fpga)
- if(div_ctr==5)
- div_ctr = 0;
- else
- div_ctr = div_ctr + 1;
- assign div_clk = (div_ctr == 0) | (div_ctr == 1) | (div_ctr == 2);
-
- assign dsp_clk = clk_fpga;
- assign wb_clk = clock_ready ? div_clk : aux_clk;
-
- initial
- $monitor($time, ,clock_ready);
-
- initial begin
- $dumpfile("eth_tb.vcd");
- $dumpvars(0,eth_tb);
- end
-
- initial #10000000 $finish;
-
- cpld_model
- cpld_model (.aux_clk(aux_clk),.start(cpld_start),.mode(cpld_mode),.done(cpld_done),
- .dout(cpld_din),.sclk(cpld_clk),.detached(cpld_detached));
-
- eth_sim_top eth_sim_top(.dsp_clk (dsp_clk),
- .wb_clk (wb_clk),
- .clock_ready (clock_ready),
- .clk_to_mac (clk_to_mac),
- .pps_in (pps_in),
- .led1 (led1),
- .led2 (led2),
- .debug (debug[31:0]),
- .debug_clk (debug_clk[1:0]),
- .exp_pps_in (exp_pps_in),
- .exp_pps_out (exp_pps_out),
- .GMII_COL (GMII_COL),
- .GMII_CRS (GMII_CRS),
- .GMII_TXD (GMII_TXD[7:0]),
- .GMII_TX_EN (GMII_TX_EN),
- .GMII_TX_ER (GMII_TX_ER),
- .GMII_GTX_CLK (GMII_GTX_CLK),
- .GMII_TX_CLK (GMII_TX_CLK),
- .GMII_RXD (GMII_RXD[7:0]),
- .GMII_RX_CLK (GMII_RX_CLK),
- .GMII_RX_DV (GMII_RX_DV),
- .GMII_RX_ER (GMII_RX_ER),
- .MDIO (MDIO),
- .MDC (MDC),
- .PHY_INTn (PHY_INTn),
- .PHY_RESETn (PHY_RESETn),
- .PHY_CLK (PHY_CLK),
- .ser_enable (ser_enable),
- .ser_prbsen (ser_prbsen),
- .ser_loopen (ser_loopen),
- .ser_rx_en (ser_rx_en),
- .ser_tx_clk (ser_tx_clk),
- .ser_t (ser_t[15:0]),
- .ser_tklsb (ser_tklsb),
- .ser_tkmsb (ser_tkmsb),
- .ser_rx_clk (ser_rx_clk),
- .ser_r (ser_r[15:0]),
- .ser_rklsb (ser_rklsb),
- .ser_rkmsb (ser_rkmsb),
- .cpld_start (cpld_start),
- .cpld_mode (cpld_mode),
- .cpld_done (cpld_done),
- .cpld_din (cpld_din),
- .cpld_clk (cpld_clk),
- .cpld_detached (cpld_detached),
- .adc_a (adc_a[13:0]),
- .adc_ovf_a (adc_ovf_a),
- .adc_oen_a (adc_oen_a),
- .adc_pdn_a (adc_pdn_a),
- .adc_b (adc_b[13:0]),
- .adc_ovf_b (adc_ovf_b),
- .adc_oen_b (adc_oen_b),
- .adc_pdn_b (adc_pdn_b),
- .dac_a (dac_a[15:0]),
- .dac_b (dac_b[15:0]),
- .scl_pad_i (scl_pad_i),
- .scl_pad_o (scl_pad_o),
- .scl_pad_oen_o (scl_pad_oen_o),
- .sda_pad_i (sda_pad_i),
- .sda_pad_o (sda_pad_o),
- .sda_pad_oen_o (sda_pad_oen_o),
- .clk_en (clk_en[1:0]),
- .clk_sel (clk_sel[1:0]),
- .clk_func (clk_func),
- .clk_status (clk_status),
- .sclk (sclk),
- .mosi (mosi),
- .miso (miso),
- .sen_clk (sen_clk),
- .sen_dac (sen_dac),
- .sen_tx_db (sen_tx_db),
- .sen_tx_adc (sen_tx_adc),
- .sen_tx_dac (sen_tx_dac),
- .sen_rx_db (sen_rx_db),
- .sen_rx_adc (sen_rx_adc),
- .sen_rx_dac (sen_rx_dac),
- .io_tx (io_tx[15:0]),
- .io_rx (io_rx[15:0]));
-
- // Experimental printf-like function
- always @(posedge wb_clk)
- begin
- if((eth_sim_top.m0_we == 1'd1)&&(eth_sim_top.m0_adr == 16'hC000))
- $write("%x",eth_sim_top.m0_dat_i);
- if((eth_sim_top.m0_we == 1'd1)&&(eth_sim_top.m0_adr == 16'hC100))
- $display("%x",eth_sim_top.m0_dat_i);
- if((eth_sim_top.m0_we == 1'd1)&&(eth_sim_top.m0_adr == 16'hC004))
- $write("%c",eth_sim_top.m0_dat_i);
- if((eth_sim_top.m0_we == 1'd1)&&(eth_sim_top.m0_adr == 16'hC104))
- $display("%c",eth_sim_top.m0_dat_i);
- if((eth_sim_top.m0_we == 1'd1)&&(eth_sim_top.m0_adr == 16'hC008))
- $display("");
- end
-
-
-endmodule // u2_sim_top
-
-// Local Variables:
-// verilog-library-directories:("." "subdir" "subdir2")
-// verilog-library-files:("/home/matt/u2f/top/u2_basic/u2_basic.v")
-// verilog-library-extensions:(".v" ".h")
-// End:
diff --git a/fpga/usrp2/top/safe_u2plus/.gitignore b/fpga/usrp2/top/safe_u2plus/.gitignore
deleted file mode 100644
index a96f0be92..000000000
--- a/fpga/usrp2/top/safe_u2plus/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-build*
-*impact*
diff --git a/fpga/usrp2/top/safe_u2plus/Makefile b/fpga/usrp2/top/safe_u2plus/Makefile
deleted file mode 100644
index b72241050..000000000
--- a/fpga/usrp2/top/safe_u2plus/Makefile
+++ /dev/null
@@ -1,245 +0,0 @@
-#
-# Copyright 2008 Ettus Research LLC
-#
-# 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-##################################################
-# xtclsh Shell and tcl Script Path
-##################################################
-#XTCLSH := /opt/Xilinx/10.1/ISE/bin/lin/xtclsh
-XTCLSH := xtclsh
-ISE_HELPER := ../tcl/ise_helper.tcl
-
-##################################################
-# Project Setup
-##################################################
-BUILD_DIR := build/
-export TOP_MODULE := safe_u2plus
-export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
-
-##################################################
-# Project Properties
-##################################################
-export PROJECT_PROPERTIES := \
-family "Spartan-3A DSP" \
-device xc3sd3400a \
-package fg676 \
-speed -5 \
-top_level_module_type "HDL" \
-synthesis_tool "XST (VHDL/Verilog)" \
-simulator "ISE Simulator (VHDL/Verilog)" \
-"Preferred Language" "Verilog" \
-"Enable Message Filtering" FALSE \
-"Display Incremental Messages" FALSE
-
-##################################################
-# Sources
-##################################################
-export SOURCE_ROOT := ../../../
-export SOURCES := \
-control_lib/CRC16_D16.v \
-control_lib/atr_controller.v \
-control_lib/bin2gray.v \
-control_lib/dcache.v \
-control_lib/decoder_3_8.v \
-control_lib/dpram32.v \
-control_lib/gray2bin.v \
-control_lib/gray_send.v \
-control_lib/icache.v \
-control_lib/mux4.v \
-control_lib/mux8.v \
-control_lib/nsgpio.v \
-control_lib/ram_2port.v \
-control_lib/ram_harv_cache.v \
-control_lib/ram_loader.v \
-control_lib/setting_reg.v \
-control_lib/settings_bus.v \
-control_lib/srl.v \
-control_lib/system_control.v \
-control_lib/wb_1master.v \
-control_lib/wb_readback_mux.v \
-control_lib/simple_uart.v \
-control_lib/simple_uart_tx.v \
-control_lib/simple_uart_rx.v \
-control_lib/oneshot_2clk.v \
-control_lib/sd_spi.v \
-control_lib/sd_spi_wb.v \
-control_lib/wb_bridge_16_32.v \
-control_lib/reset_sync.v \
-simple_gemac/simple_gemac_wrapper.v \
-simple_gemac/simple_gemac.v \
-simple_gemac/simple_gemac_wb.v \
-simple_gemac/simple_gemac_tx.v \
-simple_gemac/simple_gemac_rx.v \
-simple_gemac/crc.v \
-simple_gemac/delay_line.v \
-simple_gemac/flow_ctrl_tx.v \
-simple_gemac/flow_ctrl_rx.v \
-simple_gemac/address_filter.v \
-simple_gemac/ll8_to_txmac.v \
-simple_gemac/rxmac_to_ll8.v \
-simple_gemac/miim/eth_miim.v \
-simple_gemac/miim/eth_clockgen.v \
-simple_gemac/miim/eth_outputcontrol.v \
-simple_gemac/miim/eth_shiftreg.v \
-control_lib/newfifo/buffer_int.v \
-control_lib/newfifo/buffer_pool.v \
-control_lib/newfifo/fifo_2clock.v \
-control_lib/newfifo/fifo_2clock_cascade.v \
-control_lib/newfifo/ll8_shortfifo.v \
-control_lib/newfifo/ll8_to_fifo36.v \
-control_lib/newfifo/fifo_short.v \
-control_lib/newfifo/fifo_long.v \
-control_lib/newfifo/fifo_cascade.v \
-control_lib/newfifo/fifo36_to_ll8.v \
-control_lib/longfifo.v \
-control_lib/shortfifo.v \
-control_lib/medfifo.v \
-coregen/fifo_xlnx_2Kx36_2clk.v \
-coregen/fifo_xlnx_2Kx36_2clk.xco \
-coregen/fifo_xlnx_512x36_2clk.v \
-coregen/fifo_xlnx_512x36_2clk.xco \
-coregen/fifo_xlnx_64x36_2clk.v \
-coregen/fifo_xlnx_64x36_2clk.xco \
-opencores/8b10b/decode_8b10b.v \
-opencores/8b10b/encode_8b10b.v \
-opencores/aemb/rtl/verilog/aeMB_bpcu.v \
-opencores/aemb/rtl/verilog/aeMB_core_BE.v \
-opencores/aemb/rtl/verilog/aeMB_ctrl.v \
-opencores/aemb/rtl/verilog/aeMB_edk32.v \
-opencores/aemb/rtl/verilog/aeMB_ibuf.v \
-opencores/aemb/rtl/verilog/aeMB_regf.v \
-opencores/aemb/rtl/verilog/aeMB_xecu.v \
-opencores/i2c/rtl/verilog/i2c_master_bit_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_byte_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_defines.v \
-opencores/i2c/rtl/verilog/i2c_master_top.v \
-opencores/i2c/rtl/verilog/timescale.v \
-opencores/simple_pic/rtl/simple_pic.v \
-opencores/spi/rtl/verilog/spi_clgen.v \
-opencores/spi/rtl/verilog/spi_defines.v \
-opencores/spi/rtl/verilog/spi_shift.v \
-opencores/spi/rtl/verilog/spi_top.v \
-opencores/spi/rtl/verilog/timescale.v \
-sdr_lib/acc.v \
-sdr_lib/add2.v \
-sdr_lib/add2_and_round.v \
-sdr_lib/add2_and_round_reg.v \
-sdr_lib/add2_reg.v \
-sdr_lib/cic_dec_shifter.v \
-sdr_lib/cic_decim.v \
-sdr_lib/cic_int_shifter.v \
-sdr_lib/cic_interp.v \
-sdr_lib/cic_strober.v \
-sdr_lib/clip.v \
-sdr_lib/clip_reg.v \
-sdr_lib/cordic.v \
-sdr_lib/cordic_z24.v \
-sdr_lib/cordic_stage.v \
-sdr_lib/dsp_core_rx.v \
-sdr_lib/dsp_core_tx.v \
-sdr_lib/hb_dec.v \
-sdr_lib/hb_interp.v \
-sdr_lib/round.v \
-sdr_lib/round_reg.v \
-sdr_lib/rx_control.v \
-sdr_lib/rx_dcoffset.v \
-sdr_lib/sign_extend.v \
-sdr_lib/small_hb_dec.v \
-sdr_lib/small_hb_int.v \
-sdr_lib/tx_control.v \
-serdes/serdes.v \
-serdes/serdes_fc_rx.v \
-serdes/serdes_fc_tx.v \
-serdes/serdes_rx.v \
-serdes/serdes_tx.v \
-timing/time_receiver.v \
-timing/time_sender.v \
-timing/time_sync.v \
-timing/timer.v \
-top/u2_core/u2_core.v \
-top/u2plus/capture_ddrlvds.v \
-top/safe_u2plus/u2plus.ucf \
-top/safe_u2plus/safe_u2plus.v
-
-##################################################
-# Process Properties
-##################################################
-export SYNTHESIZE_PROPERTIES := \
-"Number of Clock Buffers" 6 \
-"Pack I/O Registers into IOBs" Yes \
-"Optimization Effort" High \
-"Optimize Instantiated Primitives" TRUE \
-"Register Balancing" Yes \
-"Use Clock Enable" Auto \
-"Use Synchronous Reset" Auto \
-"Use Synchronous Set" Auto
-
-export TRANSLATE_PROPERTIES := \
-"Macro Search Path" "$(shell pwd)/../../coregen/"
-
-export MAP_PROPERTIES := \
-"Allow Logic Optimization Across Hierarchy" TRUE \
-"Map to Input Functions" 4 \
-"Optimization Strategy (Cover Mode)" Speed \
-"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \
-"Perform Timing-Driven Packing and Placement" TRUE \
-"Map Effort Level" High \
-"Extra Effort" Normal \
-"Combinatorial Logic Optimization" TRUE \
-"Register Duplication" TRUE
-
-export PLACE_ROUTE_PROPERTIES := \
-"Place & Route Effort Level (Overall)" High
-
-export STATIC_TIMING_PROPERTIES := \
-"Number of Paths in Error/Verbose Report" 10 \
-"Report Type" "Error Report"
-
-export GEN_PROG_FILE_PROPERTIES := \
-"Configuration Rate" 6 \
-"Create Binary Configuration File" TRUE \
-"Done (Output Events)" 5 \
-"Enable Bitstream Compression" TRUE \
-"Enable Outputs (Output Events)" 6
-
-export SIM_MODEL_PROPERTIES := ""
-
-##################################################
-# Make Options
-##################################################
-all:
- @echo make proj, check, synth, bin, or clean
-
-proj:
- PROCESS_RUN="" $(XTCLSH) $(ISE_HELPER)
-
-check:
- PROCESS_RUN="Check Syntax" $(XTCLSH) $(ISE_HELPER)
-
-synth:
- PROCESS_RUN="Synthesize - XST" $(XTCLSH) $(ISE_HELPER)
-
-bin:
- PROCESS_RUN="Generate Programming File" $(XTCLSH) $(ISE_HELPER)
-
-clean:
- rm -rf $(BUILD_DIR)
-
-
diff --git a/fpga/usrp2/top/safe_u2plus/safe_u2plus.v b/fpga/usrp2/top/safe_u2plus/safe_u2plus.v
deleted file mode 100644
index dca9688c5..000000000
--- a/fpga/usrp2/top/safe_u2plus/safe_u2plus.v
+++ /dev/null
@@ -1,23 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-
-module safe_u2plus
- (
- input CLK_FPGA_P, input CLK_FPGA_N, // Diff
- output [5:1] leds, // LED4 is shared w/INIT_B
- output ETH_LED
- );
-
- wire clk_fpga;
-
- IBUFGDS clk_fpga_pin (.O(clk_fpga),.I(CLK_FPGA_P),.IB(CLK_FPGA_N));
- defparam clk_fpga_pin.IOSTANDARD = "LVPECL_25";
-
- reg [31:0] ctr;
-
- always @(posedge clk_fpga)
- ctr <= ctr + 1;
-
- assign {leds,ETH_LED} = ~ctr[29:24];
-
-endmodule // safe_u2plus
diff --git a/fpga/usrp2/top/safe_u2plus/u2plus.ucf b/fpga/usrp2/top/safe_u2plus/u2plus.ucf
deleted file mode 100755
index 0a9460d86..000000000
--- a/fpga/usrp2/top/safe_u2plus/u2plus.ucf
+++ /dev/null
@@ -1,401 +0,0 @@
-## Main 100 MHz Clock
-NET "CLK_FPGA_P" LOC = "AA13" ;
-NET "CLK_FPGA_N" LOC = "Y13" ;
-
-## ADC
-#NET "ADC_clkout_p" LOC = "P1" ;
-#NET "ADC_clkout_n" LOC = "P2" ;
-#NET "ADCA_12_p" LOC = "Y1" ;
-#NET "ADCA_12_n" LOC = "Y2" ;
-#NET "ADCA_10_p" LOC = "W3" ;
-#NET "ADCA_10_n" LOC = "W4" ;
-#NET "ADCA_8_p" LOC = "T7" ;
-#NET "ADCA_8_n" LOC = "U6" ;
-#NET "ADCA_6_p" LOC = "U5" ;
-#NET "ADCA_6_n" LOC = "V5" ;
-#NET "ADCA_4_p" LOC = "T10" ;
-#NET "ADCA_4_n" LOC = "T9" ;
-#NET "ADCA_2_p" LOC = "V1" ;
-#NET "ADCA_2_n" LOC = "V2" ;
-#NET "ADCA_0_p" LOC = "R8" ;
-#NET "ADCA_0_n" LOC = "R7" ;
-#NET "ADCB_2_p" LOC = "U7" ;
-#NET "ADCB_2_n" LOC = "U8" ;
-#NET "ADCB_0_p" LOC = "AA2" ;
-#NET "ADCB_0_n" LOC = "AA3" ;
-#NET "ADCB_4_p" LOC = "AE1" ;
-#NET "ADCB_4_n" LOC = "AE2" ;
-#NET "ADCB_6_p" LOC = "W1" ;
-#NET "ADCB_6_n" LOC = "W2" ;
-#NET "ADCB_8_p" LOC = "U3" ;
-#NET "ADCB_8_n" LOC = "V4" ;
-#NET "ADCB_10_p" LOC = "J1" ;
-#NET "ADCB_10_n" LOC = "K1" ;
-#NET "ADCB_12_p" LOC = "J3" ;
-#NET "ADCB_12_n" LOC = "J2" ;
-
-## DAC
-#NET "DAC_LOCK" LOC = "P4" ;
-#NET "DACA<0>" LOC = "P8" ;
-#NET "DACA<1>" LOC = "P9" ;
-#NET "DACA<2>" LOC = "R5" ;
-#NET "DACA<3>" LOC = "R6" ;
-#NET "DACA<4>" LOC = "P7" ;
-#NET "DACA<5>" LOC = "P6" ;
-#NET "DACA<6>" LOC = "T3" ;
-#NET "DACA<7>" LOC = "T4" ;
-#NET "DACA<8>" LOC = "R3" ;
-#NET "DACA<9>" LOC = "R4" ;
-#NET "DACA<10>" LOC = "R2" ;
-#NET "DACA<11>" LOC = "N1" ;
-#NET "DACA<12>" LOC = "N2" ;
-#NET "DACA<13>" LOC = "N5" ;
-#NET "DACA<14>" LOC = "N4" ;
-#NET "DACA<15>" LOC = "M2" ;
-#NET "DACB<0>" LOC = "M5" ;
-#NET "DACB<1>" LOC = "M6" ;
-#NET "DACB<2>" LOC = "M4" ;
-#NET "DACB<3>" LOC = "M3" ;
-#NET "DACB<4>" LOC = "M8" ;
-#NET "DACB<5>" LOC = "M7" ;
-#NET "DACB<6>" LOC = "L4" ;
-#NET "DACB<7>" LOC = "L3" ;
-#NET "DACB<8>" LOC = "K3" ;
-#NET "DACB<9>" LOC = "K2" ;
-#NET "DACB<10>" LOC = "K5" ;
-#NET "DACB<11>" LOC = "K4" ;
-#NET "DACB<12>" LOC = "M10" ;
-#NET "DACB<13>" LOC = "M9" ;
-#NET "DACB<14>" LOC = "J5" ;
-#NET "DACB<15>" LOC = "J4" ;
-
-## TX DB GPIO
-#NET "io_tx<15>" LOC = "K6" ;
-#NET "io_tx<14>" LOC = "L7" ;
-#NET "io_tx<13>" LOC = "H2" ;
-#NET "io_tx<12>" LOC = "H1" ;
-#NET "io_tx<11>" LOC = "L10" ;
-#NET "io_tx<10>" LOC = "L9" ;
-#NET "io_tx<9>" LOC = "G3" ;
-#NET "io_tx<8>" LOC = "F3" ;
-#NET "io_tx<7>" LOC = "K7" ;
-#NET "io_tx<6>" LOC = "J6" ;
-#NET "io_tx<5>" LOC = "E1" ;
-#NET "io_tx<4>" LOC = "F2" ;
-#NET "io_tx<3>" LOC = "J7" ;
-#NET "io_tx<2>" LOC = "H6" ;
-#NET "io_tx<1>" LOC = "F5" ;
-#NET "io_tx<0>" LOC = "G4" ;
-
-## RX DB GPIO
-#NET "io_rx<15>" LOC = "AD1" ;
-#NET "io_rx<14>" LOC = "AD2" ;
-#NET "io_rx<13>" LOC = "AC2" ;
-#NET "io_rx<12>" LOC = "AC3" ;
-#NET "io_rx<11>" LOC = "W7" ;
-#NET "io_rx<10>" LOC = "W6" ;
-#NET "io_rx<9>" LOC = "U9" ;
-#NET "io_rx<8>" LOC = "V8" ;
-#NET "io_rx<7>" LOC = "AB1" ;
-#NET "io_rx<6>" LOC = "AC1" ;
-#NET "io_rx<5>" LOC = "V7" ;
-#NET "io_rx<4>" LOC = "V6" ;
-#NET "io_rx<3>" LOC = "Y5" ;
-#NET "io_rx<2>" LOC = "R10" ;
-#NET "io_rx<1>" LOC = "R1" ;
-#NET "io_rx<0>" LOC = "M1" ;
-
-## MISC
-NET "leds<5>" LOC = "AF25" ;
-NET "leds<4>" LOC = "AE25" ;
-NET "leds<3>" LOC = "AF23" ;
-NET "leds<2>" LOC = "AE23" ;
-NET "leds<1>" LOC = "AB18" ;
-#NET "FPGA_RESET" LOC = "K24" ;
-
-## Debug
-#NET "debug_clk<0>" LOC = "AA10" ;
-#NET "debug_clk<1>" LOC = "AD11" ;
-#NET "debug<0>" LOC = "AC19" ;
-#NET "debug<1>" LOC = "AF20" ;
-#NET "debug<2>" LOC = "AE20" ;
-#NET "debug<3>" LOC = "AC16" ;
-#NET "debug<4>" LOC = "AB16" ;
-#NET "debug<5>" LOC = "AF19" ;
-#NET "debug<6>" LOC = "AE19" ;
-#NET "debug<7>" LOC = "V15" ;
-#NET "debug<8>" LOC = "U15" ;
-#NET "debug<9>" LOC = "AE17" ;
-#NET "debug<10>" LOC = "AD17" ;
-#NET "debug<11>" LOC = "V14" ;
-#NET "debug<12>" LOC = "W15" ;
-#NET "debug<13>" LOC = "AC15" ;
-#NET "debug<14>" LOC = "AD14" ;
-#NET "debug<15>" LOC = "AC14" ;
-#NET "debug<16>" LOC = "AC11" ;
-#NET "debug<17>" LOC = "AB12" ;
-#NET "debug<18>" LOC = "AC12" ;
-#NET "debug<19>" LOC = "V13" ;
-#NET "debug<20>" LOC = "W13" ;
-#NET "debug<21>" LOC = "AE8" ;
-#NET "debug<22>" LOC = "AF8" ;
-#NET "debug<23>" LOC = "V12" ;
-#NET "debug<24>" LOC = "W12" ;
-#NET "debug<25>" LOC = "AB9" ;
-#NET "debug<26>" LOC = "AC9" ;
-#NET "debug<27>" LOC = "AC8" ;
-#NET "debug<28>" LOC = "AB7" ;
-#NET "debug<29>" LOC = "V11" ;
-#NET "debug<30>" LOC = "U11" ;
-#NET "debug<31>" LOC = "Y10" ;
-
-## UARTS
-#NET "TXD<3>" LOC = "AD20" ;
-#NET "TXD<2>" LOC = "AC20" ;
-#NET "TXD<1>" LOC = "AD19" ;
-#NET "RXD<3>" LOC = "AF17" ;
-#NET "RXD<2>" LOC = "AF15" ;
-#NET "RXD<1>" LOC = "AD12" ;
-
-## AD9510
-#NET "CLK_STATUS" LOC = "AD22" ;
-#NET "CLK_FUNC" LOC = "AC21" ;
-#NET "clk_sel<0>" LOC = "AE21" ;
-#NET "clk_sel<1>" LOC = "AD21" ;
-#NET "clk_en<1>" LOC = "AA17" ;
-#NET "clk_en<0>" LOC = "Y17" ;
-
-## I2C
-#NET "SDA" LOC = "V16" ;
-#NET "SCL" LOC = "U16" ;
-
-## Timing
-#NET "PPS_IN" LOC = "AB6" ;
-#NET "PPS2_IN" LOC = "AA20" ;
-
-## SPI
-#NET "SEN_CLK" LOC = "AA18" ;
-#NET "MOSI_CLK" LOC = "W17" ;
-#NET "SCLK_CLK" LOC = "V17" ;
-#NET "MISO_CLK" LOC = "AC10" ;
-
-#NET "SEN_DAC" LOC = "AE7" ;
-#NET "SCLK_DAC" LOC = "AF5" ;
-#NET "MOSI_DAC" LOC = "AE6" ;
-#NET "MISO_DAC" LOC = "Y3" ;
-
-#NET "SCLK_ADC" LOC = "B1" ;
-#NET "MOSI_ADC" LOC = "J8" ;
-#NET "SEN_ADC" LOC = "J9" ;
-
-#NET "MOSI_TX_ADC" LOC = "V10" ;
-#NET "SEN_TX_ADC" LOC = "W10" ;
-#NET "SCLK_TX_ADC" LOC = "AC6" ;
-#NET "MISO_TX_ADC" LOC = "G1" ;
-
-#NET "MOSI_TX_DAC" LOC = "AD6" ;
-#NET "SEN_TX_DAC" LOC = "AE4" ;
-#NET "SCLK_TX_DAC" LOC = "AF4" ;
-
-#NET "SCLK_TX_DB" LOC = "AE3" ;
-#NET "MOSI_TX_DB" LOC = "AF3" ;
-#NET "SEN_TX_DB" LOC = "W9" ;
-#NET "MISO_TX_DB" LOC = "AA5" ;
-
-#NET "MOSI_RX_ADC" LOC = "E3" ;
-#NET "SCLK_RX_ADC" LOC = "F4" ;
-#NET "SEN_RX_ADC" LOC = "D3" ;
-#NET "MISO_RX_ADC" LOC = "C1" ;
-
-#NET "SCLK_RX_DAC" LOC = "E4" ;
-#NET "SEN_RX_DAC" LOC = "K9" ;
-#NET "MOSI_RX_DAC" LOC = "K8" ;
-
-#NET "SCLK_RX_DB" LOC = "G6" ;
-#NET "MOSI_RX_DB" LOC = "H7" ;
-#NET "SEN_RX_DB" LOC = "B2" ;
-#NET "MISO_RX_DB" LOC = "H4" ;
-
-## ETH PHY
-#NET "CLK_TO_MAC" LOC = "P26" ;
-
-#NET "GMII_TXD<7>" LOC = "G21" ;
-#NET "GMII_TXD<6>" LOC = "C26" ;
-#NET "GMII_TXD<5>" LOC = "C25" ;
-#NET "GMII_TXD<4>" LOC = "J21" ;
-#NET "GMII_TXD<3>" LOC = "H21" ;
-#NET "GMII_TXD<2>" LOC = "D25" ;
-#NET "GMII_TXD<1>" LOC = "D24" ;
-#NET "GMII_TXD<0>" LOC = "E26" ;
-#NET "GMII_TX_EN" LOC = "D26" ;
-#NET "GMII_TX_ER" LOC = "J19" ;
-#NET "GMII_GTX_CLK" LOC = "J20" ;
-#NET "GMII_TX_CLK" LOC = "P25" ;
-
-#NET "GMII_RX_CLK" LOC = "P21" ;
-#NET "GMII_RXD<7>" LOC = "G22" ;
-#NET "GMII_RXD<6>" LOC = "K19" ;
-#NET "GMII_RXD<5>" LOC = "K18" ;
-#NET "GMII_RXD<4>" LOC = "E24" ;
-#NET "GMII_RXD<3>" LOC = "F23" ;
-#NET "GMII_RXD<2>" LOC = "L18" ;
-#NET "GMII_RXD<1>" LOC = "L17" ;
-#NET "GMII_RXD<0>" LOC = "F25" ;
-#NET "GMII_RX_DV" LOC = "F24" ;
-#NET "GMII_RX_ER" LOC = "L20" ;
-#NET "GMII_CRS" LOC = "K20" ;
-#NET "GMII_COL" LOC = "G23" ;
-
-#NET "PHY_INTn" LOC = "L22" ;
-#NET "MDIO" LOC = "K21" ;
-#NET "MDC" LOC = "J23" ;
-#NET "PHY_RESETn" LOC = "J22" ;
-NET "ETH_LED" LOC = "H20" ;
-
-## MIMO Interface
-#NET "exp_time_out_p" LOC = "Y14" ;
-#NET "exp_time_out_n" LOC = "AA14" ;
-#NET "exp_time_in_p" LOC = "N18" ;
-#NET "exp_time_in_n" LOC = "N17" ;
-#NET "exp_user_out_p" LOC = "AF14" ;
-#NET "exp_user_out_n" LOC = "AE14" ;
-#NET "exp_user_in_p" LOC = "L24" ;
-#NET "exp_user_in_n" LOC = "M23" ;
-
-## SERDES
-#NET "ser_enable" LOC = "R20" ;
-#NET "ser_prbsen" LOC = "U23" ;
-#NET "ser_loopen" LOC = "R19" ;
-#NET "ser_rx_en" LOC = "Y21" ;
-#NET "ser_tx_clk" LOC = "P23" ; # SERDES TX CLK
-#NET "ser_t<15>" LOC = "V23" ;
-#NET "ser_t<14>" LOC = "U22" ;
-#NET "ser_t<13>" LOC = "V24" ;
-#NET "ser_t<12>" LOC = "V25" ;
-#NET "ser_t<11>" LOC = "W23" ;
-#NET "ser_t<10>" LOC = "V22" ;
-#NET "ser_t<9>" LOC = "T18" ;
-#NET "ser_t<8>" LOC = "T17" ;
-#NET "ser_t<7>" LOC = "Y24" ;
-#NET "ser_t<6>" LOC = "Y25" ;
-#NET "ser_t<5>" LOC = "U21" ;
-#NET "ser_t<4>" LOC = "T20" ;
-#NET "ser_t<3>" LOC = "Y22" ;
-#NET "ser_t<2>" LOC = "Y23" ;
-#NET "ser_t<1>" LOC = "U19" ;
-#NET "ser_t<0>" LOC = "U18" ;
-#NET "ser_tkmsb" LOC = "AA24" ;
-#NET "ser_tklsb" LOC = "AA25" ;
-#NET "ser_rx_clk" LOC = "P18" ;
-#NET "ser_r<15>" LOC = "V21" ;
-#NET "ser_r<14>" LOC = "U20" ;
-#NET "ser_r<13>" LOC = "AA22" ;
-#NET "ser_r<12>" LOC = "AA23" ;
-#NET "ser_r<11>" LOC = "V18" ;
-#NET "ser_r<10>" LOC = "V19" ;
-#NET "ser_r<9>" LOC = "AB23" ;
-#NET "ser_r<8>" LOC = "AC26" ;
-#NET "ser_r<7>" LOC = "AB26" ;
-#NET "ser_r<6>" LOC = "AD26" ;
-#NET "ser_r<5>" LOC = "AC25" ;
-#NET "ser_r<4>" LOC = "W20" ;
-#NET "ser_r<3>" LOC = "W21" ;
-#NET "ser_r<2>" LOC = "AC23" ;
-#NET "ser_r<1>" LOC = "AC24" ;
-#NET "ser_r<0>" LOC = "AE26" ;
-#NET "ser_rkmsb" LOC = "AD25" ;
-#NET "ser_rklsb" LOC = "Y20" ;
-
-## SRAM
-#NET "RAM_D<35>" LOC = "K16" ;
-#NET "RAM_D<34>" LOC = "D20" ;
-#NET "RAM_D<33>" LOC = "C20" ;
-#NET "RAM_D<32>" LOC = "E21" ;
-#NET "RAM_D<31>" LOC = "D21" ;
-#NET "RAM_D<30>" LOC = "C21" ;
-#NET "RAM_D<29>" LOC = "B21" ;
-#NET "RAM_D<28>" LOC = "H17" ;
-#NET "RAM_D<27>" LOC = "G17" ;
-#NET "RAM_D<26>" LOC = "B23" ;
-#NET "RAM_D<25>" LOC = "A22" ;
-#NET "RAM_D<24>" LOC = "D23" ;
-#NET "RAM_D<23>" LOC = "C23" ;
-#NET "RAM_D<22>" LOC = "D22" ;
-#NET "RAM_D<21>" LOC = "C22" ;
-#NET "RAM_D<20>" LOC = "F19" ;
-#NET "RAM_D<19>" LOC = "G20" ;
-#NET "RAM_D<18>" LOC = "F20" ;
-#NET "RAM_D<17>" LOC = "F7" ;
-#NET "RAM_D<16>" LOC = "E7" ;
-#NET "RAM_D<15>" LOC = "G9" ;
-#NET "RAM_D<14>" LOC = "H9" ;
-#NET "RAM_D<13>" LOC = "G10" ;
-#NET "RAM_D<12>" LOC = "H10" ;
-#NET "RAM_D<11>" LOC = "A4" ;
-#NET "RAM_D<10>" LOC = "B4" ;
-#NET "RAM_D<9>" LOC = "C5" ;
-#NET "RAM_D<8>" LOC = "D6" ;
-#NET "RAM_D<7>" LOC = "J11" ;
-#NET "RAM_D<6>" LOC = "K11" ;
-#NET "RAM_D<5>" LOC = "B7" ;
-#NET "RAM_D<4>" LOC = "C7" ;
-#NET "RAM_D<3>" LOC = "B6" ;
-#NET "RAM_D<2>" LOC = "C6" ;
-#NET "RAM_D<1>" LOC = "C8" ;
-#NET "RAM_D<0>" LOC = "D8" ;
-#NET "RAM_A<0>" LOC = "C11" ;
-#NET "RAM_A<1>" LOC = "E12" ;
-#NET "RAM_A<2>" LOC = "F12" ;
-#NET "RAM_A<3>" LOC = "D13" ;
-#NET "RAM_A<4>" LOC = "C12" ;
-#NET "RAM_A<5>" LOC = "A12" ;
-#NET "RAM_A<6>" LOC = "B12" ;
-#NET "RAM_A<7>" LOC = "E14" ;
-#NET "RAM_A<8>" LOC = "F14" ;
-#NET "RAM_A<9>" LOC = "B15" ;
-#NET "RAM_A<10>" LOC = "A15" ;
-#NET "RAM_A<11>" LOC = "D16" ;
-#NET "RAM_A<12>" LOC = "C15" ;
-#NET "RAM_A<13>" LOC = "D17" ;
-#NET "RAM_A<14>" LOC = "C16" ;
-#NET "RAM_A<15>" LOC = "F15" ;
-#NET "RAM_A<16>" LOC = "C17" ;
-#NET "RAM_A<17>" LOC = "B17" ;
-#NET "RAM_A<18>" LOC = "B18" ;
-#NET "RAM_A<19>" LOC = "A18" ;
-#NET "RAM_A<20>" LOC = "D18" ;
-#NET "RAM_BWn<3>" LOC = "D9" ;
-#NET "RAM_BWn<2>" LOC = "A9" ;
-#NET "RAM_BWn<1>" LOC = "B9" ;
-#NET "RAM_BWn<0>" LOC = "G12" ;
-#NET "RAM_ZZ" LOC = "J12" ;
-#NET "RAM_LDn" LOC = "H12" ;
-#NET "RAM_OEn" LOC = "C10" ;
-#NET "RAM_WEn" LOC = "D10" ;
-#NET "RAM_CENn" LOC = "B10" ;
-#NET "RAM_CLK" LOC = "A10" ;
-
-## SPI Flash
-#NET "flash_miso" LOC = "AF24" ;
-#NET "flash_clk" LOC = "AE24" ;
-#NET "flash_mosi" LOC = "AB15" ;
-#NET "flash_cs" LOC = "AA7" ;
-
-## MISC FPGA, unused for now
-##NET "PROG_B" LOC = "A2" ;
-##NET "PUDC_B" LOC = "G8" ;
-##NET "DONE" LOC = "AB21" ;
-##NET "INIT_B" LOC = "AA15" ;
-
-
-##NET "unnamed_net19" LOC = "AE9" ; # VS1
-##NET "unnamed_net18" LOC = "AF9" ; # VS0
-##NET "unnamed_net17" LOC = "AA12" ; # VS2
-##NET "unnamed_net16" LOC = "Y7" ; # M2
-##NET "unnamed_net15" LOC = "AC4" ; # M1
-##NET "unnamed_net14" LOC = "AD4" ; # M0
-##NET "unnamed_net13" LOC = "D4" ; # TMS
-##NET "unnamed_net12" LOC = "E23" ; # TDO
-##NET "unnamed_net11" LOC = "G7" ; # TDI
-##NET "unnamed_net10" LOC = "A25" ; # TCK
-##NET "unnamed_net20" LOC = "V20" ; # SUSPEND
diff --git a/fpga/usrp2/top/tcl/ise_helper.tcl b/fpga/usrp2/top/tcl/ise_helper.tcl
index a4bee76b8..f11596f8b 100644
--- a/fpga/usrp2/top/tcl/ise_helper.tcl
+++ b/fpga/usrp2/top/tcl/ise_helper.tcl
@@ -1,8 +1,6 @@
#
# Copyright 2008 Ettus Research LLC
#
-# 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)
diff --git a/fpga/usrp2/top/u1e_ethdebug/.gitignore b/fpga/usrp2/top/u1e_ethdebug/.gitignore
deleted file mode 100644
index 8d872713e..000000000
--- a/fpga/usrp2/top/u1e_ethdebug/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-*~
-build
-*.log
-*.cmd
-tb_u1e
-*.lxt
diff --git a/fpga/usrp2/top/u1e_ethdebug/u1e.ucf b/fpga/usrp2/top/u1e_ethdebug/u1e.ucf
deleted file mode 100644
index d6a2ea4ed..000000000
--- a/fpga/usrp2/top/u1e_ethdebug/u1e.ucf
+++ /dev/null
@@ -1,88 +0,0 @@
-
-## GPMC
-NET "EM_D<15>" LOC = "D13" ;
-NET "EM_D<14>" LOC = "D15" ;
-NET "EM_D<13>" LOC = "C16" ;
-NET "EM_D<12>" LOC = "B20" ;
-NET "EM_D<11>" LOC = "A19" ;
-NET "EM_D<10>" LOC = "A17" ;
-NET "EM_D<9>" LOC = "E15" ;
-NET "EM_D<8>" LOC = "F15" ;
-NET "EM_D<7>" LOC = "E16" ;
-NET "EM_D<6>" LOC = "F16" ;
-NET "EM_D<5>" LOC = "B17" ;
-NET "EM_D<4>" LOC = "C17" ;
-NET "EM_D<3>" LOC = "B19" ;
-NET "EM_D<2>" LOC = "D19" ;
-NET "EM_D<1>" LOC = "C19" ;
-NET "EM_D<0>" LOC = "A20" ;
-
-NET "EM_A<10>" LOC = "C14" ;
-NET "EM_A<9>" LOC = "C10" ;
-NET "EM_A<8>" LOC = "C5" ;
-NET "EM_A<7>" LOC = "A18" ;
-NET "EM_A<6>" LOC = "A15" ;
-NET "EM_A<5>" LOC = "A12" ;
-NET "EM_A<4>" LOC = "A10" ;
-NET "EM_A<3>" LOC = "E7" ;
-NET "EM_A<2>" LOC = "A7" ;
-NET "EM_A<1>" LOC = "C15" ;
-
-NET "EM_NCS6" LOC = "E17" ;
-NET "EM_NCS5" LOC = "E10" ;
-NET "EM_NCS4" LOC = "E6" ;
-#NET "EM_NCS1" LOC = "D18" ;
-#NET "EM_NCS0" LOC = "D17" ;
-
-NET "EM_CLK" LOC = "F11" ;
-NET "EM_WAIT0" LOC = "F14" ;
-#NET "EM_NBE<1>" LOC = "D14" ;
-#NET "EM_NBE<0>" LOC = "A13" ;
-NET "EM_NWE" LOC = "B13" ;
-NET "EM_NOE" LOC = "A14" ;
-NET "EM_NADV_ALE" LOC = "B15" ;
-#NET "EM_NWP" LOC = "F13" ;
-NET "overo_gpio64" LOC = "A4" ; # nRESET
-NET "overo_gpio176" LOC = "B4" ; # IRQ
-
-## Debug pins
-NET "debug_led<3>" LOC = "Y15" ;
-NET "debug_led<2>" LOC = "K16" ;
-NET "debug_led<1>" LOC = "J17" ;
-NET "debug_led<0>" LOC = "H22" ;
-NET "debug<0>" LOC = "G22" ;
-NET "debug<1>" LOC = "H17" ;
-NET "debug<2>" LOC = "H18" ;
-NET "debug<3>" LOC = "K20" ;
-NET "debug<4>" LOC = "J20" ;
-NET "debug<5>" LOC = "K19" ;
-NET "debug<6>" LOC = "K18" ;
-NET "debug<7>" LOC = "L22" ;
-NET "debug<8>" LOC = "K22" ;
-NET "debug<9>" LOC = "N22" ;
-NET "debug<10>" LOC = "M22" ;
-NET "debug<11>" LOC = "N20" ;
-NET "debug<12>" LOC = "N19" ;
-NET "debug<13>" LOC = "R22" ;
-NET "debug<14>" LOC = "P22" ;
-NET "debug<15>" LOC = "N17" ;
-NET "debug<16>" LOC = "P16" ;
-NET "debug<17>" LOC = "U22" ;
-NET "debug<18>" LOC = "P19" ;
-NET "debug<19>" LOC = "R18" ;
-NET "debug<20>" LOC = "U20" ;
-NET "debug<21>" LOC = "T20" ;
-NET "debug<22>" LOC = "R19" ;
-NET "debug<23>" LOC = "R20" ;
-NET "debug<24>" LOC = "W22" ;
-NET "debug<25>" LOC = "Y22" ;
-NET "debug<26>" LOC = "T18" ;
-NET "debug<27>" LOC = "T17" ;
-NET "debug<28>" LOC = "W19" ;
-NET "debug<29>" LOC = "V20" ;
-NET "debug<30>" LOC = "Y21" ;
-NET "debug<31>" LOC = "AA22" ;
-NET "debug_clk<0>" LOC = "N18" ;
-NET "debug_clk<1>" LOC = "M17" ;
-
-NET "debug_pb" LOC = "C22" ;
diff --git a/fpga/usrp2/top/u1e_ethdebug/u1e.v b/fpga/usrp2/top/u1e_ethdebug/u1e.v
deleted file mode 100644
index 2a543a313..000000000
--- a/fpga/usrp2/top/u1e_ethdebug/u1e.v
+++ /dev/null
@@ -1,28 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-
-//`define DCM 1
-
-module u1e
- (output [3:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
- input debug_pb,
-
- // GPMC
- input EM_CLK, input [15:0] EM_D, input [10:1] EM_A,
- input EM_WAIT0, input EM_NCS4, input EM_NCS5, input EM_NCS6, input EM_NWE, input EM_NOE,
- input EM_NADV_ALE,
-
- input overo_gpio64, input overo_gpio176
- );
-
- assign debug_clk = {EM_CLK, EM_NADV_ALE};
-
- assign debug_led = {1'b0, EM_A[9], EM_A[8], debug_pb};
-
- assign debug = { {overo_gpio64, overo_gpio176, EM_WAIT0, EM_NCS4, EM_NCS5, EM_NCS6, EM_NWE, EM_NOE },
- { EM_A[10], EM_A[7:1] },
- { EM_D[15:8] },
- { EM_D[7:0] } };
-
-
-endmodule // u1e
diff --git a/fpga/usrp2/top/u1e_passthru/passthru.v b/fpga/usrp2/top/u1e_passthru/passthru.v
deleted file mode 100644
index 12e4db017..000000000
--- a/fpga/usrp2/top/u1e_passthru/passthru.v
+++ /dev/null
@@ -1,18 +0,0 @@
-`timescale 1ns / 1ps
-//////////////////////////////////////////////////////////////////////////////////
-
-module passthru
- (input overo_gpio145,
- output cgen_sclk,
- output cgen_sen_b,
- output cgen_mosi,
- input fpga_cfg_din,
- input fpga_cfg_cclk
- );
-
- assign cgen_sclk = fpga_cfg_cclk;
- assign cgen_sen_b = overo_gpio145;
- assign cgen_mosi = fpga_cfg_din;
-
-
-endmodule // passthru
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile b/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile
deleted file mode 100644
index 334089839..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/Makefile
+++ /dev/null
@@ -1,253 +0,0 @@
-#
-# Copyright 2008 Ettus Research LLC
-#
-# 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-##################################################
-# xtclsh Shell and tcl Script Path
-##################################################
-#XTCLSH := /opt/Xilinx/10.1/ISE/bin/lin/xtclsh
-XTCLSH := xtclsh
-ISE_HELPER := ../tcl/ise_helper.tcl
-
-##################################################
-# Project Setup
-##################################################
-BUILD_DIR := build/
-export TOP_MODULE := u2_rev3
-export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
-
-##################################################
-# Project Properties
-##################################################
-export PROJECT_PROPERTIES := \
-family Spartan3 \
-device xc3s2000 \
-package fg456 \
-speed -5 \
-top_level_module_type "HDL" \
-synthesis_tool "XST (VHDL/Verilog)" \
-simulator "ISE Simulator (VHDL/Verilog)" \
-"Preferred Language" "Verilog" \
-"Enable Message Filtering" FALSE \
-"Display Incremental Messages" FALSE
-
-##################################################
-# Sources
-##################################################
-export SOURCE_ROOT := ../../../
-export SOURCES := \
-control_lib/CRC16_D16.v \
-control_lib/atr_controller.v \
-control_lib/bin2gray.v \
-control_lib/buffer_int.v \
-control_lib/buffer_pool.v \
-control_lib/cascadefifo2.v \
-control_lib/dcache.v \
-control_lib/decoder_3_8.v \
-control_lib/dpram32.v \
-control_lib/fifo_2clock.v \
-control_lib/fifo_2clock_casc.v \
-control_lib/gray2bin.v \
-control_lib/gray_send.v \
-control_lib/icache.v \
-control_lib/longfifo.v \
-control_lib/mux4.v \
-control_lib/mux8.v \
-control_lib/nsgpio.v \
-control_lib/ram_2port.v \
-control_lib/ram_harv_cache.v \
-control_lib/ram_loader.v \
-control_lib/setting_reg.v \
-control_lib/settings_bus.v \
-control_lib/shortfifo.v \
-control_lib/medfifo.v \
-control_lib/srl.v \
-control_lib/system_control.v \
-control_lib/wb_1master.v \
-control_lib/wb_readback_mux.v \
-control_lib/simple_uart.v \
-control_lib/simple_uart_tx.v \
-control_lib/simple_uart_rx.v \
-control_lib/oneshot_2clk.v \
-control_lib/sd_spi.v \
-control_lib/sd_spi_wb.v \
-control_lib/wb_bridge_16_32.v \
-coregen/fifo_xlnx_2Kx36_2clk.v \
-coregen/fifo_xlnx_2Kx36_2clk.xco \
-coregen/fifo_xlnx_512x36_2clk.v \
-coregen/fifo_xlnx_512x36_2clk.xco \
-eth/mac_rxfifo_int.v \
-eth/mac_txfifo_int.v \
-eth/rtl/verilog/Clk_ctrl.v \
-eth/rtl/verilog/MAC_rx.v \
-eth/rtl/verilog/MAC_rx/Broadcast_filter.v \
-eth/rtl/verilog/MAC_rx/CRC_chk.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_FF.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v \
-eth/rtl/verilog/MAC_top.v \
-eth/rtl/verilog/MAC_tx.v \
-eth/rtl/verilog/MAC_tx/CRC_gen.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_FF.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v \
-eth/rtl/verilog/MAC_tx/Random_gen.v \
-eth/rtl/verilog/Phy_int.v \
-eth/rtl/verilog/RMON.v \
-eth/rtl/verilog/RMON/RMON_addr_gen.v \
-eth/rtl/verilog/RMON/RMON_ctrl.v \
-eth/rtl/verilog/Reg_int.v \
-eth/rtl/verilog/eth_miim.v \
-eth/rtl/verilog/flow_ctrl_rx.v \
-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 \
-opencores/8b10b/decode_8b10b.v \
-opencores/8b10b/encode_8b10b.v \
-opencores/aemb/rtl/verilog/aeMB_bpcu.v \
-opencores/aemb/rtl/verilog/aeMB_core_BE.v \
-opencores/aemb/rtl/verilog/aeMB_ctrl.v \
-opencores/aemb/rtl/verilog/aeMB_edk32.v \
-opencores/aemb/rtl/verilog/aeMB_ibuf.v \
-opencores/aemb/rtl/verilog/aeMB_regf.v \
-opencores/aemb/rtl/verilog/aeMB_xecu.v \
-opencores/i2c/rtl/verilog/i2c_master_bit_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_byte_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_defines.v \
-opencores/i2c/rtl/verilog/i2c_master_top.v \
-opencores/i2c/rtl/verilog/timescale.v \
-opencores/simple_pic/rtl/simple_pic.v \
-opencores/spi/rtl/verilog/spi_clgen.v \
-opencores/spi/rtl/verilog/spi_defines.v \
-opencores/spi/rtl/verilog/spi_shift.v \
-opencores/spi/rtl/verilog/spi_top.v \
-opencores/spi/rtl/verilog/timescale.v \
-sdr_lib/acc.v \
-sdr_lib/add2.v \
-sdr_lib/add2_and_round.v \
-sdr_lib/add2_and_round_reg.v \
-sdr_lib/add2_reg.v \
-sdr_lib/cic_dec_shifter.v \
-sdr_lib/cic_decim.v \
-sdr_lib/cic_int_shifter.v \
-sdr_lib/cic_interp.v \
-sdr_lib/cic_strober.v \
-sdr_lib/clip.v \
-sdr_lib/clip_reg.v \
-sdr_lib/cordic.v \
-sdr_lib/cordic_z24.v \
-sdr_lib/cordic_stage.v \
-sdr_lib/dsp_core_tx.v \
-sdr_lib/hb_dec.v \
-sdr_lib/hb_interp.v \
-sdr_lib/integrate.v \
-sdr_lib/round.v \
-sdr_lib/round_reg.v \
-sdr_lib/rx_control.v \
-sdr_lib/rx_dcoffset.v \
-sdr_lib/sign_extend.v \
-sdr_lib/small_hb_dec.v \
-sdr_lib/small_hb_int.v \
-sdr_lib/tx_control.v \
-serdes/serdes.v \
-serdes/serdes_fc_rx.v \
-serdes/serdes_fc_tx.v \
-serdes/serdes_rx.v \
-serdes/serdes_tx.v \
-timing/time_receiver.v \
-timing/time_sender.v \
-timing/time_sync.v \
-timing/timer.v \
-top/u2_rev3/u2_rev3.ucf \
-top/u2_rev3/u2_rev3.v \
-top/u2_rev3_2rx_iad/u2_core.v \
-top/u2_rev3_2rx_iad/dsp_core_rx.v
-
-##################################################
-# Process Properties
-##################################################
-export SYNTHESIZE_PROPERTIES := \
-"Number of Clock Buffers" 6 \
-"Pack I/O Registers into IOBs" Yes \
-"Optimization Effort" High \
-"Optimize Instantiated Primitives" TRUE \
-"Register Balancing" Yes \
-"Use Clock Enable" Auto \
-"Use Synchronous Reset" Auto \
-"Use Synchronous Set" Auto
-
-export TRANSLATE_PROPERTIES := \
-"Macro Search Path" "$(shell pwd)/../../coregen/"
-
-export MAP_PROPERTIES := \
-"Allow Logic Optimization Across Hierarchy" TRUE \
-"Map to Input Functions" 4 \
-"Optimization Strategy (Cover Mode)" Speed \
-"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \
-"Perform Timing-Driven Packing and Placement" TRUE \
-"Map Effort Level" High \
-"Extra Effort" Normal \
-"Combinatorial Logic Optimization" TRUE \
-"Register Duplication" TRUE
-
-export PLACE_ROUTE_PROPERTIES := \
-"Place & Route Effort Level (Overall)" High
-
-export STATIC_TIMING_PROPERTIES := \
-"Number of Paths in Error/Verbose Report" 10 \
-"Report Type" "Error Report"
-
-export GEN_PROG_FILE_PROPERTIES := \
-"Configuration Rate" 6 \
-"Create Binary Configuration File" TRUE \
-"Done (Output Events)" 5 \
-"Enable Bitstream Compression" TRUE \
-"Enable Outputs (Output Events)" 6
-
-export SIM_MODEL_PROPERTIES := ""
-
-##################################################
-# Make Options
-##################################################
-all:
- @echo make proj, check, synth, bin, testbench, or clean
-
-proj:
- PROCESS_RUN="" $(XTCLSH) $(ISE_HELPER)
-
-check:
- PROCESS_RUN="Check Syntax" $(XTCLSH) $(ISE_HELPER)
-
-synth:
- PROCESS_RUN="Synthesize - XST" $(XTCLSH) $(ISE_HELPER)
-
-bin:
- PROCESS_RUN="Generate Programming File" $(XTCLSH) $(ISE_HELPER)
-
-testbench:
- iverilog -c cmdfile -o dsp_core_tb dsp_core_tb.v
-
-clean:
- rm -rf $(BUILD_DIR)
- rm -f dsp_core_tb
- rm -f *.lx2
- rm -f *.dat
- rm -f *.vcd
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/README b/fpga/usrp2/top/u2_rev3_2rx_iad/README
deleted file mode 100644
index 3efc5305b..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/README
+++ /dev/null
@@ -1,32 +0,0 @@
-This is a custom build for USRP2 FPGA. It allows using a BasicRX or
-LFRX board and feed two independent, real signals. In addition, instead
-of the CIC/HB decimator, which optimizes frequency response, it uses an
-integrate and dump decimator, which optimizes for time-domain impulse
-response.
-
-These changes have been made in dsp_core_rx.v:
-
-* A second DDC has been added, sharing a frequency register with
- the existing DDC.
-
-* The output of the two DDCs are interleaved as I1 Q1 I2 Q2I ...
- into the receive FIFO. This limits the host configured decimation
- to 8 intead of 4. Use gr.deinterleave to recover the streams.
-
-* The ADCs are hardcoded:
-
- RX_A ==> DDC #1 I-input
- 0 ==> DDC #1 Q-input
- RX_B ==> DDC #2 I-input
- 0 ==> DDC #2 Q-input
-
- Thus, the input mux has been disabled.
-
-* The CIC/HB decimator has been replaced by an integrate and dump at
- the decimation rate.
-
-* To assist with meeting timing, the external RAM has been disabled.
-
-The basic application is to coherently sample two real IF streams and
-downconvert to baseband, while minimizing the impulse response duration
-of the resampling filters.
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/cmdfile b/fpga/usrp2/top/u2_rev3_2rx_iad/cmdfile
deleted file mode 100644
index 34373a676..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/cmdfile
+++ /dev/null
@@ -1,4 +0,0 @@
--y .
--y ../../sdr_lib
--y ../../control_lib
--y ../../models
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_rx.v b/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_rx.v
deleted file mode 100644
index 4a945bd1a..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_rx.v
+++ /dev/null
@@ -1,212 +0,0 @@
-`define DSP_CORE_RX_BASE 160
-module dsp_core_rx
- (input clk, input rst,
- input set_stb, input [7:0] set_addr, input [31:0] set_data,
-
- input [13:0] adc_a, input adc_ovf_a,
- input [13:0] adc_b, input adc_ovf_b,
-
- input [15:0] io_rx,
-
- output reg [31:0] sample,
- input run,
- output strobe,
- output [31:0] debug
- );
-
- wire [15:0] scale_i, scale_q;
- wire [13:0] adc_a_ofs, adc_b_ofs;
- reg [13:0] adc_i, adc_q;
- wire [31:0] phase_inc;
- reg [31:0] phase;
-
- wire [35:0] prod_i, prod_q;
- wire [23:0] i_cordic_a, q_cordic_a, i_cordic_b, q_cordic_b;
- wire [31:0] i_iad_a, q_iad_a, i_iad_b, q_iad_b;
- wire [15:0] i_out_a, q_out_a, i_out_b, q_out_b;
-
- wire enable_hb1, enable_hb2; // Correspond to std firmware settings
- wire [7:0] cic_decim; // for combined CIC/HB decimator
- wire [9:0] decim_rate; // Reconstructed original decimation setting
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+0)) sr_0
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(phase_inc),.changed());
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+1)) sr_1
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out({scale_i,scale_q}),.changed());
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+2)) sr_2
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out({enable_hb1,enable_hb2,cic_decim}),.changed());
-
- rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+6)) rx_dcoffset_a
- (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_in(adc_a),.adc_out(adc_a_ofs));
-
- rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+7)) rx_dcoffset_b
- (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_in(adc_b),.adc_out(adc_b_ofs));
-
-`ifdef MUXCTRL
- wire [3:0] muxctrl;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+8)) sr_8
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(muxctrl),.changed());
-`endif
-
- wire [1:0] gpio_ena;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+9)) sr_9
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(gpio_ena),.changed());
-
- // The TVRX connects to what is called adc_b, thus A and B are
- // swapped throughout the design.
- //
- // In the interest of expediency and keeping the s/w sane, we just remap them here.
- // The I & Q fields are mapped the same:
- // 0 -> "the real A" (as determined by the TVRX)
- // 1 -> "the real B"
- // 2 -> const zero
-
-`ifdef MUXCTRL
- always @(posedge clk)
- case(muxctrl[1:0]) // The I mapping
- 0: adc_i <= adc_b_ofs; // "the real A"
- 1: adc_i <= adc_a_ofs;
- 2: adc_i <= 0;
- default: adc_i <= 0;
- endcase // case(muxctrl[1:0])
-
- always @(posedge clk)
- case(muxctrl[3:2]) // The Q mapping
- 0: adc_q <= adc_b_ofs; // "the real A"
- 1: adc_q <= adc_a_ofs;
- 2: adc_q <= 0;
- default: adc_q <= 0;
- endcase // case(muxctrl[3:2])
-`else // !`ifdef MUXCTRL
- always @(posedge clk)
- begin
- adc_i <= adc_a_ofs;
- adc_q <= adc_b_ofs;
- end
-`endif // !`ifdef MUXCTRL
-
- always @(posedge clk)
- if(rst)
- phase <= 0;
- else if(~run)
- phase <= 0;
- else
- phase <= phase + phase_inc;
-
- MULT18X18S mult_i
- (.P(prod_i), // 36-bit multiplier output
- .A({{4{adc_i[13]}},adc_i} ), // 18-bit multiplier input
- .B({{2{scale_i[15]}},scale_i}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
- MULT18X18S mult_q
- (.P(prod_q), // 36-bit multiplier output
- .A({{4{adc_q[13]}},adc_q} ), // 18-bit multiplier input
- .B({{2{scale_q[15]}},scale_q}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
-
- // Route I,0 to first CORDIC
- cordic_z24 #(.bitwidth(24))
- cordic_a(.clock(clk), .reset(rst), .enable(run),
- .xi(prod_i[24:1]),. yi(0), .zi(phase[31:8]),
- .xo(i_cordic_a),.yo(q_cordic_a),.zo() );
-
- // Route Q,0 to second CORDIC
- cordic_z24 #(.bitwidth(24))
- cordic_b(.clock(clk), .reset(rst), .enable(run),
- .xi(prod_q[24:1]),. yi(0), .zi(phase[31:8]),
- .xo(i_cordic_b),.yo(q_cordic_b),.zo() );
-
- // Reconstruct original decimation rate from standard firmware settings
- assign decim_rate = enable_hb2 ? (enable_hb1 ? {cic_decim,2'b0} :
- {1'b0,cic_decim,1'b0 }) :
- cic_decim;
-
- cic_strober #(.WIDTH(10)) // Convenient reuse of strobe generator
- cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(decim_rate),
- .strobe_fast(1),.strobe_slow(strobe_iad) );
-
- wire strobe_iad_o;
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_i_a
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(i_cordic_a),
- .stb_o(strobe_iad_o),.integ_o(i_iad_a) );
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_q_a
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(q_cordic_a),
- .stb_o(),.integ_o(q_iad_a) );
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_i_b
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(i_cordic_b),
- .stb_o(),.integ_o(i_iad_b) );
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_q_b
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(q_cordic_b),
- .stb_o(),.integ_o(q_iad_b) );
-
- round #(.bits_in(32),.bits_out(16)) round_iout_a (.in(i_iad_a),.out(i_out_a));
- round #(.bits_in(32),.bits_out(16)) round_qout_a (.in(q_iad_a),.out(q_out_a));
- round #(.bits_in(32),.bits_out(16)) round_iout_b (.in(i_iad_b),.out(i_out_b));
- round #(.bits_in(32),.bits_out(16)) round_qout_b (.in(q_iad_b),.out(q_out_b));
-
- reg [31:0] sample_out_a, sample_out_b, sample_out;
- reg stb_d1, stb_d2, stb_d3, stb_d4, stb_d5;
- reg strobe_out;
-
- // Register samples on strobe_iad
- // Output A on d1
- // Output B on d5
- always @(posedge clk)
- begin
- stb_d1 <= strobe_iad_o;
- stb_d2 <= stb_d1;
- stb_d3 <= stb_d2;
- stb_d4 <= stb_d3;
- stb_d5 <= stb_d4;
- end
-
- always @(posedge clk)
- if (strobe_iad_o)
- begin
- // Streaming GPIO
- // io_rx[15] => I channel LSB if gpio_ena[0] high
- // io_rx[14] => Q channel LSB if gpio_ena[1] high
- sample_out_a <= {i_out_a[15:1], gpio_ena[0] ? io_rx[15] : i_out_a[0],
- q_out_a[15:1], gpio_ena[1] ? io_rx[14] : q_out_a[0] };
- sample_out_b <= {i_out_b[15:1], gpio_ena[0] ? io_rx[15] : i_out_b[0],
- q_out_b[15:1], gpio_ena[1] ? io_rx[14] : q_out_b[0] };
- end
-
- always @(posedge clk)
- begin
- if (stb_d1)
- sample <= sample_out_a;
- else if (stb_d5)
- sample <= sample_out_b;
- strobe_out <= stb_d1|stb_d5;
- end
-
- assign strobe = strobe_out;
- assign debug = 0;
-
-endmodule // dsp_core_rx
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.sav b/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.sav
deleted file mode 100644
index 12f746860..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.sav
+++ /dev/null
@@ -1,106 +0,0 @@
-[size] 1680 975
-[pos] -1 -1
-*-17.007835 70679400 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-[treeopen] dsp_core_tb.
-@200
--SYSCON
-@28
-dsp_core_tb.clk
-dsp_core_tb.rst
-dsp_core_tb.run
-@200
--
--Settings Bus
-@22
-dsp_core_tb.set_addr[7:0]
-@24
-dsp_core_tb.set_data[31:0]
-@28
-dsp_core_tb.set_stb
-@200
--
--RX DSP CORE
-@22
-dsp_core_tb.rx_path.adc_a[13:0]
-dsp_core_tb.rx_path.adc_b[13:0]
-@28
-dsp_core_tb.rx_path.adc_ovf_a
-dsp_core_tb.rx_path.adc_ovf_b
-@22
-dsp_core_tb.rx_path.io_rx[15:0]
-@200
--
-@22
-dsp_core_tb.rx_path.sample[31:0]
-@28
-dsp_core_tb.rx_path.strobe
-@200
--
-@22
-dsp_core_tb.rx_path.phase_inc[31:0]
-dsp_core_tb.rx_path.scale_i[15:0]
-dsp_core_tb.rx_path.scale_q[15:0]
-@28
-dsp_core_tb.rx_path.enable_hb1
-dsp_core_tb.rx_path.enable_hb2
-@22
-dsp_core_tb.rx_path.cic_decim[7:0]
-dsp_core_tb.rx_path.adc_a_ofs[13:0]
-dsp_core_tb.rx_path.adc_b_ofs[13:0]
-dsp_core_tb.rx_path.muxctrl[3:0]
-@200
--
-@22
-dsp_core_tb.rx_path.adc_i[13:0]
-dsp_core_tb.rx_path.adc_q[13:0]
-dsp_core_tb.rx_path.phase[31:0]
-dsp_core_tb.rx_path.prod_i[35:0]
-dsp_core_tb.rx_path.prod_q[35:0]
-@8420
-dsp_core_tb.rx_path.i_cordic_a[23:0]
-dsp_core_tb.rx_path.q_cordic_a[23:0]
-dsp_core_tb.rx_path.i_cordic_b[23:0]
-dsp_core_tb.rx_path.q_cordic_b[23:0]
-@22
-dsp_core_tb.rx_path.decim_rate[9:0]
-@28
-dsp_core_tb.rx_path.strobe_iad
-@22
-dsp_core_tb.rx_path.i_iad_a[31:0]
-dsp_core_tb.rx_path.q_iad_a[31:0]
-@23
-dsp_core_tb.rx_path.i_iad_b[31:0]
-@22
-dsp_core_tb.rx_path.q_iad_b[31:0]
-@28
-dsp_core_tb.rx_path.strobe_iad_o
-@8420
-dsp_core_tb.rx_path.i_out_a[15:0]
-dsp_core_tb.rx_path.q_out_a[15:0]
-dsp_core_tb.rx_path.i_out_b[15:0]
-dsp_core_tb.rx_path.q_out_b[15:0]
-@28
-dsp_core_tb.rx_path.gpio_ena[1:0]
-@22
-dsp_core_tb.rx_path.sample_out_a[31:0]
-dsp_core_tb.rx_path.sample_out_b[31:0]
-dsp_core_tb.rx_path.sample[31:0]
-@28
-dsp_core_tb.rx_path.strobe_out
-dsp_core_tb.rx_path.stb_d1
-dsp_core_tb.rx_path.stb_d2
-dsp_core_tb.rx_path.stb_d3
-dsp_core_tb.rx_path.stb_d4
-dsp_core_tb.rx_path.stb_d5
-@200
--
--FIFO Bus
-@22
-dsp_core_tb.master_time[31:0]
-dsp_core_tb.wr_dat[31:0]
-@28
-dsp_core_tb.wr_done
-dsp_core_tb.wr_error
-dsp_core_tb.wr_full
-dsp_core_tb.wr_ready
-dsp_core_tb.wr_write
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.v b/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.v
deleted file mode 100644
index d947df40a..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/dsp_core_tb.v
+++ /dev/null
@@ -1,233 +0,0 @@
-`timescale 1ns / 100ps
-
-module dsp_core_tb;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Sim-wide wires/busses //
-///////////////////////////////////////////////////////////////////////////////////
-
- // System control bus
- reg clk = 0;
- reg rst = 1;
-
- // Configuration bus
- reg set_stb = 0;
- reg [7:0] set_addr = 0;
- reg [31:0] set_data = 0;
-
- // ADC input bus
- wire signed [13:0] adc_a;
- wire signed [13:0] adc_b;
- wire adc_ovf_a;
- wire adc_ovf_b;
-
- // RX sample bus
- reg run = 1;
- wire [31:0] sample;
- wire stb;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Simulation control //
-///////////////////////////////////////////////////////////////////////////////////
-
- // Set up output files
- initial begin
- $dumpfile("dsp_core_tb.vcd");
- $dumpvars(0,dsp_core_tb);
- end
-
- // Update display every 10 us
- always #1000 $monitor("Time in us ",$time/1000);
-
- // Generate master clock 50% @ 100 MHz
- always
- #5 clk = ~clk;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Unit(s) under test //
-///////////////////////////////////////////////////////////////////////////////////
-
- reg [13:0] amplitude = 13'h1fff;
- reg [15:0] impulse_len = 0;
- reg [15:0] zero_len = 0;
- reg adc_ena = 0;
-
- initial #500 @(posedge clk) adc_ena = 1;
-
- impulse adc
- (.clk(clk),.rst(rst),.ena(adc_ena),
- .dc_offset_a(0),.dc_offset_b(0),
- .amplitude(amplitude),
- .impulse_len(impulse_len),.zero_len(zero_len),
- .adc_a(adc_a),.adc_b(adc_b),
- .adc_ovf_a(adc_ovf_a),.adc_ovf_b(adc_ovf_b) );
-
- initial rx_path.rx_dcoffset_a.integrator = 0; // so sim doesn't propagate X's
- initial rx_path.rx_dcoffset_b.integrator = 0; // generated before reset
- dsp_core_rx rx_path
- (.clk(clk),.rst(rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),
- .adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .io_rx(16'b0),
- .run(adc_ena),.sample(sample),.strobe(stb),
- .debug() );
-
- reg [31:0] master_time = 0;
- always @(posedge clk)
- master_time <= master_time + 1;
-
- reg wr_ready = 1;
- reg wr_full = 0;
-
- wire [31:0] wr_dat;
- wire wr_write;
- wire wr_done;
- wire wr_error;
- wire [15:0] fifo_occupied;
- wire fifo_full;
- wire fifo_empty;
-
- rx_control rx_buffer
- (.clk(clk),.rst(rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .master_time(master_time),
- .overrun(), // unconnected output
- .wr_dat_o(wr_dat),
- .wr_write_o(wr_write),
- .wr_done_o(wr_done),
- .wr_error_o(wr_error),
- .wr_ready_i(wr_ready),
- .wr_full_i(wr_full),
- .sample(sample),
- .run(), // unconnected output, supposed to drive 'run'
- .strobe(stb),
- .fifo_occupied(fifo_occupied),
- .fifo_full(fifo_full),
- .fifo_empty(fifo_empty),
- .debug_rx() // unconnected output
- );
-
-
-
-///////////////////////////////////////////////////////////////////////////////////
-// Simulation output/checking //
-///////////////////////////////////////////////////////////////////////////////////
-
- integer rx_file;
-
- initial
- rx_file = $fopen("rx.dat", "wb");
-
- always @(posedge clk)
- begin
- // Write RX sample I&Q in format Octave can load
- if (stb)
- begin
- $fwrite(rx_file, sample[31:16]);
- $fputc(32, rx_file);
- $fwrite(rx_file, sample[15:0]);
- $fputc(13, rx_file);
- end
- end
-
-///////////////////////////////////////////////////////////////////////////////////
-// Tasks //
-///////////////////////////////////////////////////////////////////////////////////
-
- task power_on;
- begin
- @(posedge clk)
- rst = #1 1'b1;
- @(posedge clk)
- rst = #1 1'b0;
- end
- endtask // power_on
-
- task set_impulse_len;
- input [15:0] len;
- @(posedge clk) impulse_len = len-1;
- endtask
-
- task set_zero_len;
- input [15:0] len;
- @(posedge clk) zero_len = len-1;
- endtask
-
- // Strobe configuration bus with addr, data
- task write_cfg_register;
- input [7:0] regno;
- input [31:0] value;
-
- begin
- @(posedge clk);
- set_addr <= regno;
- set_data <= value;
- set_stb <= 1'b1;
- @(posedge clk);
- set_stb <= 1'b0;
- end
- endtask // write_cfg_register
-
- // Set RX DDC frequency
- task set_ddc_freq;
- input [31:0] freq;
-
- write_cfg_register(160, freq);
- endtask // set_ddc_freq
-
- // Set RX IQ scaling registers
- task set_rx_scale_iq;
- input [15:0] scale_i;
- input [15:0] scale_q;
-
- write_cfg_register(161, {scale_i,scale_q});
- endtask // set_rx_scale_iq
-
- // Set RX MUX control
- task set_rx_muxctrl;
- input [3:0] muxctrl;
-
- write_cfg_register(168, muxctrl);
- endtask // set_rx_muxctrl
-
- // Set RX CIC decim and halfband enables
- task set_decim;
- input hb1_ena;
- input hb2_ena;
- input [7:0] decim;
-
- write_cfg_register(162, {hb1_ena,hb2_ena,decim});
- endtask // set_decim
-
-
-///////////////////////////////////////////////////////////////////////////////////
-// Individual tests //
-///////////////////////////////////////////////////////////////////////////////////
-
- task test_rx;
- begin
- set_impulse_len(10);
- set_zero_len(990);
- set_rx_muxctrl(1);
- set_ddc_freq(32'h10000000);
- set_rx_scale_iq(1243, 1243);
- set_decim(1, 1, 1);
-
- #100000 $finish;
- end
- endtask // test_rx
-
-
-///////////////////////////////////////////////////////////////////////////////////
-// Top-level test //
-///////////////////////////////////////////////////////////////////////////////////
-
- // Execute tests
- initial
- begin
- power_on();
- test_rx();
- end
-
-endmodule // dsp_core_tb
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/impulse.v b/fpga/usrp2/top/u2_rev3_2rx_iad/impulse.v
deleted file mode 100644
index fc5e3c1ed..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/impulse.v
+++ /dev/null
@@ -1,68 +0,0 @@
-module impulse
- (input clk,
- input rst,
- input ena,
-
- input [13:0] dc_offset_a,
- input [13:0] dc_offset_b,
- input [13:0] amplitude,
- input [15:0] impulse_len,
- input [15:0] zero_len,
-
- output [13:0] adc_a,
- output [13:0] adc_b,
- output adc_ovf_a,
- output adc_ovf_b
- );
-
- reg [13:0] adc_a_int = 0;
- reg [13:0] adc_b_int = 0;
-
- reg [15:0] count;
-
- localparam ST_ZERO = 0;
- localparam ST_HIGH = 1;
- reg state;
-
- always @(posedge clk)
- if (rst | ~ena)
- begin
- adc_a_int <= 0;
- adc_b_int <= 0;
- count <= 0;
- state <= ST_ZERO;
- end
- else
- case(state)
- ST_ZERO:
- if (count == zero_len)
- begin
- adc_a_int <= amplitude;
- adc_b_int <= amplitude >> 2;
- state <= ST_HIGH;
- count <= 0;
- end
- else
- count <= count + 1;
-
- ST_HIGH:
- if (count == impulse_len)
- begin
- adc_a_int <= 0;
- adc_b_int <= 0;
- state <= ST_ZERO;
- count <= 0;
- end
- else
- count <= count + 1;
-
- endcase // case (state)
-
- assign adc_a = adc_a_int + dc_offset_a;
- assign adc_b = adc_b_int + dc_offset_b;
-
- // Ignore for now
- assign adc_ovf_a = 0;
- assign adc_ovf_b = 0;
-
-endmodule // impulse
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/u2_core.v b/fpga/usrp2/top/u2_rev3_2rx_iad/u2_core.v
deleted file mode 100755
index 3d96a4e0e..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/u2_core.v
+++ /dev/null
@@ -1,789 +0,0 @@
-// ////////////////////////////////////////////////////////////////////////////////
-// Module Name: u2_core
-// ////////////////////////////////////////////////////////////////////////////////
-
-module u2_core
- #(parameter RAM_SIZE=32768)
- (// Clocks
- input dsp_clk,
- input wb_clk,
- output clock_ready,
- input clk_to_mac,
- input pps_in,
-
- // Misc, debug
- output [7:0] leds,
- output [31:0] debug,
- output [1:0] debug_clk,
-
- // Expansion
- input exp_pps_in,
- output exp_pps_out,
-
- // GMII
- // GMII-CTRL
- input GMII_COL,
- input GMII_CRS,
-
- // GMII-TX
- output [7:0] GMII_TXD,
- output GMII_TX_EN,
- output GMII_TX_ER,
- output GMII_GTX_CLK,
- input GMII_TX_CLK, // 100mbps clk
-
- // GMII-RX
- input [7:0] GMII_RXD,
- input GMII_RX_CLK,
- input GMII_RX_DV,
- input GMII_RX_ER,
-
- // GMII-Management
- inout MDIO,
- output MDC,
- input PHY_INTn, // open drain
- output PHY_RESETn,
-
- // SERDES
- output ser_enable,
- output ser_prbsen,
- output ser_loopen,
- output ser_rx_en,
-
- output ser_tx_clk,
- output [15:0] ser_t,
- output ser_tklsb,
- output ser_tkmsb,
-
- input ser_rx_clk,
- input [15:0] ser_r,
- input ser_rklsb,
- input ser_rkmsb,
-
- // CPLD interface
- output cpld_start,
- output cpld_mode,
- output cpld_done,
- input cpld_din,
- input cpld_clk,
- input cpld_detached,
- output cpld_misc,
- input cpld_init_b,
- input por,
- output config_success,
-
- // ADC
- input [13:0] adc_a,
- input adc_ovf_a,
- output adc_on_a,
- output adc_oe_a,
-
- input [13:0] adc_b,
- input adc_ovf_b,
- output adc_on_b,
- output adc_oe_b,
-
- // DAC
- output [15:0] dac_a,
- output [15:0] dac_b,
-
- // I2C
- input scl_pad_i,
- output scl_pad_o,
- output scl_pad_oen_o,
- input sda_pad_i,
- output sda_pad_o,
- output sda_pad_oen_o,
-
- // Clock Gen Control
- output [1:0] clk_en,
- output [1:0] clk_sel,
- input clk_func, // FIXME is an input to control the 9510
- input clk_status,
-
- // Generic SPI
- output sclk,
- output mosi,
- input miso,
- output sen_clk,
- output sen_dac,
- output sen_tx_db,
- output sen_tx_adc,
- output sen_tx_dac,
- output sen_rx_db,
- output sen_rx_adc,
- output sen_rx_dac,
-
- // GPIO to DBoards
- inout [15:0] io_tx,
- inout [15:0] io_rx,
-
- // External RAM
- inout [17:0] RAM_D,
- output [18:0] RAM_A,
- output RAM_CE1n,
- output RAM_CENn,
- output RAM_CLK,
- output RAM_WEn,
- output RAM_OEn,
- output RAM_LDn,
-
- // Debug stuff
- output uart_tx_o,
- input uart_rx_i,
- output uart_baud_o,
- input sim_mode,
- input [3:0] clock_divider
- );
-
- wire [7:0] set_addr;
- wire [31:0] set_data;
- wire set_stb;
-
- wire ram_loader_done;
- wire ram_loader_rst, wb_rst, dsp_rst;
-
- wire [31:0] status, status_b0, status_b1, status_b2, status_b3, status_b4, status_b5, status_b6, status_b7;
- wire bus_error, spi_int, i2c_int, pps_int, timer_int, buffer_int, proc_int, overrun, underrun, 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_mac0, debug_mac1, debug_tx_dsp, debug_txc,
- debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp;
-
- 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;
- wire ser_rx_empty, ser_tx_empty, dsp_rx_empty, dsp_tx_empty, eth_rx_empty, eth_tx_empty, eth_rx_empty2;
-
- wire serdes_link_up;
- wire epoch;
-
- // ///////////////////////////////////////////////////////////////////////////////////////////////
- // Wishbone Single Master INTERCON
- localparam dw = 32; // Data bus width
- localparam aw = 16; // Address bus width, for byte addressibility, 16 = 64K byte memory space
- localparam sw = 4; // Select width -- 32-bit data bus with 8-bit granularity.
-
- wire [dw-1:0] m0_dat_o, m0_dat_i;
- wire [dw-1:0] s0_dat_o, s1_dat_o, s0_dat_i, s1_dat_i, s2_dat_o, s3_dat_o, s2_dat_i, s3_dat_i,
- s4_dat_o, s5_dat_o, s4_dat_i, s5_dat_i, s6_dat_o, s7_dat_o, s6_dat_i, s7_dat_i,
- s8_dat_o, s9_dat_o, s8_dat_i, s9_dat_i, s10_dat_o, s10_dat_i, s11_dat_i, s11_dat_o,
- s12_dat_i, s12_dat_o, s13_dat_i, s13_dat_o, s14_dat_i, s14_dat_o;
- wire [aw-1:0] m0_adr,s0_adr,s1_adr,s2_adr,s3_adr,s4_adr,s5_adr,s6_adr,s7_adr,s8_adr,s9_adr,s10_adr,s11_adr,s12_adr, s13_adr, s14_adr;
- wire [sw-1:0] m0_sel,s0_sel,s1_sel,s2_sel,s3_sel,s4_sel,s5_sel,s6_sel,s7_sel,s8_sel,s9_sel,s10_sel,s11_sel,s12_sel, s13_sel, s14_sel;
- wire m0_ack,s0_ack,s1_ack,s2_ack,s3_ack,s4_ack,s5_ack,s6_ack,s7_ack,s8_ack,s9_ack,s10_ack,s11_ack,s12_ack, s13_ack, s14_ack;
- wire m0_stb,s0_stb,s1_stb,s2_stb,s3_stb,s4_stb,s5_stb,s6_stb,s7_stb,s8_stb,s9_stb,s10_stb,s11_stb,s12_stb, s13_stb, s14_stb;
- wire m0_cyc,s0_cyc,s1_cyc,s2_cyc,s3_cyc,s4_cyc,s5_cyc,s6_cyc,s7_cyc,s8_cyc,s9_cyc,s10_cyc,s11_cyc,s12_cyc, s13_cyc, s14_cyc;
- wire m0_err,s0_err,s1_err,s2_err,s3_err,s4_err,s5_err,s6_err,s7_err,s8_err,s9_err,s10_err,s11_err,s12_err, s13_err, s14_err;
- wire m0_rty,s0_rty,s1_rty,s2_rty,s3_rty,s4_rty,s5_rty,s6_rty,s7_rty,s8_rty,s9_rty,s10_rty,s11_rty,s12_rty, s13_rty, s14_rty;
- wire m0_we,s0_we,s1_we,s2_we,s3_we,s4_we,s5_we,s6_we,s7_we,s8_we,s9_we,s10_we,s11_we,s12_we,s13_we, s14_we;
-
- wb_1master #(.s0_addr_w(1),.s0_addr(1'b0),.s1_addr_w(2),.s1_addr(2'b10),
- .s215_addr_w(6),.s2_addr(6'b1100_00),.s3_addr(6'b1100_01),.s4_addr(6'b1100_10),
- .s5_addr(6'b1100_11),.s6_addr(6'b1101_00),.s7_addr(6'b1101_01),.s8_addr(6'b1101_10),
- .s9_addr(6'b1101_11),.s10_addr(6'b1110_00),.s11_addr(6'b1110_01),.s12_addr(6'b1110_10),
- .s13_addr(6'b1110_11),.s14_addr(6'b1111_00),.s15_addr(6'b1111_01),
- .dw(dw),.aw(aw),.sw(sw)) wb_1master
- (.clk_i(wb_clk),.rst_i(wb_rst),
- .m0_dat_o(m0_dat_o),.m0_ack_o(m0_ack),.m0_err_o(m0_err),.m0_rty_o(m0_rty),.m0_dat_i(m0_dat_i),
- .m0_adr_i(m0_adr),.m0_sel_i(m0_sel),.m0_we_i(m0_we),.m0_cyc_i(m0_cyc),.m0_stb_i(m0_stb),
- .s0_dat_o(s0_dat_o),.s0_adr_o(s0_adr),.s0_sel_o(s0_sel),.s0_we_o (s0_we),.s0_cyc_o(s0_cyc),.s0_stb_o(s0_stb),
- .s0_dat_i(s0_dat_i),.s0_ack_i(s0_ack),.s0_err_i(s0_err),.s0_rty_i(s0_rty),
- .s1_dat_o(s1_dat_o),.s1_adr_o(s1_adr),.s1_sel_o(s1_sel),.s1_we_o (s1_we),.s1_cyc_o(s1_cyc),.s1_stb_o(s1_stb),
- .s1_dat_i(s1_dat_i),.s1_ack_i(s1_ack),.s1_err_i(s1_err),.s1_rty_i(s1_rty),
- .s2_dat_o(s2_dat_o),.s2_adr_o(s2_adr),.s2_sel_o(s2_sel),.s2_we_o (s2_we),.s2_cyc_o(s2_cyc),.s2_stb_o(s2_stb),
- .s2_dat_i(s2_dat_i),.s2_ack_i(s2_ack),.s2_err_i(s2_err),.s2_rty_i(s2_rty),
- .s3_dat_o(s3_dat_o),.s3_adr_o(s3_adr),.s3_sel_o(s3_sel),.s3_we_o (s3_we),.s3_cyc_o(s3_cyc),.s3_stb_o(s3_stb),
- .s3_dat_i(s3_dat_i),.s3_ack_i(s3_ack),.s3_err_i(s3_err),.s3_rty_i(s3_rty),
- .s4_dat_o(s4_dat_o),.s4_adr_o(s4_adr),.s4_sel_o(s4_sel),.s4_we_o (s4_we),.s4_cyc_o(s4_cyc),.s4_stb_o(s4_stb),
- .s4_dat_i(s4_dat_i),.s4_ack_i(s4_ack),.s4_err_i(s4_err),.s4_rty_i(s4_rty),
- .s5_dat_o(s5_dat_o),.s5_adr_o(s5_adr),.s5_sel_o(s5_sel),.s5_we_o (s5_we),.s5_cyc_o(s5_cyc),.s5_stb_o(s5_stb),
- .s5_dat_i(s5_dat_i),.s5_ack_i(s5_ack),.s5_err_i(s5_err),.s5_rty_i(s5_rty),
- .s6_dat_o(s6_dat_o),.s6_adr_o(s6_adr),.s6_sel_o(s6_sel),.s6_we_o (s6_we),.s6_cyc_o(s6_cyc),.s6_stb_o(s6_stb),
- .s6_dat_i(s6_dat_i),.s6_ack_i(s6_ack),.s6_err_i(s6_err),.s6_rty_i(s6_rty),
- .s7_dat_o(s7_dat_o),.s7_adr_o(s7_adr),.s7_sel_o(s7_sel),.s7_we_o (s7_we),.s7_cyc_o(s7_cyc),.s7_stb_o(s7_stb),
- .s7_dat_i(s7_dat_i),.s7_ack_i(s7_ack),.s7_err_i(s7_err),.s7_rty_i(s7_rty),
- .s8_dat_o(s8_dat_o),.s8_adr_o(s8_adr),.s8_sel_o(s8_sel),.s8_we_o (s8_we),.s8_cyc_o(s8_cyc),.s8_stb_o(s8_stb),
- .s8_dat_i(s8_dat_i),.s8_ack_i(s8_ack),.s8_err_i(s8_err),.s8_rty_i(s8_rty),
- .s9_dat_o(s9_dat_o),.s9_adr_o(s9_adr),.s9_sel_o(s9_sel),.s9_we_o (s9_we),.s9_cyc_o(s9_cyc),.s9_stb_o(s9_stb),
- .s9_dat_i(s9_dat_i),.s9_ack_i(s9_ack),.s9_err_i(s9_err),.s9_rty_i(s9_rty),
- .s10_dat_o(s10_dat_o),.s10_adr_o(s10_adr),.s10_sel_o(s10_sel),.s10_we_o(s10_we),.s10_cyc_o(s10_cyc),.s10_stb_o(s10_stb),
- .s10_dat_i(s10_dat_i),.s10_ack_i(s10_ack),.s10_err_i(s10_err),.s10_rty_i(s10_rty),
- .s11_dat_o(s11_dat_o),.s11_adr_o(s11_adr),.s11_sel_o(s11_sel),.s11_we_o(s11_we),.s11_cyc_o(s11_cyc),.s11_stb_o(s11_stb),
- .s11_dat_i(s11_dat_i),.s11_ack_i(s11_ack),.s11_err_i(s11_err),.s11_rty_i(s11_rty),
- .s12_dat_o(s12_dat_o),.s12_adr_o(s12_adr),.s12_sel_o(s12_sel),.s12_we_o(s12_we),.s12_cyc_o(s12_cyc),.s12_stb_o(s12_stb),
- .s12_dat_i(s12_dat_i),.s12_ack_i(s12_ack),.s12_err_i(s12_err),.s12_rty_i(s12_rty),
- .s13_dat_o(s13_dat_o),.s13_adr_o(s13_adr),.s13_sel_o(s13_sel),.s13_we_o(s13_we),.s13_cyc_o(s13_cyc),.s13_stb_o(s13_stb),
- .s13_dat_i(s13_dat_i),.s13_ack_i(s13_ack),.s13_err_i(s13_err),.s13_rty_i(s13_rty),
- .s14_dat_o(s14_dat_o),.s14_adr_o(s14_adr),.s14_sel_o(s14_sel),.s14_we_o(s14_we),.s14_cyc_o(s14_cyc),.s14_stb_o(s14_stb),
- .s14_dat_i(s14_dat_i),.s14_ack_i(s14_ack),.s14_err_i(s14_err),.s14_rty_i(s14_rty),
- .s15_dat_i(0),.s15_ack_i(0),.s15_err_i(0),.s15_rty_i(0) );
-
- //////////////////////////////////////////////////////////////////////////////////////////
- // Reset Controller
- system_control sysctrl (.wb_clk_i(wb_clk), // .por_i(por),
- .ram_loader_rst_o(ram_loader_rst),
- .wb_rst_o(wb_rst),
- .ram_loader_done_i(ram_loader_done));
-
- assign config_success = ram_loader_done;
- reg takeover = 0;
-
- wire cpld_start_int, cpld_mode_int, cpld_done_int;
-
- always @(posedge wb_clk)
- if(ram_loader_done)
- takeover = 1;
- assign cpld_misc = ~takeover;
-
- wire sd_clk, sd_csn, sd_mosi, sd_miso;
-
- assign sd_miso = cpld_din;
- assign cpld_start = takeover ? sd_clk : cpld_start_int;
- assign cpld_mode = takeover ? sd_csn : cpld_mode_int;
- assign cpld_done = takeover ? sd_mosi : cpld_done_int;
-
- // ///////////////////////////////////////////////////////////////////
- // RAM Loader
-
- wire [31:0] ram_loader_dat, iwb_dat;
- wire [15:0] ram_loader_adr, iwb_adr;
- wire [3:0] ram_loader_sel;
- wire ram_loader_stb, ram_loader_we, ram_loader_ack;
- wire iwb_ack, iwb_stb;
- ram_loader #(.AWIDTH(16),.RAM_SIZE(RAM_SIZE))
- ram_loader (.clk_i(wb_clk),.rst_i(ram_loader_rst),
- // CPLD Interface
- .cfg_clk_i(cpld_clk),
- .cfg_data_i(cpld_din),
- .start_o(cpld_start_int),
- .mode_o(cpld_mode_int),
- .done_o(cpld_done_int),
- .detached_i(cpld_detached),
- // Wishbone Interface
- .wb_dat_o(ram_loader_dat),.wb_adr_o(ram_loader_adr),
- .wb_stb_o(ram_loader_stb),.wb_cyc_o(),.wb_sel_o(ram_loader_sel),
- .wb_we_o(ram_loader_we),.wb_ack_i(ram_loader_ack),
- .ram_loader_done_o(ram_loader_done));
-
- // Processor
- aeMB_core_BE #(.ISIZ(16),.DSIZ(16),.MUL(0),.BSF(1))
- aeMB (.sys_clk_i(wb_clk), .sys_rst_i(wb_rst),
- // Instruction Wishbone bus to I-RAM
- .iwb_stb_o(iwb_stb),.iwb_adr_o(iwb_adr),
- .iwb_dat_i(iwb_dat),.iwb_ack_i(iwb_ack),
- // Data Wishbone bus to system bus fabric
- .dwb_we_o(m0_we),.dwb_stb_o(m0_stb),.dwb_dat_o(m0_dat_i),.dwb_adr_o(m0_adr),
- .dwb_dat_i(m0_dat_o),.dwb_ack_i(m0_ack),.dwb_sel_o(m0_sel),.dwb_cyc_o(m0_cyc),
- // Interrupts and exceptions
- .sys_int_i(proc_int),.sys_exc_i(bus_error) );
-
- assign bus_error = m0_err | m0_rty;
-
- // Dual Ported RAM -- D-Port is Slave #0 on main Wishbone
- // I-port connects directly to processor and ram loader
-
- wire flush_icache;
- ram_harv_cache #(.AWIDTH(15),.RAM_SIZE(RAM_SIZE),.ICWIDTH(7),.DCWIDTH(6))
- sys_ram(.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
-
- .ram_loader_adr_i(ram_loader_adr[14:0]), .ram_loader_dat_i(ram_loader_dat),
- .ram_loader_stb_i(ram_loader_stb), .ram_loader_sel_i(ram_loader_sel),
- .ram_loader_we_i(ram_loader_we), .ram_loader_ack_o(ram_loader_ack),
- .ram_loader_done_i(ram_loader_done),
-
- .iwb_adr_i(iwb_adr[14:0]), .iwb_stb_i(iwb_stb),
- .iwb_dat_o(iwb_dat), .iwb_ack_o(iwb_ack),
-
- .dwb_adr_i(s0_adr[14:0]), .dwb_dat_i(s0_dat_o), .dwb_dat_o(s0_dat_i),
- .dwb_we_i(s0_we), .dwb_ack_o(s0_ack), .dwb_stb_i(s0_stb), .dwb_sel_i(s0_sel),
- .flush_icache(flush_icache));
-
- assign s0_err = 1'b0;
- assign s0_rty = 1'b0;
-
- setting_reg #(.my_addr(7)) sr_icache (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(),.changed(flush_icache));
-
- // Buffer Pool, slave #1
- wire rd0_read, rd0_sop, rd0_error, rd0_done, rd0_eop;
- wire rd1_read, rd1_sop, rd1_error, rd1_done, rd1_eop;
- wire rd2_read, rd2_sop, rd2_error, rd2_done, rd2_eop;
- wire rd3_read, rd3_sop, rd3_error, rd3_done, rd3_eop;
- wire [31:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat;
-
- wire wr0_write, wr0_done, wr0_error, wr0_ready, wr0_full;
- wire wr1_write, wr1_done, wr1_error, wr1_ready, wr1_full;
- wire wr2_write, wr2_done, wr2_error, wr2_ready, wr2_full;
- wire wr3_write, wr3_done, wr3_error, wr3_ready, wr3_full;
- wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
-
- buffer_pool buffer_pool
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),
- .wb_we_i(s1_we),.wb_stb_i(s1_stb),.wb_adr_i(s1_adr),.wb_dat_i(s1_dat_o),
- .wb_dat_o(s1_dat_i),.wb_ack_o(s1_ack),.wb_err_o(s1_err),.wb_rty_o(s1_rty),
-
- .stream_clk(dsp_clk), .stream_rst(dsp_rst),
- .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
- .status(status),.sys_int_o(buffer_int),
-
- .s0(status_b0),.s1(status_b1),.s2(status_b2),.s3(status_b3),
- .s4(status_b4),.s5(status_b5),.s6(status_b6),.s7(status_b7),
-
- // Write Interfaces
- .wr0_dat_i(wr0_dat), .wr0_write_i(wr0_write), .wr0_done_i(wr0_done),
- .wr0_error_i(wr0_error), .wr0_ready_o(wr0_ready), .wr0_full_o(wr0_full),
- .wr1_dat_i(wr1_dat), .wr1_write_i(wr1_write), .wr1_done_i(wr1_done),
- .wr1_error_i(wr1_error), .wr1_ready_o(wr1_ready), .wr1_full_o(wr1_full),
- .wr2_dat_i(wr2_dat), .wr2_write_i(wr2_write), .wr2_done_i(wr2_done),
- .wr2_error_i(wr2_error), .wr2_ready_o(wr2_ready), .wr2_full_o(wr2_full),
- .wr3_dat_i(wr3_dat), .wr3_write_i(wr3_write), .wr3_done_i(wr3_done),
- .wr3_error_i(wr3_error), .wr3_ready_o(wr3_ready), .wr3_full_o(wr3_full),
- // Read Interfaces
- .rd0_dat_o(rd0_dat), .rd0_read_i(rd0_read), .rd0_done_i(rd0_done),
- .rd0_error_i(rd0_error), .rd0_sop_o(rd0_sop), .rd0_eop_o(rd0_eop),
- .rd1_dat_o(rd1_dat), .rd1_read_i(rd1_read), .rd1_done_i(rd1_done),
- .rd1_error_i(rd1_error), .rd1_sop_o(rd1_sop), .rd1_eop_o(rd1_eop),
- .rd2_dat_o(rd2_dat), .rd2_read_i(rd2_read), .rd2_done_i(rd2_done),
- .rd2_error_i(rd2_error), .rd2_sop_o(rd2_sop), .rd2_eop_o(rd2_eop),
- .rd3_dat_o(rd3_dat), .rd3_read_i(rd3_read), .rd3_done_i(rd3_done),
- .rd3_error_i(rd3_error), .rd3_sop_o(rd3_sop), .rd3_eop_o(rd3_eop)
- );
-
- // SPI -- Slave #2
- spi_top shared_spi
- (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.wb_adr_i(s2_adr[4:0]),.wb_dat_i(s2_dat_o),
- .wb_dat_o(s2_dat_i),.wb_sel_i(s2_sel),.wb_we_i(s2_we),.wb_stb_i(s2_stb),
- .wb_cyc_i(s2_cyc),.wb_ack_o(s2_ack),.wb_err_o(s2_err),.wb_int_o(spi_int),
- .ss_pad_o({sen_tx_db,sen_tx_adc,sen_tx_dac,sen_rx_db,sen_rx_adc,sen_rx_dac,sen_dac,sen_clk}),
- .sclk_pad_o(sclk),.mosi_pad_o(mosi),.miso_pad_i(miso) );
-
- assign s2_rty = 1'b0;
-
- // I2C -- Slave #3
- i2c_master_top #(.ARST_LVL(1))
- i2c (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst),.arst_i(1'b0),
- .wb_adr_i(s3_adr[4:2]),.wb_dat_i(s3_dat_o[7:0]),.wb_dat_o(s3_dat_i[7:0]),
- .wb_we_i(s3_we),.wb_stb_i(s3_stb),.wb_cyc_i(s3_cyc),
- .wb_ack_o(s3_ack),.wb_inta_o(i2c_int),
- .scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_pad_oen_o),
- .sda_pad_i(sda_pad_i),.sda_pad_o(sda_pad_o),.sda_padoen_o(sda_pad_oen_o) );
-
- assign s3_dat_i[31:8] = 24'd0;
- assign s3_err = 1'b0;
- assign s3_rty = 1'b0;
-
- // GPIOs -- Slave #4
- nsgpio nsgpio(.clk_i(wb_clk),.rst_i(wb_rst),
- .cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we),
- .dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack),
- .atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1),
- .gpio( {io_tx,io_rx} ) );
- assign s4_err = 1'b0;
- assign s4_rty = 1'b0;
-
- // Buffer Pool Status -- Slave #5
- 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(status_b0),.word01(status_b1),.word02(status_b2),.word03(status_b3),
- .word04(status_b4),.word05(status_b5),.word06(status_b6),.word07(status_b7),
- .word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(32'b0),
- .word11(32'b0),.word12(32'b0),.word13(32'b0),.word14(32'b0),.word15(32'b0)
- );
-
- assign s5_err = 1'b0;
- assign s5_rty = 1'b0;
-
- // Slave, #6 Ethernet MAC, see below
-
- // Settings Bus -- Slave #7
- settings_bus settings_bus
- (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s7_adr),.wb_dat_i(s7_dat_o),
- .wb_stb_i(s7_stb),.wb_we_i(s7_we),.wb_ack_o(s7_ack),
- .sys_clk(dsp_clk),.strobe(set_stb),.addr(set_addr),.data(set_data));
-
- assign s7_err = 1'b0;
- assign s7_rty = 1'b0;
- assign s7_dat_i = 32'd0;
-
- // Output control lines
- wire [7:0] clock_outs, serdes_outs, adc_outs;
- assign {clock_ready, clk_en[1:0], clk_sel[1:0]} = clock_outs[4:0];
- assign {ser_enable, ser_prbsen, ser_loopen, ser_rx_en} = serdes_outs[3:0];
- assign {adc_oe_a, adc_on_a, adc_oe_b, adc_on_b } = adc_outs[3:0];
-
- wire phy_reset;
- assign PHY_RESETn = ~phy_reset;
-
- setting_reg #(.my_addr(0)) 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)) 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)) 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)) sr_phy (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(phy_reset),.changed());
-
- // /////////////////////////////////////////////////////////////////////////
- // LEDS
- // register 8 determines whether leds are controlled by SW or not
- // 1 = controlled by HW, 0 = by SW
- // In Rev3 there are only 6 leds, and the highest one is on the ETH connector
-
- wire [7:0] led_src, led_sw;
- wire [7:0] led_hw = {clk_status,serdes_link_up};
-
- setting_reg #(.my_addr(3)) 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)) 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);
-
- // /////////////////////////////////////////////////////////////////////////
- // Ethernet MAC Slave #6
-
- wire Tx_mac_wa, Tx_mac_wr, Tx_mac_sop, Tx_mac_eop;
- wire Rx_mac_empty, Rx_mac_rd, Rx_mac_sop, Rx_mac_eop, Rx_mac_err;
- wire [31:0] Tx_mac_data, Rx_mac_data;
- wire [1:0] Tx_mac_BE, Rx_mac_BE;
- wire rst_mac;
-
- oneshot_2clk mac_rst_1shot (.clk_in(wb_clk),.in(wb_rst),.clk_out(clk_to_mac),.out(rst_mac));
-
- MAC_top #(.TX_FF_DEPTH(9), .RX_FF_DEPTH(11))
- MAC_top
- (.Clk_125M(clk_to_mac),.Clk_user(dsp_clk),
- .rst_mac(rst_mac),.rst_user(dsp_rst),
- .RST_I(wb_rst),.CLK_I(wb_clk),.STB_I(s6_stb),.CYC_I(s6_cyc),.ADR_I(s6_adr[8:2]),
- .WE_I(s6_we),.DAT_I(s6_dat_o),.DAT_O(s6_dat_i),.ACK_O(s6_ack),
- .Rx_mac_empty(Rx_mac_empty),.Rx_mac_rd(Rx_mac_rd),.Rx_mac_data(Rx_mac_data),.Rx_mac_BE(Rx_mac_BE),
- .Rx_mac_sop(Rx_mac_sop),.Rx_mac_eop(Rx_mac_eop),.Rx_mac_err(Rx_mac_err),
- .Tx_mac_wa(Tx_mac_wa),.Tx_mac_wr(Tx_mac_wr),.Tx_mac_data(Tx_mac_data),
- .Tx_mac_BE(Tx_mac_BE),.Tx_mac_sop(Tx_mac_sop),.Tx_mac_eop(Tx_mac_eop),
- .Gtx_clk(GMII_GTX_CLK),.Tx_clk(GMII_TX_CLK),.Tx_er(GMII_TX_ER),.Tx_en(GMII_TX_EN),.Txd(GMII_TXD),
- .Rx_clk(GMII_RX_CLK),.Rx_er(GMII_RX_ER),.Rx_dv(GMII_RX_DV),.Rxd(GMII_RXD),
- .Crs(GMII_CRS),.Col(GMII_COL),
- .Mdio(MDIO),.Mdc(MDC),
- .rx_fifo_occupied(eth_rx_occ2),.rx_fifo_full(eth_rx_full2),.rx_fifo_empty(eth_rx_empty2),
- .tx_fifo_occupied(),.tx_fifo_full(),.tx_fifo_empty(),
- .debug0(debug_mac0),.debug1(debug_mac1) );
-
- assign s6_err = 1'b0;
- assign s6_rty = 1'b0;
-
- mac_rxfifo_int mac_rxfifo_int
- (.clk(dsp_clk),.rst(dsp_rst),
- .Rx_mac_empty(Rx_mac_empty),.Rx_mac_rd(Rx_mac_rd),.Rx_mac_data(Rx_mac_data),
- .Rx_mac_BE(Rx_mac_BE),.Rx_mac_sop(Rx_mac_sop),
- .Rx_mac_eop(Rx_mac_eop),.Rx_mac_err(Rx_mac_err),
- .wr_dat_o(wr2_dat),.wr_write_o(wr2_write),.wr_done_o(wr2_done),
- .wr_error_o(wr2_error),.wr_ready_i(wr2_ready),.wr_full_i(wr2_full),
- .fifo_occupied(eth_rx_occ),.fifo_full(eth_rx_full),.fifo_empty(eth_rx_empty) );
-
- mac_txfifo_int mac_txfifo_int
- (.clk(dsp_clk),.rst(dsp_rst),.mac_clk(clk_to_mac),
- .Tx_mac_wa(Tx_mac_wa),.Tx_mac_wr(Tx_mac_wr),.Tx_mac_data(Tx_mac_data),
- .Tx_mac_BE(Tx_mac_BE),.Tx_mac_sop(Tx_mac_sop),.Tx_mac_eop(Tx_mac_eop),
- .rd_dat_i(rd2_dat),.rd_read_o(rd2_read),.rd_done_o(rd2_done),
- .rd_error_o(rd2_error),.rd_sop_i(rd2_sop),.rd_eop_i(rd2_eop),
- .fifo_occupied(eth_tx_occ),.fifo_full(eth_tx_full),.fifo_empty(eth_tx_empty) );
-
- // /////////////////////////////////////////////////////////////////////////
- // Interrupt Controller, Slave #8
-
- wire [15:0] irq={{4'b0, clk_status, serdes_link_up, uart_tx_int, uart_rx_int},
- {pps_int,overrun,underrun,PHY_INTn,i2c_int,spi_int,timer_int,buffer_int}};
-
- simple_pic #(.is(16),.dwidth(32)) simple_pic
- (.clk_i(wb_clk),.rst_i(wb_rst),.cyc_i(s8_cyc),.stb_i(s8_stb),.adr_i(s8_adr[3:2]),
- .we_i(s8_we),.dat_i(s8_dat_o),.dat_o(s8_dat_i),.ack_o(s8_ack),.int_o(proc_int),
- .irq(irq) );
- assign s8_err = 0;
- assign s8_rty = 0;
-
- // /////////////////////////////////////////////////////////////////////////
- // Master Timer, Slave #9
-
- wire [31:0] master_time;
- timer timer
- (.wb_clk_i(wb_clk),.rst_i(wb_rst),
- .cyc_i(s9_cyc),.stb_i(s9_stb),.adr_i(s9_adr[4:2]),
- .we_i(s9_we),.dat_i(s9_dat_o),.dat_o(s9_dat_i),.ack_o(s9_ack),
- .sys_clk_i(dsp_clk),.master_time_i(master_time),.int_o(timer_int) );
- assign s9_err = 0;
- assign s9_rty = 0;
-
- // /////////////////////////////////////////////////////////////////////////
- // UART, Slave #10
-
- simple_uart #(.TXDEPTH(3),.RXDEPTH(3)) uart // depth of 3 is 128 entries
- (.clk_i(wb_clk),.rst_i(wb_rst),
- .we_i(s10_we),.stb_i(s10_stb),.cyc_i(s10_cyc),.ack_o(s10_ack),
- .adr_i(s10_adr[4:2]),.dat_i(s10_dat_o),.dat_o(s10_dat_i),
- .rx_int_o(uart_rx_int),.tx_int_o(uart_tx_int),
- .tx_o(uart_tx_o),.rx_i(uart_rx_i),.baud_o(uart_baud_o));
-
- assign s10_err = 0;
- assign s10_rty = 0;
-
- // /////////////////////////////////////////////////////////////////////////
- // ATR Controller, Slave #11
-
- wire run_rx, run_tx;
- reg run_rx_d1;
- always @(posedge dsp_clk)
- run_rx_d1 <= run_rx;
-
- atr_controller atr_controller
- (.clk_i(wb_clk),.rst_i(wb_rst),
- .adr_i(s11_adr[5:0]),.sel_i(s11_sel),.dat_i(s11_dat_o),.dat_o(s11_dat_i),
- .we_i(s11_we),.stb_i(s11_stb),.cyc_i(s11_cyc),.ack_o(s11_ack),
- .run_rx(run_rx_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) );
- assign s11_err = 0;
- assign s11_rty = 0;
-
- // //////////////////////////////////////////////////////////////////////////
- // Time Sync, Slave #12
-
- reg pps_posedge, pps_negedge, pps_pos_d1, pps_neg_d1;
- always @(negedge dsp_clk) pps_negedge <= pps_in;
- always @(posedge dsp_clk) pps_posedge <= pps_in;
- always @(posedge dsp_clk) pps_pos_d1 <= pps_posedge;
- always @(posedge dsp_clk) pps_neg_d1 <= pps_negedge;
-
- wire pps_o;
- time_sync time_sync
- (.wb_clk_i(wb_clk),.rst_i(wb_rst),
- .cyc_i(s12_cyc),.stb_i(s12_stb),.adr_i(s12_adr[4:2]),
- .we_i(s12_we),.dat_i(s12_dat_o),.dat_o(s12_dat_i),.ack_o(s12_ack),
- .sys_clk_i(dsp_clk),.master_time_o(master_time),
- .pps_posedge(pps_posedge),.pps_negedge(pps_negedge),
- .exp_pps_in(exp_pps_in),.exp_pps_out(exp_pps_out),
- .int_o(pps_int),.epoch_o(epoch),.pps_o(pps_o) );
- assign s12_err = 0;
- assign s12_rty = 0;
-
- // /////////////////////////////////////////////////////////////////////////
- // SD Card Reader / Writer, Slave #13
-
- sd_spi_wb sd_spi_wb
- (.clk(wb_clk),.rst(wb_rst),
- .sd_clk(sd_clk),.sd_csn(sd_csn),.sd_mosi(sd_mosi),.sd_miso(sd_miso),
- .wb_cyc_i(s13_cyc),.wb_stb_i(s13_stb),.wb_we_i(s13_we),
- .wb_adr_i(s13_adr[3:2]),.wb_dat_i(s13_dat_o),.wb_dat_o(s13_dat_i),
- .wb_ack_o(s13_ack) );
- assign s13_err = 0;
- assign s13_rty = 0;
- // /////////////////////////////////////////////////////////////////////////
- // DSP
- wire [31:0] sample_rx, sample_tx;
- wire strobe_rx, strobe_tx;
-
- rx_control #(.FIFOSIZE(10)) rx_control
- (.clk(dsp_clk), .rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .master_time(master_time),.overrun(overrun),
- .wr_dat_o(wr1_dat), .wr_write_o(wr1_write), .wr_done_o(wr1_done), .wr_error_o(wr1_error),
- .wr_ready_i(wr1_ready), .wr_full_i(wr1_full),
- .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
- .fifo_occupied(dsp_rx_occ),.fifo_full(dsp_rx_full),.fifo_empty(dsp_rx_empty),
- .debug_rx(debug_rx) );
-
- // dummy_rx dsp_core_rx
- dsp_core_rx dsp_core_rx
- (.clk(dsp_clk),.rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .io_rx(io_rx),.sample(sample_rx), .run(run_rx_d1), .strobe(strobe_rx),
- .debug(debug_rx_dsp) );
-
- tx_control #(.FIFOSIZE(10)) tx_control
- (.clk(dsp_clk), .rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .master_time(master_time),.underrun(underrun),
- .rd_dat_i(rd1_dat), .rd_sop_i(rd1_sop), .rd_eop_i(rd1_eop),
- .rd_read_o(rd1_read), .rd_done_o(rd1_done), .rd_error_o(rd1_error),
- .sample(sample_tx), .run(run_tx), .strobe(strobe_tx),
- .fifo_occupied(dsp_tx_occ),.fifo_full(dsp_tx_full),.fifo_empty(dsp_tx_empty),
- .debug(debug_txc) );
-
- dsp_core_tx dsp_core_tx
- (.clk(dsp_clk),.rst(dsp_rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .dac_a(dac_a),.dac_b(dac_b),
- .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug(debug_tx_dsp) );
-
- assign dsp_rst = wb_rst;
-
- // ///////////////////////////////////////////////////////////////////////////////////
- // SERDES
-
- serdes #(.TXFIFOSIZE(9),.RXFIFOSIZE(9)) 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_read_o(rd0_read),.rd_done_o(rd0_done),.rd_error_o(rd0_error),
- .rd_sop_i(rd0_sop),.rd_eop_i(rd0_eop),
- .ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb),
- .wr_dat_o(wr0_dat),.wr_write_o(wr0_write),.wr_done_o(wr0_done),.wr_error_o(wr0_error),
- .wr_ready_i(wr0_ready),.wr_full_i(wr0_full),
- .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) );
-
-`ifdef EXTRAM
- // ///////////////////////////////////////////////////////////////////////////////////
- // External RAM Interface
-
- localparam PAGE_SIZE = 10; // PAGE SIZE is in bytes, 10 = 1024 bytes
-
- wire [15:0] bus2ram, ram2bus;
- wire [15:0] bridge_adr;
- wire [1:0] bridge_sel;
- wire bridge_stb, bridge_cyc, bridge_we, bridge_ack;
-
- wire [19:0] page;
- wire [19:0] wb_ram_adr = {page[19:PAGE_SIZE],bridge_adr[PAGE_SIZE-1:0]};
- setting_reg #(.my_addr(6)) sr_page (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(page),.changed());
-
- wb_bridge_16_32 bridge
- (.wb_clk(wb_clk),.wb_rst(wb_rst),
- .A_cyc_i(s14_cyc),.A_stb_i(s14_stb),.A_we_i(s14_we),.A_sel_i(s14_sel),
- .A_adr_i(s14_adr),.A_dat_i(s14_dat_o),.A_dat_o(s14_dat_i),.A_ack_o(s14_ack),
- .B_cyc_o(bridge_cyc),.B_stb_o(bridge_stb),.B_we_o(bridge_we),.B_sel_o(bridge_sel),
- .B_adr_o(bridge_adr),.B_dat_o(bus2ram),.B_dat_i(ram2bus),.B_ack_i(bridge_ack));
-
- wb_zbt16_b wb_zbt16_b
- (.clk(wb_clk),.rst(wb_rst),
- .wb_adr_i(wb_ram_adr),.wb_dat_i(bus2ram),.wb_dat_o(ram2bus),.wb_sel_i(bridge_sel),
- .wb_cyc_i(bridge_cyc),.wb_stb_i(bridge_stb),.wb_ack_o(bridge_ack),.wb_we_i(bridge_we),
- .sram_clk(RAM_CLK),.sram_a(RAM_A),.sram_d(RAM_D[15:0]),.sram_we(RAM_WEn),
- .sram_bw(),.sram_adv(RAM_LDn),.sram_ce(RAM_CENn),.sram_oe(RAM_OEn),
- .sram_mode(),.sram_zz() );
-
- assign s14_err = 0; assign s14_rty = 0;
- assign RAM_CE1n = 0;
- assign RAM_D[17:16] = 2'bzz;
-`endif
-
-`ifdef DEBUG
- // /////////////////////////////////////////////////////////////////////////////////////////
- // Debug Pins
-
- // FIFO Level Debugging
- reg [31:0] host_to_dsp_fifo,dsp_to_host_fifo,eth_mac_debug,serdes_to_dsp_fifo,dsp_to_serdes_fifo;
-
- always @(posedge dsp_clk)
- serdes_to_dsp_fifo <= { {ser_rx_full,ser_rx_empty,ser_rx_occ[13:0]},
- {dsp_tx_full,dsp_tx_empty,dsp_tx_occ[13:0]} };
-
- always @(posedge dsp_clk)
- dsp_to_serdes_fifo <= { {ser_tx_full,ser_tx_empty,ser_tx_occ[13:0]},
- {dsp_rx_full,dsp_rx_empty,dsp_rx_occ[13:0]} };
-
- always @(posedge dsp_clk)
- host_to_dsp_fifo <= { {eth_rx_full,eth_rx_empty,eth_rx_occ[13:0]},
- {dsp_tx_full,dsp_tx_empty,dsp_tx_occ[13:0]} };
-
- always @(posedge dsp_clk)
- dsp_to_host_fifo <= { {eth_tx_full,eth_tx_empty,eth_tx_occ[13:0]},
- {dsp_rx_full,dsp_rx_empty,dsp_rx_occ[13:0]} };
-
- always @(posedge dsp_clk)
- eth_mac_debug <= { { 6'd0, GMII_TX_EN, GMII_RX_DV, debug_mac0[7:0]},
- {eth_rx_full2, eth_rx_empty2, eth_rx_occ2[13:0]} };
-
- assign debug_clk[0] = 0;
- assign debug_clk[1] = dsp_clk;
-
- assign debug = host_to_dsp_fifo; // debug_mux ? host_to_dsp_fifo : dsp_to_host_fifo;
- assign debug_gpio_0 = eth_mac_debug;
- assign debug_gpio_1 = 0;
-`endif
-
-endmodule // u2_core
-
-// wire debug_mux;
-// setting_reg #(.my_addr(5)) sr_debug (.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),
-// .in(set_data),.out(debug_mux),.changed());
-
-//assign debug = debug_mux ? host_to_dsp_fifo : dsp_to_host_fifo;
-//assign debug = debug_mux ? serdes_to_dsp_fifo : dsp_to_serdes_fifo;
-
-//assign debug = {{strobe_rx,/*adc_ovf_a*/ 1'b0,adc_a},
-// {run_rx,/*adc_ovf_b*/ 1'b0,adc_b}};
-
-//assign debug = debug_tx_dsp;
-//assign debug = debug_serdes0;
-
-//assign debug_gpio_0 = 0; //debug_serdes0;
-//assign debug_gpio_1 = 0; //debug_serdes1;
-
-// assign debug={{3'b0, wb_clk, wb_rst, dsp_rst, por, config_success},
-// {8'b0},
-// {3'b0,ram_loader_ack, ram_loader_stb, ram_loader_we,ram_loader_rst,ram_loader_done },
-// {cpld_start,cpld_mode,cpld_done,cpld_din,cpld_clk,cpld_detached,cpld_misc,cpld_init_b} };
-
-//assign debug = {dac_a,dac_b};
-
-/*
- assign debug = {{ram_loader_done, takeover, 6'd0},
- {1'b0, cpld_start_int, cpld_mode_int, cpld_done_int, sd_clk, sd_csn, sd_miso, sd_mosi},
- {8'd0},
- {cpld_start, cpld_mode, cpld_done, cpld_din, cpld_misc, cpld_detached, cpld_clk, cpld_init_b}}; */
-
-/*assign debug = host_to_dsp_fifo;
- assign debug_gpio_0 = eth_mac_debug;
- assign debug_gpio_1 = 0;
- */
-// Assign various commonly used debug buses.
-/*
- wire [31:0] debug_rx_1 = {uart_tx_o,GMII_TX_EN,strobe_rx,overrun,proc_int,buffer_int,timer_int,GMII_RX_DV,
- irq[7:0],
- GMII_RXD,
- GMII_TXD};
-
- wire [31:0] debug_rx_2 = { 5'd0, s8_we, s8_stb, s8_ack, debug_rx[23:0] };
-
- wire [31:0] debug_time = {uart_tx_o, 7'b0,
- irq[7:0],
- 6'b0, GMII_RX_DV, GMII_TX_EN,
- 4'b0, exp_pps_in, exp_pps_out, pps_in, pps_int};
-
- wire [31:0] debug_irq = {uart_tx_o, iwb_adr, iwb_ack,
- irq[7:0],
- proc_int, 7'b0 };
-
- wire [31:0] debug_eth =
- {{uart_tx_o,proc_int,underrun,buffer_int,wr2_ready,wr2_error,wr2_done,wr2_write},
- {8'd0},
- {8'd0},
- {GMII_TX_EN,GMII_RX_DV,Rx_mac_empty,Rx_mac_rd,Rx_mac_err,Rx_mac_sop,Rx_mac_eop,wr2_full} };
-
- assign debug_serdes0 = { { rd0_dat[7:0] },
- { ser_tx_clk, ser_tkmsb, ser_tklsb, rd0_sop, rd0_eop, rd0_read, rd0_error, rd0_done },
- { ser_t[15:8] },
- { ser_t[7:0] } };
-
- assign debug_serdes1 = { {1'b0,proc_int,underrun,buffer_int,wr0_ready,wr0_error,wr0_done,wr0_write},
- { 1'b0, ser_rx_clk, ser_rkmsb, ser_rklsb, ser_enable, ser_prbsen, ser_loopen, ser_rx_en },
- { ser_r[15:8] },
- { ser_r[7:0] } };
-
- assign debug_gpio_1 = {uart_tx_o,7'd0,
- 3'd0,rd1_sop,rd1_eop,rd1_read,rd1_done,rd1_error,
- debug_txc[15:0]};
- assign debug_gpio_1 = debug_rx;
- assign debug_gpio_1 = debug_serdes1;
- assign debug_gpio_1 = debug_eth;
-
- */
-
diff --git a/fpga/usrp2/top/u2_rev3_2rx_iad/wave.sh b/fpga/usrp2/top/u2_rev3_2rx_iad/wave.sh
deleted file mode 100755
index 626f224e5..000000000
--- a/fpga/usrp2/top/u2_rev3_2rx_iad/wave.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-gtkwave dsp_core_tb.vcd dsp_core_tb.sav &
diff --git a/fpga/usrp2/top/u2_rev3_iad/.gitignore b/fpga/usrp2/top/u2_rev3_iad/.gitignore
deleted file mode 100644
index e4daaf1ea..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/build
-/*.vcd
-/dsp_core_tb
-/*.dat
diff --git a/fpga/usrp2/top/u2_rev3_iad/Makefile b/fpga/usrp2/top/u2_rev3_iad/Makefile
deleted file mode 100644
index 15df9e43e..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/Makefile
+++ /dev/null
@@ -1,253 +0,0 @@
-#
-# Copyright 2008 Ettus Research LLC
-#
-# 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-##################################################
-# xtclsh Shell and tcl Script Path
-##################################################
-#XTCLSH := /opt/Xilinx/10.1/ISE/bin/lin/xtclsh
-XTCLSH := xtclsh
-ISE_HELPER := ../tcl/ise_helper.tcl
-
-##################################################
-# Project Setup
-##################################################
-BUILD_DIR := build/
-export TOP_MODULE := u2_rev3
-export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
-
-##################################################
-# Project Properties
-##################################################
-export PROJECT_PROPERTIES := \
-family Spartan3 \
-device xc3s2000 \
-package fg456 \
-speed -5 \
-top_level_module_type "HDL" \
-synthesis_tool "XST (VHDL/Verilog)" \
-simulator "ISE Simulator (VHDL/Verilog)" \
-"Preferred Language" "Verilog" \
-"Enable Message Filtering" FALSE \
-"Display Incremental Messages" FALSE
-
-##################################################
-# Sources
-##################################################
-export SOURCE_ROOT := ../../../
-export SOURCES := \
-control_lib/CRC16_D16.v \
-control_lib/atr_controller.v \
-control_lib/bin2gray.v \
-control_lib/buffer_int.v \
-control_lib/buffer_pool.v \
-control_lib/cascadefifo2.v \
-control_lib/dcache.v \
-control_lib/decoder_3_8.v \
-control_lib/dpram32.v \
-control_lib/fifo_2clock.v \
-control_lib/fifo_2clock_casc.v \
-control_lib/gray2bin.v \
-control_lib/gray_send.v \
-control_lib/icache.v \
-control_lib/longfifo.v \
-control_lib/mux4.v \
-control_lib/mux8.v \
-control_lib/nsgpio.v \
-control_lib/ram_2port.v \
-control_lib/ram_harv_cache.v \
-control_lib/ram_loader.v \
-control_lib/setting_reg.v \
-control_lib/settings_bus.v \
-control_lib/shortfifo.v \
-control_lib/medfifo.v \
-control_lib/srl.v \
-control_lib/system_control.v \
-control_lib/wb_1master.v \
-control_lib/wb_readback_mux.v \
-control_lib/simple_uart.v \
-control_lib/simple_uart_tx.v \
-control_lib/simple_uart_rx.v \
-control_lib/oneshot_2clk.v \
-control_lib/sd_spi.v \
-control_lib/sd_spi_wb.v \
-control_lib/wb_bridge_16_32.v \
-coregen/fifo_xlnx_2Kx36_2clk.v \
-coregen/fifo_xlnx_2Kx36_2clk.xco \
-coregen/fifo_xlnx_512x36_2clk.v \
-coregen/fifo_xlnx_512x36_2clk.xco \
-eth/mac_rxfifo_int.v \
-eth/mac_txfifo_int.v \
-eth/rtl/verilog/Clk_ctrl.v \
-eth/rtl/verilog/MAC_rx.v \
-eth/rtl/verilog/MAC_rx/Broadcast_filter.v \
-eth/rtl/verilog/MAC_rx/CRC_chk.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_FF.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v \
-eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v \
-eth/rtl/verilog/MAC_top.v \
-eth/rtl/verilog/MAC_tx.v \
-eth/rtl/verilog/MAC_tx/CRC_gen.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_FF.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v \
-eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v \
-eth/rtl/verilog/MAC_tx/Random_gen.v \
-eth/rtl/verilog/Phy_int.v \
-eth/rtl/verilog/RMON.v \
-eth/rtl/verilog/RMON/RMON_addr_gen.v \
-eth/rtl/verilog/RMON/RMON_ctrl.v \
-eth/rtl/verilog/Reg_int.v \
-eth/rtl/verilog/eth_miim.v \
-eth/rtl/verilog/flow_ctrl_rx.v \
-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 \
-opencores/8b10b/decode_8b10b.v \
-opencores/8b10b/encode_8b10b.v \
-opencores/aemb/rtl/verilog/aeMB_bpcu.v \
-opencores/aemb/rtl/verilog/aeMB_core_BE.v \
-opencores/aemb/rtl/verilog/aeMB_ctrl.v \
-opencores/aemb/rtl/verilog/aeMB_edk32.v \
-opencores/aemb/rtl/verilog/aeMB_ibuf.v \
-opencores/aemb/rtl/verilog/aeMB_regf.v \
-opencores/aemb/rtl/verilog/aeMB_xecu.v \
-opencores/i2c/rtl/verilog/i2c_master_bit_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_byte_ctrl.v \
-opencores/i2c/rtl/verilog/i2c_master_defines.v \
-opencores/i2c/rtl/verilog/i2c_master_top.v \
-opencores/i2c/rtl/verilog/timescale.v \
-opencores/simple_pic/rtl/simple_pic.v \
-opencores/spi/rtl/verilog/spi_clgen.v \
-opencores/spi/rtl/verilog/spi_defines.v \
-opencores/spi/rtl/verilog/spi_shift.v \
-opencores/spi/rtl/verilog/spi_top.v \
-opencores/spi/rtl/verilog/timescale.v \
-sdr_lib/acc.v \
-sdr_lib/add2.v \
-sdr_lib/add2_and_round.v \
-sdr_lib/add2_and_round_reg.v \
-sdr_lib/add2_reg.v \
-sdr_lib/cic_dec_shifter.v \
-sdr_lib/cic_decim.v \
-sdr_lib/cic_int_shifter.v \
-sdr_lib/cic_interp.v \
-sdr_lib/cic_strober.v \
-sdr_lib/clip.v \
-sdr_lib/clip_reg.v \
-sdr_lib/cordic.v \
-sdr_lib/cordic_z24.v \
-sdr_lib/cordic_stage.v \
-sdr_lib/dsp_core_tx.v \
-sdr_lib/hb_dec.v \
-sdr_lib/hb_interp.v \
-sdr_lib/integrate.v \
-sdr_lib/round.v \
-sdr_lib/round_reg.v \
-sdr_lib/rx_control.v \
-sdr_lib/rx_dcoffset.v \
-sdr_lib/sign_extend.v \
-sdr_lib/small_hb_dec.v \
-sdr_lib/small_hb_int.v \
-sdr_lib/tx_control.v \
-serdes/serdes.v \
-serdes/serdes_fc_rx.v \
-serdes/serdes_fc_tx.v \
-serdes/serdes_rx.v \
-serdes/serdes_tx.v \
-timing/time_receiver.v \
-timing/time_sender.v \
-timing/time_sync.v \
-timing/timer.v \
-top/u2_core/u2_core.v \
-top/u2_rev3/u2_rev3.ucf \
-top/u2_rev3/u2_rev3.v \
-top/u2_rev3_iad/dsp_core_rx.v
-
-##################################################
-# Process Properties
-##################################################
-export SYNTHESIZE_PROPERTIES := \
-"Number of Clock Buffers" 6 \
-"Pack I/O Registers into IOBs" Yes \
-"Optimization Effort" High \
-"Optimize Instantiated Primitives" TRUE \
-"Register Balancing" Yes \
-"Use Clock Enable" Auto \
-"Use Synchronous Reset" Auto \
-"Use Synchronous Set" Auto
-
-export TRANSLATE_PROPERTIES := \
-"Macro Search Path" "$(shell pwd)/../../coregen/"
-
-export MAP_PROPERTIES := \
-"Allow Logic Optimization Across Hierarchy" TRUE \
-"Map to Input Functions" 4 \
-"Optimization Strategy (Cover Mode)" Speed \
-"Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" \
-"Perform Timing-Driven Packing and Placement" TRUE \
-"Map Effort Level" High \
-"Extra Effort" Normal \
-"Combinatorial Logic Optimization" TRUE \
-"Register Duplication" TRUE
-
-export PLACE_ROUTE_PROPERTIES := \
-"Place & Route Effort Level (Overall)" High
-
-export STATIC_TIMING_PROPERTIES := \
-"Number of Paths in Error/Verbose Report" 10 \
-"Report Type" "Error Report"
-
-export GEN_PROG_FILE_PROPERTIES := \
-"Configuration Rate" 6 \
-"Create Binary Configuration File" TRUE \
-"Done (Output Events)" 5 \
-"Enable Bitstream Compression" TRUE \
-"Enable Outputs (Output Events)" 6
-
-export SIM_MODEL_PROPERTIES := ""
-
-##################################################
-# Make Options
-##################################################
-all:
- @echo make proj, check, synth, bin, testbench, or clean
-
-proj:
- PROCESS_RUN="" $(XTCLSH) $(ISE_HELPER)
-
-check:
- PROCESS_RUN="Check Syntax" $(XTCLSH) $(ISE_HELPER)
-
-synth:
- PROCESS_RUN="Synthesize - XST" $(XTCLSH) $(ISE_HELPER)
-
-bin:
- PROCESS_RUN="Generate Programming File" $(XTCLSH) $(ISE_HELPER)
-
-testbench:
- iverilog -c cmdfile -o dsp_core_tb dsp_core_tb.v
-
-clean:
- rm -rf $(BUILD_DIR)
- rm -f dsp_core_tb
- rm -f *.lx2
- rm -f *.dat
- rm -f *.vcd
diff --git a/fpga/usrp2/top/u2_rev3_iad/cmdfile b/fpga/usrp2/top/u2_rev3_iad/cmdfile
deleted file mode 100644
index 34373a676..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/cmdfile
+++ /dev/null
@@ -1,4 +0,0 @@
--y .
--y ../../sdr_lib
--y ../../control_lib
--y ../../models
diff --git a/fpga/usrp2/top/u2_rev3_iad/dsp_core_rx.v b/fpga/usrp2/top/u2_rev3_iad/dsp_core_rx.v
deleted file mode 100644
index 2882464ba..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/dsp_core_rx.v
+++ /dev/null
@@ -1,158 +0,0 @@
-`define DSP_CORE_RX_BASE 160
-module dsp_core_rx
- (input clk, input rst,
- input set_stb, input [7:0] set_addr, input [31:0] set_data,
-
- input [13:0] adc_a, input adc_ovf_a,
- input [13:0] adc_b, input adc_ovf_b,
-
- input [15:0] io_rx,
-
- output [31:0] sample,
- input run,
- output strobe,
- output [31:0] debug
- );
-
- wire [15:0] scale_i, scale_q;
- wire [13:0] adc_a_ofs, adc_b_ofs;
- reg [13:0] adc_i, adc_q;
- wire [31:0] phase_inc;
- reg [31:0] phase;
-
- wire [35:0] prod_i, prod_q;
- wire [23:0] i_cordic, q_cordic;
- wire [31:0] i_iad, q_iad;
- wire [15:0] i_out, q_out;
-
- wire enable_hb1, enable_hb2; // Correspond to std firmware settings
- wire [7:0] cic_decim; // for combined CIC/HB decimator
- wire [9:0] decim_rate; // Reconstructed original decimation setting
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+0)) sr_0
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(phase_inc),.changed());
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+1)) sr_1
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out({scale_i,scale_q}),.changed());
-
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+2)) sr_2
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out({enable_hb1,enable_hb2,cic_decim}),.changed());
-
- rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+6)) rx_dcoffset_a
- (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_in(adc_a),.adc_out(adc_a_ofs));
-
- rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+7)) rx_dcoffset_b
- (.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_in(adc_b),.adc_out(adc_b_ofs));
-
- wire [3:0] muxctrl;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+8)) sr_8
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(muxctrl),.changed());
-
- wire [1:0] gpio_ena;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+9)) sr_9
- (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(gpio_ena),.changed());
-
- // The TVRX connects to what is called adc_b, thus A and B are
- // swapped throughout the design.
- //
- // In the interest of expediency and keeping the s/w sane, we just remap them here.
- // The I & Q fields are mapped the same:
- // 0 -> "the real A" (as determined by the TVRX)
- // 1 -> "the real B"
- // 2 -> const zero
-
- always @(posedge clk)
- case(muxctrl[1:0]) // The I mapping
- 0: adc_i <= adc_b_ofs; // "the real A"
- 1: adc_i <= adc_a_ofs;
- 2: adc_i <= 0;
- default: adc_i <= 0;
- endcase // case(muxctrl[1:0])
-
- always @(posedge clk)
- case(muxctrl[3:2]) // The Q mapping
- 0: adc_q <= adc_b_ofs; // "the real A"
- 1: adc_q <= adc_a_ofs;
- 2: adc_q <= 0;
- default: adc_q <= 0;
- endcase // case(muxctrl[3:2])
-
- always @(posedge clk)
- if(rst)
- phase <= 0;
- else if(~run)
- phase <= 0;
- else
- phase <= phase + phase_inc;
-
- MULT18X18S mult_i
- (.P(prod_i), // 36-bit multiplier output
- .A({{4{adc_i[13]}},adc_i} ), // 18-bit multiplier input
- .B({{2{scale_i[15]}},scale_i}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
- MULT18X18S mult_q
- (.P(prod_q), // 36-bit multiplier output
- .A({{4{adc_q[13]}},adc_q} ), // 18-bit multiplier input
- .B({{2{scale_q[15]}},scale_q}), // 18-bit multiplier input
- .C(clk), // Clock input
- .CE(1), // Clock enable input
- .R(rst) // Synchronous reset input
- );
-
-
- cordic_z24 #(.bitwidth(24))
- cordic(.clock(clk), .reset(rst), .enable(run),
- .xi(prod_i[24:1]),. yi(prod_q[24:1]), .zi(phase[31:8]),
- .xo(i_cordic),.yo(q_cordic),.zo() );
-
- // Reconstruct original decimation rate from standard firmware settings
- assign decim_rate = enable_hb2 ? (enable_hb1 ? {cic_decim,2'b0} :
- {1'b0,cic_decim,1'b0 }) :
- cic_decim;
-
- cic_strober #(.WIDTH(10)) // Convenient reuse of strobe generator
- cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(decim_rate),
- .strobe_fast(1),.strobe_slow(strobe_iad) );
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_i
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(i_cordic),
- .stb_o(strobe),.integ_o(i_iad) );
-
- integrate #(.INPUTW(24),.ACCUMW(32),.OUTPUTW(32)) integrator_q
- (.clk_i(clk),.rst_i(rst),.ena_i(run),
- .dump_i(strobe_iad),.data_i(q_cordic),
- .stb_o(),.integ_o(q_iad) );
-
- round #(.bits_in(32),.bits_out(16)) round_iout (.in(i_iad),.out(i_out));
- round #(.bits_in(32),.bits_out(16)) round_qout (.in(q_iad),.out(q_out));
-
- // Streaming GPIO
- //
- // io_rx[15] => I channel LSB if gpio_ena[0] high
- // io_rx[14] => Q channel LSB if gpio_ena[1] high
-
- reg [31:0] sample_reg;
- always @(posedge clk)
- begin
- sample_reg[31:17] <= i_out[15:1];
- sample_reg[15:1] <= q_out[15:1];
- sample_reg[16] <= gpio_ena[0] ? io_rx[15] : i_out[0];
- sample_reg[0] <= gpio_ena[1] ? io_rx[14] : q_out[0];
- end
-
- assign sample = sample_reg;
- assign debug = {clk, rst, run, strobe};
-
-endmodule // dsp_core_rx
diff --git a/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.sav b/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.sav
deleted file mode 100644
index 17c90cdd7..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.sav
+++ /dev/null
@@ -1,61 +0,0 @@
-[size] 1680 975
-[pos] -1 -1
-*-24.007835 13660000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-[treeopen] dsp_core_tb.
-@200
--SYSCON
-@28
-dsp_core_tb.clk
-dsp_core_tb.rst
-dsp_core_tb.run
-@200
--
--Settings Bus
-@22
-dsp_core_tb.set_addr[7:0]
-@24
-dsp_core_tb.set_data[31:0]
-@28
-dsp_core_tb.set_stb
-@200
--
--RX DSP CORE
--
-@24
-dsp_core_tb.rx_path.decim_rate[9:0]
-@200
--
-@8420
-dsp_core_tb.adc_a[13:0]
-@20000
--
-@200
--
-@8420
-dsp_core_tb.rx_path.adc_a_ofs[13:0]
-@20000
--
-@200
--
-@8022
-dsp_core_tb.rx_path.i_cordic[23:0]
-@20000
--
-@200
--
-@8022
-dsp_core_tb.rx_path.i_iad[31:0]
-@20000
--
-@200
--
-@8420
-dsp_core_tb.rx_path.i_out[15:0]
-@20000
--
-@200
--
-@28
-dsp_core_tb.stb
-@200
--
diff --git a/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.v b/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.v
deleted file mode 100644
index 4d5a5b537..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/dsp_core_tb.v
+++ /dev/null
@@ -1,196 +0,0 @@
-`timescale 1ns / 100ps
-
-module dsp_core_tb;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Sim-wide wires/busses //
-///////////////////////////////////////////////////////////////////////////////////
-
- // System control bus
- reg clk = 0;
- reg rst = 1;
-
- // Configuration bus
- reg set_stb = 0;
- reg [7:0] set_addr = 0;
- reg [31:0] set_data = 0;
-
- // ADC input bus
- wire signed [13:0] adc_a;
- wire signed [13:0] adc_b;
- wire adc_ovf_a;
- wire adc_ovf_b;
-
- // RX sample bus
- reg run = 1;
- wire [31:0] sample;
- wire stb;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Simulation control //
-///////////////////////////////////////////////////////////////////////////////////
-
- // Set up output files
- initial begin
- $dumpfile("dsp_core_tb.vcd");
- $dumpvars(0,dsp_core_tb);
- end
-
- // Update display every 10 us
- always #1000 $monitor("Time in us ",$time/1000);
-
- // Generate master clock 50% @ 100 MHz
- always
- #5 clk = ~clk;
-
-///////////////////////////////////////////////////////////////////////////////////
-// Unit(s) under test //
-///////////////////////////////////////////////////////////////////////////////////
-
- reg [13:0] amplitude = 13'h1fff;
- reg [15:0] impulse_len = 0;
- reg [15:0] zero_len = 0;
- reg adc_ena = 0;
-
- initial #500 @(posedge clk) adc_ena = 1;
-
- impulse adc
- (.clk(clk),.rst(rst),.ena(adc_ena),
- .dc_offset_a(0),.dc_offset_b(0),
- .amplitude(amplitude),
- .impulse_len(impulse_len),.zero_len(zero_len),
- .adc_a(adc_a),.adc_b(adc_b),
- .adc_ovf_a(adc_ovf_a),.adc_ovf_b(adc_ovf_b) );
-
- initial rx_path.rx_dcoffset_a.integrator = 0; // so sim doesn't propagate X's
- initial rx_path.rx_dcoffset_b.integrator = 0; // generated before reset
- dsp_core_rx rx_path
- (.clk(clk),.rst(rst),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),
- .adc_b(adc_b),.adc_ovf_b(adc_ovf_b),
- .io_rx(16'b0),
- .run(adc_ena),.sample(sample),.strobe(stb),
- .debug() );
-
-///////////////////////////////////////////////////////////////////////////////////
-// Simulation output/checking //
-///////////////////////////////////////////////////////////////////////////////////
-
- integer rx_file;
-
- initial
- rx_file = $fopen("rx.dat", "wb");
-
- always @(posedge clk)
- begin
- // Write RX sample I&Q in format Octave can load
- if (stb)
- begin
- $fwrite(rx_file, sample[31:16]);
- $fputc(32, rx_file);
- $fwrite(rx_file, sample[15:0]);
- $fputc(13, rx_file);
- end
- end
-
-///////////////////////////////////////////////////////////////////////////////////
-// Tasks //
-///////////////////////////////////////////////////////////////////////////////////
-
- task power_on;
- begin
- @(posedge clk)
- rst = #1 1'b1;
- @(posedge clk)
- rst = #1 1'b0;
- end
- endtask // power_on
-
- task set_impulse_len;
- input [15:0] len;
- @(posedge clk) impulse_len = len-1;
- endtask
-
- task set_zero_len;
- input [15:0] len;
- @(posedge clk) zero_len = len-1;
- endtask
-
- // Strobe configuration bus with addr, data
- task write_cfg_register;
- input [7:0] regno;
- input [31:0] value;
-
- begin
- @(posedge clk);
- set_addr <= regno;
- set_data <= value;
- set_stb <= 1'b1;
- @(posedge clk);
- set_stb <= 1'b0;
- end
- endtask // write_cfg_register
-
- // Set RX DDC frequency
- task set_ddc_freq;
- input [31:0] freq;
-
- write_cfg_register(160, freq);
- endtask // set_ddc_freq
-
- // Set RX IQ scaling registers
- task set_rx_scale_iq;
- input [15:0] scale_i;
- input [15:0] scale_q;
-
- write_cfg_register(161, {scale_i,scale_q});
- endtask // set_rx_scale_iq
-
- // Set RX MUX control
- task set_rx_muxctrl;
- input [3:0] muxctrl;
-
- write_cfg_register(168, muxctrl);
- endtask // set_rx_muxctrl
-
- // Set RX CIC decim and halfband enables
- task set_decim;
- input hb1_ena;
- input hb2_ena;
- input [7:0] decim;
-
- write_cfg_register(162, {hb1_ena,hb2_ena,decim});
- endtask // set_decim
-
-
-///////////////////////////////////////////////////////////////////////////////////
-// Individual tests //
-///////////////////////////////////////////////////////////////////////////////////
-
- task test_rx;
- begin
- set_impulse_len(1);
- set_zero_len(999);
- set_rx_muxctrl(1);
- set_ddc_freq(0);
- set_rx_scale_iq(1243, 1243);
- set_decim(0, 1, 3);
-
- #100000 $finish;
- end
- endtask // test_rx
-
-
-///////////////////////////////////////////////////////////////////////////////////
-// Top-level test //
-///////////////////////////////////////////////////////////////////////////////////
-
- // Execute tests
- initial
- begin
- power_on();
- test_rx();
- end
-
-endmodule // dsp_core_tb
diff --git a/fpga/usrp2/top/u2_rev3_iad/impulse.v b/fpga/usrp2/top/u2_rev3_iad/impulse.v
deleted file mode 100644
index 7f0cdc9be..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/impulse.v
+++ /dev/null
@@ -1,63 +0,0 @@
-module impulse
- (input clk,
- input rst,
- input ena,
-
- input [13:0] dc_offset_a,
- input [13:0] dc_offset_b,
- input [13:0] amplitude,
- input [15:0] impulse_len,
- input [15:0] zero_len,
-
- output [13:0] adc_a,
- output [13:0] adc_b,
- output adc_ovf_a,
- output adc_ovf_b
- );
-
- reg [13:0] adc_a_int = 0;
- reg [15:0] count;
-
- localparam ST_ZERO = 0;
- localparam ST_HIGH = 1;
- reg state;
-
- always @(posedge clk)
- if (rst | ~ena)
- begin
- adc_a_int <= 0;
- count <= 0;
- state <= ST_ZERO;
- end
- else
- case(state)
- ST_ZERO:
- if (count == zero_len)
- begin
- adc_a_int <= amplitude;
- state <= ST_HIGH;
- count <= 0;
- end
- else
- count <= count + 1;
-
- ST_HIGH:
- if (count == impulse_len)
- begin
- adc_a_int <= 0;
- state <= ST_ZERO;
- count <= 0;
- end
- else
- count <= count + 1;
-
- endcase // case (state)
-
- assign adc_a = adc_a_int + dc_offset_a;
-
- // Ignore for now
- assign adc_b = dc_offset_b;
- assign adc_ovf_a = 0;
- assign adc_ovf_b = 0;
-
-endmodule // impulse
diff --git a/fpga/usrp2/top/u2_rev3_iad/wave.sh b/fpga/usrp2/top/u2_rev3_iad/wave.sh
deleted file mode 100755
index 626f224e5..000000000
--- a/fpga/usrp2/top/u2_rev3_iad/wave.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-gtkwave dsp_core_tb.vcd dsp_core_tb.sav &
diff --git a/fpga/usrp2/top/u2plus/capture_ddrlvds.v b/fpga/usrp2/top/u2plus/capture_ddrlvds.v
deleted file mode 100644
index b9f53ff8c..000000000
--- a/fpga/usrp2/top/u2plus/capture_ddrlvds.v
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-module capture_ddrlvds
- #(parameter WIDTH=7)
- (input clk,
- input ssclk_p,
- input ssclk_n,
- input [WIDTH-1:0] in_p,
- input [WIDTH-1:0] in_n,
- output reg [(2*WIDTH)-1:0] out);
-
- wire [WIDTH-1:0] ddr_dat;
- wire ssclk_regional;
- wire ssclk_io;
- wire ssclk;
- wire [(2*WIDTH)-1:0] out_pre1;
- reg [(2*WIDTH)-1:0] out_pre2;
-
- IBUFGDS #(.IOSTANDARD("LVDS_25"),.DIFF_TERM("TRUE")) clkbuf (.O(ssclk), .I(ssclk_p), .IB(ssclk_n));
-
- genvar i;
- generate
- for(i = 0; i < WIDTH; i = i + 1)
- begin : gen_lvds_pins
- IBUFDS #(.IOSTANDARD("LVDS_25"),.DIFF_TERM("TRUE")) ibufds
- (.O(ddr_dat[i]), .I(in_p[i]), .IB(in_n[i]) );
- IDDR2 #(.DDR_ALIGNMENT("C1")) iddr2
- (.Q0(out_pre1[2*i]), .Q1(out_pre1[(2*i)+1]), .C0(ssclk), .C1(~ssclk),
- .CE(1'b1), .D(ddr_dat[i]), .R(1'b0), .S(1'b0));
- end
- endgenerate
-
- always @(negedge clk)
- out_pre2 <= out_pre1;
-
- always @(posedge clk)
- out <= out_pre2;
-
-endmodule // capture_ddrlvds
diff --git a/fpga/usrp2/udp/add_onescomp.v b/fpga/usrp2/udp/add_onescomp.v
index 048842a86..e02604114 100644
--- a/fpga/usrp2/udp/add_onescomp.v
+++ b/fpga/usrp2/udp/add_onescomp.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module add_onescomp
diff --git a/fpga/usrp2/udp/fifo19_rxrealign.v b/fpga/usrp2/udp/fifo19_rxrealign.v
index 35ad90951..da5fd20af 100644
--- a/fpga/usrp2/udp/fifo19_rxrealign.v
+++ b/fpga/usrp2/udp/fifo19_rxrealign.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
// Adds a junk line at the beginning of every packet, which the
diff --git a/fpga/usrp2/udp/prot_eng_rx.v b/fpga/usrp2/udp/prot_eng_rx.v
index 5df158b2b..ccb59b7ff 100644
--- a/fpga/usrp2/udp/prot_eng_rx.v
+++ b/fpga/usrp2/udp/prot_eng_rx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
diff --git a/fpga/usrp2/udp/prot_eng_tx.v b/fpga/usrp2/udp/prot_eng_tx.v
index b4f6e55b8..40abf3c04 100644
--- a/fpga/usrp2/udp/prot_eng_tx.v
+++ b/fpga/usrp2/udp/prot_eng_tx.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module prot_eng_tx
#(parameter BASE=0)
diff --git a/fpga/usrp2/udp/prot_eng_tx_tb.v b/fpga/usrp2/udp/prot_eng_tx_tb.v
index 138794e57..866093ef5 100644
--- a/fpga/usrp2/udp/prot_eng_tx_tb.v
+++ b/fpga/usrp2/udp/prot_eng_tx_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module prot_eng_tx_tb();
localparam BASE = 128;
diff --git a/fpga/usrp2/udp/udp_wrapper.v b/fpga/usrp2/udp/udp_wrapper.v
index f4c642615..20bcb477b 100644
--- a/fpga/usrp2/udp/udp_wrapper.v
+++ b/fpga/usrp2/udp/udp_wrapper.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module udp_wrapper
#(parameter BASE=0)
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs
index 4851bc924..166ed44ef 100644
--- a/fpga/usrp2/vrt/Makefile.srcs
+++ b/fpga/usrp2/vrt/Makefile.srcs
@@ -14,4 +14,5 @@ vita_tx_deframer.v \
vita_tx_chain.v \
gen_context_pkt.v \
trigger_context_pkt.v \
+vita_pkt_gen.v \
))
diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v
index cc34cceed..bdfca8237 100644
--- a/fpga/usrp2/vrt/gen_context_pkt.v
+++ b/fpga/usrp2/vrt/gen_context_pkt.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module gen_context_pkt
diff --git a/fpga/usrp2/vrt/trigger_context_pkt.v b/fpga/usrp2/vrt/trigger_context_pkt.v
index 1d456814b..3d9c2e5c6 100644
--- a/fpga/usrp2/vrt/trigger_context_pkt.v
+++ b/fpga/usrp2/vrt/trigger_context_pkt.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module trigger_context_pkt
diff --git a/fpga/usrp2/vrt/vita_pkt_gen.v b/fpga/usrp2/vrt/vita_pkt_gen.v
new file mode 100644
index 000000000..b962254a6
--- /dev/null
+++ b/fpga/usrp2/vrt/vita_pkt_gen.v
@@ -0,0 +1,59 @@
+//
+// 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/>.
+//
+
+
+
+module vita_pkt_gen
+ (input clk, input reset, input clear,
+ input [15:0] len,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ reg [15:0] state;
+ reg [31:0] seq, data;
+
+ wire sof = (state == 0);
+ wire eof = (state == (len-1));
+ wire consume = src_rdy_o & dst_rdy_i;
+
+ assign src_rdy_o = 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ state <= 0;
+ seq <= 0;
+ end
+ else
+ if(consume)
+ if(eof)
+ begin
+ state <= 0;
+ seq <= seq + 1;
+ end
+ else
+ state <= state + 1;
+
+ always @*
+ case(state)
+ 0 : data <= {24'h000,seq[3:0],len};
+ 1 : data <= seq;
+ default : data <= {~state,state};
+ endcase // case (state)
+
+ assign data_o = {2'b00, eof, sof, data};
+
+endmodule // vita_pkt_gen
diff --git a/fpga/usrp2/vrt/vita_rx_chain.v b/fpga/usrp2/vrt/vita_rx_chain.v
index 28955d108..1986743b3 100644
--- a/fpga/usrp2/vrt/vita_rx_chain.v
+++ b/fpga/usrp2/vrt/vita_rx_chain.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_rx_chain
#(parameter BASE=0,
diff --git a/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v
index 4c0cef50d..39f32d7fe 100644
--- a/fpga/usrp2/vrt/vita_rx_control.v
+++ b/fpga/usrp2/vrt/vita_rx_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_rx_control
#(parameter BASE=0,
diff --git a/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v
index 04b636778..bd09315bc 100644
--- a/fpga/usrp2/vrt/vita_rx_framer.v
+++ b/fpga/usrp2/vrt/vita_rx_framer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_rx_framer
#(parameter BASE=0,
diff --git a/fpga/usrp2/vrt/vita_rx_tb.v b/fpga/usrp2/vrt/vita_rx_tb.v
index 023934f39..8cd08a972 100644
--- a/fpga/usrp2/vrt/vita_rx_tb.v
+++ b/fpga/usrp2/vrt/vita_rx_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_rx_tb;
diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v
index fa84d7a2f..542968afa 100644
--- a/fpga/usrp2/vrt/vita_tx_chain.v
+++ b/fpga/usrp2/vrt/vita_tx_chain.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_tx_chain
#(parameter BASE_CTRL=0,
diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v
index 14b97a215..5df89bdbe 100644
--- a/fpga/usrp2/vrt/vita_tx_control.v
+++ b/fpga/usrp2/vrt/vita_tx_control.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_tx_control
#(parameter BASE=0,
diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v
index 163c2af20..06ca27767 100644
--- a/fpga/usrp2/vrt/vita_tx_deframer.v
+++ b/fpga/usrp2/vrt/vita_tx_deframer.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_tx_deframer
#(parameter BASE=0,
diff --git a/fpga/usrp2/vrt/vita_tx_tb.v b/fpga/usrp2/vrt/vita_tx_tb.v
index a118ffd4e..b686a8a16 100644
--- a/fpga/usrp2/vrt/vita_tx_tb.v
+++ b/fpga/usrp2/vrt/vita_tx_tb.v
@@ -1,3 +1,20 @@
+//
+// 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/>.
+//
+
module vita_tx_tb;
diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt
index 5926e062e..88afb9c98 100644
--- a/host/docs/CMakeLists.txt
+++ b/host/docs/CMakeLists.txt
@@ -30,6 +30,7 @@ SET(manual_sources
transport.rst
usrp1.rst
usrp2.rst
+ usrp_b1xx.rst
usrp_e1xx.rst
)
diff --git a/host/docs/general.rst b/host/docs/general.rst
index ff85fb0f9..cc00fc0f9 100644
--- a/host/docs/general.rst
+++ b/host/docs/general.rst
@@ -61,6 +61,42 @@ Pseudo-code for dealing with settling time after tuning on receive:
usrp->issue_stream_command(...);
------------------------------------------------------------------------
+Overflow/Underflow notes
+------------------------------------------------------------------------
+**Note:** The following overflow/underflow notes do not apply to USRP1,
+which does not support the advanced features available in newer products.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Overflow notes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+When receiving, the device produces samples at a constant rate.
+Overflows occurs when the host does not consume data fast enough.
+When UHD detects the overflow, it prints an "O" to stdout,
+and pushes an inline message packet into the receive stream.
+
+**Network-based devices**:
+The host does not back-pressure the receive stream.
+When the kernel's socket buffer becomes full, it will drop subsequent packets.
+UHD detects the overflow as a discontinuity in the packet's sequence numbers,
+and muxes an inline message packet into the receive stream.
+
+**Other devices**:
+The host back-pressures the receive stream.
+Therefore, overflows always occur in the device itself.
+When the device's internal buffers become full, streaming is shutoff,
+and an inline message packet is sent to the host.
+If the device was in continuous streaming mode,
+the UHD will automatically restart streaming.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Underflow notes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+When transmitting, the device consumes samples at a constant rate.
+Underflow occurs when the host does not produce data fast enough.
+When the UHD detects underflow, it prints an "U" to stdout,
+and pushes a message packet into the async message stream.
+
+------------------------------------------------------------------------
Threading notes
------------------------------------------------------------------------
@@ -114,3 +150,21 @@ For a module to be loaded at runtime, it must be:
* found in the UHD_MODULE_PATH environment variable,
* installed into the <install-path>/share/uhd/modules directory,
* or installed into /usr/share/uhd/modules directory (unix only).
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Disabling or redirecting prints to stdout
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The user can disable the UHD library from printing directly to stdout by registering a custom message handler.
+The handler will intercept all messages, which can be dropped or redirected.
+Only one handler can be registered at a time.
+Make "register_handler" your first call into UHD:
+
+::
+
+ #include <uhd/utils/msg.hpp>
+
+ void my_handler(uhd::msg::type_t type, const std::string &msg){
+ //handle the message...
+ }
+
+ uhd::msg::register_handler(&my_handler);
diff --git a/host/docs/index.rst b/host/docs/index.rst
index 40fe64599..b4ebdad6c 100644
--- a/host/docs/index.rst
+++ b/host/docs/index.rst
@@ -24,6 +24,7 @@ Application Notes
* `USRP1 Application Notes <./usrp1.html>`_
* `USRP2 Application Notes <./usrp2.html>`_
* `USRP-N2XX Series Application Notes <./usrp2.html>`_
+* `USRP-B1XX Series Application Notes <./usrp_b1xx.html>`_
* `USRP-E1XX Series Application Notes <./usrp_e1xx.html>`_
* `Daughterboard Application Notes <./dboards.html>`_
* `Transport Application Notes <./transport.html>`_
diff --git a/host/docs/usrp_b1xx.rst b/host/docs/usrp_b1xx.rst
new file mode 100644
index 000000000..2f7385070
--- /dev/null
+++ b/host/docs/usrp_b1xx.rst
@@ -0,0 +1,76 @@
+========================================================================
+UHD - USRP-B1XX Series Application Notes
+========================================================================
+
+.. contents:: Table of Contents
+
+------------------------------------------------------------------------
+Specify a non-standard image
+------------------------------------------------------------------------
+The UHD will automatically select the USRP B-Series images from the installed images package.
+The image selection can be overridden with the "fpga" and "fw" device address parameters.
+
+Example device address string representations to specify non-standard images:
+
+::
+
+ fpga=usrp_b100_fpga_firmware.bin
+
+ -- OR --
+
+ fw=usrp_b100_fw_firmware.ihx
+
+------------------------------------------------------------------------
+Changing the master clock rate
+------------------------------------------------------------------------
+The master clock rate of the USRP embedded feeds both the FPGA DSP and the codec chip.
+Hundreds of rates between 32MHz and 64MHz are available.
+A few notable rates are:
+
+* 64MHz - maximum rate of the codec chip
+* 61.44MHz - good for UMTS/WCDMA applications
+* 52Mhz - good for GSM applications
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Set 61.44MHz - uses external VCXO
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+To use the 61.44MHz clock rate, the USRP embedded will require two jumpers to be moved.
+
+* J16 is a two pin header, remove the jumper (or leave it on pin1 only)
+* J15 is a three pin header, move the jumper to (pin1, pin2)
+
+**Note:** See instructions below to communicate the desired clock rate into the UHD.
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Set other rates - uses internal VCO
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+To use other clock rates, the jumpers will need to be in the default position.
+
+* J16 is a two pin header, move the jumper to (pin1, pin2)
+* J15 is a three pin header, move the jumper to (pin2, pin3)
+
+To communicate the desired clock rate into the UHD,
+specify the a special device address argument,
+where the key is "master_clock_rate" and the value is a rate in Hz.
+Example:
+::
+
+ uhd_usrp_probe --args="master_clock_rate=52e6"
+
+------------------------------------------------------------------------
+OS specific notes
+------------------------------------------------------------------------
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Linux - setup udev
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+On Linux, udev handles USB plug and unplug events.
+The following commands create a udev rule for the B100
+so that non-root users may access the device:
+
+::
+
+ echo 'ACTION=="add", BUS=="usb", SYSFS{idVendor}=="2500", SYSFS{idProduct}=="0001", MODE:="0666"' > tmpfile
+ sudo chown root.root tmpfile
+ sudo mv tmpfile /etc/udev/rules.d/10-usrp_b100.rules
+ sudo udevadm control --reload-rules
diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp
index 8fc2f38db..99f1860ae 100644
--- a/host/include/uhd/convert.hpp
+++ b/host/include/uhd/convert.hpp
@@ -29,7 +29,7 @@ namespace uhd{ namespace convert{
typedef uhd::ref_vector<void *> output_type;
typedef uhd::ref_vector<const void *> input_type;
- typedef boost::function<void(const input_type&, const output_type&, size_t)> function_type;
+ typedef boost::function<void(const input_type&, const output_type&, size_t, double)> function_type;
/*!
* Describe the priority of a converter function.
diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp
index b39171fba..dc344ad8b 100644
--- a/host/include/uhd/transport/usb_zero_copy.hpp
+++ b/host/include/uhd/transport/usb_zero_copy.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
@@ -49,6 +49,7 @@ public:
* \param recv_endpoint an integer specifiying an IN endpoint number
* \param send_endpoint an integer specifiying an OUT endpoint number
* \param hints optional parameters to pass to the underlying transport
+ * \return a new zero copy usb object
*/
static sptr make(
usb_device_handle::sptr handle,
@@ -56,6 +57,24 @@ public:
size_t send_endpoint,
const device_addr_t &hints = device_addr_t()
);
+
+ /*!
+ * Make a wrapper around a zero copy implementation.
+ * The wrapper performs the following functions:
+ * - Pad commits to the frame boundary
+ * - Extract multiple packets on recv
+ *
+ * When enable multiple receive packets is set to true,
+ * the implementation inspects the vita length on transfers,
+ * and may split a single transfer into multiple managed buffers.
+ *
+ * \param usb_zc a usb zero copy interface object
+ * \param usb_frame_boundary bytes per frame
+ * \return a new zero copy wrapper object
+ */
+ static sptr make_wrapper(
+ sptr usb_zc, size_t usb_frame_boundary = 512
+ );
};
}} //namespace
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt
index d189aa687..5f05b0cb8 100644
--- a/host/lib/convert/CMakeLists.txt
+++ b/host/lib/convert/CMakeLists.txt
@@ -26,6 +26,7 @@ MESSAGE(STATUS "")
########################################################################
IF(CMAKE_COMPILER_IS_GNUCXX)
SET(EMMINTRIN_FLAGS -msse2)
+ SET(NEON_FLAGS "-mfloat-abi=softfp -mfpu=neon")
ELSEIF(MSVC)
SET(EMMINTRIN_FLAGS /arch:SSE2)
ENDIF()
@@ -47,12 +48,53 @@ ENDIF(HAVE_EMMINTRIN_H)
########################################################################
# Check for NEON SIMD headers
########################################################################
+SET(CMAKE_REQUIRED_FLAGS ${NEON_FLAGS})
CHECK_INCLUDE_FILE_CXX(arm_neon.h HAVE_ARM_NEON_H)
-IF(HAVE_ARM_NEON_H)
+UNSET(CMAKE_REQUIRED_FLAGS)
+if(HAVE_ARM_NEON_H)
+ MESSAGE(STATUS "Enabling NEON support")
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_neon.cpp
+ PROPERTIES COMPILE_FLAGS "${NEON_FLAGS}"
+ )
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/convert_with_neon.cpp
)
-ENDIF(HAVE_ARM_NEON_H)
+else(HAVE_ARM_NEON_H)
+ MESSAGE(STATUS "Disabling NEON support")
+endif(HAVE_ARM_NEON_H)
+########################################################################
+# Look for Orc support
+########################################################################
+FIND_PACKAGE(PkgConfig)
+IF(PKG_CONFIG_FOUND)
+PKG_CHECK_MODULES(ORC "orc-0.4")
+ENDIF(PKG_CONFIG_FOUND)
+
+FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+
+IF(ORC_FOUND AND ORCC_EXECUTABLE)
+ INCLUDE_DIRECTORIES(${ORC_INCLUDE_DIRS})
+ LINK_DIRECTORIES(${ORC_LIBRARY_DIRS})
+ ENABLE_LANGUAGE(C)
+
+ SET(orcc_src ${CMAKE_CURRENT_SOURCE_DIR}/convert_orc.orc)
+
+ GET_FILENAME_COMPONENT(orc_file_name_we ${orcc_src} NAME_WE)
+ SET(orcc_gen ${CMAKE_CURRENT_BINARY_DIR}/${orc_file_name_we}.c)
+ MESSAGE(STATUS "Orc found, enabling Orc support")
+ ADD_CUSTOM_COMMAND(
+ COMMAND ${ORCC_EXECUTABLE} --implementation -o ${orcc_gen} ${orcc_src}
+ DEPENDS ${orcc_src} OUTPUT ${orcc_gen}
+ )
+ LIBUHD_APPEND_SOURCES(${orcc_gen})
+ LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_orc.cpp
+ )
+ LIBUHD_APPEND_LIBS(${ORC_LIBRARIES})
+ELSE()
+ MESSAGE(STATUS "Orc not found, disabling orc support...")
+ENDIF(ORC_FOUND AND ORCC_EXECUTABLE)
########################################################################
# Convert types generation
diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp
index c2ca233d9..7f513b124 100644
--- a/host/lib/convert/convert_common.hpp
+++ b/host/lib/convert/convert_common.hpp
@@ -27,7 +27,7 @@
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps \
+ size_t nsamps, double scale_factor \
); \
UHD_STATIC_BLOCK(register_##fcn##_##prio){ \
uhd::convert::register_converter(#fcn, fcn, prio); \
@@ -35,7 +35,7 @@
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps \
+ size_t nsamps, double scale_factor \
)
/***********************************************************************
@@ -50,7 +50,7 @@ typedef boost::uint32_t item32_t;
/***********************************************************************
* Convert complex short buffer to items32
**********************************************************************/
-static UHD_INLINE item32_t sc16_to_item32(sc16_t num){
+static UHD_INLINE item32_t sc16_to_item32(sc16_t num, double){
boost::uint16_t real = num.real();
boost::uint16_t imag = num.imag();
return (item32_t(real) << 16) | (item32_t(imag) << 0);
@@ -59,7 +59,7 @@ static UHD_INLINE item32_t sc16_to_item32(sc16_t num){
/***********************************************************************
* Convert items32 buffer to complex short
**********************************************************************/
-static UHD_INLINE sc16_t item32_to_sc16(item32_t item){
+static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){
return sc16_t(
boost::int16_t(item >> 16),
boost::int16_t(item >> 0)
@@ -69,46 +69,38 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item){
/***********************************************************************
* Convert complex float buffer to items32 (no swap)
**********************************************************************/
-static const float shorts_per_float = float(32767);
-
-static UHD_INLINE item32_t fc32_to_item32(fc32_t num){
- boost::uint16_t real = boost::int16_t(num.real()*shorts_per_float);
- boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_float);
+static UHD_INLINE item32_t fc32_to_item32(fc32_t num, float scale_factor){
+ boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
+ boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
* Convert items32 buffer to complex float
**********************************************************************/
-static const float floats_per_short = float(1.0/shorts_per_float);
-
-static UHD_INLINE fc32_t item32_to_fc32(item32_t item){
+static UHD_INLINE fc32_t item32_to_fc32(item32_t item, float scale_factor){
return fc32_t(
- float(boost::int16_t(item >> 16)*floats_per_short),
- float(boost::int16_t(item >> 0)*floats_per_short)
+ float(boost::int16_t(item >> 16)*scale_factor),
+ float(boost::int16_t(item >> 0)*scale_factor)
);
}
/***********************************************************************
* Convert complex double buffer to items32 (no swap)
**********************************************************************/
-static const double shorts_per_double = double(32767);
-
-static UHD_INLINE item32_t fc64_to_item32(fc64_t num){
- boost::uint16_t real = boost::int16_t(num.real()*shorts_per_double);
- boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_double);
+static UHD_INLINE item32_t fc64_to_item32(fc64_t num, double scale_factor){
+ boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
+ boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
* Convert items32 buffer to complex double
**********************************************************************/
-static const double doubles_per_short = double(1.0/shorts_per_double);
-
-static UHD_INLINE fc64_t item32_to_fc64(item32_t item){
+static UHD_INLINE fc64_t item32_to_fc64(item32_t item, double scale_factor){
return fc64_t(
- float(boost::int16_t(item >> 16)*doubles_per_short),
- float(boost::int16_t(item >> 0)*doubles_per_short)
+ float(boost::int16_t(item >> 16)*scale_factor),
+ float(boost::int16_t(item >> 0)*scale_factor)
);
}
diff --git a/host/lib/convert/convert_orc.orc b/host/lib/convert/convert_orc.orc
new file mode 100644
index 000000000..5450bf4db
--- /dev/null
+++ b/host/lib/convert/convert_orc.orc
@@ -0,0 +1,63 @@
+.function _convert_fc32_1_to_item32_1_nswap_orc
+.source 8 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 8 scaled
+.temp 8 converted
+.temp 4 short
+x2 mulf scaled, src, scalar
+x2 convfl converted, scaled
+x2 convlw short, converted
+swapl short, short
+x2 swapw dst, short
+
+.function _convert_fc32_1_to_item32_1_bswap_orc
+.source 8 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 8 scaled
+.temp 8 converted
+.temp 4 short
+x2 mulf scaled, src, scalar
+x2 convfl converted, scaled
+x2 convlw short, converted
+x2 swapw dst, short
+
+.function _convert_item32_1_to_fc32_1_nswap_orc
+.source 4 src
+.dest 8 dst
+.floatparam 4 scalar
+.temp 4 tmp1
+.temp 8 tmp2
+x2 swapw tmp1, src
+swapl tmp1, tmp1
+x2 convswl tmp2, tmp1
+x2 convlf tmp2, tmp2
+x2 mulf dst, tmp2, scalar
+
+.function _convert_item32_1_to_fc32_1_bswap_orc
+.source 4 src
+.dest 8 dst
+.floatparam 4 scalar
+.temp 4 tmp1
+.temp 8 tmp2
+x2 swapw tmp1, src
+x2 convswl tmp2, tmp1
+x2 convlf tmp2, tmp2
+x2 mulf dst, tmp2, scalar
+
+.function _convert_sc16_1_to_item32_1_nswap_orc
+.source 4 src
+.dest 4 dst
+.temp 4 tmp
+.floatparam 4 scalar
+swapl tmp, src
+x2 swapw dst, tmp
+
+.function _convert_item32_1_to_sc16_1_nswap_orc
+.source 4 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 4 tmp
+x2 swapw tmp, src
+swapl dst, tmp
diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp
index 3d677db5b..e5f08cad9 100644
--- a/host/lib/convert/convert_with_neon.cpp
+++ b/host/lib/convert/convert_with_neon.cpp
@@ -26,7 +26,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
size_t i;
- float32x4_t Q0 = vdupq_n_f32(shorts_per_float);
+ float32x4_t Q0 = vdupq_n_f32(float(scale_factor));
for (i=0; i < (nsamps & ~0x03); i+=2) {
float32x4_t Q1 = vld1q_f32(reinterpret_cast<const float *>(&input[i]));
float32x4_t Q2 = vmulq_f32(Q1, Q0);
@@ -37,7 +37,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = fc32_to_item32(input[i]);
+ output[i] = fc32_to_item32(input[i], float(scale_factor));
}
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
@@ -46,7 +46,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
size_t i;
- float32x4_t Q1 = vdupq_n_f32(floats_per_short);
+ float32x4_t Q1 = vdupq_n_f32(float(scale_factor));
for (i=0; i < (nsamps & ~0x03); i+=2) {
int16x4_t D0 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i]));
int16x4_t D1 = vrev32_s16(D0);
@@ -57,5 +57,5 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = item32_to_fc32(input[i]);
+ output[i] = item32_to_fc32(input[i], float(scale_factor));
}
diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp
new file mode 100644
index 000000000..844c2595c
--- /dev/null
+++ b/host/lib/convert/convert_with_orc.cpp
@@ -0,0 +1,54 @@
+//
+// 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 "convert_common.hpp"
+#include <uhd/utils/byteswap.hpp>
+
+using namespace uhd::convert;
+
+extern "C" {
+extern void _convert_fc32_1_to_item32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_fc32_1_to_item32_1_bswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_fc32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_fc32_1_bswap_orc(void *, const void *, float, int);
+extern void _convert_sc16_1_to_item32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_sc16_1_nswap_orc(void *, const void *, float, int);
+}
+
+DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_LIBORC){
+ _convert_fc32_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_LIBORC){
+ _convert_fc32_1_to_item32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_fc32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_fc32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_sc16_1_to_item32_1_nswap, PRIORITY_LIBORC){
+ _convert_sc16_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_sc16_1_nswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_sc16_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
diff --git a/host/lib/convert/convert_with_sse2.cpp b/host/lib/convert/convert_with_sse2.cpp
index 96ee9134c..52beea24a 100644
--- a/host/lib/convert/convert_with_sse2.cpp
+++ b/host/lib/convert/convert_with_sse2.cpp
@@ -25,7 +25,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(shorts_per_float);
+ __m128 scalar = _mm_set_ps1(float(scale_factor));
//convert blocks of samples with intrinsics
size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){
@@ -48,7 +48,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = fc32_to_item32(input[i]);
+ output[i] = fc32_to_item32(input[i], float(scale_factor));
}
}
@@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(shorts_per_float);
+ __m128 scalar = _mm_set_ps1(float(scale_factor));
//convert blocks of samples with intrinsics
size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){
@@ -78,7 +78,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = uhd::byteswap(fc32_to_item32(input[i]));
+ output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor)));
}
}
@@ -86,7 +86,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16));
+ __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
__m128i zeroi = _mm_setzero_si128();
//convert blocks of samples with intrinsics
@@ -111,7 +111,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(input[i]);
+ output[i] = item32_to_fc32(input[i], float(scale_factor));
}
}
@@ -119,7 +119,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16));
+ __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
__m128i zeroi = _mm_setzero_si128();
//convert blocks of samples with intrinsics
@@ -143,6 +143,6 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(uhd::byteswap(input[i]));
+ output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor));
}
}
diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py
index f03448047..8c3138bda 100644
--- a/host/lib/convert/gen_convert_general.py
+++ b/host/lib/convert/gen_convert_general.py
@@ -34,7 +34,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i]));
+ output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor)));
}
}
@@ -43,7 +43,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){
$(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]));
+ output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor));
}
}
"""
@@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GEN
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i]));
+ output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
#end for
}
}
@@ -69,7 +69,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GEN
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]));
+ output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor));
#end for
}
}
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 90360977a..b1821956c 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -98,5 +98,5 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/udp_simple.cpp
${CMAKE_CURRENT_SOURCE_DIR}/udp_zero_copy.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/vrt_packet_handler.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/usb_zero_copy_wrapper.cpp
)
diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py
index 7440def6a..5f048d8c7 100755
--- a/host/lib/transport/gen_vrt_if_packet.py
+++ b/host/lib/transport/gen_vrt_if_packet.py
@@ -62,6 +62,8 @@ static pred_table_type get_pred_unpack_table(void){
if(vrt_hdr_word & $hex(0x3 << 22)) table[i] |= $hex($tsi_p);
if(vrt_hdr_word & $hex(0x3 << 20)) table[i] |= $hex($tsf_p);
if(vrt_hdr_word & $hex(0x1 << 26)) table[i] |= $hex($tlr_p);
+ if(vrt_hdr_word & $hex(0x1 << 24)) table[i] |= $hex($eob_p);
+ if(vrt_hdr_word & $hex(0x1 << 25)) table[i] |= $hex($sob_p);
}
return table;
}
@@ -84,9 +86,11 @@ void vrt::if_hdr_pack_$(suffix)(
if (if_packet_info.has_tsi) pred |= $hex($tsi_p);
if (if_packet_info.has_tsf) pred |= $hex($tsf_p);
if (if_packet_info.has_tlr) pred |= $hex($tlr_p);
+ if (if_packet_info.eob) pred |= $hex($eob_p);
+ if (if_packet_info.sob) pred |= $hex($sob_p);
switch(pred){
- #for $pred in range(2**5)
+ #for $pred in range(2**7)
case $pred:
#set $num_header_words = 1
#set $flags = 0
@@ -126,6 +130,13 @@ void vrt::if_hdr_pack_$(suffix)(
#else
#set $num_trailer_words = 0;
#end if
+ ########## Burst Flags ##########
+ #if $pred & $eob_p
+ #set $flags |= (0x1 << 24);
+ #end if
+ #if $pred & $sob_p
+ #set $flags |= (0x1 << 25);
+ #end if
########## Variables ##########
if_packet_info.num_header_words32 = $num_header_words;
if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32;
@@ -134,10 +145,6 @@ void vrt::if_hdr_pack_$(suffix)(
#end for
}
- //set the burst flags
- if (if_packet_info.sob) vrt_hdr_flags |= $hex(0x1 << 25);
- if (if_packet_info.eob) vrt_hdr_flags |= $hex(0x1 << 24);
-
//fill in complete header word
packet_buff[0] = $(XE_MACRO)(boost::uint32_t(0
| (if_packet_info.packet_type << 29)
@@ -162,13 +169,11 @@ void vrt::if_hdr_unpack_$(suffix)(
//extract fields from the header
if_packet_info.packet_type = if_packet_info_t::packet_type_t(vrt_hdr_word >> 29);
if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf;
- //if_packet_info.sob = bool(vrt_hdr_word & $hex(0x1 << 25)); //not implemented
- //if_packet_info.eob = bool(vrt_hdr_word & $hex(0x1 << 24)); //not implemented
const pred_type pred = pred_unpack_table[pred_table_index(vrt_hdr_word)];
switch(pred){
- #for $pred in range(2**5)
+ #for $pred in range(2**7)
case $pred:
#set $has_time_spec = False
#set $num_header_words = 1
@@ -215,6 +220,17 @@ void vrt::if_hdr_unpack_$(suffix)(
if_packet_info.has_tlr = false;
#set $num_trailer_words = 0;
#end if
+ ########## Burst Flags ##########
+ #if $pred & $eob_p
+ if_packet_info.eob = true;
+ #else
+ if_packet_info.eob = false;
+ #end if
+ #if $pred & $sob_p
+ if_packet_info.sob = true;
+ #else
+ if_packet_info.sob = false;
+ #end if
########## Variables ##########
//another failure case
if (packet_words32 < $($num_header_words + $num_trailer_words))
@@ -243,9 +259,11 @@ if __name__ == '__main__':
open(sys.argv[1], 'w').write(parse_tmpl(
TMPL_TEXT,
file=__file__,
- sid_p = 0b00001,
- cid_p = 0b00010,
- tsi_p = 0b00100,
- tsf_p = 0b01000,
- tlr_p = 0b10000,
+ sid_p = 0b0000001,
+ cid_p = 0b0000010,
+ tsi_p = 0b0000100,
+ tsf_p = 0b0001000,
+ tlr_p = 0b0010000,
+ sob_p = 0b0100000,
+ eob_p = 0b1000000,
))
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 28bea978b..19a7a3742 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/log.hpp>
+#include <uhd/utils/msg.hpp>
#include <uhd/exception.hpp>
#include <boost/function.hpp>
#include <boost/foreach.hpp>
@@ -44,15 +44,24 @@ static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
* to ensure that they are compiled with the same calling convention as libusb.
*/
-//! helper function: handles all async callbacks
-static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut){
+//! helper function: handles all rx async callbacks
+static void LIBUSB_CALL libusb_async_rx_cb(libusb_transfer *lut){
+ if(lut->actual_length == 0) {
+ UHD_ASSERT_THROW(libusb_submit_transfer(lut) == 0); //get out until you find some real data
+ return;
+ }
+ (*static_cast<boost::function<void()> *>(lut->user_data))();
+}
+
+//! helper function: handles all tx async callbacks
+static void LIBUSB_CALL libusb_async_tx_cb(libusb_transfer *lut) {
(*static_cast<boost::function<void()> *>(lut->user_data))();
}
//! callback to free transfer upon cancellation
static void LIBUSB_CALL cancel_transfer_cb(libusb_transfer *lut){
- if (lut->status == LIBUSB_TRANSFER_CANCELLED) libusb_free_transfer(lut);
- else UHD_LOGV(rarely) << "libusb cancel_transfer unexpected status " << lut->status << std::endl;
+ if (lut->status == LIBUSB_TRANSFER_CANCELLED || lut->status == LIBUSB_TRANSFER_TIMED_OUT) libusb_free_transfer(lut);
+ else UHD_MSG(error) << "libusb cancel_transfer unexpected status " << lut->status << std::endl;
}
/***********************************************************************
@@ -97,7 +106,7 @@ public:
void commit(size_t len){
if (_expired) return;
_lut->length = len;
- if(len == 0) libusb_async_cb(_lut);
+ if(len == 0) libusb_async_tx_cb(_lut);
else UHD_ASSERT_THROW(libusb_submit_transfer(_lut) == 0);
_expired = true;
}
@@ -157,9 +166,9 @@ public:
(recv_endpoint & 0x7f) | 0x80, // endpoint
static_cast<unsigned char *>(_recv_buffer_pool->at(i)), // buffer
this->get_recv_frame_size(), // length
- libusb_transfer_cb_fn(&libusb_async_cb), // callback
+ libusb_transfer_cb_fn(&libusb_async_rx_cb), // callback
static_cast<void *>(&_callbacks.back()), // user_data
- 0 // timeout
+ 0 // timeout (ms)
);
_all_luts.push_back(lut);
@@ -183,13 +192,13 @@ public:
(send_endpoint & 0x7f) | 0x00, // endpoint
static_cast<unsigned char *>(_send_buffer_pool->at(i)), // buffer
this->get_send_frame_size(), // length
- libusb_transfer_cb_fn(&libusb_async_cb), // callback
+ libusb_transfer_cb_fn(&libusb_async_tx_cb), // callback
static_cast<void *>(&_callbacks.back()), // user_data
0 // timeout
);
_all_luts.push_back(lut);
- libusb_async_cb(lut);
+ libusb_async_tx_cb(lut);
}
//spawn the event handler threads
@@ -206,7 +215,9 @@ public:
BOOST_FOREACH(libusb_transfer *lut, _all_luts){
lut->callback = libusb_transfer_cb_fn(&cancel_transfer_cb);
libusb_cancel_transfer(lut);
- while(lut->status != LIBUSB_TRANSFER_CANCELLED && lut->status != LIBUSB_TRANSFER_COMPLETED) {
+ while(lut->status != LIBUSB_TRANSFER_CANCELLED
+ && lut->status != LIBUSB_TRANSFER_COMPLETED
+ && lut->status != LIBUSB_TRANSFER_TIMED_OUT) {
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
}
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
new file mode 100644
index 000000000..80ad17b6c
--- /dev/null
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -0,0 +1,638 @@
+//
+// 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/>.
+//
+
+#ifndef INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP
+#define INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/convert.hpp>
+#include <uhd/device.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <uhd/types/io_type.hpp>
+#include <uhd/types/otw_type.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+#include <vector>
+
+namespace uhd{ namespace transport{ namespace sph{
+
+UHD_INLINE boost::uint32_t get_context_code(
+ const boost::uint32_t *vrt_hdr, const vrt::if_packet_info_t &if_packet_info
+){
+ //extract the context word (we dont know the endianness so mirror the bytes)
+ boost::uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] |
+ uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]);
+ return word0 & 0xff;
+}
+
+typedef boost::function<void(void)> handle_overflow_type;
+static inline void handle_overflow_nop(void){}
+
+/***********************************************************************
+ * Alignment indexes class:
+ * - Access an integer set with very quick operations.
+ **********************************************************************/
+class alignment_indexes{
+public:
+ typedef boost::uint16_t index_type; //16 buffers
+
+ alignment_indexes(void):
+ _indexes(0),
+ _sizes(256, 0),
+ _fronts(256, ~0)
+ {
+ //fill the O(1) look up tables for a single byte
+ for (size_t i = 0; i < 256; i++){
+ for (size_t j = 0; j < 8; j++){
+ if (i & (1 << j)){
+ _sizes[i]++;
+ _fronts[i] = j;
+ }
+ }
+ }
+ }
+
+ UHD_INLINE void reset(size_t len){_indexes = (1 << len) - 1;}
+
+ UHD_INLINE size_t front(void){
+ //check one byte per iteration
+ for (size_t i = 0; i < sizeof(_indexes)*8; i+=8){
+ size_t front = _fronts[(_indexes >> i) & 0xff];
+ if (front != size_t(~0)) return front + i;
+ }
+ if (empty()) throw uhd::runtime_error("cannot call front() when empty");
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+
+ UHD_INLINE void remove(size_t index){_indexes &= ~(1 << index);}
+
+ UHD_INLINE bool empty(void){return _indexes == 0;}
+
+ UHD_INLINE size_t size(void){
+ size_t size = 0;
+ //check one byte per iteration
+ for (size_t i = 0; i < sizeof(_indexes)*8; i+=8){
+ size += _sizes[(_indexes >> i) & 0xff];
+ }
+ return size;
+ }
+
+private:
+ index_type _indexes;
+ std::vector<size_t> _sizes;
+ std::vector<size_t> _fronts;
+};
+
+/***********************************************************************
+ * Super receive packet handler
+ *
+ * A receive packet handler represents a group of channels.
+ * The channel group shares a common sample rate.
+ * All channels are received in unison in recv().
+ **********************************************************************/
+class recv_packet_handler{
+public:
+ typedef boost::function<managed_recv_buffer::sptr(double)> get_buff_type;
+ typedef void(*vrt_unpacker_type)(const boost::uint32_t *, vrt::if_packet_info_t &);
+ //typedef boost::function<void(const boost::uint32_t *, vrt::if_packet_info_t &)> vrt_unpacker_type;
+
+ /*!
+ * Make a new packet handler for receive
+ * \param size the number of transport channels
+ */
+ recv_packet_handler(const size_t size = 1):
+ _queue_error_for_next_call(false),
+ _buffers_infos_index(0)
+ {
+ UHD_ASSERT_THROW(size <= sizeof(alignment_indexes::index_type)*8);
+ this->resize(size);
+ set_alignment_failure_threshold(1000);
+ }
+
+ //! Resize the number of transport channels
+ void resize(const size_t size){
+ if (this->size() == size) return;
+ _props.resize(size);
+ //re-initialize all buffers infos by re-creating the vector
+ _buffers_infos = std::vector<buffers_info_type>(4, buffers_info_type(size));
+ }
+
+ //! Get the channel width of this handler
+ size_t size(void) const{
+ return _props.size();
+ }
+
+ //! Setup the vrt unpacker function and offset
+ void set_vrt_unpacker(const vrt_unpacker_type &vrt_unpacker, const size_t header_offset_words32 = 0){
+ _vrt_unpacker = vrt_unpacker;
+ _header_offset_words32 = header_offset_words32;
+ }
+
+ /*!
+ * Set the threshold for alignment failure.
+ * How many packets throw out before giving up?
+ * \param threshold number of packets per channel
+ */
+ void set_alignment_failure_threshold(const size_t threshold){
+ _alignment_faulure_threshold = threshold*this->size();
+ }
+
+ //! Set the rate of ticks per second
+ void set_tick_rate(const double rate){
+ _tick_rate = rate;
+ }
+
+ //! Set the rate of samples per second
+ void set_samp_rate(const double rate){
+ _samp_rate = rate;
+ }
+
+ /*!
+ * Set the function to get a managed buffer.
+ * \param xport_chan which transport channel
+ * \param get_buff the getter function
+ */
+ void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type &get_buff){
+ _props.at(xport_chan).get_buff = get_buff;
+ }
+
+ /*!
+ * Setup the conversion functions (homogeneous across transports).
+ * Here, we load a table of converters for all possible io types.
+ * This makes the converter look-up an O(1) operation.
+ * \param otw_type the channel data type
+ * \param width the streams per channel (usually 1)
+ */
+ void set_converter(const uhd::otw_type_t &otw_type, const size_t width = 1){
+ _io_buffs.resize(width);
+ _converters.resize(128);
+ for (size_t io_type = 0; io_type < _converters.size(); io_type++){
+ try{
+ _converters[io_type] = uhd::convert::get_converter_otw_to_cpu(
+ io_type_t::tid_t(io_type), otw_type, 1, width
+ );
+ }catch(const uhd::value_error &){} //we expect this, not all io_types valid...
+ }
+ _bytes_per_item = otw_type.get_sample_size();
+ }
+
+ //! Set the transport channel's overflow handler
+ void set_overflow_handler(const size_t xport_chan, const handle_overflow_type &handle_overflow){
+ _props.at(xport_chan).handle_overflow = handle_overflow;
+ }
+
+ //! Get a scoped lock object for this instance
+ boost::mutex::scoped_lock get_scoped_lock(void){
+ return boost::mutex::scoped_lock(_mutex);
+ }
+
+ /*******************************************************************
+ * Receive:
+ * The entry point for the fast-path receive calls.
+ * Dispatch into combinations of single packet receive calls.
+ ******************************************************************/
+ UHD_INLINE size_t recv(
+ const uhd::device::recv_buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ uhd::rx_metadata_t &metadata,
+ const uhd::io_type_t &io_type,
+ uhd::device::recv_mode_t recv_mode,
+ double timeout
+ ){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ //handle metadata queued from a previous receive
+ if (_queue_error_for_next_call){
+ _queue_error_for_next_call = false;
+ metadata = _queue_metadata;
+ //We want to allow a full buffer recv to be cut short by a timeout,
+ //but do not want to generate an inline timeout message packet.
+ if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_TIMEOUT) return 0;
+ }
+
+ switch(recv_mode){
+
+ ////////////////////////////////////////////////////////////////
+ case uhd::device::RECV_MODE_ONE_PACKET:{
+ ////////////////////////////////////////////////////////////////
+ return recv_one_packet(buffs, nsamps_per_buff, metadata, io_type, timeout);
+ }
+
+ ////////////////////////////////////////////////////////////////
+ case uhd::device::RECV_MODE_FULL_BUFF:{
+ ////////////////////////////////////////////////////////////////
+ size_t accum_num_samps = recv_one_packet(
+ buffs, nsamps_per_buff, metadata, io_type, timeout
+ );
+
+ //first recv had an error code set, return immediately
+ if (metadata.error_code != rx_metadata_t::ERROR_CODE_NONE) return accum_num_samps;
+
+ //loop until buffer is filled or error code
+ while(accum_num_samps < nsamps_per_buff){
+ size_t num_samps = recv_one_packet(
+ buffs, nsamps_per_buff - accum_num_samps, _queue_metadata,
+ io_type, timeout, accum_num_samps*io_type.size
+ );
+
+ //metadata had an error code set, store for next call and return
+ if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_NONE){
+ _queue_error_for_next_call = true;
+ break;
+ }
+ accum_num_samps += num_samps;
+ }
+ return accum_num_samps;
+ }
+
+ default: throw uhd::value_error("unknown recv mode");
+ }//switch(recv_mode)
+ }
+
+private:
+
+ boost::mutex _mutex;
+ vrt_unpacker_type _vrt_unpacker;
+ size_t _header_offset_words32;
+ double _tick_rate, _samp_rate;
+ bool _queue_error_for_next_call;
+ size_t _alignment_faulure_threshold;
+ rx_metadata_t _queue_metadata;
+ struct xport_chan_props_type{
+ xport_chan_props_type(void):
+ packet_count(0),
+ handle_overflow(&handle_overflow_nop)
+ {}
+ get_buff_type get_buff;
+ size_t packet_count;
+ handle_overflow_type handle_overflow;
+ };
+ std::vector<xport_chan_props_type> _props;
+ std::vector<void *> _io_buffs; //used in conversion
+ size_t _bytes_per_item; //used in conversion
+ std::vector<uhd::convert::function_type> _converters; //used in conversion
+
+ //! information stored for a received buffer
+ struct per_buffer_info_type{
+ managed_recv_buffer::sptr buff;
+ const boost::uint32_t *vrt_hdr;
+ vrt::if_packet_info_t ifpi;
+ time_spec_t time;
+ const char *copy_buff;
+ };
+
+ //!information stored for a set of aligned buffers
+ struct buffers_info_type : std::vector<per_buffer_info_type> {
+ buffers_info_type(const size_t size):
+ std::vector<per_buffer_info_type>(size),
+ alignment_time_valid(false),
+ data_bytes_to_copy(0),
+ fragment_offset_in_samps(0)
+ {
+ indexes_to_do.reset(size);
+ }
+ alignment_indexes indexes_to_do; //used in alignment logic
+ time_spec_t alignment_time; //used in alignment logic
+ bool alignment_time_valid; //used in alignment logic
+ size_t data_bytes_to_copy; //keeps track of state
+ size_t fragment_offset_in_samps; //keeps track of state
+ rx_metadata_t metadata; //packet description
+ };
+
+ //! a circular queue of buffer infos
+ std::vector<buffers_info_type> _buffers_infos;
+ size_t _buffers_infos_index;
+ buffers_info_type &get_curr_buffer_info(void){return _buffers_infos[_buffers_infos_index];}
+ buffers_info_type &get_prev_buffer_info(void){return _buffers_infos[(_buffers_infos_index + 3)%4];}
+ buffers_info_type &get_next_buffer_info(void){return _buffers_infos[(_buffers_infos_index + 1)%4];}
+ void increment_buffer_info(void){_buffers_infos_index = (_buffers_infos_index + 1)%4;}
+
+ //! possible return options for the packet receiver
+ enum packet_type{
+ PACKET_IF_DATA,
+ PACKET_TIMESTAMP_ERROR,
+ PACKET_INLINE_MESSAGE,
+ PACKET_TIMEOUT_ERROR,
+ PACKET_SEQUENCE_ERROR
+ };
+
+ /*******************************************************************
+ * Get and process a single packet from the transport:
+ * Receive a single packet at the given index.
+ * Extract all the relevant info and store.
+ * Check the info to determine the return code.
+ ******************************************************************/
+ UHD_INLINE packet_type get_and_process_single_packet(
+ const size_t index,
+ buffers_info_type &prev_buffer_info,
+ buffers_info_type &curr_buffer_info,
+ double timeout
+ ){
+ //get a single packet from the transport layer
+ managed_recv_buffer::sptr &buff = curr_buffer_info[index].buff;
+ buff = _props[index].get_buff(timeout);
+ if (buff.get() == NULL) return PACKET_TIMEOUT_ERROR;
+
+ //bounds check before extract
+ size_t num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
+ if (num_packet_words32 <= _header_offset_words32){
+ throw std::runtime_error("recv buffer smaller than vrt packet offset");
+ }
+
+ //extract packet info
+ per_buffer_info_type &info = curr_buffer_info[index];
+ info.ifpi.num_packet_words32 = num_packet_words32 - _header_offset_words32;
+ info.vrt_hdr = buff->cast<const boost::uint32_t *>() + _header_offset_words32;
+ _vrt_unpacker(info.vrt_hdr, info.ifpi);
+ info.time = time_spec_t(time_t(info.ifpi.tsi), size_t(info.ifpi.tsf), _tick_rate); //assumes has_tsi and has_tsf are true
+ info.copy_buff = reinterpret_cast<const char *>(info.vrt_hdr + info.ifpi.num_header_words32);
+
+ //store the packet count for the next iteration
+ #ifndef SRPH_DONT_CHECK_SEQUENCE
+ const size_t expected_packet_count = _props[index].packet_count;
+ _props[index].packet_count = (info.ifpi.packet_count + 1)%16;
+ #endif
+
+ //--------------------------------------------------------------
+ //-- Determine return conditions:
+ //-- The order of these checks is HOLY.
+ //--------------------------------------------------------------
+
+ //1) check for out of order timestamps
+ if (info.ifpi.has_tsi and info.ifpi.has_tsf and prev_buffer_info[index].time > info.time){
+ return PACKET_TIMESTAMP_ERROR;
+ }
+
+ //2) check for inline IF message packets
+ if (info.ifpi.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){
+ return PACKET_INLINE_MESSAGE;
+ }
+
+ //3) check for sequence errors
+ #ifndef SRPH_DONT_CHECK_SEQUENCE
+ if (expected_packet_count != info.ifpi.packet_count){
+ return PACKET_SEQUENCE_ERROR;
+ }
+ #endif
+
+ //4) otherwise the packet is normal!
+ return PACKET_IF_DATA;
+ }
+
+ /*******************************************************************
+ * Alignment check:
+ * Check the received packet for alignment and mark accordingly.
+ ******************************************************************/
+ UHD_INLINE void alignment_check(
+ const size_t index, buffers_info_type &info
+ ){
+ //if alignment time was not valid or if the sequence id is newer:
+ // use this index's time as the alignment time
+ // reset the indexes list and remove this index
+ if (not info.alignment_time_valid or info[index].time > info.alignment_time){
+ info.alignment_time_valid = true;
+ info.alignment_time = info[index].time;
+ info.indexes_to_do.reset(this->size());
+ info.indexes_to_do.remove(index);
+ info.data_bytes_to_copy = info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t);
+ }
+
+ //if the sequence id matches:
+ // remove this index from the list and continue
+ else if (info[index].time == info.alignment_time){
+ info.indexes_to_do.remove(index);
+ }
+
+ //if the sequence id is older:
+ // continue with the same index to try again
+ //else if (info[index].time < info.alignment_time)...
+ }
+
+ /*******************************************************************
+ * Get aligned buffers:
+ * Iterate through each index and try to accumulate aligned buffers.
+ * Handle all of the edge cases like inline messages and errors.
+ * The logic will throw out older packets until it finds a match.
+ ******************************************************************/
+ UHD_INLINE void get_aligned_buffs(double timeout){
+
+ increment_buffer_info(); //increment to next buffer
+ buffers_info_type &prev_info = get_prev_buffer_info();
+ buffers_info_type &curr_info = get_curr_buffer_info();
+ buffers_info_type &next_info = get_next_buffer_info();
+
+ //Loop until we get a message of an aligned set of buffers:
+ // - Receive a single packet and extract its info.
+ // - Handle the packet type yielded by the receive.
+ // - Check the timestamps for alignment conditions.
+ size_t iterations = 0;
+ while (not curr_info.indexes_to_do.empty()){
+
+ //get the index to process for this iteration
+ const size_t index = curr_info.indexes_to_do.front();
+ packet_type packet;
+
+ //receive a single packet from the transport
+ try{
+ packet = get_and_process_single_packet(
+ index, prev_info, curr_info, timeout
+ );
+ }
+
+ //handle the case when the get packet throws
+ catch(const std::exception &e){
+ UHD_MSG(error) << boost::format(
+ "The receive packet handler caught an exception.\n%s"
+ ) % e.what() << std::endl;
+ std::swap(curr_info, next_info); //save progress from curr -> next
+ curr_info.metadata.has_time_spec = false;
+ curr_info.metadata.time_spec = time_spec_t(0.0);
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ curr_info.metadata.start_of_burst = false;
+ curr_info.metadata.end_of_burst = false;
+ curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_BAD_PACKET;
+ return;
+ }
+
+ switch(packet){
+ case PACKET_IF_DATA:
+ alignment_check(index, curr_info);
+ break;
+
+ case PACKET_TIMESTAMP_ERROR:
+ //If the user changes the device time while streaming or without flushing,
+ //we can receive a packet that comes before the previous packet in time.
+ //This could cause the alignment logic to discard future received packets.
+ //Therefore, when this occurs, we reset the info to restart from scratch.
+ if (curr_info.alignment_time_valid and curr_info.alignment_time != curr_info[index].time){
+ curr_info.alignment_time_valid = false;
+ }
+ alignment_check(index, curr_info);
+ break;
+
+ case PACKET_INLINE_MESSAGE:
+ std::swap(curr_info, next_info); //save progress from curr -> next
+ curr_info.metadata.has_time_spec = next_info[index].ifpi.has_tsi and next_info[index].ifpi.has_tsf;
+ curr_info.metadata.time_spec = next_info[index].time;
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ curr_info.metadata.start_of_burst = false;
+ curr_info.metadata.end_of_burst = false;
+ curr_info.metadata.error_code = rx_metadata_t::error_code_t(get_context_code(next_info[index].vrt_hdr, next_info[index].ifpi));
+ if (curr_info.metadata.error_code == rx_metadata_t::ERROR_CODE_OVERFLOW) _props[index].handle_overflow();
+ UHD_MSG(fastpath) << "O";
+ return;
+
+ case PACKET_TIMEOUT_ERROR:
+ std::swap(curr_info, next_info); //save progress from curr -> next
+ curr_info.metadata.has_time_spec = false;
+ curr_info.metadata.time_spec = time_spec_t(0.0);
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ curr_info.metadata.start_of_burst = false;
+ curr_info.metadata.end_of_burst = false;
+ curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_TIMEOUT;
+ return;
+
+ case PACKET_SEQUENCE_ERROR:
+ alignment_check(index, curr_info);
+ std::swap(curr_info, next_info); //save progress from curr -> next
+ curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec;
+ curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t(0,
+ prev_info[index].ifpi.num_payload_words32*sizeof(boost::uint32_t)/_bytes_per_item, _samp_rate);
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ curr_info.metadata.start_of_burst = false;
+ curr_info.metadata.end_of_burst = false;
+ curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW;
+ UHD_MSG(fastpath) << "O";
+ return;
+
+ }
+
+ //too many iterations: detect alignment failure
+ if (iterations++ > _alignment_faulure_threshold){
+ UHD_MSG(error) << boost::format(
+ "The receive packet handler failed to time-align packets.\n"
+ "%u received packets were processed by the handler.\n"
+ "However, a timestamp match could not be determined.\n"
+ ) % iterations << std::endl;
+ std::swap(curr_info, next_info); //save progress from curr -> next
+ curr_info.metadata.has_time_spec = false;
+ curr_info.metadata.time_spec = time_spec_t(0.0);
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ curr_info.metadata.start_of_burst = false;
+ curr_info.metadata.end_of_burst = false;
+ curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_ALIGNMENT;
+ return;
+ }
+
+ }
+
+ //set the metadata from the buffer information at index zero
+ curr_info.metadata.has_time_spec = curr_info[0].ifpi.has_tsi and curr_info[0].ifpi.has_tsf;
+ curr_info.metadata.time_spec = curr_info[0].time;
+ curr_info.metadata.more_fragments = false;
+ curr_info.metadata.fragment_offset = 0;
+ /* TODO SOB on RX not supported in hardware
+ static const int tlr_sob_flags = (1 << 21) | (1 << 9); //enable and indicator bits
+ curr_info.metadata.start_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_sob_flags) != 0);
+ */
+ curr_info.metadata.start_of_burst = false;
+ static const int tlr_eob_flags = (1 << 20) | (1 << 8); //enable and indicator bits
+ curr_info.metadata.end_of_burst = curr_info[0].ifpi.has_tlr and (int(curr_info[0].ifpi.tlr & tlr_eob_flags) != 0);
+ curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_NONE;
+
+ }
+
+ /*******************************************************************
+ * Receive a single packet:
+ * Handles fragmentation, messages, errors, and copy-conversion.
+ * When no fragments are available, call the get aligned buffers.
+ * Then copy-convert available data into the user's IO buffers.
+ ******************************************************************/
+ UHD_INLINE size_t recv_one_packet(
+ const uhd::device::recv_buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ uhd::rx_metadata_t &metadata,
+ const uhd::io_type_t &io_type,
+ double timeout,
+ const size_t buffer_offset_bytes = 0
+ ){
+ //get the next buffer if the current one has expired
+ if (get_curr_buffer_info().data_bytes_to_copy == 0){
+
+ //reset current buffer info members for reuse
+ get_curr_buffer_info().fragment_offset_in_samps = 0;
+ get_curr_buffer_info().alignment_time_valid = false;
+ get_curr_buffer_info().indexes_to_do.reset(this->size());
+
+ //perform receive with alignment logic
+ get_aligned_buffs(timeout);
+ }
+
+ buffers_info_type &info = get_curr_buffer_info();
+ metadata = info.metadata;
+
+ //interpolate the time spec (useful when this is a fragment)
+ metadata.time_spec += time_spec_t(0, info.fragment_offset_in_samps, _samp_rate);
+
+ //extract the number of samples available to copy
+ const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_item;
+ const size_t nsamps_to_copy = std::min(nsamps_per_buff*_io_buffs.size(), nsamps_available);
+ const size_t bytes_to_copy = nsamps_to_copy*_bytes_per_item;
+ const size_t nsamps_to_copy_per_io_buff = nsamps_to_copy/_io_buffs.size();
+
+ size_t buff_index = 0;
+ BOOST_FOREACH(per_buffer_info_type &buff_info, info){
+
+ //fill a vector with pointers to the io buffers
+ BOOST_FOREACH(void *&io_buff, _io_buffs){
+ io_buff = reinterpret_cast<char *>(buffs[buff_index++]) + buffer_offset_bytes;
+ }
+
+ //copy-convert the samples from the recv buffer
+ _converters[io_type.tid](buff_info.copy_buff, _io_buffs, nsamps_to_copy_per_io_buff, 1/32767.);
+
+ //update the rx copy buffer to reflect the bytes copied
+ buff_info.copy_buff += bytes_to_copy;
+ }
+ //update the copy buffer's availability
+ info.data_bytes_to_copy -= bytes_to_copy;
+
+ //setup the fragment flags and offset
+ metadata.more_fragments = info.data_bytes_to_copy != 0;
+ metadata.fragment_offset = info.fragment_offset_in_samps;
+ info.fragment_offset_in_samps += nsamps_to_copy; //set for next call
+
+ return nsamps_to_copy_per_io_buff;
+ }
+};
+
+}}} //namespace
+
+#endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP */
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp
new file mode 100644
index 000000000..8ebc264ef
--- /dev/null
+++ b/host/lib/transport/super_send_packet_handler.hpp
@@ -0,0 +1,287 @@
+//
+// 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/>.
+//
+
+#ifndef INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP
+#define INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/convert.hpp>
+#include <uhd/device.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <uhd/types/io_type.hpp>
+#include <uhd/types/otw_type.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <iostream>
+#include <vector>
+
+namespace uhd{ namespace transport{ namespace sph{
+
+/***********************************************************************
+ * Super send packet handler
+ *
+ * A send packet handler represents a group of channels.
+ * The channel group shares a common sample rate.
+ * All channels are sent in unison in send().
+ **********************************************************************/
+class send_packet_handler{
+public:
+ typedef boost::function<managed_send_buffer::sptr(double)> get_buff_type;
+ typedef void(*vrt_packer_type)(boost::uint32_t *, vrt::if_packet_info_t &);
+ //typedef boost::function<void(boost::uint32_t *, vrt::if_packet_info_t &)> vrt_packer_type;
+
+ /*!
+ * Make a new packet handler for send
+ * \param size the number of transport channels
+ */
+ send_packet_handler(const size_t size = 1):
+ _next_packet_seq(0)
+ {
+ this->resize(size);
+ }
+
+ //! Resize the number of transport channels
+ void resize(const size_t size){
+ if (this->size() == size) return;
+ _props.resize(size);
+ static const boost::uint64_t zero = 0;
+ _zero_buffs.resize(size, &zero);
+ }
+
+ //! Get the channel width of this handler
+ size_t size(void) const{
+ return _props.size();
+ }
+
+ //! Setup the vrt packer function and offset
+ void set_vrt_packer(const vrt_packer_type &vrt_packer, const size_t header_offset_words32 = 0){
+ _vrt_packer = vrt_packer;
+ _header_offset_words32 = header_offset_words32;
+ }
+
+ //! Set the rate of ticks per second
+ void set_tick_rate(const double rate){
+ _tick_rate = rate;
+ }
+
+ //! Set the rate of samples per second
+ void set_samp_rate(const double rate){
+ _samp_rate = rate;
+ }
+
+ /*!
+ * Set the function to get a managed buffer.
+ * \param xport_chan which transport channel
+ * \param get_buff the getter function
+ */
+ void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type &get_buff){
+ _props.at(xport_chan).get_buff = get_buff;
+ }
+
+ /*!
+ * Setup the conversion functions (homogeneous across transports).
+ * Here, we load a table of converters for all possible io types.
+ * This makes the converter look-up an O(1) operation.
+ * \param otw_type the channel data type
+ * \param width the streams per channel (usually 1)
+ */
+ void set_converter(const uhd::otw_type_t &otw_type, const size_t width = 1){
+ _io_buffs.resize(width);
+ _converters.resize(128);
+ for (size_t io_type = 0; io_type < _converters.size(); io_type++){
+ try{
+ _converters[io_type] = uhd::convert::get_converter_cpu_to_otw(
+ io_type_t::tid_t(io_type), otw_type, 1, width
+ );
+ }catch(const uhd::value_error &){} //we expect this, not all io_types valid...
+ }
+ _bytes_per_item = otw_type.get_sample_size();
+ }
+
+ /*!
+ * Set the maximum number of samples per host packet.
+ * Ex: A USRP1 in dual channel mode would be half.
+ * \param num_samps the maximum samples in a packet
+ */
+ void set_max_samples_per_packet(const size_t num_samps){
+ _max_samples_per_packet = num_samps;
+ }
+
+ //! Get a scoped lock object for this instance
+ boost::mutex::scoped_lock get_scoped_lock(void){
+ return boost::mutex::scoped_lock(_mutex);
+ }
+
+ /*******************************************************************
+ * Send:
+ * The entry point for the fast-path send calls.
+ * Dispatch into combinations of single packet send calls.
+ ******************************************************************/
+ UHD_INLINE size_t send(
+ const uhd::device::send_buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ const uhd::tx_metadata_t &metadata,
+ const uhd::io_type_t &io_type,
+ uhd::device::send_mode_t send_mode,
+ double timeout
+ ){
+ boost::mutex::scoped_lock lock(_mutex);
+
+ //translate the metadata to vrt if packet info
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tlr = false;
+ if_packet_info.has_tsi = metadata.has_time_spec;
+ if_packet_info.has_tsf = metadata.has_time_spec;
+ if_packet_info.tsi = boost::uint32_t(metadata.time_spec.get_full_secs());
+ if_packet_info.tsf = boost::uint64_t(metadata.time_spec.get_tick_count(_tick_rate));
+ if_packet_info.sob = metadata.start_of_burst;
+ if_packet_info.eob = metadata.end_of_burst;
+
+ if (nsamps_per_buff <= _max_samples_per_packet) send_mode = uhd::device::SEND_MODE_ONE_PACKET;
+ switch(send_mode){
+
+ ////////////////////////////////////////////////////////////////
+ case uhd::device::SEND_MODE_ONE_PACKET:{
+ ////////////////////////////////////////////////////////////////
+
+ //TODO remove this code when sample counts of zero are supported by hardware
+ if (nsamps_per_buff == 0) return send_one_packet(
+ _zero_buffs, 1, if_packet_info, io_type, timeout
+ );
+
+ return send_one_packet(
+ buffs,
+ std::min(nsamps_per_buff, _max_samples_per_packet),
+ if_packet_info, io_type, timeout
+ );
+ }
+
+ ////////////////////////////////////////////////////////////////
+ case uhd::device::SEND_MODE_FULL_BUFF:{
+ ////////////////////////////////////////////////////////////////
+ size_t total_num_samps_sent = 0;
+
+ //false until final fragment
+ if_packet_info.eob = false;
+
+ const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet;
+ const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1;
+
+ //loop through the following fragment indexes
+ for (size_t i = 0; i < num_fragments; i++){
+
+ //send a fragment with the helper function
+ const size_t num_samps_sent = send_one_packet(
+ buffs, _max_samples_per_packet,
+ if_packet_info, io_type, timeout,
+ total_num_samps_sent*io_type.size
+ );
+ total_num_samps_sent += num_samps_sent;
+ if (num_samps_sent == 0) return total_num_samps_sent;
+
+ //setup metadata for the next fragment
+ const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate);
+ if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs());
+ if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate));
+ if_packet_info.sob = false;
+
+ }
+
+ //send the final fragment with the helper function
+ if_packet_info.eob = metadata.end_of_burst;
+ return total_num_samps_sent + send_one_packet(
+ buffs, final_length,
+ if_packet_info, io_type, timeout,
+ total_num_samps_sent*io_type.size
+ );
+ }
+
+ default: throw uhd::value_error("unknown send mode");
+ }//switch(send_mode)
+ }
+
+private:
+
+ boost::mutex _mutex;
+ vrt_packer_type _vrt_packer;
+ size_t _header_offset_words32;
+ double _tick_rate, _samp_rate;
+ struct xport_chan_props_type{
+ get_buff_type get_buff;
+ };
+ std::vector<xport_chan_props_type> _props;
+ std::vector<const void *> _io_buffs; //used in conversion
+ size_t _bytes_per_item; //used in conversion
+ std::vector<uhd::convert::function_type> _converters; //used in conversion
+ size_t _max_samples_per_packet;
+ std::vector<const void *> _zero_buffs;
+ size_t _next_packet_seq;
+
+ /*******************************************************************
+ * Send a single packet:
+ ******************************************************************/
+ size_t send_one_packet(
+ const uhd::device::send_buffs_type &buffs,
+ const size_t nsamps_per_buff,
+ vrt::if_packet_info_t &if_packet_info,
+ const uhd::io_type_t &io_type,
+ double timeout,
+ const size_t buffer_offset_bytes = 0
+ ){
+ //load the rest of the if_packet_info in here
+ if_packet_info.num_payload_words32 = (nsamps_per_buff*_io_buffs.size()*_bytes_per_item)/sizeof(boost::uint32_t);
+ if_packet_info.packet_count = _next_packet_seq;
+
+ size_t buff_index = 0;
+ BOOST_FOREACH(xport_chan_props_type &props, _props){
+ managed_send_buffer::sptr buff = props.get_buff(timeout);
+ if (buff.get() == NULL) return 0; //timeout
+
+ //fill a vector with pointers to the io buffers
+ BOOST_FOREACH(const void *&io_buff, _io_buffs){
+ io_buff = reinterpret_cast<const char *>(buffs[buff_index++]) + buffer_offset_bytes;
+ }
+ boost::uint32_t *otw_mem = buff->cast<boost::uint32_t *>() + _header_offset_words32;
+
+ //pack metadata into a vrt header
+ _vrt_packer(otw_mem, if_packet_info);
+ otw_mem += if_packet_info.num_header_words32;
+
+ //copy-convert the samples into the send buffer
+ _converters[io_type.tid](_io_buffs, otw_mem, nsamps_per_buff, 32767.);
+
+ //commit the samples to the zero-copy interface
+ size_t num_bytes_total = (_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t);
+ buff->commit(num_bytes_total);
+
+ }
+ _next_packet_seq++; //increment sequence after commits
+ return nsamps_per_buff;
+ }
+};
+
+}}} //namespace
+
+#endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP */
diff --git a/host/lib/transport/usb_zero_copy_wrapper.cpp b/host/lib/transport/usb_zero_copy_wrapper.cpp
new file mode 100644
index 000000000..227c4b392
--- /dev/null
+++ b/host/lib/transport/usb_zero_copy_wrapper.cpp
@@ -0,0 +1,202 @@
+//
+// 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/transport/usb_zero_copy.hpp>
+#include <uhd/transport/bounded_buffer.hpp>
+#include <uhd/transport/buffer_pool.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+#include <iostream>
+
+using namespace uhd::transport;
+bool debug = true;
+
+static inline size_t next_boundary(size_t length, size_t boundary){
+ //pad to the boundary, assumes boundary is a power of 2
+ return (length + (boundary-1)) & ~(boundary-1);
+}
+
+/***********************************************************************
+ * USB zero copy wrapper - managed receive buffer
+ **********************************************************************/
+class usb_zero_copy_wrapper_mrb : public managed_recv_buffer{
+public:
+ usb_zero_copy_wrapper_mrb(bounded_buffer<usb_zero_copy_wrapper_mrb *> &queue):
+ _queue(queue){/*NOP*/}
+
+ void release(void){
+ if (_mrb.get() == NULL) return;
+ _mrb->release();
+ _queue.push_with_haste(this);
+ _mrb.reset();
+ }
+
+ sptr get_new(managed_recv_buffer::sptr mrb, const void *mem, size_t len){
+ _mrb = mrb;
+ _mem = mem;
+ _len = len;
+ return make_managed_buffer(this);
+ }
+
+private:
+ const void *get_buff(void) const{return _mem;}
+ size_t get_size(void) const{return _len;}
+
+ bounded_buffer<usb_zero_copy_wrapper_mrb *> &_queue;
+ const void *_mem;
+ size_t _len;
+ managed_recv_buffer::sptr _mrb;
+};
+
+/***********************************************************************
+ * USB zero copy wrapper - managed send buffer
+ **********************************************************************/
+class usb_zero_copy_wrapper_msb : public managed_send_buffer{
+public:
+ usb_zero_copy_wrapper_msb(bounded_buffer<usb_zero_copy_wrapper_msb *> &queue, size_t boundary):
+ _queue(queue), _boundary(boundary){/*NOP*/}
+
+ void commit(size_t len){
+ if (_msb.get() == NULL) return;
+ _msb->commit(next_boundary(len, _boundary));
+ _queue.push_with_haste(this);
+ _msb.reset();
+ }
+
+ sptr get_new(managed_send_buffer::sptr msb){
+ _msb = msb;
+ return make_managed_buffer(this);
+ }
+
+private:
+ void *get_buff(void) const{return _msb->cast<void *>();}
+ size_t get_size(void) const{return _msb->size();}
+
+ bounded_buffer<usb_zero_copy_wrapper_msb *> &_queue;
+ size_t _boundary;
+ managed_send_buffer::sptr _msb;
+};
+
+/***********************************************************************
+ * USB zero copy wrapper implementation
+ **********************************************************************/
+class usb_zero_copy_wrapper : public usb_zero_copy{
+public:
+ usb_zero_copy_wrapper(
+ sptr usb_zc, size_t usb_frame_boundary
+ ):
+ _internal_zc(usb_zc),
+ _usb_frame_boundary(usb_frame_boundary),
+ _available_recv_buffs(this->get_num_recv_frames()),
+ _available_send_buffs(this->get_num_send_frames()),
+ _mrb_pool(this->get_num_recv_frames(), usb_zero_copy_wrapper_mrb(_available_recv_buffs)),
+ _msb_pool(this->get_num_send_frames(), usb_zero_copy_wrapper_msb(_available_send_buffs, usb_frame_boundary))
+ {
+ BOOST_FOREACH(usb_zero_copy_wrapper_mrb &mrb, _mrb_pool){
+ _available_recv_buffs.push_with_haste(&mrb);
+ }
+
+ BOOST_FOREACH(usb_zero_copy_wrapper_msb &msb, _msb_pool){
+ _available_send_buffs.push_with_haste(&msb);
+ }
+ }
+
+ managed_recv_buffer::sptr get_recv_buff(double timeout){
+ //attempt to get a managed recv buffer
+ if (not _last_recv_buff.get()){
+ _last_recv_buff = _internal_zc->get_recv_buff(timeout);
+ _last_recv_offset = 0;
+ }
+
+ //attempt to get a wrapper for a managed recv buffer
+ usb_zero_copy_wrapper_mrb *wmrb = NULL;
+ if (_last_recv_buff.get() and _available_recv_buffs.pop_with_timed_wait(wmrb, timeout)){
+ //extract this packet's memory address and length in bytes
+ const char *mem = _last_recv_buff->cast<const char *>() + _last_recv_offset;
+ const boost::uint32_t *mem32 = reinterpret_cast<const boost::uint32_t *>(mem);
+ size_t len = (mem32[0] & 0xffff)*sizeof(boost::uint32_t); //length in bytes (from VRT header)
+
+ managed_recv_buffer::sptr recv_buff; //the buffer to be returned to the user
+
+ recv_buff = wmrb->get_new(_last_recv_buff, mem, len);
+ _last_recv_offset = next_boundary(_last_recv_offset + len, _usb_frame_boundary);
+
+ //check if this receive buffer has been exhausted
+ if (_last_recv_offset >= _last_recv_buff->size()) {
+ _last_recv_buff.reset();
+ }
+
+ return recv_buff;
+ }
+
+ //otherwise return a null sptr for failure
+ return managed_recv_buffer::sptr();
+ }
+
+ size_t get_num_recv_frames(void) const{
+ return _internal_zc->get_num_recv_frames();
+ }
+
+ size_t get_recv_frame_size(void) const{
+ return _internal_zc->get_recv_frame_size();
+ }
+
+ managed_send_buffer::sptr get_send_buff(double timeout){
+ managed_send_buffer::sptr send_buff = _internal_zc->get_send_buff(timeout);
+
+ //attempt to get a wrapper for a managed send buffer
+ usb_zero_copy_wrapper_msb *wmsb = NULL;
+ if (send_buff.get() and _available_send_buffs.pop_with_haste(wmsb)){
+ return wmsb->get_new(send_buff);
+ }
+
+ //otherwise return a null sptr for failure
+ return managed_send_buffer::sptr();
+ }
+
+ size_t get_num_send_frames(void) const{
+ return _internal_zc->get_num_send_frames();
+ }
+
+ size_t get_send_frame_size(void) const{
+ return _internal_zc->get_send_frame_size();
+ }
+
+private:
+ sptr _internal_zc;
+ size_t _usb_frame_boundary;
+ bounded_buffer<usb_zero_copy_wrapper_mrb *> _available_recv_buffs;
+ bounded_buffer<usb_zero_copy_wrapper_msb *> _available_send_buffs;
+ std::vector<usb_zero_copy_wrapper_mrb> _mrb_pool;
+ std::vector<usb_zero_copy_wrapper_msb> _msb_pool;
+
+ //buffer to store partially-received VRT packets in
+ buffer_pool::sptr _fragment_mem;
+
+ //state for last recv buffer to create multiple managed buffers
+ managed_recv_buffer::sptr _last_recv_buff;
+ size_t _last_recv_offset;
+};
+
+/***********************************************************************
+ * USB zero copy wrapper factory function
+ **********************************************************************/
+usb_zero_copy::sptr usb_zero_copy::make_wrapper(
+ sptr usb_zc, size_t usb_frame_boundary
+){
+ return sptr(new usb_zero_copy_wrapper(usb_zc, usb_frame_boundary));
+}
diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp
deleted file mode 100644
index d74b2c13c..000000000
--- a/host/lib/transport/vrt_packet_handler.hpp
+++ /dev/null
@@ -1,470 +0,0 @@
-//
-// 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_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP
-#define INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP
-
-#include <uhd/config.hpp>
-#include <uhd/device.hpp>
-#include <uhd/exception.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/types/io_type.hpp>
-#include <uhd/types/otw_type.hpp>
-#include <uhd/types/metadata.hpp>
-#include <uhd/transport/vrt_if_packet.hpp>
-#include <uhd/convert.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <boost/function.hpp>
-#include <stdexcept>
-#include <iostream>
-#include <vector>
-
-namespace vrt_packet_handler{
-
-//this may change in the future but its a constant for now
-static const size_t OTW_BYTES_PER_SAMP = sizeof(boost::uint32_t);
-
-template <typename T> UHD_INLINE T get_context_code(
- const boost::uint32_t *vrt_hdr,
- const uhd::transport::vrt::if_packet_info_t &if_packet_info
-){
- //extract the context word (we dont know the endianness so mirror the bytes)
- boost::uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] |
- uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]);
- return T(word0 & 0xff);
-}
-
-/***********************************************************************
- * vrt packet handler for recv
- **********************************************************************/
- typedef std::vector<uhd::transport::managed_recv_buffer::sptr> managed_recv_buffs_t;
- typedef boost::function<bool(managed_recv_buffs_t &)> get_recv_buffs_t;
- typedef boost::function<void(size_t /*which channel*/)> handle_overflow_t;
- typedef boost::function<void(const boost::uint32_t *, uhd::transport::vrt::if_packet_info_t &)> vrt_unpacker_t;
-
- static inline void handle_overflow_nop(size_t){}
-
- struct recv_state{
- //width of the receiver in channels
- size_t width;
-
- //state variables to handle fragments
- managed_recv_buffs_t managed_buffs;
- std::vector<const boost::uint8_t *> copy_buffs;
- size_t size_of_copy_buffs;
- size_t fragment_offset_in_samps;
- std::vector<void *> io_buffs;
- std::vector<const void *> otw_buffs;
-
- recv_state(size_t width = 1):
- width(width),
- managed_buffs(width),
- copy_buffs(width, NULL),
- size_of_copy_buffs(0),
- fragment_offset_in_samps(0),
- io_buffs(0) //resized later
- {
- /* NOP */
- }
- };
-
- /*******************************************************************
- * Unpack a received vrt header and set the copy buffer.
- * - helper function for vrt_packet_handler::_recv1
- ******************************************************************/
- static UHD_INLINE void _recv1_helper(
- recv_state &state,
- uhd::rx_metadata_t &metadata,
- double tick_rate,
- const vrt_unpacker_t &vrt_unpacker,
- const handle_overflow_t &handle_overflow,
- size_t vrt_header_offset_words32
- ){
- //vrt unpack each managed buffer
- uhd::transport::vrt::if_packet_info_t if_packet_info;
- for (size_t i = 0; i < state.width; i++){
- if (state.managed_buffs[i].get() == NULL) continue; //better have a message packet coming up...
-
- //extract packet words and check thats its enough to move on
- size_t num_packet_words32 = state.managed_buffs[i]->size()/sizeof(boost::uint32_t);
- if (num_packet_words32 <= vrt_header_offset_words32){
- throw std::runtime_error("recv buffer smaller than vrt packet offset");
- }
-
- //unpack the vrt header into the info struct
- const boost::uint32_t *vrt_hdr = state.managed_buffs[i]->cast<const boost::uint32_t *>() + vrt_header_offset_words32;
- if_packet_info.num_packet_words32 = num_packet_words32 - vrt_header_offset_words32;
- vrt_unpacker(vrt_hdr, if_packet_info);
-
- //handle the non-data packet case and parse its contents
- if (if_packet_info.packet_type != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA){
-
- metadata.error_code = get_context_code<uhd::rx_metadata_t::error_code_t>(vrt_hdr, if_packet_info);
- if (metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) handle_overflow(i);
-
- //break to exit loop and store metadata below
- state.size_of_copy_buffs = 0; break;
- }
-
- //setup the buffer to point to the data
- state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_hdr + if_packet_info.num_header_words32);
-
- //store the minimum payload length into the copy buffer length
- size_t num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t);
- if (i == 0 or state.size_of_copy_buffs > num_payload_bytes){
- state.size_of_copy_buffs = num_payload_bytes;
- }
- }
-
- //store the last vrt info into the metadata
- metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf;
- metadata.time_spec = uhd::time_spec_t(
- time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), tick_rate
- );
- static const int tlr_sob_flags = (1 << 21) | (1 << 9); //enable and indicator bits
- metadata.start_of_burst = if_packet_info.has_tlr and (int(if_packet_info.tlr & tlr_sob_flags) == tlr_sob_flags);
- static const int tlr_eob_flags = (1 << 20) | (1 << 8); //enable and indicator bits
- metadata.end_of_burst = if_packet_info.has_tlr and (int(if_packet_info.tlr & tlr_eob_flags) == tlr_eob_flags);
- }
-
- /*******************************************************************
- * Recv data, unpack a vrt header, and copy-convert the data.
- * - helper function for vrt_packet_handler::recv
- ******************************************************************/
- static UHD_INLINE size_t _recv1(
- recv_state &state,
- const uhd::device::recv_buffs_type &buffs,
- size_t offset_bytes,
- size_t total_samps,
- uhd::rx_metadata_t &metadata,
- uhd::convert::function_type &converter,
- double tick_rate,
- const vrt_unpacker_t &vrt_unpacker,
- const get_recv_buffs_t &get_recv_buffs,
- const handle_overflow_t &handle_overflow,
- size_t vrt_header_offset_words32,
- size_t chans_per_otw_buff
- ){
- metadata.error_code = uhd::rx_metadata_t::ERROR_CODE_NONE;
-
- //perform a receive if no rx data is waiting to be copied
- if (state.size_of_copy_buffs == 0){
- state.fragment_offset_in_samps = 0;
- if (not get_recv_buffs(state.managed_buffs)){
- metadata.error_code = uhd::rx_metadata_t::ERROR_CODE_TIMEOUT;
- return 0;
- }
- try{
- _recv1_helper(
- state, metadata, tick_rate,
- vrt_unpacker, handle_overflow,
- vrt_header_offset_words32
- );
- }catch(const std::exception &e){
- state.size_of_copy_buffs = 0; //reset copy buffs size
- std::cerr << "Error (recv): " << e.what() << std::endl;
- metadata.error_code = uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET;
- return 0;
- }
- }
- //defaults for the metadata when this is a fragment
- else{
- metadata.has_time_spec = false;
- metadata.start_of_burst = false;
- metadata.end_of_burst = false;
- }
-
- //extract the number of samples available to copy
- size_t bytes_per_item = OTW_BYTES_PER_SAMP;
- size_t nsamps_available = state.size_of_copy_buffs/bytes_per_item;
- size_t nsamps_to_copy = std::min(total_samps*chans_per_otw_buff, nsamps_available);
- size_t bytes_to_copy = nsamps_to_copy*bytes_per_item;
- size_t nsamps_to_copy_per_io_buff = nsamps_to_copy/chans_per_otw_buff;
-
- for (size_t i = 0; i < buffs.size(); i+=chans_per_otw_buff){
-
- //fill a vector with pointers to the io buffers
- for (size_t j = 0; j < chans_per_otw_buff; j++){
- state.io_buffs[j] = reinterpret_cast<boost::uint8_t *>(buffs[i+j]) + offset_bytes;
- }
-
- //copy-convert the samples from the recv buffer
- converter(state.copy_buffs[i], state.io_buffs, nsamps_to_copy_per_io_buff);
-
- //update the rx copy buffer to reflect the bytes copied
- state.copy_buffs[i] += bytes_to_copy;
- }
- //update the copy buffer's availability
- state.size_of_copy_buffs -= bytes_to_copy;
-
- //setup the fragment flags and offset
- metadata.more_fragments = state.size_of_copy_buffs != 0;
- metadata.fragment_offset = state.fragment_offset_in_samps;
- state.fragment_offset_in_samps += nsamps_to_copy; //set for next call
-
- return nsamps_to_copy_per_io_buff;
- }
-
- /*******************************************************************
- * Recv vrt packets and copy convert the samples into the buffer.
- ******************************************************************/
- static UHD_INLINE size_t recv(
- recv_state &state,
- const uhd::device::recv_buffs_type &buffs,
- const size_t total_num_samps,
- uhd::rx_metadata_t &metadata,
- uhd::device::recv_mode_t recv_mode,
- const uhd::io_type_t &io_type,
- const uhd::otw_type_t &otw_type,
- double tick_rate,
- const vrt_unpacker_t &vrt_unpacker,
- const get_recv_buffs_t &get_recv_buffs,
- const handle_overflow_t &handle_overflow = &handle_overflow_nop,
- size_t vrt_header_offset_words32 = 0,
- size_t chans_per_otw_buff = 1
- ){
- state.io_buffs.resize(chans_per_otw_buff);
-
- uhd::convert::function_type converter(
- uhd::convert::get_converter_otw_to_cpu(
- io_type, otw_type, 1, chans_per_otw_buff
- ));
-
- switch(recv_mode){
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::RECV_MODE_ONE_PACKET:{
- ////////////////////////////////////////////////////////////////
- return _recv1(
- state,
- buffs, 0,
- total_num_samps,
- metadata,
- converter,
- tick_rate,
- vrt_unpacker,
- get_recv_buffs,
- handle_overflow,
- vrt_header_offset_words32,
- chans_per_otw_buff
- );
- }
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::RECV_MODE_FULL_BUFF:{
- ////////////////////////////////////////////////////////////////
- size_t accum_num_samps = 0;
- uhd::rx_metadata_t tmp_md;
- while(accum_num_samps < total_num_samps){
- size_t num_samps = _recv1(
- state,
- buffs, accum_num_samps*io_type.size,
- total_num_samps - accum_num_samps,
- (accum_num_samps == 0)? metadata : tmp_md, //only the first metadata gets kept
- converter,
- tick_rate,
- vrt_unpacker,
- get_recv_buffs,
- handle_overflow,
- vrt_header_offset_words32,
- chans_per_otw_buff
- );
- if (num_samps == 0) break; //had a recv timeout or error, break loop
- accum_num_samps += num_samps;
- }
- return accum_num_samps;
- }
-
- default: throw std::runtime_error("unknown recv mode");
- }//switch(recv_mode)
- }
-
-/***********************************************************************
- * vrt packet handler for send
- **********************************************************************/
- typedef std::vector<uhd::transport::managed_send_buffer::sptr> managed_send_buffs_t;
- 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;
- 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),
- zero_buffs(width, &zeros),
- io_buffs(0) //resized later
- {
- /* NOP */
- }
- };
-
- /*******************************************************************
- * Pack a vrt header, copy-convert the data, and send it.
- * - helper function for vrt_packet_handler::send
- ******************************************************************/
- static UHD_INLINE size_t _send1(
- send_state &state,
- const uhd::device::send_buffs_type &buffs,
- const size_t offset_bytes,
- const size_t num_samps,
- uhd::transport::vrt::if_packet_info_t &if_packet_info,
- uhd::convert::function_type &converter,
- const vrt_packer_t &vrt_packer,
- const get_send_buffs_t &get_send_buffs,
- const size_t vrt_header_offset_words32,
- const size_t chans_per_otw_buff
- ){
- //load the rest of the if_packet_info in here
- if_packet_info.num_payload_words32 = (num_samps*chans_per_otw_buff*OTW_BYTES_PER_SAMP)/sizeof(boost::uint32_t);
- if_packet_info.packet_count = state.next_packet_seq;
-
- //get send buffers for each otw channel
- if (not get_send_buffs(state.managed_buffs)) return 0;
-
- for (size_t i = 0; i < buffs.size(); i+=chans_per_otw_buff){
- //calculate pointers with offsets to io and otw memory
- for (size_t j = 0; j < chans_per_otw_buff; j++){
- state.io_buffs[j] = reinterpret_cast<const boost::uint8_t *>(buffs[i+j]) + offset_bytes;
- }
- boost::uint32_t *otw_mem = state.managed_buffs[i]->cast<boost::uint32_t *>() + vrt_header_offset_words32;
-
- //pack metadata into a vrt header
- vrt_packer(otw_mem, if_packet_info);
- otw_mem += if_packet_info.num_header_words32;
-
- //copy-convert the samples into the send buffer
- converter(state.io_buffs, otw_mem, num_samps);
-
- //commit the samples to the zero-copy interface
- size_t num_bytes_total = (vrt_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t);
- state.managed_buffs[i]->commit(num_bytes_total);
- }
- state.next_packet_seq++; //increment sequence after commits
- return num_samps;
- }
-
- /*******************************************************************
- * Send vrt packets and copy convert the samples into the buffer.
- ******************************************************************/
- static UHD_INLINE size_t send(
- send_state &state,
- const uhd::device::send_buffs_type &buffs,
- const size_t total_num_samps,
- const uhd::tx_metadata_t &metadata,
- uhd::device::send_mode_t send_mode,
- const uhd::io_type_t &io_type,
- const uhd::otw_type_t &otw_type,
- double tick_rate,
- const vrt_packer_t &vrt_packer,
- const get_send_buffs_t &get_send_buffs,
- size_t max_samples_per_packet,
- size_t vrt_header_offset_words32 = 0,
- size_t chans_per_otw_buff = 1
- ){
- state.io_buffs.resize(chans_per_otw_buff);
-
- uhd::convert::function_type converter(
- uhd::convert::get_converter_cpu_to_otw(
- io_type, otw_type, chans_per_otw_buff, 1
- ));
-
- //translate the metadata to vrt if packet info
- uhd::transport::vrt::if_packet_info_t if_packet_info;
- if_packet_info.has_sid = false;
- if_packet_info.has_cid = false;
- if_packet_info.has_tlr = false;
- if_packet_info.tsi = boost::uint32_t(metadata.time_spec.get_full_secs());
- if_packet_info.tsf = boost::uint64_t(metadata.time_spec.get_tick_count(tick_rate));
-
- if (total_num_samps <= max_samples_per_packet) send_mode = uhd::device::SEND_MODE_ONE_PACKET;
- switch(send_mode){
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::SEND_MODE_ONE_PACKET:{
- ////////////////////////////////////////////////////////////////
-
- //fill in parts of the packet info overwrote in full buff mode
- if_packet_info.has_tsi = metadata.has_time_spec;
- if_packet_info.has_tsf = metadata.has_time_spec;
- if_packet_info.sob = metadata.start_of_burst;
- if_packet_info.eob = metadata.end_of_burst;
-
- return _send1(
- state,
- //TODO remove this code when sample counts of zero are supported by hardware
- (total_num_samps)?buffs : state.zero_buffs, 0,
- std::max<size_t>(1, std::min(total_num_samps, max_samples_per_packet)),
- if_packet_info,
- converter,
- vrt_packer,
- get_send_buffs,
- vrt_header_offset_words32,
- chans_per_otw_buff
- );
- }
-
- ////////////////////////////////////////////////////////////////
- case uhd::device::SEND_MODE_FULL_BUFF:{
- ////////////////////////////////////////////////////////////////
- size_t total_num_samps_sent = 0;
-
- //loop through the following fragment indexes
- while(total_num_samps_sent < total_num_samps){
-
- //calculate per-loop-iteration variables
- const size_t total_num_samps_unsent = total_num_samps - total_num_samps_sent;
- const bool first_fragment = (total_num_samps_sent == 0);
- const bool final_fragment = (total_num_samps_unsent <= max_samples_per_packet);
-
- //calculate new flags for the fragments
- if_packet_info.has_tsi = metadata.has_time_spec and first_fragment;
- if_packet_info.has_tsf = if_packet_info.has_tsi;
- if_packet_info.sob = metadata.start_of_burst and first_fragment;
- if_packet_info.eob = metadata.end_of_burst and final_fragment;
-
- //send the fragment with the helper function
- const size_t num_samps_sent = _send1(
- state,
- buffs, total_num_samps_sent*io_type.size,
- std::min(total_num_samps_unsent, max_samples_per_packet),
- if_packet_info,
- converter,
- vrt_packer,
- get_send_buffs,
- vrt_header_offset_words32,
- chans_per_otw_buff
- );
- total_num_samps_sent += num_samps_sent;
- if (num_samps_sent == 0) return total_num_samps_sent;
- }
- return total_num_samps_sent;
- }
-
- default: throw std::runtime_error("unknown send mode");
- }//switch(send_mode)
- }
-
-} //namespace vrt_packet_handler
-
-#endif /* INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP */
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt
index 281910735..80f4bf45e 100644
--- a/host/lib/usrp/CMakeLists.txt
+++ b/host/lib/usrp/CMakeLists.txt
@@ -37,4 +37,5 @@ INCLUDE_SUBDIRECTORY(dboard)
INCLUDE_SUBDIRECTORY(fx2)
INCLUDE_SUBDIRECTORY(usrp1)
INCLUDE_SUBDIRECTORY(usrp2)
+INCLUDE_SUBDIRECTORY(b100)
INCLUDE_SUBDIRECTORY(usrp_e100)
diff --git a/host/lib/usrp/b100/CMakeLists.txt b/host/lib/usrp/b100/CMakeLists.txt
new file mode 100644
index 000000000..e1618a49c
--- /dev/null
+++ b/host/lib/usrp/b100/CMakeLists.txt
@@ -0,0 +1,47 @@
+#
+# 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/>.
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+########################################################################
+# Conditionally configure the B100 support
+########################################################################
+LIBUHD_REGISTER_COMPONENT("B100" ENABLE_B100 ON "ENABLE_LIBUHD;ENABLE_USB" OFF)
+
+IF(ENABLE_B100)
+ LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/clock_ctrl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/clock_ctrl.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/codec_ctrl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/codec_ctrl.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/codec_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ctrl_packet.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/dboard_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/dboard_iface.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/dsp_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/io_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/mboard_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_ctrl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_ctrl.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_iface.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_iface.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_impl.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/b100_impl.hpp
+ )
+ENDIF(ENABLE_B100)
diff --git a/host/lib/usrp/b100/b100_ctrl.cpp b/host/lib/usrp/b100/b100_ctrl.cpp
new file mode 100644
index 000000000..4d4520e1e
--- /dev/null
+++ b/host/lib/usrp/b100/b100_ctrl.cpp
@@ -0,0 +1,245 @@
+//
+// 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 "../../transport/super_recv_packet_handler.hpp"
+#include "b100_ctrl.hpp"
+#include "b100_impl.hpp"
+#include <uhd/transport/usb_zero_copy.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/utils/thread_priority.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/types/serial.hpp>
+#include "ctrl_packet.hpp"
+#include <boost/thread.hpp>
+#include <uhd/exception.hpp>
+
+using namespace uhd::transport;
+using namespace uhd;
+
+bool b100_ctrl_debug = false;
+
+class b100_ctrl_impl : public b100_ctrl {
+public:
+ b100_ctrl_impl(uhd::transport::usb_zero_copy::sptr ctrl_transport) :
+ sync_ctrl_fifo(2),
+ async_msg_fifo(100),
+ _ctrl_transport(ctrl_transport),
+ _seq(0)
+ {
+ boost::barrier spawn_barrier(2);
+ viking_marauders.create_thread(boost::bind(&b100_ctrl_impl::viking_marauder_loop, this, boost::ref(spawn_barrier)));
+ spawn_barrier.wait();
+ }
+
+ int write(boost::uint32_t addr, const ctrl_data_t &data);
+ ctrl_data_t read(boost::uint32_t addr, size_t len);
+
+ ~b100_ctrl_impl(void) {
+ bbl_out_marauding = false;
+ viking_marauders.interrupt_all();
+ viking_marauders.join_all();
+ }
+
+ bool get_ctrl_data(ctrl_data_t &pkt_data, double timeout);
+ bool recv_async_msg(uhd::async_metadata_t &async_metadata, double timeout);
+
+private:
+ int send_pkt(boost::uint16_t *cmd);
+
+ //änd hërë wë gö ä-Vïkïng för äsynchronous control packets
+ void viking_marauder_loop(boost::barrier &);
+ bounded_buffer<ctrl_data_t> sync_ctrl_fifo;
+ bounded_buffer<async_metadata_t> async_msg_fifo;
+ boost::thread_group viking_marauders;
+ bool bbl_out_marauding;
+
+ uhd::transport::usb_zero_copy::sptr _ctrl_transport;
+ boost::uint8_t _seq;
+};
+
+/***********************************************************************
+ * helper functions for packing/unpacking control packets
+ **********************************************************************/
+void pack_ctrl_pkt(boost::uint16_t *pkt_buff,
+ const ctrl_pkt_t &pkt){
+ //first two bits are OP
+ //next six bits are CALLBACKS
+ //next 8 bits are SEQUENCE
+ //next 16 bits are LENGTH (16-bit word)
+ //next 32 bits are ADDRESS (16-bit word LSW)
+ //then DATA (28 16-bit words)
+ pkt_buff[0] = (boost::uint16_t(pkt.pkt_meta.op) << 14) | (boost::uint16_t(pkt.pkt_meta.callbacks) << 8) | pkt.pkt_meta.seq;
+ pkt_buff[1] = pkt.pkt_meta.len;
+ pkt_buff[2] = (pkt.pkt_meta.addr & 0x00000FFF);
+ pkt_buff[3] = 0x0000; //address high bits always 0 on this device
+
+ for(size_t i = 0; i < pkt.data.size(); i++) {
+ pkt_buff[4+i] = pkt.data[i];
+ }
+}
+
+void unpack_ctrl_pkt(const boost::uint16_t *pkt_buff,
+ ctrl_pkt_t &pkt){
+ pkt.pkt_meta.seq = pkt_buff[0] & 0xFF;
+ pkt.pkt_meta.op = CTRL_PKT_OP_READ; //really this is useless
+ pkt.pkt_meta.len = pkt_buff[1];
+ pkt.pkt_meta.callbacks = 0; //callbacks aren't implemented yet
+ pkt.pkt_meta.addr = pkt_buff[2] | boost::uint32_t(pkt_buff[3] << 16);
+
+ //let's check this so we don't go pushing 64K of crap onto the pkt
+ if(pkt.pkt_meta.len > CTRL_PACKET_DATA_LENGTH) {
+ throw uhd::runtime_error("Received control packet too long");
+ }
+
+ for(int i = 4; i < 4+pkt.pkt_meta.len; i++) pkt.data.push_back(pkt_buff[i]);
+}
+
+int b100_ctrl_impl::send_pkt(boost::uint16_t *cmd) {
+ managed_send_buffer::sptr sbuf = _ctrl_transport->get_send_buff();
+ if(!sbuf.get()) {
+ throw uhd::runtime_error("Control channel send error");
+ }
+
+ //FIXME there's a better way to do this
+ for(size_t i = 0; i < (CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)); i++) {
+ sbuf->cast<boost::uint16_t *>()[i] = cmd[i];
+ }
+ sbuf->commit(CTRL_PACKET_LENGTH); //fixed size transaction
+ return 0;
+}
+
+int b100_ctrl_impl::write(boost::uint32_t addr, const ctrl_data_t &data) {
+ UHD_ASSERT_THROW(data.size() <= (CTRL_PACKET_DATA_LENGTH / sizeof(boost::uint16_t)));
+ ctrl_pkt_t pkt;
+ pkt.data = data;
+ pkt.pkt_meta.op = CTRL_PKT_OP_WRITE;
+ pkt.pkt_meta.callbacks = 0;
+ pkt.pkt_meta.seq = _seq++;
+ pkt.pkt_meta.len = pkt.data.size();
+ pkt.pkt_meta.addr = addr;
+ boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)];
+
+ pack_ctrl_pkt(pkt_buff, pkt);
+ size_t result = send_pkt(pkt_buff);
+ return result;
+}
+
+ctrl_data_t b100_ctrl_impl::read(boost::uint32_t addr, size_t len) {
+ UHD_ASSERT_THROW(len <= (CTRL_PACKET_DATA_LENGTH / sizeof(boost::uint16_t)));
+
+ ctrl_pkt_t pkt;
+ pkt.pkt_meta.op = CTRL_PKT_OP_READ;
+ pkt.pkt_meta.callbacks = 0;
+ pkt.pkt_meta.seq = _seq++;
+ pkt.pkt_meta.len = len;
+ pkt.pkt_meta.addr = addr;
+ boost::uint16_t pkt_buff[CTRL_PACKET_LENGTH / sizeof(boost::uint16_t)];
+
+ pack_ctrl_pkt(pkt_buff, pkt);
+ send_pkt(pkt_buff);
+
+ //loop around waiting for the response to appear
+ while(!get_ctrl_data(pkt.data, 0.05));
+
+ return pkt.data;
+}
+
+/***********************************************************************
+ * Viking marauders go pillaging for asynchronous control packets in the
+ * control response endpoint. Sync packets go in sync_ctrl_fifo,
+ * async TX error messages go in async_msg_fifo. sync_ctrl_fifo should
+ * never have more than 1 message in it, since it's expected that we'll
+ * wait for a control operation to finish before starting another one.
+ **********************************************************************/
+void b100_ctrl_impl::viking_marauder_loop(boost::barrier &spawn_barrier) {
+ bbl_out_marauding = true;
+ spawn_barrier.wait();
+ set_thread_priority_safe();
+
+ while(bbl_out_marauding){
+ managed_recv_buffer::sptr rbuf = _ctrl_transport->get_recv_buff();
+ if(!rbuf.get()) continue; //that's ok, there are plenty of villages to pillage!
+ const boost::uint16_t *pkt_buf = rbuf->cast<const boost::uint16_t *>();
+
+ if(pkt_buf[0] >> 8 == CTRL_PACKET_HEADER_MAGIC) {
+ //so it's got a control packet header, let's parse it.
+ ctrl_pkt_t pkt;
+ unpack_ctrl_pkt(pkt_buf, pkt);
+
+ if(pkt.pkt_meta.seq != boost::uint8_t(_seq - 1)) {
+ throw uhd::runtime_error("Sequence error on control channel");
+ }
+ if(pkt.pkt_meta.len > (CTRL_PACKET_LENGTH - CTRL_PACKET_HEADER_LENGTH)) {
+ throw uhd::runtime_error("Control channel packet length too long");
+ }
+
+ //push it onto the queue
+ sync_ctrl_fifo.push_with_wait(pkt.data);
+ } else { //it's an async status pkt
+ //extract the vrt header packet info
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.num_packet_words32 = rbuf->size()/sizeof(boost::uint32_t);
+ const boost::uint32_t *vrt_hdr = rbuf->cast<const boost::uint32_t *>();
+ vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info);
+
+ if( if_packet_info.sid == 0
+ and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){
+ //fill in the async metadata
+ async_metadata_t metadata;
+ metadata.channel = 0;
+ metadata.has_time_spec = if_packet_info.has_tsi and if_packet_info.has_tsf;
+ metadata.time_spec = time_spec_t(
+ time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), 64e6 //FIXME get from clock_ctrl
+ );
+ metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
+ //print the famous U, and push the metadata into the message queue
+ if (metadata.event_code &
+ ( async_metadata_t::EVENT_CODE_UNDERFLOW
+ | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) )
+ UHD_MSG(fastpath) << "U";
+
+ if (metadata.event_code &
+ ( async_metadata_t::EVENT_CODE_SEQ_ERROR
+ | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) )
+ UHD_MSG(fastpath) << "S";
+
+ async_msg_fifo.push_with_pop_on_full(metadata);
+ continue;
+ }
+ throw uhd::runtime_error("Control: unknown async response");
+ }
+ }
+}
+
+bool b100_ctrl_impl::get_ctrl_data(ctrl_data_t &pkt_data, double timeout){
+ boost::this_thread::disable_interruption di; //disable because the wait can throw
+ return sync_ctrl_fifo.pop_with_timed_wait(pkt_data, timeout);
+}
+
+bool b100_ctrl_impl::recv_async_msg(uhd::async_metadata_t &async_metadata, double timeout) {
+ boost::this_thread::disable_interruption di; //disable because the wait can throw
+ return async_msg_fifo.pop_with_timed_wait(async_metadata, timeout);
+}
+
+/***********************************************************************
+ * Public make function for b100_ctrl interface
+ **********************************************************************/
+b100_ctrl::sptr b100_ctrl::make(uhd::transport::usb_zero_copy::sptr ctrl_transport){
+ return sptr(new b100_ctrl_impl(ctrl_transport));
+}
diff --git a/host/lib/usrp/b100/b100_ctrl.hpp b/host/lib/usrp/b100/b100_ctrl.hpp
new file mode 100644
index 000000000..ae706dbb4
--- /dev/null
+++ b/host/lib/usrp/b100/b100_ctrl.hpp
@@ -0,0 +1,69 @@
+//
+// 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_B100_CTRL_HPP
+#define INCLUDED_B100_CTRL_HPP
+
+#include <uhd/transport/bounded_buffer.hpp>
+#include <uhd/transport/usb_zero_copy.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/types/serial.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "ctrl_packet.hpp"
+#include <boost/thread.hpp>
+
+class b100_ctrl : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<b100_ctrl> sptr;
+
+ /*!
+ * Make a USRP control object from a data transport
+ * \param ctrl_transport a USB data transport
+ * \return a new b100 control object
+ */
+ static sptr make(uhd::transport::usb_zero_copy::sptr ctrl_transport);
+
+ /*!
+ * Write a byte vector to an FPGA register
+ * \param addr the FPGA register address
+ * \param bytes the data to write
+ * \return 0 on success, error code on failure
+ */
+ virtual int write(boost::uint32_t addr, const ctrl_data_t &data) = 0;
+
+ /*!
+ * Read a byte vector from an FPGA register (blocking read)
+ * \param addr the FPGA register address
+ * \param len the length of the read
+ * \return a vector of bytes from the register(s) in question
+ */
+ virtual ctrl_data_t read(boost::uint32_t addr, size_t len) = 0;
+
+ /*!
+ * Get a sync ctrl packet (blocking)
+ * \param the packet data buffer
+ * \param the timeout value
+ * \return true if it got something
+ */
+ virtual bool get_ctrl_data(ctrl_data_t &pkt_data, double timeout) = 0;
+
+ virtual bool recv_async_msg(uhd::async_metadata_t &async_metadata, double timeout) = 0;
+
+};
+
+#endif /* INCLUDED_B100_CTRL_HPP */
diff --git a/host/lib/usrp/b100/b100_iface.cpp b/host/lib/usrp/b100/b100_iface.cpp
new file mode 100644
index 000000000..17ea2e6ad
--- /dev/null
+++ b/host/lib/usrp/b100/b100_iface.cpp
@@ -0,0 +1,336 @@
+//
+// 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 "b100_iface.hpp"
+#include "usrp_commands.h"
+#include <uhd/exception.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <uhd/utils/msg.hpp>
+#include <boost/format.hpp>
+#include <iomanip>
+#include <iostream>
+
+//FOR TESTING ONLY
+#include "b100_regs.hpp"
+#include <boost/thread/thread.hpp>
+#include "usrp_i2c_addr.h"
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace uhd::transport;
+
+/***********************************************************************
+ * Constants
+ **********************************************************************/
+static const bool iface_debug = true;
+static const boost::uint16_t USRP_B_FW_COMPAT_NUM = 0x02;
+static const boost::uint16_t USRP_B_FPGA_COMPAT_NUM = 0x03;
+
+/***********************************************************************
+ * I2C + FX2 implementation wrapper
+ **********************************************************************/
+class b100_i2c_fx2_iface : public i2c_iface{
+public:
+ b100_i2c_fx2_iface(uhd::usrp::fx2_ctrl::sptr fx2_ctrl){
+ _fx2_ctrl = fx2_ctrl;
+ }
+
+ void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes)
+ {
+ UHD_ASSERT_THROW(bytes.size() < max_i2c_data_bytes);
+
+ unsigned char buff[max_i2c_data_bytes];
+ std::copy(bytes.begin(), bytes.end(), buff);
+
+ int ret = _fx2_ctrl->usrp_i2c_write(addr & 0xff,
+ buff,
+ bytes.size());
+
+ if (iface_debug && (ret < 0))
+ uhd::runtime_error("USRP: failed i2c write");
+ }
+
+ byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes)
+ {
+ UHD_ASSERT_THROW(num_bytes < max_i2c_data_bytes);
+
+ unsigned char buff[max_i2c_data_bytes];
+ int ret = _fx2_ctrl->usrp_i2c_read(addr & 0xff,
+ buff,
+ num_bytes);
+
+ if (iface_debug && ((ret < 0) || (unsigned)ret < (num_bytes)))
+ uhd::runtime_error("USRP: failed i2c read");
+
+ byte_vector_t out_bytes;
+ for (size_t i = 0; i < num_bytes; i++)
+ out_bytes.push_back(buff[i]);
+
+ return out_bytes;
+ }
+
+private:
+ static const size_t max_i2c_data_bytes = 64;
+ uhd::usrp::fx2_ctrl::sptr _fx2_ctrl;
+};
+
+/***********************************************************************
+ * USRP-E100 interface implementation
+ **********************************************************************/
+class b100_iface_impl : public b100_iface{
+public:
+ /*******************************************************************
+ * Structors
+ ******************************************************************/
+ b100_iface_impl(uhd::usrp::fx2_ctrl::sptr fx2_ctrl,
+ b100_ctrl::sptr fpga_ctrl) :
+ _fx2_i2c_iface(fx2_ctrl),
+ _fx2_ctrl(fx2_ctrl),
+ _fpga_ctrl(fpga_ctrl)
+ {
+ this->check_fw_compat();
+ if (fpga_ctrl.get() != NULL){
+ enable_gpif(1);
+ i2c_init();
+ this->check_fpga_compat();
+ }
+ mb_eeprom = mboard_eeprom_t(get_fx2_i2c_iface(), mboard_eeprom_t::MAP_B000);
+ }
+
+ void check_fw_compat(void){
+ unsigned char data[4]; //useless data buffer
+ const boost::uint16_t fw_compat_num = _fx2_ctrl->usrp_control_read(
+ VRQ_FW_COMPAT, 0, 0, data, sizeof(data)
+ );
+ if (fw_compat_num != USRP_B_FW_COMPAT_NUM){
+ throw uhd::runtime_error(str(boost::format(
+ "Expected firmware compatibility number 0x%x, but got 0x%x:\n"
+ "The firmware build is not compatible with the host code build."
+ ) % USRP_B_FW_COMPAT_NUM % fw_compat_num));
+ }
+ }
+
+ void check_fpga_compat(void){
+ const boost::uint16_t fpga_compat_num = this->peek16(B100_REG_MISC_COMPAT);
+ if (fpga_compat_num != USRP_B_FPGA_COMPAT_NUM){
+ 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_B_FPGA_COMPAT_NUM % fpga_compat_num));
+ }
+ }
+
+ ~b100_iface_impl(void)
+ {
+ /* NOP */
+ }
+
+ /*******************************************************************
+ * Peek and Poke
+ ******************************************************************/
+
+ void poke(boost::uint32_t addr, const ctrl_data_t &data) {
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+ _fpga_ctrl->write(addr, data);
+ }
+
+ ctrl_data_t peek(boost::uint32_t addr, size_t len) {
+ boost::mutex::scoped_lock lock(_ctrl_mutex);
+ return _fpga_ctrl->read(addr, len);
+ }
+
+ void poke16(boost::uint32_t addr, boost::uint16_t value)
+ {
+ ctrl_data_t words(1);
+ words[0] = value;
+ poke(addr, words);
+ }
+
+ void poke32(boost::uint32_t addr, boost::uint32_t value)
+ {
+ //just a subset of poke() to maintain compatibility
+ ctrl_data_t words(2);
+ words[0] = value & 0x0000FFFF;
+ words[1] = value >> 16;
+ poke(addr, words);
+ }
+
+ boost::uint32_t peek32(boost::uint32_t addr)
+ {
+ ctrl_data_t words = peek(addr, 2);
+ return boost::uint32_t((boost::uint32_t(words[1]) << 16) | words[0]);
+ }
+
+ boost::uint16_t peek16(boost::uint32_t addr)
+ {
+ ctrl_data_t words = peek(addr, 1);
+ return boost::uint16_t(words[0]);
+ }
+
+ /*******************************************************************
+ * I2C
+ ******************************************************************/
+ static const boost::uint32_t i2c_datarate = 400000;
+ static const boost::uint32_t wishbone_clk = 64000000; //FIXME should go somewhere else
+
+ void i2c_init(void) {
+ //init I2C FPGA interface.
+ poke16(B100_REG_I2C_CTRL, 0x0000);
+ //set prescalers to operate at 400kHz: WB_CLK is 64MHz...
+ boost::uint16_t prescaler = wishbone_clk / (i2c_datarate*5) - 1;
+ poke16(B100_REG_I2C_PRESCALER_LO, prescaler & 0xFF);
+ poke16(B100_REG_I2C_PRESCALER_HI, (prescaler >> 8) & 0xFF);
+ poke16(B100_REG_I2C_CTRL, I2C_CTRL_EN); //enable I2C core
+ }
+
+ static const size_t max_i2c_data_bytes = 64;
+
+ void i2c_wait_for_xfer(void)
+ {
+ while(this->peek16(B100_REG_I2C_CMD_STATUS) & I2C_ST_TIP)
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+ }
+
+ bool wait_chk_ack(void) {
+ i2c_wait_for_xfer();
+ return (this->peek16(B100_REG_I2C_CMD_STATUS) & I2C_ST_RXACK) == 0;
+ }
+
+ void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes)
+ {
+ poke16(B100_REG_I2C_DATA, (addr << 1) | 0); //addr and read bit (0)
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_WR | I2C_CMD_START | (bytes.size() == 0 ? I2C_CMD_STOP : 0));
+
+ //wait for previous transfer to complete
+ if(!wait_chk_ack()) {
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_STOP);
+ return;
+ }
+
+ for(size_t i = 0; i < bytes.size(); i++) {
+ poke16(B100_REG_I2C_DATA, bytes[i]);
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_WR | ((i == (bytes.size() - 1)) ? I2C_CMD_STOP : 0));
+ if(!wait_chk_ack()) {
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_STOP);
+ return;
+ }
+ }
+ }
+
+ byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes)
+ {
+ byte_vector_t bytes;
+ if(num_bytes == 0) return bytes;
+
+ while (peek16(B100_REG_I2C_CMD_STATUS) & I2C_ST_BUSY);
+
+ poke16(B100_REG_I2C_DATA, (addr << 1) | 1); //addr and read bit (1)
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_WR | I2C_CMD_START);
+ //wait for previous transfer to complete
+ if(!wait_chk_ack()) {
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_STOP);
+ }
+
+ for(; num_bytes > 0; num_bytes--) {
+ poke16(B100_REG_I2C_CMD_STATUS, I2C_CMD_RD | ((num_bytes == 1) ? (I2C_CMD_STOP | I2C_CMD_NACK) : 0));
+ i2c_wait_for_xfer();
+ boost::uint8_t readback = peek16(B100_REG_I2C_DATA) & 0xFF;
+ bytes.push_back(readback);
+ }
+ return bytes;
+ }
+
+ i2c_iface &get_fx2_i2c_iface(void){
+ return _fx2_i2c_iface;
+ }
+
+ /*******************************************************************
+ * SPI interface
+ * Eventually this will be replaced with a control-channel system
+ * to let the firmware do the actual write/readback cycles.
+ * This keeps the bandwidth on the control channel down.
+ ******************************************************************/
+
+ void spi_wait(void) {
+ while(peek32(B100_REG_SPI_CTRL) & SPI_CTRL_GO_BSY);
+ }
+
+ boost::uint32_t transact_spi(int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t bits,
+ size_t num_bits,
+ bool readback)
+ {
+ UHD_ASSERT_THROW((num_bits <= 32) && !(num_bits % 8));
+
+ int edge_flags = ((config.miso_edge==spi_config_t::EDGE_FALL) ? SPI_CTRL_RXNEG : 0) |
+ ((config.mosi_edge==spi_config_t::EDGE_FALL) ? 0 : SPI_CTRL_TXNEG)
+ ;
+
+ boost::uint16_t ctrl = SPI_CTRL_ASS | (SPI_CTRL_CHAR_LEN_MASK & num_bits) | edge_flags;
+
+ poke16(B100_REG_SPI_DIV, 0x0001); // = fpga_clk / 4
+ poke32(B100_REG_SPI_SS, which_slave & 0xFFFF);
+ poke32(B100_REG_SPI_TXRX0, bits);
+ poke16(B100_REG_SPI_CTRL, ctrl);
+
+ poke16(B100_REG_SPI_CTRL, ctrl | SPI_CTRL_GO_BSY);
+ if(readback) {
+ spi_wait();
+ return peek32(B100_REG_SPI_TXRX0);
+ }
+ else {
+ return 0;
+ }
+ }
+
+ void reset_gpif(boost::uint16_t ep) {
+ _fx2_ctrl->usrp_control_write(VRQ_RESET_GPIF, ep, ep, 0, 0);
+ }
+
+ void enable_gpif(bool en) {
+ _fx2_ctrl->usrp_control_write(VRQ_ENABLE_GPIF, en ? 1 : 0, 0, 0, 0);
+ }
+
+ void clear_fpga_fifo(void) {
+ _fx2_ctrl->usrp_control_write(VRQ_CLEAR_FPGA_FIFO, 0, 0, 0, 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()");
+ }
+
+private:
+ b100_i2c_fx2_iface _fx2_i2c_iface;
+ uhd::usrp::fx2_ctrl::sptr _fx2_ctrl;
+ b100_ctrl::sptr _fpga_ctrl;
+ boost::mutex _ctrl_mutex;
+};
+
+/***********************************************************************
+ * Public Make Function
+ **********************************************************************/
+b100_iface::sptr b100_iface::make(uhd::usrp::fx2_ctrl::sptr fx2_ctrl,
+ b100_ctrl::sptr fpga_ctrl)
+{
+ return b100_iface::sptr(new b100_iface_impl(fx2_ctrl, fpga_ctrl));
+}
diff --git a/host/lib/usrp/b100/b100_iface.hpp b/host/lib/usrp/b100/b100_iface.hpp
new file mode 100644
index 000000000..57ed6a45c
--- /dev/null
+++ b/host/lib/usrp/b100/b100_iface.hpp
@@ -0,0 +1,73 @@
+//
+// 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_B100_IFACE_HPP
+#define INCLUDED_B100_IFACE_HPP
+
+#include <uhd/usrp/mboard_iface.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <uhd/transport/usb_zero_copy.hpp>
+#include "../fx2/fx2_ctrl.hpp"
+#include "b100_ctrl.hpp"
+
+/*!
+ * The usrp1 interface class:
+ * Provides a set of functions to implementation layer.
+ * Including spi, peek, poke, control...
+ */
+class b100_iface : boost::noncopyable, public uhd::usrp::mboard_iface{
+public:
+ typedef boost::shared_ptr<b100_iface> sptr;
+
+ /*!
+ * Make a new b100 interface with the control transport.
+ * \param fx2_ctrl the usrp control object
+ * \param fpga_ctrl the FPGA interface control object
+ * \return a new usrp1 interface object
+ */
+ static sptr make(uhd::usrp::fx2_ctrl::sptr fx2_ctrl,
+ b100_ctrl::sptr fpga_ctrl = b100_ctrl::sptr()
+ );
+
+ /*!
+ * Reset the GPIF interface on the FX2
+ * \param which endpoint to reset
+ * \return
+ */
+ virtual void reset_gpif(boost::uint16_t ep) = 0;
+
+ /*!
+ * Clear the GPIF FIFOs on the FPGA
+ * \return
+ */
+ virtual void clear_fpga_fifo(void) = 0;
+
+ /*!
+ * Enable/disable the GPIF interfaces on the FX2
+ * \return
+ */
+ virtual void enable_gpif(bool en) = 0;
+
+ //! Get access to the FX2 I2C interface
+ virtual uhd::i2c_iface &get_fx2_i2c_iface(void) = 0;
+
+ uhd::usrp::mboard_eeprom_t mb_eeprom;
+};
+
+#endif /* INCLUDED_USRP1_IFACE_HPP */
diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp
new file mode 100644
index 000000000..7e733ddd9
--- /dev/null
+++ b/host/lib/usrp/b100/b100_impl.cpp
@@ -0,0 +1,280 @@
+//
+// 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 "b100_impl.hpp"
+#include "b100_ctrl.hpp"
+#include "fpga_regs_standard.h"
+#include "usrp_spi_defs.h"
+#include <uhd/transport/usb_control.hpp>
+#include "ctrl_packet.hpp"
+#include <uhd/usrp/device_props.hpp>
+#include <uhd/usrp/mboard_props.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/static.hpp>
+#include <uhd/utils/images.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <boost/format.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/lexical_cast.hpp>
+#include "b100_regs.hpp"
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace uhd::transport;
+
+const boost::uint16_t B100_VENDOR_ID = 0x2500;
+const boost::uint16_t B100_PRODUCT_ID = 0x0001;
+const boost::uint16_t FX2_VENDOR_ID = 0x04b4;
+const boost::uint16_t FX2_PRODUCT_ID = 0x8613;
+
+/***********************************************************************
+ * Discovery
+ **********************************************************************/
+static device_addrs_t b100_find(const device_addr_t &hint)
+{
+ device_addrs_t b100_addrs;
+
+ //return an empty list of addresses when type is set to non-b100
+ if (hint.has_key("type") and hint["type"] != "b100") return b100_addrs;
+
+ //Return an empty list of addresses when an address is specified,
+ //since an address is intended for a different, non-USB, device.
+ if (hint.has_key("addr")) return b100_addrs;
+
+ boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : B100_VENDOR_ID;
+ boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : B100_PRODUCT_ID;
+
+ // Important note:
+ // The get device list calls are nested inside the for loop.
+ // This allows the usb guts to decontruct when not in use,
+ // so that re-enumeration after fw load can occur successfully.
+ // This requirement is a courtesy of libusb1.0 on windows.
+
+ //find the usrps and load firmware
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
+ //extract the firmware path for the b100
+ std::string b100_fw_image;
+ try{
+ b100_fw_image = find_image_path(hint.get("fw", "usrp_b100_fw.ihx"));
+ }
+ catch(...){
+ UHD_MSG(warning) << boost::format(
+ "Could not locate B100 firmware.\n"
+ "Please install the images package.\n"
+ );
+ return b100_addrs;
+ }
+ UHD_LOG << "the firmware image: " << b100_fw_image << std::endl;
+
+ usb_control::sptr control;
+ try{control = usb_control::make(handle);}
+ catch(const uhd::exception &){continue;} //ignore claimed
+
+ fx2_ctrl::make(control)->usrp_load_firmware(b100_fw_image);
+ }
+
+ //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware
+ vid = B100_VENDOR_ID;
+ pid = B100_PRODUCT_ID;
+
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
+ device_addr_t new_addr;
+ new_addr["type"] = "b100";
+
+ //Attempt to read the name from the EEPROM and perform filtering.
+ //This operation can throw due to compatibility mismatch.
+ try{
+ usb_control::sptr control = usb_control::make(handle);
+ b100_iface::sptr iface = b100_iface::make(fx2_ctrl::make(control));
+ new_addr["name"] = iface->mb_eeprom["name"];
+ new_addr["serial"] = handle->get_serial();
+ }
+ catch(const uhd::exception &){
+ //set these values as empty string so the device may still be found
+ //and the filter's below can still operate on the discovered device
+ new_addr["name"] = "";
+ new_addr["serial"] = "";
+ }
+
+ //this is a found b100 when the hint serial and name match or blank
+ if (
+ (not hint.has_key("name") or hint["name"] == new_addr["name"]) and
+ (not hint.has_key("serial") or hint["serial"] == new_addr["serial"])
+ ){
+ b100_addrs.push_back(new_addr);
+ }
+ }
+
+ return b100_addrs;
+}
+
+/***********************************************************************
+ * Make
+ **********************************************************************/
+static device::sptr b100_make(const device_addr_t &device_addr){
+
+ //extract the FPGA path for the B100
+ std::string b100_fpga_image = find_image_path(
+ device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_b100_fpga.bin"
+ );
+
+ //try to match the given device address with something on the USB bus
+ std::vector<usb_device_handle::sptr> device_list =
+ usb_device_handle::get_device_list(B100_VENDOR_ID, B100_PRODUCT_ID);
+
+ //locate the matching handle in the device list
+ usb_device_handle::sptr handle;
+ BOOST_FOREACH(usb_device_handle::sptr dev_handle, device_list) {
+ if (dev_handle->get_serial() == device_addr["serial"]){
+ handle = dev_handle;
+ break;
+ }
+ }
+ UHD_ASSERT_THROW(handle.get() != NULL); //better be found
+
+ //create control objects and a data transport
+ usb_control::sptr fx2_transport = usb_control::make(handle);
+ fx2_ctrl::sptr fx2_ctrl = fx2_ctrl::make(fx2_transport);
+ fx2_ctrl->usrp_load_fpga(b100_fpga_image);
+
+ device_addr_t data_xport_args;
+ data_xport_args["recv_frame_size"] = device_addr.get("recv_frame_size", "16384");
+ data_xport_args["num_recv_frames"] = device_addr.get("num_recv_frames", "16");
+ data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", "16384");
+ data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16");
+
+ usb_zero_copy::sptr data_transport = usb_zero_copy::make_wrapper(
+ usb_zero_copy::make(
+ handle, // identifier
+ 6, // IN endpoint
+ 2, // OUT endpoint
+ data_xport_args // param hints
+ )
+ );
+
+ //create the control transport
+ device_addr_t ctrl_xport_args;
+ ctrl_xport_args["recv_frame_size"] = boost::lexical_cast<std::string>(CTRL_PACKET_LENGTH);
+ ctrl_xport_args["num_recv_frames"] = "16";
+ ctrl_xport_args["send_frame_size"] = boost::lexical_cast<std::string>(CTRL_PACKET_LENGTH);
+ ctrl_xport_args["num_send_frames"] = "4";
+
+ usb_zero_copy::sptr ctrl_transport = usb_zero_copy::make(
+ handle,
+ 8,
+ 4,
+ ctrl_xport_args
+ );
+
+ const double master_clock_rate = device_addr.cast<double>("master_clock_rate", 64e6);
+
+
+ //create the b100 implementation guts
+ return device::sptr(new b100_impl(data_transport, ctrl_transport, fx2_ctrl, master_clock_rate));
+}
+
+UHD_STATIC_BLOCK(register_b100_device){
+ device::register_device(&b100_find, &b100_make);
+}
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+b100_impl::b100_impl(uhd::transport::usb_zero_copy::sptr data_transport,
+ uhd::transport::usb_zero_copy::sptr ctrl_transport,
+ uhd::usrp::fx2_ctrl::sptr fx2_ctrl,
+ const double master_clock_rate)
+ : _data_transport(data_transport), _fx2_ctrl(fx2_ctrl)
+{
+ //this is the handler object for FPGA control packets
+ _fpga_ctrl = b100_ctrl::make(ctrl_transport);
+
+ _iface = b100_iface::make(_fx2_ctrl, _fpga_ctrl);
+
+ //create clock interface
+ _clock_ctrl = b100_clock_ctrl::make(_iface, master_clock_rate);
+
+ //create codec interface
+ _codec_ctrl = b100_codec_ctrl::make(_iface);
+
+ //initialize the codecs
+ codec_init();
+
+ //initialize the mboard
+ mboard_init();
+
+ //initialize the dboards
+ dboard_init();
+
+ //initialize the dsps
+ rx_ddc_init();
+
+ //initialize the dsps
+ tx_duc_init();
+
+ //init the subdev specs
+ this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t());
+ this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t());
+
+ //initialize the send/recv buffs
+ io_init();
+}
+
+b100_impl::~b100_impl(void){
+ /* NOP */
+}
+
+bool b100_impl::recv_async_msg(uhd::async_metadata_t &md, double timeout){
+ return _fpga_ctrl->recv_async_msg(md, timeout);
+}
+
+/***********************************************************************
+ * Device Get
+ **********************************************************************/
+void b100_impl::get(const wax::obj &key_, wax::obj &val)
+{
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<device_prop_t>()){
+ case DEVICE_PROP_NAME:
+ val = std::string("USRP-B100 device");
+ return;
+
+ case DEVICE_PROP_MBOARD:
+ UHD_ASSERT_THROW(key.name == "");
+ val = _mboard_proxy->get_link();
+ return;
+
+ case DEVICE_PROP_MBOARD_NAMES:
+ val = prop_names_t(1, ""); //vector of size 1 with empty string
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * Device Set
+ **********************************************************************/
+void b100_impl::set(const wax::obj &, const wax::obj &)
+{
+ UHD_THROW_PROP_SET_ERROR();
+}
diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp
new file mode 100644
index 000000000..daec70bca
--- /dev/null
+++ b/host/lib/usrp/b100/b100_impl.hpp
@@ -0,0 +1,204 @@
+//
+// 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 "b100_iface.hpp"
+#include "b100_ctrl.hpp"
+#include "clock_ctrl.hpp"
+#include "codec_ctrl.hpp"
+#include <uhd/device.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/types/otw_type.hpp>
+#include <uhd/types/clock_config.hpp>
+#include <uhd/types/stream_cmd.hpp>
+#include <uhd/usrp/dboard_id.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
+#include <uhd/usrp/dboard_eeprom.hpp>
+#include <uhd/usrp/dboard_manager.hpp>
+#include <uhd/transport/usb_zero_copy.hpp>
+
+#ifndef INCLUDED_B100_IMPL_HPP
+#define INCLUDED_B100_IMPL_HPP
+
+/*!
+ * Make a b100 dboard interface.
+ * \param iface the b100 interface object
+ * \param clock the clock control interface
+ * \param codec the codec control interface
+ * \return a sptr to a new dboard interface
+ */
+uhd::usrp::dboard_iface::sptr make_b100_dboard_iface(
+ b100_iface::sptr iface,
+ b100_clock_ctrl::sptr clock,
+ b100_codec_ctrl::sptr codec
+);
+
+/*!
+ * Simple wax obj proxy class:
+ * Provides a wax obj interface for a set and a get function.
+ * This allows us to create nested properties structures
+ * while maintaining flattened code within the implementation.
+ */
+class wax_obj_proxy : public wax::obj {
+public:
+ typedef boost::function<void(const wax::obj &, wax::obj &)> get_t;
+ typedef boost::function<void(const wax::obj &, const wax::obj &)> set_t;
+ typedef boost::shared_ptr<wax_obj_proxy> sptr;
+
+ static sptr make(const get_t &get, const set_t &set){
+ return sptr(new wax_obj_proxy(get, set));
+ }
+
+private:
+ get_t _get; set_t _set;
+ wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set) {};
+ void get(const wax::obj &key, wax::obj &val) {return _get(key, val);}
+ void set(const wax::obj &key, const wax::obj &val) {return _set(key, val);}
+};
+
+/*!
+ * USRP1 implementation guts:
+ * The implementation details are encapsulated here.
+ * Handles properties on the mboard, dboard, dsps...
+ */
+class b100_impl : public uhd::device {
+public:
+ //structors
+ b100_impl(uhd::transport::usb_zero_copy::sptr data_transport,
+ uhd::transport::usb_zero_copy::sptr ctrl_transport,
+ uhd::usrp::fx2_ctrl::sptr fx2_ctrl,
+ double master_clock_rate);
+
+ ~b100_impl(void);
+
+ //the io interface
+ size_t send(const send_buffs_type &,
+ size_t,
+ const uhd::tx_metadata_t &,
+ const uhd::io_type_t &,
+ send_mode_t, double);
+
+ size_t recv(const recv_buffs_type &,
+ size_t, uhd::rx_metadata_t &,
+ const uhd::io_type_t &,
+ recv_mode_t, double);
+
+ size_t get_max_send_samps_per_packet(void) const;
+
+ size_t get_max_recv_samps_per_packet(void) const;
+
+ bool recv_async_msg(uhd::async_metadata_t &, double);
+
+private:
+ //clock control
+ b100_clock_ctrl::sptr _clock_ctrl;
+
+ //interface to ioctls and file descriptor
+ b100_iface::sptr _iface;
+
+ //handle io stuff
+ uhd::transport::zero_copy_if::sptr _data_transport;
+ UHD_PIMPL_DECL(io_impl) _io_impl;
+ void update_transport_channel_mapping(void);
+ void io_init(void);
+ void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd);
+ void handle_overrun(size_t);
+
+ //otw types
+ uhd::otw_type_t _recv_otw_type;
+ uhd::otw_type_t _send_otw_type;
+
+ //configuration shadows
+ uhd::clock_config_t _clock_config;
+ uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;
+
+ //ad9862 codec control interface
+ b100_codec_ctrl::sptr _codec_ctrl;
+
+ //codec properties interfaces
+ void codec_init(void);
+ void rx_codec_get(const wax::obj &, wax::obj &);
+ void rx_codec_set(const wax::obj &, const wax::obj &);
+ void tx_codec_get(const wax::obj &, wax::obj &);
+ void tx_codec_set(const wax::obj &, const wax::obj &);
+ wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy;
+
+ //device functions and settings
+ void get(const wax::obj &, wax::obj &);
+ void set(const wax::obj &, const wax::obj &);
+
+ //mboard functions and settings
+ void mboard_init(void);
+ void mboard_get(const wax::obj &, wax::obj &);
+ void mboard_set(const wax::obj &, const wax::obj &);
+ void update_clock_config(void);
+ wax_obj_proxy::sptr _mboard_proxy;
+
+ /*!
+ * Make a usrp1 dboard interface.
+ * \param iface the usrp1 interface object
+ * \param clock the clock control interface
+ * \param codec the codec control interface
+ * \param dboard_slot the slot identifier
+ * \param rx_dboard_id the db id for the rx board (used for evil dbsrx purposes)
+ * \return a sptr to a new dboard interface
+ */
+ static uhd::usrp::dboard_iface::sptr make_dboard_iface(
+ b100_iface::sptr iface,
+ b100_clock_ctrl::sptr clock,
+ b100_codec_ctrl::sptr codec,
+ const uhd::usrp::dboard_id_t &rx_dboard_id
+ );
+
+ //xx dboard functions and settings
+ void dboard_init(void);
+ uhd::usrp::dboard_manager::sptr _dboard_manager;
+ uhd::usrp::dboard_iface::sptr _dboard_iface;
+
+ //rx dboard functions and settings
+ uhd::usrp::dboard_eeprom_t _rx_db_eeprom;
+ void rx_dboard_get(const wax::obj &, wax::obj &);
+ void rx_dboard_set(const wax::obj &, const wax::obj &);
+ wax_obj_proxy::sptr _rx_dboard_proxy;
+
+ //tx dboard functions and settings
+ uhd::usrp::dboard_eeprom_t _tx_db_eeprom, _gdb_eeprom;
+ void tx_dboard_get(const wax::obj &, wax::obj &);
+ void tx_dboard_set(const wax::obj &, const wax::obj &);
+ wax_obj_proxy::sptr _tx_dboard_proxy;
+
+ //rx ddc functions and settings
+ void rx_ddc_init(void);
+ void rx_ddc_get(const wax::obj &, wax::obj &);
+ void rx_ddc_set(const wax::obj &, const wax::obj &);
+ double _ddc_freq; size_t _ddc_decim;
+ wax_obj_proxy::sptr _rx_ddc_proxy;
+
+ //tx duc functions and settings
+ void tx_duc_init(void);
+ void tx_duc_get(const wax::obj &, wax::obj &);
+ void tx_duc_set(const wax::obj &, const wax::obj &);
+ double _duc_freq; size_t _duc_interp;
+ wax_obj_proxy::sptr _tx_duc_proxy;
+
+ //transports
+ b100_ctrl::sptr _fpga_ctrl;
+ uhd::usrp::fx2_ctrl::sptr _fx2_ctrl;
+
+};
+
+#endif /* INCLUDED_b100_IMPL_HPP */
diff --git a/host/lib/usrp/b100/b100_regs.hpp b/host/lib/usrp/b100/b100_regs.hpp
new file mode 100644
index 000000000..010df283e
--- /dev/null
+++ b/host/lib/usrp/b100/b100_regs.hpp
@@ -0,0 +1,264 @@
+
+
+////////////////////////////////////////////////////////////////
+//
+// Memory map for wishbone bus
+//
+////////////////////////////////////////////////////////////////
+
+// All addresses are byte addresses. All accesses are word (16-bit) accesses.
+// This means that address bit 0 is usually 0.
+// There are 11 bits of address for the control.
+
+#ifndef __B100_REGS_H
+#define __B100_REGS_H
+
+/////////////////////////////////////////////////////
+// Slave pointers
+
+#define B100_REG_SLAVE(n) ((n)<<7)
+#define B100_REG_SR_ADDR(n) ((B100_REG_SETTINGS_BASE) + (4*(n)))
+
+/////////////////////////////////////////////////////
+// Slave 0 -- Misc Regs
+
+#define B100_REG_MISC_BASE B100_REG_SLAVE(0)
+
+#define B100_REG_MISC_LED B100_REG_MISC_BASE + 0
+#define B100_REG_MISC_SW B100_REG_MISC_BASE + 2
+#define B100_REG_MISC_CGEN_CTRL B100_REG_MISC_BASE + 4
+#define B100_REG_MISC_CGEN_ST B100_REG_MISC_BASE + 6
+#define B100_REG_MISC_TEST B100_REG_MISC_BASE + 8
+#define B100_REG_MISC_RX_LEN B100_REG_MISC_BASE + 10
+#define B100_REG_MISC_TX_LEN B100_REG_MISC_BASE + 12
+#define B100_REG_MISC_XFER_RATE B100_REG_MISC_BASE + 14
+#define B100_REG_MISC_COMPAT B100_REG_MISC_BASE + 16
+
+/////////////////////////////////////////////////////
+// Slave 1 -- UART
+// CLKDIV is 16 bits, others are only 8
+
+#define B100_REG_UART_BASE B100_REG_SLAVE(1)
+
+#define B100_REG_UART_CLKDIV B100_REG_UART_BASE + 0
+#define B100_REG_UART_TXLEVEL B100_REG_UART_BASE + 2
+#define B100_REG_UART_RXLEVEL B100_REG_UART_BASE + 4
+#define B100_REG_UART_TXCHAR B100_REG_UART_BASE + 6
+#define B100_REG_UART_RXCHAR B100_REG_UART_BASE + 8
+
+/////////////////////////////////////////////////////
+// Slave 2 -- SPI Core
+//these are 32-bit registers mapped onto the 16-bit Wishbone bus.
+//Using peek32/poke32 should allow transparent use of these registers.
+#define B100_REG_SPI_BASE B100_REG_SLAVE(2)
+#define B100_REG_SPI_TXRX0 B100_REG_SPI_BASE + 0
+#define B100_REG_SPI_TXRX1 B100_REG_SPI_BASE + 4
+#define B100_REG_SPI_TXRX2 B100_REG_SPI_BASE + 8
+#define B100_REG_SPI_TXRX3 B100_REG_SPI_BASE + 12
+#define B100_REG_SPI_CTRL B100_REG_SPI_BASE + 16
+#define B100_REG_SPI_DIV B100_REG_SPI_BASE + 20
+#define B100_REG_SPI_SS B100_REG_SPI_BASE + 24
+
+//spi slave constants
+#define B100_SPI_SS_AD9862 (1 << 2)
+#define B100_SPI_SS_TX_DB (1 << 1)
+#define B100_SPI_SS_RX_DB (1 << 0)
+
+//spi ctrl register bit definitions
+#define SPI_CTRL_ASS (1<<13)
+#define SPI_CTRL_IE (1<<12)
+#define SPI_CTRL_LSB (1<<11)
+#define SPI_CTRL_TXNEG (1<<10) //mosi edge, push on falling edge when 1
+#define SPI_CTRL_RXNEG (1<< 9) //miso edge, latch on falling edge when 1
+#define SPI_CTRL_GO_BSY (1<< 8)
+#define SPI_CTRL_CHAR_LEN_MASK 0x7F
+
+////////////////////////////////////////////////
+// Slave 3 -- I2C Core
+
+#define B100_REG_I2C_BASE B100_REG_SLAVE(3)
+#define B100_REG_I2C_PRESCALER_LO B100_REG_I2C_BASE + 0
+#define B100_REG_I2C_PRESCALER_HI B100_REG_I2C_BASE + 2
+#define B100_REG_I2C_CTRL B100_REG_I2C_BASE + 4
+#define B100_REG_I2C_DATA B100_REG_I2C_BASE + 6
+#define B100_REG_I2C_CMD_STATUS B100_REG_I2C_BASE + 8
+
+//and while we're here...
+
+//
+// STA, STO, RD, WR, and IACK bits are cleared automatically
+//
+
+#define I2C_CTRL_EN (1 << 7) // core enable
+#define I2C_CTRL_IE (1 << 6) // interrupt enable
+
+#define I2C_CMD_START (1 << 7) // generate (repeated) start condition
+#define I2C_CMD_STOP (1 << 6) // generate stop condition
+#define I2C_CMD_RD (1 << 5) // read from slave
+#define I2C_CMD_WR (1 << 4) // write to slave
+#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1)
+#define I2C_CMD_RSVD_2 (1 << 2) // reserved
+#define I2C_CMD_RSVD_1 (1 << 1) // reserved
+#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt
+
+#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK)
+#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected
+#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration
+#define I2C_ST_RSVD_4 (1 << 4) // reserved
+#define I2C_ST_RSVD_3 (1 << 3) // reserved
+#define I2C_ST_RSVD_2 (1 << 2) // reserved
+#define I2C_ST_TIP (1 << 1) // Transfer-in-progress
+#define I2C_ST_IP (1 << 0) // Interrupt pending
+
+////////////////////////////////////////////////
+// Slave 4 -- GPIO
+
+#define B100_REG_GPIO_BASE B100_REG_SLAVE(4)
+
+#define B100_REG_GPIO_RX_IO B100_REG_GPIO_BASE + 0
+#define B100_REG_GPIO_TX_IO B100_REG_GPIO_BASE + 2
+#define B100_REG_GPIO_RX_DDR B100_REG_GPIO_BASE + 4
+#define B100_REG_GPIO_TX_DDR B100_REG_GPIO_BASE + 6
+#define B100_REG_GPIO_RX_SEL B100_REG_GPIO_BASE + 8
+#define B100_REG_GPIO_TX_SEL B100_REG_GPIO_BASE + 10
+#define B100_REG_GPIO_RX_DBG B100_REG_GPIO_BASE + 12
+#define B100_REG_GPIO_TX_DBG B100_REG_GPIO_BASE + 14
+
+//possible bit values for sel when dbg is 0:
+#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg
+#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic
+
+//possible bit values for sel when dbg is 1:
+#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric
+#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric
+
+///////////////////////////////////////////////////
+// Slave 6 -- ATR Controller
+// 16 regs
+
+#define B100_REG_ATR_BASE B100_REG_SLAVE(6)
+
+#define B100_REG_ATR_IDLE_RXSIDE B100_REG_ATR_BASE + 0
+#define B100_REG_ATR_IDLE_TXSIDE B100_REG_ATR_BASE + 2
+#define B100_REG_ATR_INTX_RXSIDE B100_REG_ATR_BASE + 4
+#define B100_REG_ATR_INTX_TXSIDE B100_REG_ATR_BASE + 6
+#define B100_REG_ATR_INRX_RXSIDE B100_REG_ATR_BASE + 8
+#define B100_REG_ATR_INRX_TXSIDE B100_REG_ATR_BASE + 10
+#define B100_REG_ATR_FULL_RXSIDE B100_REG_ATR_BASE + 12
+#define B100_REG_ATR_FULL_TXSIDE B100_REG_ATR_BASE + 14
+
+///////////////////////////////////////////////////
+// Slave 7 -- Readback Mux 32
+
+#define B100_REG_RB_MUX_32_BASE B100_REG_SLAVE(7)
+
+#define B100_REG_RB_TIME_NOW_SECS B100_REG_RB_MUX_32_BASE + 0
+#define B100_REG_RB_TIME_NOW_TICKS B100_REG_RB_MUX_32_BASE + 4
+#define B100_REG_RB_TIME_PPS_SECS B100_REG_RB_MUX_32_BASE + 8
+#define B100_REG_RB_TIME_PPS_TICKS B100_REG_RB_MUX_32_BASE + 12
+#define B100_REG_RB_MISC_TEST32 B100_REG_RB_MUX_32_BASE + 16
+
+////////////////////////////////////////////////////
+// Slaves 8 & 9 -- Settings Bus
+//
+// Output-only, no readback, 64 registers total
+// Each register must be written 32 bits at a time
+// First the address xxx_xx00 and then xxx_xx10
+
+#define B100_REG_SETTINGS_BASE_ADDR(n) (B100_REG_SLAVE(8) + (4*(n)))
+
+#define B100_REG_SR_MISC_TEST32 B100_REG_SETTINGS_BASE_ADDR(52)
+
+/////////////////////////////////////////////////
+// DSP RX Regs
+////////////////////////////////////////////////
+#define B100_REG_DSP_RX_ADDR(n) (B100_REG_SETTINGS_BASE_ADDR(16) + (4*(n)))
+#define B100_REG_DSP_RX_FREQ B100_REG_DSP_RX_ADDR(0)
+#define B100_REG_DSP_RX_SCALE_IQ B100_REG_DSP_RX_ADDR(1) // {scale_i,scale_q}
+#define B100_REG_DSP_RX_DECIM_RATE B100_REG_DSP_RX_ADDR(2) // hb and decim rate
+#define B100_REG_DSP_RX_DCOFFSET_I B100_REG_DSP_RX_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic
+#define B100_REG_DSP_RX_DCOFFSET_Q B100_REG_DSP_RX_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits
+#define B100_REG_DSP_RX_MUX B100_REG_DSP_RX_ADDR(5)
+
+///////////////////////////////////////////////////
+// VITA RX CTRL regs
+///////////////////////////////////////////////////
+// The following 3 are logically a single command register.
+// They are clocked into the underlying fifo when time_ticks is written.
+#define B100_REG_CTRL_RX_ADDR(n) (B100_REG_SETTINGS_BASE_ADDR(0) + (4*(n)))
+#define B100_REG_CTRL_RX_STREAM_CMD B100_REG_CTRL_RX_ADDR(0) // {now, chain, num_samples(30)
+#define B100_REG_CTRL_RX_TIME_SECS B100_REG_CTRL_RX_ADDR(1)
+#define B100_REG_CTRL_RX_TIME_TICKS B100_REG_CTRL_RX_ADDR(2)
+#define B100_REG_CTRL_RX_CLEAR_OVERRUN B100_REG_CTRL_RX_ADDR(3) // write anything to clear overrun
+#define B100_REG_CTRL_RX_VRT_HEADER B100_REG_CTRL_RX_ADDR(4) // word 0 of packet. FPGA fills in packet counter
+#define B100_REG_CTRL_RX_VRT_STREAM_ID B100_REG_CTRL_RX_ADDR(5) // word 1 of packet.
+#define B100_REG_CTRL_RX_VRT_TRAILER B100_REG_CTRL_RX_ADDR(6)
+#define B100_REG_CTRL_RX_NSAMPS_PER_PKT B100_REG_CTRL_RX_ADDR(7)
+#define B100_REG_CTRL_RX_NCHANNELS B100_REG_CTRL_RX_ADDR(8) // 1 in basic case, up to 4 for vector sources
+
+/////////////////////////////////////////////////
+// DSP TX Regs
+////////////////////////////////////////////////
+#define B100_REG_DSP_TX_ADDR(n) (B100_REG_SETTINGS_BASE_ADDR(32) + (4*(n)))
+#define B100_REG_DSP_TX_FREQ B100_REG_DSP_TX_ADDR(0)
+#define B100_REG_DSP_TX_SCALE_IQ B100_REG_DSP_TX_ADDR(1) // {scale_i,scale_q}
+#define B100_REG_DSP_TX_INTERP_RATE B100_REG_DSP_TX_ADDR(2)
+#define B100_REG_DSP_TX_UNUSED B100_REG_DSP_TX_ADDR(3)
+#define B100_REG_DSP_TX_MUX B100_REG_DSP_TX_ADDR(4)
+
+/////////////////////////////////////////////////
+// VITA TX CTRL regs
+////////////////////////////////////////////////
+#define B100_REG_CTRL_TX_ADDR(n) (B100_REG_SETTINGS_BASE_ADDR(24) + (4*(n)))
+#define B100_REG_CTRL_TX_NCHANNELS B100_REG_CTRL_TX_ADDR(0)
+#define B100_REG_CTRL_TX_CLEAR_UNDERRUN B100_REG_CTRL_TX_ADDR(1)
+#define B100_REG_CTRL_TX_REPORT_SID B100_REG_CTRL_TX_ADDR(2)
+#define B100_REG_CTRL_TX_POLICY B100_REG_CTRL_TX_ADDR(3)
+
+#define B100_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0)
+#define B100_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1)
+#define B100_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2)
+
+/////////////////////////////////////////////////
+// VITA49 64 bit time (write only)
+////////////////////////////////////////////////
+ /*!
+ * \brief Time 64 flags
+ *
+ * <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
+ * +-----------------------------------------------------------+-+-+
+ * | |S|P|
+ * +-----------------------------------------------------------+-+-+
+ *
+ * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+ * S - Source (0=sma, 1=mimo, 0=default)
+ *
+ * </pre>
+ */
+#define B100_REG_TIME64_ADDR(n) (B100_REG_SETTINGS_BASE_ADDR(40) + (4*(n)))
+#define B100_REG_TIME64_SECS B100_REG_TIME64_ADDR(0) // value to set absolute secs to on next PPS
+#define B100_REG_TIME64_TICKS B100_REG_TIME64_ADDR(1) // value to set absolute ticks to on next PPS
+#define B100_REG_TIME64_FLAGS B100_REG_TIME64_ADDR(2) // flags - see chart above
+#define B100_REG_TIME64_IMM B100_REG_TIME64_ADDR(3) // set immediate (0=latch on next pps, 1=latch immediate, default=0)
+#define B100_REG_TIME64_TPS B100_REG_TIME64_ADDR(4) // clock ticks per second (counter rollover)
+
+//pps flags (see above)
+#define B100_FLAG_TIME64_PPS_NEGEDGE (0 << 0)
+#define B100_FLAG_TIME64_PPS_POSEDGE (1 << 0)
+#define B100_FLAG_TIME64_PPS_SMA (0 << 1)
+#define B100_FLAG_TIME64_PPS_MIMO (1 << 1)
+
+#define B100_FLAG_TIME64_LATCH_NOW 1
+#define B100_FLAG_TIME64_LATCH_NEXT_PPS 0
+
+#define B100_REG_CLEAR_RX_FIFO B100_REG_SETTINGS_BASE_ADDR(48)
+#define B100_REG_CLEAR_TX_FIFO B100_REG_SETTINGS_BASE_ADDR(49)
+
+#define B100_REG_GLOBAL_RESET B100_REG_SETTINGS_BASE_ADDR(50)
+#define B100_REG_TEST32 B100_REG_SETTINGS_BASE_ADDR(52)
+
+#endif
+
diff --git a/host/lib/usrp/b100/clock_ctrl.cpp b/host/lib/usrp/b100/clock_ctrl.cpp
new file mode 100644
index 000000000..e138242d1
--- /dev/null
+++ b/host/lib/usrp/b100/clock_ctrl.cpp
@@ -0,0 +1,525 @@
+//
+// 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/>.
+//
+
+#include "clock_ctrl.hpp"
+#include "ad9522_regs.hpp"
+#include <uhd/utils/log.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/assert_has.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <boost/cstdint.hpp>
+#include "b100_regs.hpp" //spi slave constants
+#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/math/common_factor_rt.hpp> //gcd
+#include <algorithm>
+#include <utility>
+
+using namespace uhd;
+
+/***********************************************************************
+ * Constants
+ **********************************************************************/
+static const bool ENABLE_THE_TEST_OUT = true;
+static const double REFERENCE_INPUT_RATE = 10e6;
+
+/***********************************************************************
+ * Helpers
+ **********************************************************************/
+template <typename div_type, typename bypass_type> static void set_clock_divider(
+ size_t divider, div_type &low, div_type &high, bypass_type &bypass
+){
+ high = divider/2 - 1;
+ low = divider - high - 2;
+ bypass = (divider == 1)? 1 : 0;
+}
+
+/***********************************************************************
+ * Clock rate calculation stuff:
+ * Using the internal VCO between 1400 and 1800 MHz
+ **********************************************************************/
+struct clock_settings_type{
+ size_t ref_clock_doubler, r_counter, a_counter, b_counter, prescaler, vco_divider, chan_divider;
+ size_t get_n_counter(void) const{return prescaler * b_counter + a_counter;}
+ double get_ref_rate(void) const{return REFERENCE_INPUT_RATE * ref_clock_doubler;}
+ double get_vco_rate(void) const{return get_ref_rate()/r_counter * get_n_counter();}
+ double get_chan_rate(void) const{return get_vco_rate()/vco_divider;}
+ double get_out_rate(void) const{return get_chan_rate()/chan_divider;}
+ std::string to_pp_string(void) const{
+ return str(boost::format(
+ " r_counter: %d\n"
+ " a_counter: %d\n"
+ " b_counter: %d\n"
+ " prescaler: %d\n"
+ " vco_divider: %d\n"
+ " chan_divider: %d\n"
+ " vco_rate: %fMHz\n"
+ " chan_rate: %fMHz\n"
+ " out_rate: %fMHz\n"
+ )
+ % r_counter
+ % a_counter
+ % b_counter
+ % prescaler
+ % vco_divider
+ % chan_divider
+ % (get_vco_rate()/1e6)
+ % (get_chan_rate()/1e6)
+ % (get_out_rate()/1e6)
+ );
+ }
+};
+
+//! gives the greatest divisor of num between 1 and max inclusive
+template<typename T> static inline T greatest_divisor(T num, T max){
+ for (T i = max; i > 1; i--) if (num%i == 0) return i; return 1;
+}
+
+//! gives the least divisor of num between min and num exclusive
+template<typename T> static inline T least_divisor(T num, T min){
+ for (T i = min; i < num; i++) if (num%i == 0) return i; return 1;
+}
+
+static clock_settings_type get_clock_settings(double rate){
+ clock_settings_type cs;
+ cs.ref_clock_doubler = 2; //always doubling
+ cs.prescaler = 8; //set to 8 when input is under 2400 MHz
+
+ //basic formulas used below:
+ //out_rate*X = ref_rate*Y
+ //X = i*ref_rate/gcd
+ //Y = i*out_rate/gcd
+ //X = chan_div * vco_div * R
+ //Y = P*B + A
+
+ const boost::uint64_t out_rate = boost::uint64_t(rate);
+ const boost::uint64_t ref_rate = boost::uint64_t(cs.get_ref_rate());
+ const size_t gcd = size_t(boost::math::gcd(ref_rate, out_rate));
+
+ for (size_t i = 1; i <= 100; i++){
+ const size_t X = i*ref_rate/gcd;
+ const size_t Y = i*out_rate/gcd;
+
+ //determine A and B (P is fixed)
+ cs.b_counter = Y/cs.prescaler;
+ cs.a_counter = Y - cs.b_counter*cs.prescaler;
+
+ static const double vco_bound_pad = 100e6;
+ for ( //calculate an r divider that fits into the bounds of the vco
+ cs.r_counter = size_t(cs.get_n_counter()*cs.get_ref_rate()/(1800e6 - vco_bound_pad));
+ cs.r_counter <= size_t(cs.get_n_counter()*cs.get_ref_rate()/(1400e6 + vco_bound_pad))
+ and cs.r_counter > 0; cs.r_counter++
+ ){
+
+ //determine chan_div and vco_div
+ //and fill in that order of preference
+ cs.chan_divider = greatest_divisor<size_t>(X/cs.r_counter, 32);
+ cs.vco_divider = greatest_divisor<size_t>(X/cs.chan_divider/cs.r_counter, 6);
+
+ //avoid a vco divider of 1 (if possible)
+ if (cs.vco_divider == 1){
+ cs.vco_divider = least_divisor<size_t>(cs.chan_divider, 2);
+ cs.chan_divider /= cs.vco_divider;
+ }
+
+ UHD_LOGV(always)
+ << "gcd " << gcd << std::endl
+ << "X " << X << std::endl
+ << "Y " << Y << std::endl
+ << cs.to_pp_string() << std::endl
+ ;
+
+ //filter limits on the counters
+ if (cs.vco_divider == 1) continue;
+ if (cs.r_counter >= (1<<14)) continue;
+ if (cs.b_counter == 2) continue;
+ if (cs.b_counter == 1 and cs.a_counter != 0) continue;
+ if (cs.b_counter >= (1<<13)) continue;
+ if (cs.a_counter >= (1<<6)) continue;
+
+ UHD_MSG(status) << "USRP-B100 clock control: " << i << std::endl << cs.to_pp_string() << std::endl;
+ return cs;
+ }
+ }
+
+ throw uhd::runtime_error(str(boost::format(
+ "USRP-B100 clock control: could not calculate settings for clock rate %fMHz"
+ ) % (rate/1e6)));
+}
+
+/***********************************************************************
+ * Clock Control Implementation
+ **********************************************************************/
+class b100_clock_ctrl_impl : public b100_clock_ctrl{
+public:
+ b100_clock_ctrl_impl(b100_iface::sptr iface, double master_clock_rate){
+ _iface = iface;
+ _chan_rate = 0.0;
+ _out_rate = 0.0;
+
+ //init the clock gen registers
+ _ad9522_regs.sdo_active = ad9522_regs_t::SDO_ACTIVE_SDO_SDIO;
+ _ad9522_regs.enb_stat_eeprom_at_stat_pin = 0; //use status pin
+ _ad9522_regs.status_pin_control = 0x1; //n divider
+ _ad9522_regs.ld_pin_control = 0x00; //dld
+ _ad9522_regs.refmon_pin_control = 0x12; //show ref2
+ _ad9522_regs.lock_detect_counter = ad9522_regs_t::LOCK_DETECT_COUNTER_16CYC;
+
+ this->use_internal_ref();
+
+ this->set_fpga_clock_rate(master_clock_rate); //initialize to something
+
+ this->enable_fpga_clock(true);
+ this->enable_test_clock(ENABLE_THE_TEST_OUT);
+ this->enable_rx_dboard_clock(false);
+ this->enable_tx_dboard_clock(false);
+ }
+
+ ~b100_clock_ctrl_impl(void){
+ UHD_SAFE_CALL(
+ this->enable_test_clock(ENABLE_THE_TEST_OUT);
+ this->enable_rx_dboard_clock(false);
+ this->enable_tx_dboard_clock(false);
+ //this->enable_fpga_clock(false); //FIXME
+ )
+ }
+
+ /***********************************************************************
+ * Clock rate control:
+ * - set clock rate w/ internal VCO
+ * - set clock rate w/ external VCXO
+ **********************************************************************/
+ void set_clock_settings_with_internal_vco(double rate){
+ const clock_settings_type cs = get_clock_settings(rate);
+
+ //set the rates to private variables so the implementation knows!
+ _chan_rate = cs.get_chan_rate();
+ _out_rate = cs.get_out_rate();
+
+ _ad9522_regs.enable_clock_doubler = (cs.ref_clock_doubler == 2)? 1 : 0;
+
+ _ad9522_regs.set_r_counter(cs.r_counter);
+ _ad9522_regs.a_counter = cs.a_counter;
+ _ad9522_regs.set_b_counter(cs.b_counter);
+ UHD_ASSERT_THROW(cs.prescaler == 8); //assumes this below:
+ _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV8_9;
+
+ _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL;
+ _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA;
+
+ _ad9522_regs.bypass_vco_divider = 0;
+ switch(cs.vco_divider){
+ case 1: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV1; break;
+ case 2: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV2; break;
+ case 3: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV3; break;
+ case 4: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV4; break;
+ case 5: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; break;
+ case 6: _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV6; break;
+ }
+ _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO;
+
+ //setup fpga master clock
+ _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS;
+ set_clock_divider(cs.chan_divider,
+ _ad9522_regs.divider0_low_cycles,
+ _ad9522_regs.divider0_high_cycles,
+ _ad9522_regs.divider0_bypass
+ );
+
+ //setup codec clock
+ _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS;
+ set_clock_divider(cs.chan_divider,
+ _ad9522_regs.divider1_low_cycles,
+ _ad9522_regs.divider1_high_cycles,
+ _ad9522_regs.divider1_bypass
+ );
+
+ this->send_all_regs();
+ calibrate_now();
+ }
+
+ void set_clock_settings_with_external_vcxo(double rate){
+ //set the rates to private variables so the implementation knows!
+ _chan_rate = rate;
+ _out_rate = rate;
+
+ _ad9522_regs.enable_clock_doubler = 1; //doubler always on
+ const double ref_rate = REFERENCE_INPUT_RATE*2;
+
+ //bypass prescaler such that N = B
+ long gcd = boost::math::gcd(long(ref_rate), long(rate));
+ _ad9522_regs.set_r_counter(int(ref_rate/gcd));
+ _ad9522_regs.a_counter = 0;
+ _ad9522_regs.set_b_counter(int(rate/gcd));
+ _ad9522_regs.prescaler_p = ad9522_regs_t::PRESCALER_P_DIV1;
+
+ //setup external vcxo
+ _ad9522_regs.pll_power_down = ad9522_regs_t::PLL_POWER_DOWN_NORMAL;
+ _ad9522_regs.cp_current = ad9522_regs_t::CP_CURRENT_1_2MA;
+ _ad9522_regs.bypass_vco_divider = 1;
+ _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_EXTERNAL;
+
+ //setup fpga master clock
+ _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS;
+ _ad9522_regs.divider0_bypass = 1;
+
+ //setup codec clock
+ _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS;
+ _ad9522_regs.divider1_bypass = 1;
+
+ this->send_all_regs();
+ }
+
+ void set_fpga_clock_rate(double rate){
+ if (_out_rate == rate) return;
+ if (rate == 61.44e6) set_clock_settings_with_external_vcxo(rate);
+ else set_clock_settings_with_internal_vco(rate);
+ //clock rate changed! update dboard clocks and FPGA ticks per second
+ set_rx_dboard_clock_rate(rate);
+ set_tx_dboard_clock_rate(rate);
+ _iface->poke32(B100_REG_TIME64_TPS, boost::uint32_t(get_fpga_clock_rate()));
+ }
+
+ double get_fpga_clock_rate(void){
+ return this->_out_rate;
+ }
+
+ /***********************************************************************
+ * FPGA clock enable
+ **********************************************************************/
+ void enable_fpga_clock(bool enb){
+ _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS;
+ _ad9522_regs.out0_lvds_power_down = !enb;
+ this->send_reg(0x0F0);
+ this->latch_regs();
+ }
+
+ /***********************************************************************
+ * Special test clock output
+ **********************************************************************/
+ void enable_test_clock(bool enb){
+ //setup test clock (same divider as codec clock)
+ _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS;
+ _ad9522_regs.out4_cmos_configuration = (enb)?
+ ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON :
+ ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF;
+ this->send_reg(0x0F4);
+ this->latch_regs();
+ }
+
+ /***********************************************************************
+ * RX Dboard Clock Control (output 9, divider 3)
+ **********************************************************************/
+ void enable_rx_dboard_clock(bool enb){
+ _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS;
+ _ad9522_regs.out9_cmos_configuration = (enb)?
+ ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON :
+ ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF;
+ this->send_reg(0x0F9);
+ this->latch_regs();
+ }
+
+ std::vector<double> get_rx_dboard_clock_rates(void){
+ std::vector<double> rates;
+ for(size_t div = 1; div <= 16+16; div++)
+ rates.push_back(this->_chan_rate/div);
+ return rates;
+ }
+
+ void set_rx_dboard_clock_rate(double rate){
+ assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate");
+ _rx_clock_rate = rate;
+ size_t divider = size_t(this->_chan_rate/rate);
+ //set the divider registers
+ set_clock_divider(divider,
+ _ad9522_regs.divider3_low_cycles,
+ _ad9522_regs.divider3_high_cycles,
+ _ad9522_regs.divider3_bypass
+ );
+ this->send_reg(0x199);
+ this->send_reg(0x19a);
+ this->soft_sync();
+ }
+
+ double get_rx_clock_rate(void){
+ return _rx_clock_rate;
+ }
+
+ /***********************************************************************
+ * TX Dboard Clock Control (output 6, divider 2)
+ **********************************************************************/
+ void enable_tx_dboard_clock(bool enb){
+ _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS;
+ _ad9522_regs.out6_cmos_configuration = (enb)?
+ ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON :
+ ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF;
+ this->send_reg(0x0F6);
+ this->latch_regs();
+ }
+
+ std::vector<double> get_tx_dboard_clock_rates(void){
+ return get_rx_dboard_clock_rates(); //same master clock, same dividers...
+ }
+
+ void set_tx_dboard_clock_rate(double rate){
+ assert_has(get_tx_dboard_clock_rates(), rate, "tx dboard clock rate");
+ _tx_clock_rate = rate;
+ size_t divider = size_t(this->_chan_rate/rate);
+ //set the divider registers
+ set_clock_divider(divider,
+ _ad9522_regs.divider2_low_cycles,
+ _ad9522_regs.divider2_high_cycles,
+ _ad9522_regs.divider2_bypass
+ );
+ this->send_reg(0x196);
+ this->send_reg(0x197);
+ this->soft_sync();
+ }
+
+ double get_tx_clock_rate(void){
+ return _tx_clock_rate;
+ }
+
+ /***********************************************************************
+ * Clock reference control
+ **********************************************************************/
+ void use_internal_ref(void) {
+ _ad9522_regs.enable_ref2 = 1;
+ _ad9522_regs.enable_ref1 = 0;
+ _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF2;
+ _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL;
+ this->send_reg(0x01C);
+ this->latch_regs();
+ }
+
+ void use_external_ref(void) {
+ _ad9522_regs.enable_ref2 = 0;
+ _ad9522_regs.enable_ref1 = 1;
+ _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1;
+ _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_MANUAL;
+ this->send_reg(0x01C);
+ this->latch_regs();
+ }
+
+ void use_auto_ref(void) {
+ _ad9522_regs.enable_ref2 = 1;
+ _ad9522_regs.enable_ref1 = 1;
+ _ad9522_regs.select_ref = ad9522_regs_t::SELECT_REF_REF1;
+ _ad9522_regs.enb_auto_ref_switchover = ad9522_regs_t::ENB_AUTO_REF_SWITCHOVER_AUTO;
+ this->send_reg(0x01C);
+ this->latch_regs();
+ }
+
+private:
+ b100_iface::sptr _iface;
+ ad9522_regs_t _ad9522_regs;
+ double _out_rate; //rate at the fpga and codec
+ double _chan_rate; //rate before final dividers
+ double _rx_clock_rate, _tx_clock_rate;
+
+ void latch_regs(void){
+ _ad9522_regs.io_update = 1;
+ this->send_reg(0x232);
+ }
+
+ void send_reg(boost::uint16_t addr){
+ boost::uint32_t reg = _ad9522_regs.get_write_reg(addr);
+ UHD_LOGV(often) << "clock control write reg: " << std::hex << reg << std::endl;
+ byte_vector_t buf;
+ buf.push_back(boost::uint8_t(reg >> 16));
+ buf.push_back(boost::uint8_t(reg >> 8));
+ buf.push_back(boost::uint8_t(reg & 0xff));
+
+ _iface->get_fx2_i2c_iface().write_i2c(0x5C, buf);
+ }
+
+ boost::uint8_t read_reg(boost::uint16_t addr){
+ byte_vector_t buf;
+ buf.push_back(boost::uint8_t(addr >> 8));
+ buf.push_back(boost::uint8_t(addr & 0xff));
+ _iface->get_fx2_i2c_iface().write_i2c(0x5C, buf);
+
+ buf = _iface->get_fx2_i2c_iface().read_i2c(0x5C, 1);
+
+ return boost::uint32_t(buf[0] & 0xFF);
+ }
+
+ void calibrate_now(void){
+ //vco calibration routine:
+ _ad9522_regs.vco_calibration_now = 0;
+ this->send_reg(0x18);
+ this->latch_regs();
+ _ad9522_regs.vco_calibration_now = 1;
+ this->send_reg(0x18);
+ this->latch_regs();
+ //wait for calibration done:
+ static const boost::uint8_t addr = 0x01F;
+ for (size_t ms10 = 0; ms10 < 100; ms10++){
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+ boost::uint32_t reg = read_reg(addr);
+ _ad9522_regs.set_reg(addr, reg);
+ if (_ad9522_regs.vco_calibration_finished) goto wait_for_ld;
+ }
+ UHD_MSG(error) << "USRP-B100 clock control: VCO calibration timeout" << std::endl;
+ wait_for_ld:
+ //wait for digital lock detect:
+ for (size_t ms10 = 0; ms10 < 100; ms10++){
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+ boost::uint32_t reg = read_reg(addr);
+ _ad9522_regs.set_reg(addr, reg);
+ if (_ad9522_regs.digital_lock_detect) return;
+ }
+ UHD_MSG(error) << "USRP-B100 clock control: lock detection timeout" << std::endl;
+ }
+
+ void soft_sync(void){
+ _ad9522_regs.soft_sync = 1;
+ this->send_reg(0x230);
+ this->latch_regs();
+ _ad9522_regs.soft_sync = 0;
+ this->send_reg(0x230);
+ this->latch_regs();
+ }
+
+ void send_all_regs(void){
+ //setup a list of register ranges to write
+ typedef std::pair<boost::uint16_t, boost::uint16_t> range_t;
+ static const std::vector<range_t> ranges = boost::assign::list_of
+ (range_t(0x000, 0x000)) (range_t(0x010, 0x01F))
+ (range_t(0x0F0, 0x0FD)) (range_t(0x190, 0x19B))
+ (range_t(0x1E0, 0x1E1)) (range_t(0x230, 0x230))
+ ;
+
+ //write initial register values and latch/update
+ BOOST_FOREACH(const range_t &range, ranges){
+ for(boost::uint16_t addr = range.first; addr <= range.second; addr++){
+ this->send_reg(addr);
+ }
+ }
+ this->latch_regs();
+ }
+};
+
+/***********************************************************************
+ * Clock Control Make
+ **********************************************************************/
+b100_clock_ctrl::sptr b100_clock_ctrl::make(b100_iface::sptr iface, double master_clock_rate){
+ return sptr(new b100_clock_ctrl_impl(iface, master_clock_rate));
+}
diff --git a/host/lib/usrp/b100/clock_ctrl.hpp b/host/lib/usrp/b100/clock_ctrl.hpp
new file mode 100644
index 000000000..2a2e74024
--- /dev/null
+++ b/host/lib/usrp/b100/clock_ctrl.hpp
@@ -0,0 +1,118 @@
+//
+// 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_B100_CLOCK_CTRL_HPP
+#define INCLUDED_B100_CLOCK_CTRL_HPP
+
+#include "b100_iface.hpp"
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <vector>
+
+/*!
+ * The usrp-e clock control:
+ * - Setup system clocks.
+ * - Disable/enable clock lines.
+ */
+class b100_clock_ctrl : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<b100_clock_ctrl> sptr;
+
+ /*!
+ * Make a new clock control object.
+ * \param iface the b100 iface object
+ * \param master_clock_rate the master FPGA/sample clock rate
+ * \return the clock control object
+ */
+ static sptr make(b100_iface::sptr iface, double master_clock_rate);
+
+ /*!
+ * Set the rate of the fpga clock line.
+ * Throws if rate is not valid.
+ * \param rate the new rate in Hz
+ */
+ virtual void set_fpga_clock_rate(double rate) = 0;
+
+ /*!
+ * Get the rate of the fpga clock line.
+ * \return the fpga clock rate in Hz
+ */
+ virtual double get_fpga_clock_rate(void) = 0;
+
+ /*!
+ * Get the possible rates of the rx dboard clock.
+ * \return a vector of clock rates in Hz
+ */
+ virtual std::vector<double> get_rx_dboard_clock_rates(void) = 0;
+
+ /*!
+ * Get the possible rates of the tx dboard clock.
+ * \return a vector of clock rates in Hz
+ */
+ virtual std::vector<double> get_tx_dboard_clock_rates(void) = 0;
+
+ /*!
+ * Set the rx dboard clock rate to a possible rate.
+ * \param rate the new clock rate in Hz
+ * \throw exception when rate cannot be achieved
+ */
+ virtual void set_rx_dboard_clock_rate(double rate) = 0;
+
+ /*!
+ * Set the tx dboard clock rate to a possible rate.
+ * \param rate the new clock rate in Hz
+ * \throw exception when rate cannot be achieved
+ */
+ virtual void set_tx_dboard_clock_rate(double rate) = 0;
+
+ /*!
+ * Enable/disable the FPGA clock.
+ * \param enb true to enable
+ */
+
+ virtual void enable_fpga_clock(bool enb) = 0;
+
+ /*!
+ * Enable/disable the rx dboard clock.
+ * \param enb true to enable
+ */
+ virtual void enable_rx_dboard_clock(bool enb) = 0;
+
+ /*!
+ * Enable/disable the tx dboard clock.
+ * \param enb true to enable
+ */
+ virtual void enable_tx_dboard_clock(bool enb) = 0;
+
+ /*!
+ * Use the internal TCXO reference
+ */
+ virtual void use_internal_ref(void) = 0;
+
+ /*!
+ * Use the external SMA reference
+ */
+ virtual void use_external_ref(void) = 0;
+
+ /*!
+ * Use external if available, internal otherwise
+ */
+ virtual void use_auto_ref(void) = 0;
+
+};
+
+#endif /* INCLUDED_B100_CLOCK_CTRL_HPP */
diff --git a/host/lib/usrp/b100/codec_ctrl.cpp b/host/lib/usrp/b100/codec_ctrl.cpp
new file mode 100644
index 000000000..4d118b68b
--- /dev/null
+++ b/host/lib/usrp/b100/codec_ctrl.cpp
@@ -0,0 +1,283 @@
+//
+// 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 "codec_ctrl.hpp"
+#include "ad9862_regs.hpp"
+#include <uhd/types/dict.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/log.hpp>
+#include <uhd/utils/safe_call.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include "b100_regs.hpp" //spi slave constants
+#include <boost/assign/list_of.hpp>
+
+using namespace uhd;
+
+const gain_range_t b100_codec_ctrl::tx_pga_gain_range(-20, 0, double(0.1));
+const gain_range_t b100_codec_ctrl::rx_pga_gain_range(0, 20, 1);
+
+/***********************************************************************
+ * Codec Control Implementation
+ **********************************************************************/
+class b100_codec_ctrl_impl : public b100_codec_ctrl{
+public:
+ //structors
+ b100_codec_ctrl_impl(b100_iface::sptr iface);
+ ~b100_codec_ctrl_impl(void);
+
+ //aux adc and dac control
+ double read_aux_adc(aux_adc_t which);
+ void write_aux_dac(aux_dac_t which, double volts);
+
+ //pga gain control
+ void set_tx_pga_gain(double);
+ double get_tx_pga_gain(void);
+ void set_rx_pga_gain(double, char);
+ double get_rx_pga_gain(char);
+
+private:
+ b100_iface::sptr _iface;
+ ad9862_regs_t _ad9862_regs;
+ void send_reg(boost::uint8_t addr);
+ void recv_reg(boost::uint8_t addr);
+};
+
+/***********************************************************************
+ * Codec Control Structors
+ **********************************************************************/
+b100_codec_ctrl_impl::b100_codec_ctrl_impl(b100_iface::sptr iface){
+ _iface = iface;
+
+ //soft reset
+ _ad9862_regs.soft_reset = 1;
+ this->send_reg(0);
+
+ //initialize the codec register settings
+ _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO;
+ _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB;
+ _ad9862_regs.soft_reset = 0;
+
+ //setup rx side of codec
+ _ad9862_regs.byp_buffer_a = 1;
+ _ad9862_regs.byp_buffer_b = 1;
+ _ad9862_regs.buffer_a_pd = 1;
+ _ad9862_regs.buffer_b_pd = 1;
+ _ad9862_regs.mux_out = ad9862_regs_t::MUX_OUT_RX_MUX_MODE; //B100 uses interleaved RX->FPGA
+ _ad9862_regs.rx_pga_a = 0;//0x1f; //TODO bring under api control
+ _ad9862_regs.rx_pga_b = 0;//0x1f; //TODO bring under api control
+ _ad9862_regs.rx_twos_comp = 1;
+ _ad9862_regs.rx_hilbert = ad9862_regs_t::RX_HILBERT_DIS;
+
+ //setup tx side of codec
+ _ad9862_regs.two_data_paths = ad9862_regs_t::TWO_DATA_PATHS_BOTH;
+ _ad9862_regs.interleaved = ad9862_regs_t::INTERLEAVED_INTERLEAVED;
+ _ad9862_regs.tx_retime = ad9862_regs_t::TX_RETIME_CLKOUT2;
+ _ad9862_regs.tx_pga_gain = 199; //TODO bring under api control
+ _ad9862_regs.tx_hilbert = ad9862_regs_t::TX_HILBERT_DIS;
+ _ad9862_regs.interp = ad9862_regs_t::INTERP_2;
+ _ad9862_regs.tx_twos_comp = 1;
+ _ad9862_regs.fine_mode = ad9862_regs_t::FINE_MODE_BYPASS;
+ _ad9862_regs.coarse_mod = ad9862_regs_t::COARSE_MOD_BYPASS;
+ _ad9862_regs.dac_a_coarse_gain = 0x3;
+ _ad9862_regs.dac_b_coarse_gain = 0x3;
+ _ad9862_regs.edges = ad9862_regs_t::EDGES_NORMAL;
+
+ //setup the dll
+ _ad9862_regs.input_clk_ctrl = ad9862_regs_t::INPUT_CLK_CTRL_EXTERNAL;
+ _ad9862_regs.dll_mult = ad9862_regs_t::DLL_MULT_2;
+ _ad9862_regs.dll_mode = ad9862_regs_t::DLL_MODE_FAST;
+
+ //write the register settings to the codec
+ for (uint8_t addr = 0; addr <= 25; addr++){
+ this->send_reg(addr);
+ }
+
+ //always start conversions for aux ADC
+ _ad9862_regs.start_a = 1;
+ _ad9862_regs.start_b = 1;
+
+ //aux adc clock
+ _ad9862_regs.clk_4 = ad9862_regs_t::CLK_4_1_4;
+ this->send_reg(34);
+}
+
+b100_codec_ctrl_impl::~b100_codec_ctrl_impl(void){
+ UHD_SAFE_CALL(
+ //set aux dacs to zero
+ this->write_aux_dac(AUX_DAC_A, 0);
+ this->write_aux_dac(AUX_DAC_B, 0);
+ this->write_aux_dac(AUX_DAC_C, 0);
+ this->write_aux_dac(AUX_DAC_D, 0);
+
+ //power down
+ _ad9862_regs.all_rx_pd = 1;
+ this->send_reg(1);
+ _ad9862_regs.tx_digital_pd = 1;
+ _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH;
+ this->send_reg(8);
+ )
+}
+
+/***********************************************************************
+ * Codec Control Gain Control Methods
+ **********************************************************************/
+static const int mtpgw = 255; //maximum tx pga gain word
+
+void b100_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 = uhd::clip(gain_word, 0, mtpgw);
+ this->send_reg(16);
+}
+
+double b100_codec_ctrl_impl::get_tx_pga_gain(void){
+ return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start();
+}
+
+static const int mrpgw = 0x14; //maximum rx pga gain word
+
+void b100_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 = uhd::clip(gain_word, 0, mrpgw);
+ switch(which){
+ case 'A':
+ _ad9862_regs.rx_pga_a = gain_word;
+ this->send_reg(2);
+ return;
+ case 'B':
+ _ad9862_regs.rx_pga_b = gain_word;
+ this->send_reg(3);
+ return;
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
+}
+
+double b100_codec_ctrl_impl::get_rx_pga_gain(char which){
+ int gain_word;
+ switch(which){
+ case 'A': gain_word = _ad9862_regs.rx_pga_a; break;
+ case 'B': gain_word = _ad9862_regs.rx_pga_b; break;
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
+ return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start();
+}
+
+/***********************************************************************
+ * Codec Control AUX ADC Methods
+ **********************************************************************/
+static double aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){
+ return double((boost::uint16_t(high) << 2) | low)*3.3/0x3ff;
+}
+
+double b100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){
+ switch(which){
+
+ case AUX_ADC_A1:
+ _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1;
+ this->send_reg(34); //start conversion and select mux
+ this->recv_reg(28); //read the value (2 bytes, 2 reads)
+ this->recv_reg(29);
+ return aux_adc_to_volts(_ad9862_regs.aux_adc_a1_9_2, _ad9862_regs.aux_adc_a1_1_0);
+ case AUX_ADC_A2:
+ _ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC2;
+ this->send_reg(34); //start conversion and select mux
+ this->recv_reg(26); //read the value (2 bytes, 2 reads)
+ this->recv_reg(27);
+ return aux_adc_to_volts(_ad9862_regs.aux_adc_a2_9_2, _ad9862_regs.aux_adc_a2_1_0);
+
+ case AUX_ADC_B1:
+ _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC1;
+ this->send_reg(34); //start conversion and select mux
+ this->recv_reg(32); //read the value (2 bytes, 2 reads)
+ this->recv_reg(33);
+ return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0);
+ case AUX_ADC_B2:
+ _ad9862_regs.select_b = ad9862_regs_t::SELECT_B_AUX_ADC2;
+ this->send_reg(34); //start conversion and select mux
+ this->recv_reg(30); //read the value (2 bytes, 2 reads)
+ this->recv_reg(31);
+ return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0);
+ }
+ UHD_THROW_INVALID_CODE_PATH();
+}
+
+/***********************************************************************
+ * Codec Control AUX DAC Methods
+ **********************************************************************/
+void b100_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 = 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);
+ this->send_reg(43);
+ return;
+ }
+
+ //calculate the dac word for aux dac a, b, c
+ 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;
+ uhd::dict<aux_dac_t, dac_params_t> aux_dac_to_params = boost::assign::map_list_of
+ (AUX_DAC_A, dac_params_t(&_ad9862_regs.aux_dac_a, 36))
+ (AUX_DAC_B, dac_params_t(&_ad9862_regs.aux_dac_b, 37))
+ (AUX_DAC_C, dac_params_t(&_ad9862_regs.aux_dac_c, 38))
+ ;
+
+ //set the aux dac register
+ UHD_ASSERT_THROW(aux_dac_to_params.has_key(which));
+ boost::uint8_t *reg_ref, reg_addr;
+ boost::tie(reg_ref, reg_addr) = aux_dac_to_params[which];
+ *reg_ref = dac_word;
+ this->send_reg(reg_addr);
+}
+
+/***********************************************************************
+ * Codec Control SPI Methods
+ **********************************************************************/
+void b100_codec_ctrl_impl::send_reg(boost::uint8_t addr){
+ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr);
+ UHD_LOGV(rarely) << "codec control write reg: " << std::hex << reg << std::endl;
+ _iface->transact_spi(
+ B100_SPI_SS_AD9862,
+ spi_config_t::EDGE_RISE,
+ reg, 16, false /*no rb*/
+ );
+}
+
+void b100_codec_ctrl_impl::recv_reg(boost::uint8_t addr){
+ boost::uint32_t reg = _ad9862_regs.get_read_reg(addr);
+ UHD_LOGV(rarely) << "codec control read reg: " << std::hex << reg << std::endl;
+ boost::uint32_t ret = _iface->transact_spi(
+ B100_SPI_SS_AD9862,
+ spi_config_t::EDGE_RISE,
+ reg, 16, true /*rb*/
+ );
+ UHD_LOGV(rarely) << "codec control read ret: " << std::hex << boost::uint16_t(ret & 0xFF) << std::endl;
+ _ad9862_regs.set_reg(addr, boost::uint8_t(ret&0xff));
+}
+
+/***********************************************************************
+ * Codec Control Make
+ **********************************************************************/
+b100_codec_ctrl::sptr b100_codec_ctrl::make(b100_iface::sptr iface){
+ return sptr(new b100_codec_ctrl_impl(iface));
+}
diff --git a/host/lib/usrp/b100/codec_ctrl.hpp b/host/lib/usrp/b100/codec_ctrl.hpp
new file mode 100644
index 000000000..1bd579190
--- /dev/null
+++ b/host/lib/usrp/b100/codec_ctrl.hpp
@@ -0,0 +1,90 @@
+//
+// 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_B100_CODEC_CTRL_HPP
+#define INCLUDED_B100_CODEC_CTRL_HPP
+
+#include "b100_iface.hpp"
+#include <uhd/types/ranges.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+
+/*!
+ * The usrp-e codec control:
+ * - Init/power down codec.
+ * - Read aux adc, write aux dac.
+ */
+class b100_codec_ctrl : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<b100_codec_ctrl> sptr;
+
+ static const uhd::gain_range_t tx_pga_gain_range;
+ static const uhd::gain_range_t rx_pga_gain_range;
+
+ /*!
+ * Make a new codec control object.
+ * \param iface the usrp_e iface object
+ * \return the codec control object
+ */
+ static sptr make(b100_iface::sptr iface);
+
+ //! aux adc identifier constants
+ enum aux_adc_t{
+ AUX_ADC_A2 = 0xA2,
+ AUX_ADC_A1 = 0xA1,
+ AUX_ADC_B2 = 0xB2,
+ AUX_ADC_B1 = 0xB1
+ };
+
+ /*!
+ * Read an auxiliary adc:
+ * The internals remember which aux adc was read last.
+ * Therefore, the aux adc switch is only changed as needed.
+ * \param which which of the 4 adcs
+ * \return a value in volts
+ */
+ virtual double read_aux_adc(aux_adc_t which) = 0;
+
+ //! aux dac identifier constants
+ enum aux_dac_t{
+ AUX_DAC_A = 0xA,
+ AUX_DAC_B = 0xB,
+ AUX_DAC_C = 0xC,
+ AUX_DAC_D = 0xD //really the sigma delta output
+ };
+
+ /*!
+ * Write an auxiliary dac.
+ * \param which which of the 4 dacs
+ * \param volts the level in in volts
+ */
+ virtual void write_aux_dac(aux_dac_t which, double volts) = 0;
+
+ //! Set the TX PGA gain
+ virtual void set_tx_pga_gain(double gain) = 0;
+
+ //! Get the TX PGA gain
+ virtual double get_tx_pga_gain(void) = 0;
+
+ //! Set the RX PGA gain ('A' or 'B')
+ virtual void set_rx_pga_gain(double gain, char which) = 0;
+
+ //! Get the RX PGA gain ('A' or 'B')
+ virtual double get_rx_pga_gain(char which) = 0;
+};
+
+#endif /* INCLUDED_B100_CODEC_CTRL_HPP */
diff --git a/host/lib/usrp/b100/codec_impl.cpp b/host/lib/usrp/b100/codec_impl.cpp
new file mode 100644
index 000000000..de3ca3a66
--- /dev/null
+++ b/host/lib/usrp/b100/codec_impl.cpp
@@ -0,0 +1,149 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "b100_impl.hpp"
+#include <uhd/exception.hpp>
+#include <uhd/usrp/codec_props.hpp>
+#include <boost/bind.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+/***********************************************************************
+ * Helper Methods
+ **********************************************************************/
+void b100_impl::codec_init(void){
+ //make proxies
+ _rx_codec_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::rx_codec_get, this, _1, _2),
+ boost::bind(&b100_impl::rx_codec_set, this, _1, _2)
+ );
+ _tx_codec_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::tx_codec_get, this, _1, _2),
+ boost::bind(&b100_impl::tx_codec_set, this, _1, _2)
+ );
+}
+
+/***********************************************************************
+ * RX Codec Properties
+ **********************************************************************/
+static const std::string ad9862_pga_gain_name = "ad9862 pga";
+
+void b100_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<codec_prop_t>()){
+ case CODEC_PROP_NAME:
+ val = std::string("b100 adc - ad9522");
+ return;
+
+ case CODEC_PROP_OTHERS:
+ val = prop_names_t();
+ return;
+
+ case CODEC_PROP_GAIN_NAMES:
+ val = prop_names_t(1, ad9862_pga_gain_name);
+ return;
+
+ case CODEC_PROP_GAIN_RANGE:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ val = b100_codec_ctrl::rx_pga_gain_range;
+ return;
+
+ case CODEC_PROP_GAIN_I:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ val = _codec_ctrl->get_rx_pga_gain('A');
+ return;
+
+ case CODEC_PROP_GAIN_Q:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ val = _codec_ctrl->get_rx_pga_gain('B');
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+void b100_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the set request conditioned on the key
+ switch(key.as<codec_prop_t>()){
+ case CODEC_PROP_GAIN_I:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ _codec_ctrl->set_rx_pga_gain(val.as<double>(), 'A');
+ return;
+
+ case CODEC_PROP_GAIN_Q:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ _codec_ctrl->set_rx_pga_gain(val.as<double>(), 'B');
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * TX Codec Properties
+ **********************************************************************/
+void b100_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<codec_prop_t>()){
+ case CODEC_PROP_NAME:
+ val = std::string("b100 dac - ad9522");
+ return;
+
+ case CODEC_PROP_OTHERS:
+ val = prop_names_t();
+ return;
+
+ case CODEC_PROP_GAIN_NAMES:
+ val = prop_names_t(1, ad9862_pga_gain_name);
+ return;
+
+ case CODEC_PROP_GAIN_RANGE:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ val = b100_codec_ctrl::tx_pga_gain_range;
+ return;
+
+ case CODEC_PROP_GAIN_I: //only one gain for I and Q
+ case CODEC_PROP_GAIN_Q:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ val = _codec_ctrl->get_tx_pga_gain();
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+void b100_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the set request conditioned on the key
+ switch(key.as<codec_prop_t>()){
+ case CODEC_PROP_GAIN_I: //only one gain for I and Q
+ case CODEC_PROP_GAIN_Q:
+ UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name);
+ _codec_ctrl->set_tx_pga_gain(val.as<double>());
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
diff --git a/host/lib/usrp/b100/ctrl_packet.hpp b/host/lib/usrp/b100/ctrl_packet.hpp
new file mode 100644
index 000000000..f504fc5aa
--- /dev/null
+++ b/host/lib/usrp/b100/ctrl_packet.hpp
@@ -0,0 +1,75 @@
+//
+// 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_CTRL_PACKET_HPP
+#define INCLUDED_CTRL_PACKET_HPP
+
+#include <uhd/config.hpp>
+#include <boost/cstdint.hpp>
+#include <uhd/types/serial.hpp>
+
+typedef std::vector<boost::uint16_t> ctrl_data_t;
+
+/*!
+ * Control packet operation type
+ */
+enum ctrl_pkt_op_t {
+ CTRL_PKT_OP_WRITE = 1,
+ CTRL_PKT_OP_READ = 2,
+ CTRL_PKT_OP_READBACK = 3
+};
+
+/*!
+ * Control packet transaction length
+ */
+const size_t CTRL_PACKET_LENGTH = 32;
+const size_t CTRL_PACKET_HEADER_LENGTH = 8;
+const size_t CTRL_PACKET_DATA_LENGTH = 24; //=length-header
+
+/*!
+ * Control packet header magic value
+ */
+const boost::uint8_t CTRL_PACKET_HEADER_MAGIC = 0xAA;
+
+/*!
+ * Callback triggers for readback operation
+ */
+//FIXME: these are not real numbers, callbacks aren't implemented yet
+const boost::uint16_t CTRL_PACKET_CALLBACK_SPI = 0x0001;
+const boost::uint16_t CTRL_PACKET_CALLBACK_I2C = 0x0002;
+//and so on
+
+/*!
+ * Metadata structure to describe a control packet
+ */
+struct UHD_API ctrl_pkt_meta_t {
+ ctrl_pkt_op_t op;
+ boost::uint8_t callbacks;
+ boost::uint8_t seq;
+ boost::uint16_t len;
+ boost::uint32_t addr;
+};
+
+/*!
+ * Full control packet structure
+ */
+struct UHD_API ctrl_pkt_t {
+ ctrl_pkt_meta_t pkt_meta;
+ ctrl_data_t data;
+};
+
+#endif /* INCLUDED_CTRL_PACKET_HPP */
diff --git a/host/lib/usrp/b100/dboard_iface.cpp b/host/lib/usrp/b100/dboard_iface.cpp
new file mode 100644
index 000000000..ec3da6220
--- /dev/null
+++ b/host/lib/usrp/b100/dboard_iface.cpp
@@ -0,0 +1,298 @@
+//
+// 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 "b100_iface.hpp"
+#include "b100_regs.hpp"
+#include "clock_ctrl.hpp"
+#include "codec_ctrl.hpp"
+#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/exception.hpp>
+#include <boost/assign/list_of.hpp>
+
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+class b100_dboard_iface : public dboard_iface{
+public:
+
+ b100_dboard_iface(
+ b100_iface::sptr iface,
+ b100_clock_ctrl::sptr clock,
+ b100_codec_ctrl::sptr codec
+ ){
+ _iface = iface;
+ _clock = clock;
+ _codec = codec;
+
+ //init the clock rate shadows
+ this->set_clock_rate(UNIT_RX, _clock->get_fpga_clock_rate());
+ this->set_clock_rate(UNIT_TX, _clock->get_fpga_clock_rate());
+
+ _iface->poke16(B100_REG_GPIO_RX_DBG, 0);
+ _iface->poke16(B100_REG_GPIO_TX_DBG, 0);
+ }
+
+ ~b100_dboard_iface(void){
+ /* NOP */
+ }
+
+ special_props_t get_special_props(void){
+ special_props_t props;
+ props.soft_clock_divider = false;
+ props.mangle_i2c_addrs = false;
+ return props;
+ }
+
+ void write_aux_dac(unit_t, aux_dac_t, double);
+ double read_aux_adc(unit_t, aux_adc_t);
+
+ void _set_pin_ctrl(unit_t, boost::uint16_t);
+ void _set_atr_reg(unit_t, atr_reg_t, boost::uint16_t);
+ void _set_gpio_ddr(unit_t, boost::uint16_t);
+ void _set_gpio_out(unit_t, boost::uint16_t);
+ void set_gpio_debug(unit_t, int);
+ boost::uint16_t read_gpio(unit_t);
+
+ void write_i2c(boost::uint8_t, const byte_vector_t &);
+ byte_vector_t read_i2c(boost::uint8_t, size_t);
+
+ void write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ );
+
+ boost::uint32_t read_write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ );
+
+ void set_clock_rate(unit_t, double);
+ std::vector<double> get_clock_rates(unit_t);
+ double get_clock_rate(unit_t);
+ void set_clock_enabled(unit_t, bool);
+ double get_codec_rate(unit_t);
+
+private:
+ b100_iface::sptr _iface;
+ b100_clock_ctrl::sptr _clock;
+ b100_codec_ctrl::sptr _codec;
+ uhd::dict<unit_t, double> _clock_rates;
+};
+
+/***********************************************************************
+ * Make Function
+ **********************************************************************/
+dboard_iface::sptr make_b100_dboard_iface(
+ b100_iface::sptr iface,
+ b100_clock_ctrl::sptr clock,
+ b100_codec_ctrl::sptr codec
+){
+ return dboard_iface::sptr(new b100_dboard_iface(iface, clock, codec));
+}
+
+/***********************************************************************
+ * Clock Rates
+ **********************************************************************/
+void b100_dboard_iface::set_clock_rate(unit_t unit, double rate){
+ _clock_rates[unit] = rate;
+ switch(unit){
+ case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate);
+ case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate);
+ }
+}
+
+std::vector<double> b100_dboard_iface::get_clock_rates(unit_t unit){
+ switch(unit){
+ case UNIT_RX: return _clock->get_rx_dboard_clock_rates();
+ case UNIT_TX: return _clock->get_tx_dboard_clock_rates();
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
+}
+
+double b100_dboard_iface::get_clock_rate(unit_t unit){
+ return _clock_rates[unit];
+}
+
+void b100_dboard_iface::set_clock_enabled(unit_t unit, bool enb){
+ switch(unit){
+ case UNIT_RX: return _clock->enable_rx_dboard_clock(enb);
+ case UNIT_TX: return _clock->enable_tx_dboard_clock(enb);
+ }
+}
+
+double b100_dboard_iface::get_codec_rate(unit_t){
+ return _clock->get_fpga_clock_rate();
+}
+
+/***********************************************************************
+ * GPIO
+ **********************************************************************/
+void b100_dboard_iface::_set_pin_ctrl(unit_t unit, boost::uint16_t value){
+ UHD_ASSERT_THROW(GPIO_SEL_ATR == 1); //make this assumption
+ switch(unit){
+ case UNIT_RX: _iface->poke16(B100_REG_GPIO_RX_SEL, value); return;
+ case UNIT_TX: _iface->poke16(B100_REG_GPIO_TX_SEL, value); return;
+ }
+}
+
+void b100_dboard_iface::_set_gpio_ddr(unit_t unit, boost::uint16_t value){
+ switch(unit){
+ case UNIT_RX: _iface->poke16(B100_REG_GPIO_RX_DDR, value); return;
+ case UNIT_TX: _iface->poke16(B100_REG_GPIO_TX_DDR, value); return;
+ }
+}
+
+void b100_dboard_iface::_set_gpio_out(unit_t unit, boost::uint16_t value){
+ switch(unit){
+ case UNIT_RX: _iface->poke16(B100_REG_GPIO_RX_IO, value); return;
+ case UNIT_TX: _iface->poke16(B100_REG_GPIO_TX_IO, value); return;
+ }
+}
+
+boost::uint16_t b100_dboard_iface::read_gpio(unit_t unit){
+ switch(unit){
+ case UNIT_RX: return _iface->peek16(B100_REG_GPIO_RX_IO);
+ case UNIT_TX: return _iface->peek16(B100_REG_GPIO_TX_IO);
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
+}
+
+void b100_dboard_iface::_set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){
+ //define mapping of unit to atr regs to register address
+ static const uhd::dict<
+ unit_t, uhd::dict<atr_reg_t, boost::uint32_t>
+ > unit_to_atr_to_addr = map_list_of
+ (UNIT_RX, map_list_of
+ (ATR_REG_IDLE, B100_REG_ATR_IDLE_RXSIDE)
+ (ATR_REG_TX_ONLY, B100_REG_ATR_INTX_RXSIDE)
+ (ATR_REG_RX_ONLY, B100_REG_ATR_INRX_RXSIDE)
+ (ATR_REG_FULL_DUPLEX, B100_REG_ATR_FULL_RXSIDE)
+ )
+ (UNIT_TX, map_list_of
+ (ATR_REG_IDLE, B100_REG_ATR_IDLE_TXSIDE)
+ (ATR_REG_TX_ONLY, B100_REG_ATR_INTX_TXSIDE)
+ (ATR_REG_RX_ONLY, B100_REG_ATR_INRX_TXSIDE)
+ (ATR_REG_FULL_DUPLEX, B100_REG_ATR_FULL_TXSIDE)
+ )
+ ;
+ _iface->poke16(unit_to_atr_to_addr[unit][atr], value);
+}
+
+void b100_dboard_iface::set_gpio_debug(unit_t unit, int which){
+ //set this unit to all outputs
+ this->set_gpio_ddr(unit, 0xffff);
+
+ //calculate the debug selections
+ boost::uint32_t dbg_sels = 0x0;
+ int sel = (which == 0)? GPIO_SEL_DEBUG_0 : GPIO_SEL_DEBUG_1;
+ for(size_t i = 0; i < 16; i++) dbg_sels |= sel << i;
+
+ //set the debug on and which debug selection
+ switch(unit){
+ case UNIT_RX:
+ _iface->poke16(B100_REG_GPIO_RX_DBG, 0xffff);
+ _iface->poke16(B100_REG_GPIO_RX_SEL, dbg_sels);
+ return;
+
+ case UNIT_TX:
+ _iface->poke16(B100_REG_GPIO_TX_DBG, 0xffff);
+ _iface->poke16(B100_REG_GPIO_TX_SEL, dbg_sels);
+ return;
+ }
+}
+
+/***********************************************************************
+ * SPI
+ **********************************************************************/
+/*!
+ * Static function to convert a unit type to a spi slave device number.
+ * \param unit the dboard interface unit type enum
+ * \return the slave device number
+ */
+static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){
+ switch(unit){
+ case dboard_iface::UNIT_TX: return B100_SPI_SS_TX_DB;
+ case dboard_iface::UNIT_RX: return B100_SPI_SS_RX_DB;
+ }
+ throw std::invalid_argument("unknown unit type");
+}
+
+void b100_dboard_iface::write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+){
+ _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/);
+}
+
+boost::uint32_t b100_dboard_iface::read_write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+){
+ return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/);
+}
+
+/***********************************************************************
+ * I2C
+ **********************************************************************/
+void b100_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){
+ return _iface->write_i2c(addr, bytes);
+}
+
+byte_vector_t b100_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){
+ return _iface->read_i2c(addr, num_bytes);
+}
+
+/***********************************************************************
+ * Aux DAX/ADC
+ **********************************************************************/
+void b100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, double value){
+ //same aux dacs for each unit
+ static const uhd::dict<aux_dac_t, b100_codec_ctrl::aux_dac_t> which_to_aux_dac = map_list_of
+ (AUX_DAC_A, b100_codec_ctrl::AUX_DAC_A)
+ (AUX_DAC_B, b100_codec_ctrl::AUX_DAC_B)
+ (AUX_DAC_C, b100_codec_ctrl::AUX_DAC_C)
+ (AUX_DAC_D, b100_codec_ctrl::AUX_DAC_D)
+ ;
+ _codec->write_aux_dac(which_to_aux_dac[which], value);
+}
+
+double b100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){
+ static const uhd::dict<
+ unit_t, uhd::dict<aux_adc_t, b100_codec_ctrl::aux_adc_t>
+ > unit_to_which_to_aux_adc = map_list_of
+ (UNIT_RX, map_list_of
+ (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A1)
+ (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B1)
+ )
+ (UNIT_TX, map_list_of
+ (AUX_ADC_A, b100_codec_ctrl::AUX_ADC_A2)
+ (AUX_ADC_B, b100_codec_ctrl::AUX_ADC_B2)
+ )
+ ;
+ return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]);
+}
diff --git a/host/lib/usrp/b100/dboard_impl.cpp b/host/lib/usrp/b100/dboard_impl.cpp
new file mode 100644
index 000000000..ba3776728
--- /dev/null
+++ b/host/lib/usrp/b100/dboard_impl.cpp
@@ -0,0 +1,185 @@
+//
+// 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 "b100_impl.hpp"
+#include "b100_regs.hpp"
+#include <uhd/exception.hpp>
+#include <uhd/usrp/dboard_props.hpp>
+#include <uhd/usrp/subdev_props.hpp>
+#include <uhd/usrp/misc_utils.hpp>
+#include <boost/bind.hpp>
+#include "usrp_i2c_addr.h"
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+/***********************************************************************
+ * Dboard Initialization
+ **********************************************************************/
+void b100_impl::dboard_init(void){
+ //read the tx and rx dboard eeproms
+ _rx_db_eeprom.load(*_iface, I2C_ADDR_RX_A);
+ _tx_db_eeprom.load(*_iface, I2C_ADDR_TX_A);
+ _gdb_eeprom.load(*_iface, I2C_ADDR_TX_A ^ 5);
+
+ //create a new dboard interface and manager
+ _dboard_iface = make_b100_dboard_iface(
+ _iface, _clock_ctrl, _codec_ctrl
+ );
+ _dboard_manager = dboard_manager::make(
+ _rx_db_eeprom.id,
+ ((_gdb_eeprom.id == dboard_id_t::none())? _tx_db_eeprom : _gdb_eeprom).id,
+ _dboard_iface
+ );
+
+ //setup the dboard proxies
+ _rx_dboard_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::rx_dboard_get, this, _1, _2),
+ boost::bind(&b100_impl::rx_dboard_set, this, _1, _2)
+ );
+ _tx_dboard_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::tx_dboard_get, this, _1, _2),
+ boost::bind(&b100_impl::tx_dboard_set, this, _1, _2)
+ );
+}
+
+/***********************************************************************
+ * RX Dboard Get
+ **********************************************************************/
+void b100_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<dboard_prop_t>()){
+ case DBOARD_PROP_NAME:
+ val = std::string("b100 dboard (rx unit)");
+ return;
+
+ case DBOARD_PROP_SUBDEV:
+ val = _dboard_manager->get_rx_subdev(key.name);
+ return;
+
+ case DBOARD_PROP_SUBDEV_NAMES:
+ val = _dboard_manager->get_rx_subdev_names();
+ return;
+
+ case DBOARD_PROP_DBOARD_EEPROM:
+ val = _rx_db_eeprom;
+ return;
+
+ case DBOARD_PROP_DBOARD_IFACE:
+ val = _dboard_iface;
+ return;
+
+ case DBOARD_PROP_CODEC:
+ val = _rx_codec_proxy->get_link();
+ return;
+
+ case DBOARD_PROP_GAIN_GROUP:
+ val = make_gain_group(
+ _rx_db_eeprom.id,
+ _dboard_manager->get_rx_subdev(key.name),
+ _rx_codec_proxy->get_link(),
+ GAIN_GROUP_POLICY_RX
+ );
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * RX Dboard Set
+ **********************************************************************/
+void b100_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){
+ switch(key.as<dboard_prop_t>()){
+ case DBOARD_PROP_DBOARD_EEPROM:
+ _rx_db_eeprom = val.as<dboard_eeprom_t>();
+ _rx_db_eeprom.store(*_iface, I2C_ADDR_RX_A);
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * TX Dboard Get
+ **********************************************************************/
+void b100_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<dboard_prop_t>()){
+ case DBOARD_PROP_NAME:
+ val = std::string("b100 dboard (tx unit)");
+ return;
+
+ case DBOARD_PROP_SUBDEV:
+ val = _dboard_manager->get_tx_subdev(key.name);
+ return;
+
+ case DBOARD_PROP_SUBDEV_NAMES:
+ val = _dboard_manager->get_tx_subdev_names();
+ return;
+
+ case DBOARD_PROP_DBOARD_EEPROM:
+ val = _tx_db_eeprom;
+ return;
+
+ case DBOARD_PROP_GBOARD_EEPROM:
+ val = _gdb_eeprom;
+ return;
+
+ case DBOARD_PROP_DBOARD_IFACE:
+ val = _dboard_iface;
+ return;
+
+ case DBOARD_PROP_CODEC:
+ val = _tx_codec_proxy->get_link();
+ return;
+
+ case DBOARD_PROP_GAIN_GROUP:
+ val = make_gain_group(
+ _tx_db_eeprom.id,
+ _dboard_manager->get_tx_subdev(key.name),
+ _tx_codec_proxy->get_link(),
+ GAIN_GROUP_POLICY_TX
+ );
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * TX Dboard Set
+ **********************************************************************/
+void b100_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){
+ switch(key.as<dboard_prop_t>()){
+ case DBOARD_PROP_DBOARD_EEPROM:
+ _tx_db_eeprom = val.as<dboard_eeprom_t>();
+ _tx_db_eeprom.store(*_iface, I2C_ADDR_TX_A);
+ return;
+
+ case DBOARD_PROP_GBOARD_EEPROM:
+ _gdb_eeprom = val.as<dboard_eeprom_t>();
+ _gdb_eeprom.store(*_iface, I2C_ADDR_TX_A ^ 5);
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
diff --git a/host/lib/usrp/b100/dsp_impl.cpp b/host/lib/usrp/b100/dsp_impl.cpp
new file mode 100644
index 000000000..c1bf6bedd
--- /dev/null
+++ b/host/lib/usrp/b100/dsp_impl.cpp
@@ -0,0 +1,189 @@
+//
+// 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 "b100_impl.hpp"
+#include "b100_regs.hpp"
+#include <uhd/usrp/dsp_utils.hpp>
+#include <uhd/usrp/dsp_props.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <boost/bind.hpp>
+
+#define rint boost::math::iround
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+static const double MASTER_CLOCK_RATE = 64e6; //TODO get from clock control
+
+/***********************************************************************
+ * RX DDC Initialization
+ **********************************************************************/
+void b100_impl::rx_ddc_init(void){
+ _rx_ddc_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::rx_ddc_get, this, _1, _2),
+ boost::bind(&b100_impl::rx_ddc_set, this, _1, _2)
+ );
+
+ //initial config and update
+ rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0));
+ rx_ddc_set(DSP_PROP_HOST_RATE, double(16e6));
+}
+
+/***********************************************************************
+ * RX DDC Get
+ **********************************************************************/
+void b100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ switch(key.as<dsp_prop_t>()){
+ case DSP_PROP_NAME:
+ val = std::string("USRP-B100 RX DSP");
+ return;
+
+ case DSP_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case DSP_PROP_FREQ_SHIFT:
+ val = _ddc_freq;
+ return;
+
+ case DSP_PROP_CODEC_RATE:
+ val = _clock_ctrl->get_fpga_clock_rate();
+ return;
+
+ case DSP_PROP_HOST_RATE:
+ val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim;
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * RX DDC Set
+ **********************************************************************/
+void b100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ 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(B100_REG_DSP_RX_FREQ,
+ dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate())
+ );
+ _ddc_freq = new_freq; //shadow
+ }
+ return;
+
+ case DSP_PROP_HOST_RATE:{
+ //set the decimation
+ _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
+ _iface->poke32(B100_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim));
+
+ //set the scaling
+ static const boost::int16_t default_rx_scale_iq = 1024;
+ _iface->poke32(B100_REG_DSP_RX_SCALE_IQ,
+ dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
+ );
+ }
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * TX DUC Initialization
+ **********************************************************************/
+void b100_impl::tx_duc_init(void){
+ _tx_duc_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::tx_duc_get, this, _1, _2),
+ boost::bind(&b100_impl::tx_duc_set, this, _1, _2)
+ );
+
+ //initial config and update
+ tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0));
+ tx_duc_set(DSP_PROP_HOST_RATE, double(16e6));
+}
+
+/***********************************************************************
+ * TX DUC Get
+ **********************************************************************/
+void b100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ switch(key.as<dsp_prop_t>()){
+ case DSP_PROP_NAME:
+ val = std::string("USRP-B100 TX DSP");
+ return;
+
+ case DSP_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case DSP_PROP_FREQ_SHIFT:
+ val = _duc_freq;
+ return;
+
+ case DSP_PROP_CODEC_RATE:
+ val = _clock_ctrl->get_fpga_clock_rate();
+ return;
+
+ case DSP_PROP_HOST_RATE:
+ val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp;
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * TX DUC Set
+ **********************************************************************/
+void b100_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ switch(key.as<dsp_prop_t>()){
+
+ case DSP_PROP_FREQ_SHIFT:{
+ double new_freq = val.as<double>();
+ _iface->poke32(B100_REG_DSP_TX_FREQ,
+ dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate())
+ );
+ _duc_freq = new_freq; //shadow
+ }
+ return;
+
+ case DSP_PROP_HOST_RATE:{
+ _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
+
+ //set the interpolation
+ _iface->poke32(B100_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp));
+
+ //set the scaling
+ _iface->poke32(B100_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp));
+ }
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp
new file mode 100644
index 000000000..3978bea75
--- /dev/null
+++ b/host/lib/usrp/b100/io_impl.cpp
@@ -0,0 +1,210 @@
+//
+// 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 "../../transport/super_recv_packet_handler.hpp"
+#include "../../transport/super_send_packet_handler.hpp"
+#include "usrp_commands.h"
+#include "b100_impl.hpp"
+#include "b100_regs.hpp"
+#include <uhd/usrp/dsp_utils.hpp>
+#include <uhd/usrp/dsp_props.hpp>
+#include <uhd/utils/thread_priority.hpp>
+#include <uhd/transport/bounded_buffer.hpp>
+#include <boost/bind.hpp>
+#include <boost/format.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/utils/log.hpp>
+#include <iostream>
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace uhd::transport;
+namespace asio = boost::asio;
+
+/***********************************************************************
+ * IO Implementation Details
+ **********************************************************************/
+struct b100_impl::io_impl{
+ io_impl(zero_copy_if::sptr data_transport):
+ data_transport(data_transport)
+ {
+ /* NOP */
+ }
+
+ ~io_impl(void){
+ //drain the rx buffs
+ //while(data_transport->get_recv_buff().get() != NULL){
+ /* NOP */
+ //}
+ }
+
+ zero_copy_if::sptr &data_transport;
+
+ sph::recv_packet_handler recv_handler;
+ sph::send_packet_handler send_handler;
+ bool continuous_streaming;
+};
+
+/***********************************************************************
+ * Initialize internals within this file
+ **********************************************************************/
+void b100_impl::io_init(void){
+ _recv_otw_type.width = 16;
+ _recv_otw_type.shift = 0;
+ _recv_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
+
+ _send_otw_type.width = 16;
+ _send_otw_type.shift = 0;
+ _send_otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN;
+
+ _iface->reset_gpif(6);
+
+ //reset state machines
+ _iface->poke32(B100_REG_CTRL_TX_CLEAR_UNDERRUN, 0);
+ _iface->poke32(B100_REG_CTRL_RX_CLEAR_OVERRUN, 0);
+
+ _io_impl = UHD_PIMPL_MAKE(io_impl, (_data_transport));
+
+ //setup rx data path
+ _iface->poke32(B100_REG_CTRL_RX_NSAMPS_PER_PKT, get_max_recv_samps_per_packet());
+ UHD_LOGV(always) << "IO: Using " << get_max_recv_samps_per_packet() << " samples per packet" << std::endl;
+ _iface->poke32(B100_REG_CTRL_RX_NCHANNELS, 1);
+ _iface->poke32(B100_REG_CTRL_RX_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(B100_REG_CTRL_RX_VRT_TRAILER, 0);
+
+ //set the streamid to reset the seq num
+ _iface->poke32(B100_REG_CTRL_TX_REPORT_SID, 0);
+ //setup the tx policy
+ _iface->poke32(B100_REG_CTRL_TX_POLICY, B100_FLAG_CTRL_TX_POLICY_NEXT_PACKET);
+
+ //set the expected packet size in USB frames
+ _iface->poke32(B100_REG_MISC_RX_LEN, 4);
+
+ update_transport_channel_mapping();
+}
+
+void b100_impl::update_transport_channel_mapping(void){
+ if (_io_impl.get() == NULL) return; //not inited yet
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock recv_lock = _io_impl->recv_handler.get_scoped_lock();
+ _io_impl->recv_handler.resize(_rx_subdev_spec.size());
+ _io_impl->recv_handler.set_vrt_unpacker(&vrt::if_hdr_unpack_le);
+ _io_impl->recv_handler.set_tick_rate(_clock_ctrl->get_fpga_clock_rate());
+ _io_impl->recv_handler.set_samp_rate(_rx_ddc_proxy->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < _io_impl->recv_handler.size(); chan++){
+ _io_impl->recv_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &uhd::transport::zero_copy_if::get_recv_buff, _io_impl->data_transport, _1
+ ));
+ _io_impl->recv_handler.set_overflow_handler(chan, boost::bind(
+ &b100_impl::handle_overrun, this, chan
+ ));
+ }
+ _io_impl->recv_handler.set_converter(_recv_otw_type);
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock send_lock = _io_impl->send_handler.get_scoped_lock();
+ _io_impl->send_handler.resize(_tx_subdev_spec.size());
+ _io_impl->send_handler.set_vrt_packer(&vrt::if_hdr_pack_le);
+ _io_impl->send_handler.set_tick_rate(_clock_ctrl->get_fpga_clock_rate());
+ _io_impl->send_handler.set_samp_rate(_tx_duc_proxy->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < _io_impl->send_handler.size(); chan++){
+ _io_impl->send_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &uhd::transport::zero_copy_if::get_send_buff, _io_impl->data_transport, _1
+ ));
+ }
+ _io_impl->send_handler.set_converter(_send_otw_type);
+ _io_impl->send_handler.set_max_samples_per_packet(get_max_send_samps_per_packet());
+}
+
+/***********************************************************************
+ * Data send + helper functions
+ **********************************************************************/
+size_t b100_impl::get_max_send_samps_per_packet(void) const {
+ static const size_t hdr_size = 0
+ + vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ - sizeof(vrt::if_packet_info_t().cid) //no class id ever used
+ ;
+ static const size_t bpp = 2048 - hdr_size;
+ return bpp / _send_otw_type.get_sample_size();
+}
+
+size_t b100_impl::send(
+ const send_buffs_type &buffs, size_t nsamps_per_buff,
+ const tx_metadata_t &metadata, const io_type_t &io_type,
+ send_mode_t send_mode, double timeout
+){
+ return _io_impl->send_handler.send(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ send_mode, timeout
+ );
+}
+
+/***********************************************************************
+ * Data recv + helper functions
+ **********************************************************************/
+
+size_t b100_impl::get_max_recv_samps_per_packet(void) const {
+ static const size_t hdr_size = 0
+ + vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
+ + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
+ - sizeof(vrt::if_packet_info_t().cid) //no class id ever used
+ ;
+ size_t bpp = 2048 - hdr_size; //limited by FPGA pkt buffer size
+ return bpp/_recv_otw_type.get_sample_size();
+}
+
+size_t b100_impl::recv(
+ const recv_buffs_type &buffs, size_t nsamps_per_buff,
+ rx_metadata_t &metadata, const io_type_t &io_type,
+ recv_mode_t recv_mode, double timeout
+){
+ return _io_impl->recv_handler.recv(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ recv_mode, timeout
+ );
+}
+
+void b100_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd)
+{
+ _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
+ _iface->poke32(B100_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word(stream_cmd));
+ _iface->poke32(B100_REG_CTRL_RX_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs()));
+ _iface->poke32(B100_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate()));
+
+ if (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) {
+ while(_io_impl->data_transport->get_recv_buff().get() != NULL){
+ /* NOP */
+ }
+ }
+}
+
+void b100_impl::handle_overrun(size_t){
+ if (_io_impl->continuous_streaming){
+ this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
+ }
+}
diff --git a/host/lib/usrp/b100/mboard_impl.cpp b/host/lib/usrp/b100/mboard_impl.cpp
new file mode 100644
index 000000000..c651ff2a2
--- /dev/null
+++ b/host/lib/usrp/b100/mboard_impl.cpp
@@ -0,0 +1,246 @@
+//
+// 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 "b100_impl.hpp"
+#include "usrp_commands.h"
+#include "fpga_regs_standard.h"
+#include "fpga_regs_common.h"
+#include "b100_regs.hpp"
+#include "usrp_i2c_addr.h"
+#include <uhd/usrp/misc_utils.hpp>
+#include <uhd/usrp/mboard_props.hpp>
+#include <uhd/usrp/dboard_props.hpp>
+#include <uhd/usrp/subdev_props.hpp>
+#include <uhd/utils/msg.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/images.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/thread.hpp>
+#include <uhd/usrp/dsp_utils.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+static const bool b100_mboard_verbose = true;
+
+/***********************************************************************
+ * Mboard Initialization
+ **********************************************************************/
+void b100_impl::mboard_init(void)
+{
+ _mboard_proxy = wax_obj_proxy::make(
+ boost::bind(&b100_impl::mboard_get, this, _1, _2),
+ boost::bind(&b100_impl::mboard_set, this, _1, _2));
+
+ //set the ticks per seconds into the vita time control
+ _iface->poke32(B100_REG_TIME64_TPS,
+ boost::uint32_t(_clock_ctrl->get_fpga_clock_rate())
+ );
+
+ //init the clock config
+ _clock_config = clock_config_t::internal();
+ update_clock_config();
+}
+
+void b100_impl::update_clock_config(void){
+ boost::uint32_t pps_flags = 0;
+
+ //translate pps polarity enums
+ switch(_clock_config.pps_polarity){
+ case clock_config_t::PPS_POS: pps_flags |= B100_FLAG_TIME64_PPS_POSEDGE; break;
+ case clock_config_t::PPS_NEG: pps_flags |= B100_FLAG_TIME64_PPS_NEGEDGE; break;
+ default: throw uhd::runtime_error("unhandled clock configuration pps polarity");
+ }
+
+ //set the pps flags
+ _iface->poke32(B100_REG_TIME64_FLAGS, pps_flags);
+
+ //clock source ref 10mhz
+ switch(_clock_config.ref_source){
+ 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 uhd::runtime_error("unhandled clock configuration ref source");
+ }
+}
+
+/***********************************************************************
+ * Mboard Get
+ **********************************************************************/
+void b100_impl::mboard_get(const wax::obj &key_, wax::obj &val){
+ named_prop_t key = named_prop_t::extract(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<mboard_prop_t>()){
+ case MBOARD_PROP_NAME:
+ val = std::string("USRP-B100 mboard");
+ return;
+
+ case MBOARD_PROP_OTHERS:
+ val = prop_names_t();
+ return;
+
+ case MBOARD_PROP_RX_DBOARD:
+ UHD_ASSERT_THROW(key.name == "");
+ val = _rx_dboard_proxy->get_link();
+ return;
+
+ case MBOARD_PROP_RX_DBOARD_NAMES:
+ val = prop_names_t(1, ""); //vector of size 1 with empty string
+ return;
+
+ case MBOARD_PROP_TX_DBOARD:
+ UHD_ASSERT_THROW(key.name == "");
+ val = _tx_dboard_proxy->get_link();
+ return;
+
+ case MBOARD_PROP_TX_DBOARD_NAMES:
+ val = prop_names_t(1, ""); //vector of size 1 with empty string
+ return;
+
+ case MBOARD_PROP_RX_DSP:
+ UHD_ASSERT_THROW(key.name == "");
+ val = _rx_ddc_proxy->get_link();
+ return;
+
+ case MBOARD_PROP_RX_DSP_NAMES:
+ val = prop_names_t(1, "");
+ return;
+
+ case MBOARD_PROP_TX_DSP:
+ UHD_ASSERT_THROW(key.name == "");
+ val = _tx_duc_proxy->get_link();
+ return;
+
+ case MBOARD_PROP_TX_DSP_NAMES:
+ val = prop_names_t(1, "");
+ return;
+
+ case MBOARD_PROP_CLOCK_CONFIG:
+ val = _clock_config;
+ return;
+
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ val = _rx_subdev_spec;
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ val = _tx_subdev_spec;
+ return;
+
+ case MBOARD_PROP_EEPROM_MAP:
+ val = _iface->mb_eeprom;
+ return;
+
+ case MBOARD_PROP_TIME_NOW:while(true){
+ uint32_t secs = _iface->peek32(B100_REG_RB_TIME_NOW_SECS);
+ uint32_t ticks = _iface->peek32(B100_REG_RB_TIME_NOW_TICKS);
+ if (secs != _iface->peek32(B100_REG_RB_TIME_NOW_SECS)) continue;
+ val = time_spec_t(secs, ticks, _clock_ctrl->get_fpga_clock_rate());
+ return;
+ }
+
+ case MBOARD_PROP_TIME_PPS: while(true){
+ uint32_t secs = _iface->peek32(B100_REG_RB_TIME_PPS_SECS);
+ uint32_t ticks = _iface->peek32(B100_REG_RB_TIME_PPS_TICKS);
+ if (secs != _iface->peek32(B100_REG_RB_TIME_PPS_SECS)) continue;
+ val = time_spec_t(secs, ticks, _clock_ctrl->get_fpga_clock_rate());
+ return;
+ }
+
+ case MBOARD_PROP_CLOCK_RATE:
+ val = _clock_ctrl->get_fpga_clock_rate();
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * Mboard Set
+ **********************************************************************/
+void b100_impl::mboard_set(const wax::obj &key, const wax::obj &val)
+{
+ if(key.type() == typeid(std::string)) {
+ if(key.as<std::string>() == "load_eeprom") {
+ std::string b100_eeprom_image = val.as<std::string>();
+ UHD_MSG(status) << "B100 EEPROM image: " << b100_eeprom_image << std::endl;
+ _fx2_ctrl->usrp_load_eeprom(val.as<std::string>());
+ }
+ return;
+ }
+
+ //handle the get request conditioned on the key
+ switch(key.as<mboard_prop_t>()){
+ case MBOARD_PROP_TIME_NOW:
+ case MBOARD_PROP_TIME_PPS:{
+ time_spec_t time_spec = val.as<time_spec_t>();
+ _iface->poke32(B100_REG_TIME64_TICKS, time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate()));
+ boost::uint32_t imm_flags = (key.as<mboard_prop_t>() == MBOARD_PROP_TIME_NOW)? 1 : 0;
+ _iface->poke32(B100_REG_TIME64_IMM, imm_flags);
+ _iface->poke32(B100_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs()));
+ }
+ return;
+
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ _rx_subdev_spec = val.as<subdev_spec_t>();
+ verify_rx_subdev_spec(_rx_subdev_spec, _mboard_proxy->get_link());
+ UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1);
+ //set the mux
+ _iface->poke32(B100_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word(
+ _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ _tx_subdev_spec = val.as<subdev_spec_t>();
+ verify_tx_subdev_spec(_tx_subdev_spec, _mboard_proxy->get_link());
+ UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1);
+ //set the mux and set the number of tx channels
+ _iface->poke32(B100_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word(
+ _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
+ case MBOARD_PROP_EEPROM_MAP:
+ // Step1: commit the map, writing only those values set.
+ // Step2: readback the entire eeprom map into the iface.
+ val.as<mboard_eeprom_t>().commit(*_iface, mboard_eeprom_t::MAP_B000);
+ _iface->mb_eeprom = mboard_eeprom_t(*_iface, mboard_eeprom_t::MAP_B000);
+ return;
+
+ case MBOARD_PROP_CLOCK_CONFIG:
+ _clock_config = val.as<clock_config_t>();
+ update_clock_config();
+ return;
+
+ case MBOARD_PROP_CLOCK_RATE:
+ UHD_MSG(warning)
+ << "You are setting the master clock rate from the API.\n"
+ << "You may want to pass this into the device address as master_clock_rate=<rate>.\n"
+ << "This way, the clock rate is guaranteed to be initialized first.\n"
+ << "See the application notes for USRP-B100 for further instructions.\n"
+ ;
+ _clock_ctrl->set_fpga_clock_rate(val.as<double>());
+ update_transport_channel_mapping();
+ return;
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp
index 6f8de9a7b..566e24d97 100644
--- a/host/lib/usrp/dboard/db_basic_and_lf.cpp
+++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp
@@ -111,6 +111,7 @@ basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0000);
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0xFFFF);
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0x0000);
+ this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);
}
basic_rx::~basic_rx(void){
@@ -216,6 +217,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){
**********************************************************************/
basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){
_max_freq = max_freq;
+ this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);
}
basic_tx::~basic_tx(void){
diff --git a/host/lib/usrp/fx2/fx2_ctrl.hpp b/host/lib/usrp/fx2/fx2_ctrl.hpp
index 98c98bb8c..37fa09605 100644
--- a/host/lib/usrp/fx2/fx2_ctrl.hpp
+++ b/host/lib/usrp/fx2/fx2_ctrl.hpp
@@ -57,7 +57,7 @@ public:
* \param filename name of EEPROM image
*/
virtual void usrp_load_eeprom(std::string filestring) = 0;
-
+
/*!
* Submit an IN transfer
* \param request device specific request
diff --git a/host/lib/usrp/usrp1/dsp_impl.cpp b/host/lib/usrp/usrp1/dsp_impl.cpp
index 66b11b989..0bddc49f0 100644
--- a/host/lib/usrp/usrp1/dsp_impl.cpp
+++ b/host/lib/usrp/usrp1/dsp_impl.cpp
@@ -114,6 +114,7 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t wh
_iface->poke32(FR_DECIM_RATE, _rx_dsp_decim/2 - 1);
this->restore_rx(s);
}
+ this->update_xport_channel_mapping(); //rate changed -> update
return;
case DSP_PROP_STREAM_CMD:
@@ -211,8 +212,10 @@ void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t wh
bool s = this->disable_tx();
_iface->poke32(FR_INTERP_RATE, _tx_dsp_interp/2 - 1);
this->restore_tx(s);
- return;
}
+ this->update_xport_channel_mapping(); //rate changed -> update
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index 8ac2696eb..90ed17cd8 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -15,12 +15,15 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include "../../transport/vrt_packet_handler.hpp"
+#define SRPH_DONT_CHECK_SEQUENCE
+#include "../../transport/super_recv_packet_handler.hpp"
+#include "../../transport/super_send_packet_handler.hpp"
#include "usrp_commands.h"
#include "usrp1_impl.hpp"
#include <uhd/utils/msg.hpp>
#include <uhd/utils/safe_call.hpp>
#include <uhd/utils/thread_priority.hpp>
+#include <uhd/usrp/dsp_props.hpp>
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/bind.hpp>
#include <boost/format.hpp>
@@ -88,13 +91,39 @@ private:
};
/***********************************************************************
+ * BS VRT packer/unpacker functions (since samples don't have headers)
+ **********************************************************************/
+static void usrp1_bs_vrt_packer(
+ boost::uint32_t *,
+ vrt::if_packet_info_t &if_packet_info
+){
+ if_packet_info.num_header_words32 = 0;
+ if_packet_info.num_packet_words32 = if_packet_info.num_payload_words32;
+}
+
+static void usrp1_bs_vrt_unpacker(
+ const boost::uint32_t *,
+ vrt::if_packet_info_t &if_packet_info
+){
+ if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ if_packet_info.num_payload_words32 = if_packet_info.num_packet_words32;
+ if_packet_info.num_header_words32 = 0;
+ if_packet_info.packet_count = 0;
+ if_packet_info.sob = false;
+ if_packet_info.eob = false;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tsi = false;
+ if_packet_info.has_tsf = false;
+ if_packet_info.has_tlr = false;
+}
+
+/***********************************************************************
* IO Implementation Details
**********************************************************************/
struct usrp1_impl::io_impl{
io_impl(zero_copy_if::sptr data_transport):
data_transport(data_transport),
- get_recv_buffs_fcn(boost::bind(&usrp1_impl::io_impl::get_recv_buffs, this, _1)),
- get_send_buffs_fcn(boost::bind(&usrp1_impl::io_impl::get_send_buffs, this, _1)),
underflow_poll_samp_count(0),
overflow_poll_samp_count(0),
curr_buff(offset_send_buffer(data_transport->get_send_buff())),
@@ -109,16 +138,9 @@ struct usrp1_impl::io_impl{
zero_copy_if::sptr data_transport;
- //timeouts set on calls to recv/send (passed into get buffs methods)
- double recv_timeout, send_timeout;
-
- //bound callbacks for get buffs (bound once here, not in fast-path)
- vrt_packet_handler::get_recv_buffs_t get_recv_buffs_fcn;
- vrt_packet_handler::get_send_buffs_t get_send_buffs_fcn;
-
//state management for the vrt packet handler code
- vrt_packet_handler::recv_state packet_handler_recv_state;
- vrt_packet_handler::send_state packet_handler_send_state;
+ sph::recv_packet_handler recv_handler;
+ sph::send_packet_handler send_handler;
//state management for overflow and underflow
size_t underflow_poll_samp_count;
@@ -132,11 +154,13 @@ struct usrp1_impl::io_impl{
offset_managed_send_buffer omsb;
void commit_send_buff(offset_send_buffer&, offset_send_buffer&, size_t);
void flush_send_buff(void);
- bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &);
- bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs){
- UHD_ASSERT_THROW(buffs.size() == 1);
- buffs[0] = data_transport->get_recv_buff(recv_timeout);
- return buffs[0].get() != NULL;
+ managed_send_buffer::sptr get_send_buff(double timeout){
+ //try to get a new managed buffer with timeout
+ offset_send_buffer next_buff(data_transport->get_send_buff(timeout));
+ if (not next_buff.buff.get()) return managed_send_buffer::sptr(); /* propagate timeout here */
+
+ //make a new managed buffer with the offset buffs
+ return omsb.get_new(curr_buff, next_buff);
}
};
@@ -185,32 +209,13 @@ void usrp1_impl::io_impl::flush_send_buff(void){
if (bytes_to_pad == 0) bytes_to_pad = alignment_padding;
//get the buffer, clear, and commit (really current buffer)
- vrt_packet_handler::managed_send_buffs_t buffs(1);
- if (this->get_send_buffs(buffs)){
- std::memset(buffs[0]->cast<void *>(), 0, bytes_to_pad);
- buffs[0]->commit(bytes_to_pad);
+ managed_send_buffer::sptr buff = this->get_send_buff(.1);
+ if (buff.get() != NULL){
+ std::memset(buff->cast<void *>(), 0, bytes_to_pad);
+ buff->commit(bytes_to_pad);
}
}
-/*!
- * Get a managed send buffer with the alignment padding:
- * Always grab the next send buffer so we can timeout here.
- */
-bool usrp1_impl::io_impl::get_send_buffs(
- vrt_packet_handler::managed_send_buffs_t &buffs
-){
- UHD_ASSERT_THROW(buffs.size() == 1);
-
- //try to get a new managed buffer with timeout
- offset_send_buffer next_buff(data_transport->get_send_buff(send_timeout));
- if (not next_buff.buff.get()) return false; /* propagate timeout here */
-
- //make a new managed buffer with the offset buffs
- buffs[0] = omsb.get_new(curr_buff, next_buff);
-
- return true;
-}
-
/***********************************************************************
* Initialize internals within this file
**********************************************************************/
@@ -232,6 +237,34 @@ void usrp1_impl::io_init(void){
this->enable_tx(true); //always enabled
rx_stream_on_off(false);
_io_impl->flush_send_buff();
+
+ //update mapping here since it didnt b4 when io init not called first
+ update_xport_channel_mapping();
+}
+
+void usrp1_impl::update_xport_channel_mapping(void){
+ if (_io_impl.get() == NULL) return; //not inited yet
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock recv_lock = _io_impl->recv_handler.get_scoped_lock();
+ _io_impl->recv_handler.set_vrt_unpacker(&usrp1_bs_vrt_unpacker);
+ _io_impl->recv_handler.set_tick_rate(_clock_ctrl->get_master_clock_freq());
+ _io_impl->recv_handler.set_samp_rate(_rx_dsp_proxies[_rx_dsp_proxies.keys().at(0)]->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ _io_impl->recv_handler.set_xport_chan_get_buff(0, boost::bind(
+ &uhd::transport::zero_copy_if::get_recv_buff, _io_impl->data_transport, _1
+ ));
+ _io_impl->recv_handler.set_converter(_rx_otw_type, _rx_subdev_spec.size());
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock send_lock = _io_impl->send_handler.get_scoped_lock();
+ _io_impl->send_handler.set_vrt_packer(&usrp1_bs_vrt_packer);
+ _io_impl->send_handler.set_tick_rate(_clock_ctrl->get_master_clock_freq());
+ _io_impl->send_handler.set_samp_rate(_tx_dsp_proxies[_tx_dsp_proxies.keys().at(0)]->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ _io_impl->send_handler.set_xport_chan_get_buff(0, boost::bind(
+ &usrp1_impl::io_impl::get_send_buff, _io_impl.get(), _1
+ ));
+ _io_impl->send_handler.set_converter(_tx_otw_type, _tx_subdev_spec.size());
+ _io_impl->send_handler.set_max_samples_per_packet(get_max_send_samps_per_packet());
}
void usrp1_impl::rx_stream_on_off(bool enb){
@@ -245,14 +278,6 @@ void usrp1_impl::rx_stream_on_off(bool enb){
/***********************************************************************
* Data send + helper functions
**********************************************************************/
-static void usrp1_bs_vrt_packer(
- boost::uint32_t *,
- vrt::if_packet_info_t &if_packet_info
-){
- if_packet_info.num_header_words32 = 0;
- if_packet_info.num_packet_words32 = if_packet_info.num_payload_words32;
-}
-
size_t usrp1_impl::get_max_send_samps_per_packet(void) const {
return (_data_transport->get_send_frame_size() - alignment_padding)
/ _tx_otw_type.get_sample_size()
@@ -261,29 +286,21 @@ size_t usrp1_impl::get_max_send_samps_per_packet(void) const {
}
size_t usrp1_impl::send(
- const send_buffs_type &buffs, size_t num_samps,
+ const send_buffs_type &buffs, size_t nsamps_per_buff,
const tx_metadata_t &metadata, const io_type_t &io_type,
send_mode_t send_mode, double timeout
){
- if (_soft_time_ctrl->send_pre(metadata, timeout)) return num_samps;
-
- _io_impl->send_timeout = timeout;
- size_t num_samps_sent = vrt_packet_handler::send(
- _io_impl->packet_handler_send_state, //last state of the send handler
- buffs, num_samps, //buffer to fill
- metadata, send_mode, //samples metadata
- io_type, _tx_otw_type, //input and output types to convert
- _clock_ctrl->get_master_clock_freq(), //master clock tick rate
- &usrp1_bs_vrt_packer,
- _io_impl->get_send_buffs_fcn,
- get_max_send_samps_per_packet(),
- 0, //vrt header offset
- _tx_subdev_spec.size() //num channels
+ if (_soft_time_ctrl->send_pre(metadata, timeout)) return 0;
+
+ size_t num_samps_sent = _io_impl->send_handler.send(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ send_mode, timeout
);
//handle eob flag (commit the buffer, disable the DACs)
//check num samps sent to avoid flush on incomplete/timeout
- if (metadata.end_of_burst and num_samps_sent == num_samps){
+ if (metadata.end_of_burst and num_samps_sent == nsamps_per_buff){
_io_impl->flush_send_buff();
}
@@ -306,23 +323,6 @@ size_t usrp1_impl::send(
/***********************************************************************
* Data recv + helper functions
**********************************************************************/
-static void usrp1_bs_vrt_unpacker(
- const boost::uint32_t *,
- vrt::if_packet_info_t &if_packet_info
-){
- if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA;
- if_packet_info.num_payload_words32 = if_packet_info.num_packet_words32;
- if_packet_info.num_header_words32 = 0;
- if_packet_info.packet_count = 0;
- if_packet_info.sob = false;
- if_packet_info.eob = false;
- if_packet_info.has_sid = false;
- if_packet_info.has_cid = false;
- if_packet_info.has_tsi = false;
- if_packet_info.has_tsf = false;
- if_packet_info.has_tlr = false;
-}
-
size_t usrp1_impl::get_max_recv_samps_per_packet(void) const {
return _data_transport->get_recv_frame_size()
/ _rx_otw_type.get_sample_size()
@@ -331,22 +331,14 @@ size_t usrp1_impl::get_max_recv_samps_per_packet(void) const {
}
size_t usrp1_impl::recv(
- const recv_buffs_type &buffs, size_t num_samps,
+ const recv_buffs_type &buffs, size_t nsamps_per_buff,
rx_metadata_t &metadata, const io_type_t &io_type,
recv_mode_t recv_mode, double timeout
){
- _io_impl->recv_timeout = timeout;
- size_t num_samps_recvd = vrt_packet_handler::recv(
- _io_impl->packet_handler_recv_state, //last state of the recv handler
- buffs, num_samps, //buffer to fill
- metadata, recv_mode, //samples metadata
- io_type, _rx_otw_type, //input and output types to convert
- _clock_ctrl->get_master_clock_freq(), //master clock tick rate
- &usrp1_bs_vrt_unpacker,
- _io_impl->get_recv_buffs_fcn,
- &vrt_packet_handler::handle_overflow_nop,
- 0, //vrt header offset
- _rx_subdev_spec.size() //num channels
+ size_t num_samps_recvd = _io_impl->recv_handler.recv(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ recv_mode, timeout
);
_soft_time_ctrl->recv_post(metadata, num_samps_recvd);
diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp
index f699c8e12..a265a5089 100644
--- a/host/lib/usrp/usrp1/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1/mboard_impl.cpp
@@ -352,6 +352,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
bool s = this->disable_rx();
_iface->poke32(FR_RX_MUX, calc_rx_mux(_rx_subdev_spec, _mboard_proxy->get_link()));
this->restore_rx(s);
+ this->update_xport_channel_mapping();
}return;
case MBOARD_PROP_TX_SUBDEV_SPEC:{
@@ -367,6 +368,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
bool s = this->disable_tx();
_iface->poke32(FR_TX_MUX, calc_tx_mux(_tx_subdev_spec, _mboard_proxy->get_link()));
this->restore_tx(s);
+ this->update_xport_channel_mapping();
}return;
case MBOARD_PROP_EEPROM_MAP:
@@ -387,6 +389,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
<< "See the application notes for USRP1 for further instructions.\n"
;
_clock_ctrl->set_master_clock_freq(val.as<double>());
+ this->update_xport_channel_mapping();
return;
case MBOARD_PROP_CLOCK_CONFIG:{
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 37955d628..a3d502038 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -199,12 +199,12 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,
//initialize the dsps
tx_dsp_init();
- //initialize the send/recv
- io_init();
-
//init the subdev specs
this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t());
this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t());
+
+ //initialize the send/recv
+ io_init();
}
usrp1_impl::~usrp1_impl(void){UHD_SAFE_CALL(
diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp
index fbae2a3b9..bea1dbe3b 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.hpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.hpp
@@ -114,6 +114,9 @@ private:
const uhd::usrp::dboard_id_t &rx_dboard_id
);
+ //!call when the channel mapping is changed
+ void update_xport_channel_mapping(void);
+
//soft time control emulation
uhd::usrp::soft_time_ctrl::sptr _soft_time_ctrl;
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 292659f36..03cdeae42 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -118,12 +118,6 @@ void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd, siz
_iface->poke32(U2_REG_RX_CTRL_TIME_TICKS(which_dsp), stream_cmd.time_spec.get_tick_count(get_master_clock_freq()));
}
-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
**********************************************************************/
@@ -186,6 +180,7 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val, size_
dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
);
}
+ _device.update_xport_channel_mapping(); //rate changed -> update
return;
default: UHD_THROW_PROP_SET_ERROR();
@@ -259,6 +254,7 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val, size_
//set the scaling
_iface->poke32(U2_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_dsp_impl->duc_interp[which_dsp]));
}
+ _device.update_xport_channel_mapping(); //rate changed -> update
return;
default: UHD_THROW_PROP_SET_ERROR();
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 33f249599..ffe9a88e7 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -15,18 +15,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include "../../transport/vrt_packet_handler.hpp"
+#include "../../transport/super_recv_packet_handler.hpp"
+#include "../../transport/super_send_packet_handler.hpp"
#include "usrp2_impl.hpp"
#include "usrp2_regs.hpp"
#include <uhd/utils/log.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/exception.hpp>
#include <uhd/usrp/mboard_props.hpp>
+#include <uhd/usrp/dsp_props.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <iostream>
@@ -80,14 +83,21 @@ public:
}
/*!
+ * Gets the current sequence number to go out.
+ * Increments the sequence for the next call
+ * \return the sequence to be sent to the dsp
+ */
+ UHD_INLINE seq_type get_curr_seq_out(void){
+ return _last_seq_out++;
+ }
+
+ /*!
* Check the flow control condition.
- * \param seq the sequence to go out
* \param timeout the timeout in seconds
* \return false on timeout
*/
- UHD_INLINE bool check_fc_condition(seq_type seq, double timeout){
- boost::unique_lock<boost::mutex> lock(_fc_mutex);
- _last_seq_out = seq;
+ UHD_INLINE bool check_fc_condition(double timeout){
+ boost::mutex::scoped_lock lock(_fc_mutex);
if (this->ready()) return true;
boost::this_thread::disable_interruption di; //disable because the wait can throw
return _fc_cond.timed_wait(lock, to_time_dur(timeout), _ready_fcn);
@@ -98,7 +108,7 @@ public:
* \param seq the last sequence number to be ACK'd
*/
UHD_INLINE void update_fc_condition(seq_type seq){
- boost::unique_lock<boost::mutex> lock(_fc_mutex);
+ boost::mutex::scoped_lock lock(_fc_mutex);
_last_seq_ack = seq;
lock.unlock();
_fc_cond.notify_one();
@@ -116,23 +126,6 @@ private:
};
/***********************************************************************
- * Alignment indexes class: keeps track of indexes
- **********************************************************************/
-class alignment_indexes{
-public:
- alignment_indexes(void){_indexes = 0;}
- void reset(size_t len){_indexes = (1 << len) - 1;}
- size_t front(void){ //TODO replace with look-up table
- size_t index = 0;
- while ((_indexes & (1 << index)) == 0) index++;
- return index;
- }
- void remove(size_t index){_indexes &= ~(1 << index);}
- bool empty(void){return _indexes == 0;}
-private: size_t _indexes;
-};
-
-/***********************************************************************
* io impl details (internal to this file)
* - pirate crew
* - alignment buffer
@@ -143,24 +136,13 @@ struct usrp2_impl::io_impl{
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)),
async_msg_fifo(100/*messages deep*/)
{
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){
@@ -169,38 +151,27 @@ struct usrp2_impl::io_impl{
recv_pirate_crew.join_all();
}
- bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){
- UHD_ASSERT_THROW(send_map.size() == buffs.size());
+ managed_send_buffer::sptr get_send_buff(size_t chan, double timeout){
+ const size_t index = send_map[chan];
+ flow_control_monitor &fc_mon = *fc_mons[index];
- //calculate the flow control word
- const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq;
+ //wait on flow control w/ timeout
+ if (not fc_mon.check_fc_condition(timeout)) return managed_send_buffer::sptr();
- //grab a managed buffer for each index
- for (size_t i = 0; i < buffs.size(); i++){
- 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);
- }
- return true;
- }
+ //get a buffer from the transport w/ timeout
+ managed_send_buffer::sptr buff = dsp_xports[index]->get_send_buff(timeout);
+
+ //write the flow control word into the buffer
+ if (buff.get()) buff->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_mon.get_curr_seq_out());
- 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);
+ return buff;
+ }
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;
-
- //bound callbacks for get buffs (bound once here, not in fast-path)
- vrt_packet_handler::get_recv_buffs_t get_recv_buffs_fcn;
- vrt_packet_handler::get_send_buffs_t get_send_buffs_fcn;
-
//previous state for each buffer
std::vector<vrt::if_packet_info_t> prev_infos;
@@ -208,8 +179,8 @@ struct usrp2_impl::io_impl{
std::vector<flow_control_monitor::sptr> fc_mons;
//state management for the vrt packet handler code
- vrt_packet_handler::recv_state packet_handler_recv_state;
- vrt_packet_handler::send_state packet_handler_send_state;
+ sph::recv_packet_handler recv_handler;
+ sph::send_packet_handler send_handler;
//methods and variables for the pirate crew
void recv_pirate_loop(boost::barrier &, usrp2_mboard_impl::sptr, zero_copy_if::sptr, size_t);
@@ -258,7 +229,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(
metadata.time_spec = time_spec_t(
time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), mboard->get_master_clock_freq()
);
- metadata.event_code = vrt_packet_handler::get_context_code<async_metadata_t::event_code_t>(vrt_hdr, if_packet_info);
+ metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
//catch the flow control packets and react
if (metadata.event_code == 0){
@@ -327,8 +298,39 @@ void usrp2_impl::update_xport_channel_mapping(void){
}
- _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());
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock recv_lock = _io_impl->recv_handler.get_scoped_lock();
+ _io_impl->recv_handler.resize(_io_impl->recv_map.size());
+ _io_impl->recv_handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be);
+ _io_impl->recv_handler.set_tick_rate(_mboards.front()->get_master_clock_freq());
+ //TODO temporarily use the first dsp rate until we support non-homo rates
+ const std::string rx_dsp_name = _mboards.at(0)->get_link()[MBOARD_PROP_RX_DSP_NAMES].as<prop_names_t>().at(0);
+ const double rx_host_rate = _mboards.at(0)->get_link()[named_prop_t(MBOARD_PROP_RX_DSP, rx_dsp_name)][DSP_PROP_HOST_RATE].as<double>();
+ _io_impl->recv_handler.set_samp_rate(rx_host_rate);
+ for (size_t chan = 0; chan < _io_impl->recv_handler.size(); chan++){
+ _io_impl->recv_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &uhd::transport::zero_copy_if::get_recv_buff,
+ _io_impl->dsp_xports[_io_impl->recv_map[chan]], _1
+ ));
+ }
+ _io_impl->recv_handler.set_converter(_rx_otw_type);
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock send_lock = _io_impl->send_handler.get_scoped_lock();
+ _io_impl->send_handler.resize(_io_impl->send_map.size());
+ _io_impl->send_handler.set_vrt_packer(&vrt::if_hdr_pack_be, vrt_send_header_offset_words32);
+ _io_impl->send_handler.set_tick_rate(_mboards.front()->get_master_clock_freq());
+ //TODO temporarily use the first dsp rate until we support non-homo rates
+ const std::string tx_dsp_name = _mboards.at(0)->get_link()[MBOARD_PROP_TX_DSP_NAMES].as<prop_names_t>().at(0);
+ const double tx_host_rate = _mboards.at(0)->get_link()[named_prop_t(MBOARD_PROP_TX_DSP, tx_dsp_name)][DSP_PROP_HOST_RATE].as<double>();
+ _io_impl->send_handler.set_samp_rate(tx_host_rate);
+ for (size_t chan = 0; chan < _io_impl->send_handler.size(); chan++){
+ _io_impl->send_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &usrp2_impl::io_impl::get_send_buff, _io_impl.get(), chan, _1
+ ));
+ }
+ _io_impl->send_handler.set_converter(_tx_otw_type);
+ _io_impl->send_handler.set_max_samples_per_packet(get_max_send_samps_per_packet());
}
/***********************************************************************
@@ -355,143 +357,17 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{
}
size_t usrp2_impl::send(
- const send_buffs_type &buffs, size_t num_samps,
+ const send_buffs_type &buffs, size_t nsamps_per_buff,
const tx_metadata_t &metadata, const io_type_t &io_type,
send_mode_t send_mode, double timeout
){
- _io_impl->send_timeout = timeout;
- return vrt_packet_handler::send(
- _io_impl->packet_handler_send_state, //last state of the send handler
- buffs, num_samps, //buffer to fill
- metadata, send_mode, //samples metadata
- io_type, _tx_otw_type, //input and output types to convert
- _mboards.front()->get_master_clock_freq(), //master clock tick rate
- uhd::transport::vrt::if_hdr_pack_be,
- _io_impl->get_send_buffs_fcn,
- get_max_send_samps_per_packet(),
- vrt_send_header_offset_words32
- );
-}
-
-/***********************************************************************
- * Alignment logic on receive
- **********************************************************************/
-static UHD_INLINE time_spec_t extract_time_spec(
- const vrt::if_packet_info_t &packet_info
-){
- return time_spec_t( //assumes has_tsi and has_tsf are true
- time_t(packet_info.tsi), size_t(packet_info.tsf),
- 100e6 //tick rate does not have to be correct for comparison purposes
+ return _io_impl->send_handler.send(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ send_mode, timeout
);
}
-static UHD_INLINE void extract_packet_info(
- managed_recv_buffer::sptr &buff,
- vrt::if_packet_info_t &prev_info,
- time_spec_t &time, bool &clear, bool &msg
-){
- //extract packet info
- vrt::if_packet_info_t next_info;
- next_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
- vrt::if_hdr_unpack_be(buff->cast<const boost::uint32_t *>(), next_info);
-
- //handle the packet count / sequence number
- if ((prev_info.packet_count+1)%16 != next_info.packet_count){
- UHD_MSG(fastpath) << "O"; //report overflow (drops in the kernel)
- }
-
- time = extract_time_spec(next_info);
- clear = extract_time_spec(prev_info) > time;
- msg = next_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA;
- prev_info = next_info;
-}
-
-static UHD_INLINE bool handle_msg_packet(
- vrt_packet_handler::managed_recv_buffs_t &buffs, size_t index
-){
- for (size_t i = 0; i < buffs.size(); i++){
- if (i == index) continue;
- buffs[i].reset(); //set NULL
- }
- return true;
-}
-
-UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(
- vrt_packet_handler::managed_recv_buffs_t &buffs
-){
- if (buffs.size() == 1){
- 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[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;
- 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_pop_initial;
-
- //respond to a clear by starting from scratch
- got_clear:
- indexes_to_do.reset(buffs.size());
- clear = false;
-
- //do an initial pop to load an initial sequence id
- 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[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 = 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[recv_map[index]], this_time, clear, msg);
- if (clear) goto got_clear;
- buffs[index] = buff_tmp;
- if (msg) return handle_msg_packet(buffs, index);
-
- //if the sequence id matches:
- // remove this index from the list and continue
- if (this_time == expected_time){
- indexes_to_do.remove(index);
- }
-
- //if the sequence id is newer:
- // use the new expected time for comparison
- // add all other indexes back into the list
- else if (this_time > expected_time){
- expected_time = this_time;
- indexes_to_do.reset(buffs.size());
- indexes_to_do.remove(index);
- }
-
- //if the sequence id is older:
- // continue with the same index to try again
- //else if (this_time < expected_time)...
-
- }
- return true;
- //-------------------- end alignment logic -----------------------//
-}
-
/***********************************************************************
* Receive Data
**********************************************************************/
@@ -505,26 +381,14 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
return bpp/_rx_otw_type.get_sample_size();
}
-void usrp2_impl::handle_overflow(size_t chan){
- UHD_MSG(fastpath) << "O";
- ldiv_t indexes = ldiv(chan, usrp2_mboard_impl::NUM_RX_DSPS);
- _mboards.at(indexes.quot)->handle_overflow(indexes.rem);
-}
-
size_t usrp2_impl::recv(
- const recv_buffs_type &buffs, size_t num_samps,
+ const recv_buffs_type &buffs, size_t nsamps_per_buff,
rx_metadata_t &metadata, const io_type_t &io_type,
recv_mode_t recv_mode, double timeout
){
- _io_impl->recv_timeout = timeout;
- return vrt_packet_handler::recv(
- _io_impl->packet_handler_recv_state, //last state of the recv handler
- buffs, num_samps, //buffer to fill
- metadata, recv_mode, //samples metadata
- io_type, _rx_otw_type, //input and output types to convert
- _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(&usrp2_impl::handle_overflow, this, _1)
+ return _io_impl->recv_handler.recv(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ recv_mode, timeout
);
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 4a28ea9c4..6bf412a3e 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -466,6 +466,7 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
case MBOARD_PROP_CLOCK_RATE:
UHD_ASSERT_THROW(val.as<double>() == this->get_master_clock_freq());
+ _device.update_xport_channel_mapping();
return;
default: UHD_THROW_PROP_SET_ERROR();
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index ccaf0c9a8..4d19863b1 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -220,7 +220,6 @@ private:
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/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp
index 8d084f066..93034b5dc 100644
--- a/host/lib/usrp/usrp_e100/dsp_impl.cpp
+++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp
@@ -104,6 +104,7 @@ void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){
dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
);
}
+ this->update_xport_channel_mapping(); //rate changed -> update
return;
default: UHD_THROW_PROP_SET_ERROR();
@@ -181,6 +182,7 @@ void usrp_e100_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){
//set the scaling
_iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp));
}
+ this->update_xport_channel_mapping(); //rate changed -> update
return;
default: UHD_THROW_PROP_SET_ERROR();
diff --git a/host/lib/usrp/usrp_e100/io_impl.cpp b/host/lib/usrp/usrp_e100/io_impl.cpp
index aa6e7c485..91b129276 100644
--- a/host/lib/usrp/usrp_e100/io_impl.cpp
+++ b/host/lib/usrp/usrp_e100/io_impl.cpp
@@ -15,14 +15,16 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include "../../transport/super_recv_packet_handler.hpp"
+#include "../../transport/super_send_packet_handler.hpp"
#include "usrp_e100_impl.hpp"
#include "usrp_e100_regs.hpp"
#include <uhd/utils/msg.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/usrp/dsp_utils.hpp>
+#include <uhd/usrp/dsp_props.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/transport/bounded_buffer.hpp>
-#include "../../transport/vrt_packet_handler.hpp"
#include <boost/bind.hpp>
#include <boost/format.hpp>
#include <boost/thread/thread.hpp>
@@ -51,8 +53,6 @@ static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | asyn
struct usrp_e100_impl::io_impl{
io_impl(zero_copy_if::sptr &xport):
data_xport(xport),
- get_recv_buffs_fcn(boost::bind(&usrp_e100_impl::io_impl::get_recv_buffs, this, _1)),
- get_send_buffs_fcn(boost::bind(&usrp_e100_impl::io_impl::get_send_buffs, this, _1)),
recv_pirate_booty(data_xport->get_num_recv_frames()),
async_msg_fifo(100/*messages deep*/)
{
@@ -65,16 +65,11 @@ struct usrp_e100_impl::io_impl{
recv_pirate_crew.join_all();
}
- bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs){
- UHD_ASSERT_THROW(buffs.size() == 1);
+ managed_recv_buffer::sptr get_recv_buff(double timeout){
boost::this_thread::disable_interruption di; //disable because the wait can throw
- return recv_pirate_booty.pop_with_timed_wait(buffs.front(), recv_timeout);
- }
-
- bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){
- UHD_ASSERT_THROW(buffs.size() == 1);
- buffs[0] = data_xport->get_send_buff(send_timeout);
- return buffs[0].get() != NULL;
+ managed_recv_buffer::sptr buff;
+ recv_pirate_booty.pop_with_timed_wait(buff, timeout);
+ return buff; //ASSUME buff == NULL when pop times-out
}
//The data transport is listed first so that it is deconstructed last,
@@ -82,16 +77,9 @@ struct usrp_e100_impl::io_impl{
//This comment is invalid because its now a reference and not stored here.
zero_copy_if::sptr &data_xport;
- //bound callbacks for get buffs (bound once here, not in fast-path)
- vrt_packet_handler::get_recv_buffs_t get_recv_buffs_fcn;
- vrt_packet_handler::get_send_buffs_t get_send_buffs_fcn;
-
- //timeouts set on calls to recv/send (passed into get buffs methods)
- double recv_timeout, send_timeout;
-
//state management for the vrt packet handler code
- vrt_packet_handler::recv_state packet_handler_recv_state;
- vrt_packet_handler::send_state packet_handler_send_state;
+ sph::recv_packet_handler recv_handler;
+ sph::send_packet_handler send_handler;
bool continuous_streaming;
//a pirate's life is the life for me!
@@ -133,16 +121,18 @@ void usrp_e100_impl::io_impl::recv_pirate_loop(
vrt::if_packet_info_t if_packet_info;
if_packet_info.num_packet_words32 = buff->size()/sizeof(boost::uint32_t);
const boost::uint32_t *vrt_hdr = buff->cast<const boost::uint32_t *>();
- vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info);
//handle an rx data packet or inline message
- if (if_packet_info.sid == rx_data_inline_sid){
+ if (uhd::ntohx(vrt_hdr[1]) == rx_data_inline_sid){ //ASSUME has_sid
if (fp_recv_debug) UHD_LOGV(always) << "this is rx_data_inline_sid\n";
//same number of frames as the data transport -> always immediate
recv_pirate_booty.push_with_wait(buff);
continue;
}
+ //unpack the vrt header and process below...
+ vrt::if_hdr_unpack_le(vrt_hdr, if_packet_info);
+
//handle a tx async report message
if (if_packet_info.sid == tx_async_report_sid and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){
if (fp_recv_debug) UHD_LOGV(always) << "this is tx_async_report_sid\n";
@@ -154,7 +144,7 @@ void usrp_e100_impl::io_impl::recv_pirate_loop(
metadata.time_spec = time_spec_t(
time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), clock_ctrl->get_fpga_clock_rate()
);
- metadata.event_code = vrt_packet_handler::get_context_code<async_metadata_t::event_code_t>(vrt_hdr, if_packet_info);
+ metadata.event_code = async_metadata_t::event_code_t(sph::get_context_code(vrt_hdr, if_packet_info));
//print the famous U, and push the metadata into the message queue
if (metadata.event_code & underflow_flags) UHD_MSG(fastpath) << "U";
@@ -162,6 +152,7 @@ void usrp_e100_impl::io_impl::recv_pirate_loop(
continue;
}
+ //TODO replace this below with a UHD_MSG(error)
if (fp_recv_debug) UHD_LOGV(always) << "this is unknown packet\n";
}catch(const std::exception &e){
@@ -213,6 +204,42 @@ void usrp_e100_impl::io_init(void){
boost::ref(spawn_barrier), _clock_ctrl
));
spawn_barrier.wait();
+ //update mapping here since it didnt b4 when io init not called first
+ update_xport_channel_mapping();
+}
+
+void usrp_e100_impl::update_xport_channel_mapping(void){
+ if (_io_impl.get() == NULL) return; //not inited yet
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock recv_lock = _io_impl->recv_handler.get_scoped_lock();
+ _io_impl->recv_handler.resize(_rx_subdev_spec.size());
+ _io_impl->recv_handler.set_vrt_unpacker(&vrt::if_hdr_unpack_le);
+ _io_impl->recv_handler.set_tick_rate(_clock_ctrl->get_fpga_clock_rate());
+ _io_impl->recv_handler.set_samp_rate(_rx_ddc_proxy->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < _io_impl->recv_handler.size(); chan++){
+ _io_impl->recv_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &usrp_e100_impl::io_impl::get_recv_buff, _io_impl.get(), _1
+ ));
+ _io_impl->recv_handler.set_overflow_handler(chan, boost::bind(
+ &usrp_e100_impl::handle_overrun, this, chan
+ ));
+ }
+ _io_impl->recv_handler.set_converter(_recv_otw_type);
+
+ //set all of the relevant properties on the handler
+ boost::mutex::scoped_lock send_lock = _io_impl->send_handler.get_scoped_lock();
+ _io_impl->send_handler.resize(_tx_subdev_spec.size());
+ _io_impl->send_handler.set_vrt_packer(&vrt::if_hdr_pack_le);
+ _io_impl->send_handler.set_tick_rate(_clock_ctrl->get_fpga_clock_rate());
+ _io_impl->send_handler.set_samp_rate(_tx_duc_proxy->get_link()[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < _io_impl->send_handler.size(); chan++){
+ _io_impl->send_handler.set_xport_chan_get_buff(chan, boost::bind(
+ &uhd::transport::zero_copy_if::get_send_buff, _io_impl->data_xport, _1
+ ));
+ }
+ _io_impl->send_handler.set_converter(_send_otw_type);
+ _io_impl->send_handler.set_max_samples_per_packet(get_max_send_samps_per_packet());
}
void usrp_e100_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){
@@ -222,8 +249,7 @@ void usrp_e100_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){
_iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate()));
}
-void usrp_e100_impl::handle_overrun(size_t){
- UHD_MSG(fastpath) << "O"; //the famous OOOOOOOOOOO
+void usrp_e100_impl::handle_overrun(size_t /*chan*/){
if (_io_impl->continuous_streaming){
this->issue_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
}
@@ -242,20 +268,14 @@ size_t usrp_e100_impl::get_max_send_samps_per_packet(void) const{
}
size_t usrp_e100_impl::send(
- const send_buffs_type &buffs, size_t num_samps,
+ const send_buffs_type &buffs, size_t nsamps_per_buff,
const tx_metadata_t &metadata, const io_type_t &io_type,
send_mode_t send_mode, double timeout
){
- _io_impl->send_timeout = timeout;
- return vrt_packet_handler::send(
- _io_impl->packet_handler_send_state, //last state of the send handler
- buffs, num_samps, //buffer to fill
- metadata, send_mode, //samples metadata
- io_type, _send_otw_type, //input and output types to convert
- _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate
- uhd::transport::vrt::if_hdr_pack_le,
- _io_impl->get_send_buffs_fcn,
- get_max_send_samps_per_packet()
+ return _io_impl->send_handler.send(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ send_mode, timeout
);
}
@@ -273,20 +293,14 @@ size_t usrp_e100_impl::get_max_recv_samps_per_packet(void) const{
}
size_t usrp_e100_impl::recv(
- const recv_buffs_type &buffs, size_t num_samps,
+ const recv_buffs_type &buffs, size_t nsamps_per_buff,
rx_metadata_t &metadata, const io_type_t &io_type,
recv_mode_t recv_mode, double timeout
){
- _io_impl->recv_timeout = timeout;
- return vrt_packet_handler::recv(
- _io_impl->packet_handler_recv_state, //last state of the recv handler
- buffs, num_samps, //buffer to fill
- metadata, recv_mode, //samples metadata
- io_type, _recv_otw_type, //input and output types to convert
- _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate
- uhd::transport::vrt::if_hdr_unpack_le,
- _io_impl->get_recv_buffs_fcn,
- boost::bind(&usrp_e100_impl::handle_overrun, this, _1)
+ return _io_impl->recv_handler.recv(
+ buffs, nsamps_per_buff,
+ metadata, io_type,
+ recv_mode, timeout
);
}
diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp
index 483286e47..f4b8d79f6 100644
--- a/host/lib/usrp/usrp_e100/mboard_impl.cpp
+++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp
@@ -214,6 +214,7 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){
<< "See the application notes for USRP-E1XX for further instructions.\n"
;
_clock_ctrl->set_fpga_clock_rate(val.as<double>());
+ this->update_xport_channel_mapping();
return;
default: UHD_THROW_PROP_SET_ERROR();
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
index e9e9b6e20..5b039aafc 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp
@@ -39,7 +39,7 @@ static device_addrs_t usrp_e100_find(const device_addr_t &hint){
device_addrs_t usrp_e100_addrs;
//return an empty list of addresses when type is set to non-usrp-e
- if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e100_addrs;
+ if (hint.has_key("type") and hint["type"] != "e100") return usrp_e100_addrs;
//device node not provided, assume its 0
if (not hint.has_key("node")){
@@ -171,12 +171,13 @@ usrp_e100_impl::usrp_e100_impl(
//init the codec properties
codec_init();
- //init the io send/recv
- io_init();
-
//set default subdev specs
this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t());
this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t());
+
+ //init the io send/recv
+ io_init();
+
}
usrp_e100_impl::~usrp_e100_impl(void){
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp
index 318a75191..1c17863fb 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp
@@ -104,6 +104,7 @@ private:
void io_init(void);
void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd);
void handle_overrun(size_t);
+ void update_xport_channel_mapping(void);
//configuration shadows
uhd::clock_config_t _clock_config;
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index b38afccf0..b7bcfb7d5 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -28,6 +28,8 @@ SET(test_sources
gain_group_test.cpp
msg_test.cpp
ranges_test.cpp
+ sph_recv_test.cpp
+ sph_send_test.cpp
subdev_spec_test.cpp
time_spec_test.cpp
tune_helper_test.cpp
diff --git a/host/tests/convert_test.cpp b/host/tests/convert_test.cpp
index d1c2b7625..d828ed64a 100644
--- a/host/tests/convert_test.cpp
+++ b/host/tests/convert_test.cpp
@@ -31,7 +31,7 @@ typedef std::complex<boost::int16_t> sc16_t;
typedef std::complex<float> fc32_t;
typedef std::complex<double> fc64_t;
-#define MY_CHECK_CLOSE(a, b, f) if ((std::abs(a) > (f) and std::abs(b) > (f))) \
+#define MY_CHECK_CLOSE(a, b, f) if ((std::abs(a) > (f))) \
BOOST_CHECK_CLOSE_FRACTION(a, b, f)
/***********************************************************************
@@ -55,12 +55,12 @@ template <typename Range> static void loopback(
//convert to intermediate type
convert::get_converter_cpu_to_otw(
io_type, otw_type, input0.size(), output0.size()
- )(input0, output0, nsamps);
+ )(input0, output0, nsamps, 32767.);
//convert back to host type
convert::get_converter_otw_to_cpu(
io_type, otw_type, input1.size(), output1.size()
- )(input1, output1, nsamps);
+ )(input1, output1, nsamps, 1/32767.);
}
/***********************************************************************
@@ -207,12 +207,12 @@ BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){
//convert float to intermediate
convert::get_converter_cpu_to_otw(
io_type_in, otw_type, input0.size(), output0.size()
- )(input0, output0, nsamps);
+ )(input0, output0, nsamps, 32767.);
//convert intermediate to short
convert::get_converter_otw_to_cpu(
io_type_out, otw_type, input1.size(), output1.size()
- )(input1, output1, nsamps);
+ )(input1, output1, nsamps, 1/32767.);
//test that the inputs and outputs match
for (size_t i = 0; i < nsamps; i++){
@@ -247,12 +247,12 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){
//convert short to intermediate
convert::get_converter_cpu_to_otw(
io_type_in, otw_type, input0.size(), output0.size()
- )(input0, output0, nsamps);
+ )(input0, output0, nsamps, 32767.);
//convert intermediate to float
convert::get_converter_otw_to_cpu(
io_type_out, otw_type, input1.size(), output1.size()
- )(input1, output1, nsamps);
+ )(input1, output1, nsamps, 1/32767.);
//test that the inputs and outputs match
for (size_t i = 0; i < nsamps; i++){
diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp
new file mode 100644
index 000000000..6bb5d1175
--- /dev/null
+++ b/host/tests/sph_recv_test.cpp
@@ -0,0 +1,715 @@
+//
+// 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 <boost/test/unit_test.hpp>
+#include "../lib/transport/super_recv_packet_handler.hpp"
+#include <boost/shared_array.hpp>
+#include <boost/bind.hpp>
+#include <complex>
+#include <vector>
+#include <list>
+
+#define BOOST_CHECK_TS_CLOSE(a, b) \
+ BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001)
+
+/***********************************************************************
+ * A dummy managed receive buffer for testing
+ **********************************************************************/
+class dummy_mrb : public uhd::transport::managed_recv_buffer{
+public:
+ void release(void){
+ //NOP
+ }
+
+ sptr get_new(boost::shared_array<char> mem, size_t len){
+ _mem = mem;
+ _len = len;
+ return make_managed_buffer(this);
+ }
+
+private:
+ const void *get_buff(void) const{return _mem.get();}
+ size_t get_size(void) const{return _len;}
+
+ boost::shared_array<char> _mem;
+ size_t _len;
+};
+
+/***********************************************************************
+ * A dummy transport class to fill with fake data
+ **********************************************************************/
+class dummy_recv_xport_class{
+public:
+ dummy_recv_xport_class(const uhd::otw_type_t &otw_type){
+ _otw_type = otw_type;
+ }
+
+ void push_back_packet(
+ uhd::transport::vrt::if_packet_info_t &ifpi,
+ const boost::uint32_t optional_msg_word = 0
+ ){
+ const size_t max_pkt_len = (ifpi.num_payload_words32 + uhd::transport::vrt::max_if_hdr_words32 + 1/*tlr*/)*sizeof(boost::uint32_t);
+ _mems.push_back(boost::shared_array<char>(new char[max_pkt_len]));
+ if (_otw_type.byteorder == uhd::otw_type_t::BO_BIG_ENDIAN){
+ uhd::transport::vrt::if_hdr_pack_be(reinterpret_cast<boost::uint32_t *>(_mems.back().get()), ifpi);
+ }
+ if (_otw_type.byteorder == uhd::otw_type_t::BO_LITTLE_ENDIAN){
+ uhd::transport::vrt::if_hdr_pack_le(reinterpret_cast<boost::uint32_t *>(_mems.back().get()), ifpi);
+ }
+ (reinterpret_cast<boost::uint32_t *>(_mems.back().get()) + ifpi.num_header_words32)[0] = optional_msg_word | uhd::byteswap(optional_msg_word);
+ _lens.push_back(ifpi.num_packet_words32*sizeof(boost::uint32_t));
+ }
+
+ uhd::transport::managed_recv_buffer::sptr get_recv_buff(double){
+ if (_mems.empty()) return uhd::transport::managed_recv_buffer::sptr(); //timeout
+ _mrbs.push_back(dummy_mrb());
+ uhd::transport::managed_recv_buffer::sptr mrb = _mrbs.back().get_new(_mems.front(), _lens.front());
+ _mems.pop_front();
+ _lens.pop_front();
+ return mrb;
+ }
+
+private:
+ std::list<boost::shared_array<char> > _mems;
+ std::list<size_t> _lens;
+ std::list<dummy_mrb> _mrbs; //list means no-realloc
+ uhd::otw_type_t _otw_type;
+};
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ dummy_recv_xport_class dummy_recv_xport(otw_type);
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ dummy_recv_xport.push_back_packet(ifpi);
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(1);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1));
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > buff(20);
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ dummy_recv_xport_class dummy_recv_xport(otw_type);
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ if (i != NUM_PKTS_TO_TEST/2){ //simulate a lost packet
+ dummy_recv_xport.push_back_packet(ifpi);
+ }
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(1);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1));
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > buff(20);
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ if (i == NUM_PKTS_TO_TEST/2){
+ //must get the soft overflow here
+ BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ num_accum_samps += 10 + i%10;
+ }
+ else{
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ }
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ dummy_recv_xport_class dummy_recv_xport(otw_type);
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ dummy_recv_xport.push_back_packet(ifpi);
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+
+ //simulate overflow
+ if (i == NUM_PKTS_TO_TEST/2){
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_EXTENSION;
+ ifpi.num_payload_words32 = 1;
+ dummy_recv_xport.push_back_packet(ifpi, uhd::rx_metadata_t::ERROR_CODE_OVERFLOW);
+ ifpi.packet_count++;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ }
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(1);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1));
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > buff(20);
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ if (i == NUM_PKTS_TO_TEST/2){
+ handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ std::cout << "metadata.error_code " << metadata.error_code << std::endl;
+ BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ }
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+ static const size_t NUM_SAMPS_PER_BUFF = 20;
+ static const size_t NCHANNELS = 4;
+
+ std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class(otw_type));
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ dummy_recv_xports[ch].push_back_packet(ifpi);
+ }
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(NCHANNELS);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1));
+ }
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::vector<std::complex<float> *> buffs(NCHANNELS);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
+ }
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+ static const size_t NUM_SAMPS_PER_BUFF = 20;
+ static const size_t NCHANNELS = 4;
+
+ std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class(otw_type));
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ if (i == NUM_PKTS_TO_TEST/2 and ch == 2){
+ continue; //simulates a lost packet
+ }
+ dummy_recv_xports[ch].push_back_packet(ifpi);
+ }
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(NCHANNELS);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1));
+ }
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::vector<std::complex<float> *> buffs(NCHANNELS);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
+ }
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ if (i == NUM_PKTS_TO_TEST/2){
+ //must get the soft overflow here
+ BOOST_REQUIRE(metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ num_accum_samps += 10 + i%10;
+ }
+ else{
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ }
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+ static const size_t NUM_SAMPS_PER_BUFF = 20;
+ static const size_t NCHANNELS = 4;
+
+ std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class(otw_type));
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ dummy_recv_xports[ch].push_back_packet(ifpi);
+ }
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ if (i == NUM_PKTS_TO_TEST/2){
+ ifpi.tsf = 0; //simulate the user changing the time
+ }
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(NCHANNELS);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1));
+ }
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::vector<std::complex<float> *> buffs(NCHANNELS);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
+ }
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10 + i%10);
+ num_accum_samps += num_samps_ret;
+ if (i == NUM_PKTS_TO_TEST/2){
+ num_accum_samps = 0; //simulate the user changing the time
+ }
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA;
+ ifpi.num_payload_words32 = 0;
+ ifpi.packet_count = 0;
+ ifpi.sob = true;
+ ifpi.eob = false;
+ ifpi.has_sid = false;
+ ifpi.has_cid = false;
+ ifpi.has_tsi = true;
+ ifpi.has_tsf = true;
+ ifpi.tsi = 0;
+ ifpi.tsf = 0;
+ ifpi.has_tlr = false;
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+ static const size_t NUM_SAMPS_PER_BUFF = 10;
+ static const size_t NCHANNELS = 4;
+
+ std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class(otw_type));
+
+ //generate a bunch of packets
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ ifpi.num_payload_words32 = 10 + i%10;
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ dummy_recv_xports[ch].push_back_packet(ifpi);
+ }
+ ifpi.packet_count++;
+ ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE);
+ }
+
+ //create the super receive packet handler
+ uhd::transport::sph::recv_packet_handler handler(NCHANNELS);
+ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1));
+ }
+ handler.set_converter(otw_type);
+
+ //check the received packets
+ size_t num_accum_samps = 0;
+ std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::vector<std::complex<float> *> buffs(NCHANNELS);
+ for (size_t ch = 0; ch < NCHANNELS; ch++){
+ buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
+ }
+ uhd::rx_metadata_t metadata;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ size_t num_samps_ret = handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, 10);
+ num_accum_samps += num_samps_ret;
+
+ if (not metadata.more_fragments) continue;
+
+ num_samps_ret = handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_NONE);
+ BOOST_CHECK(not metadata.more_fragments);
+ BOOST_CHECK_EQUAL(metadata.fragment_offset, 10);
+ BOOST_CHECK(metadata.has_time_spec);
+ BOOST_CHECK_TS_CLOSE(metadata.time_spec, uhd::time_spec_t(0, num_accum_samps, SAMP_RATE));
+ BOOST_CHECK_EQUAL(num_samps_ret, i%10);
+ num_accum_samps += num_samps_ret;
+ }
+
+ //subsequent receives should be a timeout
+ for (size_t i = 0; i < 3; i++){
+ std::cout << "timeout check " << i << std::endl;
+ handler.recv(
+ buffs, NUM_SAMPS_PER_BUFF, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::RECV_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(metadata.error_code, uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
+ }
+
+}
diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp
new file mode 100644
index 000000000..ed2f54371
--- /dev/null
+++ b/host/tests/sph_send_test.cpp
@@ -0,0 +1,204 @@
+//
+// 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 <boost/test/unit_test.hpp>
+#include "../lib/transport/super_send_packet_handler.hpp"
+#include <boost/shared_array.hpp>
+#include <boost/bind.hpp>
+#include <complex>
+#include <vector>
+#include <list>
+
+#define BOOST_CHECK_TS_CLOSE(a, b) \
+ BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001)
+
+/***********************************************************************
+ * A dummy managed send buffer for testing
+ **********************************************************************/
+class dummy_msb : public uhd::transport::managed_send_buffer{
+public:
+ void commit(size_t len){
+ if (len == 0) return;
+ *_len = len;
+ }
+
+ sptr get_new(boost::shared_array<char> mem, size_t *len){
+ _mem = mem;
+ _len = len;
+ return make_managed_buffer(this);
+ }
+
+private:
+ void *get_buff(void) const{return _mem.get();}
+ size_t get_size(void) const{return *_len;}
+
+ boost::shared_array<char> _mem;
+ size_t *_len;
+};
+
+/***********************************************************************
+ * A dummy transport class to fill with fake data
+ **********************************************************************/
+class dummy_send_xport_class{
+public:
+ dummy_send_xport_class(const uhd::otw_type_t &otw_type){
+ _otw_type = otw_type;
+ }
+
+ void pop_front_packet(
+ uhd::transport::vrt::if_packet_info_t &ifpi
+ ){
+ ifpi.num_packet_words32 = _lens.front()/sizeof(boost::uint32_t);
+ if (_otw_type.byteorder == uhd::otw_type_t::BO_BIG_ENDIAN){
+ uhd::transport::vrt::if_hdr_unpack_be(reinterpret_cast<boost::uint32_t *>(_mems.front().get()), ifpi);
+ }
+ if (_otw_type.byteorder == uhd::otw_type_t::BO_LITTLE_ENDIAN){
+ uhd::transport::vrt::if_hdr_unpack_le(reinterpret_cast<boost::uint32_t *>(_mems.front().get()), ifpi);
+ }
+ _mems.pop_front();
+ _lens.pop_front();
+ }
+
+ uhd::transport::managed_send_buffer::sptr get_send_buff(double){
+ _msbs.push_back(dummy_msb());
+ _mems.push_back(boost::shared_array<char>(new char[1000]));
+ _lens.push_back(1000);
+ uhd::transport::managed_send_buffer::sptr mrb = _msbs.back().get_new(_mems.back(), &_lens.back());
+ return mrb;
+ }
+
+private:
+ std::list<boost::shared_array<char> > _mems;
+ std::list<size_t> _lens;
+ std::list<dummy_msb> _msbs; //list means no-realloc
+ uhd::otw_type_t _otw_type;
+};
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ dummy_send_xport_class dummy_send_xport(otw_type);
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+
+ //create the super send packet handler
+ uhd::transport::sph::send_packet_handler handler(1);
+ handler.set_vrt_packer(&uhd::transport::vrt::if_hdr_pack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ handler.set_xport_chan_get_buff(0, boost::bind(&dummy_send_xport_class::get_send_buff, &dummy_send_xport, _1));
+ handler.set_converter(otw_type);
+ handler.set_max_samples_per_packet(20);
+
+ //allocate metadata and buffer
+ std::vector<std::complex<float> > buff(20);
+ uhd::tx_metadata_t metadata;
+ metadata.has_time_spec = true;
+ metadata.time_spec = uhd::time_spec_t(0.0);
+
+ //generate the test data
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ metadata.start_of_burst = (i == 0);
+ metadata.end_of_burst = (i == NUM_PKTS_TO_TEST-1);
+ const size_t num_sent = handler.send(
+ &buff.front(), 10 + i%10, metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::SEND_MODE_ONE_PACKET, 1.0
+ );
+ BOOST_CHECK_EQUAL(num_sent, 10 + i%10);
+ metadata.time_spec += uhd::time_spec_t(0, num_sent, SAMP_RATE);
+ }
+
+ //check the sent packets
+ size_t num_accum_samps = 0;
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ dummy_send_xport.pop_front_packet(ifpi);
+ BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10+i%10);
+ BOOST_CHECK(ifpi.has_tsi);
+ BOOST_CHECK(ifpi.has_tsf);
+ BOOST_CHECK_EQUAL(ifpi.tsi, 0);
+ BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE);
+ BOOST_CHECK_EQUAL(ifpi.sob, i == 0);
+ BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1);
+ num_accum_samps += ifpi.num_payload_words32;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){
+////////////////////////////////////////////////////////////////////////
+ uhd::otw_type_t otw_type;
+ otw_type.width = 16;
+ otw_type.shift = 0;
+ otw_type.byteorder = uhd::otw_type_t::BO_BIG_ENDIAN;
+
+ dummy_send_xport_class dummy_send_xport(otw_type);
+
+ static const double TICK_RATE = 100e6;
+ static const double SAMP_RATE = 10e6;
+ static const size_t NUM_PKTS_TO_TEST = 30;
+
+ //create the super send packet handler
+ uhd::transport::sph::send_packet_handler handler(1);
+ handler.set_vrt_packer(&uhd::transport::vrt::if_hdr_pack_be);
+ handler.set_tick_rate(TICK_RATE);
+ handler.set_samp_rate(SAMP_RATE);
+ handler.set_xport_chan_get_buff(0, boost::bind(&dummy_send_xport_class::get_send_buff, &dummy_send_xport, _1));
+ handler.set_converter(otw_type);
+ handler.set_max_samples_per_packet(20);
+
+ //allocate metadata and buffer
+ std::vector<std::complex<float> > buff(20*NUM_PKTS_TO_TEST);
+ uhd::tx_metadata_t metadata;
+ metadata.start_of_burst = true;
+ metadata.end_of_burst = true;
+ metadata.has_time_spec = true;
+ metadata.time_spec = uhd::time_spec_t(0.0);
+
+ //generate the test data
+ const size_t num_sent = handler.send(
+ &buff.front(), buff.size(), metadata,
+ uhd::io_type_t::COMPLEX_FLOAT32,
+ uhd::device::SEND_MODE_FULL_BUFF, 1.0
+ );
+ BOOST_CHECK_EQUAL(num_sent, buff.size());
+
+ //check the sent packets
+ size_t num_accum_samps = 0;
+ uhd::transport::vrt::if_packet_info_t ifpi;
+ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){
+ std::cout << "data check " << i << std::endl;
+ dummy_send_xport.pop_front_packet(ifpi);
+ BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20);
+ BOOST_CHECK(ifpi.has_tsi);
+ BOOST_CHECK(ifpi.has_tsf);
+ BOOST_CHECK_EQUAL(ifpi.tsi, 0);
+ BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE);
+ BOOST_CHECK_EQUAL(ifpi.sob, i == 0);
+ BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST-1);
+ num_accum_samps += ifpi.num_payload_words32;
+ }
+}
diff --git a/host/usrp_e_utils/usrp-e-loopback.c b/host/usrp_e_utils/usrp-e-loopback.c
index 0bd3d3100..762e55ac8 100644
--- a/host/usrp_e_utils/usrp-e-loopback.c
+++ b/host/usrp_e_utils/usrp-e-loopback.c
@@ -51,12 +51,27 @@ static int calc_checksum(struct pkt *p)
return sum;
}
+static struct timeval delta_time(struct timeval f, struct timeval s)
+{
+ struct timeval d;
+
+ if (f.tv_usec > s.tv_usec) {
+ d.tv_usec = f.tv_usec - s.tv_usec;
+ d.tv_sec = f.tv_sec - s.tv_sec;
+ } else {
+ d.tv_usec = f.tv_usec - s.tv_usec + 1e6;
+ d.tv_sec = f.tv_sec - s.tv_sec - 1;
+ }
+
+ return d;
+}
+
static void *read_thread(void *threadid)
{
int cnt, prev_seq_num, pkt_count, seq_num_failure;
struct pkt *p;
- unsigned long bytes_transfered, elapsed_seconds;
- struct timeval start_time, finish_time;
+ unsigned long bytes_transfered;
+ struct timeval start_time;
int rb_read;
printf("Greetings from the reading thread!\n");
@@ -125,11 +140,15 @@ static void *read_thread(void *threadid)
bytes_transfered += cnt;
if (bytes_transfered > (100 * 1000000)) {
+ struct timeval finish_time, d_time;
+ float elapsed_seconds;
+
gettimeofday(&finish_time, NULL);
- elapsed_seconds = finish_time.tv_sec - start_time.tv_sec;
+ d_time = delta_time(finish_time, start_time);
+ elapsed_seconds = (float)d_time.tv_sec + ((float)d_time.tv_usec * 1e-6f);
printf("RX data transfer rate = %f K Samples/second\n",
- (float) bytes_transfered / (float) elapsed_seconds / 4000);
+ (float) bytes_transfered / elapsed_seconds / 4000.0f);
start_time = finish_time;
diff --git a/host/usrp_e_utils/usrp-e-timed.c b/host/usrp_e_utils/usrp-e-timed.c
index 06dfdf512..407564429 100644
--- a/host/usrp_e_utils/usrp-e-timed.c
+++ b/host/usrp_e_utils/usrp-e-timed.c
@@ -273,7 +273,7 @@ static void *write_thread(void *threadid)
d_time = delta_time(finish_time, start_time);
- elapsed_seconds = (float)d_time.tv_sec - ((float)d_time.tv_usec * 1e-6f);
+ elapsed_seconds = (float)d_time.tv_sec + ((float)d_time.tv_usec * 1e-6f);
printf("Bytes transfered = %ld, elapsed seconds = %f\n", bytes_transfered, elapsed_seconds);
printf("TX data transfer rate = %f K Samples/second\n",
diff --git a/images/Makefile b/images/Makefile
index 71b46d14e..10e3eb7ba 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -52,13 +52,14 @@ ifeq ($(shell xtclsh -h > /dev/null 2>&1 && echo $$?),0)
endif
########################################################################
-# USRP1 firmware
+# USRP1 and B100 firmware
########################################################################
ifdef HAS_SDCC
_usrp1_fw_dir = $(TOP_FW_DIR)/fx2
_usrp1_fw_ihx = $(BUILT_IMAGES_DIR)/usrp1_fw.ihx
-IMAGES_LIST += $(_usrp1_fw_ihx)
+_usrp_b100_fw_ihx = $(BUILT_IMAGES_DIR)/usrp_b100_fw.ihx
+IMAGES_LIST += $(_usrp1_fw_ihx) $(_usrp_b100_fw_ihx)
$(_usrp1_fw_ihx): $(GLOBAL_DEPS)
cd $(_usrp1_fw_dir) && rm -rf build
@@ -67,6 +68,9 @@ $(_usrp1_fw_ihx): $(GLOBAL_DEPS)
cd $(_usrp1_fw_dir)/build && make
cp $(_usrp1_fw_dir)/build/usrp1/usrp1_fw.ihx $@
+$(_usrp_b100_fw_ihx): $(_usrp1_fw_ihx)
+ cp $(_usrp1_fw_dir)/build/b100/b100_fw.ihx $(_usrp_b100_fw_ihx)
+
endif
########################################################################
@@ -84,6 +88,22 @@ $(_usrp1_fpga_4rx_rbf): $(GLOBAL_DEPS)
cp $(_usrp1_fpga_dir)/std_4rx_0tx.rbf $@
########################################################################
+# USRP-B100 fpga
+########################################################################
+ifdef HAS_XTCLSH
+
+_usrp_b100_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/B100
+_usrp_b100_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_b100_fpga.bin
+IMAGES_LIST += $(_usrp_b100_fpga_bin)
+
+$(_usrp_b100_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_b100_fpga_dir) && make clean
+ cd $(_usrp_b100_fpga_dir) && make bin
+ cp $(_usrp_b100_fpga_dir)/build/u1plus.bin $@
+
+endif
+
+########################################################################
# USRP2 and N Series firmware
########################################################################
ifdef HAS_ZPU_GCC
@@ -114,7 +134,7 @@ endif
########################################################################
ifdef HAS_XTCLSH
-_usrp2_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u2_rev3
+_usrp2_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/USRP2
_usrp2_fpga_bin = $(BUILT_IMAGES_DIR)/usrp2_fpga.bin
IMAGES_LIST += $(_usrp2_fpga_bin)
@@ -126,66 +146,94 @@ $(_usrp2_fpga_bin): $(GLOBAL_DEPS)
endif
########################################################################
-# USRP-N200 fpga
+# USRP-N200 R2/R3 fpga
########################################################################
ifdef HAS_XTCLSH
-_usrp_n200_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u2plus
-_usrp_n200_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n200_fpga.bin
-IMAGES_LIST += $(_usrp_n200_fpga_bin)
+_usrp_n200_r3_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/N2x0
+_usrp_n200_r3_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n200_r3_fpga.bin
+IMAGES_LIST += $(_usrp_n200_r3_fpga_bin)
-$(_usrp_n200_fpga_bin): $(GLOBAL_DEPS)
- cd $(_usrp_n200_fpga_dir) && make -f Makefile.N200 clean
- cd $(_usrp_n200_fpga_dir) && make -f Makefile.N200 bin
- cp $(_usrp_n200_fpga_dir)/build-N200/u2plus.bin $@
+$(_usrp_n200_r3_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_n200_r3_fpga_dir) && make -f Makefile.N200R3 clean
+ cd $(_usrp_n200_r3_fpga_dir) && make -f Makefile.N200R3 bin
+ cp $(_usrp_n200_r3_fpga_dir)/build-N200R3/u2plus.bin $@
+
+#its called r2 on the silkscreen, so make an r2
+_usrp_n200_r2_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n200_r2_fpga.bin
+IMAGES_LIST += $(_usrp_n200_r2_fpga_bin)
+$(_usrp_n200_r2_fpga_bin): $(_usrp_n200_r3_fpga_bin)
+ cp $< $@
endif
########################################################################
-# USRP-N210 fpga
+# USRP-N210 R2/R3 fpga
########################################################################
ifdef HAS_XTCLSH
-_usrp_n210_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u2plus
-_usrp_n210_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n210_fpga.bin
-IMAGES_LIST += $(_usrp_n210_fpga_bin)
+_usrp_n210_r3_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/N2x0
+_usrp_n210_r3_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n210_r3_fpga.bin
+IMAGES_LIST += $(_usrp_n210_r3_fpga_bin)
+
+$(_usrp_n210_r3_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_n210_r3_fpga_dir) && make -f Makefile.N210R3 clean
+ cd $(_usrp_n210_r3_fpga_dir) && make -f Makefile.N210R3 bin
+ cp $(_usrp_n210_r3_fpga_dir)/build-N210R3/u2plus.bin $@
-$(_usrp_n210_fpga_bin): $(GLOBAL_DEPS)
- cd $(_usrp_n210_fpga_dir) && make clean
- cd $(_usrp_n210_fpga_dir) && make bin
- cp $(_usrp_n210_fpga_dir)/build/u2plus.bin $@
+#its called r2 on the silkscreen, so make an r2
+_usrp_n210_r2_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n210_r2_fpga.bin
+IMAGES_LIST += $(_usrp_n210_r2_fpga_bin)
+$(_usrp_n210_r2_fpga_bin): $(_usrp_n210_r3_fpga_bin)
+ cp $< $@
endif
########################################################################
-# USRP-E100 fpga
+# USRP-N200 R4 fpga
########################################################################
ifdef HAS_XTCLSH
-_usrp_e100_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u1e
-_usrp_e100_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_e100_fpga.bin
-IMAGES_LIST += $(_usrp_e100_fpga_bin)
+_usrp_n200_r4_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/N2x0
+_usrp_n200_r4_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n200_r4_fpga.bin
+IMAGES_LIST += $(_usrp_n200_r4_fpga_bin)
-$(_usrp_e100_fpga_bin): $(GLOBAL_DEPS)
- cd $(_usrp_e100_fpga_dir) && make clean
- cd $(_usrp_e100_fpga_dir) && make bin
- cp $(_usrp_e100_fpga_dir)/build/u1e.bin $@
+$(_usrp_n200_r4_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_n200_r4_fpga_dir) && make -f Makefile.N200R4 clean
+ cd $(_usrp_n200_r4_fpga_dir) && make -f Makefile.N200R4 bin
+ cp $(_usrp_n200_r4_fpga_dir)/build-N200R4/u2plus.bin $@
+
+endif
+
+########################################################################
+# USRP-N210 R4 fpga
+########################################################################
+ifdef HAS_XTCLSH
+
+_usrp_n210_r4_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/N2x0
+_usrp_n210_r4_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_n210_r4_fpga.bin
+IMAGES_LIST += $(_usrp_n210_r4_fpga_bin)
+
+$(_usrp_n210_r4_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_n210_r4_fpga_dir) && make -f Makefile.N210R4 clean
+ cd $(_usrp_n210_r4_fpga_dir) && make -f Makefile.N210R4 bin
+ cp $(_usrp_n210_r4_fpga_dir)/build-N210R4/u2plus.bin $@
endif
########################################################################
-# USRP-E100 pass-through fpga
+# USRP-E100 fpga
########################################################################
ifdef HAS_XTCLSH
-_usrp_e100_pt_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/u1e_passthru
-_usrp_e100_pt_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_e100_pt_fpga.bin
-IMAGES_LIST += $(_usrp_e100_pt_fpga_bin)
+_usrp_e100_fpga_dir = $(TOP_FPGA_DIR)/usrp2/top/E1x0
+_usrp_e100_fpga_bin = $(BUILT_IMAGES_DIR)/usrp_e100_fpga.bin
+IMAGES_LIST += $(_usrp_e100_fpga_bin)
-$(_usrp_e100_pt_fpga_bin): $(GLOBAL_DEPS)
- cd $(_usrp_e100_pt_fpga_dir) && make clean
- cd $(_usrp_e100_pt_fpga_dir) && make bin
- cp $(_usrp_e100_pt_fpga_dir)/build/passthru.bin $@
+$(_usrp_e100_fpga_bin): $(GLOBAL_DEPS)
+ cd $(_usrp_e100_fpga_dir) && make clean
+ cd $(_usrp_e100_fpga_dir) && make bin
+ cp $(_usrp_e100_fpga_dir)/build/u1e.bin $@
endif