diff options
author | Matt Ettus <matt@ettus.com> | 2010-08-25 18:22:44 -0700 |
---|---|---|
committer | Matt Ettus <matt@ettus.com> | 2010-08-25 18:22:44 -0700 |
commit | 5583e21ae6ff5832d4bdd935f42b4b13f1ad683a (patch) | |
tree | 4b8044e3be49dfe2b3b259d9b40fb6d40e931088 /usrp2/vrt | |
parent | d0815967a27d01059230679e2d635377ac8c18b3 (diff) | |
parent | 9fa6105a49f41e39321438086b00ab12d8437828 (diff) | |
download | uhd-5583e21ae6ff5832d4bdd935f42b4b13f1ad683a.tar.gz uhd-5583e21ae6ff5832d4bdd935f42b4b13f1ad683a.tar.bz2 uhd-5583e21ae6ff5832d4bdd935f42b4b13f1ad683a.zip |
Merge branch 'tx_policy' into u2p_txpolicy
* tx_policy: (21 commits)
clean up DAC inversion and swapping to match schematics
Clean up iq swapping on RX. It is now swapped in the top level. widened muxes to 4 bits to match tx side and handle more ADCs in future
rx error context packets should not be marked as errors in the fifo
added compat number to usrp2 readback mux
makefile dependency fix for second expansion
provide a way to get out of the error state without processor intervention
sequence number reset upon programming streamid
attempt at avoiding infinite error messages
implemented "next packet" and "next burst" policies
sequence errors can happen on start of burst as well.
more informative error codes
cleaner error handling
introduce new error types
test mux and gen_context_pkt
this is an output file, it shouldn't be checked in
insert protocol engine flags when requested
move the streamid so it isn't at the same address as clear_state
connect the demux
fix a typo
tx error packets now muxed into the ethernet stream back to the host
...
Diffstat (limited to 'usrp2/vrt')
-rw-r--r-- | usrp2/vrt/Makefile.srcs | 2 | ||||
-rw-r--r-- | usrp2/vrt/gen_context_pkt.v | 72 | ||||
-rw-r--r-- | usrp2/vrt/vita_rx_framer.v | 2 | ||||
-rw-r--r-- | usrp2/vrt/vita_tx_chain.v | 71 | ||||
-rw-r--r-- | usrp2/vrt/vita_tx_control.v | 115 | ||||
-rw-r--r-- | usrp2/vrt/vita_tx_deframer.v | 30 |
6 files changed, 260 insertions, 32 deletions
diff --git a/usrp2/vrt/Makefile.srcs b/usrp2/vrt/Makefile.srcs index 07c62224b..dc4bd8c96 100644 --- a/usrp2/vrt/Makefile.srcs +++ b/usrp2/vrt/Makefile.srcs @@ -10,4 +10,6 @@ vita_rx_control.v \ vita_rx_framer.v \ vita_tx_control.v \ vita_tx_deframer.v \ +vita_tx_chain.v \ +gen_context_pkt.v \ )) diff --git a/usrp2/vrt/gen_context_pkt.v b/usrp2/vrt/gen_context_pkt.v new file mode 100644 index 000000000..780a027ba --- /dev/null +++ b/usrp2/vrt/gen_context_pkt.v @@ -0,0 +1,72 @@ + + +module gen_context_pkt + #(parameter PROT_ENG_FLAGS=1) + (input clk, input reset, input clear, + input trigger, output sent, + input [31:0] streamid, + input [63:0] vita_time, + input [31:0] message, + output [35:0] data_o, output src_rdy_o, input dst_rdy_i); + + localparam CTXT_IDLE = 0; + 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_DONE = 8; + + reg [33:0] data_int; + wire src_rdy_int, dst_rdy_int; + wire [3:0] seqno = 0; + reg [3:0] ctxt_state; + reg [63:0] err_time; + + always @(posedge clk) + if(reset | clear) + ctxt_state <= CTXT_IDLE; + else + case(ctxt_state) + CTXT_IDLE : + if(trigger) + begin + err_time <= vita_time; + if(PROT_ENG_FLAGS) + ctxt_state <= CTXT_PROT_ENG; + else + ctxt_state <= CTXT_HEADER; + end + + CTXT_DONE : + if(~trigger) + ctxt_state <= CTXT_IDLE; + + default : + if(dst_rdy_int) + ctxt_state <= ctxt_state + 1; + endcase // case (ctxt_state) + + assign src_rdy_int = ~( (ctxt_state == CTXT_IDLE) | (ctxt_state == CTXT_DONE) ); + + 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_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 }; + default : data_int <= {2'b00, 32'b00}; + endcase // case (ctxt_state) + + fifo_short #(.WIDTH(34)) ctxt_fifo + (.clk(clk), .reset(reset), .clear(clear), + .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int), + .dataout(data_o[33:0]), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); + assign data_o[35:34] = 2'b00; + +endmodule // gen_context_pkt diff --git a/usrp2/vrt/vita_rx_framer.v b/usrp2/vrt/vita_rx_framer.v index fd82263d0..235817941 100644 --- a/usrp2/vrt/vita_rx_framer.v +++ b/usrp2/vrt/vita_rx_framer.v @@ -128,7 +128,7 @@ module vita_rx_framer 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_TICS2 : pkt_fifo_line <= {2'b00,vita_time_fifo_o[31:0]}; - VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b11,28'd0,flags_fifo_o}; + VITA_ERR_PAYLOAD : pkt_fifo_line <= {2'b10,28'd0,flags_fifo_o}; //VITA_ERR_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer}; default : pkt_fifo_line <= 34'h0_FFFF_FFFF; diff --git a/usrp2/vrt/vita_tx_chain.v b/usrp2/vrt/vita_tx_chain.v new file mode 100644 index 000000000..662cdca62 --- /dev/null +++ b/usrp2/vrt/vita_tx_chain.v @@ -0,0 +1,71 @@ + +module vita_tx_chain + #(parameter BASE_CTRL=0, + parameter BASE_DSP=0, + parameter REPORT_ERROR=0, + parameter PROT_ENG_FLAGS=0) + (input clk, input reset, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + 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 [15:0] dac_a, output [15:0] dac_b, + output underrun, output run, + output [31:0] debug); + + localparam MAXCHAN = 1; + localparam FIFOWIDTH = 5+64+16+(32*MAXCHAN); + + 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; + + wire error; + wire [31:0] error_code; + wire clear_seqnum; + + assign underrun = error; + 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 + (.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), + .debug(debug_vtd) ); + + vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control + (.clk(clk), .reset(reset), .clear(clear_vita), + .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), + .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), + .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 + + assign debug = debug_vtc | debug_vtd; + +endmodule // vita_tx_chain diff --git a/usrp2/vrt/vita_tx_control.v b/usrp2/vrt/vita_tx_control.v index bffc64e52..d0516bec8 100644 --- a/usrp2/vrt/vita_tx_control.v +++ b/usrp2/vrt/vita_tx_control.v @@ -6,10 +6,11 @@ module vita_tx_control input set_stb, input [7:0] set_addr, input [31:0] set_data, input [63:0] vita_time, - output underrun, + output error, + output reg [31:0] error_code, // From vita_tx_deframer - input [4+64+WIDTH-1:0] sample_fifo_i, + input [5+64+16+WIDTH-1:0] sample_fifo_i, input sample_fifo_src_rdy_i, output sample_fifo_dst_rdy_o, @@ -20,14 +21,17 @@ module vita_tx_control output [31:0] debug ); - - assign sample = sample_fifo_i[4+64+WIDTH-1:4+64]; + + assign sample = sample_fifo_i[5+64+16+WIDTH-1:5+64+16]; 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 [15:0] seqnum = sample_fifo_i[79:64]; + wire eop = sample_fifo_i[80]; + wire eob = sample_fifo_i[81]; + wire sob = sample_fifo_i[82]; + wire send_at = sample_fifo_i[83]; + wire seqnum_err = sample_fifo_i[84]; + wire now, early, late, too_early; // FIXME ignore too_early for now for timing reasons @@ -40,8 +44,15 @@ module vita_tx_control 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; + localparam IBS_ERROR = 3; + localparam IBS_ERROR_DONE = 4; + localparam IBS_ERROR_WAIT = 5; + + 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}; + wire [31:0] CODE_UNDERRUN_MIDPKT = {seqnum,16'd16}; + wire [31:0] CODE_SEQ_ERROR_MIDBURST = {seqnum,16'd32}; reg [2:0] ibs_state; @@ -50,22 +61,49 @@ module vita_tx_control (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(),.changed(clear_state)); + wire [31:0] error_policy; + setting_reg #(.my_addr(BASE+3)) sr_error_policy + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out(error_policy),.changed()); + + wire policy_wait = error_policy[0]; + wire policy_next_packet = error_policy[1]; + wire policy_next_burst = error_policy[2]; + reg send_error; + always @(posedge clk) if(reset | clear_state) - ibs_state <= 0; + begin + ibs_state <= IBS_IDLE; + send_error <= 0; + end else case(ibs_state) IBS_IDLE : if(sample_fifo_src_rdy_i) - if(~send_at | now) + if(seqnum_err) + begin + ibs_state <= IBS_ERROR; + error_code <= CODE_SEQ_ERROR; + send_error <= 1; + end + else if(~send_at | now) ibs_state <= IBS_RUN; else if(late | too_early) - ibs_state <= IBS_UNDERRUN; + begin + ibs_state <= IBS_ERROR; + error_code <= CODE_TIME_ERROR; + send_error <= 1; + end IBS_RUN : if(strobe) if(~sample_fifo_src_rdy_i) - ibs_state <= IBS_UNDERRUN; + begin + ibs_state <= IBS_ERROR; + error_code <= CODE_UNDERRUN_MIDPKT; + send_error <= 1; + end else if(eop) if(eob) ibs_state <= IBS_IDLE; @@ -74,24 +112,53 @@ module vita_tx_control IBS_CONT_BURST : if(strobe) - ibs_state <= IBS_UNDERRUN_DONE; + begin + if(policy_next_packet) + ibs_state <= IBS_ERROR_DONE; + else if(policy_wait) + ibs_state <= IBS_ERROR_WAIT; + else + ibs_state <= IBS_ERROR; + error_code <= CODE_UNDERRUN; + send_error <= 1; + end else if(sample_fifo_src_rdy_i) - ibs_state <= IBS_RUN; + if(seqnum_err) + begin + ibs_state <= IBS_ERROR; + error_code <= CODE_SEQ_ERROR_MIDBURST; + send_error <= 1; + end + else + ibs_state <= IBS_RUN; - IBS_UNDERRUN : - if(sample_fifo_src_rdy_i & eop) - ibs_state <= IBS_UNDERRUN_DONE; + IBS_ERROR : + begin + send_error <= 0; + if(sample_fifo_src_rdy_i & eop) + if(policy_next_packet | (policy_next_burst & eob)) + ibs_state <= IBS_IDLE; + else if(policy_wait) + ibs_state <= IBS_ERROR_WAIT; + end - IBS_UNDERRUN_DONE : - ; + IBS_ERROR_DONE : + begin + send_error <= 0; + ibs_state <= IBS_IDLE; + end + + IBS_ERROR_WAIT : + send_error <= 0; endcase // case (ibs_state) - assign sample_fifo_dst_rdy_o = (ibs_state == IBS_UNDERRUN) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout + 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 underrun = (ibs_state == IBS_UNDERRUN_DONE); + //assign error = (ibs_state == IBS_ERROR_DONE); + assign error = send_error; 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] }, + { sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, error, ibs_state[2:0] }, { 8'b0 }, { 8'b0 } }; diff --git a/usrp2/vrt/vita_tx_deframer.v b/usrp2/vrt/vita_tx_deframer.v index 3b95f5902..f9cd7d00d 100644 --- a/usrp2/vrt/vita_tx_deframer.v +++ b/usrp2/vrt/vita_tx_deframer.v @@ -2,7 +2,7 @@ module vita_tx_deframer #(parameter BASE=0, parameter MAXCHAN=1) - (input clk, input reset, input clear, + (input clk, input reset, input clear, input clear_seqnum, input set_stb, input [7:0] set_addr, input [31:0] set_data, // To FIFO interface of Buffer Pool @@ -10,7 +10,7 @@ module vita_tx_deframer input src_rdy_i, output dst_rdy_o, - output [4+64+(32*MAXCHAN)-1:0] sample_fifo_o, + output [5+64+16+(32*MAXCHAN)-1:0] sample_fifo_o, output sample_fifo_src_rdy_o, input sample_fifo_dst_rdy_i, @@ -21,6 +21,8 @@ module vita_tx_deframer output [31:0] debug ); + localparam FIFOWIDTH = 5+64+16+(32*MAXCHAN); + wire [1:0] numchan; setting_reg #(.my_addr(BASE), .at_reset(0), .width(2)) sr_numchan (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), @@ -36,14 +38,18 @@ module vita_tx_deframer 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; + 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; + // Output FIFO for packetized data localparam VITA_HEADER = 0; localparam VITA_STREAMID = 1; @@ -61,6 +67,13 @@ module vita_tx_deframer wire eop = eof | (pkt_len==hdr_len); // FIXME would ignoring eof allow larger VITA packets? wire fifo_space; + + always @(posedge clk) + if(reset | clear_seqnum) + seqnum_reg <= 4'hF; + else + if((vita_state==VITA_HEADER) & src_rdy_i) + seqnum_reg <= seqnum; always @(posedge clk) if(reset | clear) @@ -68,6 +81,7 @@ module vita_tx_deframer 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; + seqnum_err <= 0; end else if((vita_state == VITA_STORE) & fifo_space) @@ -99,6 +113,7 @@ module vita_tx_deframer vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; + seqnum_err <= ~(seqnum == next_seqnum); end // case: VITA_HEADER VITA_STREAMID : if(has_classid_reg) @@ -145,7 +160,7 @@ module vita_tx_deframer assign line_done = (vector_phase == numchan); - wire [4+64+32*MAXCHAN-1:0] fifo_i; + wire [FIFOWIDTH-1:0] fifo_i; reg [63:0] send_time; reg [31:0] sample_a, sample_b, sample_c, sample_d; @@ -169,13 +184,14 @@ module vita_tx_deframer endcase // case (vector_phase) wire store = (vita_state == VITA_STORE); - fifo_short #(.WIDTH(4+64+32*MAXCHAN)) short_tx_q + 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,has_secs_reg,is_sob_reg,is_eob_reg,eop,send_time}; + 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}; assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; |