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,
19 output [15:0] occupied);
23 localparam PRE_READ = 1;
24 localparam READING = 2;
26 reg [SIZE-1:0] wr_addr, rd_addr;
29 wire [SIZE-1:0] fullness = wr_addr - rd_addr; // Approximate, for simulation only
30 assign occupied = {{16-SIZE{1'b0}},fullness};
32 wire [SIZE-1:0] free_space = rd_addr - wr_addr - 2; // Approximate, for SERDES flow control
33 assign space = {{16-SIZE{1'b0}},free_space};
35 reg empty_reg, full_reg;
42 wr_addr <= wr_addr + 1;
44 ram_2port #(.DWIDTH(WIDTH),.AWIDTH(SIZE))
53 .enb((read_state==PRE_READ)|read),
79 read_state <= PRE_READ;
83 read_state <= READING;
85 rd_addr <= rd_addr + 1;
90 if(rd_addr == wr_addr)
94 read_state <= PRE_READ;
99 rd_addr <= rd_addr + 1;
100 endcase // case(read_state)
102 wire [SIZE-1:0] dont_write_past_me = rd_addr - 3;
103 wire becoming_full = wr_addr == dont_write_past_me;
105 always @(posedge clk)
110 else if(read & ~write)
112 //else if(write & ~read & (wr_addr == (rd_addr-3)))
113 else if(write & ~read & becoming_full)
116 //assign empty = (read_state != READING);
117 assign empty = empty_reg;
119 // assign full = ((rd_addr - 1) == wr_addr);
120 assign full = full_reg;
122 endmodule // longfifo