go-board-code/fifo.v

181 lines
3.6 KiB
Verilog

module FIFO(
input i_Clock,
input i_writeDataReady_Flash,
input [WIDTH_BITS-1:0] i_writeData,
input [$clog2(DEPTH_WORDS)-1:0] i_almostFullLevel,
output o_almostFull,
output o_Full,
input i_doRead_Flash,
output reg o_readDataReady,
output reg [WIDTH_BITS-1:0] o_readData,
input [$clog2(DEPTH_WORDS)-1:0] i_almostEmptyLevel,
output o_almostEmpty,
output o_Empty,
input i_Reset_Low
);
parameter WIDTH_BITS = 8;
parameter DEPTH_WORDS = 16;
reg [WIDTH_BITS-1:0] r_RAM [DEPTH_WORDS-1:0];
reg [$clog2(DEPTH_WORDS)-1:0] r_writeAddress;
reg [$clog2(DEPTH_WORDS)-1:0] r_readAddress;
reg [$clog2(DEPTH_WORDS)-1:0] r_Count;
always @(posedge i_Clock or negedge i_Reset_Low) begin
if (~i_Reset_Low) begin
r_writeAddress <= 0;
r_readAddress <= 0;
r_Count <= 0;
end else begin
if (i_writeDataReady_Flash) begin
r_RAM[r_writeAddress] <= i_writeData;
if (r_writeAddress == DEPTH_WORDS - 1) begin
r_writeAddress <= 0;
end else begin
r_writeAddress <= r_writeAddress + 1;
end
end
if (i_doRead_Flash) begin
o_readData <= r_RAM[r_readAddress];
o_readDataReady <= i_doRead_Flash;
if (r_readAddress == DEPTH_WORDS - 1) begin
r_readAddress <= 0;
end else begin
r_readAddress <= r_readAddress + 1;
end
end
if (i_doRead_Flash & ~i_writeDataReady_Flash) begin
if (r_Count != 0) begin
r_Count <= r_Count - 1;
end
end else if (i_writeDataReady_Flash & ~i_doRead_Flash) begin
if (r_Count != DEPTH_WORDS) begin
r_Count <= r_Count + 1;
end
end
end
end
assign o_Full = (
r_Count == DEPTH_WORDS
) || (
r_Count == DEPTH_WORDS-1 &&
i_writeDataReady_Flash &&
!i_doRead_Flash
);
assign o_Empty = (r_Count == 0);
assign o_almostFull = (r_Count > DEPTH_WORDS - i_almostFullLevel);
assign o_almostEmpty = (r_Count < i_almostEmptyLevel);
endmodule
module TestFIFO();
reg r_Clk = 0;
always #1 r_Clk <= !r_Clk;
reg r_Reset_Low = 0;
reg r_writeDataReady_Flash = 0;
reg [7:0] r_writeData = 50;
reg [3:0] r_almostFullLevel = 4;
wire w_almostFull;
wire w_Full;
reg r_doReadFlash = 0;
wire w_readDataReady;
wire [7:0] w_readData;
reg [3:0] r_almostEmptyLevel = 4;
wire w_almostEmpty;
wire w_Empty;
FIFO myFifo(
.i_Clock(r_Clk),
.i_Reset_Low(r_Reset_Low),
.i_writeDataReady_Flash(r_writeDataReady_Flash),
.i_writeData(r_writeData),
.i_almostFullLevel(r_almostFullLevel),
.o_almostFull(w_almostFull),
.o_Full(w_Full),
.i_doRead_Flash(r_doReadFlash),
.o_readDataReady(w_readDataReady),
.o_readData(w_readData),
.i_almostEmptyLevel(r_almostEmptyLevel),
.o_almostEmpty(w_almostEmpty),
.o_Empty(w_Empty)
);
initial begin
$dumpfile("test.vcd");
$dumpvars;
#2;
r_Reset_Low <= 1;
#2;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_writeData = 69;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_writeDataReady_Flash <= 1;
#2;
r_writeDataReady_Flash <= 0;
#2;
r_doReadFlash <= 1;
#2;
r_doReadFlash <= 0;
#2;
r_doReadFlash <= 1;
#2;
r_doReadFlash <= 0;
#2;
$finish;
end
endmodule