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
1
/*
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行
case
(state)
//
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 for WR1_LOAD & RD1_LOAD to clear FIFO
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)