summaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/vrt
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-10-14 16:55:56 -0700
committerJosh Blum <josh@joshknows.com>2010-10-14 16:55:56 -0700
commit26b7de0ac0cd64946582b2d52ab0bb3555156039 (patch)
tree5dc670eaaab60bf2bda90d905210bc9432cecea3 /fpga/usrp2/vrt
parent71e1763332141603e9edba097fd19b00e9a76ab8 (diff)
parentee03f1d4acf5c7d3359c86baba5085660d63ebae (diff)
downloaduhd-26b7de0ac0cd64946582b2d52ab0bb3555156039.tar.gz
uhd-26b7de0ac0cd64946582b2d52ab0bb3555156039.tar.bz2
uhd-26b7de0ac0cd64946582b2d52ab0bb3555156039.zip
Merge branch 'flow_control' into flow_ctrl
Diffstat (limited to 'fpga/usrp2/vrt')
-rw-r--r--fpga/usrp2/vrt/Makefile.srcs1
-rw-r--r--fpga/usrp2/vrt/gen_context_pkt.v38
-rw-r--r--fpga/usrp2/vrt/trigger_context_pkt.v52
-rw-r--r--fpga/usrp2/vrt/vita_tx_chain.v51
-rw-r--r--fpga/usrp2/vrt/vita_tx_control.v17
-rw-r--r--fpga/usrp2/vrt/vita_tx_deframer.v89
6 files changed, 194 insertions, 54 deletions
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs
index dc4bd8c96..aa1356d82 100644
--- a/fpga/usrp2/vrt/Makefile.srcs
+++ b/fpga/usrp2/vrt/Makefile.srcs
@@ -12,4 +12,5 @@ vita_tx_control.v \
vita_tx_deframer.v \
vita_tx_chain.v \
gen_context_pkt.v \
+trigger_context_pkt.v \
))
diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v
index 780a027ba..0eb035f3e 100644
--- a/fpga/usrp2/vrt/gen_context_pkt.v
+++ b/fpga/usrp2/vrt/gen_context_pkt.v
@@ -7,6 +7,8 @@ module gen_context_pkt
input [31:0] streamid,
input [63:0] vita_time,
input [31:0] message,
+ input [31:0] seqnum0,
+ input [31:0] seqnum1,
output [35:0] data_o, output src_rdy_o, input dst_rdy_i);
localparam CTXT_IDLE = 0;
@@ -17,17 +19,32 @@ module gen_context_pkt
localparam CTXT_TICS = 5;
localparam CTXT_TICS2 = 6;
localparam CTXT_MESSAGE = 7;
- localparam CTXT_DONE = 8;
+ localparam CTXT_FLOWCTRL0 = 8;
+ localparam CTXT_FLOWCTRL1 = 9;
+ localparam CTXT_DONE = 10;
reg [33:0] data_int;
wire src_rdy_int, dst_rdy_int;
- wire [3:0] seqno = 0;
+ reg [3:0] seqno;
reg [3:0] ctxt_state;
reg [63:0] err_time;
+ reg [31:0] stored_message;
always @(posedge clk)
if(reset | clear)
- ctxt_state <= CTXT_IDLE;
+ stored_message <= 0;
+ else
+ if(trigger)
+ stored_message <= message;
+ else if(ctxt_state == CTXT_FLOWCTRL1)
+ stored_message <= 0;
+
+ always @(posedge clk)
+ if(reset | clear)
+ begin
+ ctxt_state <= CTXT_IDLE;
+ seqno <= 0;
+ end
else
case(ctxt_state)
CTXT_IDLE :
@@ -41,9 +58,10 @@ module gen_context_pkt
end
CTXT_DONE :
- if(~trigger)
- ctxt_state <= CTXT_IDLE;
-
+ begin
+ ctxt_state <= CTXT_IDLE;
+ seqno <= seqno + 4'd1;
+ end
default :
if(dst_rdy_int)
ctxt_state <= ctxt_state + 1;
@@ -53,13 +71,15 @@ module gen_context_pkt
always @*
case(ctxt_state)
- CTXT_PROT_ENG : data_int <= { 2'b01, 16'd1, 16'd24 };
- CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd6 };
+ CTXT_PROT_ENG : data_int <= { 2'b01, 16'd1, 16'd32 };
+ CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd8 };
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_TICS2 : data_int <= { 2'b00, err_time[31:0] };
- CTXT_MESSAGE : data_int <= { 2'b10, message };
+ CTXT_MESSAGE : data_int <= { 2'b00, message };
+ CTXT_FLOWCTRL0 : data_int <= { 2'b00, seqnum0 };
+ CTXT_FLOWCTRL1 : data_int <= { 2'b10, seqnum1 };
default : data_int <= {2'b00, 32'b00};
endcase // case (ctxt_state)
diff --git a/fpga/usrp2/vrt/trigger_context_pkt.v b/fpga/usrp2/vrt/trigger_context_pkt.v
new file mode 100644
index 000000000..226ec45f2
--- /dev/null
+++ b/fpga/usrp2/vrt/trigger_context_pkt.v
@@ -0,0 +1,52 @@
+
+
+module trigger_context_pkt
+ #(parameter BASE=0)
+ (input clk, input reset, input clear,
+ input set_stb, input [7:0] set_addr, input [31:0] set_data,
+ input packet_consumed, output reg trigger);
+
+ wire [23:0] cycles;
+ wire [15:0] packets;
+ wire [6:0] dummy1;
+ wire [14:0] dummy2;
+ wire enable_timed, enable_consumed;
+ reg [30:0] cycle_count, packet_count;
+
+
+ setting_reg #(.my_addr(BASE+4), .at_reset(0)) sr_cycles
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out({enable_cycle,dummy1,cycles}),.changed());
+
+ setting_reg #(.my_addr(BASE+5), .at_reset(0)) sr_packets
+ (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
+ .in(set_data),.out({enable_consumed,dummy2,packets}),.changed());
+
+ always @(posedge clk)
+ if(reset | clear)
+ cycle_count <= 0;
+ else
+ if(trigger)
+ cycle_count <= 0;
+ else if(enable_cycle)
+ cycle_count <= cycle_count + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ packet_count <= 0;
+ else
+ if(trigger)
+ packet_count <= 0;
+ else if(packet_consumed & enable_consumed)
+ packet_count <= packet_count + 1;
+
+ always @(posedge clk)
+ if(reset | clear)
+ trigger <= 0;
+ else
+ if((cycle_count > cycles)|(packet_count > packets))
+ trigger <= 1;
+ else
+ trigger <= 0;
+
+endmodule // trigger_context_pkt
diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v
index 662cdca62..00da4c6e1 100644
--- a/fpga/usrp2/vrt/vita_tx_chain.v
+++ b/fpga/usrp2/vrt/vita_tx_chain.v
@@ -3,7 +3,9 @@ module vita_tx_chain
#(parameter BASE_CTRL=0,
parameter BASE_DSP=0,
parameter REPORT_ERROR=0,
- parameter PROT_ENG_FLAGS=0)
+ parameter DO_FLOW_CONTROL=0,
+ parameter PROT_ENG_FLAGS=0,
+ parameter USE_TRANS_HEADER=0)
(input clk, input reset,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input [63:0] vita_time,
@@ -24,22 +26,27 @@ module vita_tx_chain
wire trigger, sent;
wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp;
- wire error;
+ wire error, packet_consumed;
wire [31:0] error_code;
wire clear_seqnum;
+ wire [31:0] current_seqnum;
- assign underrun = error;
+ assign underrun = error & ~(error_code == 1);
assign message = error_code;
setting_reg #(.my_addr(BASE_CTRL+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), .MAXCHAN(MAXCHAN)) vita_tx_deframer
+ vita_tx_deframer #(.BASE(BASE_CTRL),
+ .MAXCHAN(MAXCHAN),
+ .USE_TRANS_HEADER(USE_TRANS_HEADER))
+ vita_tx_deframer
(.clk(clk), .reset(reset), .clear(clear_vita), .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),
.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
@@ -47,7 +54,7 @@ module vita_tx_chain
.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
.vita_time(vita_time),.error(error),.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),
+ .sample(sample_tx), .run(run), .strobe(strobe_tx), .packet_consumed(packet_consumed),
.debug(debug_vtc) );
dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx
@@ -57,15 +64,33 @@ module vita_tx_chain
.dac_a(dac_a),.dac_b(dac_b),
.debug(debug_tx_dsp) );
- generate
- if(REPORT_ERROR==1)
- gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) gen_tx_err_pkt
- (.clk(clk), .reset(reset), .clear(clear_vita),
- .trigger(error), .sent(),
- .streamid(streamid), .vita_time(vita_time), .message(message),
- .data_o(err_data_o), .src_rdy_o(err_src_rdy_o), .dst_rdy_i(err_dst_rdy_i));
- endgenerate
+ 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)) gen_flow_pkt
+ (.clk(clk), .reset(reset), .clear(clear_vita),
+ .trigger(trigger & (DO_FLOW_CONTROL==1)), .sent(),
+ .streamid(streamid), .vita_time(vita_time), .message(32'd0),
+ .seqnum0(current_seqnum), .seqnum1(32'd0),
+ .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),
+ .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)) gen_tx_err_pkt
+ (.clk(clk), .reset(reset), .clear(clear_vita),
+ .trigger(error & (REPORT_ERROR==1)), .sent(),
+ .streamid(streamid), .vita_time(vita_time), .message(message),
+ .seqnum0(current_seqnum), .seqnum1(32'd0),
+ .data_o(err_data_int), .src_rdy_o(err_src_rdy_int), .dst_rdy_i(err_dst_rdy_int));
+
assign debug = debug_vtc | debug_vtd;
+ fifo36_mux #(.prio(1)) mux_err_and_flow // Priority to err messages
+ (.clk(clk), .reset(reset), .clear(clear_vita),
+ .data0_i(err_data_int), .src0_rdy_i(err_src_rdy_int), .dst0_rdy_o(err_dst_rdy_int),
+ .data1_i(flow_data), .src1_rdy_i(flow_src_rdy), .dst1_rdy_o(flow_dst_rdy),
+ .data_o(err_data_o), .src_rdy_o(err_src_rdy_o), .dst_rdy_i(err_dst_rdy_i));
+
endmodule // vita_tx_chain
diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v
index d0516bec8..936762212 100644
--- a/fpga/usrp2/vrt/vita_tx_control.v
+++ b/fpga/usrp2/vrt/vita_tx_control.v
@@ -8,7 +8,8 @@ module vita_tx_control
input [63:0] vita_time,
output error,
output reg [31:0] error_code,
-
+ output reg packet_consumed,
+
// From vita_tx_deframer
input [5+64+16+WIDTH-1:0] sample_fifo_i,
input sample_fifo_src_rdy_i,
@@ -48,6 +49,7 @@ module vita_tx_control
localparam IBS_ERROR_DONE = 4;
localparam IBS_ERROR_WAIT = 5;
+ wire [31:0] CODE_EOB_ACK = {seqnum,16'd1};
wire [31:0] CODE_UNDERRUN = {seqnum,16'd2};
wire [31:0] CODE_SEQ_ERROR = {seqnum,16'd4};
wire [31:0] CODE_TIME_ERROR = {seqnum,16'd8};
@@ -106,7 +108,11 @@ module vita_tx_control
end
else if(eop)
if(eob)
- ibs_state <= IBS_IDLE;
+ begin
+ ibs_state <= IBS_ERROR_DONE; // Not really an error
+ error_code <= CODE_EOB_ACK;
+ send_error <= 1;
+ end
else
ibs_state <= IBS_CONT_BURST;
@@ -154,9 +160,14 @@ module vita_tx_control
assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout
assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST);
- //assign error = (ibs_state == IBS_ERROR_DONE);
assign error = send_error;
+ always @(posedge clk)
+ if(reset)
+ packet_consumed <= 0;
+ else
+ packet_consumed <= eop & sample_fifo_src_rdy_i & sample_fifo_dst_rdy_o;
+
assign debug = { { now,early,late,too_early,eop,eob,sob,send_at },
{ sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, error, ibs_state[2:0] },
{ 8'b0 },
diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v
index f9cd7d00d..7fb8e3893 100644
--- a/fpga/usrp2/vrt/vita_tx_deframer.v
+++ b/fpga/usrp2/vrt/vita_tx_deframer.v
@@ -1,7 +1,8 @@
module vita_tx_deframer
#(parameter BASE=0,
- parameter MAXCHAN=1)
+ parameter MAXCHAN=1,
+ parameter USE_TRANS_HEADER=0)
(input clk, input reset, input clear, input clear_seqnum,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
@@ -13,6 +14,8 @@ module vita_tx_deframer
output [5+64+16+(32*MAXCHAN)-1:0] sample_fifo_o,
output sample_fifo_src_rdy_o,
input sample_fifo_dst_rdy_i,
+
+ output [31:0] current_seqnum,
// FIFO Levels
output [15:0] fifo_occupied,
@@ -45,58 +48,80 @@ module vita_tx_deframer
reg [1:0] vector_phase;
wire line_done;
- reg seqnum_err;
- reg [3:0] seqnum_reg;
- wire [3:0] seqnum = data_i[19:16];
- wire [3:0] next_seqnum = seqnum_reg + 4'd1;
+ wire [31:0] seqnum = data_i;
+ reg [31:0] seqnum_reg;
+ wire [31:0] next_seqnum = seqnum_reg + 32'd1;
+ wire [3:0] vita_seqnum = data_i[19:16];
+ reg [3:0] vita_seqnum_reg;
+ wire [3:0] next_vita_seqnum = vita_seqnum_reg[3:0] + 4'd1;
+ reg seqnum_err;
+
+ assign current_seqnum = seqnum_reg;
// 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;
-
+ localparam VITA_TRANS_HEADER = 0;
+ localparam VITA_HEADER = 1;
+ localparam VITA_STREAMID = 2;
+ localparam VITA_CLASSID = 3;
+ localparam VITA_CLASSID2 = 4;
+ localparam VITA_SECS = 5;
+ localparam VITA_TICS = 6;
+ localparam VITA_TICS2 = 7;
+ localparam VITA_PAYLOAD = 8;
+ localparam VITA_STORE = 9;
+ localparam VITA_TRAILER = 10;
+ localparam VITA_DUMP = 11;
+
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 vita_eof = (pkt_len==hdr_len);
+ wire eop = eof | vita_eof; // FIXME would ignoring eof allow larger VITA packets?
wire fifo_space;
always @(posedge clk)
if(reset | clear_seqnum)
- seqnum_reg <= 4'hF;
+ begin
+ seqnum_reg <= 32'hFFFF_FFFF;
+ vita_seqnum_reg <= 4'hF;
+ end
else
- if((vita_state==VITA_HEADER) & src_rdy_i)
- seqnum_reg <= seqnum;
+ begin
+ if((vita_state==VITA_TRANS_HEADER) & src_rdy_i)
+ seqnum_reg <= seqnum;
+ if((vita_state==VITA_HEADER) & src_rdy_i)
+ vita_seqnum_reg <= vita_seqnum;
+ end // else: !if(reset | clear_seqnum)
always @(posedge clk)
if(reset | clear)
begin
- vita_state <= VITA_HEADER;
+ vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
{has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg}
<= 0;
seqnum_err <= 0;
end
else
if((vita_state == VITA_STORE) & fifo_space)
- if(eop)
- if(has_trailer_reg)
+ 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_HEADER;
- else
+ vita_state <= VITA_DUMP;
+ else
begin
vita_state <= VITA_PAYLOAD;
pkt_len <= pkt_len - 1;
end
else if(src_rdy_i)
case(vita_state)
+ VITA_TRANS_HEADER :
+ begin
+ seqnum_err <= ~(seqnum == next_seqnum);
+ vita_state <= VITA_HEADER;
+ end
VITA_HEADER :
begin
{has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg}
@@ -113,7 +138,7 @@ module vita_tx_deframer
vita_state <= VITA_TICS;
else
vita_state <= VITA_PAYLOAD;
- seqnum_err <= ~(seqnum == next_seqnum);
+ seqnum_err <= seqnum_err | ~(vita_seqnum == next_vita_seqnum);
end // case: VITA_HEADER
VITA_STREAMID :
if(has_classid_reg)
@@ -151,11 +176,17 @@ module vita_tx_deframer
else
vector_phase <= vector_phase + 1;
VITA_TRAILER :
- vita_state <= VITA_HEADER;
+ if(eof)
+ vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
+ else
+ vita_state <= VITA_DUMP;
+ VITA_DUMP :
+ if(eof)
+ vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
VITA_STORE :
;
default :
- vita_state <= VITA_HEADER;
+ vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER;
endcase // case (vita_state)
assign line_done = (vector_phase == numchan);
@@ -191,7 +222,7 @@ module vita_tx_deframer
// 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,send_time};
+ 12'd0,seqnum_reg[3:0],send_time};
assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ;