module vita_tx_deframer #(parameter BASE=0, parameter MAXCHAN=1) (input clk, input reset, input clear, input set_stb, input [7:0] set_addr, input [31:0] set_data, // To FIFO interface of Buffer Pool input [35:0] data_i, input src_rdy_i, output dst_rdy_o, output [4+64+(32*MAXCHAN)-1:0] sample_fifo_o, output sample_fifo_src_rdy_o, input sample_fifo_dst_rdy_i, // FIFO Levels output [15:0] fifo_occupied, output fifo_full, output fifo_empty, output [31:0] debug ); wire [1:0] numchan; setting_reg #(.my_addr(BASE), .at_reset(0)) sr_numchan (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(numchan),.changed()); reg [3:0] vita_state; wire has_streamid, has_classid, has_secs, has_tics, has_trailer; assign has_streamid = (data_i[31:28]==4'b0001); assign has_classid = data_i[27]; assign has_secs = ~(data_i[23:22]==2'b00); assign has_tics = ~(data_i[21:20]==2'b00); assign has_trailer = data_i[26]; 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; // 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; 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 fifo_space; always @(posedge clk) if(reset | clear) begin 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; end else if((vita_state == VITA_STORE) & fifo_space) if(eop) if(has_trailer_reg) vita_state <= VITA_TRAILER; else vita_state <= VITA_HEADER; else begin vita_state <= VITA_PAYLOAD; pkt_len <= pkt_len - 1; end else if(src_rdy_i) case(vita_state) VITA_HEADER : begin {has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg} <= {has_streamid, has_classid, has_secs, has_tics, has_trailer, is_sob, is_eob}; pkt_len <= data_i[15:0]; vector_phase <= 0; if(has_streamid) vita_state <= VITA_STREAMID; else if(has_classid) vita_state <= VITA_CLASSID; else if(has_secs) vita_state <= VITA_SECS; else if(has_tics) vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; end // case: VITA_HEADER VITA_STREAMID : if(has_classid_reg) vita_state <= VITA_CLASSID; else if(has_secs_reg) vita_state <= VITA_SECS; else if(has_tics_reg) vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; VITA_CLASSID : vita_state <= VITA_CLASSID2; VITA_CLASSID2 : if(has_secs_reg) vita_state <= VITA_SECS; else if(has_tics_reg) vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; VITA_SECS : if(has_tics_reg) vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; VITA_TICS : 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_TRAILER : vita_state <= VITA_HEADER; VITA_STORE : ; default : vita_state <= VITA_HEADER; endcase // case (vita_state) assign line_done = (vector_phase == numchan); wire [4+64+32*MAXCHAN-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 : send_time[63:32] <= data_i[31:0]; VITA_TICS2 : send_time[31:0] <= data_i[31:0]; VITA_STORE, VITA_HEADER : send_time[63:0] <= 64'd0; endcase // case (vita_state) 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); fifo_short #(.WIDTH(4+64+32*MAXCHAN)) 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 dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; assign debug = { { 8'b0 }, { 8'b0 }, { eof, line_done, store, fifo_space, src_rdy_i, dst_rdy_o, vector_phase[1:0] }, { has_secs_reg, is_sob_reg, is_eob_reg, eop, vita_state[3:0] } }; endmodule // vita_tx_deframer