对于异步FIFO。最基本的两个方面是地址控制和空、满标志位的产生。首先地址控制分别为读地址和写地址,每次读写时能读写地址应该加1.计数次数为ram深度的2倍。当读写地址相等时则空标志位有效,当读写地址最高位互补其余位相等时则满标志位有效。

存储部分採用双口RAM实现。

以下是详细的Verilog代码:

module afifo(r_clk,w_clk,rst_n,data_in,data_out,we,re,empty,full);

input r_clk,w_clk,rst_n,re,we;

output empty,full;

input [7:0] data_in;

output[7:0] data_out;

wire[4:0] waddr,raddr;

wire [4:0] g_waddr,g_raddr;

// empty full

assign empty=(raddr==waddr);

assign full=((raddr[3:0]==waddr[3:0])&&(raddr[4]==(~waddr[4])));





wire wenable=we&&(~full);

wire renable=re&&(~empty);





afifo_control afifo_control1(

.r_clk(r_clk),

.w_clk(w_clk),

.rst_n(rst_n),

.we(wenable),

.re(renable),

.raddr(raddr),

.waddr(waddr)

);





dualram dualram_inst (

.data ( data_in ),

.rdaddress ( raddr[3:0] ),

.rdclock ( r_clk ),

.wraddress ( waddr[3:0] ),

.wrclock ( w_clk ),

.wren ( wenable ),

.q ( data_out )

);





endmodule

module afifo_control(r_clk,w_clk,rst_n,we,re,raddr,waddr);

input r_clk,w_clk,rst_n,we,re;

output reg[4:0] raddr,waddr;





always @(posedge r_clk or negedge rst_n)

if(!rst_n) begin

raddr<=3'd0;

end

else if(re) begin

raddr<=raddr+1'b1;

end

always @(posedge w_clk or negedge rst_n)

if(!rst_n) begin

waddr<=3'd0;

end

else if(we) begin

waddr<=waddr+1'b1;

end

endmodule

testbench例如以下:

`timescale 1 ns/ 1 ps

module afifo_vlg_tst();

// constants                                           

// general purpose registers

//reg eachvec;

// test vector input registers

reg [7:0] data_in;

reg r_clk;

reg re;

reg rst_n;

reg w_clk;

reg we;

// wires                                               

wire [7:0]  data_out;

wire empty;

wire full;





// assign statements (if any)                          

afifo i1 (

// port map - connection between master ports and signals/registers   

.data_in(data_in),

.data_out(data_out),

.empty(empty),

.full(full),

.r_clk(r_clk),

.re(re),

.rst_n(rst_n),

.w_clk(w_clk),

.we(we)

);

initial                                                

begin                                                  

#0; rst_n=1;data_in=100;re=0;we=0;

#50;rst_n=0; 

#50;rst_n=1;  

#20;re=1;

#20;re=0; 

#20;we=1;

#60;data_in=180;

#2000;we=0;re=1;

#3000;re=0;

#100;$stop();

                   

end                                                    

always                                                 

// optional sensitivity list                           

// @(event1 or event2 or .... eventn)                  

begin                                                  

// code executes for every event on sensitivity list   

// insert code here --> begin                          

   #10 r_clk=1; w_clk=0;

   #10 r_clk=0; w_clk=1;

//@eachvec;                                              

// --> end                                             

end                                                    

endmodule

最新文章

  1. js和php对bool值的判断区别
  2. plt和got
  3. [已解决]EnvironmentError: mysql_config not found
  4. input按钮事件的一个隐藏bug,分享出来
  5. RSA
  6. js对select动态添加和删除OPTION
  7. Day02_JAVA语言基础第二天
  8. Yii 打造带有缓存功能的AR
  9. 基于Intranet的零件库管理信息系统设计--part02
  10. html页面的音频问题
  11. Selenium Webdriver元素定位的八种常用方法
  12. PostgreSQL学习笔记(一)-安装PostgreSQL
  13. NET Core应用中使用缓存
  14. 二叉树的简单操作(Binary Tree)
  15. 洛谷 P4408 逃学的小孩 解题报告
  16. nginx——优化 Nginx worker 进程数
  17. C# Liseview的使用方法之一:滚动到选中的行
  18. Android开发——断点续传原理以及实现
  19. 【Unity】7.3 键盘输入
  20. Selenium - Css Selector 使用方法

热门文章

  1. 类的封装,property特性,类与对象的绑定方法和非绑定方法,
  2. 网络编程 - 协议遇到IO自动切换
  3. hdfs深入:02、今日课程内容大纲以及hdfs的基本实现
  4. react-native Android WARNING: API &#39;variant.getMergeAssets()&#39; is obsolete and has been replaced with &#39;variant.getMergeAssetsProvider()&#39;.
  5. vue-router scrollBehavior的用法
  6. Hibernate-02
  7. 基于PHP的微信支付教程
  8. leds-gpio driver 续1
  9. c++基础_杨辉三角形
  10. Java线上应用故障排查