summaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/vrt
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-02-17 16:55:59 -0800
committerJosh Blum <josh@joshknows.com>2012-02-17 16:55:59 -0800
commitace4489066d1621a09e70650a00d736f0b03ed8c (patch)
treef02b34b70da9e9beb0f34dc5e64d48daa5aa4bf6 /fpga/usrp2/vrt
parent8f8ac3397aaa85b64aaa8722efdc1c0c40e93052 (diff)
parent2e37dd87234e5beddd6f76fcda714916f761f812 (diff)
downloaduhd-ace4489066d1621a09e70650a00d736f0b03ed8c.tar.gz
uhd-ace4489066d1621a09e70650a00d736f0b03ed8c.tar.bz2
uhd-ace4489066d1621a09e70650a00d736f0b03ed8c.zip
Merge branch 'fpga_next' into next
Diffstat (limited to 'fpga/usrp2/vrt')
-rw-r--r--fpga/usrp2/vrt/Makefile.srcs2
-rw-r--r--fpga/usrp2/vrt/gen_context_pkt.v18
-rw-r--r--fpga/usrp2/vrt/vita_rx_chain.v31
-rw-r--r--fpga/usrp2/vrt/vita_rx_engine_glue.v95
-rw-r--r--fpga/usrp2/vrt/vita_rx_framer.v38
-rw-r--r--fpga/usrp2/vrt/vita_tx_chain.v103
-rw-r--r--fpga/usrp2/vrt/vita_tx_control.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_deframer.v99
-rw-r--r--fpga/usrp2/vrt/vita_tx_engine_glue.v99
9 files changed, 382 insertions, 120 deletions
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs
index 166ed44ef..84ba5dc29 100644
--- a/fpga/usrp2/vrt/Makefile.srcs
+++ b/fpga/usrp2/vrt/Makefile.srcs
@@ -15,4 +15,6 @@ vita_tx_chain.v \
gen_context_pkt.v \
trigger_context_pkt.v \
vita_pkt_gen.v \
+vita_rx_engine_glue.v \
+vita_tx_engine_glue.v \
))
diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v
index bdfca8237..d6674e887 100644
--- a/fpga/usrp2/vrt/gen_context_pkt.v
+++ b/fpga/usrp2/vrt/gen_context_pkt.v
@@ -32,12 +32,11 @@ module gen_context_pkt
localparam CTXT_PROT_ENG = 1;
localparam CTXT_HEADER = 2;
localparam CTXT_STREAMID = 3;
- localparam CTXT_SECS = 4;
- localparam CTXT_TICS = 5;
- localparam CTXT_TICS2 = 6;
- localparam CTXT_MESSAGE = 7;
- localparam CTXT_FLOWCTRL = 8;
- localparam CTXT_DONE = 9;
+ localparam CTXT_TICS = 4;
+ localparam CTXT_TICS2 = 5;
+ localparam CTXT_MESSAGE = 6;
+ localparam CTXT_FLOWCTRL = 7;
+ localparam CTXT_DONE = 8;
reg [33:0] data_int;
wire src_rdy_int, dst_rdy_int;
@@ -88,11 +87,10 @@ module gen_context_pkt
always @*
case(ctxt_state)
- CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd28 }; // UDP port 1 or 3
- CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd7 };
+ CTXT_PROT_ENG : data_int <= { 2'b01, 13'b0, DSP_NUMBER[0], 1'b1, 1'b1, 16'd24 }; // UDP port 1 or 3
+ CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100000001, seqno, 16'd6 };
CTXT_STREAMID : data_int <= { 2'b00, streamid };
- CTXT_SECS : data_int <= { 2'b00, err_time[63:32] };
- CTXT_TICS : data_int <= { 2'b00, 32'd0 };
+ CTXT_TICS : data_int <= { 2'b00, err_time[63:32] };
CTXT_TICS2 : data_int <= { 2'b00, err_time[31:0] };
CTXT_MESSAGE : data_int <= { 2'b00, message };
CTXT_FLOWCTRL : data_int <= { 2'b10, seqnum };
diff --git a/fpga/usrp2/vrt/vita_rx_chain.v b/fpga/usrp2/vrt/vita_rx_chain.v
index 8b41e5fa8..c57e6cc05 100644
--- a/fpga/usrp2/vrt/vita_rx_chain.v
+++ b/fpga/usrp2/vrt/vita_rx_chain.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -20,21 +20,31 @@ module vita_rx_chain
#(parameter BASE=0,
parameter UNIT=0,
parameter FIFOSIZE=10,
- parameter PROT_ENG_FLAGS=1)
- (input clk, input reset, input clear,
+ parameter PROT_ENG_FLAGS=1,
+ parameter DSP_NUMBER=0)
+ (input clk, input reset,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
- input [63:0] vita_time, output overrun,
- input [31:0] sample, output run, input strobe,
+ input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user,
+ input [63:0] vita_time,
+ input [31:0] sample, input strobe,
output [35:0] rx_data_o, output rx_src_rdy_o, input rx_dst_rdy_i,
+ output overrun, output run, output clear_o,
output [31:0] debug );
-
+
wire [100:0] sample_data;
wire sample_dst_rdy, sample_src_rdy;
wire [31:0] vrc_debug, vrf_debug;
wire [35:0] rx_data_int;
wire rx_src_rdy_int, rx_dst_rdy_int;
-
+
+ wire clear;
+ assign clear_o = clear;
+
+ setting_reg #(.my_addr(BASE+3)) sr
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out(),.changed(clear));
+
vita_rx_control #(.BASE(BASE), .WIDTH(32)) vita_rx_control
(.clk(clk), .reset(reset), .clear(clear),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
@@ -65,9 +75,10 @@ module vita_rx_chain
.data_i(rx_data_int), .src_rdy_i(rx_src_rdy_int), .dst_rdy_o(rx_dst_rdy_int),
.data_o(rx_data_int2), .src_rdy_o(rx_src_rdy_int2), .dst_rdy_i(rx_dst_rdy_int2));
- dspengine_16to8 #(.BASE(BASE+9), .BUF_SIZE(FIFOSIZE)) dspengine_16to8
- (.clk(clk),.reset(reset),.clear(clear),
- .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ vita_rx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+3), .BUF_SIZE(FIFOSIZE)) dspengine_rx
+ (.clock(clk),.reset(reset),.clear(clear),
+ .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data),
+ .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user),
.access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
.access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
.access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf));
diff --git a/fpga/usrp2/vrt/vita_rx_engine_glue.v b/fpga/usrp2/vrt/vita_rx_engine_glue.v
new file mode 100644
index 000000000..56447a7aa
--- /dev/null
+++ b/fpga/usrp2/vrt/vita_rx_engine_glue.v
@@ -0,0 +1,95 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+//The following module is used to re-write receive packets to the host.
+//This module provides a packet-based ram interface for manipulating packets.
+//By default, this module uses the built-in 16 to 8 bit converter engine.
+
+module vita_rx_engine_glue
+#(
+ //the dsp unit number: 0, 1, 2...
+ parameter DSPNO = 0,
+
+ //buffer size for ram interface engine
+ parameter BUF_SIZE = 10,
+
+ //base address for built-in settings registers used in this module
+ parameter MAIN_SETTINGS_BASE = 0
+)
+(
+ //control signals
+ input clock, input reset, input clear,
+
+ //main settings bus for built-in modules
+ input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main,
+
+ //user settings bus, controlled through user setting regs API
+ input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user,
+
+ //ram interface for engine
+ output access_we,
+ output access_stb,
+ input access_ok,
+ output access_done,
+ output access_skip_read,
+ output [BUF_SIZE-1:0] access_adr,
+ input [BUF_SIZE-1:0] access_len,
+ output [35:0] access_dat_o,
+ input [35:0] access_dat_i,
+
+ //debug output (optional)
+ output [31:0] debug
+);
+
+ generate
+ if (DSPNO==0) begin
+ `ifndef RX_ENG0_MODULE
+ dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8
+ (.clk(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `else
+ `RX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng0_custom
+ (.clock(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `endif
+ end
+ else begin
+ `ifndef RX_ENG1_MODULE
+ dspengine_16to8 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE)) dspengine_16to8
+ (.clk(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `else
+ `RX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE)) rx_eng1_custom
+ (.clock(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `endif
+ end
+ endgenerate
+
+endmodule //vita_rx_engine_glue
diff --git a/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v
index bd09315bc..514df1151 100644
--- a/fpga/usrp2/vrt/vita_rx_framer.v
+++ b/fpga/usrp2/vrt/vita_rx_framer.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -93,18 +93,16 @@ module vita_rx_framer
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; // Extension context packets have no trailer
+ localparam VITA_TICS = 3;
+ localparam VITA_TICS2 = 4;
+ localparam VITA_PAYLOAD = 5;
+ localparam VITA_TRAILER = 6;
+ localparam VITA_ERR_HEADER = 7; // All ERR at 4'b1000 or'ed with base
+ localparam VITA_ERR_STREAMID = 8;
+ localparam VITA_ERR_TICS = 9;
+ localparam VITA_ERR_TICS2 = 10;
+ localparam VITA_ERR_PAYLOAD = 11;
+ localparam VITA_ERR_TRAILER = 12; // Extension context packets have no trailer
always @(posedge clk)
if(reset | clear | clear_pkt_count)
@@ -122,17 +120,15 @@ module vita_rx_framer
VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:24],
vita_header[23:20],pkt_count[3:0],vita_pkt_len[15:0]};
VITA_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
- VITA_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
- VITA_TICS : pkt_fifo_line <= {2'b00,32'd0};
+ VITA_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
VITA_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
VITA_PAYLOAD : pkt_fifo_line <= {2'b00,data_fifo_o};
VITA_TRAILER : pkt_fifo_line <= {2'b10,vita_trailer[31:21],1'b1,vita_trailer[19:9],trl_eob,8'd0};
// Error packets are Extension Context packets, which have no trailer
- VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd6};
+ VITA_ERR_HEADER : pkt_fifo_line <= {2'b01,4'b0101,4'b0000,vita_header[23:20],pkt_count,16'd5};
VITA_ERR_STREAMID : pkt_fifo_line <= {2'b00,vita_streamid};
- VITA_ERR_SECS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
- VITA_ERR_TICS : pkt_fifo_line <= {2'b00,32'd0};
+ VITA_ERR_TICS : pkt_fifo_line <= {2'b00,vita_time_fifo_o[63:32]};
VITA_ERR_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]};
VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b10,27'd0,flags_fifo_o};
//VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer};
@@ -164,7 +160,7 @@ module vita_rx_framer
if(has_streamid)
vita_state <= VITA_STREAMID;
else
- vita_state <= VITA_SECS;
+ vita_state <= VITA_TICS;
VITA_PAYLOAD :
if(sample_fifo_src_rdy_i)
begin
@@ -194,12 +190,12 @@ module vita_rx_framer
case(vita_state)
VITA_IDLE :
req_write_pkt_fifo <= 0;
- VITA_HEADER, VITA_STREAMID, VITA_SECS, VITA_TICS, VITA_TICS2, VITA_TRAILER :
+ VITA_HEADER, VITA_STREAMID, 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[4:1]);
- VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD :
+ VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD :
req_write_pkt_fifo <= 1;
default :
req_write_pkt_fifo <= 0;
diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v
index ac9f08fc8..82a43d57a 100644
--- a/fpga/usrp2/vrt/vita_tx_chain.v
+++ b/fpga/usrp2/vrt/vita_tx_chain.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -17,8 +17,9 @@
module vita_tx_chain
- #(parameter BASE_CTRL=0,
- parameter BASE_DSP=0,
+ #(parameter BASE=0,
+ parameter FIFOSIZE=10,
+ parameter POST_ENGINE_FIFOSIZE=10,
parameter REPORT_ERROR=0,
parameter DO_FLOW_CONTROL=0,
parameter PROT_ENG_FLAGS=0,
@@ -26,11 +27,12 @@ module vita_tx_chain
parameter DSP_NUMBER=0)
(input clk, input reset,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user,
input [63:0] vita_time,
input [35:0] tx_data_i, input tx_src_rdy_i, output tx_dst_rdy_o,
output [35:0] err_data_o, output err_src_rdy_o, input err_dst_rdy_i,
- output [23:0] tx_i, output [23:0] tx_q,
- output underrun, output run,
+ output [31:0] sample, input strobe,
+ output underrun, output run, output clear_o,
output [31:0] debug);
localparam MAXCHAN = 1;
@@ -38,8 +40,6 @@ module vita_tx_chain
wire [FIFOWIDTH-1:0] tx1_data;
wire tx1_src_rdy, tx1_dst_rdy;
- wire clear_vita;
- wire [31:0] sample_tx;
wire [31:0] streamid, message;
wire trigger, sent;
wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp;
@@ -48,61 +48,104 @@ module vita_tx_chain
wire [31:0] error_code;
wire clear_seqnum;
wire [31:0] current_seqnum;
- wire strobe_tx;
-
+
+ wire clear, flush;
+ assign clear_o = clear;
assign underrun = error;
assign message = error_code;
-
- setting_reg #(.my_addr(BASE_CTRL+1)) sr
+
+ setting_reg #(.my_addr(BASE+0), .width(1)) sr
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
- .in(set_data),.out(),.changed(clear_vita));
+ .in(set_data),.out(flush),.changed(clear));
- setting_reg #(.my_addr(BASE_CTRL+2), .at_reset(0)) sr_streamid
+ setting_reg #(.my_addr(BASE+2), .at_reset(0)) sr_streamid
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(streamid),.changed(clear_seqnum));
- vita_tx_deframer #(.BASE(BASE_CTRL),
+ //flush control - full rate vacuum of input until flush cleared
+ wire tx_dst_rdy_int, tx_src_rdy_int;
+ wire [35:0] tx_data_int;
+ valve36 flusher_valve
+ (.clk(clk), .reset(reset), .clear(clear & flush), .shutoff(flush),
+ .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o),
+ .data_o(tx_data_int), .src_rdy_o(tx_src_rdy_int), .dst_rdy_i(tx_dst_rdy_int));
+
+ wire [35:0] tx_data_int1;
+ wire tx_src_rdy_int1, tx_dst_rdy_int1;
+
+ generate
+ if (FIFOSIZE==0) begin
+ assign tx_data_int1 = tx_data_int;
+ assign tx_src_rdy_int1 = tx_src_rdy_int;
+ assign tx_dst_rdy_int = tx_dst_rdy_int1;
+ end
+ else begin
+ wire [FIFOSIZE-1:0] access_adr, access_len;
+ wire access_we, access_stb, access_ok, access_done, access_skip_read;
+ wire [35:0] dsp_to_buf, buf_to_dsp;
+ wire [35:0] tx_data_int0;
+ wire tx_src_rdy_int0, tx_dst_rdy_int0;
+
+ double_buffer #(.BUF_SIZE(FIFOSIZE)) db
+ (.clk(clk),.reset(reset),.clear(clear),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(dsp_to_buf), .access_dat_o(buf_to_dsp),
+
+ .data_i(tx_data_int), .src_rdy_i(tx_src_rdy_int), .dst_rdy_o(tx_dst_rdy_int),
+ .data_o(tx_data_int0), .src_rdy_o(tx_src_rdy_int0), .dst_rdy_i(tx_dst_rdy_int0));
+
+ vita_tx_engine_glue #(.DSPNO(DSP_NUMBER), .MAIN_SETTINGS_BASE(BASE+1), .BUF_SIZE(FIFOSIZE), .HEADER_OFFSET(USE_TRANS_HEADER)) dspengine_tx
+ (.clock(clk),.reset(reset),.clear(clear),
+ .set_stb_main(set_stb), .set_addr_main(set_addr), .set_data_main(set_data),
+ .set_stb_user(set_stb_user), .set_addr_user(set_addr_user), .set_data_user(set_data_user),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(buf_to_dsp), .access_dat_o(dsp_to_buf));
+
+ fifo_cascade #(.WIDTH(36), .SIZE(POST_ENGINE_FIFOSIZE)) post_engine_buffering(
+ .clk(clk), .reset(reset), .clear(clear),
+ .datain(tx_data_int0), .src_rdy_i(tx_src_rdy_int0), .dst_rdy_o(tx_dst_rdy_int0),
+ .dataout(tx_data_int1), .src_rdy_o(tx_src_rdy_int1), .dst_rdy_i(tx_dst_rdy_int1));
+
+ end
+ endgenerate
+
+ vita_tx_deframer #(.BASE(BASE),
.MAXCHAN(MAXCHAN),
.USE_TRANS_HEADER(USE_TRANS_HEADER))
vita_tx_deframer
- (.clk(clk), .reset(reset), .clear(clear_vita), .clear_seqnum(clear_seqnum),
+ (.clk(clk), .reset(reset), .clear(clear), .clear_seqnum(clear_seqnum),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o),
+ .data_i(tx_data_int1), .src_rdy_i(tx_src_rdy_int1), .dst_rdy_o(tx_dst_rdy_int1),
.sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy),
.current_seqnum(current_seqnum),
.debug(debug_vtd) );
- vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control
- (.clk(clk), .reset(reset), .clear(clear_vita),
+ vita_tx_control #(.BASE(BASE), .WIDTH(32*MAXCHAN)) vita_tx_control
+ (.clk(clk), .reset(reset), .clear(clear),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.vita_time(vita_time), .error(error), .ack(ack), .error_code(error_code),
.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), .strobe(strobe_tx), .packet_consumed(packet_consumed),
+ .sample(sample), .run(run), .strobe(strobe), .packet_consumed(packet_consumed),
.debug(debug_vtc) );
-
- dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx
- (.clk(clk),.rst(reset),
- .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
- .sample(sample_tx), .run(run), .strobe(strobe_tx),
- .tx_i(tx_i),.tx_q(tx_q),
- .debug(debug_tx_dsp) );
wire [35:0] flow_data, err_data_int;
wire flow_src_rdy, flow_dst_rdy, err_src_rdy_int, err_dst_rdy_int;
gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_flow_pkt
- (.clk(clk), .reset(reset), .clear(clear_vita),
+ (.clk(clk), .reset(reset), .clear(clear),
.trigger(trigger & (DO_FLOW_CONTROL==1)), .sent(),
.streamid(streamid), .vita_time(vita_time), .message(32'd0),
.seqnum(current_seqnum),
.data_o(flow_data), .src_rdy_o(flow_src_rdy), .dst_rdy_i(flow_dst_rdy));
- trigger_context_pkt #(.BASE(BASE_CTRL)) trigger_context_pkt
- (.clk(clk), .reset(reset), .clear(clear_vita),
+ trigger_context_pkt #(.BASE(BASE)) trigger_context_pkt
+ (.clk(clk), .reset(reset), .clear(clear),
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.packet_consumed(packet_consumed), .trigger(trigger));
gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS),.DSP_NUMBER(DSP_NUMBER)) gen_tx_err_pkt
- (.clk(clk), .reset(reset), .clear(clear_vita),
+ (.clk(clk), .reset(reset), .clear(clear),
.trigger((error|ack) & (REPORT_ERROR==1)), .sent(),
.streamid(streamid), .vita_time(vita_time), .message(message),
.seqnum(current_seqnum),
diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v
index 5df89bdbe..c3ce2b96a 100644
--- a/fpga/usrp2/vrt/vita_tx_control.v
+++ b/fpga/usrp2/vrt/vita_tx_control.v
@@ -50,11 +50,9 @@ module vita_tx_control
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());
+ .now(now), .early(early), .late(late), .too_early(too_early));
reg late_qual, late_del;
@@ -187,8 +185,17 @@ module vita_tx_control
assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout
- assign sample = (ibs_state == IBS_RUN) ? sample_fifo_i[5+64+16+WIDTH-1:5+64+16] : {WIDTH{1'b0}};
- //assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST);
+ //register the output sample
+ reg [31:0] sample_held;
+ assign sample = sample_held;
+ always @(posedge clk)
+ if(reset | clear)
+ sample_held <= 0;
+ else if (~run)
+ sample_held <= 0;
+ else if (strobe)
+ sample_held <= sample_fifo_i[5+64+16+WIDTH-1:5+64+16];
+
assign error = send_error;
assign ack = send_ack;
diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v
index 06ca27767..6919da11a 100644
--- a/fpga/usrp2/vrt/vita_tx_deframer.v
+++ b/fpga/usrp2/vrt/vita_tx_deframer.v
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -85,7 +85,6 @@ module vita_tx_deframer
localparam VITA_TICS = 6;
localparam VITA_TICS2 = 7;
localparam VITA_PAYLOAD = 8;
- localparam VITA_STORE = 9;
localparam VITA_TRAILER = 10;
localparam VITA_DUMP = 11;
@@ -118,21 +117,7 @@ module vita_tx_deframer
<= 0;
seqnum_err <= 0;
end
- else
- if((vita_state == VITA_STORE) & fifo_space)
- if(vita_eof)
- if(eof)
- vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
- else if(has_trailer_reg)
- vita_state <= VITA_TRAILER;
- else
- vita_state <= VITA_DUMP;
- else
- begin
- vita_state <= VITA_PAYLOAD;
- pkt_len <= pkt_len - 1;
- end
- else if(src_rdy_i)
+ else if(src_rdy_i & dst_rdy_o) begin //valid read
case(vita_state)
VITA_TRANS_HEADER :
begin
@@ -184,14 +169,33 @@ module vita_tx_deframer
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_PAYLOAD : begin
+
+ //step through each element until line done, then reset
+ vector_phase <= (line_done)? 0: vector_phase + 1;
+
+ //decrement the packet count after each line
+ pkt_len <= (line_done)? pkt_len - 1 : pkt_len;
+
+ //end of frame reached, determine next state
+ //otherwise, keep processing through the payload
+ if (line_done && vita_eof) begin
+
+ if (eof) begin
+ vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
+ end
+ else if (has_trailer_reg) begin
+ vita_state <= VITA_TRAILER;
+ end
+ else begin
+ vita_state <= VITA_DUMP;
+ end
+
+ end //line_done && vita_eof
+
+ end //end VITA_PAYLOAD
+
VITA_TRAILER :
if(eof)
vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
@@ -200,46 +204,53 @@ module vita_tx_deframer
VITA_DUMP :
if(eof)
vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
- VITA_STORE :
- ;
default :
vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
endcase // case (vita_state)
- assign line_done = (vector_phase == numchan);
+ end //valid read
+
+ assign line_done = (MAXCHAN == 1)? 1 : (vector_phase == numchan);
wire [FIFOWIDTH-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 :
+ VITA_TICS :
send_time[63:32] <= data_i[31:0];
VITA_TICS2 :
send_time[31:0] <= data_i[31:0];
endcase // case (vita_state)
-
+
+ //sample registers for de-framing a vector input
+ reg [31:0] sample_reg [1:0];
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);
+ if(src_rdy_i && dst_rdy_o)
+ sample_reg[vector_phase] <= data_i[31:0];
+
+ wire store = (vita_state == VITA_PAYLOAD)? (src_rdy_i && line_done) : 0;
+ assign dst_rdy_o = (vita_state == VITA_PAYLOAD)? fifo_space : 1;
+
fifo_short #(.WIDTH(FIFOWIDTH)) 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,seqnum_err,has_secs_reg,is_sob_reg,is_eob_reg,eop,
- 12'd0,seqnum_reg[3:0],send_time};
+ //assign registered/live data to the samples vector
+ //the numchan'th sample vector is muxed to live data
+ wire [(32*MAXCHAN)-1:0] samples;
+ generate
+ genvar i;
+ for (i=0; i < MAXCHAN; i = i +1) begin : assign_samples
+ wire live_data = (i == (MAXCHAN-1))? 1 : numchan == i;
+ assign samples[32*i + 31:32*i] = (live_data)? data_i[31:0] : sample_reg[i];
+ end
+ endgenerate
- assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ;
+ // sob, eob, has_tics (send_at) ignored on all lines except first
+ assign fifo_i = {samples,seqnum_err,has_tics_reg,is_sob_reg,is_eob_reg,eop,
+ 12'd0,seqnum_reg[3:0],send_time};
assign debug = { { 8'b0 },
{ 8'b0 },
diff --git a/fpga/usrp2/vrt/vita_tx_engine_glue.v b/fpga/usrp2/vrt/vita_tx_engine_glue.v
new file mode 100644
index 000000000..db0d55dee
--- /dev/null
+++ b/fpga/usrp2/vrt/vita_tx_engine_glue.v
@@ -0,0 +1,99 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+//The following module is used to re-write transmit packets from the host.
+//This module provides a packet-based ram interface for manipulating packets.
+//By default, this module uses the built-in 8 to 16 bit converter engine.
+
+module vita_tx_engine_glue
+#(
+ //the dsp unit number: 0, 1, 2...
+ parameter DSPNO = 0,
+
+ //buffer size for ram interface engine
+ parameter BUF_SIZE = 10,
+
+ //base address for built-in settings registers used in this module
+ parameter MAIN_SETTINGS_BASE = 0,
+
+ //the number of 32bit lines between start of buffer and vita header
+ //the metadata before the header should be preserved by the engine
+ parameter HEADER_OFFSET = 0
+)
+(
+ //control signals
+ input clock, input reset, input clear,
+
+ //main settings bus for built-in modules
+ input set_stb_main, input [7:0] set_addr_main, input [31:0] set_data_main,
+
+ //user settings bus, controlled through user setting regs API
+ input set_stb_user, input [7:0] set_addr_user, input [31:0] set_data_user,
+
+ //ram interface for engine
+ output access_we,
+ output access_stb,
+ input access_ok,
+ output access_done,
+ output access_skip_read,
+ output [BUF_SIZE-1:0] access_adr,
+ input [BUF_SIZE-1:0] access_len,
+ output [35:0] access_dat_o,
+ input [35:0] access_dat_i,
+
+ //debug output (optional)
+ output [31:0] debug
+);
+
+ generate
+ if (DSPNO==0) begin
+ `ifndef TX_ENG0_MODULE
+ dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16
+ (.clk(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `else
+ `TX_ENG0_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng0_custom
+ (.clock(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `endif
+ end
+ else begin
+ `ifndef TX_ENG1_MODULE
+ dspengine_8to16 #(.BASE(MAIN_SETTINGS_BASE), .BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) dspengine_8to16
+ (.clk(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_main), .set_addr(set_addr_main), .set_data(set_data_main),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `else
+ `TX_ENG1_MODULE #(.BUF_SIZE(BUF_SIZE), .HEADER_OFFSET(HEADER_OFFSET)) tx_eng1_custom
+ (.clock(clock),.reset(reset),.clear(clear),
+ .set_stb(set_stb_user), .set_addr(set_addr_user), .set_data(set_data_user),
+ .access_we(access_we), .access_stb(access_stb), .access_ok(access_ok), .access_done(access_done),
+ .access_skip_read(access_skip_read), .access_adr(access_adr), .access_len(access_len),
+ .access_dat_i(access_dat_i), .access_dat_o(access_dat_o));
+ `endif
+ end
+ endgenerate
+
+endmodule //vita_tx_engine_glue