AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
Main Page
Design Unit List
Files
File List
All
Classes
Files
Variables
src
common
DDR
ddr3_1_9_a
controller
mig_7series_v1_9_col_mach.v
1
//*****************************************************************************
2
// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved.
3
//
4
// This file contains confidential and proprietary information
5
// of Xilinx, Inc. and is protected under U.S. and
6
// international copyright and other intellectual property
7
// laws.
8
//
9
// DISCLAIMER
10
// This disclaimer is not a license and does not grant any
11
// rights to the materials distributed herewith. Except as
12
// otherwise provided in a valid license issued to you by
13
// Xilinx, and to the maximum extent permitted by applicable
14
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
15
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
16
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
17
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
18
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
19
// (2) Xilinx shall not be liable (whether in contract or tort,
20
// including negligence, or under any other theory of
21
// liability) for any loss or damage of any kind or nature
22
// related to, arising under or in connection with these
23
// materials, including for any direct, or any indirect,
24
// special, incidental, or consequential loss or damage
25
// (including loss of data, profits, goodwill, or any type of
26
// loss or damage suffered as a result of any action brought
27
// by a third party) even if such damage or loss was
28
// reasonably foreseeable or Xilinx had been advised of the
29
// possibility of the same.
30
//
31
// CRITICAL APPLICATIONS
32
// Xilinx products are not designed or intended to be fail-
33
// safe, or for use in any application requiring fail-safe
34
// performance, such as life-support or safety devices or
35
// systems, Class III medical devices, nuclear facilities,
36
// applications related to the deployment of airbags, or any
37
// other applications that could lead to death, personal
38
// injury, or severe property or environmental damage
39
// (individually and collectively, "Critical
40
// Applications"). Customer assumes the sole risk and
41
// liability of any use of Xilinx products in Critical
42
// Applications, subject only to applicable laws and
43
// regulations governing limitations on product liability.
44
//
45
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46
// PART OF THIS FILE AT ALL TIMES.
47
//
48
//*****************************************************************************
49
// ____ ____
50
// / /\/ /
51
// /___/ \ / Vendor : Xilinx
52
// \ \ \/ Version : %version
53
// \ \ Application : MIG
54
// / / Filename : col_mach.v
55
// /___/ /\ Date Last Modified : $date$
56
// \ \ / \ Date Created : Tue Jun 30 2009
57
// \___\/\___\
58
//
59
//Device : 7-Series
60
//Design Name : DDR3 SDRAM
61
//Purpose :
62
//Reference :
63
//Revision History :
64
//*****************************************************************************
65
66
// The column machine manages the dq bus. Since there is a single DQ
67
// bus, and the column part of the DRAM is tightly coupled to this DQ
68
// bus, conceptually, the DQ bus and all of the column hardware in
69
// a multi rank DRAM array are managed as a single unit.
70
//
71
//
72
// The column machine does not "enforce" the column timing directly.
73
// It generates information and sends it to the bank machines. If the
74
// bank machines incorrectly make a request, the column machine will
75
// simply overwrite the existing request with the new request even
76
// if this would result in a timing or protocol violation.
77
//
78
// The column machine
79
// hosts the block that controls read and write data transfer
80
// to and from the dq bus.
81
//
82
// And if configured, there is provision for tracking the address
83
// of a command as it moves through the column pipeline. This
84
// address will be logged for detected ECC errors.
85
86
`timescale
1
ps /
1
ps
87
88
module
mig_7series_v1_9_col_mach
#
89
(
90
parameter
TCQ
=
100
,
91
parameter
BANK_WIDTH
=
3
,
92
parameter
BURST_MODE
=
"8"
,
93
parameter
COL_WIDTH
=
12
,
94
parameter
CS_WIDTH
=
4
,
95
parameter
DATA_BUF_ADDR_WIDTH
=
8
,
96
parameter
DATA_BUF_OFFSET_WIDTH
=
1
,
97
parameter
DELAY_WR_DATA_CNTRL
=
0
,
98
parameter
DQS_WIDTH
=
8
,
99
parameter
DRAM_TYPE
=
"DDR3"
,
100
parameter
EARLY_WR_DATA_ADDR
=
"OFF"
,
101
parameter
ECC
=
"OFF"
,
102
parameter
MC_ERR_ADDR_WIDTH
=
31
,
103
parameter
nCK_PER_CLK
=
2
,
104
parameter
nPHY_WRLAT
=
0
,
105
parameter
RANK_WIDTH
=
2
,
106
parameter
ROW_WIDTH
=
16
107
)
108
(
/*AUTOARG**/
109
// Outputs
110
dq_busy_data
,
wr_data_offset
,
mc_wrdata_en
,
wr_data_en
,
111
wr_data_addr
,
rd_rmw
,
ecc_err_addr
,
ecc_status_valid
,
wr_ecc_buf
,
rd_data_end
,
112
rd_data_addr
,
rd_data_offset
,
rd_data_en
,
col_read_fifo_empty
,
113
// Inputs
114
clk
,
rst
,
sent_col
,
col_size
,
col_wr_data_buf_addr
,
115
phy_rddata_valid
,
col_periodic_rd
,
col_data_buf_addr
,
col_rmw
,
116
col_rd_wr
,
col_ra
,
col_ba
,
col_row
,
col_a
117
);
118
119
input
clk
;
120
input
rst
;
121
122
input
sent_col
;
123
input
col_rd_wr
;
124
125
output
reg
dq_busy_data
=
1'b0
;
126
127
// The following generates a column command disable based mostly on the type
128
// of DRAM and the fabric to DRAM CK ratio.
129
generate
130
if
((
nCK_PER_CLK
==
1
) && ((
BURST_MODE
==
"8"
) || (
DRAM_TYPE
==
"DDR3"
)))
131
begin
:
three_bumps
132
reg
[
1
:
0
]
granted_col_d_r
;
133
wire
[
1
:
0
]
granted_col_d_ns
= {
sent_col
,
granted_col_d_r
[
1
]};
134
always
@(
posedge
clk
)
granted_col_d_r
<= #TCQ
granted_col_d_ns
;
135
always
@(
/*AS**/
granted_col_d_r
or
sent_col
)
136
dq_busy_data
=
sent_col
|| |
granted_col_d_r
;
137
end
138
if
(((
nCK_PER_CLK
==
2
) && ((
BURST_MODE
==
"8"
) || (
DRAM_TYPE
==
"DDR3"
)))
139
|| ((
nCK_PER_CLK
==
1
) && ((
BURST_MODE
==
"4"
) || (
DRAM_TYPE
==
"DDR2"
))))
140
begin
:
one_bump
141
always
@(
/*AS**/
sent_col
)
dq_busy_data
=
sent_col
;
142
end
143
endgenerate
144
145
// This generates a data offset based on fabric clock to DRAM CK ratio and
146
// the size bit. Note that this is different that the dq_busy_data signal
147
// generated above.
148
reg
[
1
:
0
]
offset_r
=
2'b0
;
149
reg
[
1
:
0
]
offset_ns
=
2'b0
;
150
151
input
col_size
;
152
wire
data_end
;
153
generate
154
155
if
(
nCK_PER_CLK
==
4
)
begin
:
data_valid_4_1
156
157
// For 4:1 mode all data is transfered in a single beat so the default
158
// values of 0 for offset_r/offset_ns suffice - just tie off data_end
159
assign
data_end
=
1'b1
;
160
161
end
162
163
else
begin
164
165
if
(
DATA_BUF_OFFSET_WIDTH
==
2
)
begin
:
data_valid_1_1
166
167
always
@(
col_size
or
offset_r
or
rst
or
sent_col
)
begin
168
if
(
rst
)
offset_ns
=
2'b0
;
169
else
begin
170
offset_ns
=
offset_r
;
171
if
(
sent_col
)
offset_ns
=
2'b1
;
172
else
if
(|
offset_r
&& (
offset_r
!= {
col_size
,
1'b1
}))
173
offset_ns
=
offset_r
+
2'b1
;
174
else
offset_ns
=
2'b0
;
175
end
176
177
end
178
179
always
@(
posedge
clk
)
offset_r
<= #TCQ
offset_ns
;
180
assign
data_end
=
col_size
? (
offset_r
==
2'b11
) :
offset_r
[
0
];
181
182
end
183
184
else
begin
:
data_valid_2_1
185
186
always
@(
col_size
or
rst
or
sent_col
)
187
offset_ns
[
0
] =
rst
?
1'b0
:
sent_col
&&
col_size
;
188
always
@(
posedge
clk
)
offset_r
[
0
] <= #TCQ
offset_ns
[
0
];
189
assign
data_end
=
col_size
?
offset_r
[
0
] :
1'b1
;
190
191
end
192
193
end
194
195
endgenerate
196
197
reg
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
offset_r1
= {
DATA_BUF_OFFSET_WIDTH
{
1'b0
}};
198
reg
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
offset_r2
= {
DATA_BUF_OFFSET_WIDTH
{
1'b0
}};
199
reg
col_rd_wr_r1
;
200
reg
col_rd_wr_r2
;
201
generate
202
if
((
nPHY_WRLAT
>=
1
) || (
DELAY_WR_DATA_CNTRL
==
1
))
begin
:
offset_pipe_0
203
always
@(
posedge
clk
)
offset_r1
<=
204
#TCQ
offset_r
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
];
205
always
@(
posedge
clk
)
col_rd_wr_r1
<= #TCQ
col_rd_wr
;
206
end
207
if
(
nPHY_WRLAT
==
2
)
begin
:
offset_pipe_1
208
always
@(
posedge
clk
)
offset_r2
<=
209
#TCQ
offset_r1
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
];
210
always
@(
posedge
clk
)
col_rd_wr_r2
<= #TCQ
col_rd_wr_r1
;
211
end
212
endgenerate
213
214
output
wire
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
wr_data_offset
;
215
assign
wr_data_offset
= (
DELAY_WR_DATA_CNTRL
==
1
)
216
?
offset_r1
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
217
: (
EARLY_WR_DATA_ADDR
==
"OFF"
)
218
?
offset_r
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
219
:
offset_ns
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
];
220
221
reg
sent_col_r1
;
222
reg
sent_col_r2
;
223
always
@(
posedge
clk
)
sent_col_r1
<= #TCQ
sent_col
;
224
always
@(
posedge
clk
)
sent_col_r2
<= #TCQ
sent_col_r1
;
225
226
wire
wrdata_en
= (
nPHY_WRLAT
==
0
) ?
227
(
sent_col
|| |
offset_r
) & ~
col_rd_wr
:
228
(
nPHY_WRLAT
==
1
) ?
229
(
sent_col_r1
|| |
offset_r1
) & ~
col_rd_wr_r1
:
230
//(nPHY_WRLAT >= 2) ?
231
(
sent_col_r2
|| |
offset_r2
) & ~
col_rd_wr_r2
;
232
233
output
wire
mc_wrdata_en
;
234
assign
mc_wrdata_en
=
wrdata_en
;
235
236
output
wire
wr_data_en
;
237
assign
wr_data_en
= (
DELAY_WR_DATA_CNTRL
==
1
)
238
? ((
sent_col_r1
|| |
offset_r1
) && ~
col_rd_wr_r1
)
239
: ((
sent_col
|| |
offset_r
) && ~
col_rd_wr
);
240
241
242
input
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
col_wr_data_buf_addr
;
243
output
wire
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
wr_data_addr
;
244
generate
245
if
(
DELAY_WR_DATA_CNTRL
==
1
)
begin
:
delay_wr_data_cntrl_eq_1
246
reg
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
col_wr_data_buf_addr_r
;
247
always
@(
posedge
clk
)
col_wr_data_buf_addr_r
<=
248
#TCQ
col_wr_data_buf_addr
;
249
assign
wr_data_addr
=
col_wr_data_buf_addr_r
;
250
end
251
else
begin
:
delay_wr_data_cntrl_ne_1
252
assign
wr_data_addr
=
col_wr_data_buf_addr
;
253
end
254
endgenerate
255
256
// CAS-RD to mc_rddata_en
257
258
wire
read_data_valid
= (
sent_col
|| |
offset_r
) &&
col_rd_wr
;
259
260
function
integer
clogb2
(
input
integer
size
);
// ceiling logb2
261
begin
262
size
=
size
-
1
;
263
for
(
clogb2
=
1
;
size
>
1
;
clogb2
=
clogb2
+
1
)
264
size
=
size
>>
1
;
265
end
266
endfunction
// clogb2
267
268
// Implement FIFO that records reads as they are sent to the DRAM.
269
// When phy_rddata_valid is returned some unknown time later, the
270
// FIFO output is used to control how the data is interpreted.
271
272
input
phy_rddata_valid
;
273
output
wire
rd_rmw
;
274
output
reg
[
MC_ERR_ADDR_WIDTH
-
1
:
0
]
ecc_err_addr
;
275
output
reg
ecc_status_valid
;
276
output
reg
wr_ecc_buf
;
277
output
reg
rd_data_end
;
278
output
reg
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
rd_data_addr
;
279
output
reg
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
rd_data_offset
;
280
(*
keep
=
"true"
,
max_fanout
=
10
*)
output
reg
rd_data_en
/* synthesis syn_maxfan = 10 **/
;
281
output
col_read_fifo_empty
;
282
283
input
col_periodic_rd
;
284
input
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
col_data_buf_addr
;
285
input
col_rmw
;
286
input
[
RANK_WIDTH
-
1
:
0
]
col_ra
;
287
input
[
BANK_WIDTH
-
1
:
0
]
col_ba
;
288
input
[
ROW_WIDTH
-
1
:
0
]
col_row
;
289
input
[
ROW_WIDTH
-
1
:
0
]
col_a
;
290
291
// Real column address (skip A10/AP and A12/BC#). The maximum width is 12;
292
// the width will be tailored for the target DRAM downstream.
293
wire
[
11
:
0
]
col_a_full
;
294
295
// Minimum row width is 12; take remaining 11 bits after omitting A10/AP
296
assign
col_a_full
[
10
:
0
] = {
col_a
[
11
],
col_a
[
9
:
0
]};
297
298
// Get the 12th bit when row address width accommodates it; omit A12/BC#
299
generate
300
if
(
ROW_WIDTH
>=
14
)
begin
:
COL_A_FULL_11_1
301
assign
col_a_full
[
11
] =
col_a
[
13
];
302
end
else
begin
:
COL_A_FULL_11_0
303
assign
col_a_full
[
11
] =
0
;
304
end
305
endgenerate
306
307
// Extract only the width of the target DRAM
308
wire
[
COL_WIDTH
-
1
:
0
]
col_a_extracted
=
col_a_full
[
COL_WIDTH
-
1
:
0
];
309
310
localparam
MC_ERR_LINE_WIDTH
=
MC_ERR_ADDR_WIDTH
-
DATA_BUF_OFFSET_WIDTH
;
311
localparam
FIFO_WIDTH
=
1
/*data_end**/
+
312
1
/*periodic_rd**/
+
313
DATA_BUF_ADDR_WIDTH
+
314
DATA_BUF_OFFSET_WIDTH
+
315
((
ECC
==
"OFF"
) ?
0
:
1
+
MC_ERR_LINE_WIDTH
);
316
localparam
FULL_RAM_CNT
= (
FIFO_WIDTH
/
6
);
317
localparam
REMAINDER
=
FIFO_WIDTH
%
6
;
318
localparam
RAM_CNT
=
FULL_RAM_CNT
+ ((
REMAINDER
==
0
) ?
0
:
1
);
319
localparam
RAM_WIDTH
= (
RAM_CNT
*
6
);
320
321
generate
322
begin
:
read_fifo
323
324
wire
[
MC_ERR_LINE_WIDTH
:
0
]
ecc_line
;
325
if
(
CS_WIDTH
==
1
)
326
assign
ecc_line
= {
col_rmw
,
col_ba
,
col_row
,
col_a_extracted
};
327
else
328
assign
ecc_line
= {
col_rmw
,
329
col_ra
,
330
col_ba
,
331
col_row
,
332
col_a_extracted
};
333
334
wire
[
FIFO_WIDTH
-
1
:
0
]
real_fifo_data
;
335
if
(
ECC
==
"OFF"
)
336
assign
real_fifo_data
= {
data_end
,
337
col_periodic_rd
,
338
col_data_buf_addr
,
339
offset_r
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]};
340
else
341
assign
real_fifo_data
= {
data_end
,
342
col_periodic_rd
,
343
col_data_buf_addr
,
344
offset_r
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
],
345
ecc_line
};
346
347
wire
[
RAM_WIDTH
-
1
:
0
]
fifo_in_data
;
348
if
(
REMAINDER
==
0
)
349
assign
fifo_in_data
=
real_fifo_data
;
350
else
351
assign
fifo_in_data
= {{
6
-
REMAINDER
{
1'b0
}},
real_fifo_data
};
352
353
wire
[
RAM_WIDTH
-
1
:
0
]
fifo_out_data_ns
;
354
355
reg
[
4
:
0
]
head_r
;
356
wire
[
4
:
0
]
head_ns
=
rst
?
5'b0
:
read_data_valid
357
? (
head_r
+
5'b1
)
358
:
head_r
;
359
always
@(
posedge
clk
)
head_r
<= #TCQ
head_ns
;
360
361
362
reg
[
4
:
0
]
tail_r
;
363
wire
[
4
:
0
]
tail_ns
=
rst
?
5'b0
:
phy_rddata_valid
364
? (
tail_r
+
5'b1
)
365
:
tail_r
;
366
always
@(
posedge
clk
)
tail_r
<= #TCQ
tail_ns
;
367
368
assign
col_read_fifo_empty
=
head_r
==
tail_r
?
1'b1
:
1'b0
;
369
370
genvar
i
;
371
for
(
i
=
0
;
i
<
RAM_CNT
;
i
=
i
+
1
)
begin
:
fifo_ram
372
RAM32M
373
#(.
INIT_A
(
64'h0000000000000000
),
374
.
INIT_B
(
64'h0000000000000000
),
375
.
INIT_C
(
64'h0000000000000000
),
376
.
INIT_D
(
64'h0000000000000000
)
377
)
RAM32M0
(
378
.
DOA
(
fifo_out_data_ns
[((
i
*
6
)+
4
)+:
2
]),
379
.
DOB
(
fifo_out_data_ns
[((
i
*
6
)+
2
)+:
2
]),
380
.
DOC
(
fifo_out_data_ns
[((
i
*
6
)+
0
)+:
2
]),
381
.
DOD
(),
382
.
DIA
(
fifo_in_data
[((
i
*
6
)+
4
)+:
2
]),
383
.
DIB
(
fifo_in_data
[((
i
*
6
)+
2
)+:
2
]),
384
.
DIC
(
fifo_in_data
[((
i
*
6
)+
0
)+:
2
]),
385
.
DID
(
2'b0
),
386
.
ADDRA
(
tail_ns
),
387
.
ADDRB
(
tail_ns
),
388
.
ADDRC
(
tail_ns
),
389
.
ADDRD
(
head_r
),
390
.
WE
(
1'b1
),
391
.
WCLK
(
clk
)
392
);
393
end
// block: fifo_ram
394
395
reg
[
RAM_WIDTH
-
1
:
0
]
fifo_out_data_r
;
396
always
@(
posedge
clk
)
fifo_out_data_r
<= #TCQ
fifo_out_data_ns
;
397
398
// When ECC is ON, most of the FIFO output is delayed
399
// by one state.
400
if
(
ECC
==
"OFF"
)
begin
401
reg
periodic_rd
;
402
always
@(
/*AS**/
phy_rddata_valid
or
fifo_out_data_r
)
begin
403
{
rd_data_end
,
404
periodic_rd
,
405
rd_data_addr
,
406
rd_data_offset
} =
fifo_out_data_r
[
FIFO_WIDTH
-
1
:
0
];
407
ecc_err_addr
= {
MC_ERR_ADDR_WIDTH
{
1'b0
}};
408
rd_data_en
=
phy_rddata_valid
&& ~
periodic_rd
;
409
ecc_status_valid
=
1'b0
;
410
wr_ecc_buf
=
1'b0
;
411
end
412
assign
rd_rmw
=
1'b0
;
413
end
414
else
begin
415
wire
rd_data_end_ns
;
416
wire
periodic_rd
;
417
wire
[
DATA_BUF_ADDR_WIDTH
-
1
:
0
]
rd_data_addr_ns
;
418
wire
[
DATA_BUF_OFFSET_WIDTH
-
1
:
0
]
rd_data_offset_ns
;
419
wire
[
MC_ERR_ADDR_WIDTH
-
1
:
0
]
ecc_err_addr_ns
;
420
assign
{
rd_data_end_ns
,
421
periodic_rd
,
422
rd_data_addr_ns
,
423
rd_data_offset_ns
,
424
rd_rmw
,
425
ecc_err_addr_ns
[
DATA_BUF_OFFSET_WIDTH
+:
MC_ERR_LINE_WIDTH
]} =
426
{
fifo_out_data_r
[
FIFO_WIDTH
-
1
:
0
]};
427
assign
ecc_err_addr_ns
[
0
+:
DATA_BUF_OFFSET_WIDTH
] =
rd_data_offset_ns
;
428
always
@(
posedge
clk
)
rd_data_end
<= #TCQ
rd_data_end_ns
;
429
always
@(
posedge
clk
)
rd_data_addr
<= #TCQ
rd_data_addr_ns
;
430
always
@(
posedge
clk
)
rd_data_offset
<= #TCQ
rd_data_offset_ns
;
431
always
@(
posedge
clk
)
ecc_err_addr
<= #TCQ
ecc_err_addr_ns
;
432
wire
rd_data_en_ns
=
phy_rddata_valid
&& ~(
periodic_rd
||
rd_rmw
);
433
always
@(
posedge
clk
)
rd_data_en
<=
rd_data_en_ns
;
434
wire
ecc_status_valid_ns
=
phy_rddata_valid
&& ~
periodic_rd
;
435
always
@(
posedge
clk
)
ecc_status_valid
<= #TCQ
ecc_status_valid_ns
;
436
wire
wr_ecc_buf_ns
=
phy_rddata_valid
&& ~
periodic_rd
&&
rd_rmw
;
437
always
@(
posedge
clk
)
wr_ecc_buf
<= #TCQ
wr_ecc_buf_ns
;
438
end
439
end
440
endgenerate
441
442
endmodule
Generated on Sun Mar 6 2016 12:24:19 for AMC13 by
1.8.1