diff options
author | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2009-07-30 21:54:38 +0000 |
---|---|---|
committer | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2009-07-30 21:54:38 +0000 |
commit | 7ffbd04c273ef96472e18f98a40b3ad171bc0c9b (patch) | |
tree | fe5c3db6b0389db32468b421581141d71d1e951c /top | |
parent | 8575074ce0c6cfca9114bfc9e73bb790d09645c8 (diff) | |
download | uhd-7ffbd04c273ef96472e18f98a40b3ad171bc0c9b.tar.gz uhd-7ffbd04c273ef96472e18f98a40b3ad171bc0c9b.tar.bz2 uhd-7ffbd04c273ef96472e18f98a40b3ad171bc0c9b.zip |
Add custom FPGA build.
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.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11519 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'top')
-rw-r--r-- | top/u2_rev3_2rx_iad/Makefile | 254 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/README | 32 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/cmdfile | 4 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/dsp_core_rx.v | 212 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/dsp_core_tb.sav | 106 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/dsp_core_tb.v | 233 | ||||
-rw-r--r-- | top/u2_rev3_2rx_iad/impulse.v | 68 | ||||
-rwxr-xr-x | top/u2_rev3_2rx_iad/u2_core.v | 789 | ||||
-rwxr-xr-x | top/u2_rev3_2rx_iad/wave.sh | 3 | ||||
-rw-r--r-- | top/u2_rev3_iad/Makefile | 4 | ||||
-rw-r--r-- | top/u2_rev3_iad/impulse.v | 2 | ||||
-rw-r--r-- | top/u2_rev3_iad/integrate.v | 38 |
12 files changed, 1704 insertions, 41 deletions
diff --git a/top/u2_rev3_2rx_iad/Makefile b/top/u2_rev3_2rx_iad/Makefile new file mode 100644 index 000000000..5b7ed5a8e --- /dev/null +++ b/top/u2_rev3_2rx_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/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/top/u2_rev3_2rx_iad/README b/top/u2_rev3_2rx_iad/README new file mode 100644 index 000000000..3efc5305b --- /dev/null +++ b/top/u2_rev3_2rx_iad/README @@ -0,0 +1,32 @@ +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/top/u2_rev3_2rx_iad/cmdfile b/top/u2_rev3_2rx_iad/cmdfile new file mode 100644 index 000000000..34373a676 --- /dev/null +++ b/top/u2_rev3_2rx_iad/cmdfile @@ -0,0 +1,4 @@ +-y . +-y ../../sdr_lib +-y ../../control_lib +-y ../../models diff --git a/top/u2_rev3_2rx_iad/dsp_core_rx.v b/top/u2_rev3_2rx_iad/dsp_core_rx.v new file mode 100644 index 000000000..4a945bd1a --- /dev/null +++ b/top/u2_rev3_2rx_iad/dsp_core_rx.v @@ -0,0 +1,212 @@ +`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/top/u2_rev3_2rx_iad/dsp_core_tb.sav b/top/u2_rev3_2rx_iad/dsp_core_tb.sav new file mode 100644 index 000000000..12f746860 --- /dev/null +++ b/top/u2_rev3_2rx_iad/dsp_core_tb.sav @@ -0,0 +1,106 @@ +[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/top/u2_rev3_2rx_iad/dsp_core_tb.v b/top/u2_rev3_2rx_iad/dsp_core_tb.v new file mode 100644 index 000000000..d947df40a --- /dev/null +++ b/top/u2_rev3_2rx_iad/dsp_core_tb.v @@ -0,0 +1,233 @@ +`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/top/u2_rev3_2rx_iad/impulse.v b/top/u2_rev3_2rx_iad/impulse.v new file mode 100644 index 000000000..fc5e3c1ed --- /dev/null +++ b/top/u2_rev3_2rx_iad/impulse.v @@ -0,0 +1,68 @@ +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/top/u2_rev3_2rx_iad/u2_core.v b/top/u2_rev3_2rx_iad/u2_core.v new file mode 100755 index 000000000..3d96a4e0e --- /dev/null +++ b/top/u2_rev3_2rx_iad/u2_core.v @@ -0,0 +1,789 @@ +// //////////////////////////////////////////////////////////////////////////////// +// 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/top/u2_rev3_2rx_iad/wave.sh b/top/u2_rev3_2rx_iad/wave.sh new file mode 100755 index 000000000..626f224e5 --- /dev/null +++ b/top/u2_rev3_2rx_iad/wave.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +gtkwave dsp_core_tb.vcd dsp_core_tb.sav & diff --git a/top/u2_rev3_iad/Makefile b/top/u2_rev3_iad/Makefile index 24dffd92b..5ae8846dd 100644 --- a/top/u2_rev3_iad/Makefile +++ b/top/u2_rev3_iad/Makefile @@ -159,6 +159,7 @@ 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 \ @@ -179,8 +180,7 @@ 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 +top/u2_rev3_iad/dsp_core_rx.v ################################################## # Process Properties diff --git a/top/u2_rev3_iad/impulse.v b/top/u2_rev3_iad/impulse.v index ecdf101ab..7f0cdc9be 100644 --- a/top/u2_rev3_iad/impulse.v +++ b/top/u2_rev3_iad/impulse.v @@ -60,4 +60,4 @@ module impulse assign adc_ovf_a = 0; assign adc_ovf_b = 0; -endmodule // adc_model +endmodule // impulse diff --git a/top/u2_rev3_iad/integrate.v b/top/u2_rev3_iad/integrate.v deleted file mode 100644 index db33de979..000000000 --- a/top/u2_rev3_iad/integrate.v +++ /dev/null @@ -1,38 +0,0 @@ -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 |