帮我写一个参数化的同步FIFO
时间: 2024-06-11 09:05:13 浏览: 129
同步FIFO的编写,非常有用,自己写的
以下是一个参数化的同步FIFO的代码,可以根据需要修改参数来适应不同的应用场景:
```
module SyncFIFO #(parameter DATA_WIDTH = 8, parameter FIFO_DEPTH = 16) (
input clk,
input rst,
input wr_en,
input rd_en,
input [DATA_WIDTH-1:0] wr_data,
output [DATA_WIDTH-1:0] rd_data,
output full,
output empty
);
reg [DATA_WIDTH-1:0] fifo [0:FIFO_DEPTH-1];
reg [FIFO_DEPTH-1:0] wr_ptr = 0;
reg [FIFO_DEPTH-1:0] rd_ptr = 0;
reg [FIFO_DEPTH-1:0] count = 0;
assign empty = (count == 0);
assign full = (count == FIFO_DEPTH);
always @(posedge clk) begin
if (rst) begin
wr_ptr <= 0;
rd_ptr <= 0;
count <= 0;
end else begin
if (wr_en && ~full) begin
fifo[wr_ptr] <= wr_data;
wr_ptr <= (wr_ptr == FIFO_DEPTH-1) ? 0 : wr_ptr + 1;
count <= count + 1;
end
if (rd_en && ~empty) begin
rd_data <= fifo[rd_ptr];
rd_ptr <= (rd_ptr == FIFO_DEPTH-1) ? 0 : rd_ptr + 1;
count <= count - 1;
end
end
end
endmodule
```
该同步FIFO具有以下特点:
- 参数化:可以根据需要指定数据宽度和FIFO深度。
- 同步:读写操作都在时钟上升沿触发,确保同步。
- 阻塞/非阻塞:写入操作如果FIFO满了会被阻塞,读取操作如果FIFO为空也会被阻塞。
- 重置:在rst为1时可以重置FIFO。
- 数据宽度:可以根据需要指定不同的数据宽度。
- FIFO深度:可以根据需要指定不同的FIFO深度。
使用示例:
```
module test_SyncFIFO;
parameter DATA_WIDTH = 8;
parameter FIFO_DEPTH = 16;
reg clk = 0;
always #5 clk <= ~clk;
reg rst = 1;
reg wr_en = 0;
reg rd_en = 0;
reg [DATA_WIDTH-1:0] wr_data = 0;
wire [DATA_WIDTH-1:0] rd_data;
wire full;
wire empty;
SyncFIFO #(
.DATA_WIDTH(DATA_WIDTH),
.FIFO_DEPTH(FIFO_DEPTH)
) fifo (
.clk(clk),
.rst(rst),
.wr_en(wr_en),
.rd_en(rd_en),
.wr_data(wr_data),
.rd_data(rd_data),
.full(full),
.empty(empty)
);
initial begin
#20 rst = 0;
#40 wr_en = 1; wr_data = 8'h55;
#40 wr_en = 1; wr_data = 8'hAA;
#40 rd_en = 1;
#40 wr_en = 1; wr_data = 8'h33;
#40 rd_en = 1;
#40 wr_en = 1; wr_data = 8'h77;
#40 $finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, test_SyncFIFO);
end
endmodule
```
该测试代码示例了一些读写操作的场景,可以根据需要修改。在本例中,FIFO的数据宽度为8位,深度为16,时钟周期为5个时间单位。在rst为0之前,FIFO处于重置状态,一旦rst变为0,就可以开始写入数据。在写入了两个数据后,开始读取数据,然后再写入两个数据,最后结束测试。测试代码还使用了vcd波形文件来记录仿真波形。
阅读全文