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
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 Wed Apr 18 2018 10:55:27 for AMC13 by
1.8.1