1// 2// Copyright 2011 Ettus Research LLC 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU General Public License for more details. 13// 14// You should have received a copy of the GNU General Public License 15// along with this program. If not, see <http://www.gnu.org/licenses/>. 16// 17 18 19// This has 3 functions: 20// Correct the VITA packet length 21// [optional] Frame DSP packets with an header line to be handled by the protocol machine 22// Hold on to the packet until there is a complete one before allowing to leave 23 24module dsp_framer36 25 #(parameter BUF_SIZE = 9, 26 parameter PORT_SEL = 0, 27 parameter PROT_ENG_FLAGS = 1) 28 (input clk, input reset, input clear, 29 input [35:0] data_i, input src_rdy_i, output dst_rdy_o, 30 output [35:0] data_o, output src_rdy_o, input dst_rdy_i); 31 32 wire dfifo_in_dst_rdy, dfifo_in_src_rdy, dfifo_out_dst_rdy, dfifo_out_src_rdy; 33 wire tfifo_in_dst_rdy, tfifo_in_src_rdy, tfifo_out_dst_rdy, tfifo_out_src_rdy; 34 35 wire do_xfer_in = dfifo_in_src_rdy & dfifo_in_dst_rdy; 36 wire do_xfer_out = src_rdy_o & dst_rdy_i; 37 38 wire have_space = dfifo_in_dst_rdy & tfifo_in_dst_rdy; 39 reg [15:0] pkt_len_in, pkt_len_out; 40 wire [15:0] tfifo_data; 41 wire [35:0] dfifo_out_data; 42 43 assign dst_rdy_o = have_space; 44 assign dfifo_in_src_rdy = src_rdy_i & have_space; 45 46 fifo_cascade #(.WIDTH(36), .SIZE(BUF_SIZE)) dfifo 47 (.clk(clk), .reset(reset), .clear(clear), 48 .datain(data_i), .src_rdy_i(dfifo_in_src_rdy), .dst_rdy_o(dfifo_in_dst_rdy), 49 .dataout(dfifo_out_data), .src_rdy_o(dfifo_out_src_rdy), .dst_rdy_i(dfifo_out_dst_rdy) ); 50 51 fifo_short #(.WIDTH(16)) tfifo 52 (.clk(clk), .reset(reset), .clear(clear), 53 .datain(pkt_len_in), .src_rdy_i(tfifo_in_src_rdy), .dst_rdy_o(tfifo_in_dst_rdy), 54 .dataout(tfifo_data), .src_rdy_o(tfifo_out_src_rdy), .dst_rdy_i(tfifo_out_dst_rdy), 55 .space(), .occupied() ); 56 57 // FIXME won't handle single-line packets, will show wrong length 58 always @(posedge clk) 59 if(reset | clear) 60 pkt_len_in <= 0; 61 else if(do_xfer_in) 62 if(data_i[32]) // sof 63 pkt_len_in <= 2; // fixes off by one since number is stored before increment 64 else 65 pkt_len_in <= pkt_len_in + 1; 66 67 assign tfifo_in_src_rdy = do_xfer_in & data_i[33]; // store length when at eof in 68 assign tfifo_out_dst_rdy = do_xfer_out & data_o[33]; // remove length from list at eof out 69 70 always @(posedge clk) 71 if(reset | clear) 72 pkt_len_out <= (PROT_ENG_FLAGS ? 1'b0 : 1'b1); 73 else if(do_xfer_out) 74 if(dfifo_out_data[33]) // eof 75 pkt_len_out <= (PROT_ENG_FLAGS ? 1'b0 : 1'b1); 76 else 77 pkt_len_out <= pkt_len_out + 1; 78 79 assign dfifo_out_dst_rdy = do_xfer_out & (pkt_len_out != 0); 80 81 wire [1:0] port_sel_bits = PORT_SEL; 82 83 assign data_o = (pkt_len_out == 0) ? {3'b000, 1'b1, 13'b0, port_sel_bits, 1'b1, tfifo_data[13:0],2'b00} : 84 (pkt_len_out == 1) ? {3'b000, (PROT_ENG_FLAGS ? 1'b0: 1'b1), dfifo_out_data[31:16],tfifo_data} : 85 {dfifo_out_data[35:33], 1'b0, dfifo_out_data[31:0] }; 86 87 assign src_rdy_o = dfifo_out_src_rdy & tfifo_out_src_rdy; 88 89endmodule // dsp_framer36 90