日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

vfifo控制mig_MIG IP控制DDR3读写测试

發布時間:2024/9/19 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vfifo控制mig_MIG IP控制DDR3读写测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文設計思想采用明德揚至簡設計法。在高速信號處理場合下,很短時間內就要緩存大量的數據,這時片內存儲資源已經遠遠不夠了。DDR SDRAM因其極高的性價比幾乎是每一款中高檔FPGA開發板的首選外部存儲芯片。DDR操作時序非常復雜,之所以在FPGA開發中用途如此廣泛,都要得意于MIG IP核。網上關于MIG控制DDR的資料很多,因此本文只講述個人認為較重要的內容。由于MIG IP核用戶接口時序較復雜,這里給出擴展接口模塊用于進一步簡化接口時序。

先來看看MIG IP核的架構:

了解下存儲芯片側重要接口:

ddr_addr             DDR3的行列地址

ddr_ba ? ?            DDR3的bank地址

ddr_cas_n ddr_ras_n ddr_we_n   命令控制

ddr_ck ddr_ck_n          ?差分時鐘

ddr_dm             ? 數據輸入屏蔽

ddr_o_dt            片上終端使能,用于使能和禁止片內終端電阻

ddr_reset_n           ? DDR3復位

ddr_dqs ddr_dqs_n        ?數據同步信號

ddr_dq             ? ?傳輸數據

之后我們從IP核配置開始說起。Controller Options這頁最為重要,其中包括時鐘策略和外部DDR芯片參數配置。首先時鐘周期選擇為400MHz,此時PHY to Controller Clock Ratio只能是4:1,也就是說MIG用戶側時鐘為100MHz。下半部分是選擇合適的DDR芯片型號和參數,要再三確認無誤。

Memory Options這頁輸入時鐘周期選擇為200MHz,根據Controller Options頁的選項,該時鐘經過PLL分頻和倍頻后的時鐘分別作為用戶側時鐘100MHz和DDR接口時鐘400MHz。

這里有個參考時鐘選項,如果Memory Options頁PLL輸入時鐘頻率選為200MHz,此處可以直接選擇Use System Clock,從而簡化接口。

以上是MIG IP核配置過程中較為重要的部分,實際上上述配置也可通過修改工程代碼中參數來重定義。IP核配置完成,打開example design工程頂層文件,我們來重點關注下用戶側接口功能和時序。

這是本人寫的注釋,更具體清晰的說明還是要查看官方文檔UG586.接下來看看寫數據和讀數據的接口時序圖(時鐘比例4:1,burst length = 8為例):

指令通道:

寫數據:

從時序圖可以看出,指令地址和數據使用兩套時序,彼此相互獨立。為了便于設計,直接將兩套時序嚴格對齊(情況1)也可以正常工作。

讀數據:

為什么說“時鐘比例4:1,burst length = 8為例”?這一點特別關鍵。此時用戶時鐘周期是DDR接口時鐘周期的4倍,也就是一個用戶時鐘信號上升沿對應8個DDR時鐘邊沿。burst length可以理解為MIG連續操作DDR地址的個數,故在4:1時鐘比例下,一個用戶時鐘周期正好對8個地址進行了讀/寫操作,256bit數據分8次(32bit)寫入DDR中。由此分析,在寫數據時讓app_wdf_end = app_wdf_wren即可,并且讀/寫操作時地址遞增步長為8.

雖然MIG IP核提供了用戶接口,但讀寫指令通道復用且需要實時關注兩個rdy信號造成了時序操作上的不方便。為此我們需要對接口進一步封裝,保證寫操作時只關注:寫使能user_wdata_en 寫地址user_waddr 寫數據user_wdata和寫準備就緒信號user_wdata_rdy,讀操作時只關注:讀使能user_rdata_en 讀地址user_raddr 讀數據user_rdata 讀數據有效user_rdata_vld和讀操作準備就緒user_rdata_rdy。

利用擴展接口模塊,將讀通道和寫通道接口分離,并分別例化一個FIFO緩存地址和數據。當讀/寫指令同時有效時,通過MIG側的優先級輪換邏輯輪流讀取其中一個FIFO,每次選一個FIFO讀取直至FIFO為空再重新選擇。其工程結構和核心代碼如下:

讀側邏輯核心代碼:

1 //讀側--------------------------------------------------------------

2

3 always @(posedge clk or negedge rst_n )begin

4 if(rst_n==0) begin

5 rd_flag <= (0) ;6 end

7 else if(rd_flag == 0 && mig_rdy && mig_wdf_rdy && !rdempty1 && (rdempty0 || (!rdempty0 && priority == 0)))begin

8 rd_flag <= (2'b01) ;//讀取 寫指令FIFO

9 end

10 else if(rd_flag == 0 && mig_rdy && !rdempty0 && (rdempty1 || (!rdempty1 && priority == 1)))begin

11 rd_flag <= (2'b10) ;//讀取 讀指令FIFO

12 end

13 else if((rd_flag == 2'b01 && rdempty1)||(rd_flag == 2'b10 &&rdempty0))14 rd_flag <= 0;15 end

16

17 //同時非空時輪換優先級

18 always @(posedge clk or negedge rst_n )begin

19 if(rst_n==0) begin

20 priority <= (0) ;21 end

22 else if(rd_flag == 0 && !rdempty0 && !rdempty1)begin

23 priority <= (!priority) ;24 end

25 end

為了方便測試,設計樣式生成模塊與擴展接口模塊用戶側連接,不斷向一段地址寫入固定數據序列并在一段時間后讀回。

1 `timescale 1ns /1ps2 /*

3 該模塊功能:4 周期性向一段地址執行讀寫操作 產生固定樣式待寫入數據用戶測試目的5 測試完畢后刪除該模塊,開發用戶接口6

7 具體為:8 1 寫從0開始之后的10個用戶地址(80個DDR地址):0~9遞增序列9 2 等待20個時鐘周期10 3 讀取寫入的10個用戶地址11 4 等待20個時鐘周期12 5 重復上述步驟13

14 說明:15 1 每個步驟之間有一個時鐘周期空閑16 2 由于burst_len = 8 4:1時鐘模式下一個用戶時鐘周期寫入數據對應同樣時間內8個DDR時鐘邊沿寫入數據,17 因此地址遞增步長為818 */

19 moduletraffic_gen20 #(parameter DATA_WIDTH = 32,21 ADDR_WIDTH = 29)22 (23 inputclk ,24 inputrst_n ,25

26 output reggen_wdata_en ,27 output reg [ ADDR_WIDTH-1:0] gen_waddr ,28 output reg [ DATA_WIDTH-1:0] gen_wdata ,29 input gen_wdata_rdy ,//寫指令和數據通道準備就緒

30

31 output reggen_rdata_en ,32 output reg [ ADDR_WIDTH-1:0] gen_raddr ,33 input [ DATA_WIDTH-1:0] gen_rdata ,34 inputgen_rdata_vld ,35 input gen_rdata_rdy //讀指令通道準備就緒

36 );37

38

39 reg [ (8-1):0] cnt0 ;40 wireadd_cnt0 ;41 wireend_cnt0 ;42 reg [ (2-1):0] cnt1 ;43 wireadd_cnt1 ;44 wireend_cnt1 ;45

46 reg [ DATA_WIDTH-1:0] gen_rdata_r ;47 reggen_rdata_vld_r ;48 regcom_flag ;49

50 wirewri_state;51 wirerd_state;52 wirecom_change_t;53

54 //操作周期計數器,計數值為欲操作用戶地址段長度+1(需要一個時鐘周期空閑)

55 always @(posedge clk or negedge rst_n) begin

56 if (rst_n==0) begin

57 cnt0 <= 0;58 end

59 else if(add_cnt0) begin

60 if(end_cnt0)61 cnt0 <= 0;62 else

63 cnt0 <= cnt0+1;64 end

65 end

66 assign add_cnt0 = (com_flag == 0 && gen_wdata_rdy) || (com_flag == 1 &&gen_rdata_rdy);67 assign end_cnt0 = add_cnt0 && cnt0 == (30)-1;68

69 //指令標志位 先是0--寫 再是1--讀

70 always @(posedge clk or negedge rst_n )begin

71 if(rst_n==0) begin

72 com_flag <= (0) ;73 end

74 else if(com_change_t)begin

75 com_flag <= (!com_flag) ;76 end

77 end

78

79 assign com_change_t = add_cnt0 && cnt0 == 10 - 1;80

81 //寫操作---------------------------------------------

82 always @(posedge clk or negedge rst_n )begin

83 if(rst_n==0) begin

84 gen_wdata_en <= (0) ;85 end

86 else if(wri_state)begin

87 gen_wdata_en <= (1'b1) ;

88 end

89 else begin

90 gen_wdata_en <= (0) ;91 end

92 end

93

94 assign wri_state = add_cnt0 && cnt0 <= 10-1 && com_flag == 0;95 assign rd_state = add_cnt0 && cnt0 <= 10-1 && com_flag == 1;96

97 always @(posedge clk or negedge rst_n )begin

98 if(rst_n==0) begin

99 gen_wdata <= (0) ;100 end

101 else begin

102 gen_wdata <=(cnt0) ;103 end

104 end

105

106 always@(posedge clk or negedge rst_n)begin

107 if(rst_n == 0)108 gen_waddr <= 0;109 else if(wri_state)110 gen_waddr <= gen_waddr + 29'd8;

111 else

112 gen_waddr <= 0;113 end

114 //讀操作----------------------------------------------

115

116 always @(posedge clk or negedge rst_n )begin

117 if(rst_n==0) begin

118 gen_rdata_en <= (0) ;119 end

120 else if(rd_state)begin

121 gen_rdata_en <= (1'b1) ;

122 end

123 else begin

124 gen_rdata_en <= (0) ;125 end

126 end

127

128 always@(posedge clk or negedge rst_n)begin

129 if(rst_n == 0)130 gen_raddr <= 0;131 else if(rd_state)132 gen_raddr <= gen_raddr + 29'd8;

133 else

134 gen_raddr <= 0;135 end

136

137 always @(posedge clk or negedge rst_n )begin

138 if(rst_n==0) begin

139 gen_rdata_r <= (0) ;140 end

141 else begin

142 gen_rdata_r <=(gen_rdata) ;143 end

144 end

145

146 always @(posedge clk or negedge rst_n )begin

147 if(rst_n==0) begin

148 gen_rdata_vld_r <= (0) ;149 end

150 else if(gen_rdata_vld)begin

151 gen_rdata_vld_r <= (1'b1) ;

152 end

153 else begin

154 gen_rdata_vld_r <= (0) ;155 end

156 end

157

158 endmodule

將traffic_gen和extend_interface模塊例化在MIG的example design中,利用ILA抓取MIG IP核用戶接口信號。

向地址8~80寫入數據0~9,再從此段地址中讀回數據,0~9被正確讀出,MIG IP核控制DDR3讀寫測試完畢。

總結

以上是生活随笔為你收集整理的vfifo控制mig_MIG IP控制DDR3读写测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。