OpenCores
URL https://opencores.org/ocsvn/hpdmc/hpdmc/trunk

Subversion Repositories hpdmc

[/] [hpdmc/] [trunk/] [hpdmc_ddr32/] [rtl/] [hpdmc_datactl.v] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 lekernel
/*
2
 * Milkymist VJ SoC
3
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, version 3 of the License.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
 
18
module hpdmc_datactl(
19
        input sys_clk,
20
        input sdram_rst,
21
 
22
        input read,
23
        input write,
24
        input [3:0] concerned_bank,
25
        output reg read_safe,
26
        output reg write_safe,
27
        output [3:0] precharge_safe,
28
 
29
        output reg ack,
30
        output reg direction,
31
        output direction_r,
32
 
33
        input tim_cas,
34
        input [1:0] tim_wr
35
);
36
 
37
/*
38
 * read_safe: whether it is safe to register a Read command
39
 * into the SDRAM at the next cycle.
40
 */
41
 
42
reg [2:0] read_safe_counter;
43
always @(posedge sys_clk) begin
44
        if(sdram_rst) begin
45
                read_safe_counter <= 3'd0;
46
                read_safe <= 1'b1;
47
        end else begin
48
                if(read) begin
49
                        read_safe_counter <= 3'd4;
50
                        read_safe <= 1'b0;
51
                end else if(write) begin
52
                        /* after a write, read is unsafe for 5 cycles (4 transfers + tWTR=1) */
53
                        read_safe_counter <= 3'd5;
54
                        read_safe <= 1'b0;
55
                end else begin
56
                        if(read_safe_counter == 3'd1)
57
                                read_safe <= 1'b1;
58
                        if(~read_safe)
59
                                read_safe_counter <= read_safe_counter - 3'd1;
60
                end
61
        end
62
end
63
 
64
/*
65
 * write_safe: whether it is safe to register a Write command
66
 * into the SDRAM at the next cycle.
67
 */
68
 
69
reg [2:0] write_safe_counter;
70
always @(posedge sys_clk) begin
71
        if(sdram_rst) begin
72
                write_safe_counter <= 3'd0;
73
                write_safe <= 1'b1;
74
        end else begin
75
                if(read) begin
76
                        write_safe_counter <= {1'b1, tim_cas, ~tim_cas};
77
                        write_safe <= 1'b0;
78
                end else if(write) begin
79
                        write_safe_counter <= 3'd3;
80
                        write_safe <= 1'b0;
81
                end else begin
82
                        if(write_safe_counter == 3'd1)
83
                                write_safe <= 1'b1;
84
                        if(~write_safe)
85
                                write_safe_counter <= write_safe_counter - 3'd1;
86
                end
87
        end
88
end
89
 
90
/* Generate ack signal.
91
 * After write is asserted, it should pulse after 2 cycles.
92
 * After read is asserted, it should pulse after CL+3 cycles, that is
93
 * 5 cycles when tim_cas = 0
94
 * 6 cycles when tim_cas = 1
95
 */
96
 
97
reg ack_read3;
98
reg ack_read2;
99
reg ack_read1;
100
reg ack_read0;
101
 
102
always @(posedge sys_clk) begin
103
        if(sdram_rst) begin
104
                ack_read3 <= 1'b0;
105
                ack_read2 <= 1'b0;
106
                ack_read1 <= 1'b0;
107
                ack_read0 <= 1'b0;
108
        end else begin
109
                if(tim_cas) begin
110
                        ack_read3 <= read;
111
                        ack_read2 <= ack_read3;
112
                        ack_read1 <= ack_read2;
113
                        ack_read0 <= ack_read1;
114
                end else begin
115
                        ack_read2 <= read;
116
                        ack_read1 <= ack_read2;
117
                        ack_read0 <= ack_read1;
118
                end
119
        end
120
end
121
 
122
reg ack0;
123
always @(posedge sys_clk) begin
124
        if(sdram_rst) begin
125
                ack0 <= 1'b0;
126
                ack <= 1'b0;
127
        end else begin
128
                ack0 <= ack_read0|write;
129
                ack <= ack0;
130
        end
131
end
132
 
133
/* during a 4-word write, we drive the pins for 5 cycles
134
 * and 1 cycle in advance (first word is invalid)
135
 * so that we remove glitches on DQS without resorting
136
 * to asynchronous logic.
137
 */
138
 
139
/* direction must be glitch-free, as it directly drives the
140
 * tri-state enable for DQ and DQS.
141
 */
142
reg write_d;
143
reg [2:0] counter_writedirection;
144
always @(posedge sys_clk) begin
145
        if(sdram_rst) begin
146
                counter_writedirection <= 3'd0;
147
                direction <= 1'b0;
148
        end else begin
149
                if(write_d) begin
150
                        counter_writedirection <= 3'b101;
151
                        direction <= 1'b1;
152
                end else begin
153
                        if(counter_writedirection == 3'b001)
154
                                direction <= 1'b0;
155
                        if(direction)
156
                                counter_writedirection <= counter_writedirection - 3'd1;
157
                end
158
        end
159
end
160
 
161
assign direction_r = write_d|(|counter_writedirection);
162
 
163
always @(posedge sys_clk) begin
164
        if(sdram_rst)
165
                write_d <= 1'b0;
166
        else
167
                write_d <= write;
168
end
169
 
170
/* Counters that prevent a busy bank from being precharged */
171
hpdmc_banktimer banktimer0(
172
        .sys_clk(sys_clk),
173
        .sdram_rst(sdram_rst),
174
 
175
        .tim_cas(tim_cas),
176
        .tim_wr(tim_wr),
177
 
178
        .read(read & concerned_bank[0]),
179
        .write(write & concerned_bank[0]),
180
        .precharge_safe(precharge_safe[0])
181
);
182
hpdmc_banktimer banktimer1(
183
        .sys_clk(sys_clk),
184
        .sdram_rst(sdram_rst),
185
 
186
        .tim_cas(tim_cas),
187
        .tim_wr(tim_wr),
188
 
189
        .read(read & concerned_bank[1]),
190
        .write(write & concerned_bank[1]),
191
        .precharge_safe(precharge_safe[1])
192
);
193
hpdmc_banktimer banktimer2(
194
        .sys_clk(sys_clk),
195
        .sdram_rst(sdram_rst),
196
 
197
        .tim_cas(tim_cas),
198
        .tim_wr(tim_wr),
199
 
200
        .read(read & concerned_bank[2]),
201
        .write(write & concerned_bank[2]),
202
        .precharge_safe(precharge_safe[2])
203
);
204
hpdmc_banktimer banktimer3(
205
        .sys_clk(sys_clk),
206
        .sdram_rst(sdram_rst),
207
 
208
        .tim_cas(tim_cas),
209
        .tim_wr(tim_wr),
210
 
211
        .read(read & concerned_bank[3]),
212
        .write(write & concerned_bank[3]),
213
        .precharge_safe(precharge_safe[3])
214
);
215
 
216
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.