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

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [fpga-2.04b/] [ipcore_dir/] [mem0/] [user_design/] [sim/] [read_data_path.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
//*****************************************************************************
2
// (c) Copyright 2008-2009 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
//  /   /\/   /
52
// /___/  \  /    Vendor: Xilinx
53
// \   \   \/     Version: %version
54
//  \   \         Application: MIG
55
//  /   /         Filename: read_data_path.v
56
// /___/   /\     Date Last Modified: 
57
// \   \  /  \    Date Created: 
58
//  \___\/\___\
59
//
60
//Device: Spartan6
61
//Design Name: DDR/DDR2/DDR3/LPDDR 
62
//Purpose: This is top level of read path and also consist of comparison logic
63
//         for read data. 
64
//Reference:
65
//Revision History:
66
//*****************************************************************************
67
 
68
`timescale 1ps/1ps
69
 
70
module read_data_path #(
71
   parameter TCQ           = 100,
72
 
73
   parameter FAMILY = "VIRTEX6",
74
   parameter MEM_BURST_LEN = 8,
75
   parameter ADDR_WIDTH = 32,
76
   parameter CMP_DATA_PIPE_STAGES = 3,
77
   parameter DWIDTH = 32,
78
   parameter DATA_PATTERN = "DGEN_ALL", //"DGEN__HAMMER", "DGEN_WALING1","DGEN_WALING0","DGEN_ADDR","DGEN_NEIGHBOR","DGEN_PRBS","DGEN_ALL"  
79
   parameter NUM_DQ_PINS   = 8,
80
   parameter DQ_ERROR_WIDTH = 1,
81
   parameter SEL_VICTIM_LINE = 3,  // VICTIM LINE is one of the DQ pins is selected to be different than hammer pattern
82
 
83
   parameter MEM_COL_WIDTH = 10
84
 
85
    )
86
    (
87
 
88
 
89
   input                  clk_i,
90
   input [9:0]                 rst_i,
91
   input                  manual_clear_error,
92
   output                 cmd_rdy_o,
93
   input                  cmd_valid_i,
94
   input [31:0]           prbs_fseed_i,
95
 
96
   input [3:0]            data_mode_i,
97
   input [2:0]           cmd_sent,
98
   input [5:0]           bl_sent  ,
99
   input                 cmd_en_i ,
100
//   input [31:0]           m_addr_i, 
101
   input [DWIDTH-1:0]     fixed_data_i,
102
   input [31:0]           addr_i,
103
   input [5:0]            bl_i,
104
 
105
 
106
   output                 data_rdy_o,
107
   input                  data_valid_i,
108
   input [DWIDTH-1:0]     data_i,
109
   output                 last_word_rd_o,
110
   output                 data_error_o,                  //data_error on user data bus side
111
   output [DWIDTH-1:0]    cmp_data_o,
112
   output [DWIDTH-1:0]    rd_mdata_o ,
113
   output                 cmp_data_valid,
114
   output [31:0]          cmp_addr_o,
115
   output [5 :0]          cmp_bl_o,
116
   output                 force_wrcmd_gen_o,
117
   output [6:0]           rd_buff_avail_o,
118
   output [DQ_ERROR_WIDTH - 1:0] dq_error_bytelane_cmp,   // V6: real time compare error byte lane
119
   output  [DQ_ERROR_WIDTH - 1:0] cumlative_dq_lane_error_r  // V6: latched error byte lane that occure on
120
                                                       //     first error
121
 
122
   );
123
 
124
   wire                   gen_rdy;
125
   wire                   gen_valid;
126
   wire [31:0]  gen_addr;
127
   wire [5:0]    gen_bl;
128
 
129
   wire                   cmp_rdy;
130
   wire                   cmp_valid;
131
   wire [31:0]  cmp_addr;
132
   wire [5:0]    cmp_bl;
133
 
134
   reg                    data_error;
135
   wire [DWIDTH-1:0]      cmp_data;
136
   reg  [DWIDTH-1:0]      cmp_data_r;
137
   reg  [DWIDTH-1:0]      cmp_data_r2;
138
   reg  [DWIDTH-1:0]      cmp_data_r3;
139
   reg  [DWIDTH-1:0]      cmp_data_r4;
140
   reg                    last_word_rd;
141
   reg [5:0]              bl_counter;
142
   wire                   cmd_rdy;
143
   wire                   user_bl_cnt_is_1;
144
   wire                   data_rdy;
145
   reg [DWIDTH:0] delayed_data;
146
   wire                  rd_mdata_en;
147
   reg [DWIDTH-1:0]      rd_data_r;
148
   reg [DWIDTH-1:0]      rd_data_r2;
149
   reg [DWIDTH-1:0]      rd_data_r3;
150
   reg [DWIDTH-1:0]      rd_data_r4;
151
   reg                   force_wrcmd_gen;
152
   reg                   wait_bl_end;
153
   reg                   wait_bl_end_r1;
154
reg l_data_error ;
155
reg u_data_error;
156
reg v6_data_cmp_valid;
157
wire [DWIDTH -1 :0] rd_v6_mdata;
158
reg [DWIDTH -1 :0] rd_v6_mdata_r1;
159
reg [DWIDTH -1 :0] rd_v6_mdata_r2;
160
reg [DWIDTH -1 :0] rd_v6_mdata_r3;
161
reg [DWIDTH -1 :0] rd_v6_mdata_r4;
162
reg [DWIDTH -1 :0] cmpdata_r;
163
wire [DWIDTH -1 :0] rd_mdata;
164
wire                rd_mdata_fifo_empty;
165
 reg cmp_data_en;
166
 
167
 
168
wire [ DQ_ERROR_WIDTH-1:0] dq_lane_error;
169
reg [ DQ_ERROR_WIDTH-1:0] dq_lane_error_r1;
170
reg [ DQ_ERROR_WIDTH-1:0] dq_lane_error_r2;
171
wire [ DQ_ERROR_WIDTH-1:0] cum_dq_lane_error_mask;
172
wire [ DQ_ERROR_WIDTH-1:0] cumlative_dq_lane_error_c;
173
reg [ DQ_ERROR_WIDTH-1:0] cumlative_dq_lane_error_reg;
174
 
175
reg data_valid_r;
176
 
177
 
178
      always @ (posedge clk_i) begin
179
             wait_bl_end_r1 <= #TCQ wait_bl_end;
180
             rd_data_r <= #TCQ data_i;
181
             rd_data_r2 <= #TCQ rd_data_r;
182
             rd_data_r3 <= #TCQ rd_data_r2;
183
             rd_data_r4 <= #TCQ rd_data_r3;
184
      end
185
 
186
   assign force_wrcmd_gen_o = force_wrcmd_gen;
187
  reg [7:0]         force_wrcmd_timeout_cnts ;
188
 
189
   always @ (posedge clk_i) begin
190
    if (rst_i[0])
191
         force_wrcmd_gen <= #TCQ 1'b0;
192
    else if ((wait_bl_end == 1'b0 &&  wait_bl_end_r1 == 1'b1) || force_wrcmd_timeout_cnts == 8'b11111111)
193
         force_wrcmd_gen <= #TCQ 1'b0;
194
 
195
    else if ((cmd_valid_i && bl_i > 16) || wait_bl_end )
196
         force_wrcmd_gen <= #TCQ 1'b1;
197
    end
198
 
199
 
200
   always @ (posedge clk_i) begin
201
    if (rst_i[0])
202
        force_wrcmd_timeout_cnts <= #TCQ 'b0;
203
    else if (wait_bl_end == 1'b0 &&  wait_bl_end_r1 == 1'b1)
204
        force_wrcmd_timeout_cnts <= #TCQ 'b0;
205
 
206
    else if (force_wrcmd_gen)
207
        force_wrcmd_timeout_cnts <= #TCQ force_wrcmd_timeout_cnts + 1;
208
   end
209
 
210
   always @ (posedge clk_i)
211
    if (rst_i[0])
212
         wait_bl_end <= #TCQ 1'b0;
213
    else if (force_wrcmd_timeout_cnts == 8'b11111111)
214
         wait_bl_end <= #TCQ 1'b0;
215
 
216
    else if (gen_rdy && gen_valid && gen_bl > 16)
217
         wait_bl_end <= #TCQ 1'b1;
218
    else if (wait_bl_end && user_bl_cnt_is_1)
219
         wait_bl_end <= #TCQ 1'b0;
220
 
221
 
222
   assign cmd_rdy_o = cmd_rdy;
223
   read_posted_fifo #(
224
           .TCQ               (TCQ),
225
           .FAMILY    (FAMILY),
226
           .MEM_BURST_LEN (MEM_BURST_LEN),
227
           .ADDR_WIDTH(32),
228
           .BL_WIDTH(6)
229
           )
230
   read_postedfifo(
231
                    .clk_i              (clk_i),
232
                    .rst_i                (rst_i[0]),
233
                    .cmd_rdy_o          (cmd_rdy      ),
234
                    .cmd_valid_i        (cmd_valid_i    ),
235
                    .data_valid_i         (data_rdy        ),  // input to
236
                    .addr_i             (addr_i         ),
237
                    .bl_i               (bl_i           ),
238
 
239
                    .cmd_sent           (cmd_sent),
240
                    .bl_sent            (bl_sent ),
241
                    .cmd_en_i           (cmd_en_i),
242
 
243
                    .user_bl_cnt_is_1   (user_bl_cnt_is_1),
244
                    .gen_rdy_i          (gen_rdy        ),
245
                    .gen_valid_o        (gen_valid      ),
246
                    .gen_addr_o         (gen_addr       ),
247
                    .gen_bl_o           (gen_bl         ),
248
                    .rd_buff_avail_o      (rd_buff_avail_o),
249
                    .rd_mdata_fifo_empty    (rd_mdata_fifo_empty),
250
                    .rd_mdata_en            (rd_mdata_en)
251
                    );
252
 
253
 
254
 
255
 
256
   rd_data_gen #(
257
              .TCQ               (TCQ),
258
              .FAMILY  (FAMILY),
259
              .MEM_BURST_LEN    (MEM_BURST_LEN),
260
              .NUM_DQ_PINS (NUM_DQ_PINS),
261
              .SEL_VICTIM_LINE   (SEL_VICTIM_LINE),
262
 
263
              .DATA_PATTERN  (DATA_PATTERN),
264
              .DWIDTH(DWIDTH),
265
              .COLUMN_WIDTH     (MEM_COL_WIDTH)
266
 
267
              )
268
   rd_datagen(
269
            .clk_i              (clk_i          ),
270
            .rst_i              (rst_i[4:0]),
271
            .prbs_fseed_i       (prbs_fseed_i),
272
            .data_mode_i        (data_mode_i    ),
273
            .cmd_rdy_o          (gen_rdy        ),
274
            .cmd_valid_i        (gen_valid      ),
275
            .last_word_o        (last_word_rd_o ),
276
 
277
//            .m_addr_i           (m_addr_i       ),
278
            .fixed_data_i         (fixed_data_i),
279
 
280
            .addr_i             (gen_addr       ),
281
            .bl_i               (gen_bl         ),
282
            .user_bl_cnt_is_1_o   (user_bl_cnt_is_1),
283
            .data_rdy_i         (data_valid_i        ),  // input to
284
            .data_valid_o       (cmp_valid      ),
285
            .data_o             (cmp_data       ),
286
            .rd_mdata_en          (rd_mdata_en)
287
            );
288
 
289
 
290
   afifo #
291
   (
292
    .TCQ           (TCQ),
293
    .DSIZE         (DWIDTH),
294
    .FIFO_DEPTH    (32),
295
    .ASIZE         (5),
296
    .SYNC          (1)  // set the SYNC to 1 because rd_clk = wr_clk to reduce latency 
297
 
298
 
299
   )
300
   rd_mdata_fifo
301
   (
302
    .wr_clk        (clk_i),
303
    .rst           (rst_i[0]),
304
    .wr_en         (data_valid_i),
305
    .wr_data       (data_i),
306
    .rd_en         (rd_mdata_en),
307
    .rd_clk        (clk_i),
308
    .rd_data       (rd_v6_mdata),
309
    .full          (),
310
    .empty         (rd_mdata_fifo_empty),
311
    .almost_full   ()
312
   );
313
 
314
always @ (posedge clk_i)
315
begin
316
//    delayed_data <= #TCQ {cmp_valid & data_valid_i,cmp_data};
317
    cmp_data_r <= #TCQ cmp_data;
318
    cmp_data_r2 <= #TCQ cmp_data_r;
319
    cmp_data_r3 <= #TCQ cmp_data_r2;
320
    cmp_data_r4 <= #TCQ cmp_data_r3;
321
end
322
 
323
assign rd_mdata_o = rd_mdata;
324
 
325
assign rd_mdata = (FAMILY == "SPARTAN6") ? rd_data_r3:
326
                  (FAMILY == "VIRTEX6" && MEM_BURST_LEN == 4)? rd_v6_mdata_r2:
327
                  rd_data_r;
328
 
329
assign cmp_data_valid = (FAMILY == "SPARTAN6") ? cmp_data_en :
330
                        (FAMILY == "VIRTEX6" && MEM_BURST_LEN == 4)? v6_data_cmp_valid :data_valid_i;
331
 
332
 
333
 
334
 
335
assign        cmp_data_o  = (FAMILY == "SPARTAN6") ? cmp_data_r3 : cmp_data_r2;
336
assign        cmp_addr_o  = gen_addr;
337
assign        cmp_bl_o    = gen_bl;
338
 
339
 
340
 
341
assign data_rdy_o = data_rdy;
342
assign data_rdy = cmp_valid & data_valid_i;
343
 
344
 always @ (posedge clk_i)
345
    v6_data_cmp_valid <= #TCQ rd_mdata_en;
346
 
347
 
348
 always @ (posedge clk_i)
349
       cmp_data_en <= #TCQ data_rdy;
350
 
351
 generate
352
 if (FAMILY == "SPARTAN6") begin: gen_error_1
353
   always @ (posedge clk_i)
354
     begin
355
       if (cmp_data_en)
356
           l_data_error <= #TCQ (rd_data_r[DWIDTH/2-1:0] !== cmp_data_r[DWIDTH/2-1:0]);
357
        else
358
           l_data_error <= #TCQ 1'b0;
359
 
360
       if (cmp_data_en)
361
           u_data_error <= #TCQ (rd_data_r[DWIDTH-1:DWIDTH/2] !== cmp_data_r[DWIDTH-1:DWIDTH/2]);
362
        else
363
           u_data_error <= #TCQ 1'b0;
364
 
365
       data_error <= #TCQ l_data_error | u_data_error;
366
      //synthesis translate_off
367
      if (data_error)
368
        $display ("ERROR: Expected data=%h and recieved data= %h @ %t" ,cmp_data_r4, rd_data_r4, $time);
369
      //synthesis translate_on
370
 
371
     end
372
 
373
end
374
endgenerate
375
wire [NUM_DQ_PINS/2 - 1:0] error_byte;
376
reg [NUM_DQ_PINS/2 - 1:0] error_byte_r1;
377
 
378
genvar i;
379
 generate
380
 if (FAMILY == "VIRTEX6" && MEM_BURST_LEN == 4) begin: gen_error_2
381
 
382
 
383
    for (i = 0; i < NUM_DQ_PINS/2; i = i + 1) begin: gen_cmp
384
      assign error_byte[i]
385
               = (~rd_mdata_fifo_empty && rd_mdata_en && (rd_v6_mdata[8*(i+1)-1:8*i] !== cmp_data[8*(i+1)-1:8*i]) );
386
 
387
 
388
    end
389
 
390
always @ (posedge clk_i)
391
begin
392
  rd_v6_mdata_r1 <= rd_v6_mdata;
393
  rd_v6_mdata_r2 <= rd_v6_mdata_r1;
394
  rd_v6_mdata_r3 <= rd_v6_mdata_r2;
395
  rd_v6_mdata_r4 <= rd_v6_mdata_r3;
396
end
397
 
398
always @ (posedge clk_i)
399
begin
400
    if (rst_i[1] || manual_clear_error) begin
401
 
402
      error_byte_r1 <= #TCQ 'b0;
403
      data_error <= #TCQ 1'b0;
404
      end
405
    else begin
406
      error_byte_r1 <= #TCQ error_byte;
407
      data_error <= #TCQ | error_byte_r1;
408
 
409
 
410
      //synthesis translate_off
411
      if (data_error)
412
        $display ("ERROR: Expected data=%h and recieved data= %h @ %t" ,cmp_data_r2,rd_v6_mdata_r2,$time);
413
      //synthesis translate_on
414
    end
415
 
416
end
417
 
418
  // remap the app_rd_data error byte locastion to dq bus side.
419
    for ( i = 0; i < DQ_ERROR_WIDTH; i = i+1) begin: gen_dq_error_map
420
        assign dq_lane_error[i] = (error_byte_r1[i] | error_byte_r1[i+DQ_ERROR_WIDTH] |
421
                              error_byte_r1[i+ (NUM_DQ_PINS*2/8)] |
422
                              error_byte_r1[i+ (NUM_DQ_PINS*3/8)]);
423
 
424
        assign cumlative_dq_lane_error_c[i] =  cumlative_dq_lane_error_r[i] | dq_lane_error_r1[i];
425
    end
426
 
427
 
428
always @ (posedge clk_i)
429
begin
430
    if (rst_i[1] || manual_clear_error) begin
431
 
432
      dq_lane_error_r1 <= #TCQ 'b0;
433
      dq_lane_error_r2 <= #TCQ 'b0;
434
      data_valid_r <= #TCQ 1'b0;
435
      cumlative_dq_lane_error_reg <= #TCQ 'b0;
436
      end
437
    else begin
438
      data_valid_r <= #TCQ data_valid_i;
439
 
440
      dq_lane_error_r1 <= #TCQ dq_lane_error;
441
      cumlative_dq_lane_error_reg <= #TCQ cumlative_dq_lane_error_c;
442
    end
443
end
444
end
445
//end
446
endgenerate
447
 
448
 generate
449
 if (FAMILY == "VIRTEX6" && MEM_BURST_LEN == 8) begin: gen_error_3
450
    for (i = 0; i < NUM_DQ_PINS/2; i = i + 1) begin: gen_cmp
451
      assign error_byte[i]
452
               = (data_valid_i && (data_i[8*(i+1)-1:8*i] !== cmp_data[8*(i+1)-1:8*i]) );
453
    end
454
 
455
 
456
 
457
 
458
always @ (posedge clk_i)
459
begin
460
    if (rst_i[1] || manual_clear_error) begin
461
 
462
      error_byte_r1 <= #TCQ 'b0;
463
      data_error <= #TCQ 1'b0;
464
      end
465
    else begin
466
 
467
    error_byte_r1 <= #TCQ error_byte;
468
    data_error <= #TCQ | error_byte_r1;
469
 
470
      //synthesis translate_off
471
    if (data_error)
472
        $display ("ERROR: Expected data=%h and recieved data= %h @ %t" ,cmp_data_r2,rd_data_r2,$time);
473
      //synthesis translate_on
474
 
475
    end
476
end
477
 
478
 
479
    for ( i = 0; i < DQ_ERROR_WIDTH; i = i+1) begin: gen_dq_error_map
480
        assign dq_lane_error[i] = (error_byte_r1[i] | error_byte_r1[i+DQ_ERROR_WIDTH] |
481
                              error_byte_r1[i+ (NUM_DQ_PINS*2/8)] |
482
                              error_byte_r1[i+ (NUM_DQ_PINS*3/8)]);
483
 
484
        assign cumlative_dq_lane_error_c[i] =  cumlative_dq_lane_error_r[i] | dq_lane_error_r1[i];
485
    end
486
 
487
 
488
always @ (posedge clk_i)
489
begin
490
    if (rst_i[1] || manual_clear_error) begin
491
 
492
      dq_lane_error_r1 <= #TCQ 'b0;
493
      dq_lane_error_r2 <= #TCQ 'b0;
494
      data_valid_r <= #TCQ 1'b0;
495
      cumlative_dq_lane_error_reg <= #TCQ 'b0;
496
      end
497
    else begin
498
      data_valid_r <= #TCQ data_valid_i;
499
      dq_lane_error_r1 <= #TCQ dq_lane_error;
500
      cumlative_dq_lane_error_reg <= #TCQ cumlative_dq_lane_error_c;
501
    end
502
end
503
end
504
//end
505
endgenerate
506
 
507
assign cumlative_dq_lane_error_r = cumlative_dq_lane_error_reg;
508
assign dq_error_bytelane_cmp = dq_lane_error_r1;
509
assign data_error_o = data_error;
510
 
511
 
512
endmodule
513
 

powered by: WebSVN 2.1.0

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