verilog实现FIFO

一、计数器
代码

module sync_fifo_cnt #(
parameter DEPTH = 8,
parameter WIDTH = 8
)(
input wire clk,
input wire rst_n,
input wire i_wen,
input wire [WIDTH-1:0] i_wdata,
input wire i_ren,
output reg [WIDTH-1:0] o_rdata,
output wire o_empty,
output wire o_full,
output reg [$clog2(DEPTH):0] cnt
);
reg [$clog2(DEPTH)-1:0] w_addr;
reg [$clog2(DEPTH)-1:0] r_addr;
reg [WIDTH-1:0] fifo_buffer[DEPTH-1:0]; //鐢ㄤ簩缁存暟缁勫疄鐜癛AM
//counter
//read
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
r_addr <= 0;
end
else if(i_ren && !o_empty)
begin
r_addr <= r_addr+1'b1;
o_rdata <= fifo_buffer[r_addr];
end
end
//write
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
w_addr <= 0;
end
else if(i_wen && !o_full)
begin
w_addr <= w_addr + 1'b1;
fifo_buffer[w_addr] <= i_wdata;
end
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
cnt <= 0;
end
else if(i_wen && i_ren)
begin
cnt <= cnt;
end
else if(i_wen && !(cnt == DEPTH))
begin
cnt <= cnt + 1'b1;
end
else if(i_ren && !(cnt == 0))
begin
cnt <= cnt - 1'b1;
end
end
assign o_empty = (cnt == 0)?1'b1:1'b0;
assign o_full = (cnt == DEPTH)?1'b1:1'b0;
endmodule

测试

`timescale 1ns/1ns //时间单位/精度
//------------<模块及端口声明>----------------------------------------
module tb_sync_fifo_cnt();
parameter WIDTH = 8 ; //FIFO位宽
parameter DEPTH = 8 ; //FIFO深度
reg clk ;
reg rst_n ;
reg [WIDTH-1:0] data_in ;
reg rd_en ;
reg wr_en ;
wire [WIDTH-1:0] data_out;
wire empty ;
wire full ;
wire [$clog2(DEPTH) : 0] fifo_cnt;
//------------<例化被测试模块>----------------------------------------
sync_fifo_cnt
#(
.WIDTH (WIDTH), //FIFO位宽
.DEPTH (DEPTH) //FIFO深度
)
sync_fifo_cnt_inst(
.clk (clk ),
.rst_n (rst_n ),
.i_wdata (data_in ),
.i_ren (rd_en ),
.i_wen (wr_en ),
.o_rdata (data_out ),
.o_empty (empty ),
.o_full (full ),
.cnt (fifo_cnt )
);
//------------<设置初始测试条件>----------------------------------------
initial begin
clk = 1'b0; //初始时钟为0
rst_n <= 1'b0; //初始复位
data_in <= 'd0;
wr_en <= 1'b0;
rd_en <= 1'b0;
//重复8次写操作,让FIFO写满
repeat(8) begin
@(negedge clk)begin
rst_n <= 1'b1;
wr_en <= 1'b1;
data_in <= $random; //生成8位随机数
end
end
//重复8次读操作,让FIFO读空
repeat(8) begin
@(negedge clk)begin
wr_en <= 1'b0;
rd_en <= 1'd1;
end
end
//重复4次写操作,写入4个随机数据
repeat(4) begin
@(negedge clk)begin
wr_en <= 1'b1;
data_in <= $random; //生成8位随机数
rd_en <= 1'b0;
end
end
//持续同时对FIFO读写,写入数据为随机数据
forever begin
@(negedge clk)begin
wr_en <= 1'b1;
data_in <= $random; //生成8位随机数
rd_en <= 1'b1;
end
end
end
//------------<设置时钟>----------------------------------------------
always #10 clk = ~clk; //系统时钟周期20ns
endmodule

本文作者:大耳毛豆

本文链接:https://www.cnblogs.com/yjxmike/p/18727589

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   大耳毛豆  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起