基于verilog的同步FIFO设计

1、理论介绍

同步电路和异步电路

同步电路:所有触发器的时钟输入端都接同一个时钟脉冲,所有触发器状态的改变都与所加脉冲信号同步。

异步电路:电路没有统一的时钟。

FIFO介绍

        先进先出存储器(first input first output),即先写入的数据被先读出,后写入的数据被后读出,一般使用同步fifo做缓存,使用异步fifo做跨时钟处理。

2、架构设计

同步FIFO

        即只有一个时钟驱动,其模块框图如图1所示,FIFO中需要注意的地方是满空的判断,也就是在写满后不再写入,读空后不再读出,其内部主要电路框图如图2所示。

图1 同步FIFO模块

 

 图2 同步FIFO内部主要电路框图

3、代码设计

一、同步FIFO代码设计

/***************************************
#
#			Filename:fifo_sync.v
#
#			Developer:annotater
#			Description:---
#			CreatTime:2021-08-11 19:22:09
#
***************************************/
module fifo_sync(
input clk_200m,
input sys_rst,
input wr_en,
input rd_en,
input[7:0] wr_data,
output reg[7:0] rd_data,
output full,
output empty
);
reg[7:0] fifo[7:0];//定义一个深度为8,位宽为8的FIFO
reg[3:0] wr_cnt,rd_cnt;//定义读指针和写指针,如果定义为[2:0],则会发现fifo不能完全写满,这里多定义一位,通过最高位来判断写满。
wire wr_e;
wire rd_e;
integer i;
always@(posedge clk_200m or posedge sys_rst)begin
	if(sys_rst)begin
		for(i=0;i<8;i=i+1)begin
			fifo[i] <= 0;
		end
		wr_cnt <= 0;
		rd_cnt <= 0;
	    rd_data <= 0;
	end
	else if(rd_e && wr_e)begin
		fifo[wr_cnt[2:0]] <= wr_data;
		rd_data <= fifo[rd_cnt[2:0]];
		wr_cnt <= wr_cnt + 1;
		rd_cnt <= rd_cnt + 1;
	end
	else if(rd_e)begin
		rd_data <= fifo[rd_cnt[2:0]];
		rd_cnt <= rd_cnt + 1;
	end
	else if(wr_e)begin
		fifo[wr_cnt[2:0]] <= wr_data;
		wr_cnt <= wr_cnt + 1;
	end
end

assign full = (wr_cnt[3] ^ rd_cnt[3])&&(wr_cnt[2:0]==rd_cnt[2:0]);
assign empty = (wr_cnt[3:0] == rd_cnt[3:0]);

assign wr_e = wr_en && ~full;
assign rd_e = rd_en && ~empty;

endmodule

二、仿真代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/08/11 19:44:50
// Design Name: 
// Module Name: tb_fifo_sync
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_fifo_sync();
reg      clk_200m    ;
reg      sys_rst     ;
reg      wr_en       ;
reg      rd_en       ;
reg[7:0] wr_data     ;
wire[7:0] rd_data     ;
wire      full        ;
wire      empty       ;

initial begin
clk_200m = 0;
sys_rst = 1;
wr_en = 0;
rd_en = 0;
wr_data = 0;
#10 sys_rst = 0;
forever #5 clk_200m = ~clk_200m;
end

initial begin
#200 wr_data = 8'b10101010;
     wr_en = 1;
#180 wr_en = 0;
#10  rd_en = 1;
#100 rd_en = 0;
#30  wr_data = 8'b01010101;
     wr_en = 1;
#180 wr_en = 0;
#10  rd_en = 1;
#100 rd_en = 0;
end
always@(posedge clk_200m) begin
if(wr_en)
    #1 wr_data <= {wr_data[7:0],1'b0};
end

fifo_sync U_FIFO_SYNC(
    .clk_200m  ( clk_200m  ), //i
    .sys_rst   ( sys_rst   ), //i
    .wr_en     ( wr_en     ), //i
    .rd_en     ( rd_en     ), //i
    .wr_data   ( wr_data   ), //i
    .rd_data   ( rd_data   ), //o
    .full      ( full      ), //o
    .empty     ( empty     )  //o
);

endmodule

4、仿真分析

        可以看到深度写完8位后,full信号拉高,这时候wr_en为高,但是也没有继续写入,后rd_en拉高,可以看到数据读出的顺序为写入的顺序,也就是先入先出,读完8位数据后,显示读空(日如图3),这时候再次写入,可发现规律是一样的(如图4),说明设计的FIFO重复读写时没有问题的。

图3 

 图4

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Annotater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值