(原創) 如何在DE2用硬體存取SDRAM(4 port)? (IC Design) (DE2)
Abstract
之前曾經討論如何在DE2用硬體的Verilog存取SDRAM,當時所使用的SDRAM controller是2 port的,一個read一個write,對大部分情況而言是夠用的,這次要討論的是4 port的SDRAM controller, 2 read, 2 write。
Introduction
使用環境:Quartus II 7.2 SP1 + MegaCore IP 7.2 SP1 + DE2(Cyclone II EP2C35F627C6)
友晶的很多範例,用的都是DE2_CCD、DE2_CCD_detect、DE2_CCD_PIP、DE2_pong_demo、DE2_LCM_CCD....等用的都是Sdram_Control_4Port這個SDRAM controller,有2個write port與2個read port,優點是在一個clock下,可做2次的read和write。但這個4 port的SDRAM controller用法與之前2 port SDAM controller用法並不一樣。
如同上一篇的範例,用switch當成2進位的輸入,用七段顯示器做16進位輸出,但這次使用的是4 port的SDRAM controller。
Verilog / SDRAM_HR_HW.v
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3
4 Filename : SDRAM_HR_HW.v
5 Compiler : Quartus II 7.2 SP1
6 Description : Demo how to use abstract base class simulate interface
7 Release : 04/25/2008 1.0
8 */
9 module SDRAM_HR_HW (
10 input CLOCK_50,
11 input [3:0] KEY,
12 input [17:0] SW,
13 output [17:0] LEDR,
14 output [6:0] HEX0,
15 HEX1,
16 HEX2,
17 HEX3,
18 HEX4,
19 HEX5,
20 HEX6,
21 HEX7,
22 //SDRAM side
23 output [11:0] DRAM_ADDR,
24 inout [15:0] DRAM_DQ,
25 output DRAM_BA_0,
26 DRAM_BA_1,
27 DRAM_RAS_N,
28 DRAM_CAS_N,
29 DRAM_CKE,
30 DRAM_CLK,
31 DRAM_WE_N,
32 DRAM_CS_N,
33 DRAM_LDQM,
34 DRAM_UDQM
35 );
36
37 reg read; // read enable register
38 reg write; // write enable register
39 reg [1:0] state; // FSM state register
40 reg [15:0] data_in; // data input register
41 wire [15:0] DATA_OUT; // data output
42 reg [15:0] data_out; // data output register
43 wire DELAY_RESET; // delay for SDRAM controller load
44 wire RESET_n = KEY[0]; // reset from KEY[0]
45
46 assign LEDR = SW;
47
48 Sdram_Control_4Port u0 (
49 // HOST Side
50 .REF_CLK(CLOCK_50),
51 .RESET_N(1'b1),
52 // FIFO Write Side 1
53 .WR1_DATA(data_in),
54 .WR1(write),
55 .WR1_ADDR(0),
56 .WR1_MAX_ADDR(640*512*2),
57 .WR1_LENGTH(9'h100),
58 .WR1_LOAD(!DELAY_RESET),
59 .WR1_CLK(CLOCK_50),
60 // FIFO Read Side 1
61 .RD1_DATA(DATA_OUT),
62 .RD1(read),
63 .RD1_ADDR(640*16),
64 .RD1_MAX_ADDR(640*496),
65 .RD1_LENGTH(9'h100),
66 .RD1_LOAD(!DELAY_RESET),
67 .RD1_CLK(CLOCK_50),
68 // SDRAM Side
69 .SA(DRAM_ADDR),
70 .BA({DRAM_BA_1,DRAM_BA_0}),
71 .CS_N(DRAM_CS_N),
72 .CKE(DRAM_CKE),
73 .RAS_N(DRAM_RAS_N),
74 .CAS_N(DRAM_CAS_N),
75 .WE_N(DRAM_WE_N),
76 .DQ(DRAM_DQ),
77 .DQM({DRAM_UDQM,DRAM_LDQM}),
78 .SDR_CLK(DRAM_CLK)
79 );
80
81 SEG7_LUT_8 u1 (
82 .oSEG0(HEX0), // output SEG0
83 .oSEG1(HEX1), // output SEG1
84 .oSEG2(HEX2), // output SEG2
85 .oSEG3(HEX3), // output SEG3
86 .oSEG4(HEX4), // output SEG4
87 .oSEG5(HEX5), // output SEG5
88 .oSEG6(HEX6), // output SEG6
89 .oSEG7(HEX7), // output SEG7
90 .iDIG(data_out), // input data
91 .iWR(1'b1), // write enable
92 .iCLK(CLOCK_50), // clock
93 .iRESET_n(RESET_n)
94 );
95
96
97 // reset delay for WR1_LOAD & RD1_LOAD to clear FIFO
98 Reset_Delay u2 (
99 .iCLK(CLOCK_50),
100 .iRST(KEY[0]),
101 .oRST(DELAY_RESET),
102 );
103
104 // state 0 : read switch & write SDRAM
105 // state 1 : read SDRAM & write to SEG7
106 always @(posedge CLOCK_50 or negedge RESET_n)
107 begin
108 if (!RESET_n) begin
109 read <= 0; // read enable register
110 write <= 0; // write enale register
111 state <= 0; // FSM state register
112 data_in <= 0; // data input register
113 data_out <= 0; // data output register
114 end
115 else
116 begin
117 case (state)
118 // state 0 : read switch & write SDRAM
119 0: begin
120 read <= 0; // read diable
121 write <= 1; // write enable
122 data_in <= {SW[15:0]}; // write SDRAM data
123 state <= 1; // next state
124 end
125
126 // state 2 : read SDRAM & write to SEG7
127 1: begin
128 read <= 1; // read enable
129 write <= 0; // write disable
130 data_out <= DATA_OUT; // read SDRAM data
131 state <= 0; // next state
132 end
133 endcase
134 end
135 end
136
137 endmodule
109行
// state 0 : read switch & write SDRAM
0: begin
read <= 0; // read diable
write <= 1; // write enable
data_in <= {SW[15:0]}; // write SDRAM data
state <= 1; // next state
end
// state 2 : read SDRAM & write to SEG7
1: begin
read <= 1; // read enable
write <= 0; // write disable
data_out <= DATA_OUT; // read SDRAM data
state <= 0; // next state
end
endcase
2 port由於需要判斷DONE,還需多一個clock,因此需要4個FSM,但4 port並不需要,所以只要2個FSM即可。當要寫入SDRAM時,只需將read設為0,write設為1,將欲寫入的資料傳入data_in,最後進入下一個state即可。
同理,當要從SDRAM讀出資料時,只需將read設為1,write設為0,從DATA_OUT讀出資料,最後進入下一個state即可。
比較詭異的是97行
Reset_Delay u2 (
.iCLK(CLOCK_50),
.iRST(KEY[0]),
.oRST(DELAY_RESET),
);
58行的WR1_LOAD()與66行的RD1_LOAD()是為了清空FIFO,若只傳由KEY[0]所連結的RESET_n,將無法正常運作,必須做了Reset_Delay之後,再傳入SDRAM controller。
完整程式碼下載
sdram_hr_hw_4port.7z
Conclusion
Sdram_Control_4Port都放在完整程式碼中,有需要的人可自行下載。
由於SDRAM的容量很大,4 port可以讓你在一個clock內做2次的讀寫,有效的運用將可加快整體速度。
See Also
(原創) 如何在DE2用軟體存取SDRAM? (IC Design) (DE2) (Nios II)
(原創) 如何在DE2用硬體存取SDRAM? (IC Design) (DE2)
(筆記) DE2與SDRAM相關資料總整理 (SOC) (DE2)