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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α...

發(fā)布時(shí)間:2025/3/17 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

實(shí)驗(yàn)二十:SDRAM模塊③ — 頁(yè)讀寫 α

完成單字讀寫與多字讀寫以后,接下來我們要實(shí)驗(yàn)頁(yè)讀寫。丑話當(dāng)前,實(shí)驗(yàn)二十的頁(yè)讀寫只是實(shí)驗(yàn)性質(zhì)的東西,其中不存在任何實(shí)用價(jià)值,筆者希望讀者可以把它當(dāng)成頁(yè)讀寫的熱身運(yùn)動(dòng)。

表示20.1 Mode Register的內(nèi)容。

Mode Register

A12

A11

A10

A9

A8

A7

A6

A5

A4

A3

A2

A1

A0

0

0

OP Code

0

0

CAS Latency

BT

Burst Length

A3

Burst Type

0

Sequential

1

Interleave

?

Burst Length

A2

A1

A0

A3 = 0

A3 = 1

0

0

0

1

1

0

0

1

2

2

0

1

0

4

4

0

1

1

8

8

1

1

1

Full Page

Reserved

A9

Write Mode

0

Burst Read and Burst Write

1

Burst Read and Single Write

A6

A5

A4

CAS Latency

0

1

0

2

0

1

1

3

所謂頁(yè)讀寫就是全列讀寫,而且表20.1告訴我們,頁(yè)讀寫必須將 A2~A0設(shè)置為3’b111。然而,Verilog的描述結(jié)果如代碼20.1所示:

7: // Send LMR Cmd. Burst Read & Write, 3'b010 mean CAS latecy = 3, Sequential,Full Page begin rCMD <= _LMR; rBA <= 2'b11; rA <= { 3'd0, 1'b0, 2'd0, 3'b011, 1'b0, 3'b111 }; i <= i + 1'b1; end

代碼20.1

如果我們一頁(yè)一頁(yè)的叫,基本上“一頁(yè)”的定義是非常曖昧的,因?yàn)椤耙豁?yè)”所指定的范圍會(huì)隨著該存儲(chǔ)器的容量而有所改變。舉例HY57V2562GTR 這只SDRAM,地址的指定范圍有 BA1~BA0,R12~R0,C8~C0,其中“一頁(yè)”是全列,亦即C8~C0。根據(jù)計(jì)算,C8~C0等價(jià)29 = 512,或者說頁(yè)讀寫有512的地址偏移量。

頁(yè)寫操作:

圖20.1 頁(yè)寫操作的理想時(shí)序圖。

圖20.1是筆者自定義的頁(yè)寫操作的理想時(shí)序圖,其中C1是為了控制讀寫的次數(shù)。頁(yè)讀寫相較字讀寫,前者好比一只不會(huì)停下沖鋒的山豬。一旦讀寫開始,SDRAM內(nèi)部的計(jì)數(shù)器就會(huì)從0開始計(jì)數(shù),計(jì)數(shù)結(jié)果為511又會(huì)從0重新計(jì)數(shù)。因?yàn)槿绱?#xff0c;頁(yè)讀寫需要利用BSTP命令禁止山豬繼續(xù)沖鋒。

此外,自動(dòng)預(yù)充對(duì)頁(yè)讀寫來說是無效的東西,因此A10拉不拉高都沒有關(guān)系,而且頁(yè)寫操作也不需要滿足 TWR/TDPL與TPR。圖20.1大致的時(shí)序過程如下:

l T1,發(fā)送ACT命令,BANK地址與行地址;

l T1半周期,SDRAM讀取;

l T2,滿足TRCD;

l T3,發(fā)送WR命令,BANK地址與列地址,還有第0數(shù)據(jù);

l T3半周期,SDRAM讀取

l T4,發(fā)送第1~511數(shù)據(jù),然后發(fā)送BSTP命令結(jié)束頁(yè)寫。

Verilog則可以這樣描述,結(jié)果如代碼20.2所示:

1. 1: // Send Active Command with Bank and Row address 2. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end 3. 4. 2: // wait TRCD 20ns 5. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 6. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 7. 8. 3: // Send Write command with row address 9. begin rCMD <= _WR; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0] }; D1 <= iData; i <= i + 1'b1; end 10. 11. 4: // continue write until end and send BSTP 12. if( C1 == 512 -1 ) begin rCMD <= _BSTP; C1 <= 14'd0; i <= i + 1'b1 ;end 13. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; D1 <= D1 + 1'b1; end

代碼20.2

如代碼20.2所示,步驟3寫第0數(shù)據(jù),步驟4則寫入第1~511數(shù)據(jù)并且發(fā)送 BSTP命令。

頁(yè)讀操作:

圖20.2 頁(yè)讀操作的理想時(shí)序圖。

圖20.2也是筆者自定義的理想時(shí)序圖。同樣,頁(yè)讀操也是一只不斷沖鋒的山豬,因此它需要BSTP這支停下的告示牌。除此之外,頁(yè)讀也沒有自行預(yù)充電的必要,而且TPR也不用滿足。實(shí)驗(yàn)二十要實(shí)驗(yàn)的頁(yè)讀比較單純,我們讀取第0數(shù)據(jù)以后立即發(fā)送BSTP命令來結(jié)束也操作。圖20.2大致的時(shí)序過程如下:

l T1,發(fā)送ACT命令,BANK地址與行地址;

l T1半周期,SDRAM讀取;

l T2,滿足TRCD;

l T3,發(fā)送RD命令,BANK地址與列地址;

l T3半周期,SDRAM讀取命令。

l T4,滿足 CAS Latency。

l T5,讀取第0數(shù)據(jù),然后發(fā)送BSTP命令。

Verilog則可以這樣描述,結(jié)果如代碼20.3所示:

1. 1: // Send Active command with Bank and Row address 2. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end 3. 4. 2: // wait TRCD 20ns 5. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 6. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 7. 8. 3: // Send Read command and column address 9. begin rCMD <= _RD; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0]}; i <= i + 1'b1; end 10. 11. 4: // wait CL 3 clock 12. if( C1 == CL -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 13. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 14. 15. 5: // Read Data 16. begin D1 <= S_DQ; rCMD <= _BSTP; i <= i + 1'b1; end

代碼20.3

如代碼20.3所示,步驟5讀取數(shù)據(jù)以后立即發(fā)送 BSTP命令以示結(jié)束頁(yè)讀操作。理解完畢以后我們便可以開始建模了。

圖20.3 SDRAM基礎(chǔ)模塊的建模圖。

圖20.3是SDRAM基礎(chǔ)模塊的建模圖,外表上和實(shí)驗(yàn)十八差不多,不過SDRAM功能模塊的內(nèi)容卻有一些改變。

sdram_funcmod.v
1. module sdram_funcmod 2. ( 3. input CLOCK, 4. input RESET, 5. 6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE, 7. output [1:0]S_BA, 8. output [12:0]S_A, 9. output [1:0]S_DQM, 10. inout [15:0]S_DQ, 11. 12. input [3:0]iCall, 13. output oDone, 14. input [23:0]iAddr, // [23:22]BA,[21:9]Row,[8:0]Column 15. input [15:0]iData, 16. output [15:0]oData 17. );

第3~16行是相關(guān)的輸入端聲明。

18. parameter T100US = 14'd13300; 19. // tRP 20ns, tRRC 63ns, tRCD 20ns, tMRD 2CLK, tWR/tDPL 2CLK, CAS Latency 3CLK 20. parameter TRP = 14'd3, TRRC = 14'd9, TMRD = 14'd2, TRCD = 14'd3, TWR = 14'd2, CL = 14'd3; 21. parameter _INIT = 5'b01111, _NOP = 5'b10111, _ACT = 5'b10011, _RD = 5'b10101, _WR = 5'b10100, 22. _BSTP = 5'b10110, _PR = 5'b10010, _AR = 5'b10001, _LMR = 5'b10000; 23.

第18~22行是相關(guān)的常量聲明。

24. reg [4:0]i; 25. reg [13:0]C1; 26. reg [15:0]D1; 27. reg [4:0]rCMD; 28. reg [1:0]rBA; 29. reg [12:0]rA; 30. reg [1:0]rDQM; 31. reg isOut; 32. reg isDone; 33. 34. always @ ( posedge CLOCK or negedge RESET ) 35. if( !RESET ) 36. begin 37. i <= 4'd0; 38. C1 <= 14'd0; 39. D1 <= 16'd0; 40. rCMD <= _NOP; 41. rBA <= 2'b11; 42. rA <= 13'h1fff; 43. rDQM <= 2'b00; 44. isOut <= 1'b1; 45. isDone <= 1'b0; 46. end

第24~46行是相關(guān)的寄存器聲明與復(fù)位操作。

47. else if( iCall[3] ) 48. case( i ) 49. 50. 0: // Set IO to output State 51. begin isOut <= 1'b1; i <= i + 1'b1; end 52. 53. 1: // Send Active Command with Bank and Row address 54. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end 55. 56. 2: // wait TRCD 20ns 57. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 58. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 59. 60. /*********************************************/ 61. 62. 3: // Send Write command with row address 63. begin rCMD <= _WR; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0] }; D1 <= iData; i <= i + 1'b1; end 64. 65. 4: // continue write until end and send BSTP 66. if( C1 == 512 -1 ) begin rCMD <= _BSTP; C1 <= 14'd0; i <= i + 1'b1 ;end 67. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; D1 <= D1 + 1'b1; end 68. 69. /**********************************************/ 70. 71. 5: // Generate done signal 72. begin rCMD <= _NOP; isDone <= 1'b1; i <= i + 1'b1; end 73. 74. 6: 75. begin isDone <= 1'b0; i <= 4'd0; end 76. 77. endcase

以上內(nèi)容為頁(yè)寫操作,注意步驟3寫入第0數(shù)據(jù),步驟4則寫入第1~511數(shù)據(jù)并且發(fā)送BSTP命令。

? 78. else if( iCall[2] ) 79. case( i ) 80. 81. 0: 82. begin isOut <= 1'b0; D1 <= 16'd0; i <= i + 1'b1; end 83. 84. 1: // Send Active command with Bank and Row address 85. begin rCMD <= _ACT; rBA <= iAddr[23:22]; rA <= iAddr[21:9]; i <= i + 1'b1; end 86. 87. 2: // wait TRCD 20ns 88. if( C1 == TRCD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 89. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 90. 91. /********************/ 92. 93. 3: // Send Read command and column address 94. begin rCMD <= _RD; rBA <= iAddr[23:22]; rA <= { 4'b0010, iAddr[8:0]}; i <= i + 1'b1; end 95. 96. 4: // wait CL 3 clock 97. if( C1 == CL -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 98. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 99. 100. /********************/ 101. 102. 5: // Read Data 103. begin D1 <= S_DQ; rCMD <= _BSTP; i <= i + 1'b1; end 104. 105. /********************/ 106. 107. 6: // Generate done signal 108. begin rCMD <= _NOP; isDone <= 1'b1; i <= i + 1'b1; end 109. 110. 7: 111. begin isDone <= 1'b0; i <= 4'd0; end 112. 113. endcase

以上內(nèi)容為頁(yè)讀操作,注意步驟5是讀取第0數(shù)據(jù)并且發(fā)送 BSTP命令。

114. else if( iCall[1] ) 115. case( i ) 116. 117. 0: // Send Precharge Command 118. begin rCMD <= _PR; i <= i + 1'b1; end 119. 120. 1: // wait TRP 20ns 121. if( C1 == TRP -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 122. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 123. 124. 2: // Send Auto Refresh Command 125. begin rCMD <= _AR; i <= i + 1'b1; end 126. 127. 3: // wait TRRC 63ns 128. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 129. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 130. 131. 4: // Send Auto Refresh Command 132. begin rCMD <= _AR; i <= i + 1'b1; end 133. 134. 5: // wait TRRC 63ns 135. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 136. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 137. 138. /********************/ 139. 140. 6: // Generate done signal 141. begin isDone <= 1'b1; i <= i + 1'b1; end 142. 143. 7: 144. begin isDone <= 1'b0; i <= 4'd0; end 145. 146. endcase

以上內(nèi)容是刷新操作。

? 147. else if( iCall[0] ) 148. case( i ) 149. 150. 0: // delay 100us 151. if( C1 == T100US -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 152. else begin C1 <= C1 + 1'b1; end 153. 154. /********************/ 155. 156. 1: // Send Precharge Command 157. begin rCMD <= _PR; { rBA, rA } <= 15'h3fff; i <= i + 1'b1; end 158. 159. 2: // wait TRP 20ns 160. if( C1 == TRP -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 161. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 162. 163. 3: // Send Auto Refresh Command 164. begin rCMD <= _AR; i <= i + 1'b1; end 165. 166. 4: // wait TRRC 63ns 167. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 168. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 169. 170. 5: // Send Auto Refresh Command 171. begin rCMD <= _AR; i <= i + 1'b1; end 172. 173. 6: // wait TRRC 63ns 174. if( C1 == TRRC -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 175. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 176. 177. /********************/ 178. 179. 7: // Send LMR Cmd. Burst Read & Write, 3'b010 mean CAS latecy = 3, Sequential,Full Page 180. begin rCMD <= _LMR; rBA <= 2'b11; rA <= { 3'd0, 1'b0, 2'd0, 3'b011, 1'b0, 3'b111 }; i <= i + 1'b1; end 181. 182. 8: // Send 2 nop CLK for tMRD 183. if( C1 == TMRD -1 ) begin C1 <= 14'd0; i <= i + 1'b1; end 184. else begin rCMD <= _NOP; C1 <= C1 + 1'b1; end 185. 186. /********************/ 187. 188. 9: // Generate done signal 189. begin isDone <= 1'b1; i <= i + 1'b1; end 190. 191. 10: 192. begin isDone <= 1'b0; i <= 4'd0; end 193. 194. endcase 195.

以上內(nèi)容是初始化,注意步驟7的Mode Register 內(nèi)容,Busrt Length 為 3’b111。

196. assign { S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE } = rCMD; 197. assign { S_BA, S_A } = { rBA, rA }; 198. assign S_DQM = rDQM; 199. assign S_DQ = isOut ? D1 : 16'hzzzz; 200. assign oDone = isDone; 201. assign oData = D1; 202. 203. endmodule

第196~201行是相關(guān)的輸出驅(qū)動(dòng)。

sdram_ctrlmod.v

該控制模塊的內(nèi)容與實(shí)驗(yàn)十八一致。

sdram_basemod.v

該組合模塊的內(nèi)容也與實(shí)驗(yàn)十八一致

sdram_demo.v

圖20.4 實(shí)驗(yàn)二十的建模圖。

圖20.4是實(shí)驗(yàn)二十的建模圖,外觀上與實(shí)驗(yàn)十八一樣,不過核心操作的內(nèi)容卻有所不同,具體內(nèi)容我們還是來看代碼吧。

1. module sdram_demo 2. ( 3. input CLOCK, 4. input RESET, 5. output S_CLK, 6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE, 7. output [12:0]S_A, 8. output [1:0]S_BA, 9. output [1:0]S_DQM, 10. inout [15:0]S_DQ, 11. output TXD 12. );

以上內(nèi)容為相關(guān)的出入端聲明。

13. wire CLOCK1,CLOCK2; 14. 15. pll_module U1 16. ( 17. .inclk0 ( CLOCK ), // 50Mhz 18. .c0 ( CLOCK1 ), // 133Mhz -210 degree phase 19. .c1 ( CLOCK2 ) // 133Mhz 20. ); 21.

以上內(nèi)容為PLL模塊的實(shí)例化。

22. wire [1:0]DoneU2; 23. wire [15:0]DataU2; 24. 25. sdram_basemod U2 26. ( 27. .CLOCK( CLOCK1 ), 28. .RESET( RESET ), 29. .S_CKE( S_CKE ), 30. .S_NCS( S_NCS ), 31. .S_NRAS( S_NRAS ), 32. .S_NCAS( S_NCAS ), 33. .S_NWE( S_NWE ), 34. .S_A( S_A ), 35. .S_BA( S_BA ), 36. .S_DQM( S_DQM ), 37. .S_DQ( S_DQ ), 38. .iCall( isCall ), 39. .oDone( DoneU2 ), 40. .iAddr( D1 ), 41. .iData( D2 ), 42. .oData( DataU2 ) 43. ); 44.

以上內(nèi)容為SDRAM基礎(chǔ)模塊的實(shí)例化。

45. parameter B115K2 = 11'd1157, TXFUNC = 6'd16; 46. 47. reg [5:0]i,Go; 48. reg [10:0]C1; 49. reg [23:0]D1; 50. reg [15:0]D2,D3; 51. reg [10:0]T; 52. reg [1:0]isCall; 53. reg rTXD; 54. 55. always @ ( posedge CLOCK1 or negedge RESET ) 56. if( !RESET ) 57. begin 58. i <= 6'd0; 59. Go <= 6'd0; 60. C1 <= 11'd0; 61. D1 <= 24'd0; 62. D2 <= 16'd0; 63. D3 <= 16'd0; 64. T <= 11'd0; 65. isCall <= 2'b00; 66. rTXD <= 1'b1; 67. end 68. else

以上內(nèi)容為相關(guān)的寄存器聲明還有復(fù)位操作。第45行是波特率還有偽函數(shù)入口的常量聲明。

69. case( i ) 70. 71. 0: 72. if( DoneU2[1] ) begin isCall[1] <= 1'b0; i <= i + 1'b1; end 73. else begin isCall[1] <= 1'b1; D1 <= 24'd0; D2 <= 16'hA000; end 74. 75. 1: 76. if( DoneU2[0] ) begin D3 <= DataU2; isCall[0] <= 1'b0; i <= i + 1'b1; end 77. else begin isCall[0] <= 1'b1; end 78. 79. 2: 80. begin T <= { 2'b11, D3[15:8], 1'b0 }; i <= TXFUNC; Go <= i + 1'b1; end 81. 82. 3: 83. begin T <= { 2'b11, D3[7:0], 1'b0 }; i <= TXFUNC; Go <= i + 1'b1; end 84. 85. 4: 86. if( D1 == 24'd511 ) i <= i + 1'b1; 87. else begin D1 <= D1 + 1'b1; i <= 6'd1; end 88. 89. 5: 90. i <= i; 91. 92. /******************************/ 93.

以上內(nèi)容為部分核心操作。步驟0將數(shù)據(jù) 16’hA×××從地址0寫至地址511,其中×××?xí)?jīng)由頁(yè)寫而自行遞增。換句話說,數(shù)據(jù)16’hA000~16’hA1FF從地址0寫至地址511。

步驟1則用來讀取數(shù)據(jù),步驟2~3將讀出的數(shù)據(jù)一一發(fā)送出去。步驟4用來遞增地址,從0~511,然后返回步驟1,直至人為頁(yè)讀結(jié)束。

94. 16,17,18,19,20,21,22,23,24,25,26: 95. if( C1 == B115K2 -1 ) begin C1 <= 11'd0; i <= i + 1'b1; end 96. else begin rTXD <= T[i - 16]; C1 <= C1 + 1'b1; end 97. 98. 27: 99. i <= Go; 100. 101. endcase 102. 103. assign S_CLK = CLOCK2; 104. assign TXD = rTXD; 105. 106. endmodule

以上內(nèi)容為部分核心操作。步驟16~27是發(fā)送一幀數(shù)據(jù)的偽函數(shù)。第103~104行則是相關(guān)的輸出驅(qū)動(dòng)。綜合完畢并且下載程序,如果串口調(diào)試軟件出現(xiàn)數(shù)據(jù) A000~A1FF表示實(shí)驗(yàn)成功。

總結(jié)

以上是生活随笔為你收集整理的【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。