1. //Module Name:afifo_ctrl
  2. //Description:parameterized afifo
  3.  
  4. module afifo_ctrl(
  5. clk_push,
  6. rst_push_n,
  7. clk_pop,
  8. rst_pop_n,
  9. push,
  10. push_data,
  11. full,
  12. pop,
  13. pop_data,
  14. empty,
  15. mem_waddr,
  16. mem_wen,
  17. mem_wdata,
  18. mem_raddr,
  19. mem_ren,
  20. mem_rdata,
  21. almost_full
  22. );
  23.  
  24. parameter DATAWIDTH = ; //the data width of AFIFO
  25. parameter ADDRWIDTH = ; //the address bits of AFIFO and it must be >=2
  26. //the AFIFO depth must be 2^ADDRWIDTH
  27. //input declaration
  28. input clk_push; //push clock
  29. input rst_push_n; //reset signal in push clock domain
  30.  
  31. input clk_pop; //pop clock
  32. input rst_pop_n; //reset signal in pop clock domain
  33. input push ; //push enable to AFIFO
  34. input [DATAWIDTH-:] push_data; //push data to AFIFO
  35. input pop ; //pop enable to AFIFO
  36. input [DATAWIDTH-:] mem_rdata; //read data from memory stack
  37.  
  38. //output declaration
  39. output full; //full indicator,and the logic of user can't push data when this signal is high //ok
  40. output [DATAWIDTH-:] pop_data ; //pop data from AFIFO //ok
  41. output empty; //empty indicator, and the logic of user can't pop data when this signal is high //ok
  42. output [ADDRWIDTH-:] mem_waddr; //write address to memory stack //ok
  43. output mem_wen; //write enable to memory stack //ok
  44. output [DATAWIDTH-:] mem_wdata; //write data to memory stack //ok
  45. output [ADDRWIDTH-:] mem_raddr; //read address to memory stack //ok
  46. output mem_ren; //read enable to memory stack //ok
  47. output almost_full;
  48.  
  49. //register declaration
  50.  
  51. reg [ADDRWIDTH-:] mem_waddr;
  52. reg [ADDRWIDTH-:] mem_raddr;
  53. reg [ADDRWIDTH-:] gray_waddr_1r;
  54. reg [ADDRWIDTH-:] gray_waddr_2r_1_sync;
  55. reg [ADDRWIDTH-:] gray_waddr_3r_2_sync;
  56. reg [ADDRWIDTH-:] gray_raddr_1r;
  57. reg [ADDRWIDTH-:] gray_raddr_2r_1_sync;
  58. reg [ADDRWIDTH-:] gray_raddr_3r_2_sync;
  59. reg [ADDRWIDTH-:] gray_waddr_temp;
  60. reg [ADDRWIDTH-:] gray_raddr_temp;
  61. reg [ADDRWIDTH-:] biny_waddr;
  62. reg [ADDRWIDTH-:] biny_raddr;
  63. reg [ADDRWIDTH-:] biny_waddr_temp;
  64. reg [ADDRWIDTH-:] biny_raddr_temp;
  65. reg [DATAWIDTH-:] pop_data_r;
  66. reg pop_r;
  67. reg empty_flag;
  68. reg full_flag;
  69.  
  70. //net declaration
  71. wire mem_wen;
  72. wire mem_ren;
  73. wire [DATAWIDTH-:] mem_wdata;
  74. wire [DATAWIDTH-:] pop_data;
  75. wire [ADDRWIDTH-:] gray_waddr;
  76. wire [ADDRWIDTH-:] gray_raddr;
  77. wire pop_one_left;
  78. wire pop_ptr_diff;
  79. wire push_one_left;
  80. wire push_ptr_diff;
  81.  
  82. integer i;
  83.  
  84. assign mem_wen = push;
  85. assign mem_wdata[DATAWIDTH-:] = push_data[DATAWIDTH-:];
  86. assign mem_ren = pop;
  87.  
  88. //for output signal pop_data
  89. always@(posedge clk_pop or negedge rst_pop_n)
  90. begin
  91. if(~rst_pop_n)
  92. pop_r<='b0;
  93. else
  94. pop_r<=pop;
  95. end
  96.  
  97. always@(posedge clk_pop or negedge rst_pop_n)
  98. begin
  99. if(~rst_pop_n)
  100. pop_data_r[DATAWIDTH-:] <= ;
  101. else
  102. pop_data_r[DATAWIDTH-:] <= mem_rdata[DATAWIDTH-:];
  103. end
  104.  
  105. assign pop_data[DATAWIDTH-:] = pop_r ? mem_rdata[DATAWIDTH-:]:pop_data_r[DATAWIDTH-:];
  106.  
  107. //for output signal mem_waddr
  108. always@(posedge clk_push or negedge rst_push_n)
  109. begin
  110. if(~rst_push_n)
  111. mem_waddr[ADDRWIDTH-:] <=;
  112. else
  113. mem_waddr[ADDRWIDTH-:] <= mem_waddr[ADDRWIDTH-:] + 'b1;
  114. end
  115.  
  116. //for output signal mem_raddr
  117. always@(posedge clk_pop or negedge rest_pop_n)
  118. begin
  119. if(~rst_pop_n)
  120. mem_raddr[ADDRWIDTH-:]<=;
  121. else
  122. mem_raddr[ADDRWIDTH-:] <= mem_raddr[ADDRWIDTH-:] + 'b1;
  123. end
  124.  
  125. //for output signal empty
  126. assign gray_addr[ADDRWIDTH-:] = {mem_waddr[ADDRWIDTH-],gray_waddr_temp[ADDRWIDTH-:]};
  127. always@(* )
  128. for(i=;i<(ADDRWIDTH-);i=i+)
  129. gray_waddr_temp[i] = mem_waddr[i]^mem_waddr[i+];
  130.  
  131. always@(posedge clk_push or negedge rst_push_n)
  132. begin
  133. if(~rst_push_n)
  134. gray_waddr_1r[ADDRWIDTH-:] <= ;
  135. else
  136. gray_waddr_1r[ADDRWIDTH-:] <= gray_waddr[ADDRWIDTH-:];
  137. end
  138.  
  139. always@(posedge clk_pop or negedge rst_pop_n)
  140. begin
  141. if(~rst_pop_n) begin
  142. gray_waddr_2r_1_sync[ADDRWIDTH-:] <=;
  143. gray_waddr_3r_2_sync[ADDRWIDTH-:] <=;
  144. end
  145. else begin
  146. gray_waddr_2r_1_sync[ADDRWIDTH-:] <= gray_waddr_1r[ADDRWIDTH-:];
  147. gray_waddr_3r_2_sync[ADDRWIDTH-:] <= gray_waddr_2r_1_sync[ADDRWIDTH-:];
  148. end
  149. end
  150.  
  151. always@(*)
  152. biny_waddr[ADDRWIDTH-] = gray_waddr_3r_2_sync[ADDRWIDTH-];
  153.  
  154. always@(*)
  155. for(i=;i<(ADDRWIDTH-);i=i+)
  156. biny_waddr[ADDRWIDTH--i] = gray_waddr_3r_2_sync[ADDRWIDTH--i]^biny_waddr_temp[ADDRWIDTH--i];
  157.  
  158. always@(*)
  159. biny_waddr_temp[ADDRWIDTH-:] = biny_waddr[ADDRWIDTH-:];
  160.  
  161. assign pop_one_left = (biny_waddr[ADDRWIDTH-:] ==(mem_raddr[ADDRWIDTH-:] + 'b1));
  162. assign pop_ptr_diff = (biny_waddr[ADDRWIDTH-:] != mem_raddr[ADDRWIDTH-:]);
  163.  
  164. always@(posedge clk_pop or negedge rst_pop_n)
  165. begin
  166. if(~rst_pop_n)
  167. empty_flag <='b1;
  168. else if(pop_one_left && pop)
  169. empty_flag <= 'b1;
  170. else if(empty_flag && pop_ptr_diff)
  171. empty_flag <= 'b0;
  172. end
  173.  
  174. assign empty = ~pop_ptr_diff && empty_flag;
  175.  
  176. //for output signal full
  177. assign gray_raddr[ADDRWIDTH-:] = {mem_raddr[ADDRWIDTH-],gray_raddr_temp[ADDRWIDTH-:]};
  178.  
  179. always@(*)
  180. for(i=;i<(ADDRWIDTH-);i=i+)
  181. gray_raddr_temp[i] = mem_raddr[i] ^ mem_raddr[i+];
  182.  
  183. always@(posedge clk_pop or negedge rst_pop_n)
  184. begin
  185. if(~rst_pop_n)
  186. gray_raddr_1r[ADDRWIDTH-:] <=;
  187. else
  188. gray_raddr_1r[ADDRWIDTH-:] <= gray_raddr[ADDRWIDTH-:];
  189. end
  190.  
  191. always@(posedge clk_push or negedge rst_push_n)
  192. begin
  193. if(~rst_push_n)begin
  194. gray_raddr_2r_1_sync[ADDRWIDTH-:]<=;
  195. gray_raddr_3r_2_sync[ADDRWIDTH-:]<=;
  196. end
  197. else begin
  198. gray_raddr_2r_1_sync[ADDRWIDTH-:] <= gray_raddr_1r[ADDRWIDTH-:]:
  199. gray_raddr_3r_2_sync[ADDRWIDTH-:] <= gray_raddr_2r_sync[ADDRWIDTH-:];
  200. end
  201. end
  202.  
  203. always@(*)
  204. biny_raddr[ADDRWIDTH-] = gray_raddr_3r_2_sync[ADDRWIDTH-];
  205. always@(*)
  206. for(i=;i<(ADDRWIDTH-);i=i+)
  207. biny_raddr[ADDRWIDTH--i] = gray_raddr_3r_2_sync[ADDRWIDTH--i] ^biny_raddr_temp[ADDRWIDTH--i];
  208.  
  209. always@(*)
  210. biny_raddr_temp[ADDRWIDTH-:] = biny_raddr[ADDRWIDTH-:];
  211.  
  212. assign push_one_left = (biny_raddr[ADDRWIDTH-:] ==(mem_waddr[ADDRWIDTH-:] + 'b1));
  213. assign push_ptr_diff = (biny_raddr[ADDRWIDTH-:] !=(mem_waddr[ADDRWIDTH-:]));
  214.  
  215. always@(posedge clk_push or negedge rst_push_n)
  216. begin
  217. if(~rst_push_n)
  218. full_flag <= 'b0;
  219. else if(push_one_left && push)
  220. full_flag <= 'b1;
  221. else if(full_flag && push_ptr_diff)
  222. full_flag <='b0
  223. end
  224.  
  225. assign full= ~push_ptr_diff && full_flag;
  226. assign almost_full = push_one_left;
  227.  
  228. endmodule

asyn_fifo的更多相关文章

  1. Verilog学习笔记简单功能实现(八)...............异步FIFO

    基本原理:       1.读写指针的工作原理 写指针:总是指向下一个将要被写入的单元,复位时,指向第1个单元(编号为0). 读指针:总是指向当前要被读出的数据,复位时,指向第1个单元(编号为0). ...

  2. 在Windows下自动运行Modelsim

    首先声明:该文章是在刘志伟老师的<Modelsim的Tcl命令>的基础上写的,希望我们能越来越自动化. 1.编写好源文件.包含asyn_fifo.v.fifomem.v.rptr_empt ...

  3. 异步FIFO的verilog实现与简单验证(调试成功)

    最近在写一个异步FIFO的时候,从网上找了许多资料,文章都写的相当不错,只是附在后面的代码都多多少少有些小错误. 于是自己写了一个调试成功的代码,放上来供大家参考. 非原创 原理参考下面: 原文 ht ...

  4. 基于FPGA的异步FIFO验证

    现在开始对上一篇博文介绍的异步FIFO进行功能验证,上一篇博文地址:http://blog.chinaaet.com/crazybird/p/5100000872 .对异步FIFO验证的平台如图1所示 ...

  5. 基于FPGA的异步FIFO设计

    今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...

随机推荐

  1. VUE循环菜单

  2. 最短路之Dijkstra(单源)HDU 2544

    #include <iostream> using namespace std; ; ][]; ]; int middist; ]; void dijkstra(int n,int m) ...

  3. 爬虫的UA池和代理池

    爬虫的UA池和代理池   一.下载中间件 先祭出框架图: 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引擎将请求传递给下 ...

  4. Django (十) 项目部署 1

    阿里云部署项目 1, 购买阿里云ECS云服务器(可免费试用1个月) 2, 阿里云实例更换为Ubuntu 3, 安全组配置 4, xshell远程连接 5, 创建虚拟环境: 5.1 linux基本命令 ...

  5. 转 查看磁盘IO负载 - 看哪些进程在读写磁盘 以及oracle 异步I/O 和同步I/O

    https://www.cnblogs.com/cloudstorage/archive/2012/11/11/2764623.html #####sample 1: Oracle等待事件db fil ...

  6. 如何在VirtualBox虚拟机中安装XP系统? 转

    关闭VM (windows 7 )的方法, 使用 退出 保持状态 开启VM (windows 7 )的方法, 选择启动 ######Iissue 1 网络连接不上,可以重新初始化 网络连接. #### ...

  7. hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!

    http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...

  8. 牛客网Java刷题知识点之什么是死锁、死锁产生的4个必要条件、死锁的解除与预防

    不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?query=&asc=true&order=&page=16 ...

  9. java transient关键字作用,使用场景

    transient的作用及使用方法,官方解释为: Variables may be marked transient to indicate that they are not part of the ...

  10. Linux 查找bom头文件,清除bom头命令

    1.查找bom头文件 grep -r -I -l $'^\xEF\xBB\xBF' ./ 2.替换bom头文件 find . -type f -exec sed -i 's/\xEF\xBB\xBF/ ...