summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usrp2/control_lib/atr_controller16.v60
-rw-r--r--usrp2/control_lib/newfifo/.gitignore2
-rw-r--r--usrp2/control_lib/newfifo/fifo19_to_fifo36.v11
-rw-r--r--usrp2/control_lib/newfifo/ll8_to_fifo19.v86
-rw-r--r--usrp2/control_lib/newfifo/packet_generator.v59
-rw-r--r--usrp2/control_lib/newfifo/packet_tb.v29
-rw-r--r--usrp2/control_lib/newfifo/packet_verifier.v63
-rw-r--r--usrp2/control_lib/nsgpio16LE.v123
-rw-r--r--usrp2/control_lib/ram_2port_mixed_width.v120
-rw-r--r--usrp2/control_lib/setting_reg.v4
-rw-r--r--usrp2/control_lib/settings_bus_16LE.v54
-rw-r--r--usrp2/control_lib/simple_uart.v13
-rw-r--r--usrp2/gpmc/.gitignore2
-rw-r--r--usrp2/gpmc/burst_data_write.txt16
-rw-r--r--usrp2/gpmc/dbsm.v80
-rw-r--r--usrp2/gpmc/edge_sync.v22
-rw-r--r--usrp2/gpmc/fifo_to_gpmc_async.v38
-rw-r--r--usrp2/gpmc/fifo_to_gpmc_sync.v26
-rw-r--r--usrp2/gpmc/fifo_watcher.v54
-rw-r--r--usrp2/gpmc/gpmc_async.v111
-rw-r--r--usrp2/gpmc/gpmc_sync.v107
-rw-r--r--usrp2/gpmc/gpmc_to_fifo_async.v68
-rw-r--r--usrp2/gpmc/gpmc_to_fifo_sync.v57
-rw-r--r--usrp2/gpmc/gpmc_wb.v57
-rwxr-xr-xusrp2/gpmc/make_timing_diag6
-rw-r--r--usrp2/gpmc/ram_to_fifo.v46
-rw-r--r--usrp2/gpmc/single_data_read.txt12
-rw-r--r--usrp2/gpmc/single_data_write.txt10
-rw-r--r--usrp2/models/gpmc_model_async.v130
-rw-r--r--usrp2/models/gpmc_model_sync.v97
-rw-r--r--usrp2/opencores/spi/rtl/verilog/spi_clgen.v27
-rw-r--r--usrp2/opencores/spi/rtl/verilog/spi_defines.v10
-rw-r--r--usrp2/opencores/spi/rtl/verilog/spi_shift.v99
-rw-r--r--usrp2/opencores/spi/rtl/verilog/spi_top.v88
-rw-r--r--usrp2/opencores/spi/rtl/verilog/spi_top16.v182
-rw-r--r--usrp2/opencores/spi/rtl/verilog/timescale.v2
-rw-r--r--usrp2/sdr_lib/dsp_core_rx.v16
-rw-r--r--usrp2/sdr_lib/dsp_core_tx.v11
-rw-r--r--usrp2/simple_gemac/eth_tasks_f19.v92
-rw-r--r--usrp2/simple_gemac/ll8_shortfifo.v0
-rw-r--r--usrp2/simple_gemac/simple_gemac.v7
-rw-r--r--usrp2/simple_gemac/simple_gemac_rx.v5
-rwxr-xr-xusrp2/simple_gemac/simple_gemac_wrapper19.build1
-rw-r--r--usrp2/simple_gemac/simple_gemac_wrapper19.v170
-rw-r--r--usrp2/simple_gemac/simple_gemac_wrapper19_tb.v209
-rw-r--r--usrp2/timing/simple_timer.v60
-rw-r--r--usrp2/timing/time_64bit.v46
-rw-r--r--usrp2/timing/time_compare.v23
-rw-r--r--usrp2/top/u1e/.gitignore6
-rw-r--r--usrp2/top/u1e/Makefile257
-rw-r--r--usrp2/top/u1e/README4
-rw-r--r--usrp2/top/u1e/cmdfile20
-rw-r--r--usrp2/top/u1e/make.sim7
-rw-r--r--usrp2/top/u1e/tb_u1e.v41
-rw-r--r--usrp2/top/u1e/timing.ucf13
-rw-r--r--usrp2/top/u1e/u1e.ucf266
-rw-r--r--usrp2/top/u1e/u1e.v68
-rw-r--r--usrp2/top/u1e/u1e_core.v372
-rw-r--r--usrp2/top/u1e_passthru/.gitignore1
-rw-r--r--usrp2/top/u1e_passthru/Makefile107
-rw-r--r--usrp2/top/u1e_passthru/passthru.ucf266
-rw-r--r--usrp2/top/u1e_passthru/passthru.v18
-rw-r--r--[-rwxr-xr-x]usrp2/top/u2_core/u2_core.v214
-rw-r--r--usrp2/top/u2_rev3/Makefile22
-rw-r--r--usrp2/udp/add_onescomp.v12
-rw-r--r--usrp2/udp/fifo19_rxrealign.v42
-rw-r--r--usrp2/udp/prot_eng_rx.v121
-rw-r--r--usrp2/udp/prot_eng_tx.v119
-rw-r--r--usrp2/udp/prot_eng_tx_tb.v167
-rw-r--r--usrp2/udp/udp_wrapper.v92
-rw-r--r--usrp2/vrt/.gitignore4
-rwxr-xr-xusrp2/vrt/vita_rx.build1
-rw-r--r--usrp2/vrt/vita_rx_control.v180
-rw-r--r--usrp2/vrt/vita_rx_framer.v199
-rw-r--r--usrp2/vrt/vita_rx_tb.v213
-rwxr-xr-xusrp2/vrt/vita_tx.build1
-rw-r--r--usrp2/vrt/vita_tx_control.v98
-rw-r--r--usrp2/vrt/vita_tx_deframer.v187
-rw-r--r--usrp2/vrt/vita_tx_tb.v264
79 files changed, 5738 insertions, 255 deletions
diff --git a/usrp2/control_lib/atr_controller16.v b/usrp2/control_lib/atr_controller16.v
new file mode 100644
index 000000000..3d8b5b1e9
--- /dev/null
+++ b/usrp2/control_lib/atr_controller16.v
@@ -0,0 +1,60 @@
+
+// Automatic transmit/receive switching of control pins to daughterboards
+// Store everything in registers for now, but could use a RAM for more
+// complex state machines in the future
+
+module atr_controller16
+ (input clk_i, input rst_i,
+ input [5:0] adr_i, input [1:0] sel_i, input [15:0] dat_i, output reg [15:0] dat_o,
+ input we_i, input stb_i, input cyc_i, output reg ack_o,
+ input run_rx, input run_tx, input [31:0] master_time,
+ output [31:0] ctrl_lines);
+
+ reg [3:0] state;
+ reg [31:0] atr_ram [0:15]; // DP distributed RAM
+
+ wire [3:0] sel_int = { (sel_i[1] & adr_i[1]), (sel_i[0] & adr_i[1]),
+ (sel_i[1] & ~adr_i[1]), (sel_i[0] & ~adr_i[1]) };
+
+ // WB Interface
+ always @(posedge clk_i)
+ if(we_i & stb_i & cyc_i)
+ begin
+ if(sel_int[3])
+ atr_ram[adr_i[5:2]][31:24] <= dat_i[15:8];
+ if(sel_int[2])
+ atr_ram[adr_i[5:2]][23:16] <= dat_i[7:0];
+ if(sel_int[1])
+ atr_ram[adr_i[5:2]][15:8] <= dat_i[15:8];
+ if(sel_int[0])
+ atr_ram[adr_i[5:2]][7:0] <= dat_i[7:0];
+ end // if (we_i & stb_i & cyc_i)
+
+ always @(posedge clk_i)
+ dat_o <= adr_i[1] ? atr_ram[adr_i[5:2]][31:16] : atr_ram[adr_i[5:2]][15:0];
+
+ always @(posedge clk_i)
+ ack_o <= stb_i & cyc_i & ~ack_o;
+
+ // Control side of DP RAM
+ assign ctrl_lines = atr_ram[state];
+
+ // Put a more complex state machine with time delays and multiple states here
+ // if daughterboard requires more complex sequencing
+ localparam ATR_IDLE = 4'd0;
+ localparam ATR_TX = 4'd1;
+ localparam ATR_RX = 4'd2;
+ localparam ATR_FULL_DUPLEX = 4'd3;
+
+ always @(posedge clk_i)
+ if(rst_i)
+ state <= ATR_IDLE;
+ else
+ case ({run_rx,run_tx})
+ 2'b00 : state <= ATR_IDLE;
+ 2'b01 : state <= ATR_TX;
+ 2'b10 : state <= ATR_RX;
+ 2'b11 : state <= ATR_FULL_DUPLEX;
+ endcase // case({run_rx,run_tx})
+
+endmodule // atr_controller16
diff --git a/usrp2/control_lib/newfifo/.gitignore b/usrp2/control_lib/newfifo/.gitignore
index cba7efc8e..866f1faad 100644
--- a/usrp2/control_lib/newfifo/.gitignore
+++ b/usrp2/control_lib/newfifo/.gitignore
@@ -1 +1,3 @@
+*.vcd
+*.lxt
a.out
diff --git a/usrp2/control_lib/newfifo/fifo19_to_fifo36.v b/usrp2/control_lib/newfifo/fifo19_to_fifo36.v
index e22ca0a49..5f9aeff9b 100644
--- a/usrp2/control_lib/newfifo/fifo19_to_fifo36.v
+++ b/usrp2/control_lib/newfifo/fifo19_to_fifo36.v
@@ -7,7 +7,8 @@ module fifo19_to_fifo36
output [35:0] f36_dataout,
output f36_src_rdy_o,
- input f36_dst_rdy_i
+ input f36_dst_rdy_i,
+ output [31:0] debug
);
reg f36_sof, f36_eof, f36_occ;
@@ -50,7 +51,9 @@ module fifo19_to_fifo36
state <= 2;
2 :
if(xfer_out)
- state <= 1;
+ if(~f19_eof)
+ state <= 1;
+ // remain in state 2 if we are at eof
endcase // case(state)
else
if(xfer_out)
@@ -67,5 +70,7 @@ module fifo19_to_fifo36
assign f19_dst_rdy_o = xfer_out | (state != 2);
assign f36_dataout = {f36_occ,f36_eof,f36_sof,dat0,dat1};
assign f36_src_rdy_o = (state == 2);
-
+
+ assign debug = state;
+
endmodule // fifo19_to_fifo36
diff --git a/usrp2/control_lib/newfifo/ll8_to_fifo19.v b/usrp2/control_lib/newfifo/ll8_to_fifo19.v
index c65be5136..af3b91afb 100644
--- a/usrp2/control_lib/newfifo/ll8_to_fifo19.v
+++ b/usrp2/control_lib/newfifo/ll8_to_fifo19.v
@@ -10,68 +10,64 @@ module ll8_to_fifo19
output [18:0] f19_data,
output f19_src_rdy_o,
input f19_dst_rdy_i );
-
+
+ localparam XFER_EMPTY = 0;
+ localparam XFER_HALF = 1;
+ localparam XFER_HALF_WRITE = 3;
+
// Why anybody would use active low in an FPGA is beyond me...
wire ll_sof = ~ll_sof_n;
wire ll_eof = ~ll_eof_n;
wire ll_src_rdy = ~ll_src_rdy_n;
wire ll_dst_rdy;
assign ll_dst_rdy_n = ~ll_dst_rdy;
-
- wire xfer_out = f19_src_rdy_o & f19_dst_rdy_i;
- // wire xfer_in = ll_src_rdy & ll_dst_rdy; Not needed
- reg f19_sof, f19_eof, f19_occ;
+ wire xfer_out = f19_src_rdy_o & f19_dst_rdy_i;
+ wire xfer_in = ll_src_rdy & ll_dst_rdy;
+
+ reg hold_sof;
+ wire f19_sof, f19_eof, f19_occ;
reg [1:0] state;
- reg [7:0] dat0, dat1;
-
- always @(posedge clk)
- if(ll_src_rdy & ((state==0)|xfer_out))
- f19_sof <= ll_sof;
-
+ reg [7:0] hold_reg;
+
always @(posedge clk)
- if(ll_src_rdy & ((state != 2)|xfer_out))
- f19_eof <= ll_eof;
-
+ if(ll_src_rdy & (state==XFER_EMPTY))
+ hold_reg <= ll_data;
+
always @(posedge clk)
- if(ll_eof)
- f19_occ <= ~state[0];
- else
- f19_occ <= 0;
+ if(ll_sof & (state==XFER_EMPTY))
+ hold_sof <= 1;
+ else if(xfer_out)
+ hold_sof <= 0;
always @(posedge clk)
- if(reset)
- state <= 0;
+ if(reset | clear)
+ state <= XFER_EMPTY;
else
- if(ll_src_rdy)
- case(state)
- 0 :
+ case(state)
+ XFER_EMPTY :
+ if(ll_src_rdy)
if(ll_eof)
- state <= 2;
+ state <= XFER_HALF_WRITE;
else
- state <= 1;
- 1 :
- state <= 2;
- 2 :
- if(xfer_out)
- state <= 1;
- endcase // case(state)
- else
- if(xfer_out)
- state <= 0;
-
- always @(posedge clk)
- if(ll_src_rdy & (state==1))
- dat1 <= ll_data;
-
- always @(posedge clk)
- if(ll_src_rdy & ((state==0) | xfer_out))
- dat0 <= ll_data;
+ state <= XFER_HALF;
+ XFER_HALF :
+ if(ll_src_rdy & f19_dst_rdy_i)
+ state <= XFER_EMPTY;
+ XFER_HALF_WRITE :
+ if(f19_dst_rdy_i)
+ state <= XFER_EMPTY;
+ endcase // case (state)
+
+ assign ll_dst_rdy = (state==XFER_EMPTY) | ((state==XFER_HALF)&f19_dst_rdy_i);
+ assign f19_src_rdy_o = (state==XFER_HALF_WRITE) | ((state==XFER_HALF)&ll_src_rdy);
+
+ assign f19_sof = hold_sof | (ll_sof & (state==XFER_HALF));
+ assign f19_eof = (state == XFER_HALF_WRITE) | ll_eof;
+ assign f19_occ = (state == XFER_HALF_WRITE);
- assign ll_dst_rdy = xfer_out | (state != 2);
- assign f19_data = {f19_occ,f19_eof,f19_sof,dat0,dat1};
- assign f19_src_rdy_o = (state == 2);
+ assign f19_data = {f19_occ,f19_eof,f19_sof,hold_reg,ll_data};
endmodule // ll8_to_fifo19
diff --git a/usrp2/control_lib/newfifo/packet_generator.v b/usrp2/control_lib/newfifo/packet_generator.v
new file mode 100644
index 000000000..e5bfe5b26
--- /dev/null
+++ b/usrp2/control_lib/newfifo/packet_generator.v
@@ -0,0 +1,59 @@
+
+
+module packet_generator
+ (input clk, input reset, input clear,
+ output reg [7:0] data_o, output sof_o, output eof_o,
+ output src_rdy_o, input dst_rdy_i);
+
+ localparam len = 32'd100;
+
+ reg [31:0] state;
+ reg [31:0] seq;
+ wire [31:0] crc_out;
+ wire calc_crc = src_rdy_o & dst_rdy_i & ~(state[31:2] == 30'h3FFF_FFFF);
+
+
+ always @(posedge clk)
+ if(reset | clear)
+ seq <= 0;
+ else
+ if(eof_o & src_rdy_o & dst_rdy_i)
+ seq <= seq + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= 0;
+ else
+ if(src_rdy_o & dst_rdy_i)
+ if(state == (len - 1))
+ state <= 32'hFFFF_FFFC;
+ else
+ state <= state + 1;
+
+ always @*
+ case(state)
+ 0 : data_o <= len[7:0];
+ 1 : data_o <= len[15:8];
+ 2 : data_o <= len[23:16];
+ 3 : data_o <= len[31:24];
+ 4 : data_o <= seq[7:0];
+ 5 : data_o <= seq[15:8];
+ 6 : data_o <= seq[23:16];
+ 7 : data_o <= seq[31:24];
+ 32'hFFFF_FFFC : data_o <= crc_out[31:24];
+ 32'hFFFF_FFFD : data_o <= crc_out[23:16];
+ 32'hFFFF_FFFE : data_o <= crc_out[15:8];
+ 32'hFFFF_FFFF : data_o <= crc_out[7:0];
+ default : data_o <= state[7:0];
+ endcase // case (state)
+
+ assign src_rdy_o = 1;
+ assign sof_o = (state == 0);
+ assign eof_o = (state == 32'hFFFF_FFFF);
+
+ wire clear_crc = eof_o & src_rdy_o & dst_rdy_i;
+
+ crc crc(.clk(clk), .reset(reset), .clear(clear_crc), .data(data_o),
+ .calc(calc_crc), .crc_out(crc_out), .match());
+
+endmodule // packet_generator
diff --git a/usrp2/control_lib/newfifo/packet_tb.v b/usrp2/control_lib/newfifo/packet_tb.v
new file mode 100644
index 000000000..3c423d2ba
--- /dev/null
+++ b/usrp2/control_lib/newfifo/packet_tb.v
@@ -0,0 +1,29 @@
+
+
+module packet_tb();
+
+ wire [7:0] data;
+ wire sof, eof, src_rdy, dst_rdy;
+
+ wire clear = 0;
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk <= ~clk;
+ initial #1000 reset <= 0;
+
+ initial $dumpfile("packet_tb.vcd");
+ initial $dumpvars(0,packet_tb);
+
+ wire [31:0] total, crc_err, seq_err, len_err;
+
+ packet_generator pkt_gen (.clk(clk), .reset(reset), .clear(clear),
+ .data_o(data), .sof_o(sof), .eof_o(eof),
+ .src_rdy_o(src_rdy), .dst_rdy_i(dst_rdy));
+
+ packet_verifier pkt_ver (.clk(clk), .reset(reset), .clear(clear),
+ .data_i(data), .sof_i(sof), .eof_i(eof),
+ .src_rdy_i(src_rdy), .dst_rdy_o(dst_rdy),
+ .total(total), .crc_err(crc_err), .seq_err(seq_err), .len_err(len_err));
+
+endmodule // packet_tb
diff --git a/usrp2/control_lib/newfifo/packet_verifier.v b/usrp2/control_lib/newfifo/packet_verifier.v
new file mode 100644
index 000000000..22c924198
--- /dev/null
+++ b/usrp2/control_lib/newfifo/packet_verifier.v
@@ -0,0 +1,63 @@
+
+
+// Packet format --
+// Line 1 -- Length, 32 bits
+// Line 2 -- Sequence number, 32 bits
+// Last line -- CRC, 32 bits
+
+module packet_verifier
+ (input clk, input reset, input clear,
+ input [7:0] data_i, input sof_i, output eof_i, input src_rdy_i, output dst_rdy_o,
+
+ output reg [31:0] total,
+ output reg [31:0] crc_err,
+ output reg [31:0] seq_err,
+ output reg [31:0] len_err);
+
+ assign dst_rdy_o = ~last_byte_d1;
+
+ reg [31:0] seq_num;
+ reg [31:0] length;
+
+ wire calc_crc = src_rdy_i & dst_rdy_o;
+
+ crc crc(.clk(clk), .reset(reset), .clear(last_byte_d1), .data(data_i),
+ .calc(calc_crc), .crc_out(), .match(match_crc));
+
+ wire first_byte, last_byte;
+ reg second_byte, last_byte_d1;
+
+ assign first_byte = src_rdy_i & dst_rdy_o & sof_i;
+ assign last_byte = src_rdy_i & dst_rdy_o & eof_i;
+
+ // stubs for now
+ wire match_seq = 1;
+ wire match_len = 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ last_byte_d1 <= 0;
+ else
+ last_byte_d1 <= last_byte;
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ total <= 0;
+ crc_err <= 0;
+ seq_err <= 0;
+ len_err <= 0;
+ end
+ else
+ if(last_byte_d1)
+ begin
+ total <= total + 1;
+ if(~match_crc)
+ crc_err <= crc_err + 1;
+ else if(~match_seq)
+ seq_err <= seq_err + 1;
+ else if(~match_len)
+ seq_err <= len_err + 1;
+ end
+
+endmodule // packet_verifier
diff --git a/usrp2/control_lib/nsgpio16LE.v b/usrp2/control_lib/nsgpio16LE.v
new file mode 100644
index 000000000..d6d7dcf56
--- /dev/null
+++ b/usrp2/control_lib/nsgpio16LE.v
@@ -0,0 +1,123 @@
+// Modified from code originally by Richard Herveille, his copyright is below
+
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// OpenCores Simple General Purpose IO core ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Richard Herveille ////
+//// richard@asics.ws ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+//// ////
+//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
+//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
+//// POSSIBILITY OF SUCH DAMAGE. ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+
+
+module nsgpio16LE
+ (input clk_i, input rst_i,
+ input cyc_i, input stb_i, input [3:0] adr_i, input we_i, input [15:0] dat_i,
+ output reg [15:0] dat_o, output reg ack_o,
+ input [31:0] atr, input [31:0] debug_0, input [31:0] debug_1,
+ inout [31:0] gpio
+ );
+
+ reg [31:0] ctrl, line, ddr, dbg, lgpio;
+
+ wire wb_acc = cyc_i & stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & we_i; // WISHBONE write access
+
+ always @(posedge clk_i or posedge rst_i)
+ if (rst_i)
+ begin
+ ctrl <= 32'h0;
+ line <= 32'h0;
+ ddr <= 32'h0;
+ dbg <= 32'h0;
+ end
+ else if (wb_wr)
+ case( adr_i[3:1] )
+ 3'b000 :
+ line[15:0] <= dat_i;
+ 3'b001 :
+ line[31:16] <= dat_i;
+ 3'b010 :
+ ddr[15:0] <= dat_i;
+ 3'b011 :
+ ddr[31:16] <= dat_i;
+ 3'b100 :
+ ctrl[15:0] <= dat_i;
+ 3'b101 :
+ ctrl[31:16] <= dat_i;
+ 3'b110 :
+ dbg[15:0] <= dat_i;
+ 3'b111 :
+ dbg[31:16] <= dat_i;
+ endcase // case ( adr_i[3:1] )
+
+ always @(posedge clk_i)
+ case (adr_i[3:1])
+ 3'b000 :
+ dat_o <= lgpio[15:0];
+ 3'b001 :
+ dat_o <= lgpio[31:16];
+ 3'b010 :
+ dat_o <= ddr[15:0];
+ 3'b011 :
+ dat_o <= ddr[31:16];
+ 3'b100 :
+ dat_o <= ctrl[15:0];
+ 3'b101 :
+ dat_o <= ctrl[31:16];
+ 3'b110 :
+ dat_o <= dbg[15:0];
+ 3'b111 :
+ dat_o <= dbg[31:16];
+ endcase // case (adr_i[3:1])
+
+
+ always @(posedge clk_i or posedge rst_i)
+ if (rst_i)
+ ack_o <= 1'b0;
+ else
+ ack_o <= wb_acc & !ack_o;
+
+ // latch GPIO input pins
+ always @(posedge clk_i)
+ lgpio <= gpio;
+
+ // assign GPIO outputs
+ integer n;
+ reg [31:0] igpio; // temporary internal signal
+
+ always @(ctrl or line or debug_1 or debug_0 or atr)
+ for(n=0;n<32;n=n+1)
+ igpio[n] <= ddr[n] ? (dbg[n] ? (ctrl[n] ? debug_1[n] : debug_0[n]) :
+ (ctrl[n] ? atr[n] : line[n]) )
+ : 1'bz;
+
+ assign gpio = igpio;
+
+endmodule
+
diff --git a/usrp2/control_lib/ram_2port_mixed_width.v b/usrp2/control_lib/ram_2port_mixed_width.v
new file mode 100644
index 000000000..fae7d8de3
--- /dev/null
+++ b/usrp2/control_lib/ram_2port_mixed_width.v
@@ -0,0 +1,120 @@
+
+module ram_2port_mixed_width
+ (input clk16,
+ input en16,
+ input we16,
+ input [10:0] addr16,
+ input [15:0] di16,
+ output [15:0] do16,
+ input clk32,
+ input en32,
+ input we32,
+ input [9:0] addr32,
+ input [31:0] di32,
+ output [31:0] do32);
+
+ wire en32a = en32 & ~addr32[9];
+ wire en32b = en32 & addr32[9];
+ wire en16a = en16 & ~addr16[10];
+ wire en16b = en16 & addr16[10];
+
+ wire [31:0] do32a, do32b;
+ wire [15:0] do16a, do16b;
+
+ assign do32 = addr32[9] ? do32b : do32a;
+ assign do16 = addr16[10] ? do16b : do16a;
+
+ RAMB16BWE_S36_S18 #(.INIT_A(36'h000000000),
+ .INIT_B(18'h00000),
+ .SIM_COLLISION_CHECK("ALL"), // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL"
+ .SRVAL_A(36'h000000000), // Port A output value upon SSR assertion
+ .SRVAL_B(18'h00000), // Port B output value upon SSR assertion
+ .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE
+ .WRITE_MODE_B("WRITE_FIRST") // WRITE_FIRST, READ_FIRST or NO_CHANGE
+ )
+ RAMB16BWE_S36_S18_0 (.DOA(do32a), // Port A 32-bit Data Output
+ .DOB(do16a), // Port B 16-bit Data Output
+ .DOPA(), // Port A 4-bit Parity Output
+ .DOPB(), // Port B 2-bit Parity Output
+ .ADDRA(addr32[8:0]), // Port A 9-bit Address Input
+ .ADDRB(addr16[9:0]), // Port B 10-bit Address Input
+ .CLKA(clk32), // Port A 1-bit Clock
+ .CLKB(clk16), // Port B 1-bit Clock
+ .DIA(di32), // Port A 32-bit Data Input
+ .DIB(di16), // Port B 16-bit Data Input
+ .DIPA(0), // Port A 4-bit parity Input
+ .DIPB(0), // Port-B 2-bit parity Input
+ .ENA(en32a), // Port A 1-bit RAM Enable Input
+ .ENB(en16a), // Port B 1-bit RAM Enable Input
+ .SSRA(0), // Port A 1-bit Synchronous Set/Reset Input
+ .SSRB(0), // Port B 1-bit Synchronous Set/Reset Input
+ .WEA({4{we32}}), // Port A 4-bit Write Enable Input
+ .WEB({2{we16}}) // Port B 2-bit Write Enable Input
+ );
+
+ RAMB16BWE_S36_S18 #(.INIT_A(36'h000000000),
+ .INIT_B(18'h00000),
+ .SIM_COLLISION_CHECK("ALL"), // "NONE", "WARNING_ONLY", "GENERATE_X_ONLY", "ALL"
+ .SRVAL_A(36'h000000000), // Port A output value upon SSR assertion
+ .SRVAL_B(18'h00000), // Port B output value upon SSR assertion
+ .WRITE_MODE_A("WRITE_FIRST"), // WRITE_FIRST, READ_FIRST or NO_CHANGE
+ .WRITE_MODE_B("WRITE_FIRST") // WRITE_FIRST, READ_FIRST or NO_CHANGE
+ )
+ RAMB16BWE_S36_S18_1 (.DOA(do32b), // Port A 32-bit Data Output
+ .DOB(do16b), // Port B 16-bit Data Output
+ .DOPA(), // Port A 4-bit Parity Output
+ .DOPB(), // Port B 2-bit Parity Output
+ .ADDRA(addr32[8:0]), // Port A 9-bit Address Input
+ .ADDRB(addr16[9:0]), // Port B 10-bit Address Input
+ .CLKA(clk32), // Port A 1-bit Clock
+ .CLKB(clk16), // Port B 1-bit Clock
+ .DIA(di32), // Port A 32-bit Data Input
+ .DIB(di16), // Port B 16-bit Data Input
+ .DIPA(0), // Port A 4-bit parity Input
+ .DIPB(0), // Port-B 2-bit parity Input
+ .ENA(en32b), // Port A 1-bit RAM Enable Input
+ .ENB(en16b), // Port B 1-bit RAM Enable Input
+ .SSRA(0), // Port A 1-bit Synchronous Set/Reset Input
+ .SSRB(0), // Port B 1-bit Synchronous Set/Reset Input
+ .WEA({4{we32}}), // Port A 4-bit Write Enable Input
+ .WEB({2{we16}}) // Port B 2-bit Write Enable Input
+ );
+
+endmodule // ram_2port_mixed_width
+
+
+
+
+// ISE 10.1.03 chokes on the following
+
+/*
+
+ reg [31:0] ram [(1<<AWIDTH)-1:0];
+ integer i;
+ initial
+ for(i=0;i<512;i=i+1)
+ ram[i] <= 32'b0;
+
+ always @(posedge clk16)
+ if (en16)
+ begin
+ if (we16)
+ if(addr16[0])
+ ram[addr16[10:1]][15:0] <= di16;
+ else
+ ram[addr16[10:1]][31:16] <= di16;
+ do16 <= addr16[0] ? ram[addr16[10:1]][15:0] : ram[addr16[10:1]][31:16];
+ end
+
+ always @(posedge clk32)
+ if (en32)
+ begin
+ if (we32)
+ ram[addr32] <= di32;
+ do32 <= ram[addr32];
+ end
+
+endmodule // ram_2port_mixed_width
+
+
+ */
diff --git a/usrp2/control_lib/setting_reg.v b/usrp2/control_lib/setting_reg.v
index ccbaa3d2e..c8aff230f 100644
--- a/usrp2/control_lib/setting_reg.v
+++ b/usrp2/control_lib/setting_reg.v
@@ -1,14 +1,14 @@
module setting_reg
- #(parameter my_addr = 0)
+ #(parameter my_addr = 0, parameter at_reset=32'd0)
(input clk, input rst, input strobe, input wire [7:0] addr,
input wire [31:0] in, output reg [31:0] out, output reg changed);
always @(posedge clk)
if(rst)
begin
- out <= 32'd0;
+ out <= at_reset;
changed <= 1'b0;
end
else
diff --git a/usrp2/control_lib/settings_bus_16LE.v b/usrp2/control_lib/settings_bus_16LE.v
new file mode 100644
index 000000000..76061e9e0
--- /dev/null
+++ b/usrp2/control_lib/settings_bus_16LE.v
@@ -0,0 +1,54 @@
+
+// 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.
+// This means that you write the low 16 bits first and then the high 16 bits.
+// The setting regs are strobed when the high 16 bits are written
+
+module settings_bus_16LE
+ #(parameter AWIDTH=16, RWIDTH=8)
+ (input wb_clk,
+ input wb_rst,
+ input [AWIDTH-1:0] wb_adr_i,
+ input [15:0] wb_dat_i,
+ input wb_stb_i,
+ input wb_we_i,
+ output reg wb_ack_o,
+ output strobe,
+ output reg [7:0] addr,
+ output reg [31:0] data);
+
+ reg stb_int;
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ begin
+ stb_int <= 1'b0;
+ addr <= 8'd0;
+ data <= 32'd0;
+ end
+ else if(wb_we_i & wb_stb_i)
+ begin
+ addr <= wb_adr_i[RWIDTH+1:2]; // Zero pad high bits
+ if(wb_adr_i[1])
+ begin
+ stb_int <= 1'b1; // We now have both halves
+ data[31:16] <= wb_dat_i;
+ end
+ else
+ begin
+ stb_int <= 1'b0; // Don't strobe, we need other half
+ data[15:0] <= wb_dat_i;
+ end
+ end
+ else
+ stb_int <= 1'b0;
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ wb_ack_o <= 0;
+ else
+ wb_ack_o <= wb_stb_i & ~wb_ack_o;
+
+ assign strobe = stb_int & wb_ack_o;
+
+endmodule // settings_bus_16LE
diff --git a/usrp2/control_lib/simple_uart.v b/usrp2/control_lib/simple_uart.v
index 22f0e70a2..0dd58b5f5 100644
--- a/usrp2/control_lib/simple_uart.v
+++ b/usrp2/control_lib/simple_uart.v
@@ -1,11 +1,12 @@
module simple_uart
#(parameter TXDEPTH = 1,
- parameter RXDEPTH = 1)
- (input clk_i, input rst_i,
- input we_i, input stb_i, input cyc_i, output reg ack_o,
- input [2:0] adr_i, input [31:0] dat_i, output reg [31:0] dat_o,
- output rx_int_o, output tx_int_o, output tx_o, input rx_i, output baud_o);
+ parameter RXDEPTH = 1,
+ parameter CLKDIV_DEFAULT = 16'd0)
+ (input clk_i, input rst_i,
+ input we_i, input stb_i, input cyc_i, output reg ack_o,
+ input [2:0] adr_i, input [31:0] dat_i, output reg [31:0] dat_o,
+ output rx_int_o, output tx_int_o, output tx_o, input rx_i, output baud_o);
// Register Map
localparam SUART_CLKDIV = 0;
@@ -30,7 +31,7 @@ module simple_uart
always @(posedge clk_i)
if (rst_i)
- clkdiv <= 0;
+ clkdiv <= CLKDIV_DEFAULT;
else if (wb_wr)
case(adr_i)
SUART_CLKDIV : clkdiv <= dat_i[15:0];
diff --git a/usrp2/gpmc/.gitignore b/usrp2/gpmc/.gitignore
new file mode 100644
index 000000000..3e14fa4f7
--- /dev/null
+++ b/usrp2/gpmc/.gitignore
@@ -0,0 +1,2 @@
+*.gif
+
diff --git a/usrp2/gpmc/burst_data_write.txt b/usrp2/gpmc/burst_data_write.txt
new file mode 100644
index 000000000..3b5dfc785
--- /dev/null
+++ b/usrp2/gpmc/burst_data_write.txt
@@ -0,0 +1,16 @@
+# OMAP burst writes to FPGA
+
+CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z.
+CLK=1.
+CLK=0,nWE=0,nCS=0,DATA=WR_DATA1.
+CLK=1.
+CLK=0,nWE=0,nCS=0,DATA=WR_DATA2.
+CLK=1.
+CLK=0,nWE=0,nCS=0,DATA=WR_DATA3.
+CLK=1.
+CLK=0,nWE=0,nCS=0,DATA=WR_DATA4.
+CLK=1.
+CLK=0,nWE=1,nCS=1,DATA=Z.
+CLK=1.
+
+
diff --git a/usrp2/gpmc/dbsm.v b/usrp2/gpmc/dbsm.v
new file mode 100644
index 000000000..530af7205
--- /dev/null
+++ b/usrp2/gpmc/dbsm.v
@@ -0,0 +1,80 @@
+
+module bsm
+ (input clk, input reset, input clear,
+ input write_done,
+ input read_done,
+ output readable,
+ output writeable);
+
+ reg state;
+ localparam ST_WRITEABLE = 0;
+ localparam ST_READABLE = 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ state <= ST_WRITEABLE;
+ else
+ case(state)
+ ST_WRITEABLE :
+ if(write_done)
+ state <= ST_READABLE;
+ ST_READABLE :
+ if(read_done)
+ state <= ST_WRITEABLE;
+ endcase // case (state)
+
+ assign readable = (state == ST_READABLE);
+ assign writeable = (state == ST_WRITEABLE);
+
+endmodule // bsm
+
+module dbsm
+ (input clk, input reset, input clear,
+ output reg read_sel, output read_ready, input read_done,
+ output reg write_sel, output write_ready, input write_done);
+
+ localparam NUM_BUFS = 2;
+
+ wire [NUM_BUFS-1:0] readable, writeable, read_done_buf, write_done_buf;
+
+ // Two of these buffer state machines
+ genvar i;
+ generate
+ for(i=0;i<NUM_BUFS;i=i+1)
+ begin : BSMS
+ bsm bsm(.clk(clk), .reset(reset), .clear(clear),
+ .write_done((write_sel == i) & write_done),
+ .read_done((read_sel == i) & read_done),
+ .readable(readable[i]), .writeable(writeable[i]));
+ end
+ endgenerate
+
+ reg full;
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ write_sel <= 0;
+ full <= 0;
+ end
+ else
+ if(write_done & writeable[write_sel])
+ if(write_sel ==(NUM_BUFS-1))
+ write_sel <= 0;
+ else
+ write_sel <= write_sel + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ read_sel <= 0;
+ else
+ if(read_done & readable[read_sel])
+ if(read_sel==(NUM_BUFS-1))
+ read_sel <= 0;
+ else
+ read_sel <= read_sel + 1;
+
+ assign write_ready = writeable[write_sel];
+ assign read_ready = readable[read_sel];
+
+endmodule // dbsm
diff --git a/usrp2/gpmc/edge_sync.v b/usrp2/gpmc/edge_sync.v
new file mode 100644
index 000000000..5d9417c08
--- /dev/null
+++ b/usrp2/gpmc/edge_sync.v
@@ -0,0 +1,22 @@
+
+
+module edge_sync
+ #(parameter POSEDGE = 1)
+ (input clk,
+ input rst,
+ input sig,
+ output trig);
+
+ reg [1:0] delay;
+
+ always @(posedge clk)
+ if(rst)
+ delay <= 2'b00;
+ else
+ delay <= {delay[0],sig};
+
+ assign trig = POSEDGE ? (delay==2'b01) : (delay==2'b10);
+
+endmodule // edge_sync
+
+
diff --git a/usrp2/gpmc/fifo_to_gpmc_async.v b/usrp2/gpmc/fifo_to_gpmc_async.v
new file mode 100644
index 000000000..5ac8b19bd
--- /dev/null
+++ b/usrp2/gpmc/fifo_to_gpmc_async.v
@@ -0,0 +1,38 @@
+
+// Assumes an asynchronous GPMC cycle
+// If a packet bigger or smaller than we are told is sent, behavior is undefined.
+// If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error.
+// If there is a bus error, we should be reset
+
+module fifo_to_gpmc_async
+ (input clk, input reset, input clear,
+ input [17:0] data_i, input src_rdy_i, output dst_rdy_o,
+ output [15:0] EM_D, input EM_NCS, input EM_NOE,
+ input [15:0] frame_len);
+
+ // Synchronize the async control signals
+ reg [1:0] cs_del, oe_del;
+ reg [15:0] counter;
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ cs_del <= 2'b11;
+ oe_del <= 2'b11;
+ end
+ else
+ begin
+ cs_del <= { cs_del[0], EM_NCS };
+ oe_del <= { oe_del[0], EM_NOE };
+ end
+
+ //wire do_read = (~cs_del[0] & (oe_del == 2'b10));
+ wire do_read = (~cs_del[1] & (oe_del == 2'b01)); // change output on trailing edge
+ wire first_read = (counter == 0);
+ wire last_read = ((counter+1) == frame_len);
+
+ assign EM_D = data_i[15:0];
+
+ assign dst_rdy_o = do_read;
+
+endmodule // fifo_to_gpmc_async
diff --git a/usrp2/gpmc/fifo_to_gpmc_sync.v b/usrp2/gpmc/fifo_to_gpmc_sync.v
new file mode 100644
index 000000000..ef59d7137
--- /dev/null
+++ b/usrp2/gpmc/fifo_to_gpmc_sync.v
@@ -0,0 +1,26 @@
+
+// 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.
+// If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error.
+// If there is a bus error, we should be reset
+
+module fifo_to_gpmc_sync
+ (input arst,
+ input [17:0] data_i, input src_rdy_i, output dst_rdy_o,
+ input EM_CLK, output [15:0] EM_D, input EM_NCS, input EM_NOE,
+ output fifo_ready,
+ output reg bus_error);
+
+ assign EM_D = data_i[15:0];
+ wire read_access = ~EM_NCS & ~EM_NOE;
+
+ assign dst_rdy_o = read_access;
+
+ always @(posedge EM_CLK or posedge arst)
+ if(arst)
+ bus_error <= 0;
+ else if(dst_rdy_o & ~src_rdy_i)
+ bus_error <= 1;
+
+
+endmodule // fifo_to_gpmc_sync
diff --git a/usrp2/gpmc/fifo_watcher.v b/usrp2/gpmc/fifo_watcher.v
new file mode 100644
index 000000000..4bba142b0
--- /dev/null
+++ b/usrp2/gpmc/fifo_watcher.v
@@ -0,0 +1,54 @@
+
+
+module fifo_watcher
+ (input clk, input reset, input clear,
+ input src_rdy1, input dst_rdy1, input sof1, input eof1,
+ input src_rdy2, input dst_rdy2, input sof2, input eof2,
+ output reg have_packet, output [15:0] length, output reg bus_error);
+
+ wire write = src_rdy1 & dst_rdy1 & eof1;
+ wire read = src_rdy2 & dst_rdy2 & eof2;
+ wire have_packet_int;
+ reg [15:0] counter;
+ wire [4:0] pkt_count;
+
+ fifo_short #(.WIDTH(16)) frame_lengths
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(counter), .src_rdy_i(write), .dst_rdy_o(),
+ .dataout(length), .src_rdy_o(have_packet_int), .dst_rdy_i(read),
+ .occupied(pkt_count), .space());
+
+ always @(posedge clk)
+ if(reset | clear)
+ counter <= 1; // Start at 1
+ else if(src_rdy1 & dst_rdy1)
+ if(eof1)
+ counter <= 1;
+ else
+ counter <= counter + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ bus_error <= 0;
+ else if(dst_rdy2 & ~src_rdy2)
+ bus_error <= 1;
+ else if(read & ~have_packet_int)
+ bus_error <= 1;
+
+ reg in_packet;
+ always @(posedge clk)
+ if(reset | clear)
+ have_packet <= 0;
+ else
+ have_packet <= (have_packet_int & ~in_packet) | (pkt_count>1) ;
+
+ always @(posedge clk)
+ if(reset | clear)
+ in_packet <= 0;
+ else if(src_rdy2 & dst_rdy2)
+ if(eof2)
+ in_packet <= 0;
+ else
+ in_packet <= 1;
+
+endmodule // fifo_watcher
diff --git a/usrp2/gpmc/gpmc_async.v b/usrp2/gpmc/gpmc_async.v
new file mode 100644
index 000000000..dd06478b3
--- /dev/null
+++ b/usrp2/gpmc/gpmc_async.v
@@ -0,0 +1,111 @@
+//////////////////////////////////////////////////////////////////////////////////
+
+module gpmc_async
+ (// GPMC signals
+ input arst,
+ input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE,
+ input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE,
+
+ // GPIOs for FIFO signalling
+ output rx_have_data, output tx_have_space, output reg bus_error, input bus_reset,
+
+ // Wishbone signals
+ input wb_clk, input wb_rst,
+ output [10: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,
+
+ // FIFO interface
+ input fifo_clk, input fifo_rst,
+ 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 [15:0] tx_frame_len, output [15:0] rx_frame_len,
+
+ output [31:0] debug
+ );
+
+ wire EM_output_enable = (~EM_NOE & (~EM_NCS4 | ~EM_NCS6));
+ wire [15:0] EM_D_fifo;
+ wire [15:0] EM_D_wb;
+
+ assign EM_D = ~EM_output_enable ? 16'bz : ~EM_NCS4 ? EM_D_fifo : EM_D_wb;
+
+ wire bus_error_tx, bus_error_rx;
+
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ bus_error <= 0;
+ else
+ bus_error <= bus_error_tx | bus_error_rx;
+
+ // CS4 is RAM_2PORT for DATA PATH (high-speed data)
+ // Writes go into one RAM, reads come from the other
+ // CS6 is for CONTROL PATH (wishbone)
+
+ // ////////////////////////////////////////////
+ // TX Data Path
+
+ wire [17:0] tx18_data, tx18b_data;
+ wire tx18_src_rdy, tx18_dst_rdy, tx18b_src_rdy, tx18b_dst_rdy;
+ wire [15:0] tx_fifo_space;
+
+ gpmc_to_fifo_async gpmc_to_fifo_async
+ (.EM_D(EM_D), .EM_NBE(EM_NBE), .EM_NCS(EM_NCS4), .EM_NWE(EM_NWE),
+ .fifo_clk(fifo_clk), .fifo_rst(fifo_rst),
+ .data_o(tx18_data), .src_rdy_o(tx18_src_rdy), .dst_rdy_i(tx18_dst_rdy),
+ .frame_len(tx_frame_len), .fifo_space(tx_fifo_space), .fifo_ready(tx_have_space),
+ .bus_error(bus_error_tx) );
+
+ fifo_cascade #(.WIDTH(18), .SIZE(10)) tx_fifo
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .datain(tx18_data), .src_rdy_i(tx18_src_rdy), .dst_rdy_o(tx18_dst_rdy), .space(tx_fifo_space),
+ .dataout(tx18b_data), .src_rdy_o(tx18b_src_rdy), .dst_rdy_i(tx18b_dst_rdy), .occupied());
+
+ fifo19_to_fifo36 f19_to_f36
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .f19_datain({1'b0,tx18b_data}), .f19_src_rdy_i(tx18b_src_rdy), .f19_dst_rdy_o(tx18b_dst_rdy),
+ .f36_dataout(tx_data_o), .f36_src_rdy_o(tx_src_rdy_o), .f36_dst_rdy_i(tx_dst_rdy_i));
+
+ // ////////////////////////////////////////////
+ // RX Data Path
+
+ wire [17:0] rx18_data, rx18b_data;
+ wire rx18_src_rdy, rx18_dst_rdy, rx18b_src_rdy, rx18b_dst_rdy;
+ wire [15:0] rx_fifo_space;
+
+ fifo36_to_fifo18 f18_to_f36
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .f36_datain(rx_data_i), .f36_src_rdy_i(rx_src_rdy_i), .f36_dst_rdy_o(rx_dst_rdy_o),
+ .f18_dataout(rx18_data), .f18_src_rdy_o(rx18_src_rdy), .f18_dst_rdy_i(rx18_dst_rdy) );
+
+ fifo_cascade #(.WIDTH(18), .SIZE(12)) rx_fifo
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .datain(rx18_data), .src_rdy_i(rx18_src_rdy), .dst_rdy_o(rx18_dst_rdy), .space(rx_fifo_space),
+ .dataout(rx18b_data), .src_rdy_o(rx18b_src_rdy), .dst_rdy_i(rx18b_dst_rdy), .occupied());
+
+ fifo_to_gpmc_async fifo_to_gpmc_async
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .data_i(rx18b_data), .src_rdy_i(rx18b_src_rdy), .dst_rdy_o(rx18b_dst_rdy),
+ .EM_D(EM_D_fifo), .EM_NCS(EM_NCS4), .EM_NOE(EM_NOE),
+ .frame_len(rx_frame_len) );
+
+ fifo_watcher fifo_watcher
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .src_rdy1(rx18_src_rdy), .dst_rdy1(rx18_dst_rdy), .sof1(rx18_data[16]), .eof1(rx18_data[17]),
+ .src_rdy2(rx18b_src_rdy), .dst_rdy2(rx18b_dst_rdy), .sof2(rx18b_data[16]), .eof2(rx18b_data[17]),
+ .have_packet(rx_have_data), .length(rx_frame_len), .bus_error(bus_error_rx) );
+
+ // ////////////////////////////////////////////
+ // Control path on CS6
+
+ gpmc_wb gpmc_wb
+ (.EM_CLK(EM_CLK), .EM_D_in(EM_D), .EM_D_out(EM_D_wb), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_NCS(EM_NCS6), .EM_NWE(EM_NWE), .EM_NOE(EM_NOE),
+ .wb_clk(wb_clk), .wb_rst(wb_rst),
+ .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) );
+
+ assign debug = 0;
+
+endmodule // gpmc_async
diff --git a/usrp2/gpmc/gpmc_sync.v b/usrp2/gpmc/gpmc_sync.v
new file mode 100644
index 000000000..825d131d8
--- /dev/null
+++ b/usrp2/gpmc/gpmc_sync.v
@@ -0,0 +1,107 @@
+//////////////////////////////////////////////////////////////////////////////////
+
+module gpmc_sync
+ (// GPMC signals
+ input arst,
+ input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE,
+ input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE,
+
+ // GPIOs for FIFO signalling
+ output rx_have_data, output tx_have_space, output bus_error, input bus_reset,
+
+ // Wishbone signals
+ input wb_clk, input wb_rst,
+ output [10: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,
+
+ // FIFO interface
+ input fifo_clk, input fifo_rst,
+ 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,
+
+ output [31:0] debug
+ );
+
+ wire EM_output_enable = (~EM_NOE & (~EM_NCS4 | ~EM_NCS6));
+ wire [15:0] EM_D_fifo;
+ wire [15:0] EM_D_wb;
+
+ assign EM_D = ~EM_output_enable ? 16'bz : ~EM_NCS4 ? EM_D_fifo : EM_D_wb;
+
+ wire bus_error_tx, bus_error_rx;
+ assign bus_error = bus_error_tx | bus_error_rx;
+
+ // CS4 is RAM_2PORT for DATA PATH (high-speed data)
+ // Writes go into one RAM, reads come from the other
+ // CS6 is for CONTROL PATH (wishbone)
+
+ // ////////////////////////////////////////////
+ // TX Data Path
+
+ wire [17:0] tx18_data, tx18b_data;
+ wire tx18_src_rdy, tx18_dst_rdy, tx18b_src_rdy, tx18b_dst_rdy;
+ wire [15:0] tx_fifo_space, tx_frame_len;
+
+ assign tx_frame_len = 10;
+
+ gpmc_to_fifo_sync gpmc_to_fifo_sync
+ (.arst(arst),
+ .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_NBE(EM_NBE), .EM_NCS(EM_NCS4), .EM_NWE(EM_NWE),
+ .data_o(tx18_data), .src_rdy_o(tx18_src_rdy), .dst_rdy_i(tx18_dst_rdy),
+ .frame_len(tx_frame_len), .fifo_space(tx_fifo_space), .fifo_ready(tx_have_space),
+ .bus_error(bus_error_tx) );
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) tx_fifo
+ (.wclk(EM_CLK), .datain(tx18_data),
+ .src_rdy_i(tx18_src_rdy), .dst_rdy_o(tx18_dst_rdy), .space(tx_fifo_space),
+ .rclk(fifo_clk), .dataout(tx18b_data),
+ .src_rdy_o(tx18b_src_rdy), .dst_rdy_i(tx18b_dst_rdy), .occupied(), .arst(arst));
+
+ fifo19_to_fifo36 f19_to_f36
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .f19_datain({1'b0,tx18b_data}), .f19_src_rdy_i(tx18b_src_rdy), .f19_dst_rdy_o(tx18b_dst_rdy),
+ .f36_dataout(tx_data_o), .f36_src_rdy_o(tx_src_rdy_o), .f36_dst_rdy_i(tx_dst_rdy_i));
+
+ // ////////////////////////////////////////////
+ // RX Data Path
+
+ wire [17:0] rx18_data, rx18b_data;
+ wire rx18_src_rdy, rx18_dst_rdy, rx18b_src_rdy, rx18b_dst_rdy;
+ wire [15:0] rx_fifo_space, rx_frame_len;
+
+ fifo36_to_fifo18 f18_to_f36
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .f36_datain(rx_data_i), .f36_src_rdy_i(rx_src_rdy_i), .f36_dst_rdy_o(rx_dst_rdy_o),
+ .f18_dataout(rx18_data), .f18_src_rdy_o(rx18_src_rdy), .f18_dst_rdy_i(rx18_dst_rdy) );
+
+ fifo_2clock_cascade #(.WIDTH(18), .SIZE(10)) rx_fifo
+ (.wclk(fifo_clk), .datain(rx18_data),
+ .src_rdy_i(rx18_src_rdy), .dst_rdy_o(rx18_dst_rdy), .space(rx_fifo_space),
+ .rclk(EM_CLK), .dataout(rx18b_data),
+ .src_rdy_o(rx18b_src_rdy), .dst_rdy_i(rx18b_dst_rdy), .occupied(), .arst(arst));
+
+ fifo_to_gpmc_sync fifo_to_gpmc_sync
+ (.arst(arst),
+ .data_i(rx18b_data), .src_rdy_i(rx18b_src_rdy), .dst_rdy_o(rx18b_dst_rdy),
+ .EM_CLK(EM_CLK), .EM_D(EM_D_fifo), .EM_NCS(EM_NCS4), .EM_NOE(EM_NOE),
+ .fifo_ready(rx_have_data) );
+
+ fifo_watcher fifo_watcher
+ (.clk(fifo_clk), .reset(fifo_rst), .clear(0),
+ .src_rdy(rx18_src_rdy), .dst_rdy(rx18_dst_rdy), .sof(rx18_data[16]), .eof(rx18_data[17]),
+ .have_packet(), .length(), .next() );
+
+ // ////////////////////////////////////////////
+ // Control path on CS6
+
+ gpmc_wb gpmc_wb
+ (.EM_CLK(EM_CLK), .EM_D_in(EM_D), .EM_D_out(EM_D_wb), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_NCS(EM_NCS6), .EM_NWE(EM_NWE), .EM_NOE(EM_NOE),
+ .wb_clk(wb_clk), .wb_rst(wb_rst),
+ .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) );
+
+ assign debug = 0;
+
+endmodule // gpmc_sync
diff --git a/usrp2/gpmc/gpmc_to_fifo_async.v b/usrp2/gpmc/gpmc_to_fifo_async.v
new file mode 100644
index 000000000..3d29745a2
--- /dev/null
+++ b/usrp2/gpmc/gpmc_to_fifo_async.v
@@ -0,0 +1,68 @@
+
+module gpmc_to_fifo_async
+ (input [15:0] EM_D, input [1:0] EM_NBE, input EM_NCS, input EM_NWE,
+
+ input fifo_clk, input fifo_rst,
+ output reg [17:0] data_o, output reg src_rdy_o, input dst_rdy_i,
+
+ input [15:0] frame_len, input [15:0] fifo_space, output reg fifo_ready,
+ output reg bus_error );
+
+ reg [15:0] counter;
+ // Synchronize the async control signals
+ reg [1:0] cs_del, we_del;
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ begin
+ cs_del <= 2'b11;
+ we_del <= 2'b11;
+ end
+ else
+ begin
+ cs_del <= { cs_del[0], EM_NCS };
+ we_del <= { we_del[0], EM_NWE };
+ end
+
+ wire do_write = (~cs_del[0] & (we_del == 2'b10));
+ wire first_write = (counter == 0);
+ wire last_write = ((counter+1) == frame_len);
+
+ always @(posedge fifo_clk)
+ if(do_write)
+ begin
+ data_o[15:0] <= EM_D;
+ data_o[16] <= first_write;
+ data_o[17] <= last_write;
+ // no byte writes data_o[18] <= |EM_NBE; // mark half full if either is not enabled FIXME
+ end
+
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ src_rdy_o <= 0;
+ else if(do_write)
+ src_rdy_o <= 1;
+ else
+ src_rdy_o <= 0; // Assume it was taken
+
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ counter <= 0;
+ else if(do_write)
+ if(last_write)
+ counter <= 0;
+ else
+ counter <= counter + 1;
+
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ fifo_ready <= 0;
+ else
+ fifo_ready <= /* first_write & */ (fifo_space > 16'd1023);
+
+ always @(posedge fifo_clk)
+ if(fifo_rst)
+ bus_error <= 0;
+ else if(src_rdy_o & ~dst_rdy_i)
+ bus_error <= 1;
+
+endmodule // gpmc_to_fifo_async
diff --git a/usrp2/gpmc/gpmc_to_fifo_sync.v b/usrp2/gpmc/gpmc_to_fifo_sync.v
new file mode 100644
index 000000000..688de0e17
--- /dev/null
+++ b/usrp2/gpmc/gpmc_to_fifo_sync.v
@@ -0,0 +1,57 @@
+
+// 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.
+// If dst_rdy_i is low when we get data, behavior is undefined and we signal bus error.
+// If there is a bus error, we should be reset
+
+module gpmc_to_fifo_sync
+ (input arst,
+ input EM_CLK, input [15:0] EM_D, input [1:0] EM_NBE,
+ input EM_NCS, input EM_NWE,
+ output reg [17:0] data_o, output reg src_rdy_o, input dst_rdy_i,
+ input [15:0] frame_len, input [15:0] fifo_space, output fifo_ready,
+ output reg bus_error);
+
+ reg [10:0] counter;
+ wire first_write = (counter == 0);
+ wire last_write = ((counter+1) == frame_len);
+ wire do_write = ~EM_NCS & ~EM_NWE;
+
+ always @(posedge EM_CLK or posedge arst)
+ if(arst)
+ data_o <= 0;
+ else if(do_write)
+ begin
+ data_o[15:0] <= EM_D;
+ data_o[16] <= first_write;
+ data_o[17] <= last_write;
+ // no byte writes data_o[18] <= |EM_NBE; // mark half full if either is not enabled FIXME
+ end
+
+ always @(posedge EM_CLK or posedge arst)
+ if(arst)
+ src_rdy_o <= 0;
+ else if(do_write & ~bus_error) // Don't put junk in if there is a bus error
+ src_rdy_o <= 1;
+ else
+ src_rdy_o <= 0; // Assume it was taken, ignore dst_rdy_i
+
+ always @(posedge EM_CLK or posedge arst)
+ if(arst)
+ counter <= 0;
+ else if(do_write)
+ if(last_write)
+ counter <= 0;
+ else
+ counter <= counter + 1;
+
+ assign fifo_ready = first_write & (fifo_space > frame_len);
+
+ always @(posedge EM_CLK or posedge arst)
+ if(arst)
+ bus_error <= 0;
+ else if(src_rdy_o & ~dst_rdy_i)
+ bus_error <= 1;
+ // must be reset to make the error go away
+
+endmodule // gpmc_to_fifo_sync
diff --git a/usrp2/gpmc/gpmc_wb.v b/usrp2/gpmc/gpmc_wb.v
new file mode 100644
index 000000000..db6fbc6e9
--- /dev/null
+++ b/usrp2/gpmc/gpmc_wb.v
@@ -0,0 +1,57 @@
+
+
+module gpmc_wb
+ (input EM_CLK, input [15:0] EM_D_in, output [15:0] EM_D_out, input [10:1] EM_A, input [1:0] EM_NBE,
+ input EM_NCS, input EM_NWE, input EM_NOE,
+
+ input wb_clk, input wb_rst,
+ output reg [10:0] wb_adr_o, output reg [15:0] wb_dat_mosi, input [15:0] wb_dat_miso,
+ output reg [1:0] wb_sel_o, output wb_cyc_o, output reg wb_stb_o, output reg wb_we_o, input wb_ack_i);
+
+ // ////////////////////////////////////////////
+ // Control Path, Wishbone bus bridge (wb master)
+ reg [1:0] cs_del, we_del, oe_del;
+
+ // Synchronize the async control signals
+ always @(posedge wb_clk)
+ begin
+ cs_del <= { cs_del[0], EM_NCS };
+ we_del <= { we_del[0], EM_NWE };
+ oe_del <= { oe_del[0], EM_NOE };
+ end
+
+ always @(posedge wb_clk)
+ if(cs_del == 2'b10) // Falling Edge
+ wb_adr_o <= { EM_A, 1'b0 };
+
+ always @(posedge wb_clk)
+ if(we_del == 2'b10) // Falling Edge
+ begin
+ wb_dat_mosi <= EM_D_in;
+ wb_sel_o <= ~EM_NBE;
+ end
+
+ reg [15:0] EM_D_hold;
+
+ always @(posedge wb_clk)
+ if(wb_ack_i)
+ EM_D_hold <= wb_dat_miso;
+
+ assign EM_D_out = wb_ack_i ? wb_dat_miso : EM_D_hold;
+
+ assign wb_cyc_o = wb_stb_o;
+
+ always @(posedge wb_clk)
+ if(~cs_del[0] & (we_del == 2'b10) )
+ wb_we_o <= 1;
+ else if(wb_ack_i) // Turn off we when done. Could also use we_del[0], others...
+ wb_we_o <= 0;
+
+ // FIXME should this look at cs_del[1]?
+ always @(posedge wb_clk)
+ if(~cs_del[0] & ((we_del == 2'b10) | (oe_del == 2'b10)))
+ wb_stb_o <= 1;
+ else if(wb_ack_i)
+ wb_stb_o <= 0;
+
+endmodule // gpmc_wb
diff --git a/usrp2/gpmc/make_timing_diag b/usrp2/gpmc/make_timing_diag
new file mode 100755
index 000000000..03166ad35
--- /dev/null
+++ b/usrp2/gpmc/make_timing_diag
@@ -0,0 +1,6 @@
+#!/bin/sh
+drawtiming -o single_data_write.gif single_data_write.txt
+drawtiming -o single_data_read.gif single_data_read.txt
+drawtiming -o burst_data_write.gif burst_data_write.txt
+#drawtiming -o burst_data_read.gif burst_data_read.txt
+
diff --git a/usrp2/gpmc/ram_to_fifo.v b/usrp2/gpmc/ram_to_fifo.v
new file mode 100644
index 000000000..8549dcc35
--- /dev/null
+++ b/usrp2/gpmc/ram_to_fifo.v
@@ -0,0 +1,46 @@
+
+
+module ram_to_fifo
+ (input clk, input reset,
+ input [10:0] read_length, // From the dbsm (?)
+ output read_en, output reg [8:0] read_addr, input [31:0] read_data, input read_ready, output read_done,
+ output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
+
+ // read_length/2 = number of 32 bit lines, numbered 0 through read_length/2-1
+ wire [8:0] last_line = (read_length[10:1]-1);
+
+ reg read_phase, sop;
+
+ assign read_en = (read_phase == 0) | dst_rdy_i;
+ assign src_rdy_o = (read_phase == 1);
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ read_addr <= 0;
+ read_phase <= 0;
+ sop <= 1;
+ end
+ else
+ if(read_phase == 0)
+ begin
+ read_addr <= read_ready;
+ read_phase <= read_ready;
+ end
+ else if(dst_rdy_i)
+ begin
+ sop <= 0;
+ if(read_addr == last_line)
+ begin
+ read_addr <= 0;
+ read_phase <= 0;
+ end
+ else
+ read_addr <= read_addr + 1;
+ end
+
+ assign read_done = (read_phase == 1) & (read_addr == last_line) & dst_rdy_i;
+ wire eop = (read_addr == last_line);
+ assign data_o = { 2'b00, eop, sop, read_data };
+
+endmodule // ram_to_fifo
diff --git a/usrp2/gpmc/single_data_read.txt b/usrp2/gpmc/single_data_read.txt
new file mode 100644
index 000000000..1dc0e3a78
--- /dev/null
+++ b/usrp2/gpmc/single_data_read.txt
@@ -0,0 +1,12 @@
+# OMAP writes to FPGA
+# initialize the signals
+CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z.
+CLK=1.
+CLK=0,nOE=0,nCS=0,DATA=RD_DATA.
+CLK=1.
+CLK=0.
+CLK=1.
+CLK=0,nOE=1,nCS=1,DATA=Z.
+CLK=1.
+
+
diff --git a/usrp2/gpmc/single_data_write.txt b/usrp2/gpmc/single_data_write.txt
new file mode 100644
index 000000000..287e3e2c1
--- /dev/null
+++ b/usrp2/gpmc/single_data_write.txt
@@ -0,0 +1,10 @@
+# OMAP writes to FPGA
+# initialize the signals
+CLK=0,nWE=1,nCS=1,nOE=1,DATA=Z.
+CLK=1.
+CLK=0,nWE=0,nCS=0,DATA=WR_DATA.
+CLK=1.
+CLK=0,nWE=1,nCS=1,DATA=Z.
+CLK=1.
+
+
diff --git a/usrp2/models/gpmc_model_async.v b/usrp2/models/gpmc_model_async.v
new file mode 100644
index 000000000..beeaee028
--- /dev/null
+++ b/usrp2/models/gpmc_model_async.v
@@ -0,0 +1,130 @@
+`timescale 1ps/1ps
+
+module gpmc_model_async
+ (output EM_CLK, inout [15:0] EM_D, output reg [10:1] EM_A, output reg [1:0] EM_NBE,
+ output reg EM_WAIT0, output reg EM_NCS4, output reg EM_NCS6,
+ output reg EM_NWE, output reg EM_NOE );
+
+ assign EM_CLK = 0;
+ reg [15:0] EM_D_int;
+ assign EM_D = EM_D_int;
+
+ initial
+ begin
+ EM_A <= 10'bz;
+ EM_NBE <= 2'b11;
+ EM_NWE <= 1;
+ EM_NOE <= 1;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ EM_D_int <= 16'bz;
+ EM_WAIT0 <= 0; // FIXME this is actually an input
+ end
+
+ task GPMC_Write;
+ input ctrl;
+ input [10:0] addr;
+ input [15:0] data;
+ begin
+ #23000;
+ EM_A <= addr[10:1];
+ EM_D_int <= data;
+ #20100;
+ if(ctrl)
+ EM_NCS6 <= 0;
+ else
+ EM_NCS4 <= 0;
+ #14000;
+ EM_NWE <= 0;
+ #77500;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ //#1.5;
+ EM_NWE <= 1;
+ #60000;
+ EM_A <= 10'bz;
+ EM_D_int <= 16'bz;
+ end
+ endtask // GPMC_Write
+
+ task GPMC_Read;
+ input ctrl;
+ input [10:0] addr;
+ begin
+ #13000;
+ EM_A <= addr[10:1];
+ #3000;
+ if(ctrl)
+ EM_NCS6 <= 0;
+ else
+ EM_NCS4 <= 0;
+ #14000;
+ EM_NOE <= 0;
+ #77500;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ //#1.5;
+ $display("Data Read from GPMC: %X",EM_D);
+ EM_NOE <= 1;
+ #254000;
+ EM_A <= 10'bz;
+ end
+ endtask // GPMC_Read
+
+ initial
+ begin
+ #1000000;
+ GPMC_Write(1,36,16'hF00D);
+ #1000000;
+ GPMC_Read(1,36);
+ #1000000;
+ GPMC_Write(0,0,16'h1234);
+ GPMC_Write(0,0,16'h5678);
+ GPMC_Write(0,0,16'h9abc);
+ GPMC_Write(0,0,16'hF00D);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ #1000000;
+ GPMC_Write(0,0,16'h1234);
+ GPMC_Write(0,0,16'h5678);
+ GPMC_Write(0,0,16'h9abc);
+ GPMC_Write(0,0,16'hF00D);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'hDEAD);
+ GPMC_Write(0,0,16'h9876);
+ #1000000;
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ #1000000;
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ GPMC_Read(0,0);
+ #1000000;
+ GPMC_Read(0,0);
+ #100000000;
+ $finish;
+ end
+
+endmodule // gpmc_model_async
diff --git a/usrp2/models/gpmc_model_sync.v b/usrp2/models/gpmc_model_sync.v
new file mode 100644
index 000000000..641720c15
--- /dev/null
+++ b/usrp2/models/gpmc_model_sync.v
@@ -0,0 +1,97 @@
+
+
+module gpmc_model_sync
+ (output reg EM_CLK, inout [15:0] EM_D, output reg [10:1] EM_A, output reg [1:0] EM_NBE,
+ output reg EM_WAIT0, output reg EM_NCS4, output reg EM_NCS6,
+ output reg EM_NWE, output reg EM_NOE );
+
+ reg [15:0] EM_D_int;
+ assign EM_D = EM_D_int;
+
+ initial
+ begin
+ EM_CLK <= 0;
+ EM_A <= 10'bz;
+ EM_NBE <= 2'b11;
+ EM_NWE <= 1;
+ EM_NOE <= 1;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ EM_D_int <= 16'bz;
+ EM_WAIT0 <= 0; // FIXME this is actually an input
+ end
+
+ task GPMC_Write;
+ input ctrl;
+ input [10:0] addr;
+ input [15:0] data;
+ begin
+ EM_CLK <= 1;
+ #10;
+ EM_CLK <= 0;
+ EM_NWE <= 0;
+ if(ctrl)
+ EM_NCS6 <= 0;
+ else
+ EM_NCS4 <= 0;
+ EM_A <= addr[10:1];
+ EM_D_int <= data;
+ #10;
+ EM_CLK <= 1;
+ #10;
+ EM_CLK <= 0;
+ EM_NWE <= 1;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ EM_A <= 10'bz;
+ EM_D_int <= 16'bz;
+ #100;
+ end
+ endtask // GPMC_Write
+
+ task GPMC_Read;
+ input ctrl;
+ input [10:0] addr;
+ begin
+ #1.3;
+ EM_A <= addr[10:1];
+ #3;
+ if(ctrl)
+ EM_NCS6 <= 0;
+ else
+ EM_NCS4 <= 0;
+ #14;
+ EM_NOE <= 0;
+ #77.5;
+ EM_NCS4 <= 1;
+ EM_NCS6 <= 1;
+ //#1.5;
+ $display("Data Read from GPMC: %X",EM_D);
+ EM_NOE <= 1;
+ #254;
+ EM_A <= 10'bz;
+ end
+ endtask // GPMC_Read
+
+ initial
+ begin
+ #1000;
+ GPMC_Write(1,36,16'hF00D);
+ #1000;
+ GPMC_Read(1,36);
+ #1000;
+ GPMC_Write(0,36,16'h1234);
+ GPMC_Write(0,38,16'h5678);
+ GPMC_Write(0,40,16'h9abc);
+ GPMC_Write(0,11'h2F4,16'hF00D);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ GPMC_Write(0,11'h7FE,16'hDEAD);
+ #100000;
+ $finish;
+ end
+
+endmodule // gpmc_model
diff --git a/usrp2/opencores/spi/rtl/verilog/spi_clgen.v b/usrp2/opencores/spi/rtl/verilog/spi_clgen.v
index 7bc4f6e5e..2d9c34f40 100644
--- a/usrp2/opencores/spi/rtl/verilog/spi_clgen.v
+++ b/usrp2/opencores/spi/rtl/verilog/spi_clgen.v
@@ -39,12 +39,9 @@
//////////////////////////////////////////////////////////////////////
`include "spi_defines.v"
-`include "timescale.v"
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
- parameter Tp = 1;
-
input clk_in; // input clock (system clock)
input rst; // reset
input enable; // clock enable
@@ -68,40 +65,40 @@ module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge,
assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
// Counter counts half period
- always @(posedge clk_in or posedge rst)
+ always @(posedge clk_in)
begin
if(rst)
- cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
+ cnt <= {`SPI_DIVIDER_LEN{1'b1}};
else
begin
if(!enable || cnt_zero)
- cnt <= #Tp divider;
+ cnt <= divider;
else
- cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
+ cnt <= cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
end
end
// clk_out is asserted every other half period
- always @(posedge clk_in or posedge rst)
+ always @(posedge clk_in)
begin
if(rst)
- clk_out <= #Tp 1'b0;
+ clk_out <= 1'b0;
else
- clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
+ clk_out <= (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
// Pos and neg edge signals
- always @(posedge clk_in or posedge rst)
+ always @(posedge clk_in)
begin
if(rst)
begin
- pos_edge <= #Tp 1'b0;
- neg_edge <= #Tp 1'b0;
+ pos_edge <= 1'b0;
+ neg_edge <= 1'b0;
end
else
begin
- pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
- neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
+ pos_edge <= (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
+ neg_edge <= (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
end
end
endmodule
diff --git a/usrp2/opencores/spi/rtl/verilog/spi_defines.v b/usrp2/opencores/spi/rtl/verilog/spi_defines.v
index a6925918e..963a680a8 100644
--- a/usrp2/opencores/spi/rtl/verilog/spi_defines.v
+++ b/usrp2/opencores/spi/rtl/verilog/spi_defines.v
@@ -43,8 +43,8 @@
// low frequency of system clock this can be reduced.
// Use SPI_DIVIDER_LEN for fine tuning theexact number.
//
-//`define SPI_DIVIDER_LEN_8
-`define SPI_DIVIDER_LEN_16
+`define SPI_DIVIDER_LEN_8
+//`define SPI_DIVIDER_LEN_16
//`define SPI_DIVIDER_LEN_24
//`define SPI_DIVIDER_LEN_32
@@ -66,9 +66,9 @@
// Use SPI_MAX_CHAR for fine tuning the exact number, when using
// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
//
-`define SPI_MAX_CHAR_128
+//`define SPI_MAX_CHAR_128
//`define SPI_MAX_CHAR_64
-//`define SPI_MAX_CHAR_32
+`define SPI_MAX_CHAR_32
//`define SPI_MAX_CHAR_24
//`define SPI_MAX_CHAR_16
//`define SPI_MAX_CHAR_8
@@ -137,7 +137,7 @@
`define SPI_TX_2 2
`define SPI_TX_3 3
`define SPI_CTRL 4
-`define SPI_DEVIDE 5
+`define SPI_DIVIDE 5
`define SPI_SS 6
//
diff --git a/usrp2/opencores/spi/rtl/verilog/spi_shift.v b/usrp2/opencores/spi/rtl/verilog/spi_shift.v
index b17ac8b1f..ac3bb3f48 100644
--- a/usrp2/opencores/spi/rtl/verilog/spi_shift.v
+++ b/usrp2/opencores/spi/rtl/verilog/spi_shift.v
@@ -39,15 +39,12 @@
//////////////////////////////////////////////////////////////////////
`include "spi_defines.v"
-`include "timescale.v"
module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
pos_edge, neg_edge, rx_negedge, tx_negedge,
tip, last,
p_in, p_out, s_clk, s_in, s_out);
- parameter Tp = 1;
-
input clk; // system clock
input rst; // reset
input [3:0] latch; // latch signal for storing the data in shift register
@@ -89,149 +86,149 @@ module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
// Character bit counter
- always @(posedge clk or posedge rst)
+ always @(posedge clk)
begin
if(rst)
- cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
+ cnt <= {`SPI_CHAR_LEN_BITS+1{1'b0}};
else
begin
if(tip)
- cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
+ cnt <= pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
else
- cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
+ cnt <= !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
end
end
// Transfer in progress
- always @(posedge clk or posedge rst)
+ always @(posedge clk)
begin
if(rst)
- tip <= #Tp 1'b0;
+ tip <= 1'b0;
else if(go && ~tip)
- tip <= #Tp 1'b1;
+ tip <= 1'b1;
else if(tip && last && pos_edge)
- tip <= #Tp 1'b0;
+ tip <= 1'b0;
end
// Sending bits to the line
- always @(posedge clk or posedge rst)
+ always @(posedge clk)
begin
if (rst)
- s_out <= #Tp 1'b0;
+ s_out <= 1'b0;
else
- s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
+ s_out <= (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
end
// Receiving bits from the line
- always @(posedge clk or posedge rst)
+ always @(posedge clk)
begin
if (rst)
- data <= #Tp {`SPI_MAX_CHAR{1'b0}};
+ data <= {`SPI_MAX_CHAR{1'b0}};
`ifdef SPI_MAX_CHAR_128
else if (latch[0] && !tip)
begin
if (byte_sel[3])
- data[31:24] <= #Tp p_in[31:24];
+ data[31:24] <= p_in[31:24];
if (byte_sel[2])
- data[23:16] <= #Tp p_in[23:16];
+ data[23:16] <= p_in[23:16];
if (byte_sel[1])
- data[15:8] <= #Tp p_in[15:8];
+ data[15:8] <= p_in[15:8];
if (byte_sel[0])
- data[7:0] <= #Tp p_in[7:0];
+ data[7:0] <= p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
- data[63:56] <= #Tp p_in[31:24];
+ data[63:56] <= p_in[31:24];
if (byte_sel[2])
- data[55:48] <= #Tp p_in[23:16];
+ data[55:48] <= p_in[23:16];
if (byte_sel[1])
- data[47:40] <= #Tp p_in[15:8];
+ data[47:40] <= p_in[15:8];
if (byte_sel[0])
- data[39:32] <= #Tp p_in[7:0];
+ data[39:32] <= p_in[7:0];
end
else if (latch[2] && !tip)
begin
if (byte_sel[3])
- data[95:88] <= #Tp p_in[31:24];
+ data[95:88] <= p_in[31:24];
if (byte_sel[2])
- data[87:80] <= #Tp p_in[23:16];
+ data[87:80] <= p_in[23:16];
if (byte_sel[1])
- data[79:72] <= #Tp p_in[15:8];
+ data[79:72] <= p_in[15:8];
if (byte_sel[0])
- data[71:64] <= #Tp p_in[7:0];
+ data[71:64] <= p_in[7:0];
end
else if (latch[3] && !tip)
begin
if (byte_sel[3])
- data[127:120] <= #Tp p_in[31:24];
+ data[127:120] <= p_in[31:24];
if (byte_sel[2])
- data[119:112] <= #Tp p_in[23:16];
+ data[119:112] <= p_in[23:16];
if (byte_sel[1])
- data[111:104] <= #Tp p_in[15:8];
+ data[111:104] <= p_in[15:8];
if (byte_sel[0])
- data[103:96] <= #Tp p_in[7:0];
+ data[103:96] <= p_in[7:0];
end
`else
`ifdef SPI_MAX_CHAR_64
else if (latch[0] && !tip)
begin
if (byte_sel[3])
- data[31:24] <= #Tp p_in[31:24];
+ data[31:24] <= p_in[31:24];
if (byte_sel[2])
- data[23:16] <= #Tp p_in[23:16];
+ data[23:16] <= p_in[23:16];
if (byte_sel[1])
- data[15:8] <= #Tp p_in[15:8];
+ data[15:8] <= p_in[15:8];
if (byte_sel[0])
- data[7:0] <= #Tp p_in[7:0];
+ data[7:0] <= p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
- data[63:56] <= #Tp p_in[31:24];
+ data[63:56] <= p_in[31:24];
if (byte_sel[2])
- data[55:48] <= #Tp p_in[23:16];
+ data[55:48] <= p_in[23:16];
if (byte_sel[1])
- data[47:40] <= #Tp p_in[15:8];
+ data[47:40] <= p_in[15:8];
if (byte_sel[0])
- data[39:32] <= #Tp p_in[7:0];
+ data[39:32] <= p_in[7:0];
end
`else
else if (latch[0] && !tip)
begin
`ifdef SPI_MAX_CHAR_8
if (byte_sel[0])
- data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
+ data[`SPI_MAX_CHAR-1:0] <= p_in[`SPI_MAX_CHAR-1:0];
`endif
`ifdef SPI_MAX_CHAR_16
if (byte_sel[0])
- data[7:0] <= #Tp p_in[7:0];
+ data[7:0] <= p_in[7:0];
if (byte_sel[1])
- data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
+ data[`SPI_MAX_CHAR-1:8] <= p_in[`SPI_MAX_CHAR-1:8];
`endif
`ifdef SPI_MAX_CHAR_24
if (byte_sel[0])
- data[7:0] <= #Tp p_in[7:0];
+ data[7:0] <= p_in[7:0];
if (byte_sel[1])
- data[15:8] <= #Tp p_in[15:8];
+ data[15:8] <= p_in[15:8];
if (byte_sel[2])
- data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
+ data[`SPI_MAX_CHAR-1:16] <= p_in[`SPI_MAX_CHAR-1:16];
`endif
`ifdef SPI_MAX_CHAR_32
if (byte_sel[0])
- data[7:0] <= #Tp p_in[7:0];
+ data[7:0] <= p_in[7:0];
if (byte_sel[1])
- data[15:8] <= #Tp p_in[15:8];
+ data[15:8] <= p_in[15:8];
if (byte_sel[2])
- data[23:16] <= #Tp p_in[23:16];
+ data[23:16] <= p_in[23:16];
if (byte_sel[3])
- data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
+ data[`SPI_MAX_CHAR-1:24] <= p_in[`SPI_MAX_CHAR-1:24];
`endif
end
`endif
`endif
else
- data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
+ data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
end
endmodule
diff --git a/usrp2/opencores/spi/rtl/verilog/spi_top.v b/usrp2/opencores/spi/rtl/verilog/spi_top.v
index 09b2e50e1..8289449a9 100644
--- a/usrp2/opencores/spi/rtl/verilog/spi_top.v
+++ b/usrp2/opencores/spi/rtl/verilog/spi_top.v
@@ -1,3 +1,6 @@
+
+// Modified 2010 by Matt Ettus to remove old verilog style
+
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_top.v ////
@@ -40,7 +43,6 @@
`include "spi_defines.v"
-`include "timescale.v"
module spi_top
(
@@ -52,8 +54,6 @@ module spi_top
ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i
);
- parameter Tp = 1;
-
// Wishbone signals
input wb_clk_i; // master clock input
input wb_rst_i; // synchronous active high reset
@@ -101,7 +101,7 @@ module spi_top
wire last_bit; // marks last character bit
// Address decoder
- assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
+ assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DIVIDE);
assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL);
assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0);
assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1);
@@ -132,96 +132,96 @@ module spi_top
`endif
`endif
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
- `SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
+ `SPI_DIVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
default: wb_dat = 32'bx;
endcase
end
// Wb data out
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- wb_dat_o <= #Tp 32'b0;
+ wb_dat_o <= 32'b0;
else
- wb_dat_o <= #Tp wb_dat;
+ wb_dat_o <= wb_dat;
end
// Wb acknowledge
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- wb_ack_o <= #Tp 1'b0;
+ wb_ack_o <= 1'b0;
else
- wb_ack_o <= #Tp wb_cyc_i & wb_stb_i & ~wb_ack_o;
+ wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
end
// Wb error
assign wb_err_o = 1'b0;
// Interrupt
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- wb_int_o <= #Tp 1'b0;
+ wb_int_o <= 1'b0;
else if (ie && tip && last_bit && pos_edge)
- wb_int_o <= #Tp 1'b1;
+ wb_int_o <= 1'b1;
else if (wb_ack_o)
- wb_int_o <= #Tp 1'b0;
+ wb_int_o <= 1'b0;
end
// Divider register
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- divider <= #Tp {`SPI_DIVIDER_LEN{1'b0}};
+ divider <= {`SPI_DIVIDER_LEN{1'b0}};
else if (spi_divider_sel && wb_we_i && !tip)
begin
`ifdef SPI_DIVIDER_LEN_8
if (wb_sel_i[0])
- divider <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:0];
+ divider <= wb_dat_i[`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_16
if (wb_sel_i[0])
- divider[7:0] <= #Tp wb_dat_i[7:0];
+ divider[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- divider[`SPI_DIVIDER_LEN-1:8] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:8];
+ divider[`SPI_DIVIDER_LEN-1:8] <= wb_dat_i[`SPI_DIVIDER_LEN-1:8];
`endif
`ifdef SPI_DIVIDER_LEN_24
if (wb_sel_i[0])
- divider[7:0] <= #Tp wb_dat_i[7:0];
+ divider[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- divider[15:8] <= #Tp wb_dat_i[15:8];
+ divider[15:8] <= wb_dat_i[15:8];
if (wb_sel_i[2])
- divider[`SPI_DIVIDER_LEN-1:16] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:16];
+ divider[`SPI_DIVIDER_LEN-1:16] <= wb_dat_i[`SPI_DIVIDER_LEN-1:16];
`endif
`ifdef SPI_DIVIDER_LEN_32
if (wb_sel_i[0])
- divider[7:0] <= #Tp wb_dat_i[7:0];
+ divider[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- divider[15:8] <= #Tp wb_dat_i[15:8];
+ divider[15:8] <= wb_dat_i[15:8];
if (wb_sel_i[2])
- divider[23:16] <= #Tp wb_dat_i[23:16];
+ divider[23:16] <= wb_dat_i[23:16];
if (wb_sel_i[3])
- divider[`SPI_DIVIDER_LEN-1:24] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:24];
+ divider[`SPI_DIVIDER_LEN-1:24] <= wb_dat_i[`SPI_DIVIDER_LEN-1:24];
`endif
end
end
// Ctrl register
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- ctrl <= #Tp {`SPI_CTRL_BIT_NB{1'b0}};
+ ctrl <= {`SPI_CTRL_BIT_NB{1'b0}};
else if(spi_ctrl_sel && wb_we_i && !tip)
begin
if (wb_sel_i[0])
- ctrl[7:0] <= #Tp wb_dat_i[7:0] | {7'b0, ctrl[0]};
+ ctrl[7:0] <= wb_dat_i[7:0] | {7'b0, ctrl[0]};
if (wb_sel_i[1])
- ctrl[`SPI_CTRL_BIT_NB-1:8] <= #Tp wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
+ ctrl[`SPI_CTRL_BIT_NB-1:8] <= wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
end
else if(tip && last_bit && pos_edge)
- ctrl[`SPI_CTRL_GO] <= #Tp 1'b0;
+ ctrl[`SPI_CTRL_GO] <= 1'b0;
end
assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
@@ -233,39 +233,39 @@ module spi_top
assign ass = ctrl[`SPI_CTRL_ASS];
// Slave select register
- always @(posedge wb_clk_i or posedge wb_rst_i)
+ always @(posedge wb_clk_i)
begin
if (wb_rst_i)
- ss <= #Tp {`SPI_SS_NB{1'b0}};
+ ss <= {`SPI_SS_NB{1'b0}};
else if(spi_ss_sel && wb_we_i && !tip)
begin
`ifdef SPI_SS_NB_8
if (wb_sel_i[0])
- ss <= #Tp wb_dat_i[`SPI_SS_NB-1:0];
+ ss <= wb_dat_i[`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_16
if (wb_sel_i[0])
- ss[7:0] <= #Tp wb_dat_i[7:0];
+ ss[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- ss[`SPI_SS_NB-1:8] <= #Tp wb_dat_i[`SPI_SS_NB-1:8];
+ ss[`SPI_SS_NB-1:8] <= wb_dat_i[`SPI_SS_NB-1:8];
`endif
`ifdef SPI_SS_NB_24
if (wb_sel_i[0])
- ss[7:0] <= #Tp wb_dat_i[7:0];
+ ss[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- ss[15:8] <= #Tp wb_dat_i[15:8];
+ ss[15:8] <= wb_dat_i[15:8];
if (wb_sel_i[2])
- ss[`SPI_SS_NB-1:16] <= #Tp wb_dat_i[`SPI_SS_NB-1:16];
+ ss[`SPI_SS_NB-1:16] <= wb_dat_i[`SPI_SS_NB-1:16];
`endif
`ifdef SPI_SS_NB_32
if (wb_sel_i[0])
- ss[7:0] <= #Tp wb_dat_i[7:0];
+ ss[7:0] <= wb_dat_i[7:0];
if (wb_sel_i[1])
- ss[15:8] <= #Tp wb_dat_i[15:8];
+ ss[15:8] <= wb_dat_i[15:8];
if (wb_sel_i[2])
- ss[23:16] <= #Tp wb_dat_i[23:16];
+ ss[23:16] <= wb_dat_i[23:16];
if (wb_sel_i[3])
- ss[`SPI_SS_NB-1:24] <= #Tp wb_dat_i[`SPI_SS_NB-1:24];
+ ss[`SPI_SS_NB-1:24] <= wb_dat_i[`SPI_SS_NB-1:24];
`endif
end
end
diff --git a/usrp2/opencores/spi/rtl/verilog/spi_top16.v b/usrp2/opencores/spi/rtl/verilog/spi_top16.v
new file mode 100644
index 000000000..ee808a8ab
--- /dev/null
+++ b/usrp2/opencores/spi/rtl/verilog/spi_top16.v
@@ -0,0 +1,182 @@
+
+// Modified 2010 by Matt Ettus to remove old verilog style and
+// allow 16-bit operation
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// spi_top.v ////
+//// ////
+//// This file is part of the SPI IP core project ////
+//// http://www.opencores.org/projects/spi/ ////
+//// ////
+//// Author(s): ////
+//// - Simon Srot (simons@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2002 Authors ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "spi_defines.v"
+
+module spi_top16
+ (input wb_clk_i, input wb_rst_i,
+ input [4:0] wb_adr_i,
+ input [15:0] wb_dat_i,
+ output reg [15:0] wb_dat_o,
+ input [1:0] wb_sel_i,
+ input wb_we_i, input wb_stb_i, input wb_cyc_i,
+ output reg wb_ack_o, output wb_err_o, output reg wb_int_o,
+
+ // SPI signals
+ output [15:0] ss_pad_o, output sclk_pad_o, output mosi_pad_o, input miso_pad_i);
+
+ // Internal signals
+ reg [15:0] divider; // Divider register
+ reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
+ reg [15:0] ss; // Slave select register
+ reg [31:0] wb_dat; // wb data out
+ wire [31:0] rx; // Rx register
+ wire rx_negedge; // miso is sampled on negative edge
+ wire tx_negedge; // mosi is driven on negative edge
+ wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
+ wire go; // go
+ wire lsb; // lsb first on line
+ wire ie; // interrupt enable
+ wire ass; // automatic slave select
+ wire spi_divider_sel; // divider register select
+ wire spi_ctrl_sel; // ctrl register select
+ wire [3:0] spi_tx_sel; // tx_l register select
+ wire spi_ss_sel; // ss register select
+ wire tip; // transfer in progress
+ wire pos_edge; // recognize posedge of sclk
+ wire neg_edge; // recognize negedge of sclk
+ wire last_bit; // marks last character bit
+
+ // Address decoder
+ assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_DIVIDE);
+ assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_CTRL);
+ assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_0);
+ assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_1);
+ assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_2);
+ assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_TX_3);
+ assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[4:2] == `SPI_SS);
+
+ always @(wb_adr_i or rx or ctrl or divider or ss)
+ case (wb_adr_i[4:2])
+ `SPI_RX_0: wb_dat = rx[31:0];
+ `SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
+ `SPI_DIVIDE: wb_dat = {16'b0, divider};
+ `SPI_SS: wb_dat = {16'b0, ss};
+ default : wb_dat = 32'd0;
+ endcase // case (wb_adr_i[4:2])
+
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ wb_dat_o <= 32'b0;
+ else
+ wb_dat_o <= wb_adr_i[1] ? wb_dat[31:16] : wb_dat[15:0];
+
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ wb_ack_o <= 1'b0;
+ else
+ wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
+
+ assign wb_err_o = 1'b0;
+
+ // Interrupt
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ wb_int_o <= 1'b0;
+ else if (ie && tip && last_bit && pos_edge)
+ wb_int_o <= 1'b1;
+ else if (wb_ack_o)
+ wb_int_o <= 1'b0;
+
+ // Divider register
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ divider <= 16'b0;
+ else if (spi_divider_sel && wb_we_i && !tip && ~wb_adr_i[1])
+ divider <= wb_dat_i;
+
+ // Ctrl register
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ ctrl <= {`SPI_CTRL_BIT_NB{1'b0}};
+ else if(spi_ctrl_sel && wb_we_i && !tip && ~wb_adr_i[1])
+ begin
+ if (wb_sel_i[0])
+ ctrl[7:0] <= wb_dat_i[7:0] | {7'b0, ctrl[0]};
+ if (wb_sel_i[1])
+ ctrl[`SPI_CTRL_BIT_NB-1:8] <= wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
+ end
+ else if(tip && last_bit && pos_edge)
+ ctrl[`SPI_CTRL_GO] <= 1'b0;
+
+ assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
+ assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
+ assign go = ctrl[`SPI_CTRL_GO];
+ assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
+ assign lsb = ctrl[`SPI_CTRL_LSB];
+ assign ie = ctrl[`SPI_CTRL_IE];
+ assign ass = ctrl[`SPI_CTRL_ASS];
+
+ // Slave select register
+ always @(posedge wb_clk_i)
+ if (wb_rst_i)
+ ss <= 16'b0;
+ else if(spi_ss_sel && wb_we_i && !tip & ~wb_adr_i[1])
+ begin
+ if (wb_sel_i[0])
+ ss[7:0] <= wb_dat_i[7:0];
+ if (wb_sel_i[1])
+ ss[15:8] <= wb_dat_i[15:8];
+ end
+
+ assign ss_pad_o = ~((ss & {16{tip & ass}}) | (ss & {16{!ass}}));
+
+ spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit),
+ .divider(divider[`SPI_DIVIDER_LEN-1:0]), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
+ .neg_edge(neg_edge));
+
+ wire [3:0] new_sels = { (wb_adr_i[1] & wb_sel_i[1]), (wb_adr_i[1] & wb_sel_i[0]),
+ (~wb_adr_i[1] & wb_sel_i[1]), (~wb_adr_i[1] & wb_sel_i[0]) };
+
+
+ spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
+ .latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(new_sels), .lsb(lsb),
+ .go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
+ .rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
+ .tip(tip), .last(last_bit),
+ .p_in({wb_dat_i,wb_dat_i}), .p_out(rx),
+ .s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o));
+
+endmodule // spi_top16
diff --git a/usrp2/opencores/spi/rtl/verilog/timescale.v b/usrp2/opencores/spi/rtl/verilog/timescale.v
deleted file mode 100644
index 60d4ecbd1..000000000
--- a/usrp2/opencores/spi/rtl/verilog/timescale.v
+++ /dev/null
@@ -1,2 +0,0 @@
-`timescale 1ns / 10ps
-
diff --git a/usrp2/sdr_lib/dsp_core_rx.v b/usrp2/sdr_lib/dsp_core_rx.v
index aba18fccb..1e689fc7f 100644
--- a/usrp2/sdr_lib/dsp_core_rx.v
+++ b/usrp2/sdr_lib/dsp_core_rx.v
@@ -1,6 +1,6 @@
-`define DSP_CORE_RX_BASE 160
module dsp_core_rx
+ #(parameter BASE = 160)
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
@@ -37,33 +37,33 @@ module dsp_core_rx
wire [31:4] UNUSED_2;
wire [31:2] UNUSED_3;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+0)) sr_0
+ setting_reg #(.my_addr(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
+ setting_reg #(.my_addr(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
+ setting_reg #(.my_addr(BASE+2)) sr_2
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({UNUSED_1, enable_hb1, enable_hb2, cic_decim_rate}),.changed());
- rx_dcoffset #(.WIDTH(14),.ADDR(`DSP_CORE_RX_BASE+6)) rx_dcoffset_a
+ rx_dcoffset #(.WIDTH(14),.ADDR(BASE+3)) 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
+ rx_dcoffset #(.WIDTH(14),.ADDR(BASE+4)) 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
+ setting_reg #(.my_addr(BASE+5)) sr_8
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({UNUSED_2,muxctrl}),.changed());
wire [1:0] gpio_ena;
- setting_reg #(.my_addr(`DSP_CORE_RX_BASE+9)) sr_9
+ setting_reg #(.my_addr(BASE+6)) sr_9
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({UNUSED_3,gpio_ena}),.changed());
diff --git a/usrp2/sdr_lib/dsp_core_tx.v b/usrp2/sdr_lib/dsp_core_tx.v
index 346d65ced..22d3d44a3 100644
--- a/usrp2/sdr_lib/dsp_core_tx.v
+++ b/usrp2/sdr_lib/dsp_core_tx.v
@@ -1,7 +1,6 @@
-`define DSP_CORE_TX_BASE 128
-
module dsp_core_tx
+ #(parameter BASE=0)
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
@@ -22,19 +21,19 @@ module dsp_core_tx
wire [3:0] dacmux_a, dacmux_b;
wire enable_hb1, enable_hb2;
- setting_reg #(.my_addr(`DSP_CORE_TX_BASE+0)) sr_0
+ setting_reg #(.my_addr(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_TX_BASE+1)) sr_1
+ setting_reg #(.my_addr(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_TX_BASE+2)) sr_2
+ setting_reg #(.my_addr(BASE+2)) sr_2
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({enable_hb1, enable_hb2, interp_rate}),.changed());
- setting_reg #(.my_addr(`DSP_CORE_TX_BASE+4)) sr_4
+ setting_reg #(.my_addr(BASE+4)) sr_4
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out({dacmux_b,dacmux_a}),.changed());
diff --git a/usrp2/simple_gemac/eth_tasks_f19.v b/usrp2/simple_gemac/eth_tasks_f19.v
new file mode 100644
index 000000000..ff3ae5407
--- /dev/null
+++ b/usrp2/simple_gemac/eth_tasks_f19.v
@@ -0,0 +1,92 @@
+
+
+task SendFlowCtrl;
+ input [15:0] fc_len;
+ begin
+ $display("Sending Flow Control, quanta = %d, time = %d", fc_len,$time);
+ pause_time <= fc_len;
+ @(posedge eth_clk);
+ pause_req <= 1;
+ @(posedge eth_clk);
+ pause_req <= 0;
+ $display("Sent Flow Control");
+ end
+endtask // SendFlowCtrl
+
+task SendPacket_to_fifo19;
+ input [31:0] data_start;
+ input [15:0] data_len;
+ reg [15:0] count;
+ begin
+ $display("Sending Packet Len=%d, %d", data_len, $time);
+ count <= 2;
+ tx_f19_data <= {2'b0, 1'b0, 1'b1, data_start};
+ tx_f19_src_rdy <= 1;
+ #1;
+ while(count < data_len)
+ begin
+ while(~tx_f19_dst_rdy)
+ @(posedge sys_clk);
+ @(posedge sys_clk);
+ //tx_f19_data[31:0] = tx_f19_data[31:0] + 32'h0101_0101;
+ count = count + 4;
+ //tx_f19_data[32] <= 0;
+ end
+ //tx_f19_data[33] <= 1;
+ while(~tx_f19_dst_rdy)
+ @(posedge sys_clk);
+ @(posedge sys_clk);
+ tx_f19_src_rdy <= 0;
+ end
+endtask // SendPacket_to_fifo19
+
+/*
+task Waiter;
+ input [31:0] wait_length;
+ begin
+ tx_ll_src_rdy2 <= 0;
+ repeat(wait_length)
+ @(posedge clk);
+ tx_ll_src_rdy2 <= 1;
+ end
+endtask // Waiter
+*/
+
+/*
+task SendPacketFromFile_f19;
+ input [31:0] data_len;
+ input [31:0] wait_length;
+ input [31:0] wait_time;
+
+ integer count;
+ begin
+ $display("Sending Packet From File to LL8 Len=%d, %d",data_len,$time);
+ $readmemh("test_packet.mem",pkt_rom );
+
+ while(~tx_f19_dst_rdy)
+ @(posedge clk);
+ tx_f19_data <= pkt_rom[0];
+ tx_f19_src_rdy <= 1;
+ tx_f19_eof <= 0;
+ @(posedge clk);
+
+ for(i=1;i<data_len-1;i=i+1)
+ begin
+ while(~tx_ll_dst_rdy2)
+ @(posedge clk);
+ tx_ll_data2 <= pkt_rom[i];
+ tx_ll_sof2 <= 0;
+ @(posedge clk);
+// if(i==wait_time)
+// Waiter(wait_length);
+ end
+
+ while(~tx_ll_dst_rdy2)
+ @(posedge clk);
+ tx_ll_eof2 <= 1;
+ tx_ll_data2 <= pkt_rom[data_len-1];
+ @(posedge clk);
+ tx_ll_src_rdy2 <= 0;
+ end
+endtask
+*/
diff --git a/usrp2/simple_gemac/ll8_shortfifo.v b/usrp2/simple_gemac/ll8_shortfifo.v
deleted file mode 100644
index e69de29bb..000000000
--- a/usrp2/simple_gemac/ll8_shortfifo.v
+++ /dev/null
diff --git a/usrp2/simple_gemac/simple_gemac.v b/usrp2/simple_gemac/simple_gemac.v
index e7f327358..2dd8deb99 100644
--- a/usrp2/simple_gemac/simple_gemac.v
+++ b/usrp2/simple_gemac/simple_gemac.v
@@ -16,7 +16,9 @@ module simple_gemac
output rx_clk, output [7:0] rx_data, output rx_valid, output rx_error, output rx_ack,
// TX Client Interface
- output tx_clk, input [7:0] tx_data, input tx_valid, input tx_error, output tx_ack
+ output tx_clk, input [7:0] tx_data, input tx_valid, input tx_error, output tx_ack,
+
+ output [31:0] debug
);
localparam SGE_IFG = 8'd12; // 12 should be the absolute minimum
@@ -46,7 +48,8 @@ module simple_gemac
.ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
.pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
.pass_pause(pass_pause), .pass_all(pass_all),
- .pause_quanta_rcvd(pause_quanta_rcvd), .pause_rcvd(pause_rcvd)
+ .pause_quanta_rcvd(pause_quanta_rcvd), .pause_rcvd(pause_rcvd),
+ .debug(debug)
);
flow_ctrl_tx flow_ctrl_tx
diff --git a/usrp2/simple_gemac/simple_gemac_rx.v b/usrp2/simple_gemac/simple_gemac_rx.v
index 45ddd6dfa..b02bb0758 100644
--- a/usrp2/simple_gemac/simple_gemac_rx.v
+++ b/usrp2/simple_gemac/simple_gemac_rx.v
@@ -6,7 +6,8 @@ module simple_gemac_rx
output rx_clk, output [7:0] rx_data, output reg rx_valid, output rx_error, output reg rx_ack,
input [47:0] ucast_addr, input [47:0] mcast_addr,
input pass_ucast, input pass_mcast, input pass_bcast, input pass_pause, input pass_all,
- output reg [15:0] pause_quanta_rcvd, output pause_rcvd );
+ output reg [15:0] pause_quanta_rcvd, output pause_rcvd,
+ output [31:0] debug );
localparam RX_IDLE = 0;
localparam RX_PREAMBLE = 1;
@@ -170,5 +171,7 @@ module simple_gemac_rx
pause_quanta_rcvd[7:0] <= rxd_d1;
assign rx_clk = GMII_RX_CLK;
+
+ assign debug = rx_state;
endmodule // simple_gemac_rx
diff --git a/usrp2/simple_gemac/simple_gemac_wrapper19.build b/usrp2/simple_gemac/simple_gemac_wrapper19.build
new file mode 100755
index 000000000..4be0aac1f
--- /dev/null
+++ b/usrp2/simple_gemac/simple_gemac_wrapper19.build
@@ -0,0 +1 @@
+iverilog -Wimplict -Wportbind -y ../control_lib/newfifo/ -y ../models/ -y . -y miim -y ../coregen/ -y ../control_lib/ -o simple_gemac_wrapper19_tb simple_gemac_wrapper19_tb.v
diff --git a/usrp2/simple_gemac/simple_gemac_wrapper19.v b/usrp2/simple_gemac/simple_gemac_wrapper19.v
new file mode 100644
index 000000000..6cdbd1a59
--- /dev/null
+++ b/usrp2/simple_gemac/simple_gemac_wrapper19.v
@@ -0,0 +1,170 @@
+
+module simple_gemac_wrapper19
+ #(parameter RXFIFOSIZE=9,
+ parameter TXFIFOSIZE=6)
+ (input clk125, input reset,
+ // GMII
+ output GMII_GTX_CLK, output GMII_TX_EN, output GMII_TX_ER, output [7:0] GMII_TXD,
+ input GMII_RX_CLK, input GMII_RX_DV, input GMII_RX_ER, input [7:0] GMII_RXD,
+
+ // Client FIFO Interfaces
+ input sys_clk,
+ output [18:0] rx_f19_data, output rx_f19_src_rdy, input rx_f19_dst_rdy,
+ input [18:0] tx_f19_data, input tx_f19_src_rdy, output tx_f19_dst_rdy,
+
+ // Wishbone Interface
+ input wb_clk, input wb_rst, input wb_stb, input wb_cyc, output wb_ack, input wb_we,
+ input [7:0] wb_adr, input [31:0] wb_dat_i, output [31:0] wb_dat_o,
+
+ // MIIM
+ inout mdio, output mdc,
+ output [31:0] debug);
+
+ wire clear = 0;
+ wire [7:0] rx_data, tx_data;
+ wire tx_clk, tx_valid, tx_error, tx_ack;
+ wire rx_clk, rx_valid, rx_error, rx_ack;
+
+ wire [47:0] ucast_addr, mcast_addr;
+ wire pass_ucast, pass_mcast, pass_bcast, pass_pause, pass_all;
+ wire pause_req;
+ wire pause_request_en, pause_respect_en;
+ wire [15:0] pause_time, pause_thresh, pause_time_req, rx_fifo_space;
+
+ wire [31:0] debug_state;
+
+ wire tx_reset, rx_reset;
+ reset_sync reset_sync_tx (.clk(tx_clk),.reset_in(reset),.reset_out(tx_reset));
+ reset_sync reset_sync_rx (.clk(rx_clk),.reset_in(reset),.reset_out(rx_reset));
+
+ simple_gemac simple_gemac
+ (.clk125(clk125), .reset(reset),
+ .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
+ .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
+ .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
+ .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
+ .pause_req(pause_req), .pause_time_req(pause_time_req),
+ .pause_respect_en(pause_respect_en),
+ .ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
+ .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
+ .pass_pause(pass_pause), .pass_all(pass_all),
+ .rx_clk(rx_clk), .rx_data(rx_data),
+ .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
+ .tx_clk(tx_clk), .tx_data(tx_data),
+ .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack),
+ .debug(debug_state)
+ );
+
+ simple_gemac_wb simple_gemac_wb
+ (.wb_clk(wb_clk), .wb_rst(wb_rst),
+ .wb_cyc(wb_cyc), .wb_stb(wb_stb), .wb_ack(wb_ack), .wb_we(wb_we),
+ .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
+ .mdio(mdio), .mdc(mdc),
+ .ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
+ .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
+ .pass_pause(pass_pause), .pass_all(pass_all),
+ .pause_respect_en(pause_respect_en), .pause_request_en(pause_request_en),
+ .pause_time(pause_time), .pause_thresh(pause_thresh) );
+
+ // RX FIFO Chain
+ wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy;
+
+ wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2;
+ wire rx_ll_sof2_n, rx_ll_eof2_n, rx_ll_src_rdy2_n, rx_ll_dst_rdy2_n;
+
+ wire [7:0] rx_ll_data, rx_ll_data2;
+
+ wire [18:0] rx_f19_data_int1;
+ wire rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1;
+
+ rxmac_to_ll8 rx_adapt
+ (.clk(rx_clk), .reset(rx_reset), .clear(0),
+ .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
+ .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(), // error also encoded in sof/eof
+ .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy));
+
+ ll8_shortfifo rx_sfifo
+ (.clk(rx_clk), .reset(rx_reset), .clear(0),
+ .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof),
+ .error_i(0), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy),
+ .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2),
+ .error_o(), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2));
+
+ assign rx_ll_dst_rdy2 = ~rx_ll_dst_rdy2_n;
+ assign rx_ll_src_rdy2_n = ~rx_ll_src_rdy2;
+ assign rx_ll_sof2_n = ~rx_ll_sof2;
+ assign rx_ll_eof2_n = ~rx_ll_eof2;
+
+ ll8_to_fifo19 ll8_to_fifo19
+ (.clk(rx_clk), .reset(rx_reset), .clear(0),
+ .ll_data(rx_ll_data2), .ll_sof_n(rx_ll_sof2_n), .ll_eof_n(rx_ll_eof2_n),
+ .ll_src_rdy_n(rx_ll_src_rdy2_n), .ll_dst_rdy_n(rx_ll_dst_rdy2_n),
+ .f19_data(rx_f19_data_int1), .f19_src_rdy_o(rx_f19_src_rdy_int1), .f19_dst_rdy_i(rx_f19_dst_rdy_int1));
+
+ //fifo_2clock_cascade #(.WIDTH(19), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
+ fifo_2clock_cascade #(.WIDTH(36), .SIZE(RXFIFOSIZE)) rx_2clk_fifo
+ (.wclk(rx_clk), .datain(rx_f19_data_int1),
+ .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1), .space(rx_fifo_space),
+ .rclk(sys_clk), .dataout(rx_f19_data),
+ .src_rdy_o(rx_f19_src_rdy), .dst_rdy_i(rx_f19_dst_rdy), .occupied(), .arst(reset));
+
+ // TX FIFO Chain
+ wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
+ wire tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2;
+ wire tx_ll_sof2_n, tx_ll_eof2_n, tx_ll_src_rdy2_n, tx_ll_dst_rdy2_n;
+ wire [7:0] tx_ll_data, tx_ll_data2;
+ wire [18:0] tx_f19_data_int1;
+ wire tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1;
+
+ fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) tx_2clk_fifo
+ (.wclk(sys_clk), .datain(tx_f19_data),
+ .src_rdy_i(tx_f19_src_rdy), .dst_rdy_o(tx_f19_dst_rdy), .space(),
+ .rclk(tx_clk), .dataout(tx_f19_data_int1),
+ .src_rdy_o(tx_f19_src_rdy_int1), .dst_rdy_i(tx_f19_dst_rdy_int1), .occupied(), .arst(rx_reset));
+
+ fifo19_to_ll8 fifo19_to_ll8
+ (.clk(tx_clk), .reset(tx_reset), .clear(clear),
+ .f19_data(tx_f19_data_int1), .f19_src_rdy_i(tx_f19_src_rdy_int1), .f19_dst_rdy_o(tx_f19_dst_rdy_int1),
+ .ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n),
+ .ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(tx_ll_dst_rdy2_n));
+
+ assign tx_ll_sof2 = ~tx_ll_sof2_n;
+ assign tx_ll_eof2 = ~tx_ll_eof2_n;
+ assign tx_ll_src_rdy2 = ~tx_ll_src_rdy2_n;
+ assign tx_ll_dst_rdy2_n = ~tx_ll_dst_rdy2;
+
+ ll8_shortfifo tx_sfifo
+ (.clk(tx_clk), .reset(tx_reset), .clear(clear),
+ .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2),
+ .error_i(0), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2),
+ .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof),
+ .error_o(), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy));
+
+ ll8_to_txmac ll8_to_txmac
+ (.clk(tx_clk), .reset(tx_reset), .clear(clear),
+ .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof),
+ .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy),
+ .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack));
+
+ // Flow Control
+ flow_ctrl_rx flow_ctrl_rx
+ (.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh),
+ .rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space),
+ .tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req));
+
+ wire [31:0] debug_tx, debug_rx;
+
+ assign debug_tx = { { tx_ll_data },
+ { tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy,
+ tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2 },
+ { tx_valid, tx_error, tx_ack, tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1, tx_f19_data_int1[18:16]},
+ { tx_data} };
+ assign debug_rx = { { rx_f19_src_rdy, rx_f19_dst_rdy, debug_state[5:0] },
+ { rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy,
+ rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2 },
+ { rx_valid, rx_error, rx_ack, rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_data_int1[18:16]},
+ { rx_data} };
+
+ assign debug = debug_rx;
+
+endmodule // simple_gemac_wrapper19
diff --git a/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v b/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v
new file mode 100644
index 000000000..7d57542dc
--- /dev/null
+++ b/usrp2/simple_gemac/simple_gemac_wrapper19_tb.v
@@ -0,0 +1,209 @@
+
+
+module simple_gemac_wrapper19_tb;
+`include "eth_tasks_f19.v"
+
+ reg reset = 1;
+ initial #1000 reset = 0;
+ wire wb_rst = reset;
+
+ reg eth_clk = 0;
+ always #50 eth_clk = ~eth_clk;
+
+ reg wb_clk = 0;
+ always #173 wb_clk = ~wb_clk;
+
+ reg sys_clk = 0;
+ always #77 sys_clk = ~ sys_clk;
+
+ wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK;
+ wire [7:0] GMII_RXD, GMII_TXD;
+
+ wire rx_valid, rx_error, rx_ack;
+ wire tx_ack, tx_valid, tx_error;
+
+ wire [7:0] rx_data, tx_data;
+
+ reg [15:0] pause_time;
+ reg pause_req = 0;
+
+ wire GMII_RX_CLK = GMII_GTX_CLK;
+
+ reg [7:0] FORCE_DAT_ERR = 0;
+ reg FORCE_ERR = 0;
+
+ // Loopback
+ assign GMII_RX_DV = GMII_TX_EN;
+ assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR;
+ assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR;
+
+
+ wire [31:0] wb_dat_o;
+ reg [31:0] wb_dat_i;
+ reg [7:0] wb_adr;
+ reg wb_stb=0, wb_cyc=0, wb_we=0;
+ wire wb_ack;
+
+ reg [18:0] tx_f19_data=0;
+ reg tx_f19_src_rdy = 0;
+ wire tx_f19_dst_rdy;
+ wire [35:0] rx_f36_data;
+ wire rx_f36_src_rdy;
+ wire rx_f36_dst_rdy = 1;
+
+ simple_gemac_wrapper19 simple_gemac_wrapper19
+ (.clk125(eth_clk), .reset(reset),
+ .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
+ .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
+ .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
+ .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
+ //.pause_req(pause_req), .pause_time(pause_time),
+
+ .sys_clk(sys_clk), .rx_f36_data(rx_f36_data), .rx_f36_src_rdy(rx_f36_src_rdy), .rx_f36_dst_rdy(rx_f36_dst_rdy),
+ .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),
+
+ .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(wb_stb), .wb_cyc(wb_cyc), .wb_ack(wb_ack), .wb_we(wb_we),
+ .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
+
+ .mdio(), .mdc(),
+ .debug() );
+
+ initial $dumpfile("simple_gemac_wrapper19_tb.vcd");
+ initial $dumpvars(0,simple_gemac_wrapper19_tb);
+
+ integer i;
+ reg [7:0] pkt_rom[0:65535];
+ reg [1023:0] ROMFile;
+
+ initial
+ for (i=0;i<65536;i=i+1)
+ pkt_rom[i] <= 8'h0;
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (10)
+ @(posedge wb_clk);
+ WishboneWR(0,6'b111101);
+ WishboneWR(4,16'hA0B0);
+ WishboneWR(8,32'hC0D0_A1B1);
+ WishboneWR(12,16'h0000);
+ WishboneWR(16,32'h0000_0000);
+
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0007); // Send flow control
+ @(posedge eth_clk);
+ #30000;
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0009); // Increase flow control before it expires
+ #10000;
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0000); // Cancel flow control before it expires
+ @(posedge eth_clk);
+
+ repeat (1000)
+ @(posedge sys_clk);
+ SendPacket_to_fifo19(32'hA0B0C0D0,10); // This packet gets dropped by the filters
+ repeat (1000)
+ @(posedge sys_clk);
+
+ SendPacket_to_fifo19(32'hAABBCCDD,100); // This packet gets dropped by the filters
+ repeat (10)
+ @(posedge sys_clk);
+/*
+ SendPacketFromFile_f36(60,0,0); // The rest are valid packets
+ repeat (10)
+ @(posedge clk);
+
+ SendPacketFromFile_f36(61,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(62,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(63,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(64,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(59,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(58,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(100,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(200,150,30); // waiting 14 empties the fifo, 15 underruns
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(100,0,30);
+ */
+ #100000 $finish;
+ end
+
+ // Force a CRC error
+ initial
+ begin
+ #90000;
+ @(posedge eth_clk);
+ FORCE_DAT_ERR <= 8'h10;
+ @(posedge eth_clk);
+ FORCE_DAT_ERR <= 8'h00;
+ end
+
+ // Force an RX_ER error (i.e. link loss)
+ initial
+ begin
+ #116000;
+ @(posedge eth_clk);
+ FORCE_ERR <= 1;
+ @(posedge eth_clk);
+ FORCE_ERR <= 0;
+ end
+/*
+ // Cause receive fifo to fill, causing an RX overrun
+ initial
+ begin
+ #126000;
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 0;
+ repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 1;
+ end
+ */
+ // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun
+ // Still need to test: CRC errors on Pause Frames, MDIO, wishbone
+
+ task WishboneWR;
+ input [7:0] adr;
+ input [31:0] value;
+ begin
+ wb_adr <= adr;
+ wb_dat_i <= value;
+ wb_stb <= 1;
+ wb_cyc <= 1;
+ wb_we <= 1;
+ while (~wb_ack)
+ @(posedge wb_clk);
+ @(posedge wb_clk);
+ wb_stb <= 0;
+ wb_cyc <= 0;
+ wb_we <= 0;
+ end
+ endtask // WishboneWR
+ /*
+ always @(posedge clk)
+ if(rx_ll_src_rdy2 & rx_ll_dst_rdy2)
+ begin
+ if(rx_ll_sof2 & ~rx_ll_eof2)
+ $display("RX-PKT-START %d",$time);
+ $display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2);
+ if(rx_ll_eof2 & ~rx_ll_sof2)
+ $display("RX-PKT-END %d",$time);
+ end
+ */
+endmodule // simple_gemac_wrapper19_tb
diff --git a/usrp2/timing/simple_timer.v b/usrp2/timing/simple_timer.v
new file mode 100644
index 000000000..17c7f1c36
--- /dev/null
+++ b/usrp2/timing/simple_timer.v
@@ -0,0 +1,60 @@
+
+
+module simple_timer
+ #(parameter BASE=0)
+ (input clk, input reset,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ output reg onetime_int, output reg periodic_int);
+
+ reg [31:0] onetime_ctr;
+ always @(posedge clk)
+ if(reset)
+ begin
+ onetime_int <= 0;
+ onetime_ctr <= 0;
+ end
+ else
+ if(set_stb & (set_addr == BASE))
+ begin
+ onetime_int <= 0;
+ onetime_ctr <= set_data;
+ end
+ else
+ begin
+ if(onetime_ctr == 1)
+ onetime_int <= 1;
+ if(onetime_ctr != 0)
+ onetime_ctr <= onetime_ctr - 1;
+ else
+ onetime_int <= 0;
+ end // else: !if(set_stb & (set_addr == BASE))
+
+ reg [31:0] periodic_ctr, period;
+ always @(posedge clk)
+ if(reset)
+ begin
+ periodic_int <= 0;
+ periodic_ctr <= 0;
+ period <= 0;
+ end
+ else
+ if(set_stb & (set_addr == (BASE+1)))
+ begin
+ periodic_int <= 0;
+ periodic_ctr <= set_data;
+ period <= set_data;
+ end
+ else
+ if(periodic_ctr == 1)
+ begin
+ periodic_int <= 1;
+ periodic_ctr <= period;
+ end
+ else
+ if(periodic_ctr != 0)
+ begin
+ periodic_int <= 0;
+ periodic_ctr <= periodic_ctr - 1;
+ end
+
+endmodule // simple_timer
diff --git a/usrp2/timing/time_64bit.v b/usrp2/timing/time_64bit.v
index c0a846e74..8ccde3f54 100644
--- a/usrp2/timing/time_64bit.v
+++ b/usrp2/timing/time_64bit.v
@@ -6,19 +6,28 @@ module time_64bit
(input clk, input rst,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input pps,
- output [63:0] vita_time
+ output [63:0] vita_time, output pps_int
);
- localparam NEXT_TICKS = 0;
- localparam NEXT_SECS = 1;
+ localparam NEXT_SECS = 0;
+ localparam NEXT_TICKS = 1;
+ localparam PPS_POLSRC = 2;
+ localparam PPS_IMM = 3;
+
localparam ROLLOVER = TICKS_PER_SEC - 1;
+ reg [31:0] seconds;
+ reg [31:0] ticks;
+ wire end_of_second;
assign vita_time = {seconds,ticks};
wire [31:0] next_ticks_preset;
wire [31:0] next_seconds_preset;
wire set_on_pps_trig;
reg set_on_next_pps;
+ wire pps_polarity;
+ wire set_imm;
+ wire pps_source;
setting_reg #(.my_addr(BASE+NEXT_TICKS)) sr_next_ticks
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
@@ -27,18 +36,37 @@ module time_64bit
setting_reg #(.my_addr(BASE+NEXT_SECS)) sr_next_secs
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(next_seconds_preset),.changed(set_on_pps_trig));
+
+ setting_reg #(.my_addr(BASE+PPS_POLSRC)) sr_pps_polsrc
+ (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out({pps_source,pps_polarity}),.changed());
+
+ setting_reg #(.my_addr(BASE+PPS_IMM)) sr_pps_imm
+ (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(set_imm),.changed());
+
+ reg [1:0] pps_del;
+ reg pps_reg_p, pps_reg_n, pps_reg;
+ wire pps_edge;
- reg [31:0] seconds;
- reg [31:0] ticks;
+ always @(posedge clk) pps_reg_p <= pps;
+ always @(negedge clk) pps_reg_n <= pps;
+ always @* pps_reg <= pps_polarity ? pps_reg_p : pps_reg_n;
- wire end_of_second;
+ always @(posedge clk)
+ if(rst)
+ pps_del <= 2'b00;
+ else
+ pps_del <= {pps_del[0],pps_reg};
+
+ assign pps_edge = pps_del[0] & ~pps_del[1];
always @(posedge clk)
if(rst)
set_on_next_pps <= 0;
else if(set_on_pps_trig)
set_on_next_pps <= 1;
- else if(pps)
+ else if(set_imm | pps_edge)
set_on_next_pps <= 0;
always @(posedge clk)
@@ -47,7 +75,7 @@ module time_64bit
seconds <= 32'd0;
ticks <= 32'd0;
end
- else if(pps & set_on_next_pps)
+ else if((set_imm | pps_edge) & set_on_next_pps)
begin
seconds <= next_seconds_preset;
ticks <= next_ticks_preset;
@@ -59,5 +87,7 @@ module time_64bit
end
else
ticks <= ticks + 1;
+
+ assign pps_int = pps_edge;
endmodule // time_64bit
diff --git a/usrp2/timing/time_compare.v b/usrp2/timing/time_compare.v
new file mode 100644
index 000000000..a21c9f8e0
--- /dev/null
+++ b/usrp2/timing/time_compare.v
@@ -0,0 +1,23 @@
+
+// Top 32 bits are integer seconds, bottom 32 are clock ticks within a second
+
+module time_compare
+ (input [63:0] time_now,
+ input [63:0] trigger_time,
+ output now,
+ output early,
+ output late,
+ output too_early);
+
+ wire sec_match = (time_now[63:32] == trigger_time[63:32]);
+ wire sec_late = (time_now[63:32] > trigger_time[63:32]);
+
+ wire tick_match = (time_now[31:0] == trigger_time[31:0]);
+ wire tick_late = (time_now[31:0] > trigger_time[31:0]);
+
+ assign now = sec_match & tick_match;
+ assign late = sec_late | (sec_match & tick_late);
+ assign early = ~now & ~late;
+ assign too_early = (trigger_time[63:32] > (time_now[63:32] + 4)); // Don't wait too long
+
+endmodule // time_compare
diff --git a/usrp2/top/u1e/.gitignore b/usrp2/top/u1e/.gitignore
new file mode 100644
index 000000000..8d872713e
--- /dev/null
+++ b/usrp2/top/u1e/.gitignore
@@ -0,0 +1,6 @@
+*~
+build
+*.log
+*.cmd
+tb_u1e
+*.lxt
diff --git a/usrp2/top/u1e/Makefile b/usrp2/top/u1e/Makefile
new file mode 100644
index 000000000..2aebb33f9
--- /dev/null
+++ b/usrp2/top/u1e/Makefile
@@ -0,0 +1,257 @@
+#
+# 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 := u1e
+export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
+
+##################################################
+# Project Properties
+##################################################
+export PROJECT_PROPERTIES := \
+family "Spartan-3A DSP" \
+device xc3sd1800a \
+package cs484 \
+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
+##################################################
+export SOURCE_ROOT := ../../../
+export SOURCES := \
+control_lib/CRC16_D16.v \
+control_lib/atr_controller16.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/nsgpio16LE.v \
+control_lib/ram_2port.v \
+control_lib/ram_2port_mixed_width.v \
+control_lib/ram_harv_cache.v \
+control_lib/ram_loader.v \
+control_lib/setting_reg.v \
+control_lib/settings_bus_16LE.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/newfifo/fifo36_to_fifo18.v \
+control_lib/newfifo/fifo19_to_fifo36.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 \
+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_top16.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 \
+timing/time_64bit.v \
+gpmc/gpmc_async.v \
+gpmc/edge_sync.v \
+gpmc/dbsm.v \
+gpmc/gpmc_to_fifo_async.v \
+gpmc/fifo_to_gpmc_async.v \
+gpmc/fifo_watcher.v \
+gpmc/gpmc_wb.v \
+top/u1e/u1e_core.v \
+top/u1e/u1e.ucf \
+top/u1e/timing.ucf \
+top/u1e/u1e.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 \
+"Unused IOB Pins" "Pull Up"
+
+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/usrp2/top/u1e/README b/usrp2/top/u1e/README
new file mode 100644
index 000000000..14c7a4955
--- /dev/null
+++ b/usrp2/top/u1e/README
@@ -0,0 +1,4 @@
+
+make clean
+make sim
+./tb_u1e -lxt2
diff --git a/usrp2/top/u1e/cmdfile b/usrp2/top/u1e/cmdfile
new file mode 100644
index 000000000..291c723b8
--- /dev/null
+++ b/usrp2/top/u1e/cmdfile
@@ -0,0 +1,20 @@
+
+# My stuff
+-y .
+-y ../../control_lib
+-y ../../control_lib/newfifo
+-y ../../sdr_lib
+-y ../../timing
+-y ../../coregen
+-y ../../gpmc
+
+# Models
+-y ../../models
+-y /opt/Xilinx/10.1/ISE/verilog/src/unisims
+
+# Open Cores
+-y ../../opencores/spi/rtl/verilog
++incdir+../../opencores/spi/rtl/verilog
+-y ../../opencores/i2c/rtl/verilog
++incdir+../../opencores/i2c/rtl/verilog
+
diff --git a/usrp2/top/u1e/make.sim b/usrp2/top/u1e/make.sim
new file mode 100644
index 000000000..1c163884c
--- /dev/null
+++ b/usrp2/top/u1e/make.sim
@@ -0,0 +1,7 @@
+all: sim
+
+sim:
+ iverilog -Wimplicit -Wportbind -c cmdfile tb_u1e.v -o tb_u1e
+
+clean:
+ rm -f tb_u1e *.vcd *.lxt a.out
diff --git a/usrp2/top/u1e/tb_u1e.v b/usrp2/top/u1e/tb_u1e.v
new file mode 100644
index 000000000..5fc8134fb
--- /dev/null
+++ b/usrp2/top/u1e/tb_u1e.v
@@ -0,0 +1,41 @@
+`timescale 1ps / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+
+module tb_u1e();
+
+ wire [2:0] debug_led;
+ wire [31:0] debug;
+ wire [1:0] debug_clk;
+
+ xlnx_glbl glbl (.GSR(),.GTS());
+
+ initial begin
+ $dumpfile("tb_u1e.lxt");
+ $dumpvars(0,tb_u1e);
+ end
+
+ // GPMC
+ wire EM_CLK, EM_WAIT0, EM_NCS4, EM_NCS6, EM_NWE, EM_NOE;
+ wire [15:0] EM_D;
+ wire [10:1] EM_A;
+ wire [1:0] EM_NBE;
+
+ reg clk_fpga = 0, rst_fpga = 1;
+ always #15625 clk_fpga = ~clk_fpga;
+
+ initial #200000
+ @(posedge clk_fpga)
+ rst_fpga <= 0;
+
+ u1e_core u1e_core(.clk_fpga(clk_fpga), .rst_fpga(rst_fpga),
+ .debug_led(debug_led), .debug(debug), .debug_clk(debug_clk),
+ .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS6(EM_NCS6),
+ .EM_NWE(EM_NWE), .EM_NOE(EM_NOE) );
+
+ gpmc_model_async gpmc_model_async
+ (.EM_CLK(EM_CLK), .EM_D(EM_D), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS6(EM_NCS6),
+ .EM_NWE(EM_NWE), .EM_NOE(EM_NOE) );
+
+endmodule // tb_u1e
diff --git a/usrp2/top/u1e/timing.ucf b/usrp2/top/u1e/timing.ucf
new file mode 100644
index 000000000..8df28c9d3
--- /dev/null
+++ b/usrp2/top/u1e/timing.ucf
@@ -0,0 +1,13 @@
+
+NET "CLK_FPGA_P" TNM_NET = "CLK_FPGA_P";
+TIMESPEC "TS_clk_fpga_p" = PERIOD "CLK_FPGA_P" 15625 ps HIGH 50 %;
+
+
+
+
+#NET "adc_a<*>" TNM_NET = ADC_DATA_GRP;
+#NET "adc_b<*>" TNM_NET = ADC_DATA_GRP;
+#TIMEGRP "ADC_DATA_GRP" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING;
+
+#NET "adc_a<*>" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING;
+#NET "adc_b<*>" OFFSET = IN 1 ns VALID 5 ns BEFORE "clk_fpga_p" RISING;
diff --git a/usrp2/top/u1e/u1e.ucf b/usrp2/top/u1e/u1e.ucf
new file mode 100644
index 000000000..2caa46639
--- /dev/null
+++ b/usrp2/top/u1e/u1e.ucf
@@ -0,0 +1,266 @@
+
+NET "CLK_FPGA_P" LOC = "Y11" ;
+NET "CLK_FPGA_N" LOC = "Y10" ;
+
+## 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" ;
+
+## Overo GPIO
+NET "overo_gpio0" LOC = "F9" ; # MISC GPIO for debug
+NET "overo_gpio14" LOC = "C4" ; # MISC GPIO for debug
+NET "overo_gpio21" LOC = "D5" ; # MISC GPIO for debug
+NET "overo_gpio22" LOC = "A3" ; # MISC GPIO for debug
+NET "overo_gpio23" LOC = "B3" ; # MISC GPIO for debug
+NET "overo_gpio64" LOC = "A4" ; # MISC GPIO for debug
+NET "overo_gpio65" LOC = "F8" ; # MISC GPIO for debug
+NET "overo_gpio127" LOC = "C8" ; # MISC GPIO for debug, also used on the passthru image as the cgen_sen_b pin
+NET "overo_gpio128" LOC = "G8" ; # MISC GPIO for debug
+NET "overo_gpio144" LOC = "A5" ; # tx_have_space
+NET "overo_gpio145" LOC = "C7" ; # tx_underrun
+NET "overo_gpio146" LOC = "A6" ; # rx_have_data
+NET "overo_gpio147" LOC = "B6" ; # rx_overrun
+NET "overo_gpio163" LOC = "D7" ; # MISC GPIO for debug
+NET "overo_gpio170" LOC = "E8" ; # MISC GPIO for debug
+NET "overo_gpio176" LOC = "B4" ; # MISC GPIO for debug
+
+## Overo UART
+#NET "overo_txd1" LOC = "C6" ;
+#NET "overo_rxd1" LOC = "D6" ;
+
+## FTDI UART to USB converter
+NET "FPGA_TXD" LOC = "U1" ;
+NET "FPGA_RXD" LOC = "T6" ;
+
+#NET "SYSEN" LOC = "C11" ;
+
+## I2C
+NET "db_scl" LOC = "U4" ;
+NET "db_sda" LOC = "U5" ;
+
+## SPI
+### DBoard SPI
+NET "db_sclk_rx" LOC = "W3" ;
+NET "db_miso_rx" LOC = "W2" ;
+NET "db_mosi_rx" LOC = "V4" ;
+NET "db_sen_rx" LOC = "V3" ;
+NET "db_sclk_tx" LOC = "Y1" ;
+NET "db_miso_tx" LOC = "W1" ;
+NET "db_mosi_tx" LOC = "R3" ;
+NET "db_sen_tx" LOC = "T4" ;
+
+### AD9862 SPI and aux SPI Interfaces
+#NET "aux_sdi_codec" LOC = "F19" ;
+#NET "aux_sdo_codec" LOC = "F18" ;
+#NET "aux_sclk_codec" LOC = "D21" ;
+NET "sen_codec" LOC = "D20" ;
+NET "mosi_codec" LOC = "E19" ;
+NET "miso_codec" LOC = "F21" ;
+NET "sclk_codec" LOC = "E20" ;
+
+### Clock Gen SPI
+NET "cgen_miso" LOC = "U2" ;
+NET "cgen_mosi" LOC = "V1" ;
+NET "cgen_sclk" LOC = "R5" ;
+NET "cgen_sen_b" LOC = "T1" ;
+
+## Clock gen control
+NET "cgen_st_status" LOC = "D4" ;
+NET "cgen_st_ld" LOC = "D1" ;
+NET "cgen_st_refmon" LOC = "E1" ;
+NET "cgen_sync_b" LOC = "M1" ;
+NET "cgen_ref_sel" LOC = "J1" ;
+
+## Debug pins
+NET "debug_led<2>" LOC = "T5" ;
+NET "debug_led<1>" LOC = "R2" ;
+NET "debug_led<0>" LOC = "R1" ;
+NET "debug<0>" LOC = "P6" ;
+NET "debug<1>" LOC = "R6" ;
+NET "debug<2>" LOC = "P1" ;
+NET "debug<3>" LOC = "P2" ;
+NET "debug<4>" LOC = "N6" ;
+NET "debug<5>" LOC = "N5" ;
+NET "debug<6>" LOC = "N1" ;
+NET "debug<7>" LOC = "K2" ;
+NET "debug<8>" LOC = "K3" ;
+NET "debug<9>" LOC = "K6" ;
+NET "debug<10>" LOC = "L5" ;
+NET "debug<11>" LOC = "H2" ;
+NET "debug<12>" LOC = "K4" ;
+NET "debug<13>" LOC = "K5" ;
+NET "debug<14>" LOC = "G1" ;
+NET "debug<15>" LOC = "H1" ;
+NET "debug<16>" LOC = "H5" ;
+NET "debug<17>" LOC = "H6" ;
+NET "debug<18>" LOC = "E3" ;
+NET "debug<19>" LOC = "E4" ;
+NET "debug<20>" LOC = "G5" ;
+NET "debug<21>" LOC = "G6" ;
+NET "debug<22>" LOC = "F2" ;
+NET "debug<23>" LOC = "F1" ;
+NET "debug<24>" LOC = "H3" ;
+NET "debug<25>" LOC = "H4" ;
+NET "debug<26>" LOC = "F4" ;
+NET "debug<27>" LOC = "F5" ;
+NET "debug<28>" LOC = "C2" ;
+NET "debug<29>" LOC = "C1" ;
+NET "debug<30>" LOC = "F3" ;
+NET "debug<31>" LOC = "G3" ;
+NET "debug_clk<0>" LOC = "L6" ;
+NET "debug_clk<1>" LOC = "M5" ;
+
+NET "debug_pb<2>" LOC = "Y2" ;
+NET "debug_pb<1>" LOC = "AA1" ;
+NET "debug_pb<0>" LOC = "N3" ;
+
+NET "dip_sw<7>" LOC = "T3" ;
+NET "dip_sw<6>" LOC = "U3" ;
+NET "dip_sw<5>" LOC = "M3" ;
+NET "dip_sw<4>" LOC = "N4" ;
+NET "dip_sw<3>" LOC = "J3" ;
+NET "dip_sw<2>" LOC = "J4" ;
+NET "dip_sw<1>" LOC = "J6" ;
+NET "dip_sw<0>" LOC = "J7" ;
+
+#NET "RXSYNC" LOC = "F22" ;
+#NET "reset_codec" LOC = "D22" ;
+
+#NET "DB<11>" LOC = "E22" ;
+#NET "DB<10>" LOC = "J19" ;
+#NET "DB<9>" LOC = "H20" ;
+#NET "DB<8>" LOC = "G19" ;
+#NET "DB<7>" LOC = "F20" ;
+#NET "DB<6>" LOC = "K16" ;
+#NET "DB<5>" LOC = "J17" ;
+#NET "DB<4>" LOC = "H22" ;
+#NET "DB<3>" LOC = "G22" ;
+#NET "DB<2>" LOC = "H17" ;
+#NET "DB<1>" LOC = "H18" ;
+#NET "DB<0>" LOC = "K20" ;
+#NET "DA<11>" LOC = "J20" ;
+#NET "DA<10>" LOC = "K19" ;
+#NET "DA<9>" LOC = "K18" ;
+#NET "DA<8>" LOC = "L22" ;
+#NET "DA<7>" LOC = "K22" ;
+#NET "DA<6>" LOC = "N22" ;
+#NET "DA<5>" LOC = "M22" ;
+#NET "DA<4>" LOC = "N20" ;
+#NET "DA<3>" LOC = "N19" ;
+#NET "DA<2>" LOC = "R22" ;
+#NET "DA<1>" LOC = "P22" ;
+#NET "DA<0>" LOC = "N17" ;
+
+NET "TX<13>" LOC = "P19" ;
+NET "TX<12>" LOC = "R18" ;
+NET "TX<11>" LOC = "U20" ;
+NET "TX<10>" LOC = "T20" ;
+NET "TX<9>" LOC = "R19" ;
+NET "TX<8>" LOC = "R20" ;
+NET "TX<7>" LOC = "W22" ;
+NET "TX<6>" LOC = "Y22" ;
+NET "TX<5>" LOC = "T18" ;
+NET "TX<4>" LOC = "T17" ;
+NET "TX<3>" LOC = "W19" ;
+NET "TX<2>" LOC = "V20" ;
+NET "TX<1>" LOC = "Y21" ;
+NET "TX<0>" LOC = "AA22" ;
+NET "TXSYNC" LOC = "U18" ;
+NET "TXBLANK" LOC = "U19" ;
+
+NET "PPS_IN" LOC = "M17" ;
+
+NET "io_tx<0>" LOC = "AB20" ;
+NET "io_tx<1>" LOC = "Y17" ;
+NET "io_tx<2>" LOC = "Y16" ;
+NET "io_tx<3>" LOC = "U16" ;
+NET "io_tx<4>" LOC = "V16" ;
+NET "io_tx<5>" LOC = "AB19" ;
+NET "io_tx<6>" LOC = "AA19" ;
+NET "io_tx<7>" LOC = "U14" ;
+NET "io_tx<8>" LOC = "U15" ;
+NET "io_tx<9>" LOC = "AB17" ;
+NET "io_tx<10>" LOC = "AB18" ;
+NET "io_tx<11>" LOC = "Y13" ;
+NET "io_tx<12>" LOC = "W14" ;
+NET "io_tx<13>" LOC = "U13" ;
+NET "io_tx<14>" LOC = "AA15" ;
+NET "io_tx<15>" LOC = "AB14" ;
+
+NET "io_rx<0>" LOC = "Y8" ;
+NET "io_rx<1>" LOC = "Y9" ;
+NET "io_rx<2>" LOC = "V7" ;
+NET "io_rx<3>" LOC = "U8" ;
+NET "io_rx<4>" LOC = "V10" ;
+NET "io_rx<5>" LOC = "U9" ;
+NET "io_rx<6>" LOC = "AB7" ;
+NET "io_rx<7>" LOC = "AA8" ;
+NET "io_rx<8>" LOC = "W8" ;
+NET "io_rx<9>" LOC = "V8" ;
+NET "io_rx<10>" LOC = "AB5" ;
+NET "io_rx<11>" LOC = "AB6" ;
+NET "io_rx<12>" LOC = "AB4" ;
+NET "io_rx<13>" LOC = "AA4" ;
+NET "io_rx<14>" LOC = "W5" ;
+NET "io_rx<15>" LOC = "Y4" ;
+
+#NET "CLKOUT2_CODEC" LOC = "U12" ;
+#NET "CLKOUT1_CODEC" LOC = "V12" ;
+
+## FPGA Config Pins
+#NET "fpga_cfg_prog_b" LOC = "A2" ;
+#NET "fpga_cfg_done" LOC = "AB21" ;
+#NET "fpga_cfg_din" LOC = "W17" ;
+#NET "fpga_cfg_cclk" LOC = "V17" ;
+#NET "fpga_cfg_init_b" LOC = "W15" ;
+
+## Unused
+#NET "unnamed_net37" LOC = "B1" ; # TMS
+#NET "unnamed_net36" LOC = "B22" ; # TDO
+#NET "unnamed_net35" LOC = "D2" ; # TDI
+#NET "unnamed_net34" LOC = "A21" ; # TCK
+#NET "unnamed_net45" LOC = "F7" ; # PUDC_B
+#NET "unnamed_net44" LOC = "V6" ; # M2
+#NET "unnamed_net43" LOC = "AA3" ; # M1
+#NET "unnamed_net42" LOC = "AB3" ; # M0
+#NET "GND" LOC = "V19" ; # Suspend, unused
diff --git a/usrp2/top/u1e/u1e.v b/usrp2/top/u1e/u1e.v
new file mode 100644
index 000000000..35818e8c8
--- /dev/null
+++ b/usrp2/top/u1e/u1e.v
@@ -0,0 +1,68 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+
+module u1e
+ (input CLK_FPGA_P, input CLK_FPGA_N, // Diff
+ output [2:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
+ input [2:0] debug_pb, input [7:0] dip_sw, output FPGA_TXD, input FPGA_RXD,
+
+ // GPMC
+ input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE,
+ input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE,
+
+ inout db_sda, inout db_scl, // I2C
+
+ output db_sclk_tx, output db_sen_tx, output db_mosi_tx, input db_miso_tx, // DB TX SPI
+ output db_sclk_rx, output db_sen_rx, output db_mosi_rx, input db_miso_rx, // DB TX SPI
+ output sclk_codec, output sen_codec, output mosi_codec, input miso_codec, // AD9862 main SPI
+ output cgen_sclk, output cgen_sen_b, output cgen_mosi, input cgen_miso, // Clock gen SPI
+
+ input cgen_st_status, input cgen_st_ld, input cgen_st_refmon, output cgen_sync_b, output cgen_ref_sel,
+
+ output overo_gpio144, output overo_gpio145, output overo_gpio146, output overo_gpio147, // Fifo controls
+ input overo_gpio0, input overo_gpio14, input overo_gpio21, input overo_gpio22, // Misc GPIO
+ input overo_gpio23, input overo_gpio64, input overo_gpio65, input overo_gpio127, // Misc GPIO
+ input overo_gpio128, input overo_gpio163, input overo_gpio170, input overo_gpio176, // Misc GPIO
+
+ inout [15:0] io_tx, inout [15:0] io_rx,
+
+ output [13:0] TX, output TXSYNC, output TXBLANK,
+
+ input PPS_IN
+ );
+
+ // FPGA-specific pins connections
+ wire clk_fpga;
+
+ IBUFGDS #(.IOSTANDARD("LVDS_33"), .DIFF_TERM("TRUE"))
+ clk_fpga_pin (.O(clk_fpga),.I(CLK_FPGA_P),.IB(CLK_FPGA_N));
+
+ // SPI pins
+ wire mosi, sclk, miso;
+ assign { db_sclk_tx, db_mosi_tx } = ~db_sen_tx ? {sclk,mosi} : 2'b0;
+ assign { db_sclk_rx, db_mosi_rx } = ~db_sen_rx ? {sclk,mosi} : 2'b0;
+ assign { sclk_codec, mosi_codec } = ~sen_codec ? {sclk,mosi} : 2'b0;
+ assign { cgen_sclk, cgen_mosi } = ~cgen_sen_b ? {sclk,mosi} : 2'b0;
+ assign miso = (~db_sen_tx & db_miso_tx) | (~db_sen_rx & db_miso_rx) |
+ (~sen_codec & miso_codec) | (~cgen_sen_b & cgen_miso);
+
+ u1e_core u1e_core(.clk_fpga(clk_fpga), .rst_fpga(~debug_pb[2]),
+ .debug_led(debug_led), .debug(debug), .debug_clk(debug_clk),
+ .debug_pb(~debug_pb), .dip_sw(dip_sw), .debug_txd(FPGA_TXD), .debug_rxd(FPGA_RXD),
+ .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS6(EM_NCS6),
+ .EM_NWE(EM_NWE), .EM_NOE(EM_NOE),
+ .db_sda(db_sda), .db_scl(db_scl),
+ .sclk(sclk), .sen({cgen_sen_b,sen_codec,db_sen_tx,db_sen_rx}), .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),
+ .tx_have_space(overo_gpio144), .tx_underrun(overo_gpio145),
+ .rx_have_data(overo_gpio146), .rx_overrun(overo_gpio147),
+ .io_tx(io_tx), .io_rx(io_rx),
+ .tx(TX), .txsync(TXSYNC), .txblank(TXBLANK),
+ .misc_gpio( {{overo_gpio128,overo_gpio163,overo_gpio170,overo_gpio176},
+ {overo_gpio0,overo_gpio14,overo_gpio21,overo_gpio22},
+ {overo_gpio23,overo_gpio64,overo_gpio65,overo_gpio127}}),
+ .pps_in(PPS_IN) );
+
+endmodule // u1e
diff --git a/usrp2/top/u1e/u1e_core.v b/usrp2/top/u1e/u1e_core.v
new file mode 100644
index 000000000..a262184a8
--- /dev/null
+++ b/usrp2/top/u1e/u1e_core.v
@@ -0,0 +1,372 @@
+
+module u1e_core
+ (input clk_fpga, input rst_fpga,
+ output [2:0] debug_led, output [31:0] debug, output [1:0] debug_clk,
+ input [2:0] debug_pb, input [7:0] dip_sw, output debug_txd, input debug_rxd,
+
+ // GPMC
+ input EM_CLK, inout [15:0] EM_D, input [10:1] EM_A, input [1:0] EM_NBE,
+ input EM_WAIT0, input EM_NCS4, input EM_NCS6, input EM_NWE, input EM_NOE,
+
+ inout db_sda, inout db_scl,
+ output sclk, output [7: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_have_space, output tx_underrun, output rx_have_data, output rx_overrun,
+ inout [15:0] io_tx, inout [15:0] io_rx,
+ output reg [13:0] tx, output reg txsync, output txblank,
+
+ input [11:0] misc_gpio, input pps_in
+ );
+
+ wire wb_clk = clk_fpga;
+ wire wb_rst = rst_fpga;
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // GPMC 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;
+ wire tx_src_rdy, tx_dst_rdy, rx_src_rdy, rx_dst_rdy;
+ reg [15:0] tx_frame_len;
+ wire [15:0] rx_frame_len;
+
+ wire bus_error;
+
+ gpmc_async gpmc (.arst(wb_rst),
+ .EM_CLK(EM_CLK), .EM_D(EM_D), .EM_A(EM_A), .EM_NBE(EM_NBE),
+ .EM_WAIT0(EM_WAIT0), .EM_NCS4(EM_NCS4), .EM_NCS6(EM_NCS6), .EM_NWE(EM_NWE),
+ .EM_NOE(EM_NOE),
+
+ .rx_have_data(rx_have_data), .tx_have_space(tx_have_space),
+ .bus_error(bus_error), .bus_reset(0),
+
+ .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),
+
+ .fifo_clk(wb_clk), .fifo_rst(wb_rst),
+ .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_frame_len(tx_frame_len), .rx_frame_len(rx_frame_len),
+ .debug(debug_gpmc));
+/*
+ fifo_cascade #(.WIDTH(36), .SIZE(9)) loopback_fifo
+ (.clk(wb_clk), .reset(wb_rst), .clear(0),
+ .datain(tx_data), .src_rdy_i(tx_src_rdy), .dst_rdy_o(tx_dst_rdy),
+ .dataout(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy));
+*/
+ wire tx_strobe, rx_strobe, tx_enable, rx_enable;
+ wire [7:0] rate;
+ wire tx_fifo_rdy, rx_fifo_rdy;
+
+ cic_strober tx_strober (.clock(wb_clk), .reset(wb_rst), .enable(tx_enable),
+ .rate(rate), .strobe_fast(1), .strobe_slow(tx_strobe));
+
+ fifo_cascade #(.WIDTH(36), .SIZE(11)) tx_fifo
+ (.clk(wb_clk), .reset(wb_rst), .clear(0),
+ .datain(tx_data), .src_rdy_i(tx_src_rdy), .dst_rdy_o(tx_dst_rdy),
+ .dataout(), .src_rdy_o(tx_fifo_rdy), .dst_rdy_i(tx_strobe));
+
+
+ reg [15:0] ctr;
+ wire [15:0] rx_pkt_len = 480;
+ wire rx_eof = (ctr == rx_pkt_len);
+ wire rx_sof = (ctr == 0);
+
+ cic_strober rx_strober (.clock(wb_clk), .reset(wb_rst), .enable(rx_enable),
+ .rate(rate), .strobe_fast(1), .strobe_slow(rx_strobe));
+
+ fifo_cascade #(.WIDTH(36), .SIZE(11)) rx_fifo
+ (.clk(wb_clk), .reset(wb_rst), .clear(0),
+ .datain({2'b00,rx_eof,rx_sof,16'd0,ctr}), .src_rdy_i(rx_strobe), .dst_rdy_o(rx_fifo_rdy),
+ .dataout(rx_data), .src_rdy_o(rx_src_rdy), .dst_rdy_i(rx_dst_rdy));
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ ctr <= 0;
+ else if(rx_strobe & rx_fifo_rdy)
+ if(ctr == rx_pkt_len)
+ ctr <= 0;
+ else
+ ctr <= ctr + 1;
+
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // 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'hF), .s9_addr(4'h9), .s9_mask(4'hF),
+ .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 s7_ack = 0;
+ assign s8_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
+
+ reg [15:0] reg_leds, reg_cgen_ctrl, reg_test, xfer_rate;
+
+ localparam REG_LEDS = 7'd0; // out
+ localparam REG_SWITCHES = 7'd2; // in
+ localparam REG_CGEN_CTRL = 7'd4; // out
+ localparam REG_CGEN_ST = 7'd6; // in
+ localparam REG_TEST = 7'd8; // out
+ localparam REG_RX_FRAMELEN = 7'd10; // out
+ localparam REG_TX_FRAMELEN = 7'd12; // in
+ localparam REG_XFER_RATE = 7'd14; // in
+
+ always @(posedge wb_clk)
+ if(wb_rst)
+ begin
+ reg_leds <= 0;
+ reg_cgen_ctrl <= 2'b11;
+ reg_test <= 0;
+ tx_frame_len <= 0;
+ xfer_rate <= 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_TX_FRAMELEN :
+ tx_frame_len <= s0_dat_mosi;
+ REG_XFER_RATE :
+ xfer_rate <= s0_dat_mosi;
+ endcase // case (s0_adr[6:0])
+
+ assign tx_enable = xfer_rate[15];
+ assign rx_enable = xfer_rate[14];
+ assign rate = xfer_rate[7:0];
+
+ assign { 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 { rx_overrun, tx_underrun } = 0; // reg_test;
+
+ assign s0_dat_miso = (s0_adr[6:0] == REG_LEDS) ? reg_leds :
+ (s0_adr[6:0] == REG_SWITCHES) ? {5'b0,debug_pb[2:0],dip_sw[7:0]} :
+ (s0_adr[6:0] == REG_CGEN_CTRL) ? reg_cgen_ctrl :
+ (s0_adr[6:0] == REG_CGEN_ST) ? {13'b0,cgen_st_status,cgen_st_ld,cgen_st_refmon} :
+ (s0_adr[6:0] == REG_TEST) ? reg_test :
+ (s0_adr[6:0] == REG_RX_FRAMELEN) ? rx_frame_len :
+ 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[4:2]),.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 #5
+
+ wire [7:0] set_addr;
+ wire [31:0] set_data;
+ wire set_stb;
+
+ // only have 32 regs, 32 bits each with current setup...
+ settings_bus_16LE #(.AWIDTH(11),.RWIDTH(11-4-2)) settings_bus_16LE
+ (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s5_adr),.wb_dat_i(s5_dat_mosi),
+ .wb_stb_i(s5_stb),.wb_we_i(s5_we),.wb_ack_o(s5_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), .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(0), .run_tx(0), .ctrl_lines(atr_lines));
+
+
+ // /////////////////////////////////////////////////////////////////////////
+ // VITA Timing
+
+ localparam SR_TIME64 = 0;
+ wire pps_int;
+ wire [63:0] vita_time;
+
+ 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), .pps_int(pps_int));
+
+
+ // /////////////////////////////////////////////////////////////////////////
+ // TX
+
+ assign txblank = 0;
+
+ wire [23:0] freq = {reg_test,8'd0};
+
+ reg [23:0] tx_q_hold;
+ wire [23:0] tx_i, tx_q;
+
+ reg tx_stb;
+ always @(posedge wb_clk)
+ tx_stb <= ~tx_stb;
+
+ always @(posedge wb_clk)
+ if(tx_stb)
+ tx <= tx_i[23:10];
+ else
+ tx <= tx_q_hold[23:10];
+
+ always @(posedge wb_clk)
+ if(tx_stb)
+ tx_q_hold <= tx_q;
+
+ always @(posedge wb_clk)
+ txsync <= ~tx_stb; // TX Sync low indicates first data item
+ // We invert here if we don't use inv_txsync in the 9862
+
+ reg [23:0] phase;
+ always @(posedge wb_clk)
+ if(tx_stb)
+ phase <= phase + freq;
+
+ cordic_z24 #(.bitwidth(24)) tx_cordic
+ (.clock(wb_clk), .reset(wb_rst), .enable(1),
+ .xi(24'd2500000), .yi(24'd0), .zi(phase), .xo(tx_i), .yo(tx_q), .zo());
+
+ // /////////////////////////////////////////////////////////////////////////////////////
+ // Debug circuitry
+
+ assign debug_clk = { EM_CLK, clk_fpga };
+/*
+ assign debug = { { rx_have_data, tx_have_space, EM_NCS6, EM_NCS4, EM_NWE, EM_NOE, EM_A[10:1] },
+ { EM_D } };
+*/
+
+ assign debug = { phase[23:8], txsync, txblank, tx };
+
+
+ assign debug_gpio_0 = { debug_gpmc };
+ assign debug_gpio_1 = { {rx_enable, rx_strobe, rx_fifo_rdy, rx_strobe & ~rx_fifo_rdy},
+ {tx_enable, tx_strobe, tx_fifo_rdy, tx_strobe & ~tx_fifo_rdy},
+ {rx_sof, rx_eof, rx_src_rdy, rx_dst_rdy, rx_data[33:32],2'b0},
+ {3'b0, bus_error, misc_gpio[11:0]} };
+
+endmodule // u1e_core
diff --git a/usrp2/top/u1e_passthru/.gitignore b/usrp2/top/u1e_passthru/.gitignore
new file mode 100644
index 000000000..1b2211df0
--- /dev/null
+++ b/usrp2/top/u1e_passthru/.gitignore
@@ -0,0 +1 @@
+build*
diff --git a/usrp2/top/u1e_passthru/Makefile b/usrp2/top/u1e_passthru/Makefile
new file mode 100644
index 000000000..62923f87f
--- /dev/null
+++ b/usrp2/top/u1e_passthru/Makefile
@@ -0,0 +1,107 @@
+#
+# Copyright 2008 Ettus Research LLC
+#
+
+##################################################
+# 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 := passthru
+export PROJ_FILE := $(BUILD_DIR)$(TOP_MODULE).ise
+
+##################################################
+# Project Properties
+##################################################
+export PROJECT_PROPERTIES := \
+family "Spartan-3A DSP" \
+device xc3sd1800a \
+package cs484 \
+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
+##################################################
+export SOURCE_ROOT := ../../../
+export SOURCES := \
+top/u1e_passthru/passthru.ucf \
+top/u1e_passthru/passthru.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 \
+"Unused IOB Pins" "Pull Up"
+
+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/usrp2/top/u1e_passthru/passthru.ucf b/usrp2/top/u1e_passthru/passthru.ucf
new file mode 100644
index 000000000..3ffe33882
--- /dev/null
+++ b/usrp2/top/u1e_passthru/passthru.ucf
@@ -0,0 +1,266 @@
+
+#NET "CLK_FPGA_P" LOC = "Y11" ;
+#NET "CLK_FPGA_N" LOC = "Y10" ;
+
+## 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" ;
+
+## Overo GPIO
+#NET "overo_gpio0" LOC = "F9" ; # MISC GPIO for debug
+#NET "overo_gpio14" LOC = "C4" ; # MISC GPIO for debug
+#NET "overo_gpio21" LOC = "D5" ; # MISC GPIO for debug
+#NET "overo_gpio22" LOC = "A3" ; # MISC GPIO for debug
+#NET "overo_gpio23" LOC = "B3" ; # MISC GPIO for debug
+#NET "overo_gpio64" LOC = "A4" ; # MISC GPIO for debug
+#NET "overo_gpio65" LOC = "F8" ; # MISC GPIO for debug
+NET "overo_gpio127" LOC = "C8" ; # passed through as cgen_sen_b
+#NET "overo_gpio128" LOC = "G8" ; # MISC GPIO for debug
+#NET "overo_gpio144" LOC = "A5" ; # tx_have_space
+#NET "overo_gpio145" LOC = "C7" ; # tx_underrun
+#NET "overo_gpio146" LOC = "A6" ; # rx_have_data
+#NET "overo_gpio147" LOC = "B6" ; # rx_overrun
+#NET "overo_gpio163" LOC = "D7" ; # MISC GPIO for debug
+#NET "overo_gpio170" LOC = "E8" ; # MISC GPIO for debug
+#NET "overo_gpio176" LOC = "B4" ; # MISC GPIO for debug
+
+## Overo UART
+##NET "overo_txd1" LOC = "C6" ;
+##NET "overo_rxd1" LOC = "D6" ;
+
+## FTDI UART to USB converter
+#NET "FPGA_TXD" LOC = "U1" ;
+#NET "FPGA_RXD" LOC = "T6" ;
+
+##NET "SYSEN" LOC = "C11" ;
+
+## I2C
+#NET "db_scl" LOC = "U4" ;
+#NET "db_sda" LOC = "U5" ;
+
+## SPI
+### DBoard SPI
+#NET "db_sclk_rx" LOC = "W3" ;
+#NET "db_miso_rx" LOC = "W2" ;
+#NET "db_mosi_rx" LOC = "V4" ;
+#NET "db_sen_rx" LOC = "V3" ;
+#NET "db_sclk_tx" LOC = "Y1" ;
+#NET "db_miso_tx" LOC = "W1" ;
+#NET "db_mosi_tx" LOC = "R3" ;
+#NET "db_sen_tx" LOC = "T4" ;
+
+### AD9862 SPI and aux SPI Interfaces
+##NET "aux_sdi_codec" LOC = "F19" ;
+##NET "aux_sdo_codec" LOC = "F18" ;
+##NET "aux_sclk_codec" LOC = "D21" ;
+#NET "sen_codec" LOC = "D20" ;
+#NET "mosi_codec" LOC = "E19" ;
+#NET "miso_codec" LOC = "F21" ;
+#NET "sclk_codec" LOC = "E20" ;
+
+### Clock Gen SPI
+#NET "cgen_miso" LOC = "U2" ;
+NET "cgen_mosi" LOC = "V1" ;
+NET "cgen_sclk" LOC = "R5" ;
+NET "cgen_sen_b" LOC = "T1" ;
+
+## Clock gen control
+#NET "cgen_st_status" LOC = "D4" ;
+#NET "cgen_st_ld" LOC = "D1" ;
+#NET "cgen_st_refmon" LOC = "E1" ;
+#NET "cgen_sync_b" LOC = "M1" ;
+#NET "cgen_ref_sel" LOC = "J1" ;
+
+## Debug pins
+#NET "debug_led<2>" LOC = "T5" ;
+#NET "debug_led<1>" LOC = "R2" ;
+#NET "debug_led<0>" LOC = "R1" ;
+#NET "debug<0>" LOC = "P6" ;
+#NET "debug<1>" LOC = "R6" ;
+#NET "debug<2>" LOC = "P1" ;
+#NET "debug<3>" LOC = "P2" ;
+#NET "debug<4>" LOC = "N6" ;
+#NET "debug<5>" LOC = "N5" ;
+#NET "debug<6>" LOC = "N1" ;
+#NET "debug<7>" LOC = "K2" ;
+#NET "debug<8>" LOC = "K3" ;
+#NET "debug<9>" LOC = "K6" ;
+#NET "debug<10>" LOC = "L5" ;
+#NET "debug<11>" LOC = "H2" ;
+#NET "debug<12>" LOC = "K4" ;
+#NET "debug<13>" LOC = "K5" ;
+#NET "debug<14>" LOC = "G1" ;
+#NET "debug<15>" LOC = "H1" ;
+#NET "debug<16>" LOC = "H5" ;
+#NET "debug<17>" LOC = "H6" ;
+#NET "debug<18>" LOC = "E3" ;
+#NET "debug<19>" LOC = "E4" ;
+#NET "debug<20>" LOC = "G5" ;
+#NET "debug<21>" LOC = "G6" ;
+#NET "debug<22>" LOC = "F2" ;
+#NET "debug<23>" LOC = "F1" ;
+#NET "debug<24>" LOC = "H3" ;
+#NET "debug<25>" LOC = "H4" ;
+#NET "debug<26>" LOC = "F4" ;
+#NET "debug<27>" LOC = "F5" ;
+#NET "debug<28>" LOC = "C2" ;
+#NET "debug<29>" LOC = "C1" ;
+#NET "debug<30>" LOC = "F3" ;
+#NET "debug<31>" LOC = "G3" ;
+#NET "debug_clk<0>" LOC = "L6" ;
+#NET "debug_clk<1>" LOC = "M5" ;
+
+#NET "debug_pb<2>" LOC = "Y2" ;
+#NET "debug_pb<1>" LOC = "AA1" ;
+#NET "debug_pb<0>" LOC = "N3" ;
+
+#NET "dip_sw<7>" LOC = "T3" ;
+#NET "dip_sw<6>" LOC = "U3" ;
+#NET "dip_sw<5>" LOC = "M3" ;
+#NET "dip_sw<4>" LOC = "N4" ;
+#NET "dip_sw<3>" LOC = "J3" ;
+#NET "dip_sw<2>" LOC = "J4" ;
+#NET "dip_sw<1>" LOC = "J6" ;
+#NET "dip_sw<0>" LOC = "J7" ;
+
+##NET "RXSYNC" LOC = "F22" ;
+##NET "reset_codec" LOC = "D22" ;
+
+##NET "DB<11>" LOC = "E22" ;
+##NET "DB<10>" LOC = "J19" ;
+##NET "DB<9>" LOC = "H20" ;
+##NET "DB<8>" LOC = "G19" ;
+##NET "DB<7>" LOC = "F20" ;
+##NET "DB<6>" LOC = "K16" ;
+##NET "DB<5>" LOC = "J17" ;
+##NET "DB<4>" LOC = "H22" ;
+##NET "DB<3>" LOC = "G22" ;
+##NET "DB<2>" LOC = "H17" ;
+##NET "DB<1>" LOC = "H18" ;
+##NET "DB<0>" LOC = "K20" ;
+##NET "DA<11>" LOC = "J20" ;
+##NET "DA<10>" LOC = "K19" ;
+##NET "DA<9>" LOC = "K18" ;
+##NET "DA<8>" LOC = "L22" ;
+##NET "DA<7>" LOC = "K22" ;
+##NET "DA<6>" LOC = "N22" ;
+##NET "DA<5>" LOC = "M22" ;
+##NET "DA<4>" LOC = "N20" ;
+##NET "DA<3>" LOC = "N19" ;
+##NET "DA<2>" LOC = "R22" ;
+##NET "DA<1>" LOC = "P22" ;
+##NET "DA<0>" LOC = "N17" ;
+
+#NET "TX<13>" LOC = "P19" ;
+#NET "TX<12>" LOC = "R18" ;
+#NET "TX<11>" LOC = "U20" ;
+#NET "TX<10>" LOC = "T20" ;
+#NET "TX<9>" LOC = "R19" ;
+#NET "TX<8>" LOC = "R20" ;
+#NET "TX<7>" LOC = "W22" ;
+#NET "TX<6>" LOC = "Y22" ;
+#NET "TX<5>" LOC = "T18" ;
+#NET "TX<4>" LOC = "T17" ;
+#NET "TX<3>" LOC = "W19" ;
+#NET "TX<2>" LOC = "V20" ;
+#NET "TX<1>" LOC = "Y21" ;
+#NET "TX<0>" LOC = "AA22" ;
+#NET "TXSYNC" LOC = "U18" ;
+#NET "TXBLANK" LOC = "U19" ;
+
+#NET "PPS_IN" LOC = "M17" ;
+
+#NET "io_tx<0>" LOC = "AB20" ;
+#NET "io_tx<1>" LOC = "Y17" ;
+#NET "io_tx<2>" LOC = "Y16" ;
+#NET "io_tx<3>" LOC = "U16" ;
+#NET "io_tx<4>" LOC = "V16" ;
+#NET "io_tx<5>" LOC = "AB19" ;
+#NET "io_tx<6>" LOC = "AA19" ;
+#NET "io_tx<7>" LOC = "U14" ;
+#NET "io_tx<8>" LOC = "U15" ;
+#NET "io_tx<9>" LOC = "AB17" ;
+#NET "io_tx<10>" LOC = "AB18" ;
+#NET "io_tx<11>" LOC = "Y13" ;
+#NET "io_tx<12>" LOC = "W14" ;
+#NET "io_tx<13>" LOC = "U13" ;
+#NET "io_tx<14>" LOC = "AA15" ;
+#NET "io_tx<15>" LOC = "AB14" ;
+
+#NET "io_rx<0>" LOC = "Y8" ;
+#NET "io_rx<1>" LOC = "Y9" ;
+#NET "io_rx<2>" LOC = "V7" ;
+#NET "io_rx<3>" LOC = "U8" ;
+#NET "io_rx<4>" LOC = "V10" ;
+#NET "io_rx<5>" LOC = "U9" ;
+#NET "io_rx<6>" LOC = "AB7" ;
+#NET "io_rx<7>" LOC = "AA8" ;
+#NET "io_rx<8>" LOC = "W8" ;
+#NET "io_rx<9>" LOC = "V8" ;
+#NET "io_rx<10>" LOC = "AB5" ;
+#NET "io_rx<11>" LOC = "AB6" ;
+#NET "io_rx<12>" LOC = "AB4" ;
+#NET "io_rx<13>" LOC = "AA4" ;
+#NET "io_rx<14>" LOC = "W5" ;
+#NET "io_rx<15>" LOC = "Y4" ;
+
+##NET "CLKOUT2_CODEC" LOC = "U12" ;
+##NET "CLKOUT1_CODEC" LOC = "V12" ;
+
+## FPGA Config Pins
+##NET "fpga_cfg_prog_b" LOC = "A2" ;
+##NET "fpga_cfg_done" LOC = "AB21" ;
+NET "fpga_cfg_din" LOC = "W17" ;
+NET "fpga_cfg_cclk" LOC = "V17" ;
+##NET "fpga_cfg_init_b" LOC = "W15" ;
+
+## Unused
+##NET "unnamed_net37" LOC = "B1" ; # TMS
+##NET "unnamed_net36" LOC = "B22" ; # TDO
+##NET "unnamed_net35" LOC = "D2" ; # TDI
+##NET "unnamed_net34" LOC = "A21" ; # TCK
+##NET "unnamed_net45" LOC = "F7" ; # PUDC_B
+##NET "unnamed_net44" LOC = "V6" ; # M2
+##NET "unnamed_net43" LOC = "AA3" ; # M1
+##NET "unnamed_net42" LOC = "AB3" ; # M0
+##NET "GND" LOC = "V19" ; # Suspend, unused
diff --git a/usrp2/top/u1e_passthru/passthru.v b/usrp2/top/u1e_passthru/passthru.v
new file mode 100644
index 000000000..d846f2cf6
--- /dev/null
+++ b/usrp2/top/u1e_passthru/passthru.v
@@ -0,0 +1,18 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+
+module passthru
+ (input overo_gpio127,
+ 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_gpio127;
+ assign cgen_mosi = fpga_cfg_din;
+
+
+endmodule // passthru
diff --git a/usrp2/top/u2_core/u2_core.v b/usrp2/top/u2_core/u2_core.v
index 78922fb4f..2302f59ee 100755..100644
--- a/usrp2/top/u2_core/u2_core.v
+++ b/usrp2/top/u2_core/u2_core.v
@@ -135,6 +135,24 @@ module u2_core
input sim_mode,
input [3:0] clock_divider
);
+
+ localparam SR_BUF_POOL = 64; // Uses 1 reg
+ localparam SR_UDP_SM = 96; // 64 regs
+ localparam SR_RX_DSP = 160; // 16
+ localparam SR_RX_CTRL = 176; // 16
+ localparam SR_TIME64 = 192; // 3
+ localparam SR_SIMTIMER = 198; // 2
+ localparam SR_TX_DSP = 208; // 16
+ localparam SR_TX_CTRL = 224; // 16
+
+ // FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048
+ // all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs
+ localparam DSP_TX_FIFOSIZE = 10;
+ localparam DSP_RX_FIFOSIZE = 10;
+ localparam ETH_TX_FIFOSIZE = 10;
+ localparam ETH_RX_FIFOSIZE = 11;
+ localparam SERDES_TX_FIFOSIZE = 9;
+ localparam SERDES_RX_FIFOSIZE = 9; // RX currently doesn't use a fifo?
wire [7:0] set_addr;
wire [31:0] set_data;
@@ -144,13 +162,14 @@ module u2_core
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 bus_error, spi_int, i2c_int, pps_int, onetime_int, periodic_int, buffer_int;
+ wire proc_int, overrun, underrun, uart_tx_int, uart_rx_int;
wire [31:0] debug_gpio_0, debug_gpio_1;
wire [31:0] atr_lines;
- wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc,
- debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp;
+ wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc,
+ debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp;
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;
@@ -159,6 +178,7 @@ module u2_core
wire serdes_link_up;
wire epoch;
wire [31:0] irq;
+ wire [63:0] vita_time;
// ///////////////////////////////////////////////////////////////////////////////////////////////
// Wishbone Single Master INTERCON
@@ -333,7 +353,7 @@ module u2_core
wire [3:0] wr0_flags, wr1_flags, wr2_flags, wr3_flags;
wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat;
- buffer_pool #(.BUF_SIZE(9), .SET_ADDR(64)) buffer_pool
+ buffer_pool #(.BUF_SIZE(9), .SET_ADDR(SR_BUF_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(),.wb_rty_o(),
@@ -405,26 +425,51 @@ module u2_core
.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(irq),.word14(status_enc),.word15(cycle_count)
+ .word08(status),.word09({sim_mode,27'b0,clock_divider[3:0]}),.word10(vita_time[63:32]),
+ .word11(vita_time[31:0]),.word12(32'b0),.word13(irq),.word14(status_enc),.word15(cycle_count)
);
// /////////////////////////////////////////////////////////////////////////
// Ethernet MAC Slave #6
- simple_gemac_wrapper #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper
+ wire [18:0] rx_f19_data, tx_f19_data;
+ wire rx_f19_src_rdy, rx_f19_dst_rdy, rx_f36_src_rdy, rx_f36_dst_rdy;
+
+ simple_gemac_wrapper19 #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper19
(.clk125(clk_to_mac), .reset(wb_rst),
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
.GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
.sys_clk(dsp_clk),
- .rx_f36_data({wr2_flags,wr2_dat}), .rx_f36_src_rdy(wr2_ready_i), .rx_f36_dst_rdy(wr2_ready_o),
- .tx_f36_data({rd2_flags,rd2_dat}), .tx_f36_src_rdy(rd2_ready_o), .tx_f36_dst_rdy(rd2_ready_i),
+ .rx_f19_data(rx_f19_data), .rx_f19_src_rdy(rx_f19_src_rdy), .rx_f19_dst_rdy(rx_f19_dst_rdy),
+ .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),
.wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(s6_stb), .wb_cyc(s6_cyc), .wb_ack(s6_ack),
.wb_we(s6_we), .wb_adr(s6_adr), .wb_dat_i(s6_dat_o), .wb_dat_o(s6_dat_i),
.mdio(MDIO), .mdc(MDC),
.debug(debug_mac));
+
+ wire [35:0] udp_tx_data, udp_rx_data;
+ wire udp_tx_src_rdy, udp_tx_dst_rdy, udp_rx_src_rdy, udp_rx_dst_rdy;
+
+ udp_wrapper #(.BASE(SR_UDP_SM)) udp_wrapper
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .rx_f19_data(rx_f19_data), .rx_f19_src_rdy_i(rx_f19_src_rdy), .rx_f19_dst_rdy_o(rx_f19_dst_rdy),
+ .tx_f19_data(tx_f19_data), .tx_f19_src_rdy_o(tx_f19_src_rdy), .tx_f19_dst_rdy_i(tx_f19_dst_rdy),
+ .rx_f36_data(udp_rx_data), .rx_f36_src_rdy_o(udp_rx_src_rdy), .rx_f36_dst_rdy_i(udp_rx_dst_rdy),
+ .tx_f36_data(udp_tx_data), .tx_f36_src_rdy_i(udp_tx_src_rdy), .tx_f36_dst_rdy_o(udp_tx_dst_rdy),
+ .debug(debug_udp) );
+
+ fifo_cascade #(.WIDTH(36), .SIZE(ETH_TX_FIFOSIZE)) tx_eth_fifo
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .datain({rd2_flags,rd2_dat}), .src_rdy_i(rd2_ready_o), .dst_rdy_o(rd2_ready_i),
+ .dataout(udp_tx_data), .src_rdy_o(udp_tx_src_rdy), .dst_rdy_i(udp_tx_dst_rdy));
+
+ fifo_cascade #(.WIDTH(36), .SIZE(ETH_RX_FIFOSIZE)) rx_eth_fifo
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .datain(udp_rx_data), .src_rdy_i(udp_rx_src_rdy), .dst_rdy_o(udp_rx_dst_rdy),
+ .dataout({wr2_flags,wr2_dat}), .src_rdy_o(wr2_ready_i), .dst_rdy_i(wr2_ready_o));
// /////////////////////////////////////////////////////////////////////////
// Settings Bus -- Slave #7
@@ -474,8 +519,8 @@ module u2_core
assign irq= {{8'b0},
{8'b0},
- {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}};
+ {3'b0, periodic_int, clk_status, serdes_link_up, uart_tx_int, uart_rx_int},
+ {pps_int,overrun,underrun,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}};
pic 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),
@@ -484,13 +529,25 @@ module u2_core
// /////////////////////////////////////////////////////////////////////////
// Master Timer, Slave #9
+ // No longer used, replaced with simple_timer below
+ /*
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_ack = 0;
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Simple Timer interrupts
+
+ simple_timer #(.BASE(SR_SIMTIMER)) simple_timer
+ (.clk(wb_clk), .reset(wb_rst),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .onetime_int(onetime_int), .periodic_int(periodic_int));
+
// /////////////////////////////////////////////////////////////////////////
// UART, Slave #10
@@ -518,22 +575,9 @@ module u2_core
// //////////////////////////////////////////////////////////////////////////
// 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;
+ // No longer used, see time_64bit. Still need to handle mimo time, though
+ assign sc_ack = 0;
- wire pps_o;
- time_sync time_sync
- (.wb_clk_i(wb_clk),.rst_i(wb_rst),
- .cyc_i(sc_cyc),.stb_i(sc_stb),.adr_i(sc_adr[4:2]),
- .we_i(sc_we),.dat_i(sc_dat_o),.dat_o(sc_dat_i),.ack_o(sc_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) );
-
// /////////////////////////////////////////////////////////////////////////
// SD Card Reader / Writer, Slave #13
@@ -547,48 +591,89 @@ module u2_core
assign sd_dat_i[31:8] = 0;
// /////////////////////////////////////////////////////////////////////////
- // DSP
+ // DSP RX
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_flags_o(wr1_flags), .wr_ready_o(wr1_ready_i), .wr_ready_i(wr1_ready_o),
- .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) );
+ wire rx_dst_rdy, rx_src_rdy, rx1_dst_rdy, rx1_src_rdy;
+ wire [99:0] rx_data;
+ wire [35:0] rx1_data;
- // dummy_rx dsp_core_rx
- dsp_core_rx dsp_core_rx
+ dsp_core_rx #(.BASE(SR_RX_DSP)) 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),
.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),
+ wire [31:0] vrc_debug;
+
+ vita_rx_control #(.BASE(SR_RX_CTRL), .WIDTH(32)) vita_rx_control
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .vita_time(vita_time), .overrun(overrun),
+ .sample(sample_rx), .run(run_rx), .strobe(strobe_rx),
+ .sample_fifo_o(rx_data), .sample_fifo_dst_rdy_i(rx_dst_rdy), .sample_fifo_src_rdy_o(rx_src_rdy),
+ .debug_rx(vrc_debug));
+
+ wire [3:0] vita_state;
+
+ vita_rx_framer #(.BASE(SR_RX_CTRL), .MAXCHAN(1)) vita_rx_framer
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .master_time(master_time),.underrun(underrun),
- .rd_dat_i(rd1_dat), .rd_flags_i(rd1_flags), .rd_ready_i(rd1_ready_o), .rd_ready_o(rd1_ready_i),
+ .sample_fifo_i(rx_data), .sample_fifo_dst_rdy_o(rx_dst_rdy), .sample_fifo_src_rdy_i(rx_src_rdy),
+ .data_o(rx1_data), .dst_rdy_i(rx1_dst_rdy), .src_rdy_o(rx1_src_rdy),
+ .fifo_occupied(), .fifo_full(), .fifo_empty(),
+ .debug_rx(vita_state) );
+
+ fifo_cascade #(.WIDTH(36), .SIZE(DSP_RX_FIFOSIZE)) rx_fifo_cascade
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .datain(rx1_data), .src_rdy_i(rx1_src_rdy), .dst_rdy_o(rx1_dst_rdy),
+ .dataout({wr1_flags,wr1_dat}), .src_rdy_o(wr1_ready_i), .dst_rdy_i(wr1_ready_o));
+
+ // ///////////////////////////////////////////////////////////////////////////////////
+ // DSP TX
+
+ wire [35:0] tx_data;
+ wire [99:0] tx1_data;
+ wire tx_src_rdy, tx_dst_rdy, tx1_src_rdy, tx1_dst_rdy;
+
+ wire [31:0] debug_vtc, debug_vtd, debug_vt;
+
+ fifo_cascade #(.WIDTH(36), .SIZE(DSP_TX_FIFOSIZE)) tx_fifo_cascade
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .datain({rd1_flags,rd1_dat}), .src_rdy_i(rd1_ready_o), .dst_rdy_o(rd1_ready_i),
+ .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy) );
+
+ vita_tx_deframer #(.BASE(SR_TX_CTRL), .MAXCHAN(1)) vita_tx_deframer
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .data_i(tx_data), .src_rdy_i(tx_src_rdy), .dst_rdy_o(tx_dst_rdy),
+ .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy),
+ .debug(debug_vtd) );
+
+ vita_tx_control #(.BASE(SR_TX_CTRL), .WIDTH(32)) vita_tx_control
+ (.clk(dsp_clk), .reset(dsp_rst), .clear(0),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .vita_time(vita_time),.underrun(underrun),
+ .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy),
.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) );
+ .debug(debug_vtc) );
+
+ assign debug_vt = debug_vtc | debug_vtd;
- dsp_core_tx dsp_core_tx
+ dsp_core_tx #(.BASE(SR_TX_DSP)) dsp_core_tx
(.clk(dsp_clk),.rst(dsp_rst),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .sample(sample_tx), .run(run_tx), .strobe(strobe_tx),
.dac_a(dac_a),.dac_b(dac_b),
- .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .debug(debug_tx_dsp) );
+ .debug(debug_tx_dsp) );
assign dsp_rst = wb_rst;
// ///////////////////////////////////////////////////////////////////////////////////
// SERDES
- serdes #(.TXFIFOSIZE(9),.RXFIFOSIZE(9)) serdes
+ serdes #(.TXFIFOSIZE(SERDES_TX_FIFOSIZE),.RXFIFOSIZE(SERDES_RX_FIFOSIZE)) serdes
(.clk(dsp_clk),.rst(dsp_rst),
.ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb),
.rd_dat_i(rd0_dat),.rd_flags_i(rd0_flags),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o),
@@ -631,6 +716,13 @@ module u2_core
assign RAM_CE1n = 0;
assign RAM_D[17:16] = 2'bzz;
+ // /////////////////////////////////////////////////////////////////////////
+ // VITA Timing
+
+ time_64bit #(.TICKS_PER_SEC(32'd100000000),.BASE(SR_TIME64)) time_64bit
+ (.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .pps(pps_in), .vita_time(vita_time), .pps_int(pps_int));
+
// /////////////////////////////////////////////////////////////////////////////////////////
// Debug Pins
@@ -657,8 +749,9 @@ module u2_core
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; // wb_clk;
- assign debug_clk[1] = clk_to_mac;
+ assign debug_clk[0] = GMII_RX_CLK; // wb_clk;
+ assign debug_clk[1] = dsp_clk;
+
/*
wire mdio_cpy = MDIO;
@@ -672,14 +765,27 @@ module u2_core
{ 5'd0, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK },
{ wr2_flags, rd2_flags },
{ 4'd0, wr2_ready_i, wr2_ready_o, rd2_ready_i, rd2_ready_o } };
- */
assign debug = { { GMII_RXD },
{ 5'd0, GMII_RX_DV, GMII_RX_ER, GMII_RX_CLK },
{ wr2_flags, rd2_flags },
{ GMII_TX_EN,3'd0, wr2_ready_i, wr2_ready_o, rd2_ready_i, rd2_ready_o } };
-
- assign debug_gpio_0 = debug_mac; //eth_mac_debug;
- assign debug_gpio_1 = 0;
+ */
+
+// assign debug = debug_udp;
+ assign debug = vrc_debug;
+ assign debug_gpio_0 = { {pps_in, pps_int, 2'd0, vita_state},
+ {2'd0, rx_dst_rdy, rx_src_rdy, rx_data[99:96]},
+ {run_rx_d1, run_rx, strobe_rx, overrun, wr1_flags[3:0]} ,
+ {wr1_ready_i, wr1_ready_o, rx1_src_rdy, rx1_dst_rdy, rx1_data[35:32]}};
+
+ assign debug_gpio_1 = {vita_time[63:32] };
+
+/*
+ assign debug_gpio_1 = { { tx_f19_data[15:8] },
+ { tx_f19_data[7:0] },
+ { 3'd0, tx_f19_src_rdy, tx_f19_dst_rdy, tx_f19_data[18:16] },
+ { 2'b0, rd2_ready_i, rd2_ready_o, rd2_flags } };
+ */
endmodule // u2_core
diff --git a/usrp2/top/u2_rev3/Makefile b/usrp2/top/u2_rev3/Makefile
index 81d787566..867fb5cab 100644
--- a/usrp2/top/u2_rev3/Makefile
+++ b/usrp2/top/u2_rev3/Makefile
@@ -84,7 +84,16 @@ control_lib/wb_bridge_16_32.v \
control_lib/reset_sync.v \
control_lib/priority_enc.v \
control_lib/pic.v \
+vrt/vita_rx_control.v \
+vrt/vita_rx_framer.v \
+vrt/vita_tx_control.v \
+vrt/vita_tx_deframer.v \
+udp/udp_wrapper.v \
+udp/fifo19_rxrealign.v \
+udp/prot_eng_tx.v \
+udp/add_onescomp.v \
simple_gemac/simple_gemac_wrapper.v \
+simple_gemac/simple_gemac_wrapper19.v \
simple_gemac/simple_gemac.v \
simple_gemac/simple_gemac_wb.v \
simple_gemac/simple_gemac_tx.v \
@@ -105,11 +114,15 @@ 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/newfifo/ll8_to_fifo36.v \
+control_lib/newfifo/fifo19_to_ll8.v \
+control_lib/newfifo/ll8_to_fifo19.v \
+control_lib/newfifo/fifo36_to_fifo19.v \
+control_lib/newfifo/fifo19_to_fifo36.v \
control_lib/longfifo.v \
control_lib/shortfifo.v \
control_lib/medfifo.v \
@@ -119,6 +132,8 @@ coregen/fifo_xlnx_512x36_2clk.v \
coregen/fifo_xlnx_512x36_2clk.xco \
coregen/fifo_xlnx_64x36_2clk.v \
coregen/fifo_xlnx_64x36_2clk.xco \
+coregen/fifo_xlnx_16x19_2clk.v \
+coregen/fifo_xlnx_16x19_2clk.xco \
extram/wb_zbt16_b.v \
opencores/8b10b/decode_8b10b.v \
opencores/8b10b/encode_8b10b.v \
@@ -171,10 +186,11 @@ serdes/serdes_fc_rx.v \
serdes/serdes_fc_tx.v \
serdes/serdes_rx.v \
serdes/serdes_tx.v \
+timing/time_64bit.v \
+timing/time_compare.v \
timing/time_receiver.v \
timing/time_sender.v \
-timing/time_sync.v \
-timing/timer.v \
+timing/simple_timer.v \
top/u2_core/u2_core.v \
top/u2_rev3/u2_rev3.ucf \
top/u2_rev3/u2_rev3.v
diff --git a/usrp2/udp/add_onescomp.v b/usrp2/udp/add_onescomp.v
new file mode 100644
index 000000000..048842a86
--- /dev/null
+++ b/usrp2/udp/add_onescomp.v
@@ -0,0 +1,12 @@
+
+
+module add_onescomp
+ #(parameter WIDTH = 16)
+ (input [WIDTH-1:0] A,
+ input [WIDTH-1:0] B,
+ output [WIDTH-1:0] SUM);
+
+ wire [WIDTH:0] SUM_INT = {1'b0,A} + {1'b0,B};
+ assign SUM = SUM_INT[WIDTH-1:0] + {{WIDTH-1{1'b0}},SUM_INT[WIDTH]};
+
+endmodule // add_onescomp
diff --git a/usrp2/udp/fifo19_rxrealign.v b/usrp2/udp/fifo19_rxrealign.v
new file mode 100644
index 000000000..35ad90951
--- /dev/null
+++ b/usrp2/udp/fifo19_rxrealign.v
@@ -0,0 +1,42 @@
+
+
+// Adds a junk line at the beginning of every packet, which the
+// following stages should ignore. This gives us proper alignment due
+// to the 14 byte ethernet header
+
+// Bit 18 -- odd length
+// Bit 17 -- eof
+// Bit 16 -- sof
+// Bit 15:0 -- data
+
+module fifo19_rxrealign
+ (input clk, input reset, input clear,
+ input [18:0] datain, input src_rdy_i, output dst_rdy_o,
+ output [18:0] dataout, output src_rdy_o, input dst_rdy_i);
+
+ reg rxre_state;
+ localparam RXRE_DUMMY = 0;
+ localparam RXRE_PKT = 1;
+
+ assign dataout[18] = datain[18];
+ assign dataout[17] = datain[17];
+ assign dataout[16] = (rxre_state==RXRE_DUMMY) | (datain[17] & datain[16]); // allows for passing error signal
+ assign dataout[15:0] = datain[15:0];
+
+ always @(posedge clk)
+ if(reset | clear)
+ rxre_state <= RXRE_DUMMY;
+ else if(src_rdy_i & dst_rdy_i)
+ case(rxre_state)
+ RXRE_DUMMY :
+ rxre_state <= RXRE_PKT;
+ RXRE_PKT :
+ if(datain[17]) // if eof or error
+ rxre_state <= RXRE_DUMMY;
+ endcase // case (rxre_state)
+
+ assign src_rdy_o = src_rdy_i & dst_rdy_i; // Send anytime both sides are ready
+ assign dst_rdy_o = src_rdy_i & dst_rdy_i & (rxre_state == RXRE_PKT); // Only consume after the dummy
+
+endmodule // fifo19_rxrealign
+
diff --git a/usrp2/udp/prot_eng_rx.v b/usrp2/udp/prot_eng_rx.v
new file mode 100644
index 000000000..5df158b2b
--- /dev/null
+++ b/usrp2/udp/prot_eng_rx.v
@@ -0,0 +1,121 @@
+
+
+
+// Protocol Engine Receiver
+// Checks each line (16 bits) against values in setting regs
+// 3 options for each line --
+// Error if mismatch, Slowpath if mismatch, or ignore line
+// The engine increases the length of each packet by 32 or 48 bits,
+// bringing the total length to a multiple of 32 bits. The last line
+// is entirely new, and contains the results of the matching operation:
+// 16 bits of flags, 16 bits of data. Flags indicate error or slowpath
+// Data indicates line that caused mismatch if any.
+
+
+// Flags[2:0] is {occ, eop, sop}
+// Protocol word format is:
+// 22 Last Header Line
+// 21 SLOWPATH if mismatch
+// 20 ERROR if mismatch
+// 19 This is the IP checksum
+// 18 This is the UDP checksum
+// 17 Compute IP checksum on this word
+// 16 Compute UDP checksum on this word
+// 15:0 data word to be matched
+
+module prot_eng_rx
+ #(parameter BASE=0)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input [18:0] datain, input src_rdy_i, output dst_rdy_o,
+ output [18:0] dataout, output src_rdy_o, input dst_rdy_i);
+
+ localparam HDR_WIDTH = 16 + 7; // 16 bits plus flags
+ localparam HDR_LEN = 32; // Up to 64 bytes of protocol
+
+ // Store header values in a small dual-port (distributed) ram
+ reg [HDR_WIDTH-1:0] header_ram[0:HDR_LEN-1];
+ wire [HDR_WIDTH-1:0] header_word;
+
+ always @(posedge clk)
+ if(set_stb & ((set_addr & 8'hE0) == BASE))
+ header_ram[set_addr[4:0]] <= set_data;
+
+ assign header_word = header_ram[state];
+
+ wire consume_input = src_rdy_i & dst_rdy_o;
+ wire produce_output = src_rdy_o & dst_rdy_i;
+
+ // Main State Machine
+ reg [15:0] pkt_length, fail_word, dataout_int;
+
+ reg slowpath, error, sof_o, eof_o, occ_o, odd;
+
+ assign dataout = {occ_o, eof_o, sof_o, dataout_int};
+
+ wire [15:0] calc_ip_checksum, calc_udp_checksum;
+ reg [15:0] rx_ip_checksum, rx_udp_checksum;
+
+ always @(posedge clk)
+ if(header_word[19])
+ rx_ip_checksum <= datain[15:0];
+ always @(posedge clk)
+ if(header_word[18])
+ rx_udp_checksum <= datain[15:0];
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ slowpath <= 0;
+ error <= 0;
+ state <= 0;
+ fail_word <= 0;
+ eof_o <= 0;
+ occ_o <= 0;
+ end
+ else if(src_rdy_i & dst_rdy_i)
+ case (state)
+ 0 :
+ begin
+ slowpath <= 0;
+ error <= 0;
+ eof_o <= 0;
+ occ_o <= 0;
+ state <= 1;
+ end
+
+ ST_SLOWPATH :
+ ;
+ ST_ERROR :
+ ;
+ ST_PAYLOAD :
+ ;
+ ST_FILLER :
+ ;
+ ST_END1 :
+ ;
+ ST_END2 :
+ ;
+ default :
+ if(header_word[21] && mismatch)
+ state <= ST_SLOWPATH;
+ else if(header_word[20] && mismatch)
+ state <= ST_ERROR;
+ else if(header_word[22])
+ state <= ST_PAYLOAD;
+ else
+ state <= state + 1;
+ endcase // case (state)
+
+
+
+ // IP + UDP checksum state machines
+ checksum_sm ip_chk
+ (.clk(clk), .reset(reset), .in(datain),
+ .calc(consume_input & header_word[17]), .clear(state==0), .checksum(ip_checksum));
+
+ checksum_sm udp_chk
+ (.clk(clk), .reset(reset), .in(datain),
+ .calc(consume_input & header_word[16]), .clear(state==0), .checksum(udp_checksum));
+
+endmodule // prot_eng_rx
diff --git a/usrp2/udp/prot_eng_tx.v b/usrp2/udp/prot_eng_tx.v
new file mode 100644
index 000000000..9031011f7
--- /dev/null
+++ b/usrp2/udp/prot_eng_tx.v
@@ -0,0 +1,119 @@
+
+// The input FIFO contents should be 16 bits wide
+// The first word is 1 for fast path (accelerated protocol)
+// 0 for software implemented protocol
+// The second word is the number of bytes in the packet,
+// and must be valid even if we are in slow path mode
+// Odd means the last word is half full
+// Flags[1:0] is {eop, sop}
+// Protocol word format is:
+// 19 Last Header Line
+// 18 IP Header Checksum XOR
+// 17 IP Length Here
+// 16 UDP Length Here
+// 15:0 data word to be sent
+
+module prot_eng_tx
+ #(parameter BASE=0)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input [18:0] datain, input src_rdy_i, output dst_rdy_o,
+ output [18:0] dataout, output src_rdy_o, input dst_rdy_i);
+
+ wire [2:0] flags_i = datain[18:16];
+ reg [15:0] dataout_int;
+ reg fast_path, sof_o;
+
+ wire [2:0] flags_o = {flags_i[2], flags_i[1], sof_o}; // OCC, EOF, SOF
+
+ assign dataout = {flags_o[2:0], dataout_int[15:0]};
+
+ reg [4:0] state;
+ wire do_payload = (state == 31);
+
+ assign dst_rdy_o = dst_rdy_i & (do_payload | (state==0) | (state==1) | (state==30));
+ assign src_rdy_o = src_rdy_i & ~((state==0) | (state==1) | (state==30));
+
+ localparam HDR_WIDTH = 16 + 4; // 16 bits plus flags
+ localparam HDR_LEN = 32; // Up to 64 bytes of protocol
+
+ // Store header values in a small dual-port (distributed) ram
+ reg [HDR_WIDTH-1:0] header_ram[0:HDR_LEN-1];
+ wire [HDR_WIDTH-1:0] header_word;
+
+ always @(posedge clk)
+ if(set_stb & ((set_addr & 8'hE0) == BASE))
+ header_ram[set_addr[4:0]] <= set_data;
+
+ assign header_word = header_ram[state];
+
+ wire last_hdr_line = header_word[19];
+ wire ip_chk = header_word[18];
+ wire ip_len = header_word[17];
+ wire udp_len = header_word[16];
+
+ // Protocol State Machine
+ reg [15:0] length;
+ wire [15:0] ip_length = length + 28; // IP HDR + UDP HDR
+ wire [15:0] udp_length = length + 8; // UDP HDR
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ state <= 0;
+ fast_path <= 0;
+ sof_o <= 0;
+ end
+ else
+ if(src_rdy_i & dst_rdy_i)
+ case(state)
+ 0 :
+ begin
+ fast_path <= datain[0];
+ state <= 1;
+ end
+ 1 :
+ begin
+ length <= datain[15:0];
+ sof_o <= 1;
+ if(fast_path)
+ state <= 2;
+ else
+ state <= 30; // Skip 1 word for alignment
+ end
+ 30 :
+ state <= 31;
+ 31 :
+ begin
+ sof_o <= 0;
+ if(flags_i[1]) // eop
+ state <= 0;
+ end
+ default :
+ begin
+ sof_o <= 0;
+ if(~last_hdr_line)
+ state <= state + 1;
+ else
+ state <= 31;
+ end
+ endcase // case (state)
+
+ wire [15:0] checksum;
+ add_onescomp #(.WIDTH(16)) add_onescomp
+ (.A(header_word[15:0]),.B(ip_length),.SUM(checksum));
+
+ always @*
+ if(ip_chk)
+ //dataout_int <= header_word[15:0] ^ ip_length;
+ dataout_int <= 16'hFFFF ^ checksum;
+ else if(ip_len)
+ dataout_int <= ip_length;
+ else if(udp_len)
+ dataout_int <= udp_length;
+ else if(do_payload)
+ dataout_int <= datain[15:0];
+ else
+ dataout_int <= header_word[15:0];
+
+endmodule // prot_eng_tx
diff --git a/usrp2/udp/prot_eng_tx_tb.v b/usrp2/udp/prot_eng_tx_tb.v
new file mode 100644
index 000000000..e7ffeb5e1
--- /dev/null
+++ b/usrp2/udp/prot_eng_tx_tb.v
@@ -0,0 +1,167 @@
+module prot_eng_tx_tb();
+
+ localparam BASE = 128;
+ reg clk = 0;
+ reg rst = 1;
+ reg clear = 0;
+ initial #1000 rst = 0;
+ always #50 clk = ~clk;
+
+ reg [31:0] f36_data;
+ reg [1:0] f36_occ;
+ reg f36_sof, f36_eof;
+
+ wire [35:0] f36_in = {f36_occ,f36_eof,f36_sof,f36_data};
+ reg src_rdy_f36i = 0;
+ reg [15:0] count;
+
+ wire [35:0] casc_do;
+ wire [18:0] final_out, prot_out;
+
+ wire src_rdy_final, dst_rdy_final, src_rdy_prot;
+ reg dst_rdy_prot =0;
+
+ wire dst_rdy_f36o ;
+ fifo_long #(.WIDTH(36), .SIZE(4)) fifo_cascade36
+ (.clk(clk),.reset(rst),.clear(clear),
+ .datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i),
+ .dataout(casc_do),.src_rdy_o(src_rdy_f36o),.dst_rdy_i(dst_rdy_f36o));
+
+ fifo36_to_fifo19 fifo_converter
+ (.clk(clk),.reset(rst),.clear(clear),
+ .f36_datain(casc_do),.f36_src_rdy_i(src_rdy_f36o),.f36_dst_rdy_o(dst_rdy_f36o),
+ .f19_dataout(final_out),.f19_src_rdy_o(src_rdy_final),.f19_dst_rdy_i(dst_rdy_final));
+
+ reg set_stb;
+ reg [7:0] set_addr;
+ reg [31:0] set_data;
+
+ prot_eng_tx #(.BASE(BASE)) prot_eng_tx
+ (.clk(clk), .reset(rst),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .datain(final_out[18:0]),.src_rdy_i(src_rdy_final),.dst_rdy_o(dst_rdy_final),
+ .dataout(prot_out[18:0]),.src_rdy_o(src_rdy_prot),.dst_rdy_i(dst_rdy_prot));
+
+ reg [35:0] printer;
+
+ task WriteSREG;
+ input [7:0] addr;
+ input [31:0] data;
+
+ begin
+ @(posedge clk);
+ set_addr <= addr;
+ set_data <= data;
+ set_stb <= 1;
+ @(posedge clk);
+ set_stb <= 0;
+ end
+ endtask // WriteSREG
+
+ task ReadFromFIFO36;
+ begin
+ $display("Read from FIFO36");
+ #1 dst_rdy_prot <= 1;
+ while(~src_rdy_prot)
+ @(posedge clk);
+ while(1)
+ begin
+ while(~src_rdy_prot)
+ @(posedge clk);
+ $display("Read: %h",prot_out);
+ @(posedge clk);
+ end
+ end
+ endtask // ReadFromFIFO36
+
+ task PutPacketInFIFO36;
+ input [31:0] data_start;
+ input [31:0] data_len;
+ begin
+ count <= 4;
+ src_rdy_f36i <= 1;
+ f36_data <= 32'h0001_000c;
+ f36_sof <= 1;
+ f36_eof <= 0;
+ f36_occ <= 0;
+
+ $display("Put Packet in FIFO36");
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ $display("PPI_FIFO36: Entered First Line");
+ f36_sof <= 0;
+ f36_data <= data_start;
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ while(count+4 < data_len)
+ begin
+ f36_data <= f36_data + 32'h01010101;
+ count <= count + 4;
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ $display("PPI_FIFO36: Entered New Line");
+ end
+ f36_data <= f36_data + 32'h01010101;
+ f36_eof <= 1;
+ if(count + 4 == data_len)
+ f36_occ <= 0;
+ else if(count + 3 == data_len)
+ f36_occ <= 3;
+ else if(count + 2 == data_len)
+ f36_occ <= 2;
+ else
+ f36_occ <= 1;
+ while(~dst_rdy_f36i)
+ @(posedge clk);
+ @(posedge clk);
+ f36_occ <= 0;
+ f36_eof <= 0;
+ f36_data <= 0;
+ src_rdy_f36i <= 0;
+ $display("PPI_FIFO36: Entered Last Line");
+ end
+ endtask // PutPacketInFIFO36
+
+ initial $dumpfile("prot_eng_tx_tb.vcd");
+ initial $dumpvars(0,prot_eng_tx_tb);
+
+ initial
+ begin
+ #10000;
+ @(posedge clk);
+ ReadFromFIFO36;
+ end
+
+ initial
+ begin
+ @(negedge rst);
+ @(posedge clk);
+ WriteSREG(BASE, {12'b0, 4'h0, 16'h0000});
+ WriteSREG(BASE+1, {12'b0, 4'h0, 16'h0000});
+ WriteSREG(BASE+2, {12'b0, 4'h0, 16'hABCD});
+ WriteSREG(BASE+3, {12'b0, 4'h0, 16'h1234});
+ WriteSREG(BASE+4, {12'b0, 4'h8, 16'h5678});
+ WriteSREG(BASE+5, {12'b0, 4'h0, 16'hABCD});
+ WriteSREG(BASE+6, {12'b0, 4'h0, 16'hABCD});
+ WriteSREG(BASE+7, {12'b0, 4'h0, 16'hABCD});
+ WriteSREG(BASE+8, {12'b0, 4'h0, 16'hABCD});
+ WriteSREG(BASE+9, {12'b0, 4'h0, 16'hABCD});
+ @(posedge clk);
+ PutPacketInFIFO36(32'hA0B0C0D0,16);
+ @(posedge clk);
+ @(posedge clk);
+ #10000;
+ @(posedge clk);
+ PutPacketInFIFO36(32'hE0F0A0B0,36);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end
+
+ initial #20000 $finish;
+endmodule // prot_eng_tx_tb
diff --git a/usrp2/udp/udp_wrapper.v b/usrp2/udp/udp_wrapper.v
new file mode 100644
index 000000000..f4c642615
--- /dev/null
+++ b/usrp2/udp/udp_wrapper.v
@@ -0,0 +1,92 @@
+
+module udp_wrapper
+ #(parameter BASE=0)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input [18:0] rx_f19_data, input rx_f19_src_rdy_i, output rx_f19_dst_rdy_o,
+ output [18:0] tx_f19_data, output tx_f19_src_rdy_o, input tx_f19_dst_rdy_i,
+
+ output [35:0] rx_f36_data, output rx_f36_src_rdy_o, input rx_f36_dst_rdy_i,
+ input [35:0] tx_f36_data, input tx_f36_src_rdy_i, output tx_f36_dst_rdy_o,
+ output [31:0] debug
+ );
+
+ wire tx_int1_src_rdy, tx_int1_dst_rdy;
+ wire [18:0] tx_int1_data;
+
+ wire tx_int2_src_rdy, tx_int2_dst_rdy;
+ wire [18:0] tx_int2_data;
+ wire [31:0] debug_state;
+
+ // TX side
+ fifo36_to_fifo19 fifo36_to_fifo19
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f36_datain(tx_f36_data), .f36_src_rdy_i(tx_f36_src_rdy_i), .f36_dst_rdy_o(tx_f36_dst_rdy_o),
+ .f19_dataout(tx_int1_data), .f19_src_rdy_o(tx_int1_src_rdy), .f19_dst_rdy_i(tx_int1_dst_rdy) );
+
+ fifo_short #(.WIDTH(19)) shortfifo19_a
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(tx_int1_data), .src_rdy_i(tx_int1_src_rdy), .dst_rdy_o(tx_int1_dst_rdy),
+ .dataout(tx_int2_data), .src_rdy_o(tx_int2_src_rdy), .dst_rdy_i(tx_int2_dst_rdy),
+ .space(), .occupied() );
+
+ prot_eng_tx #(.BASE(BASE)) prot_eng_tx
+ (.clk(clk), .reset(reset), .clear(clear),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .datain(tx_int2_data), .src_rdy_i(tx_int2_src_rdy), .dst_rdy_o(tx_int2_dst_rdy),
+ .dataout(tx_f19_data), .src_rdy_o(tx_f19_src_rdy_o), .dst_rdy_i(tx_f19_dst_rdy_i) );
+
+ // RX side
+ wire rx_int1_src_rdy, rx_int1_dst_rdy;
+ wire [18:0] rx_int1_data;
+
+ wire rx_int2_src_rdy, rx_int2_dst_rdy;
+ wire [18:0] rx_int2_data;
+
+ //wire rx_int3_src_rdy, rx_int3_dst_rdy;
+ //wire [35:0] rx_int3_data;
+
+`ifdef USE_PROT_ENG
+ prot_eng_rx #(.BASE(BASE+32)) prot_eng_rx
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy_i), .dst_rdy_o(rx_f19_dst_rdy_o),
+ .dataout(rx_int1_data), .src_rdy_o(rx_int1_src_rdy), .dst_rdy_i(rx_int1_dst_rdy) );
+`else
+ fifo19_rxrealign fifo19_rxrealign
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy_i), .dst_rdy_o(rx_f19_dst_rdy_o),
+ .dataout(rx_int1_data), .src_rdy_o(rx_int1_src_rdy), .dst_rdy_i(rx_int1_dst_rdy) );
+`endif // !`ifdef USE_PROT_ENG
+
+ fifo_short #(.WIDTH(19)) shortfifo19_b
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(rx_int1_data), .src_rdy_i(rx_int1_src_rdy), .dst_rdy_o(rx_int1_dst_rdy),
+ .dataout(rx_int2_data), .src_rdy_o(rx_int2_src_rdy), .dst_rdy_i(rx_int2_dst_rdy),
+ .space(), .occupied() );
+
+ fifo19_to_fifo36 fifo19_to_fifo36
+ (.clk(clk), .reset(reset), .clear(clear),
+ .f19_datain(rx_int2_data), .f19_src_rdy_i(rx_int2_src_rdy), .f19_dst_rdy_o(rx_int2_dst_rdy),
+ .f36_dataout(rx_f36_data), .f36_src_rdy_o(rx_f36_src_rdy_o), .f36_dst_rdy_i(rx_f36_dst_rdy_i),
+ .debug(debug_state));
+
+ /*
+ fifo_cascade #(.WIDTH(36),.SIZE(RXFIFOSIZE)) eth0_rxfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(rx_int3_data), .src_rdy_i(rx_int3_src_rdy), .dst_rdy_o(rx_int3_dst_rdy),
+ .dataout(rx_f36_data), .src_rdy_o(rx_f36_src_rdy_o), .dst_rdy_i(rx_f36_dst_rdy_i),
+ .space(), .occupied() );
+*/
+ /*
+ assign debug = { { 1'b0, rx_f19_data[18:16], rx_f19_src_rdy_i, rx_f19_dst_rdy_o, rx_f36_src_rdy_o, rx_f36_dst_rdy_i },
+ { 2'b0, rx_int1_src_rdy, rx_int1_dst_rdy, rx_int2_src_rdy, rx_int2_dst_rdy, rx_int3_src_rdy, rx_int3_dst_rdy},
+ { rx_int3_data[35:32], rx_f36_data[35:32] },
+ { debug_state[1:0], rx_int1_data[18:16], rx_int2_data[18:16] } };
+ */
+
+ assign debug = { { 3'd0, tx_int1_src_rdy, tx_int1_dst_rdy, tx_int1_data[18:16] },
+ { 3'd0, tx_int2_src_rdy, tx_int2_dst_rdy, tx_int2_data[18:16] },
+ { tx_int2_data[15:8] },
+ { tx_int2_data[7:0] } };
+
+endmodule // udp_wrapper
diff --git a/usrp2/vrt/.gitignore b/usrp2/vrt/.gitignore
new file mode 100644
index 000000000..446b2daae
--- /dev/null
+++ b/usrp2/vrt/.gitignore
@@ -0,0 +1,4 @@
+vita_rx_tb
+vita_tx_tb
+*.vcd
+*.sav
diff --git a/usrp2/vrt/vita_rx.build b/usrp2/vrt/vita_rx.build
new file mode 100755
index 000000000..f6d2d75a3
--- /dev/null
+++ b/usrp2/vrt/vita_rx.build
@@ -0,0 +1 @@
+iverilog -Wimplict -Wportbind -y ../models -y . -y ../control_lib/ -y ../control_lib/newfifo -y ../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -y ../timing -o vita_rx_tb vita_rx_tb.v
diff --git a/usrp2/vrt/vita_rx_control.v b/usrp2/vrt/vita_rx_control.v
new file mode 100644
index 000000000..669b8299d
--- /dev/null
+++ b/usrp2/vrt/vita_rx_control.v
@@ -0,0 +1,180 @@
+
+module vita_rx_control
+ #(parameter BASE=0,
+ parameter WIDTH=32)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ input [63:0] vita_time,
+ output overrun,
+
+ // To vita_rx_framer
+ output [4+64+WIDTH-1:0] sample_fifo_o,
+ output sample_fifo_src_rdy_o,
+ input sample_fifo_dst_rdy_i,
+
+ // From DSP Core
+ input [WIDTH-1:0] sample,
+ output run,
+ input strobe,
+
+ output [31:0] debug_rx
+ );
+
+ // FIXME add TX Interruption (halt, pause, continue) functionality
+
+ wire [63:0] new_time;
+ wire [31:0] new_command;
+ wire sc_pre1, clear_int, clear_reg;
+
+ assign clear_int = clear | clear_reg;
+
+ wire [63:0] rcvtime_pre;
+ reg [63:0] rcvtime;
+ wire [29:0] numlines_pre;
+ wire send_imm_pre, chain_pre;
+ reg send_imm, chain;
+ wire full_ctrl, read_ctrl, empty_ctrl, write_ctrl;
+ reg sc_pre2;
+ wire [33:0] fifo_line;
+ reg [29:0] lines_left;
+ reg [2:0] ibs_state;
+ wire now, early, late;
+ wire sample_fifo_in_rdy;
+
+ setting_reg #(.my_addr(BASE)) sr_cmd
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(new_command),.changed());
+
+ setting_reg #(.my_addr(BASE+1)) sr_time_h
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(new_time[63:32]),.changed());
+
+ setting_reg #(.my_addr(BASE+2)) sr_time_l
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(new_time[31:0]),.changed(sc_pre1));
+
+ setting_reg #(.my_addr(BASE+3)) sr_clear
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear_reg));
+
+ // FIFO to store commands sent from the settings bus
+ always @(posedge clk)
+ sc_pre2 <= sc_pre1;
+ assign write_ctrl = sc_pre1 & ~sc_pre2;
+
+ wire [4:0] command_queue_len;
+ shortfifo #(.WIDTH(96)) commandfifo
+ (.clk(clk),.rst(reset),.clear(clear_int),
+ .datain({new_command,new_time}), .write(write_ctrl&~full_ctrl), .full(full_ctrl),
+ .dataout({send_imm_pre,chain_pre,numlines_pre,rcvtime_pre}),
+ .read(read_ctrl), .empty(empty_ctrl),
+ .occupied(command_queue_len), .space() );
+
+ reg [33:0] pkt_fifo_line;
+
+ localparam IBS_IDLE = 0;
+ localparam IBS_WAITING = 1;
+ localparam IBS_RUNNING = 2;
+ localparam IBS_OVERRUN = 4;
+ localparam IBS_BROKENCHAIN = 5;
+ localparam IBS_LATECMD = 6;
+
+ wire signal_cmd_done = (lines_left == 1) & (~chain | (~empty_ctrl & (numlines_pre==0)));
+ wire signal_overrun = (ibs_state == IBS_OVERRUN);
+ wire signal_brokenchain = (ibs_state == IBS_BROKENCHAIN);
+ wire signal_latecmd = (ibs_state == IBS_LATECMD);
+
+ // Buffer of samples for while we're writing the packet headers
+ wire [3:0] flags = {signal_overrun,signal_brokenchain,signal_latecmd,signal_cmd_done};
+
+ wire attempt_sample_write = ((run & strobe) | (ibs_state==IBS_OVERRUN) |
+ (ibs_state==IBS_BROKENCHAIN) | (ibs_state==IBS_LATECMD));
+
+ fifo_short #(.WIDTH(4+64+WIDTH)) rx_sample_fifo
+ (.clk(clk),.reset(reset),.clear(clear_int),
+ .datain({flags,vita_time,sample}), .src_rdy_i(attempt_sample_write), .dst_rdy_o(sample_fifo_in_rdy),
+ .dataout(sample_fifo_o),
+ .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i),
+ .space(), .occupied() );
+
+ // Inband Signalling State Machine
+ time_compare
+ time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late));
+
+ wire too_late = late & ~send_imm;
+ wire go_now = now | send_imm;
+ wire full = ~sample_fifo_in_rdy;
+
+ always @(posedge clk)
+ if(reset | clear_int)
+ begin
+ ibs_state <= IBS_IDLE;
+ lines_left <= 0;
+ rcvtime <= 0;
+ send_imm <= 0;
+ chain <= 0;
+ end
+ else
+ case(ibs_state)
+ IBS_IDLE :
+ if(~empty_ctrl)
+ begin
+ lines_left <= numlines_pre;
+ rcvtime <= rcvtime_pre;
+ ibs_state <= IBS_WAITING;
+ send_imm <= send_imm_pre;
+ chain <= chain_pre;
+ end
+ IBS_WAITING :
+ if(go_now)
+ ibs_state <= IBS_RUNNING;
+ else if(too_late)
+ ibs_state <= IBS_LATECMD;
+ IBS_RUNNING :
+ if(strobe)
+ if(full)
+ ibs_state <= IBS_OVERRUN;
+ else
+ begin
+ lines_left <= lines_left - 1;
+ if(lines_left == 1)
+ if(~chain)
+ ibs_state <= IBS_IDLE;
+ else if(empty_ctrl)
+ ibs_state <= IBS_BROKENCHAIN;
+ else
+ begin
+ lines_left <= numlines_pre;
+ rcvtime <= rcvtime_pre;
+ send_imm <= send_imm_pre;
+ chain <= chain_pre;
+ if(numlines_pre == 0) // If we are told to stop here
+ ibs_state <= IBS_IDLE;
+ else
+ ibs_state <= IBS_RUNNING;
+ end
+ end // else: !if(full)
+ IBS_OVERRUN :
+ if(sample_fifo_in_rdy)
+ ibs_state <= IBS_IDLE;
+ IBS_LATECMD :
+ if(sample_fifo_in_rdy)
+ ibs_state <= IBS_IDLE;
+ IBS_BROKENCHAIN :
+ if(sample_fifo_in_rdy)
+ ibs_state <= IBS_IDLE;
+ endcase // case(ibs_state)
+
+ assign overrun = (ibs_state == IBS_OVERRUN);
+ assign run = (ibs_state == IBS_RUNNING);
+
+ assign read_ctrl = ( (ibs_state == IBS_IDLE) | ((ibs_state == IBS_RUNNING) & strobe & ~full & (lines_left==1) & chain) )
+ & ~empty_ctrl;
+
+ assign debug_rx = { { ibs_state[2:0], command_queue_len },
+ { 8'd0 },
+ { go_now, too_late, run, strobe, read_ctrl, write_ctrl, full_ctrl, empty_ctrl },
+ { 2'b0, overrun, chain_pre, sample_fifo_in_rdy, attempt_sample_write, sample_fifo_src_rdy_o,sample_fifo_dst_rdy_i} };
+
+endmodule // rx_control
diff --git a/usrp2/vrt/vita_rx_framer.v b/usrp2/vrt/vita_rx_framer.v
new file mode 100644
index 000000000..f3a81664a
--- /dev/null
+++ b/usrp2/vrt/vita_rx_framer.v
@@ -0,0 +1,199 @@
+
+module vita_rx_framer
+ #(parameter BASE=0,
+ parameter MAXCHAN=1)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ // To FIFO interface of Buffer Pool
+ output [35:0] data_o,
+ input dst_rdy_i,
+ output src_rdy_o,
+
+ // From vita_rx_control
+ input [4+64+(32*MAXCHAN)-1:0] sample_fifo_i,
+ input sample_fifo_src_rdy_i,
+ output sample_fifo_dst_rdy_o,
+
+ // FIFO Levels
+ output [15:0] fifo_occupied,
+ output fifo_full,
+ output fifo_empty,
+
+ output [31:0] debug_rx
+ );
+
+ localparam SAMP_WIDTH = 4+64+(32*MAXCHAN);
+ reg [3:0] sample_phase;
+ wire [3:0] numchan;
+ wire [3:0] flags_fifo_o = sample_fifo_i[SAMP_WIDTH-1:SAMP_WIDTH-4];
+ wire [63:0] vita_time_fifo_o = sample_fifo_i[SAMP_WIDTH-5:SAMP_WIDTH-68];
+
+ reg [31:0] data_fifo_o;
+
+ // The tools won't synthesize properly without this kludge because of the variable
+ // parameter length
+
+ wire [127:0] FIXED_WIDTH_KLUDGE = sample_fifo_i;
+ always @*
+ case(sample_phase)
+ 4'd0 : data_fifo_o = FIXED_WIDTH_KLUDGE[31:0];
+ 4'd1 : data_fifo_o = FIXED_WIDTH_KLUDGE[63:32];
+ 4'd2 : data_fifo_o = FIXED_WIDTH_KLUDGE[95:64];
+ 4'd3 : data_fifo_o = FIXED_WIDTH_KLUDGE[127:96];
+ default : data_fifo_o = 32'hDEADBEEF;
+ endcase // case (sample_phase)
+
+ wire clear_pkt_count, pkt_fifo_rdy, sample_fifo_in_rdy;
+
+ wire [31:0] vita_header, vita_streamid, vita_trailer;
+ wire [15:0] samples_per_packet;
+
+ reg [33:0] pkt_fifo_line;
+ reg [3:0] vita_state;
+ reg [15:0] sample_ctr;
+ reg [3:0] pkt_count;
+
+ wire [15:0] vita_pkt_len = samples_per_packet + 6;
+ //wire [3:0] flags = {signal_overrun,signal_brokenchain,signal_latecmd,signal_cmd_done};
+
+ wire clear_reg;
+ wire clear_int = clear | clear_reg;
+
+ setting_reg #(.my_addr(BASE+3)) sr_clear
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear_reg));
+
+ setting_reg #(.my_addr(BASE+4)) sr_header
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(vita_header),.changed());
+
+ setting_reg #(.my_addr(BASE+5)) sr_streamid
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(vita_streamid),.changed(clear_pkt_count));
+
+ setting_reg #(.my_addr(BASE+6)) sr_trailer
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(vita_trailer),.changed());
+
+ setting_reg #(.my_addr(BASE+7)) sr_samples_per_pkt
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(samples_per_packet),.changed());
+
+ setting_reg #(.my_addr(BASE+8), .at_reset(1)) sr_numchan
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(numchan),.changed());
+
+ // Output FIFO for packetized data
+ localparam VITA_IDLE = 0;
+ localparam VITA_HEADER = 1;
+ localparam VITA_STREAMID = 2;
+ localparam VITA_SECS = 3;
+ localparam VITA_TICS = 4;
+ localparam VITA_TICS2 = 5;
+ localparam VITA_PAYLOAD = 6;
+ localparam VITA_TRAILER = 7;
+ localparam VITA_ERR_HEADER = 9; // All ERR at 4'b1000 or'ed with base
+ localparam VITA_ERR_STREAMID = 10;
+ localparam VITA_ERR_SECS = 11;
+ localparam VITA_ERR_TICS = 12;
+ localparam VITA_ERR_TICS2 = 13;
+ localparam VITA_ERR_PAYLOAD = 14;
+ localparam VITA_ERR_TRAILER = 15;
+
+ always @(posedge clk)
+ if(reset | clear_pkt_count)
+ pkt_count <= 0;
+ else if((vita_state == VITA_TRAILER) & pkt_fifo_rdy)
+ pkt_count <= pkt_count + 1;
+
+ always @*
+ case(vita_state)
+ VITA_HEADER, VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,vita_header[31:20],pkt_count,vita_pkt_len};
+ VITA_STREAMID, VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
+ VITA_SECS, VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
+ VITA_TICS, VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0};
+ VITA_TICS2, VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
+ VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o};
+ VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b00,28'd0,flags_fifo_o};
+ VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer};
+ VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer};
+ default : pkt_fifo_line <= 34'h0_FFFF_FFFF;
+ endcase // case (vita_state)
+
+ always @(posedge clk)
+ if(reset)
+ begin
+ vita_state <= VITA_IDLE;
+ sample_ctr <= 0;
+ sample_phase <= 0;
+ end
+ else
+ if(vita_state==VITA_IDLE)
+ begin
+ sample_ctr <= 1;
+ sample_phase <= 0;
+ if(sample_fifo_src_rdy_i)
+ if(|flags_fifo_o[3:1])
+ vita_state <= VITA_ERR_HEADER;
+ else
+ vita_state <= VITA_HEADER;
+ end
+ else if(pkt_fifo_rdy)
+ case(vita_state)
+ VITA_PAYLOAD :
+ if(sample_fifo_src_rdy_i)
+ begin
+ if(sample_phase == (numchan-4'd1))
+ begin
+ sample_phase <= 0;
+ sample_ctr <= sample_ctr + 1;
+ if(sample_ctr == samples_per_packet)
+ vita_state <= VITA_TRAILER;
+ if(|flags_fifo_o) // end early if any flag is set
+ vita_state <= VITA_TRAILER;
+ end
+ else
+ sample_phase <= sample_phase + 1;
+ end
+ VITA_TRAILER, VITA_ERR_TRAILER :
+ vita_state <= VITA_IDLE;
+ default :
+ vita_state <= vita_state + 1;
+ endcase // case (vita_state)
+
+ reg req_write_pkt_fifo;
+ always @*
+ case(vita_state)
+ VITA_IDLE :
+ req_write_pkt_fifo <= 0;
+ VITA_HEADER, VITA_STREAMID, VITA_SECS, VITA_TICS, VITA_TICS2, VITA_TRAILER :
+ req_write_pkt_fifo <= 1;
+ VITA_PAYLOAD :
+ // Write if sample ready and no error flags
+ req_write_pkt_fifo <= (sample_fifo_src_rdy_i & ~|flags_fifo_o[3:1]);
+ VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD, VITA_ERR_TRAILER :
+ req_write_pkt_fifo <= 1;
+ default :
+ req_write_pkt_fifo <= 0;
+ endcase // case (vita_state)
+
+ //wire req_write_pkt_fifo = (vita_state != VITA_IDLE) & (sample_fifo_src_rdy_i | (vita_state != VITA_PAYLOAD));
+
+ // Short FIFO to buffer between us and the FIFOs outside
+ fifo_short #(.WIDTH(34)) rx_pkt_fifo
+ (.clk(clk), .reset(reset), .clear(clear_int),
+ .datain(pkt_fifo_line), .src_rdy_i(req_write_pkt_fifo), .dst_rdy_o(pkt_fifo_rdy),
+ .dataout(data_o[33:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i),
+ .space(),.occupied(fifo_occupied[4:0]) );
+ assign fifo_occupied[15:5] = 0;
+ assign data_o[35:34] = 2'b00; // Always write full lines
+ assign sample_fifo_dst_rdy_o = pkt_fifo_rdy &
+ ( ((vita_state==VITA_PAYLOAD) &
+ (sample_phase == (numchan-4'd1)) &
+ ~|flags_fifo_o[3:1]) |
+ (vita_state==VITA_ERR_TRAILER));
+
+ assign debug_rx = vita_state;
+
+endmodule // rx_control
diff --git a/usrp2/vrt/vita_rx_tb.v b/usrp2/vrt/vita_rx_tb.v
new file mode 100644
index 000000000..b4fda9622
--- /dev/null
+++ b/usrp2/vrt/vita_rx_tb.v
@@ -0,0 +1,213 @@
+
+
+module vita_rx_tb;
+
+ localparam DECIM = 8'd4;
+ localparam MAXCHAN=4;
+ localparam NUMCHAN=4;
+
+ reg clk = 0;
+ reg reset = 1;
+
+ initial #1000 reset = 0;
+ always #50 clk = ~clk;
+
+ initial $dumpfile("vita_rx_tb.vcd");
+ initial $dumpvars(0,vita_rx_tb);
+
+ wire [(MAXCHAN*32)-1:0] sample;
+ wire strobe, run;
+ wire [35:0] data_o;
+ wire src_rdy;
+ reg dst_rdy = 1;
+ wire [63:0] vita_time;
+
+ reg set_stb = 0;
+ reg [7:0] set_addr;
+ reg [31:0] set_data;
+ wire set_stb_dsp;
+ wire [7:0] set_addr_dsp;
+ wire [31:0] set_data_dsp;
+
+ /*
+ settings_bus_crossclock settings_bus_xclk_dsp
+ (.clk_i(clk), .rst_i(reset), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data),
+ .clk_o(clk), .rst_o(reset), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp));
+ */
+
+ wire sample_dst_rdy, sample_src_rdy;
+ //wire [99:0] sample_data_o;
+ wire [64+4+(MAXCHAN*32)-1:0] sample_data_o;
+
+ vita_rx_control #(.BASE(0), .WIDTH(32*MAXCHAN)) vita_rx_control
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .vita_time(vita_time), .overrun(overrun),
+ .sample_fifo_o(sample_data_o), .sample_fifo_dst_rdy_i(sample_dst_rdy), .sample_fifo_src_rdy_o(sample_src_rdy),
+ .sample(sample), .run(run), .strobe(strobe));
+
+ vita_rx_framer #(.BASE(0), .MAXCHAN(MAXCHAN)) vita_rx_framer
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .data_o(data_o), .dst_rdy_i(dst_rdy), .src_rdy_o(src_rdy),
+ .sample_fifo_i(sample_data_o), .sample_fifo_dst_rdy_o(sample_dst_rdy), .sample_fifo_src_rdy_i(sample_src_rdy),
+ .fifo_occupied(), .fifo_full(), .fifo_empty() );
+
+ rx_dsp_model rx_dsp_model
+ (.clk(clk), .reset(reset), .run(run), .decim(DECIM), .strobe(strobe), .sample(sample[31:0]));
+
+ generate
+ if(MAXCHAN>1)
+ assign sample[(MAXCHAN*32)-1:32] = 0;
+ endgenerate
+
+ time_64bit #(.TICKS_PER_SEC(120000000), .BASE(0)) time_64bit
+ (.clk(clk), .rst(reset),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .pps(0), .vita_time(vita_time));
+
+ always @(posedge clk)
+ if(src_rdy & dst_rdy)
+ begin
+ if(data_o[32] & ~data_o[33])
+ begin
+ $display("RX-PKT-START %d",$time);
+ $display(" RX-PKT-DAT %x",data_o[31:0]);
+ end
+ else if(data_o[32] & data_o[33])
+ begin
+ $display(" RX-PKT-DAT %x -- With ERR",data_o[31:0]);
+ $display("RX-PKT-ERR %d",$time);
+ end
+ else if(~data_o[32] & data_o[33])
+ begin
+ $display(" RX-PKT-DAT %x",data_o[31:0]);
+ $display("RX-PKT-END %d",$time);
+ end
+ else
+ $display(" RX-PKT DAT %x",data_o[31:0]);
+ end
+
+ initial
+ begin
+ @(negedge reset);
+ @(posedge clk);
+ write_setting(4,32'hDEADBEEF); // VITA header
+ write_setting(5,32'hF00D1234); // VITA streamid
+ write_setting(6,32'h98765432); // VITA trailer
+ write_setting(7,8); // Samples per VITA packet
+ write_setting(8,NUMCHAN); // Samples per VITA packet
+ queue_rx_cmd(1,0,8,32'h0,32'h0); // send imm, single packet
+ queue_rx_cmd(1,0,16,32'h0,32'h0); // send imm, 2 packets worth
+ queue_rx_cmd(1,0,7,32'h0,32'h0); // send imm, 1 short packet worth
+ queue_rx_cmd(1,0,9,32'h0,32'h0); // send imm, just longer than 1 packet
+
+ queue_rx_cmd(1,1,16,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,8,32'h0,32'h0); // 2nd in chain
+
+ queue_rx_cmd(1,1,17,32'h0,32'h0); // chained, odd length
+ queue_rx_cmd(0,0,9,32'h0,32'h0); // 2nd in chain, also odd length
+
+ queue_rx_cmd(0,0,8,32'h0,32'h340); // send at, on time
+ queue_rx_cmd(0,0,8,32'h0,32'h100); // send at, but late
+
+ queue_rx_cmd(1,1,8,32'h0,32'h0); // chained, but break chain
+ #100000;
+ $display("\nEnd chain with zero samples, shouldn't error\n");
+ queue_rx_cmd(1,1,8,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,0,32'h0,32'h0); // end chain with zero samples, should keep us out of error
+ #100000;
+
+ $display("\nEnd chain with zero samples on odd-length, shouldn't error\n");
+ queue_rx_cmd(1,1,14,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,0,32'h0,32'h0); // end chain with zero samples, should keep us out of error
+ #100000;
+ $display("Should have gotten 14 samples and EOF by now\n");
+
+ queue_rx_cmd(1,1,9,32'h0,32'h0); // chained, but break chain, odd length
+ #100000;
+ dst_rdy <= 0; // stop pulling out of fifo so we can get an overrun
+ queue_rx_cmd(1,0,100,32'h0,32'h0); // long enough to fill the fifos
+ queue_rx_cmd(1,0,5,32'h0,32'h0); // this command waits until the previous error packet is sent
+ #100000;
+ dst_rdy <= 1; // restart the reads so we can see what we got
+ #100000;
+ dst_rdy <= 0; // stop pulling out of fifo so we can get an overrun
+ queue_rx_cmd(1,1,100,32'h0,32'h0); // long enough to fill the fifos
+ //queue_rx_cmd(1,0,5,32'h0,32'h0); // this command waits until the previous error packet is sent
+ #100000;
+ @(posedge clk);
+ dst_rdy <= 1;
+
+ #100000 $finish;
+ end
+
+ task write_setting;
+ input [7:0] addr;
+ input [31:0] data;
+ begin
+ set_stb <= 0;
+ @(posedge clk);
+ set_addr <= addr;
+ set_data <= data;
+ set_stb <= 1;
+ @(posedge clk);
+ set_stb <= 0;
+ end
+ endtask // write_setting
+
+ task queue_rx_cmd;
+ input send_imm;
+ input chain;
+ input [29:0] lines;
+ input [31:0] secs;
+ input [31:0] tics;
+ begin
+ write_setting(0,{send_imm,chain,lines});
+ write_setting(1,secs);
+ write_setting(2,tics);
+ end
+ endtask // queue_rx_cmd
+
+endmodule // rx_control_tb
+
+module rx_dsp_model
+ (input clk, input reset,
+ input run,
+ input [7:0] decim,
+ output strobe,
+ output [31:0] sample);
+
+ reg [15:0] pktnum = 0;
+ reg [15:0] counter = 0;
+
+ reg run_d1;
+ always @(posedge clk) run_d1 <= run;
+
+ always @(posedge clk)
+ if(run & ~run_d1)
+ begin
+ counter <= 0;
+ pktnum <= pktnum + 1;
+ end
+ else if(run & strobe)
+ counter <= counter + 1;
+
+ assign sample = {pktnum,counter};
+
+ reg [7:0] stb_ctr = 0;
+
+ always @(posedge clk)
+ if(reset)
+ stb_ctr <= 0;
+ else if(run & ~run_d1)
+ stb_ctr <= 1;
+ else if(run)
+ if(stb_ctr == decim-1)
+ stb_ctr <= 0;
+ else
+ stb_ctr <= stb_ctr + 1;
+
+ assign strobe = stb_ctr == decim-1;
+
+endmodule // rx_dsp_model
diff --git a/usrp2/vrt/vita_tx.build b/usrp2/vrt/vita_tx.build
new file mode 100755
index 000000000..902929c08
--- /dev/null
+++ b/usrp2/vrt/vita_tx.build
@@ -0,0 +1 @@
+iverilog -Wimplict -Wportbind -y ../sdr_lib -y ../models -y . -y ../control_lib/ -y ../control_lib/newfifo -y ../coregen -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -y ../timing -o vita_tx_tb vita_tx_tb.v
diff --git a/usrp2/vrt/vita_tx_control.v b/usrp2/vrt/vita_tx_control.v
new file mode 100644
index 000000000..bffc64e52
--- /dev/null
+++ b/usrp2/vrt/vita_tx_control.v
@@ -0,0 +1,98 @@
+
+module vita_tx_control
+ #(parameter BASE=0,
+ parameter WIDTH=32)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ input [63:0] vita_time,
+ output underrun,
+
+ // From vita_tx_deframer
+ input [4+64+WIDTH-1:0] sample_fifo_i,
+ input sample_fifo_src_rdy_i,
+ output sample_fifo_dst_rdy_o,
+
+ // To DSP Core
+ output [WIDTH-1:0] sample,
+ output run,
+ input strobe,
+
+ output [31:0] debug
+ );
+
+ assign sample = sample_fifo_i[4+64+WIDTH-1:4+64];
+
+ wire [63:0] send_time = sample_fifo_i[63:0];
+ wire eop = sample_fifo_i[64];
+ wire eob = sample_fifo_i[65];
+ wire sob = sample_fifo_i[66];
+ wire send_at = sample_fifo_i[67];
+ wire now, early, late, too_early;
+
+ // FIXME ignore too_early for now for timing reasons
+ assign too_early = 0;
+ time_compare
+ time_compare (.time_now(vita_time), .trigger_time(send_time), .now(now), .early(early),
+ .late(late), .too_early());
+// .late(late), .too_early(too_early));
+
+ localparam IBS_IDLE = 0;
+ localparam IBS_RUN = 1; // FIXME do we need this?
+ localparam IBS_CONT_BURST = 2;
+ localparam IBS_UNDERRUN = 3;
+ localparam IBS_UNDERRUN_DONE = 4;
+
+ reg [2:0] ibs_state;
+
+ wire clear_state;
+ setting_reg #(.my_addr(BASE+1)) sr
+ (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear_state));
+
+ always @(posedge clk)
+ if(reset | clear_state)
+ ibs_state <= 0;
+ else
+ case(ibs_state)
+ IBS_IDLE :
+ if(sample_fifo_src_rdy_i)
+ if(~send_at | now)
+ ibs_state <= IBS_RUN;
+ else if(late | too_early)
+ ibs_state <= IBS_UNDERRUN;
+
+ IBS_RUN :
+ if(strobe)
+ if(~sample_fifo_src_rdy_i)
+ ibs_state <= IBS_UNDERRUN;
+ else if(eop)
+ if(eob)
+ ibs_state <= IBS_IDLE;
+ else
+ ibs_state <= IBS_CONT_BURST;
+
+ IBS_CONT_BURST :
+ if(strobe)
+ ibs_state <= IBS_UNDERRUN_DONE;
+ else if(sample_fifo_src_rdy_i)
+ ibs_state <= IBS_RUN;
+
+ IBS_UNDERRUN :
+ if(sample_fifo_src_rdy_i & eop)
+ ibs_state <= IBS_UNDERRUN_DONE;
+
+ IBS_UNDERRUN_DONE :
+ ;
+ endcase // case (ibs_state)
+
+ assign sample_fifo_dst_rdy_o = (ibs_state == IBS_UNDERRUN) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout
+ assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST);
+ assign underrun = (ibs_state == IBS_UNDERRUN_DONE);
+
+ assign debug = { { now,early,late,too_early,eop,eob,sob,send_at },
+ { sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, underrun, ibs_state[2:0] },
+ { 8'b0 },
+ { 8'b0 } };
+
+endmodule // vita_tx_control
diff --git a/usrp2/vrt/vita_tx_deframer.v b/usrp2/vrt/vita_tx_deframer.v
new file mode 100644
index 000000000..49428ead5
--- /dev/null
+++ b/usrp2/vrt/vita_tx_deframer.v
@@ -0,0 +1,187 @@
+
+module vita_tx_deframer
+ #(parameter BASE=0,
+ parameter MAXCHAN=1)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+
+ // To FIFO interface of Buffer Pool
+ input [35:0] data_i,
+ input src_rdy_i,
+ output dst_rdy_o,
+
+ output [4+64+(32*MAXCHAN)-1:0] sample_fifo_o,
+ output sample_fifo_src_rdy_o,
+ input sample_fifo_dst_rdy_i,
+
+ // FIFO Levels
+ output [15:0] fifo_occupied,
+ output fifo_full,
+ output fifo_empty,
+ output [31:0] debug
+ );
+
+ wire [1:0] numchan;
+ setting_reg #(.my_addr(BASE), .at_reset(0)) sr_numchan
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(numchan),.changed());
+
+ reg [3:0] vita_state;
+ wire has_streamid, has_classid, has_secs, has_tics, has_trailer;
+ assign has_streamid = (data_i[31:28]==4'b001);
+ assign has_classid = data_i[27];
+ assign has_secs = ~(data_i[23:22]==2'b00);
+ assign has_tics = ~(data_i[21:20]==2'b00);
+ assign has_trailer = data_i[26];
+ assign is_sob = data_i[25];
+ assign is_eob = data_i[24];
+ wire eof = data_i[33];
+
+ reg has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg;
+ reg has_trailer_reg, is_sob_reg, is_eob_reg;
+
+ reg [15:0] pkt_len;
+ reg [1:0] vector_phase;
+ wire line_done;
+
+ // Output FIFO for packetized data
+ localparam VITA_HEADER = 0;
+ localparam VITA_STREAMID = 1;
+ localparam VITA_CLASSID = 2;
+ localparam VITA_CLASSID2 = 3;
+ localparam VITA_SECS = 4;
+ localparam VITA_TICS = 5;
+ localparam VITA_TICS2 = 6;
+ localparam VITA_PAYLOAD = 7;
+ localparam VITA_STORE = 8;
+ localparam VITA_TRAILER = 9;
+
+ wire [15:0] hdr_len = 2 + has_streamid_reg + has_classid_reg + has_classid_reg + has_secs_reg +
+ has_tics_reg + has_tics_reg + has_trailer_reg;
+
+ wire eop = eof | (pkt_len==hdr_len); // FIXME would ignoring eof allow larger VITA packets?
+ wire fifo_space;
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ vita_state <= VITA_HEADER;
+ {has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg}
+ <= 0;
+ end
+ else
+ if((vita_state == VITA_STORE) & fifo_space)
+ if(eop)
+ if(has_trailer_reg)
+ vita_state <= VITA_TRAILER;
+ else
+ vita_state <= VITA_HEADER;
+ else
+ begin
+ vita_state <= VITA_PAYLOAD;
+ pkt_len <= pkt_len - 1;
+ end
+ else if(src_rdy_i)
+ case(vita_state)
+ VITA_HEADER :
+ begin
+ {has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg}
+ <= {has_streamid, has_classid, has_secs, has_tics, has_trailer, is_sob, is_eob};
+ pkt_len <= data_i[15:0];
+ vector_phase <= 0;
+ if(has_streamid)
+ vita_state <= VITA_STREAMID;
+ else if(has_classid)
+ vita_state <= VITA_CLASSID;
+ else if(has_secs)
+ vita_state <= VITA_SECS;
+ else if(has_tics)
+ vita_state <= VITA_TICS;
+ else
+ vita_state <= VITA_PAYLOAD;
+ end // case: VITA_HEADER
+ VITA_STREAMID :
+ if(has_classid_reg)
+ vita_state <= VITA_CLASSID;
+ else if(has_secs_reg)
+ vita_state <= VITA_SECS;
+ else if(has_tics_reg)
+ vita_state <= VITA_TICS;
+ else
+ vita_state <= VITA_PAYLOAD;
+ VITA_CLASSID :
+ vita_state <= VITA_CLASSID2;
+ VITA_CLASSID2 :
+ if(has_secs_reg)
+ vita_state <= VITA_SECS;
+ else if(has_tics_reg)
+ vita_state <= VITA_TICS;
+ else
+ vita_state <= VITA_PAYLOAD;
+ VITA_SECS :
+ if(has_tics_reg)
+ vita_state <= VITA_TICS;
+ else
+ vita_state <= VITA_PAYLOAD;
+ VITA_TICS :
+ vita_state <= VITA_TICS2;
+ VITA_TICS2 :
+ vita_state <= VITA_PAYLOAD;
+ VITA_PAYLOAD :
+ if(line_done)
+ begin
+ vector_phase <= 0;
+ vita_state <= VITA_STORE;
+ end
+ else
+ vector_phase <= vector_phase + 1;
+ VITA_TRAILER :
+ vita_state <= VITA_HEADER;
+ VITA_STORE :
+ ;
+ default :
+ vita_state <= VITA_HEADER;
+ endcase // case (vita_state)
+
+ assign line_done = (vector_phase == numchan);
+
+ wire [4+64+32*MAXCHAN-1:0] fifo_i;
+ reg [63:0] send_time;
+ reg [31:0] sample_a, sample_b, sample_c, sample_d;
+
+ always @(posedge clk)
+ case(vita_state)
+ VITA_SECS :
+ send_time[63:32] <= data_i[31:0];
+ VITA_TICS2 :
+ send_time[31:0] <= data_i[31:0];
+ VITA_STORE, VITA_HEADER :
+ send_time[63:0] <= 64'd0;
+ endcase // case (vita_state)
+
+ always @(posedge clk)
+ if(vita_state == VITA_PAYLOAD)
+ case(vector_phase)
+ 0: sample_a <= data_i[31:0];
+ 1: sample_b <= data_i[31:0];
+ 2: sample_c <= data_i[31:0];
+ 3: sample_d <= data_i[31:0];
+ endcase // case (vector_phase)
+
+ wire store = (vita_state == VITA_STORE);
+ fifo_short #(.WIDTH(4+64+32*MAXCHAN)) short_tx_q
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(fifo_i), .src_rdy_i(store), .dst_rdy_o(fifo_space),
+ .dataout(sample_fifo_o), .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i) );
+
+ // sob, eob, has_secs (send_at) ignored on all lines except first
+ assign fifo_i = {sample_d,sample_c,sample_b,sample_a,has_secs_reg,is_sob_reg,is_eob_reg,eop,send_time};
+
+ assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ;
+
+ assign debug = { { 8'b0 },
+ { 8'b0 },
+ { eof, line_done, store, fifo_space, src_rdy_i, dst_rdy_o, vector_phase[1:0] },
+ { has_secs_reg, is_sob_reg, is_eob_reg, eop, vita_state[3:0] } };
+
+endmodule // vita_tx_deframer
diff --git a/usrp2/vrt/vita_tx_tb.v b/usrp2/vrt/vita_tx_tb.v
new file mode 100644
index 000000000..90986a35f
--- /dev/null
+++ b/usrp2/vrt/vita_tx_tb.v
@@ -0,0 +1,264 @@
+
+
+module vita_tx_tb;
+
+ localparam DECIM = 8'd4;
+ localparam INTERP = 8'd4;
+
+ localparam MAXCHAN=4;
+ localparam NUMCHAN=1;
+
+ reg clk = 0;
+ reg reset = 1;
+
+ initial #1000 reset = 0;
+ always #50 clk = ~clk;
+
+ initial $dumpfile("vita_tx_tb.vcd");
+ initial $dumpvars(0,vita_tx_tb);
+
+ wire [(MAXCHAN*32)-1:0] sample, sample_tx;
+ wire strobe, run;
+ wire [35:0] data_o;
+ wire src_rdy;
+ wire dst_rdy;
+
+ wire [63:0] vita_time;
+
+ reg set_stb = 0;
+ reg [7:0] set_addr;
+ reg [31:0] set_data;
+ wire set_stb_dsp;
+ wire [7:0] set_addr_dsp;
+ wire [31:0] set_data_dsp;
+
+ /*
+ settings_bus_crossclock settings_bus_xclk_dsp
+ (.clk_i(clk), .rst_i(reset), .set_stb_i(set_stb), .set_addr_i(set_addr), .set_data_i(set_data),
+ .clk_o(clk), .rst_o(reset), .set_stb_o(set_stb_dsp), .set_addr_o(set_addr_dsp), .set_data_o(set_data_dsp));
+ */
+
+ wire sample_dst_rdy, sample_src_rdy;
+ //wire [99:0] sample_data_o;
+ wire [64+4+(MAXCHAN*32)-1:0] sample_data_o, sample_data_tx;
+
+ time_64bit #(.TICKS_PER_SEC(100000000), .BASE(0)) time_64bit
+ (.clk(clk), .rst(reset),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .pps(0), .vita_time(vita_time));
+
+ rx_dsp_model rx_dsp_model
+ (.clk(clk), .reset(reset), .run(run), .decim(DECIM), .strobe(strobe), .sample(sample[31:0]));
+
+ generate
+ if(MAXCHAN>1)
+ assign sample[(MAXCHAN*32)-1:32] = 0;
+ endgenerate
+
+ vita_rx_control #(.BASE(0), .WIDTH(32*MAXCHAN)) vita_rx_control
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .vita_time(vita_time), .overrun(overrun),
+ .sample_fifo_o(sample_data_o), .sample_fifo_dst_rdy_i(sample_dst_rdy), .sample_fifo_src_rdy_o(sample_src_rdy),
+ .sample(sample), .run(run), .strobe(strobe));
+
+ vita_rx_framer #(.BASE(0), .MAXCHAN(MAXCHAN)) vita_rx_framer
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .data_o(data_o), .dst_rdy_i(dst_rdy), .src_rdy_o(src_rdy),
+ .sample_fifo_i(sample_data_o), .sample_fifo_dst_rdy_o(sample_dst_rdy), .sample_fifo_src_rdy_i(sample_src_rdy),
+ .fifo_occupied(), .fifo_full(), .fifo_empty() );
+
+ wire [35:0] data_tx;
+ wire src_rdy_tx, dst_rdy_tx;
+ wire sample_dst_rdy_tx, sample_src_rdy_tx;
+
+ fifo_long #(.WIDTH(36)) fifo_short
+ (.clk(clk), .reset(reset), .clear(0),
+ .datain(data_o), .src_rdy_i(src_rdy), .dst_rdy_o(dst_rdy),
+ .dataout(data_tx), .src_rdy_o(src_rdy_tx), .dst_rdy_i(dst_rdy_tx));
+
+ vita_tx_deframer #(.BASE(16), .MAXCHAN(MAXCHAN)) vita_tx_deframer
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .data_i(data_tx), .dst_rdy_o(dst_rdy_tx), .src_rdy_i(src_rdy_tx),
+ .sample_fifo_o(sample_data_tx),
+ .sample_fifo_dst_rdy_i(sample_dst_rdy_tx), .sample_fifo_src_rdy_o(sample_src_rdy_tx),
+ .fifo_occupied(), .fifo_full(), .fifo_empty() );
+
+ vita_tx_control #(.BASE(16), .WIDTH(MAXCHAN*32)) vita_tx_control
+ (.clk(clk), .reset(reset), .clear(0),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .vita_time(vita_time-100), .underrun(underrun),
+ .sample_fifo_i(sample_data_tx),
+ .sample_fifo_dst_rdy_o(sample_dst_rdy_tx), .sample_fifo_src_rdy_i(sample_src_rdy_tx),
+ .sample(sample_tx), .run(run_tx), .strobe(strobe_tx));
+
+ tx_dsp_model tx_dsp_model
+ (.clk(clk), .reset(reset), .run(run_tx), .interp(INTERP), .strobe(strobe_tx), .sample(sample_tx[31:0] ));
+
+ always @(posedge clk)
+ if(src_rdy & dst_rdy)
+ begin
+ if(data_o[32] & ~data_o[33])
+ begin
+ $display("RX-PKT-START %d",$time);
+ $display(" RX-PKT-DAT %x",data_o[31:0]);
+ end
+ else if(data_o[32] & data_o[33])
+ begin
+ $display(" RX-PKT-DAT %x -- With ERR",data_o[31:0]);
+ $display("RX-PKT-ERR %d",$time);
+ end
+ else if(~data_o[32] & data_o[33])
+ begin
+ $display(" RX-PKT-DAT %x",data_o[31:0]);
+ $display("RX-PKT-END %d",$time);
+ end
+ else
+ $display(" RX-PKT DAT %x",data_o[31:0]);
+ end
+
+ initial
+ begin
+ @(negedge reset);
+ @(posedge clk);
+ write_setting(4,32'h14900008); // VITA header
+ write_setting(5,32'hF00D1234); // VITA streamid
+ write_setting(6,32'h98765432); // VITA trailer
+ write_setting(7,8); // Samples per VITA packet
+ write_setting(8,NUMCHAN); // Samples per VITA packet
+ #10000;
+
+ queue_rx_cmd(1,0,8,32'h0,32'h0); // send imm, single packet
+/*
+ queue_rx_cmd(1,0,16,32'h0,32'h0); // send imm, 2 packets worth
+ queue_rx_cmd(1,0,7,32'h0,32'h0); // send imm, 1 short packet worth
+ queue_rx_cmd(1,0,9,32'h0,32'h0); // send imm, just longer than 1 packet
+
+ queue_rx_cmd(1,1,16,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,8,32'h0,32'h0); // 2nd in chain
+
+ queue_rx_cmd(1,1,17,32'h0,32'h0); // chained, odd length
+ queue_rx_cmd(0,0,9,32'h0,32'h0); // 2nd in chain, also odd length
+
+ queue_rx_cmd(0,0,8,32'h0,32'h340); // send at, on time
+ queue_rx_cmd(0,0,8,32'h0,32'h100); // send at, but late
+
+ queue_rx_cmd(1,1,8,32'h0,32'h0); // chained, but break chain
+ #100000;
+ $display("\nEnd chain with zero samples, shouldn't error\n");
+ queue_rx_cmd(1,1,8,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,0,32'h0,32'h0); // end chain with zero samples, should keep us out of error
+ #100000;
+
+ $display("\nEnd chain with zero samples on odd-length, shouldn't error\n");
+ queue_rx_cmd(1,1,14,32'h0,32'h0); // chained
+ queue_rx_cmd(0,0,0,32'h0,32'h0); // end chain with zero samples, should keep us out of error
+ #100000;
+ $display("Should have gotten 14 samples and EOF by now\n");
+
+ queue_rx_cmd(1,1,9,32'h0,32'h0); // chained, but break chain, odd length
+ #100000;
+ //dst_rdy <= 0; // stop pulling out of fifo so we can get an overrun
+ queue_rx_cmd(1,0,100,32'h0,32'h0); // long enough to fill the fifos
+ queue_rx_cmd(1,0,5,32'h0,32'h0); // this command waits until the previous error packet is sent
+ #100000;
+ //dst_rdy <= 1; // restart the reads so we can see what we got
+ #100000;
+ //dst_rdy <= 0; // stop pulling out of fifo so we can get an overrun
+ queue_rx_cmd(1,1,100,32'h0,32'h0); // long enough to fill the fifos
+ //queue_rx_cmd(1,0,5,32'h0,32'h0); // this command waits until the previous error packet is sent
+ #100000;
+ @(posedge clk);
+ //dst_rdy <= 1;
+ */
+ #100000 $finish;
+ end
+
+ task write_setting;
+ input [7:0] addr;
+ input [31:0] data;
+ begin
+ set_stb <= 0;
+ @(posedge clk);
+ set_addr <= addr;
+ set_data <= data;
+ set_stb <= 1;
+ @(posedge clk);
+ set_stb <= 0;
+ end
+ endtask // write_setting
+
+ task queue_rx_cmd;
+ input send_imm;
+ input chain;
+ input [29:0] lines;
+ input [31:0] secs;
+ input [31:0] tics;
+ begin
+ write_setting(0,{send_imm,chain,lines});
+ write_setting(1,secs);
+ write_setting(2,tics);
+ end
+ endtask // queue_rx_cmd
+
+endmodule // vita_tx_tb
+
+
+module rx_dsp_model
+ (input clk, input reset,
+ input run,
+ input [7:0] decim,
+ output strobe,
+ output [31:0] sample);
+
+ reg [15:0] pktnum = 0;
+ reg [15:0] counter = 0;
+
+ reg run_d1;
+ always @(posedge clk) run_d1 <= run;
+
+ always @(posedge clk)
+ if(run & ~run_d1)
+ begin
+ counter <= 0;
+ pktnum <= pktnum + 1;
+ end
+ else if(run & strobe)
+ counter <= counter + 1;
+
+ assign sample = {pktnum,counter};
+
+ reg [7:0] stb_ctr = 0;
+
+ always @(posedge clk)
+ if(reset)
+ stb_ctr <= 0;
+ else if(run & ~run_d1)
+ stb_ctr <= 1;
+ else if(run)
+ if(stb_ctr == decim-1)
+ stb_ctr <= 0;
+ else
+ stb_ctr <= stb_ctr + 1;
+
+ assign strobe = stb_ctr == decim-1;
+
+endmodule // rx_dsp_model
+
+module tx_dsp_model
+ (input clk, input reset,
+ input run,
+ input [7:0] interp,
+ output strobe,
+ input [31:0] sample);
+
+ cic_strober strober(.clock(clk), .reset(reset), .enable(run), .rate(interp), .strobe_fast(1), .strobe_slow(strobe));
+
+ always @(posedge clk)
+ if(strobe)
+ $display("Time %d, Sent Sample %x",$time,sample);
+
+
+endmodule // tx_dsp_model