学习笔记二:异步FIFO
生活随笔
收集整理的這篇文章主要介紹了
学习笔记二:异步FIFO
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
? 1 module fifo1 #(parameter DSIZE = 8,
2 parameter ASIZE = 4) //用格雷碼的局限性:循環(huán)計(jì)數(shù)深度必須是2的n次冪,否則就失去了每次只變化一位的特性
3 (wclk,wrstn,wdata,wfull,winc,rclk,rrstn,rdata,rempty,rinc);
4 input wclk,wrstn,winc;
5 input [DSIZE - 1:0] wdata;
6 output wfull;
7
8 input rclk,rrstn,rinc;
9 output [DSIZE - 1:0] rdata;
10 output rempty;
11
12 reg wfull,rempty; //空滿輸出
13 reg [ASIZE:0] rbin,wbin; //讀寫(xiě)二進(jìn)制地址
14 reg [ASIZE:0] wptr,rq1_wptr,rq2_wptr, //讀寫(xiě)指針打兩拍CDC同步
15 rptr,wq1_rptr,wq2_rptr;
16 wire [ASIZE:0] rbinnext,wbinnext, //讀寫(xiě)指針遞增
17 rgraynext,wgraynext; //讀寫(xiě)指針遞增對(duì)應(yīng)的格雷碼
18 wire [ASIZE - 1:0] waddr,raddr; //實(shí)際讀寫(xiě)mem的地址
19
20 reg [DSIZE - 1:0] mem [0:(1<<ASIZE) - 1]; //左移一位表示乘2
21
22
23 //---------------------雙口RAM存儲(chǔ)器 數(shù)據(jù)讀寫(xiě)-----------------------------
24 assign rdata = mem[raddr]; //讀
25 always@(posedge wclk) begin //寫(xiě)
26 if(winc && !wfull) begin
27 mem[waddr] <= wdata;
28 end
29 end
30
31 //---------------------將讀指針CDC到寫(xiě)時(shí)鐘域------------------------------
32 always@(posedge wclk or negedge wrstn) begin
33 if(!wrstn) begin
34 wq2_rptr <= 5'd0;
35 wq1_rptr <= 5'd0;
36 end
37 else begin
38 wq1_rptr <= rptr;
39 wq2_rptr <= wq1_rptr;
40 end
41 end
42
43 //---------------------將寫(xiě)指針CDC到讀時(shí)鐘--------------------------------
44 always@(posedge rclk or negedge rrstn) begin
45 if(!rrstn) begin
46 rq2_wptr <= 5'd0;
47 rq1_wptr <= 5'd0;
48 end
49 else begin
50 rq1_wptr <= wptr;
51 rq2_wptr <= rq1_wptr;
52 end
53 end
54
55
56 //讀相關(guān)指針的產(chǎn)生
57 always@(posedge rclk or negedge rrstn) begin
58 if(!rrstn) begin
59 rptr <= 5'd0;
60 rbin <= 5'd0;
61 end
62 else begin
63 rptr <= rgraynext;
64 rbin <= rbinnext;
65 end
66 end
67 //寫(xiě)相關(guān)的指針
68 always@(posedge wclk or negedge wrstn) begin
69 if(!wrstn) begin
70 wbin <= 5'd0;
71 wptr <= 5'd0;
72 end
73 else begin
74 wbin <= wbinnext;
75 wptr <= wgraynext;
76 end
77 end
78
79 //addr截取與格雷碼化指針
80 assign raddr = rbin[ASIZE - 1:0]; //mem的讀地址
81 assign rbinnext = rbin + (rinc & ~rempty); //mem的下一個(gè)讀地址
82 assign rgraynext = (rbinnext>>1) ^ rbinnext; //mem的讀地址對(duì)應(yīng)的格雷碼
83
84 assign waddr = wbin[ASIZE - 1:0];
85 assign wbinnext = wbin + (winc & !wfull);
86 assign wgraynext = (wbinnext>>1) ^ wbinnext;
87
88 //---------------------rempty產(chǎn)生------------------------------
89 //FIFO empty when the next rptr == synchronized wptr or on the reset
90 always@(posedge rclk or negedge rrstn) begin
91 if(!rclk) begin
92 rempty <= 1'b1;
93 else begin
94 rempty <= (rgraynext == rq2_wptr);
95 end
96 end
97
98 //---------------------wfull產(chǎn)生------------------------------
99 //FIFO full when CDC過(guò)來(lái)的格雷碼(采樣值)的最高位+次高位和bin轉(zhuǎn)換過(guò)來(lái)的格雷碼(理論值)均不同,剩下低位都相同
100 always@(posedge wclk or negedge wrstn) begin
101 if(!wrstn) begin
102 wfull <= 0;
103 end
104 else begin
105 wfull <= (wgraynext == {~wq2_rptr[ASIZE,ASIZE-1],wq2_rptr[ASIZE-2:0]});
106 end
107 end
108
109 endmodule
110 /*Clifford E. Cummings的文章中提到的STYLE #1,構(gòu)造一個(gè)指針寬度為N+1,深度為2^N字節(jié)的FIFO(為便方比較將格雷碼指
111 針轉(zhuǎn)換為二進(jìn)制指針)。當(dāng)指針的二進(jìn)制碼中最高位不一致而其它N位都 相等時(shí),FIFO為滿(在Clifford E. Cummings的文章中以
112 格雷碼表示是前兩位均不相同,而后兩位LSB相同為滿,這與換成二進(jìn)制表示的MSB不同其他相同為滿是一樣的)。當(dāng)指針完全相等時(shí),
113 FIFO為空。
114 這種方法思路非常明了,為了比較不同時(shí)鐘產(chǎn)生的指針,需要把不同時(shí)鐘域的信號(hào)同步到本時(shí)鐘域中來(lái),而使用Gray碼的目的就是使這個(gè)
115 異步同步化的過(guò)程發(fā)生亞穩(wěn)態(tài)的機(jī)率最小。
116 */
?
很好的講解:
https://www.cnblogs.com/aslmer/p/6114216.html#4067080
https://blog.csdn.net/wyj_2016/article/details/78469272
https://blog.csdn.net/IamSarah/article/details/76085635
https://blog.csdn.net/IamSarah/article/details/76093802
https://blog.csdn.net/tnaig/article/details/81503259
?
轉(zhuǎn)載于:https://www.cnblogs.com/ucas-ime/p/10254811.html
總結(jié)
以上是生活随笔為你收集整理的学习笔记二:异步FIFO的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 转 关于window10安装jdk,配置
- 下一篇: 2019.3.23 捕获异常