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// Split vita packets longer than one GPIF frame, add padding on short frames 20 21module packet_splitter 22 #(parameter FRAME_LEN=256) 23 (input clk, input reset, input clear, 24 input [7:0] frames_per_packet, 25 input [18:0] data_i, 26 input src_rdy_i, 27 output dst_rdy_o, 28 output [18:0] data_o, 29 output src_rdy_o, 30 input dst_rdy_i, 31 output [31:0] debug0, 32 output [31:0] debug1); 33 34 reg [1:0] state; 35 reg [15:0] length; 36 reg [15:0] frame_len; 37 reg [7:0] frame_count; 38 39 localparam PS_IDLE = 0; 40 localparam PS_FRAME = 1; 41 localparam PS_NEW_FRAME = 2; 42 localparam PS_PAD = 3; 43 44 wire eof_i = data_i[17]; 45 46 always @(posedge clk) 47 if(reset | clear) 48 begin 49 state <= PS_IDLE; 50 frame_count <= 0; 51 end 52 else 53 case(state) 54 PS_IDLE : 55 if(src_rdy_i & dst_rdy_i) 56 begin 57 length <= { data_i[14:0],1'b0}; 58 frame_len <= FRAME_LEN; 59 state <= PS_FRAME; 60 frame_count <= 1; 61 end 62 PS_FRAME : 63 if(src_rdy_i & dst_rdy_i) 64 if((frame_len == 2) & ((length == 2) | eof_i)) 65 state <= PS_IDLE; 66 else if(frame_len == 2) 67 begin 68 length <= length - 1; 69 state <= PS_NEW_FRAME; 70 frame_count <= frame_count + 1; 71 end 72 else if((length == 2)|eof_i) 73 begin 74 frame_len <= frame_len - 1; 75 state <= PS_PAD; 76 end 77 else 78 begin 79 frame_len <= frame_len - 1; 80 length <= length - 1; 81 end 82 PS_NEW_FRAME : 83 if(src_rdy_i & dst_rdy_i) 84 begin 85 frame_len <= FRAME_LEN; 86 if((length == 2)|eof_i) 87 state <= PS_PAD; 88 else 89 begin 90 state <= PS_FRAME; 91 length <= length - 1; 92 end // else: !if((length == 2)|eof_i) 93 end // if (src_rdy_i & dst_rdy_i) 94 95 PS_PAD : 96 if(dst_rdy_i) 97 if(frame_len == 2) 98 state <= PS_IDLE; 99 else 100 frame_len <= frame_len - 1; 101 102 endcase // case (state) 103 104 wire next_state_is_idle = dst_rdy_i & (frame_len==2) & 105 ( (state==PS_PAD) | ( (state==PS_FRAME) & src_rdy_i & ((length==2)|eof_i) ) ); 106 107 108 109 110 assign dst_rdy_o = dst_rdy_i & (state != PS_PAD); 111 assign src_rdy_o = src_rdy_i | (state == PS_PAD); 112 113 wire eof_out = (frame_len == 2) & (state != PS_IDLE) & (state != PS_NEW_FRAME); 114 wire sof_out = (state == PS_IDLE) | (state == PS_NEW_FRAME); 115 wire occ_out = eof_out & next_state_is_idle & (frames_per_packet != frame_count); 116 117 wire [15:0] data_out = data_i[15:0]; 118 assign data_o = {occ_out, eof_out, sof_out, data_out}; 119 120 assign debug0 = { 8'd0, dst_rdy_o, src_rdy_o, next_state_is_idle, eof_out, sof_out, occ_out, state[1:0], frame_count[7:0], frames_per_packet[7:0] }; 121 assign debug1 = { length[15:0], frame_len[15:0] }; 122 123endmodule // packet_splitter 124