Verilog实现同步FIFO

用Verilog实现一个同步FIFO,深度16,数据位宽8bit
module Sy_FIFO#(
	parameter DATA_WIDTH = 8,
	parameter ADDR_WIDTH = 4,
	parameter RAM_DEPTH  = (1 << ADDR_WIDTH)
    )
	 (
	 input clk,
	 input rst_n,
	 input [DATA_WIDTH-1:0] data_in,
	 input wr_en,
	 input rd_en,
	 output reg [DATA_WIDTH-1:0] data_out,
	 output empty,
	 output full
	 );

wire [ADDR_WIDTH-1:0] wr_cnt;
wire [ADDR_WIDTH-1:0] rd_cnt;
reg [ADDR_WIDTH-1:0] status_cnt;
reg [DATA_WIDTH-1:0] data_ram;


//Syn
reg rd_en_r;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		rd_en_r <= 0;
	else
		rd_en_r <= rd_en;
end

reg [ADDR_WIDTH:0] wr_cnt_next;
reg [ADDR_WIDTH:0] rd_cnt_next;

//写地址产生
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		wr_cnt_next <= 0;
	else begin 
			if(wr_en && (full == 0))                //写使能有效时进行地址递增
				wr_cnt_next <= wr_cnt_next + 1'b1;
			else
				wr_cnt_next <= wr_cnt_next;
	end
end
//读地址产生
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		rd_cnt_next <= 0;
	else begin
			if(rd_en && (empty == 0))               //读使能有效时读地址递增
				rd_cnt_next <= rd_cnt_next + 1'b1;
			else
				rd_cnt_next <= rd_cnt_next;
	end
end
//读FIFO输出缓冲器
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		data_out <= 0;
	else begin
		if(rd_en_r)
			data_out <= data_ram;
	end
end


//判断满或空
assign full = (rd_cnt_next == ({~wr_cnt_next[ADDR_WIDTH],wr_cnt_next[ADDR_WIDTH-1:0]}))?1'b1:1'b0;
assign empty = (rd_cnt_next == wr_cnt_next)?1'b1:1'b0;

assign wr_cnt = wr_cnt_next[ADDR_WIDTH-1:0];
assign rd_cnt = rd_cnt_next[ADDR_WIDTH-1:0];


//Syn_Dual_Port_RAM
integer i;
reg [DATA_WIDTH-1:0] register[RAM_DEPTH-1:0];

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		for(i=0;i<RAM_DEPTH;i=i+1)
			register[i] <= 8'd15;
	else begin
		if(wr_en && (full == 0))
			register[wr_cnt] <= data_in;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		data_ram <= 8'bz;
	else begin
		if(rd_en && (empty == 0))
			data_ram <= register[rd_cnt];
		else
			data_ram <= 8'bz;
	end
end

endmodule
测试代码
`timescale 1ns / 1ps


// Company: 
// Engineer:
//
// Create Date:   11:02:30 06/27/2021
// Design Name:   Sy_FIFO
// Module Name:   F:/LiuHengQuan/ProgramData/Xilinx/ISE_DATA/Sy_FIFO/Sy_FIFO/tb_SyFiFo.v
// Project Name:  Sy_FIFO
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: Sy_FIFO
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 


module tb_SyFiFo;

	// Inputs
	reg clk;
	reg rst_n;
	reg [7:0] data_in;
	reg wr_en;
	reg rd_en;

	// Outputs
	wire [7:0] data_out;
	wire empty;
	wire full;
	
	reg ena;
	reg enb;

	// Instantiate the Unit Under Test (UUT)
	Sy_FIFO uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.data_in(data_in), 
		.wr_en(wr_en), 
		.rd_en(rd_en), 
		.data_out(data_out), 
		.empty(empty), 
		.full(full)
	);

always #5 clk = ~clk;
	initial begin
		// Initialize Inputs
		clk = 0;
		rst_n = 0;
		data_in = 0;
		wr_en = 0;
		rd_en = 0;
		enb = 0;
		ena = 0;
		#100 rst_n = 1;
		#95 wr_en = 1;
		 ena = 1;
		#400 ena = 0;
		 wr_en = 0;
		
		#200 enb = 1;
		#10 rd_en = 1;
		#400 enb = 0;
		#10 rd_en = 0;
		
		#95 wr_en = 1;
		 ena = 1;
		#400 ena = 0;
		 wr_en = 0;
		 
		#200 enb = 1;
		#10 rd_en = 1;
		#400 enb = 0;
		#10 rd_en = 0;
	end
always @(posedge clk )begin
	if(!rst_n) 
		data_in <= 8'd2;
	else
		if(ena)
			data_in <= data_in + 2'd2;
		else
			data_in <= data_in;
end


endmodule


在这里插入图片描述

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值