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
19module fifo_short
20  #(parameter WIDTH=32)
21   (input clk, input reset, input clear,
22    input [WIDTH-1:0] datain,
23    input src_rdy_i,
24    output dst_rdy_o,
25    output [WIDTH-1:0] dataout,
26    output src_rdy_o,
27    input dst_rdy_i,
28
29    output reg [4:0] space,
30    output reg [4:0] occupied);
31
32   reg full, empty;
33   wire write 	     = src_rdy_i & dst_rdy_o;
34   wire read 	     = dst_rdy_i & src_rdy_o;
35
36   assign dst_rdy_o  = ~full;
37   assign src_rdy_o  = ~empty;
38
39   reg [3:0] 	  a;
40   genvar 	  i;
41
42   generate
43      for (i=0;i<WIDTH;i=i+1)
44	begin : gen_srl16
45	   SRL16E
46	     srl16e(.Q(dataout[i]),
47		    .A0(a[0]),.A1(a[1]),.A2(a[2]),.A3(a[3]),
48		    .CE(write),.CLK(clk),.D(datain[i]));
49	end
50   endgenerate
51
52   always @(posedge clk)
53     if(reset)
54       begin
55	  a <= 0;
56	  empty <= 1;
57	  full <= 0;
58       end
59     else if(clear)
60       begin
61	  a <= 0;
62	  empty <= 1;
63	  full<= 0;
64       end
65     else if(read & ~write)
66       begin
67	  full <= 0;
68	  if(a==0)
69	    empty <= 1;
70	  else
71	    a <= a - 1;
72       end
73     else if(write & ~read)
74       begin
75	  empty <= 0;
76	  if(~empty)
77	    a <= a + 1;
78	  if(a == 14)
79	    full <= 1;
80       end
81
82   // NOTE will fail if you write into a full fifo or read from an empty one
83
84   //////////////////////////////////////////////////////////////
85   // space and occupied are used for diagnostics, not
86   // guaranteed correct
87
88   //assign space = full ? 0 : empty ? 16 : 15-a;
89   //assign occupied = empty ? 0 : full ? 16 : a+1;
90
91   always @(posedge clk)
92     if(reset)
93       space <= 16;
94     else if(clear)
95       space <= 16;
96     else if(read & ~write)
97       space <= space + 1;
98     else if(write & ~read)
99       space <= space - 1;
100
101   always @(posedge clk)
102     if(reset)
103       occupied <= 0;
104     else if(clear)
105       occupied <= 0;
106     else if(read & ~write)
107       occupied <= occupied - 1;
108     else if(write & ~read)
109       occupied <= occupied + 1;
110
111endmodule // fifo_short
112
113