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// Pads a packet out to the minimum length
20//  Packets already longer than min length are unchanged
21
22
23module fifo19_pad
24  #(parameter LENGTH=16,
25    parameter PAD_VALUE=0)
26   (input clk, input reset, input clear,
27    input [18:0] data_i,
28    input src_rdy_i,
29    output dst_rdy_o,
30    output [18:0] data_o,
31    output src_rdy_o,
32    input dst_rdy_i);
33
34   reg [15:0] count;
35   reg [1:0]  pad_state;
36   localparam PAD_IDLE = 0;
37   localparam PAD_TOOSHORT = 1;
38   localparam PAD_LONGENOUGH = 2;
39   localparam PAD_PADDING = 3;
40
41   always @(posedge clk)
42     if(reset | clear)
43       pad_state <= PAD_IDLE;
44     else
45       case(pad_state)
46	 PAD_IDLE :
47	   begin
48	      count <= 1;
49	      pad_state <= PAD_TOOSHORT;
50	   end
51	 PAD_TOOSHORT :
52	   if(src_rdy_i & dst_rdy_i)
53	     begin
54		count <= count + 1;
55		if(data_i[17])
56		  pad_state <= PAD_PADDING;
57		else if(count == (LENGTH-1))
58		  pad_state <= PAD_LONGENOUGH;
59	     end
60	 PAD_PADDING :
61	   if(dst_rdy_i)
62	     begin
63		count <= count + 1;
64		if(count == LENGTH)
65		  pad_state <= PAD_IDLE;
66	     end
67	 PAD_LONGENOUGH :
68	   if(src_rdy_i & dst_rdy_i & data_i[17])
69	     pad_state <= PAD_IDLE;
70       endcase // case (pad_state)
71
72   wire passthru = (pad_state == PAD_TOOSHORT) | (pad_state == PAD_LONGENOUGH);
73
74   assign dst_rdy_o = passthru ? dst_rdy_i : 1'b0;
75   assign src_rdy_o = passthru ? src_rdy_i : (pad_state == PAD_PADDING);
76
77   assign data_o[15:0] = (pad_state == PAD_PADDING) ? PAD_VALUE : data_i[15:0];
78   assign data_o[16] = (count == 1);
79   assign data_o[17] = (pad_state == PAD_LONGENOUGH) ? data_i[17] : (count == LENGTH);
80   assign data_o[18] = (pad_state == PAD_LONGENOUGH) ? data_i[18] : 1'b0;
81
82
83endmodule // fifo19_pad
84