diff options
Diffstat (limited to 'fpga/usrp2/vrt')
| -rw-r--r-- | fpga/usrp2/vrt/Makefile.srcs | 2 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/gen_context_pkt.v | 72 | ||||
| -rwxr-xr-x | fpga/usrp2/vrt/vita_rx.build | 2 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_control.v | 5 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_framer.v | 47 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_tb.v | 11 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_chain.v | 71 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_control.v | 115 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_tx_deframer.v | 32 | 
9 files changed, 305 insertions, 52 deletions
diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs index 07c62224b..dc4bd8c96 100644 --- a/fpga/usrp2/vrt/Makefile.srcs +++ b/fpga/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/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v new file mode 100644 index 000000000..780a027ba --- /dev/null +++ b/fpga/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/fpga/usrp2/vrt/vita_rx.build b/fpga/usrp2/vrt/vita_rx.build index f6d2d75a3..010d1be6e 100755 --- a/fpga/usrp2/vrt/vita_rx.build +++ b/fpga/usrp2/vrt/vita_rx.build @@ -1 +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 +iverilog -Wimplict -Wportbind -y ../models -y . -y ../control_lib/ -y ../fifo -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/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v index 742dd47e0..93673d292 100644 --- a/fpga/usrp2/vrt/vita_rx_control.v +++ b/fpga/usrp2/vrt/vita_rx_control.v @@ -67,7 +67,7 @@ module vita_rx_control     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,reload_pre,numlines_pre,rcvtime_pre}),  +      .dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),        .read(read_ctrl), .empty(empty_ctrl),        .occupied(command_queue_len), .space() ); @@ -98,7 +98,7 @@ module vita_rx_control        .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i),        .space(), .occupied() ); -   // Inband Signallling State Machine +   // Inband Signalling State Machine     time_compare        time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late)); @@ -189,4 +189,3 @@ module vita_rx_control  		       { 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/fpga/usrp2/vrt/vita_rx_framer.v b/fpga/usrp2/vrt/vita_rx_framer.v index f3a81664a..fd82263d0 100644 --- a/fpga/usrp2/vrt/vita_rx_framer.v +++ b/fpga/usrp2/vrt/vita_rx_framer.v @@ -99,7 +99,7 @@ module vita_rx_framer     localparam VITA_ERR_TICS 	 = 12;     localparam VITA_ERR_TICS2 	 = 13;     localparam VITA_ERR_PAYLOAD 	 = 14; -   localparam VITA_ERR_TRAILER 	 = 15; +   localparam VITA_ERR_TRAILER 	 = 15; // Extension context packets have no trailer     always @(posedge clk)       if(reset | clear_pkt_count) @@ -107,17 +107,30 @@ module vita_rx_framer       else if((vita_state == VITA_TRAILER) & pkt_fifo_rdy)         pkt_count <= pkt_count + 1; +   wire 	  has_streamid = vita_header[28]; +   wire 	  has_trailer = vita_header[26]; +   reg 		  trl_eob; +        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]}; +       // Data packets are IF Data packets with or w/o streamid, no classid, with trailer +       VITA_HEADER : pkt_fifo_line <= {2'b01,3'b000,vita_header[28],2'b01,vita_header[25:20],pkt_count,vita_pkt_len}; +       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_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}; +       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_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_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_TRAILER : pkt_fifo_line <= {2'b11,vita_trailer}; +                default : pkt_fifo_line <= 34'h0_FFFF_FFFF;         endcase // case (vita_state) @@ -141,6 +154,11 @@ module vita_rx_framer  	 end         else if(pkt_fifo_rdy)  	 case(vita_state) +	   VITA_HEADER : +	     if(has_streamid) +	       vita_state <= VITA_STREAMID; +	     else +	       vita_state <= VITA_SECS;  	   VITA_PAYLOAD :  	     if(sample_fifo_src_rdy_i)  	       begin @@ -148,6 +166,7 @@ module vita_rx_framer  		    begin  		       sample_phase <= 0;  		       sample_ctr   <= sample_ctr + 1; +		       trl_eob <= flags_fifo_o[0];  		       if(sample_ctr == samples_per_packet)  			 vita_state <= VITA_TRAILER;  		       if(|flags_fifo_o)   // end early if any flag is set @@ -155,8 +174,10 @@ module vita_rx_framer  		    end  		  else  		    sample_phase <= sample_phase + 1; -	       end -	   VITA_TRAILER, VITA_ERR_TRAILER : +	       end // if (sample_fifo_src_rdy_i) +	   VITA_ERR_PAYLOAD : +	     vita_state <= VITA_IDLE; +	   VITA_TRAILER :  	     vita_state <= VITA_IDLE;  	   default :  	     vita_state 	   <= vita_state + 1; @@ -172,7 +193,7 @@ module vita_rx_framer         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 : +       VITA_ERR_HEADER, VITA_ERR_STREAMID, VITA_ERR_SECS, VITA_ERR_TICS, VITA_ERR_TICS2, VITA_ERR_PAYLOAD :  	 req_write_pkt_fifo <= 1;         default :  	 req_write_pkt_fifo <= 0; @@ -192,7 +213,7 @@ module vita_rx_framer  				   ( ((vita_state==VITA_PAYLOAD) &   				      (sample_phase == (numchan-4'd1)) &   				      ~|flags_fifo_o[3:1]) | -				     (vita_state==VITA_ERR_TRAILER)); +				     (vita_state==VITA_ERR_PAYLOAD));     assign debug_rx  = vita_state; diff --git a/fpga/usrp2/vrt/vita_rx_tb.v b/fpga/usrp2/vrt/vita_rx_tb.v index b4fda9622..3e01e2ee2 100644 --- a/fpga/usrp2/vrt/vita_rx_tb.v +++ b/fpga/usrp2/vrt/vita_rx_tb.v @@ -3,8 +3,8 @@  module vita_rx_tb;     localparam DECIM  = 8'd4; -   localparam MAXCHAN=4; -   localparam NUMCHAN=4; +   localparam MAXCHAN=1; +   localparam NUMCHAN=1;     reg clk 	     = 0;     reg reset 	     = 1; @@ -94,7 +94,7 @@ module vita_rx_tb;  	@(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(6,32'hF0000000);  // 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 @@ -111,8 +111,13 @@ module vita_rx_tb;  	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 +	#100000; +	$display("\nChained, break chain\n");  	queue_rx_cmd(1,1,8,32'h0,32'h0);  // chained, but break chain  	#100000; +	$display("\nSingle packet\n"); +	queue_rx_cmd(1,0,8,32'h0,32'h0);  // send imm, single packet +	#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 diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v new file mode 100644 index 000000000..662cdca62 --- /dev/null +++ b/fpga/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/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v index bffc64e52..d0516bec8 100644 --- a/fpga/usrp2/vrt/vita_tx_control.v +++ b/fpga/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/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v index 220d3b061..f9cd7d00d 100644 --- a/fpga/usrp2/vrt/vita_tx_deframer.v +++ b/fpga/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,8 +21,10 @@ 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)) sr_numchan +   setting_reg #(.my_addr(BASE), .at_reset(0), .width(2)) sr_numchan       (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),        .in(set_data),.out(numchan),.changed()); @@ -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) ;  | 
