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 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期