2 // FIFO intended to be interchangeable with shortfifo, but
3 // based on block ram instead of SRL16's
4 // only one clock domain
6 // Port A is write port, Port B is read port
9 #(parameter WIDTH=32, SIZE=9)
10 (input clk, input reset, input clear,
11 input [WIDTH-1:0] datain,
14 output [WIDTH-1:0] dataout,
18 output reg [15:0] space,
19 output reg [15:0] occupied);
21 wire write = src_rdy_i & dst_rdy_o;
22 wire read = dst_rdy_i & src_rdy_o;
25 assign dst_rdy_o = ~full;
26 assign src_rdy_o = ~empty;
30 localparam PRE_READ = 1;
31 localparam READING = 2;
33 reg [SIZE-1:0] wr_addr, rd_addr;
36 reg empty_reg, full_reg;
43 wr_addr <= wr_addr + 1;
45 ram_2port #(.DWIDTH(WIDTH),.AWIDTH(SIZE))
54 .enb((read_state==PRE_READ)|read),
80 read_state <= PRE_READ;
84 read_state <= READING;
86 rd_addr <= rd_addr + 1;
91 if(rd_addr == wr_addr)
95 read_state <= PRE_READ;
100 rd_addr <= rd_addr + 1;
101 endcase // case(read_state)
103 wire [SIZE-1:0] dont_write_past_me = rd_addr - 3;
104 wire becoming_full = wr_addr == dont_write_past_me;
106 always @(posedge clk)
111 else if(read & ~write)
113 //else if(write & ~read & (wr_addr == (rd_addr-3)))
114 else if(write & ~read & becoming_full)
117 //assign empty = (read_state != READING);
118 assign empty = empty_reg;
120 // assign full = ((rd_addr - 1) == wr_addr);
121 assign full = full_reg;
123 //////////////////////////////////////////////
124 // space and occupied are for diagnostics only
125 // not guaranteed exact
127 localparam NUMLINES = (1<<SIZE)-2;
128 always @(posedge clk)
133 else if(read & ~write)
135 else if(write & ~read)
138 always @(posedge clk)
143 else if(read & ~write)
144 occupied <= occupied - 1;
145 else if(write & ~read)
146 occupied <= occupied + 1;
148 endmodule // fifo_long