diff options
| author | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2009-04-22 00:11:28 +0000 | 
|---|---|---|
| committer | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2009-04-22 00:11:28 +0000 | 
| commit | 0d440394746183c2ed2f39c7665cbf7b67a1764a (patch) | |
| tree | c19c079c522a78a49034a3eb833146bff7542f99 | |
| parent | 8c3ec58ceb58e8356557748de5d8f1077b4fef5f (diff) | |
| download | uhd-0d440394746183c2ed2f39c7665cbf7b67a1764a.tar.gz uhd-0d440394746183c2ed2f39c7665cbf7b67a1764a.tar.bz2 uhd-0d440394746183c2ed2f39c7665cbf7b67a1764a.zip | |
Merged r10770:10887 from jcorgan/iad2 into trunk.  Adds alternative USRP2 FPGA build to use integrate-and-dump decimator instead of CIC/HB combination.  This provides a much shorter time duration impulse response for the same decimation rate, at the expense of worse stop-band rejection.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10888 221aa14e-8319-0410-a670-987f0aec2ac5
| -rw-r--r-- | top/u2_rev3_iad/Makefile | 254 | ||||
| -rw-r--r-- | top/u2_rev3_iad/cmdfile | 4 | ||||
| -rw-r--r-- | top/u2_rev3_iad/dsp_core_rx.v | 157 | ||||
| -rw-r--r-- | top/u2_rev3_iad/dsp_core_tb.sav | 61 | ||||
| -rw-r--r-- | top/u2_rev3_iad/dsp_core_tb.v | 196 | ||||
| -rw-r--r-- | top/u2_rev3_iad/impulse.v | 63 | ||||
| -rw-r--r-- | top/u2_rev3_iad/integrate.v | 38 | ||||
| -rwxr-xr-x | top/u2_rev3_iad/wave.sh | 3 | 
8 files changed, 776 insertions, 0 deletions
| diff --git a/top/u2_rev3_iad/Makefile b/top/u2_rev3_iad/Makefile new file mode 100644 index 000000000..24dffd92b --- /dev/null +++ b/top/u2_rev3_iad/Makefile @@ -0,0 +1,254 @@ +# +# 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 \ +extram/wb_zbt16_b.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/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 \ +top/u2_rev3_iad/integrate.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/top/u2_rev3_iad/cmdfile b/top/u2_rev3_iad/cmdfile new file mode 100644 index 000000000..34373a676 --- /dev/null +++ b/top/u2_rev3_iad/cmdfile @@ -0,0 +1,4 @@ +-y . +-y ../../sdr_lib +-y ../../control_lib +-y ../../models diff --git a/top/u2_rev3_iad/dsp_core_rx.v b/top/u2_rev3_iad/dsp_core_rx.v new file mode 100644 index 000000000..0ad823cac --- /dev/null +++ b/top/u2_rev3_iad/dsp_core_rx.v @@ -0,0 +1,157 @@ +`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_hb1 ? (enable_hb2 ? {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/top/u2_rev3_iad/dsp_core_tb.sav b/top/u2_rev3_iad/dsp_core_tb.sav new file mode 100644 index 000000000..17c90cdd7 --- /dev/null +++ b/top/u2_rev3_iad/dsp_core_tb.sav @@ -0,0 +1,61 @@ +[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/top/u2_rev3_iad/dsp_core_tb.v b/top/u2_rev3_iad/dsp_core_tb.v new file mode 100644 index 000000000..6b4c1669b --- /dev/null +++ b/top/u2_rev3_iad/dsp_core_tb.v @@ -0,0 +1,196 @@ +`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(1, 1, 10); + +	 #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/top/u2_rev3_iad/impulse.v b/top/u2_rev3_iad/impulse.v new file mode 100644 index 000000000..ecdf101ab --- /dev/null +++ b/top/u2_rev3_iad/impulse.v @@ -0,0 +1,63 @@ +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 // adc_model diff --git a/top/u2_rev3_iad/integrate.v b/top/u2_rev3_iad/integrate.v new file mode 100644 index 000000000..db33de979 --- /dev/null +++ b/top/u2_rev3_iad/integrate.v @@ -0,0 +1,38 @@ +module integrate +  #(parameter INPUTW = 16, +    parameter ACCUMW = 32, +    parameter OUTPUTW = 16) + +   (input clk_i, +    input rst_i, +    input ena_i, + +    input dump_i, +    input [INPUTW-1:0] data_i, + +    output reg stb_o, +    output reg [OUTPUTW-1:0] integ_o +   ); +    +   wire [ACCUMW-1:0] data_ext = {{ACCUMW-INPUTW{data_i[INPUTW-1]}},data_i}; +   reg  [ACCUMW-1:0] accum; + +   always @(posedge clk_i) +     if (rst_i | ~ena_i) +       begin +	  accum <= 0; +	  integ_o <= 0; +       end +     else +       if (dump_i) +	 begin +	    integ_o <= accum[ACCUMW-1:ACCUMW-OUTPUTW]; +	    accum <= data_ext; +	 end +       else +	 accum <= accum + data_ext; + +   always @(posedge clk_i) +     stb_o <= dump_i; +    +endmodule // integrate diff --git a/top/u2_rev3_iad/wave.sh b/top/u2_rev3_iad/wave.sh new file mode 100755 index 000000000..626f224e5 --- /dev/null +++ b/top/u2_rev3_iad/wave.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +gtkwave dsp_core_tb.vcd dsp_core_tb.sav & | 
