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 rst,
11 input [WIDTH-1:0] datain,
12 output [WIDTH-1:0] dataout,
18 output reg [15:0] space,
19 output reg [15:0] occupied);
23 localparam PRE_READ = 1;
24 localparam READING = 2;
26 reg [SIZE-1:0] wr_addr, rd_addr;
29 reg empty_reg, full_reg;
36 wr_addr <= wr_addr + 1;
38 ram_2port #(.DWIDTH(WIDTH),.AWIDTH(SIZE))
47 .enb((read_state==PRE_READ)|read),
73 read_state <= PRE_READ;
77 read_state <= READING;
79 rd_addr <= rd_addr + 1;
84 if(rd_addr == wr_addr)
88 read_state <= PRE_READ;
93 rd_addr <= rd_addr + 1;
94 endcase // case(read_state)
96 wire [SIZE-1:0] dont_write_past_me = rd_addr - 3;
97 wire becoming_full = wr_addr == dont_write_past_me;
104 else if(read & ~write)
106 //else if(write & ~read & (wr_addr == (rd_addr-3)))
107 else if(write & ~read & becoming_full)
110 //assign empty = (read_state != READING);
111 assign empty = empty_reg;
113 // assign full = ((rd_addr - 1) == wr_addr);
114 assign full = full_reg;
116 //////////////////////////////////////////////
117 // space and occupied are for diagnostics only
118 // not guaranteed exact
120 localparam NUMLINES = (1<<SIZE)-2;
121 always @(posedge clk)
126 else if(read & ~write)
128 else if(write & ~read)
131 always @(posedge clk)
136 else if(read & ~write)
137 occupied <= occupied - 1;
138 else if(write & ~read)
139 occupied <= occupied + 1;
142 wire [SIZE-1:0] fullness = wr_addr - rd_addr; // Approximate, for simulation only
143 assign occupied = {{16-SIZE{1'b0}},fullness};
145 wire [SIZE-1:0] free_space = rd_addr - wr_addr - 2; // Approximate, for SERDES flow control
146 assign space = {{16-SIZE{1'b0}},free_space};
150 endmodule // longfifo