Line 71... |
Line 71... |
////
|
////
|
//// from http://www.opencores.org/lgpl.shtml
|
//// from http://www.opencores.org/lgpl.shtml
|
////
|
////
|
////
|
////
|
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
|
`timescale 1ns/1ps
|
module fifo
|
module fifo
|
#(
|
#(
|
parameter integer DWIDTH = 32,
|
parameter integer DWIDTH = 32,
|
parameter integer AWIDTH = 4
|
parameter integer AWIDTH = 4
|
)
|
)
|
Line 85... |
Line 86... |
output f_full, f_empty,
|
output f_full, f_empty,
|
output [DWIDTH-1:0] data_out
|
output [DWIDTH-1:0] data_out
|
);
|
);
|
|
|
|
|
reg [DWIDTH-1:0] mem [0:2**AWIDTH-1];
|
// reg [DWIDTH-1:0] mem [0:2**AWIDTH-1];
|
|
parameter integer DEPTH = 1 << AWIDTH;
|
|
wire [DWIDTH-1:0] data_ram_out;
|
|
wire wr_en_ram;
|
|
wire rd_en_ram;
|
|
|
reg [AWIDTH-1:0] wr_ptr;
|
reg [AWIDTH-1:0] wr_ptr;
|
reg [AWIDTH-1:0] rd_ptr;
|
reg [AWIDTH-1:0] rd_ptr;
|
reg [AWIDTH-1:0] last_position;
|
reg [AWIDTH:0] counter;
|
|
|
reg last_was_write;
|
reg last_was_write;
|
|
|
|
//Write pointer
|
always@(posedge clock)
|
always@(posedge clock)
|
begin
|
begin
|
|
|
if (reset)
|
if (reset)
|
//SYNCHRONOUS RESET
|
|
begin
|
begin
|
rd_ptr <= {AWIDTH{1'b0}};
|
wr_ptr <= {(AWIDTH){1'b0}};
|
wr_ptr <= {AWIDTH{1'b0}};
|
|
last_position <= {AWIDTH{1'b0}};
|
|
last_was_write <= 1'b1;
|
|
|
|
// NONBLOCKING
|
|
end
|
end
|
else
|
else if (wr_en && !f_full)
|
begin
|
begin
|
|
wr_ptr <= wr_ptr + 1'b1;
|
|
end
|
|
end
|
|
|
if(wr_en)//WRITE OPERATION
|
//Read pointer
|
|
always@(posedge clock)
|
begin
|
begin
|
mem[wr_ptr] <= data_in; //WRITE TO ARRAY
|
if (reset)
|
wr_ptr <= wr_ptr + 11'd1;
|
begin
|
last_position <= last_position + 11'd1;
|
rd_ptr <= {(AWIDTH){1'b0}};
|
|
|
last_was_write <= 1'b0;
|
|
|
|
rd_ptr <= {AWIDTH{1'b0}};
|
|
|
|
end
|
end
|
else if(rd_en)// READ OPERATION
|
else if (rd_en && !f_empty)
|
begin
|
begin
|
wr_ptr <= {AWIDTH{1'b0}};
|
rd_ptr <= rd_ptr + 1'b1;
|
|
end
|
|
end
|
|
|
if(rd_ptr != {AWIDTH{1'b1}} && last_position == {AWIDTH{1'b0}})
|
//Counter
|
|
always@(posedge clock)
|
begin
|
begin
|
rd_ptr <= rd_ptr + 11'd1;
|
if (reset)
|
end
|
|
else if(rd_ptr != last_position)
|
|
begin
|
begin
|
rd_ptr <= rd_ptr + 11'd1;
|
counter <= {(AWIDTH+1){1'b0}};
|
end
|
end
|
|
else
|
if(rd_ptr == last_position - 4'b1 || rd_ptr == {AWIDTH{1'b1}})
|
|
begin
|
begin
|
last_was_write <= 1'b1;
|
if (rd_en && !f_empty && !wr_en)
|
last_position <= {AWIDTH{1'b0}};
|
begin
|
|
counter <= counter - 1'b1;
|
end
|
end
|
|
else if (wr_en && !f_full && !rd_en)
|
|
begin
|
|
counter <= counter + 1'b1;
|
end
|
end
|
|
|
end
|
end
|
|
|
end
|
end
|
|
|
|
assign f_full = (counter == DEPTH -1) ; //(!last_was_write | last_position != {AWIDTH{1'b0}} )? 1'b1:1'b0;
|
|
assign f_empty = (counter == {AWIDTH{1'b0}}); //(last_was_write)? 1'b1:1'b0;
|
|
assign wr_en_ram = wr_en;
|
|
assign rd_en_ram = rd_en;
|
|
assign data_out = data_ram_out;
|
|
|
assign f_full = (!last_was_write | last_position != {AWIDTH{1'b0}} )? 1'b1:1'b0;
|
dp_ram #(DWIDTH, AWIDTH)
|
assign f_empty = (last_was_write)? 1'b1:1'b0;
|
RAM_1 (
|
assign data_out = mem[rd_ptr];//WRITE ON OUTPUT
|
.clock(clock),
|
|
.reset(reset),
|
|
.wr_en(wr_en_ram),
|
|
.rd_en(rd_en_ram),
|
|
.data_in(data_in),
|
|
.wr_addr(wr_ptr),
|
|
.data_out(data_ram_out),
|
|
.rd_addr(rd_ptr)
|
|
);
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|