new fifos copied over from other project
[debian/gnuradio] / usrp2 / fpga / control_lib / giantfifo.v
1
2
3
4 module giantfifo
5   #(parameter WIDTH=36)
6     (input clk, input rst,
7      input [WIDTH-1:0] datain,
8      output [WIDTH-1:0] dataout,
9      input read,
10      input write,
11      input clear,
12      output full,
13      output empty,
14      output [15:0] space,
15      output [15:0] occupied,
16      
17      // External RAM
18      inout [17:0] RAM_D,
19      output reg [18:0] RAM_A,
20      output RAM_CE1n,
21      output RAM_CENn,
22      output reg RAM_CLK,
23      output reg RAM_WEn,
24      output RAM_OEn,
25      output RAM_LDn
26      );
27
28    wire [4:0] path1_occ, path2_space;
29    wire [35:0] path1_dat, path2_dat;
30    
31    shortfifo #(.WIDTH(WIDTH)) sf1
32      (.clk(clk),.rst(rst),.clear(clear),
33       .datain(datain),.write(write),.full(full),
34       .dataout(path1_dat),.read(path1_read),.empty(path1_empty),
35       .space(),.occupied(path1_occ) );
36    wire       path1_almost_empty = (path1_occ == 5'd1);
37    
38    shortfifo #(.WIDTH(WIDTH)) sf2
39      (.clk(clk),.rst(rst),.clear(clear),
40       .datain(path2_dat),.write(path2_write),.full(path2_full),
41       .dataout(dataout),.read(read),.empty(empty),
42       .space(path2_space),.occupied() );
43    wire       path2_almost_full = (path2_space == 5'd1);
44         
45    assign     RAM_CE1n = 1'b0;
46    assign     RAM_CENn = 1'b0;
47    always @(clk)
48      RAM_CLK <= #2 clk;
49    assign     RAM_LDn = 1'b0;
50
51    // State machine
52    wire       write_now, read_now, idle, phase;
53    reg        ram_full, ram_empty;
54    
55    reg [17:0] read_ptr, write_ptr;
56    reg [2:0]  zbt_state;
57
58    localparam ZBT_IDLE = 0;
59    localparam ZBT_WRITE_UPPER = 2;
60    localparam ZBT_WRITE_LOWER = 3;
61    localparam ZBT_READ_UPPER = 4;
62    localparam ZBT_READ_LOWER = 5;
63
64    wire       can_write = ~ram_full & ~path1_empty;
65    wire       can_write_chain = can_write & ~path1_almost_empty;
66
67    wire       can_read = ~ram_empty & ~path2_full;
68    wire       can_read_chain = can_read & ~path2_almost_full;
69    
70    assign     phase = zbt_state[0];
71
72    reg [17:0] ram_occupied;
73    wire       ram_almost_empty = (write_ptr == (read_ptr+1'b1));
74    wire       ram_almost_full = ((write_ptr+1'b1) == read_ptr);
75
76    always @(posedge clk)
77      if(rst | clear)
78        begin
79           zbt_state <= ZBT_IDLE;
80           write_ptr <= 0;
81           read_ptr <= 0;
82           ram_full <= 0;
83           ram_empty <= 1;
84           ram_occupied <= 0;
85        end
86      else
87        case(zbt_state)
88          ZBT_IDLE : 
89            if(can_read) 
90              zbt_state <= ZBT_READ_UPPER;
91            else if(can_write)
92              zbt_state <= ZBT_WRITE_UPPER;
93          
94          ZBT_WRITE_UPPER : 
95            begin
96               zbt_state <= ZBT_WRITE_LOWER;
97               ram_occupied <= ram_occupied + 1;
98               ram_empty <= 0;
99               if(ram_occupied == 18'd10)
100                 ram_full <= 1;
101            end
102          ZBT_WRITE_LOWER : 
103            begin
104               write_ptr <= write_ptr + 1;
105               if(can_read_chain) 
106                 zbt_state <= ZBT_READ_UPPER;
107               else if(can_write_chain)
108                 zbt_state <= ZBT_WRITE_UPPER;
109               else
110                 zbt_state <= ZBT_IDLE;
111            end
112          ZBT_READ_UPPER : 
113            begin
114               zbt_state <= ZBT_READ_LOWER;
115               ram_occupied <= ram_occupied - 1;
116               ram_full <= 0;
117               if(ram_occupied == 18'd1)
118                 ram_empty <= 1;
119            end
120          ZBT_READ_LOWER :
121            begin
122               read_ptr <= read_ptr + 1;
123               if(can_read_chain) 
124                 zbt_state <= ZBT_READ_UPPER;
125               else if(can_write_chain)
126                 zbt_state <= ZBT_WRITE_UPPER;
127               else
128                 zbt_state <= ZBT_IDLE;
129            end
130          default :
131            zbt_state <= ZBT_IDLE;
132        endcase // case(zbt_state)
133
134    // Need to generate RAM_WEn, RAM_OEn, RAM_D, RAM_A;
135    assign path1_read = (zbt_state == ZBT_WRITE_LOWER);
136    reg    path2_write, delayed_read_upper, delayed_read_lower, delayed_write;
137
138    always @(posedge clk)
139      if(delayed_read_upper)
140        path2_dat[35:18] <= RAM_D;
141    always @(posedge clk)
142      if(delayed_read_lower)
143        path2_dat[17:0] <= RAM_D;
144
145    always @(posedge clk)
146      if(rst)
147        begin
148           delayed_read_upper <= 0;
149           delayed_read_lower <= 0;
150           path2_write <= 0;
151        end
152      else 
153        begin
154           delayed_read_upper <= (zbt_state == ZBT_READ_LOWER);
155           delayed_read_lower <= delayed_read_upper;
156           path2_write <= delayed_read_lower;
157        end
158    
159    reg [17:0] RAM_D_pre2, RAM_D_pre1, RAM_D_out;
160    
161    always @(posedge clk)
162      RAM_D_pre2 <= phase ? path1_dat[17:0] : path1_dat[35:18];
163
164    always @(posedge clk)  RAM_D_pre1 <= RAM_D_pre2;
165    always @(posedge clk)  RAM_D_out <= RAM_D_pre1;
166    reg        wr_del_1, wr_del_2;             
167    always @(posedge clk)
168      if(rst)
169        begin
170           wr_del_1 <= 0;          
171           wr_del_2 <= 0;
172           delayed_write <= 0;
173        end
174      else
175        begin
176           delayed_write <= wr_del_2;
177           wr_del_2 <= wr_del_1;
178           wr_del_1 <= write_now;
179        end
180
181    reg delayed_read, rd_del_1, rd_del_2;
182    always @(posedge clk)
183      if(rst)
184        begin
185           rd_del_1 <= 0;          
186           rd_del_2 <= 0;
187           delayed_read <= 0;
188        end
189      else
190        begin
191           delayed_read <= rd_del_2;
192           rd_del_2 <= rd_del_1;
193           rd_del_1 <= read_now;
194        end
195           
196    assign     RAM_D = delayed_write ? RAM_D_out : 18'bzzzzzzzzzzzzzzzzzz;
197    assign     write_now = (zbt_state == ZBT_WRITE_UPPER) || (zbt_state == ZBT_WRITE_LOWER);
198    assign     read_now =  (zbt_state == ZBT_READ_UPPER) || (zbt_state == ZBT_READ_LOWER);
199    
200    always @(posedge clk)
201      RAM_A <= write_now ? {write_ptr,phase} : {read_ptr,phase};
202
203    always @(posedge clk)
204      RAM_WEn <= ~write_now;
205
206    assign     RAM_OEn = ~delayed_read;
207    assign     RAM_OEn = 0;
208    
209 endmodule // giantfifo