diff options
author | Josh Blum <josh@joshknows.com> | 2010-11-23 09:57:33 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-11-23 09:57:33 -0800 |
commit | d35b7327710f08f96f2cfb93bcc28f14515ea9bb (patch) | |
tree | 0cfe31630905570c776a45746fcb3e2011d3dabd /fpga/usrp2/vrt | |
parent | 6741de7b4545bb33d22cc6508e121023dd1a7a8c (diff) | |
parent | 768af46dc01d036999cb60ff16df4215d014c906 (diff) | |
download | uhd-d35b7327710f08f96f2cfb93bcc28f14515ea9bb.tar.gz uhd-d35b7327710f08f96f2cfb93bcc28f14515ea9bb.tar.bz2 uhd-d35b7327710f08f96f2cfb93bcc28f14515ea9bb.zip |
Merge branch 'flow_ctrl' into next
Diffstat (limited to 'fpga/usrp2/vrt')
-rw-r--r-- | fpga/usrp2/vrt/Makefile.srcs | 1 | ||||
-rw-r--r-- | fpga/usrp2/vrt/gen_context_pkt.v | 38 | ||||
-rw-r--r-- | fpga/usrp2/vrt/trigger_context_pkt.v | 52 | ||||
-rw-r--r-- | fpga/usrp2/vrt/vita_tx_chain.v | 51 | ||||
-rw-r--r-- | fpga/usrp2/vrt/vita_tx_control.v | 17 | ||||
-rw-r--r-- | fpga/usrp2/vrt/vita_tx_deframer.v | 89 |
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) ; |