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

Subversion Repositories vg_z80_sbc

[/] [vg_z80_sbc/] [trunk/] [rtl/] [ddr_wpath.v] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 hharte
//----------------------------------------------------------------------------
2
//
3
// Wishbone DDR Controller -- fast write data-path
4
// 
5
// (c) Joerg Bornschein (<jb@capsec.org>)
6
//
7
//----------------------------------------------------------------------------
8
 
9
`include "ddr_include.v"
10
 
11
module ddr_wpath (
12
        input                  clk,
13
        input                  clk90,
14
        input                  reset,
15
        // CBA async fifo
16
        input                  cba_clk,
17
        input [`CBA_RNG]       cba_din,
18
        input                  cba_wr,
19
        output                 cba_full,
20
        // WDATA async fifo
21
        input                  wdata_clk,
22
        input [`WFIFO_RNG]     wdata_din,
23
        input                  wdata_wr,
24
        output                 wdata_full,
25
        // sample to rdata
26
        output                 sample,
27
        // DDR 
28
        output                 ddr_clk,
29
        output                 ddr_clk_n,
30
        output                 ddr_ras_n,
31
        output                 ddr_cas_n,
32
        output                 ddr_we_n,
33
        output [  `A_RNG]      ddr_a,
34
        output [ `BA_RNG]      ddr_ba,
35
        output [ `DM_RNG]      ddr_dm,
36
        output [ `DQ_RNG]      ddr_dq,
37
        output [`DQS_RNG]      ddr_dqs,
38
        output                 ddr_dqs_oe
39
);
40
 
41
wire gnd = 1'b0;
42
wire vcc = 1'b1;
43
 
44
//----------------------------------------------------------------------------
45
// CBA async. fifo
46
//----------------------------------------------------------------------------
47
wire [`CBA_RNG]        cba_data;
48
wire                   cba_empty;
49
wire                   cba_ack;
50
 
51
wire                   cba_avail = ~cba_empty;
52
 
53
async_fifo #(
54
        .DATA_WIDTH( `CBA_WIDTH ),
55
        .ADDRESS_WIDTH( 3 )
56
) cba_fifo (
57
        .Data_out(   cba_data  ),
58
        .Empty_out(  cba_empty ),
59
        .ReadEn_in(  cba_ack   ),
60
        .RClk(       clk       ),
61
        //
62
        .Data_in(    cba_din   ),
63
        .WriteEn_in( cba_wr    ),
64
        .Full_out(   cba_full  ),
65
        .WClk(       cba_clk   ),
66
        .Clear_in(   reset     )
67
);
68
 
69
//----------------------------------------------------------------------------
70
// WDATA async. fifo
71
//----------------------------------------------------------------------------
72
wire [`WFIFO_RNG]      wdata_data;
73
wire                   wdata_empty;
74
wire                   wdata_ack;
75
 
76
wire                   wdata_avail = ~wdata_empty;
77
 
78
async_fifo #(
79
        .DATA_WIDTH( `WFIFO_WIDTH ),
80
        .ADDRESS_WIDTH( 3 )
81
) wdata_fifo (
82
        .Data_out(   wdata_data  ),
83
        .Empty_out(  wdata_empty ),
84
        .ReadEn_in(  wdata_ack   ),
85
        .RClk(      ~clk90       ),
86
        //
87
        .Data_in(    wdata_din   ),
88
        .WriteEn_in( wdata_wr    ),
89
        .Full_out(   wdata_full  ),
90
        .WClk(       wdata_clk   ),
91
        .Clear_in(   reset       )
92
);
93
 
94
 
95
//----------------------------------------------------------------------------
96
// Handle CBA 
97
//----------------------------------------------------------------------------
98
reg  [3:0]      delay_count;
99
 
100
reg [`CBA_RNG]  ddr_cba;
101
wire [`CBA_RNG] CBA_NOP = { `DDR_CMD_NOP, 15'b0 };
102
 
103
assign cba_ack = cba_avail & (delay_count == 0);
104
 
105
wire [`CMD_RNG] cba_cmd = cba_data[(`CBA_WIDTH-1):(`CBA_WIDTH-3)];
106
 
107
always @(posedge clk)
108
begin
109
        if (reset) begin
110
                delay_count <= 0;
111
                ddr_cba     <= CBA_NOP;
112
        end else begin
113
                if (delay_count != 0) begin
114
                        delay_count <= delay_count - 1;
115
                        ddr_cba     <= CBA_NOP;
116
        end
117
 
118
                if (!cba_ack) begin
119
                        ddr_cba  <= CBA_NOP;
120
                end else begin
121
                        ddr_cba <= cba_data;
122
 
123
                        case (cba_cmd)
124
                                `DDR_CMD_MRS   : delay_count <= 2;
125
                                `DDR_CMD_AR    : delay_count <= 14;
126
                                `DDR_CMD_ACT   : delay_count <= 4;
127
                                `DDR_CMD_PRE   : delay_count <= 2;
128
                                `DDR_CMD_READ  : delay_count <= 6;   // XXX
129
                                `DDR_CMD_WRITE : delay_count <= 8;   // XXX
130
                        endcase
131
                end
132
        end
133
end
134
 
135
 
136
//----------------------------------------------------------------------------
137
// READ-SHIFT-REGISTER
138
//----------------------------------------------------------------------------
139
reg [0:7] read_shr;
140
wire      read_cmd = (cba_cmd == `DDR_CMD_READ) & cba_ack;
141
assign    sample   = read_shr[1];
142
 
143
always @(posedge clk)
144
begin
145
        if (reset)
146
                read_shr <= 'b0;
147
        else begin
148
                if (read_cmd)
149
                        read_shr <= { 8'b00011111 };
150
                else
151
                        read_shr <= { read_shr[1:7], 1'b0 };
152
        end
153
end
154
 
155
//----------------------------------------------------------------------------
156
// WRITE-SHIFT-REGISTER
157
//----------------------------------------------------------------------------
158
 
159
reg [0:4] write_shr;
160
wire      write_cmd = (cba_cmd == `DDR_CMD_WRITE) & cba_ack;
161
 
162
always @(posedge clk)
163
begin
164
        if (reset)
165
                write_shr <= 'b0;
166
        else begin
167
                if (write_cmd)
168
                        write_shr <= { 5'b11111 };
169
                else
170
                        write_shr <= { write_shr[1:4], 1'b0 };
171
        end
172
end
173
 
174
//----------------------------------------------------------------------------
175
// DDR_DQS, DDR_DQS_OE
176
//----------------------------------------------------------------------------
177
genvar i;
178
 
179
reg ddr_dqs_oe_reg;
180
assign ddr_dqs_oe = ddr_dqs_oe_reg;
181
 
182
always @(negedge clk)
183
begin
184
  ddr_dqs_oe_reg <= write_shr[0];
185
end
186
 
187
FDDRRSE ddr_clk_reg (
188
        .Q(   ddr_clk      ),
189
        .C0(  clk90        ),
190
        .C1( ~clk90        ),
191
        .CE(  vcc          ),
192
        .D0(  vcc          ),
193
        .D1(  gnd          ),
194
        .R(   gnd          ),
195
        .S(   gnd          )
196
);
197
 
198
FDDRRSE ddr_clk_n_reg (
199
        .Q(   ddr_clk_n    ),
200
        .C0(  clk90        ),
201
        .C1( ~clk90        ),
202
        .CE(  vcc          ),
203
        .D0(  gnd          ),
204
        .D1(  vcc          ),
205
        .R(   gnd          ),
206
        .S(   gnd          )
207
);
208
 
209
 
210
generate
211
for (i=0; i<`DQS_WIDTH; i=i+1) begin : DQS
212
        FDDRRSE ddr_dqs_reg (
213
                .Q(   ddr_dqs[i]   ),
214
                .C0(  clk          ),
215
                .C1( ~clk          ),
216
                .CE(  vcc          ),
217
                .D0(  write_shr[1] ),
218
                .D1(  gnd          ),
219
                .R(   gnd          ),
220
                .S(   gnd          )
221
        );
222
end
223
endgenerate
224
 
225
 
226
//----------------------------------------------------------------------------
227
// DQ data output
228
//----------------------------------------------------------------------------
229
wire [`DQ_RNG] buf_d0;
230
wire [`DM_RNG] buf_m0;
231
reg  [`DQ_RNG] buf_d1;       // pipleine high word data
232
reg  [`DM_RNG] buf_m1;       // pipleine high word mask
233
 
234
assign buf_d0 = wdata_data[`WFIFO_D0_RNG];
235
assign buf_m0 = wdata_data[`WFIFO_M0_RNG];
236
 
237
always @(negedge clk90)
238
begin
239
        buf_d1 <= wdata_data[`WFIFO_D1_RNG];
240
        buf_m1 <= wdata_data[`WFIFO_M1_RNG];
241
end
242
 
243
assign wdata_ack = write_shr[1];
244
 
245
// generate DDR_DQ register
246
generate
247
for (i=0; i<`DQ_WIDTH; i=i+1) begin : DQ_REG
248
        FDDRRSE ddr_dq_reg (
249
                .Q(   ddr_dq[i]    ),
250
                .C0( ~clk90        ),
251
                .C1(  clk90        ),
252
                .CE(  vcc          ),
253
                .D0(  buf_d0[i]    ),
254
                .D1(  buf_d1[i]    ),
255
                .R(   gnd          ),
256
                .S(   gnd          )
257
        );
258
end
259
endgenerate
260
 
261
// generate DDR_DM register
262
generate
263
for (i=0; i<`DM_WIDTH; i=i+1) begin : DM_REG
264
        FDDRRSE ddr_dm_reg (
265
                .Q(   ddr_dm[i]    ),
266
                .C0( ~clk90        ),
267
                .C1(  clk90        ),
268
                .CE(  vcc          ),
269
                .D0(  buf_m0[i]    ),
270
                .D1(  buf_m1[i]    ),
271
                .R(   gnd          ),
272
                .S(   gnd          )
273
        );
274
end
275
endgenerate
276
 
277
//----------------------------------------------------------------------------
278
// Connect ddr_cba to actual DDR pins
279
//----------------------------------------------------------------------------
280
assign ddr_a     = ddr_cba[(`A_WIDTH-1):0];
281
assign ddr_ba    = ddr_cba[(`A_WIDTH+`BA_WIDTH-1):(`A_WIDTH)];
282
assign ddr_ras_n = ddr_cba[(`CBA_WIDTH-1)];
283
assign ddr_cas_n = ddr_cba[(`CBA_WIDTH-2)];
284
assign ddr_we_n  = ddr_cba[(`CBA_WIDTH-3)];
285
 
286
endmodule

powered by: WebSVN 2.1.0

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