同步FIFO设计

该博客介绍了如何设计一个同步FIFO,重点在于实现满指针和空指针的逻辑。同步FIFO在相同的时钟域中进行读写操作,读时从非空的内存位置读取数据,写时在非满的状态下写入数据。博主提供了详细的VHDL代码实现,并给出了测试用例,包括满信号和空信号的判断,以及不同情况下的读写操作仿真。
摘要由CSDN通过智能技术生成

同步FIFO的设计,难点在于满指针和空指针的产生。同步的意思是读写时钟是同一个时钟,读写在相同时钟域下工作。

读出数据时,读请求有效,只要非空,从读指针处读出数据。

写入数据时,写请求有效,只要非满,将数据写入写指针处。

输入信号:时钟、复位,写请求,写数据,读请求,;

输出:读出数据,空信号,满信号。

写一个深度为8的,位宽为8的FIFO。

`timescale 1ns/1ps

module FIFO_syn(Clk,Rst_n,rd_valid,wr_valid,rddata,wrdata,empty,full);

input Clk,Rst_n,wr_valid,rd_valid;
input [7:0] wrdata;
output reg [7:0] rddata;
output reg empty,full;
reg [2:0] wrptr,rdptr;
reg [7:0] mem [0:7]; 
integer i;
//数据写入,写指针增加
always@(posedge Clk or negedge Rst_n) begin
if(!Rst_n) begin
    for(i=0;i<=7;i=i+1) 
	    mem[i] <= 0; //mem不能直接以mem=0初始化
    wrptr <= 0;
    end
else if (wr_valid&~full) begin
    mem[wrptr] <= wrdata; 
    wrptr <= (wrptr == 3'd7)?(8'd0):(wrptr + 1'b1);
    end

end

//数据读出,读指针增加
always@(posedge Clk or negedge Rst_n) begin
if(!Rst_n) begin
    rddata <= 0;
    rdptr <= 0;
    end
else if (rd_valid&~empty) begin
    rddata <= mem[rdptr]; 
    rdptr <= (rdptr==3'd7)?8'd0:(rdptr + 1'b1);end
end


//空信号
always@(posedge Clk,negedge Rst_n) begin
if(!Rst_n)
    empty <= 1'b1;
else if (wr_valid)
    empty <= 1'b0;
else if (rd_valid&(wrptr==rdptr+1'b1))
    empty <= 1'b1;
end



//满信号
always@(posedge Clk,negedge Rst_n) begin
if(!Rst_n)
    full <= 1'b0;
else if (wr_valid&(rdptr==wrptr+1'b1))
    full <= 1'b1;
else if (rd_valid)
    full <= 1'b0;
end

endmodule

下面是仿真代码

`timescale 1ns/1ps
`define clk_period 20
module tb_FIFO_syn();

reg clk,rst_n,wr,rd;
reg [7:0] wrdata;
wire empty,full;
wire [7:0] rddata;

FIFO_syn fifos(.Clk(clk),.Rst_n(rst_n),.wr_valid(wr),.rd_valid(rd),.wrdata(wrdata),.rddata(rddata),.empty(empty),.full(full));

initial clk =1'b0;
always#(`clk_period/2) clk=~clk;

integer i;

initial begin 
i=0;rst_n=0;wrdata=0;wr=0;rd=0;
#20.01;rst_n=1;
#20.01;rd=1;
//持续读和写
#(`clk_period*10)  wr=1;wrdata=8'b0; //第一个写周期,读是读不出的。
for(i=0;i<=20;i=i+1)
	#(20)  wrdata=i+1;
rd=0;

//不读,写满
#(`clk_period*2)  wr=1;wrdata=8'b0;
for(i=0;i<=20;i=i+1)
	#(20)  wrdata=i;
wr=0;

//不写,读空
#(`clk_period*2)  rd=1;
#(`clk_period*20) 

//不读,写满
rd=0;
#(`clk_period*2)  wr=1;wrdata=8'b0;
for(i=0;i<=20;i=i+1)
	#(20)  wrdata=i;
wr=0;
end


initial
begin
  $fsdbDumpMDA();
  $fsdbDumpfile("fifosyn.fsdb");
  $fsdbDumpvars;
  $fsdbDumpon;
end

initial #5000 $finish;

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值