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/] [cmd_gen.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
// /___/  \  /    Vendor: Xilinx
52
// \   \   \/     Version: %version
53
//  \   \         Application: MIG
54
//  /   /         Filename: cmd_gen.v
55
// /___/   /\     Date Last Modified: $Date: 2011/05/27 15:50:26 $
56
// \   \  /  \    Date Created: Oct 21 2008
57
//  \___\/\___\
58
//
59
//Device: Spartan6
60
//Design Name: DDR/DDR2/DDR3/LPDDR
61
//Purpose:  This module genreates different type of commands, address,
62
//          burst_length to mcb_flow_control module.
63
//Reference:
64
//Revision History:
65
//                  Nov14 2008. Added constraints  for generating PRBS_BL when
66
//                         generated address is too close to end of address space.
67
//                         The BL will be force to 1 to avoid across other port's space.
68
//                  April 2 2009 Fixed Sequential Address Circuit to avoide generate any address
69
//                               beyond the allowed address range.                
70
//                  Oct 22 2009  Fixed BRAM interface.
71
//                               Fixed run_traffic stop and go problem.
72
//                               Merged V6 and SP6 specific requirements.
73
//                                                               Modified syntax for VHDL Formality comparison.
74
//*****************************************************************************
75
 
76
`timescale 1ps/1ps
77
 
78
`define RD              3'b001;
79
`define RDP             3'b011;
80
`define WR              3'b000;
81
`define WRP             3'b010;
82
`define REFRESH         3'b100;
83
 
84
 
85
module cmd_gen #
86
  (
87
   parameter TCQ           = 100,
88
 
89
   parameter FAMILY = "SPARTAN6",
90
   parameter MEM_BURST_LEN = 8,
91
   parameter PORT_MODE = "BI_MODE",
92
   parameter NUM_DQ_PINS   = 8,
93
   parameter DATA_PATTERN  = "DGEN_ALL", // "DGEN__HAMMER", "DGEN_WALING1","DGEN_WALING0","DGEN_ADDR","DGEN_NEIGHBOR","DGEN_PRBS","DGEN_ALL"
94
   parameter CMD_PATTERN  = "CGEN_ALL",    // "CGEN_RPBS","CGEN_FIXED",  "CGEN_BRAM", "CGEN_SEQUENTIAL", "CGEN_ALL",
95
   parameter ADDR_WIDTH    = 30,
96
   parameter DWIDTH        = 32,
97
   parameter PIPE_STAGES   = 0,
98
   parameter MEM_COL_WIDTH = 10,       // memory column width
99
   parameter PRBS_EADDR_MASK_POS = 32'hFFFFD000,
100
   parameter PRBS_SADDR_MASK_POS =  32'h00002000,
101
   parameter PRBS_EADDR = 32'h00002000,
102
   parameter PRBS_SADDR  = 32'h00002000
103
   )
104
  (
105
   input           clk_i,
106
   input [9:0]          rst_i,
107
   input           run_traffic_i,
108
  // runtime parameter
109
  input [6:0]               rd_buff_avail_i,
110
  input                     force_wrcmd_gen_i,
111
   input [31:0]             start_addr_i,   // define the start of address
112
   input [31:0]             end_addr_i,
113
   input [31:0]             cmd_seed_i,    // same seed apply to all addr_prbs_gen, bl_prbs_gen, instr_prbs_gen
114
   input [31:0]             data_seed_i,
115
   input                    load_seed_i,   //
116
   // upper layer inputs to determine the command bus and data pattern
117
   // internal traffic generator initialize the memory with
118
   input [2:0]              addr_mode_i,  // "00" = bram; takes the address from bram output
119
                                          // "01" = fixed address from the fixed_addr input
120
                                          // "10" = psuedo ramdom pattern; generated from internal 64 bit LFSR
121
                                          // "11" = sequential
122
 
123
   input [3:0]              data_mode_i,  // 4'b0010:address as data
124
                                          // 4'b0011:DGEN_HAMMER
125
                                          // 4'b0100:DGEN_NEIGHBOUR
126
                                          // 4'b0101:DGEN_WALKING1
127
                                          // 4'b0110:DGEN_WALKING0
128
                                          // 4'b0111:PRBS_DATA
129
 
130
  // for each instr_mode, traffic gen fill up with a predetermined pattern before starting the instr_pattern that defined
131
  // in the instr_mode input. The runtime mode will be automatically loaded inside when it is in
132
   input [3:0]              instr_mode_i, // "0000" = bram; takes instruction from bram output
133
                                          // "0001" = fixed instr from fixed instr input
134
                                          // "0010" = R/W
135
                                          // "0011" = RP/WP
136
                                          // "0100" = R/RP/W/WP
137
                                          // "0101" = R/RP/W/WP/REF
138
                                          // "0110" = PRBS
139
 
140
 
141
   input [1:0]              bl_mode_i,  // "00" = bram;   takes the burst length from bram output
142
                                        // "01" = fixed , takes the burst length from the fixed_bl input
143
                                        // "10" = psuedo ramdom pattern; generated from internal 16 bit LFSR
144
 
145
   input                    mode_load_i,
146
 
147
   // fixed pattern inputs interface
148
   input [5:0]              fixed_bl_i,      // range from 1 to 64
149
   input [2:0]              fixed_instr_i,   //RD              3'b001
150
                                            //RDP             3'b011
151
                                            //WR              3'b000
152
                                            //WRP             3'b010
153
                                            //REFRESH         3'b100
154
   input [31:0]             fixed_addr_i, // only upper 30 bits will be used
155
   // BRAM FIFO input
156
   input [31:0]             bram_addr_i,  //
157
   input [2:0]              bram_instr_i,
158
   input [5:0]              bram_bl_i,
159
   input                    bram_valid_i,
160
   output                   bram_rdy_o,
161
 
162
   input                    reading_rd_data_i,
163
   // mcb_flow_control interface
164
   input           rdy_i,
165
 
166
   output  [31:0]  addr_o,     // generated address
167
   output  [2:0]   instr_o,    // generated instruction
168
   output  [5:0]   bl_o,       // generated instruction
169
//   output reg [31:0]  m_addr_o,
170
   output          cmd_o_vld      // valid commands when asserted
171
  );
172
 
173
   localparam PRBS_ADDR_WIDTH = 32;
174
   localparam INSTR_PRBS_WIDTH = 16;
175
   localparam BL_PRBS_WIDTH    = 16;
176
 
177
localparam BRAM_DATAL_MODE       =    4'b0000;
178
localparam FIXED_DATA_MODE       =    4'b0001;
179
localparam ADDR_DATA_MODE        =    4'b0010;
180
localparam HAMMER_DATA_MODE      =    4'b0011;
181
localparam NEIGHBOR_DATA_MODE    =    4'b0100;
182
localparam WALKING1_DATA_MODE    =    4'b0101;
183
localparam WALKING0_DATA_MODE    =    4'b0110;
184
localparam PRBS_DATA_MODE        =    4'b0111;
185
 
186
reg [10:0] INC_COUNTS;
187
reg [2:0]  addr_mode_reg;
188
reg [1:0]  bl_mode_reg;
189
 
190
reg [31:0] addr_counts;
191
reg [31:0] addr_counts_next_r;
192
 
193
wire  [14:0]  prbs_bl;
194
reg [2:0] instr_out;
195
wire [14:0] prbs_instr_a;
196
wire [14:0] prbs_instr_b;
197
 
198
reg  [5:0]   prbs_brlen;
199
 
200
wire [31:0] prbs_addr;
201
wire [31:0] seq_addr;
202
wire [31:0] fixed_addr;
203
reg [31:0] addr_out ;
204
reg [5:0]  bl_out;
205
reg [5:0] bl_out_reg;
206
reg mode_load_d1;
207
reg mode_load_d2;
208
reg mode_load_pulse;
209
wire [41:0] pipe_data_o;
210
wire     cmd_clk_en;
211
 
212
wire     pipe_out_vld;
213
reg [15:0] end_addr_range;
214
 
215
reg force_bl1;
216
reg A0_G_E0;
217
reg A1_G_E1;
218
reg A2_G_E2;
219
reg A3_G_E3;
220
reg AC3_G_E3;
221
reg AC2_G_E2;
222
reg AC1_G_E1;
223
reg bl_out_clk_en;
224
reg [41:0] pipe_data_in;
225
reg instr_vld;
226
reg bl_out_vld;
227
reg pipe_data_in_vld;
228
reg gen_addr_larger ;
229
    reg [6:0] buf_avail_r;
230
    reg [6:0] rd_data_received_counts;
231
    reg [6:0] rd_data_counts_asked;
232
 
233
    reg [15:0] rd_data_received_counts_total;
234
reg instr_vld_dly1;
235
reg first_load_pulse;
236
reg mem_init_done;
237
reg refresh_cmd_en ;
238
reg [9:0] refresh_timer;
239
reg       refresh_prbs;
240
reg       cmd_vld;
241
reg run_traffic_r;
242
reg run_traffic_pulse;
243
always @ (posedge clk_i)
244
begin
245
     run_traffic_r <= #TCQ run_traffic_i;
246
     if (  run_traffic_i &&   ~run_traffic_r )
247
          run_traffic_pulse <= #TCQ 1'b1;
248
     else
249
          run_traffic_pulse <= #TCQ 1'b0;
250
end
251
 
252
 
253
// commands go through pipeline inserters
254
assign addr_o       = pipe_data_o[31:0];
255
assign instr_o      = pipe_data_o[34:32];
256
assign bl_o         = pipe_data_o[40:35];
257
 
258
 
259
assign cmd_o_vld    = pipe_data_o[41] & run_traffic_r;
260
assign pipe_out_vld = pipe_data_o[41] & run_traffic_r;
261
 
262
 
263
assign pipe_data_o = pipe_data_in;
264
 
265
always @(posedge clk_i) begin
266
 
267
     instr_vld        <=  #TCQ  (cmd_clk_en | (mode_load_pulse & first_load_pulse));
268
     bl_out_clk_en    <=  #TCQ  (cmd_clk_en | (mode_load_pulse & first_load_pulse));
269
     bl_out_vld       <=  #TCQ  bl_out_clk_en;
270
     pipe_data_in_vld <=  #TCQ  instr_vld;
271
 end
272
 
273
always @ (posedge clk_i) begin
274
 if (rst_i[0])
275
    first_load_pulse <= #TCQ 1'b1;
276
 else if (mode_load_pulse)
277
    first_load_pulse <= #TCQ 1'b0;
278
 else
279
    first_load_pulse <= #TCQ first_load_pulse;
280
 end
281
 
282
generate
283
if (CMD_PATTERN == "CGEN_BRAM")  begin: cv1
284
 
285
always @(posedge clk_i) begin
286
    cmd_vld          <=  #TCQ (cmd_clk_en );
287
 
288
end
289
end endgenerate
290
 
291
 
292
generate
293
if (CMD_PATTERN != "CGEN_BRAM")  begin: cv2
294
 
295
always @(posedge clk_i) begin
296
    cmd_vld          <=  #TCQ (cmd_clk_en | (mode_load_pulse & first_load_pulse ));
297
 
298
end
299
end endgenerate
300
 
301
 
302
assign cmd_clk_en =  ( rdy_i & pipe_out_vld & run_traffic_i ||  mode_load_pulse && (CMD_PATTERN == "CGEN_BRAM"));
303
 
304
 
305
 
306
integer i;
307
generate
308
if (FAMILY == "SPARTAN6")  begin: pipe_in_s6
309
    always @ (posedge clk_i) begin
310
    if (rst_i[0])
311
       pipe_data_in[31:0] <= #TCQ    start_addr_i;
312
    else if (instr_vld)
313
         if (gen_addr_larger && (addr_mode_reg == 3'b100 || addr_mode_reg == 3'b010))
314
            if (DWIDTH == 32)
315
              pipe_data_in[31:0] <= #TCQ  {end_addr_i[31:8],8'h0};
316
            else if (DWIDTH == 64)
317
              pipe_data_in[31:0] <= #TCQ  {end_addr_i[31:9],9'h0};
318
            else
319
              pipe_data_in[31:0] <= #TCQ  {end_addr_i[31:10],10'h0};
320
 
321
         else begin
322
             if (DWIDTH == 32)
323
              pipe_data_in[31:0] <= #TCQ    {addr_out[31:2],2'b00} ;
324
             else if (DWIDTH == 64)
325
              pipe_data_in[31:0] <= #TCQ    {addr_out[31:3],3'b000} ;
326
             else if (DWIDTH == 128)
327
              pipe_data_in[31:0] <= #TCQ    {addr_out[31:4],4'b0000} ;
328
             end
329
end
330
 
331
end endgenerate
332
 
333
generate
334
if (FAMILY == "VIRTEX6")  begin: pipe_in_v6
335
    always @ (posedge clk_i) begin
336
    if (rst_i[1])
337
       pipe_data_in[31:0] <= #TCQ    start_addr_i;
338
    else if (instr_vld)
339
       // address
340
      if (gen_addr_larger && (addr_mode_reg == 3'b100 || addr_mode_reg == 3'b010)) //(AC3_G_E3 && AC2_G_E2 && AC1_G_E1  )
341
              pipe_data_in[31:0] <= #TCQ  {end_addr_i[31:8],8'h0};
342
      else if ((NUM_DQ_PINS >= 128) && (NUM_DQ_PINS <=  144))
343
      begin
344
         if (MEM_BURST_LEN == 8)
345
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:7], 7'b0000000};
346
         else
347
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:6], 6'b000000};
348
       end
349
 
350
      else if ((NUM_DQ_PINS >= 64) && (NUM_DQ_PINS < 128))
351
            begin
352
 
353
         if (MEM_BURST_LEN == 8)
354
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:6], 6'b000000};
355
         else
356
         pipe_data_in[31:0] <= #TCQ    {addr_out[31:5], 5'b00000};
357
       end
358
 
359
      else if ((NUM_DQ_PINS == 32) || (NUM_DQ_PINS == 40) || (NUM_DQ_PINS == 48) || (NUM_DQ_PINS == 56))
360
            begin
361
 
362
         if (MEM_BURST_LEN == 8)
363
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:5], 5'b00000};
364
         else
365
         pipe_data_in[31:0] <= #TCQ    {addr_out[31:4], 4'b0000};
366
       end
367
 
368
      else if ((NUM_DQ_PINS == 16) || (NUM_DQ_PINS == 24))
369
         if (MEM_BURST_LEN == 8)
370
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:4], 4'b0000};
371
         else
372
         pipe_data_in[31:0] <= #TCQ    {addr_out[31:3], 3'b000};
373
 
374
      else if ((NUM_DQ_PINS == 8) )
375
         if (MEM_BURST_LEN == 8)
376
            pipe_data_in[31:0] <= #TCQ    {addr_out[31:3], 3'b000};
377
         else
378
         pipe_data_in[31:0] <= #TCQ    {addr_out[31:2], 2'b00};
379
 
380
end
381
 
382
end endgenerate
383
 
384
 
385
//generate
386
//if (FAMILY == "VIRTEX6")  begin: pipe_m_addr_o
387
//    always @ (posedge clk_i) begin
388
//    if (rst_i[1])
389
//       m_addr_o[31:0] <= #TCQ    start_addr_i;
390
//    else if (instr_vld)
391
//      if (gen_addr_larger && (addr_mode_reg == 3'b100 || addr_mode_reg == 3'b010)) //(AC3_G_E3 && AC2_G_E2 && AC1_G_E1  )
392
//              m_addr_o[31:0] <= #TCQ  {end_addr_i[31:8],8'h0};
393
//      else if ((NUM_DQ_PINS >= 128 && NUM_DQ_PINS < 256))  
394
//         m_addr_o <= #TCQ  {addr_out[31:6], 6'b00000} ;
395
//              
396
//      else if ((NUM_DQ_PINS >= 64 && NUM_DQ_PINS < 128))  
397
//         m_addr_o <= #TCQ  {addr_out[31:5], 5'b00000} ;
398
//         
399
//      else if ((NUM_DQ_PINS == 32) || (NUM_DQ_PINS == 40) || (NUM_DQ_PINS == 48) || (NUM_DQ_PINS == 56))
400
//         m_addr_o[31:0] <= #TCQ    {addr_out[31:4], 4'b0000};
401
//      else if ((NUM_DQ_PINS == 16) || (NUM_DQ_PINS == 24))
402
//         m_addr_o[31:0] <= #TCQ    {addr_out[31:3], 3'b000};
403
//      else if ((NUM_DQ_PINS == 8) )
404
//         m_addr_o[31:0] <= #TCQ    {addr_out[31:2], 2'b00};
405
//end
406
//
407
//end endgenerate
408
reg force_wrcmd_gen;
409
   always @ (posedge clk_i) begin
410
    if (rst_i[0])
411
         force_wrcmd_gen <= #TCQ  1'b0;
412
    else if (buf_avail_r == 63)
413
         force_wrcmd_gen <= #TCQ  1'b0;
414
    else if (instr_vld_dly1 && pipe_data_in[32]== 1 && pipe_data_in[41:35] > 16)
415
         force_wrcmd_gen <= #TCQ  1'b1;
416
    end
417
 
418
reg [3:0]instr_mode_reg;
419
 always @ (posedge clk_i)
420
 begin
421
      instr_mode_reg <= #TCQ  instr_mode_i;
422
 end
423
reg force_smallvalue;
424
 always @ (posedge clk_i)
425
 begin
426
    if (rst_i[2]) begin
427
       pipe_data_in[40:32] <= #TCQ    'b0;
428
       force_smallvalue <= #TCQ  1'b0;
429
       end
430
    else if (instr_vld) begin
431
      if (instr_mode_reg == 0) begin
432
              pipe_data_in[34:32] <= #TCQ    instr_out;
433
              end
434
      else if (instr_out[2]) begin
435
              pipe_data_in[34:32] <= #TCQ    3'b100;
436
              end
437
        //
438
      else if ( FAMILY == "SPARTAN6" && PORT_MODE == "RD_MODE")
439
      begin
440
            pipe_data_in[34:32] <= #TCQ  {instr_out[2:1],1'b1};
441
              end
442
 
443
      else if ((force_wrcmd_gen || buf_avail_r <=  15) && FAMILY == "SPARTAN6" &&  PORT_MODE != "RD_MODE")
444
      begin
445
            pipe_data_in[34:32] <= #TCQ    {instr_out[2],2'b00};
446
              end
447
      else begin
448
             pipe_data_in[34:32] <= #TCQ    instr_out;
449
              end
450
 
451
   //********* condition the generated bl value except if TG is programmed for BRAM interface'
452
   // if the generated address is close to end address range, the bl_out will be altered to 1.
453
     if (bl_mode_i[1:0] == 2'b00)                                        // if programmed BRAM interface
454
          pipe_data_in[40:35] <=  #TCQ   bl_out;
455
     else if (FAMILY == "VIRTEX6")
456
              pipe_data_in[40:35] <=  #TCQ   bl_out;
457
     else if (force_bl1 && (bl_mode_reg == 2'b10 ) && FAMILY == "SPARTAN6") //PRBS_BL
458
 
459
      pipe_data_in[40:35] <=  #TCQ   6'b000001;
460
     else if ((buf_avail_r[5:0]  >= 6'b111100 && buf_avail_r[6] == 1'b0) && pipe_data_in[32] == 1'b1 && FAMILY == "SPARTAN6")         //read instructon
461
 
462
 
463
       begin
464
        if (bl_mode_reg == 2'b10)
465
            force_smallvalue    <= #TCQ  ~force_smallvalue;
466
 
467
        if ((buf_avail_r[6] && bl_mode_reg == 2'b10))
468
 
469
 
470
             pipe_data_in[40:35] <= #TCQ    {2'b0,bl_out[3:1],1'b1};
471
        else
472
            pipe_data_in[40:35] <=   #TCQ  bl_out;
473
        end
474
   else if (buf_avail_r  < 64 && rd_buff_avail_i >= 0 && instr_out[0] == 1'b1 && (bl_mode_reg == 2'b10 ))
475
         if (FAMILY == "SPARTAN6")
476
         pipe_data_in[40:35] <=  #TCQ   {2'b0,bl_out[3:0] + 1};
477
         else
478
            pipe_data_in[40:35] <=   #TCQ  bl_out;
479
 
480
    end  //else instr_vld
481
 end // always
482
 
483
always @ (posedge clk_i)
484
begin
485
     if (rst_i[2])
486
        pipe_data_in[41] <=  #TCQ   'b0;
487
     else if (cmd_vld)
488
        pipe_data_in[41] <=  #TCQ   instr_vld;//instr_vld;
489
     else if (rdy_i && pipe_out_vld)
490
        pipe_data_in[41] <=  #TCQ   1'b0;
491
 end
492
 
493
 always @ (posedge clk_i)
494
    instr_vld_dly1  <=  #TCQ instr_vld;
495
 
496
always @ (posedge clk_i) begin
497
 if (rst_i[0]) begin
498
    rd_data_counts_asked <= #TCQ  'b0;
499
  end else if (instr_vld_dly1 && pipe_data_in[32]== 1) begin
500
    if (pipe_data_in[40:35] == 0)
501
       rd_data_counts_asked <=  #TCQ rd_data_counts_asked + (64) ;
502
    else
503
       rd_data_counts_asked <=  #TCQ rd_data_counts_asked + (pipe_data_in[40:35]) ;
504
 
505
    end
506
 end
507
 
508
always @ (posedge clk_i) begin
509
 if (rst_i[0]) begin
510
     rd_data_received_counts <= #TCQ  'b0;
511
     rd_data_received_counts_total <= #TCQ  'b0;
512
  end else if(reading_rd_data_i) begin
513
     rd_data_received_counts <= #TCQ  rd_data_received_counts + 1;
514
     rd_data_received_counts_total <= #TCQ  rd_data_received_counts_total + 1;
515
     end
516
 end
517
 
518
 // calculate how many buf still available
519
 always @ (posedge clk_i)
520
     buf_avail_r <= #TCQ  (rd_data_received_counts + 64) - rd_data_counts_asked;
521
 
522
localparam BRAM_ADDR       = 2'b00;
523
localparam FIXED_ADDR      = 2'b01;
524
localparam PRBS_ADDR       = 2'b10;
525
localparam SEQUENTIAL_ADDR = 2'b11;
526
 
527
// registered the mode settings
528
always @ (posedge clk_i) begin
529
   if (rst_i[3])
530
        if (CMD_PATTERN == "CGEN_BRAM")
531
         addr_mode_reg  <= #TCQ    3'b000;
532
        else
533
         addr_mode_reg  <= #TCQ    3'b011;
534
   else if (mode_load_pulse)
535
         addr_mode_reg  <= #TCQ    addr_mode_i;
536
end
537
 
538
always @ (posedge clk_i) begin
539
   if (mode_load_pulse) begin
540
        bl_mode_reg    <= #TCQ    bl_mode_i ;
541
   end
542
   mode_load_d1         <= #TCQ    mode_load_i;
543
   mode_load_d2         <= #TCQ    mode_load_d1;
544
end
545
 
546
always @ (posedge clk_i)
547
     mode_load_pulse <= #TCQ  mode_load_d1 & ~mode_load_d2;
548
 
549
// MUX the addr pattern out depending on the addr_mode setting
550
 
551
// "000" = bram; takes the address from bram output
552
// "001" = fixed address from the fixed_addr input
553
// "010" = psuedo ramdom pattern; generated from internal 64 bit LFSR
554
// "011" = sequential
555
// "100" = mode that used for prbs addr , prbs bl and prbs data
556
//always @(addr_mode_reg,prbs_addr,seq_addr,fixed_addr,bram_addr_i,data_mode_i)
557
always @ (posedge clk_i) begin
558
if (rst_i[3])
559
  addr_out <= #TCQ    start_addr_i;
560
else
561
   case({addr_mode_reg})
562
         3'b000: addr_out <= #TCQ    bram_addr_i;
563
         3'b001: addr_out <= #TCQ    fixed_addr;
564
         3'b010: addr_out <= #TCQ    prbs_addr;
565
         3'b011: addr_out <= #TCQ    {2'b0,seq_addr[29:0]};
566
         3'b100: addr_out <= #TCQ    {2'b00,seq_addr[6:2],seq_addr[23:0]};//{prbs_addr[31:6],6'b000000} ;
567
         3'b101: addr_out <= #TCQ    {prbs_addr[31:20],seq_addr[19:0]} ;
568
 
569
         default : addr_out <= #TCQ    'b0;
570
   endcase
571
end
572
 
573
//  ADDR PRBS GENERATION
574
generate
575
if (CMD_PATTERN == "CGEN_PRBS" || CMD_PATTERN == "CGEN_ALL" ) begin: gen_prbs_addr
576
cmd_prbs_gen #
577
  (
578
    .TCQ               (TCQ),
579
    .FAMILY      (FAMILY),
580
    .ADDR_WIDTH          (32),
581
    .DWIDTH     (DWIDTH),
582
    .PRBS_WIDTH (32),
583
    .SEED_WIDTH (32),
584
    .PRBS_EADDR_MASK_POS          (PRBS_EADDR_MASK_POS ),
585
    .PRBS_SADDR_MASK_POS           (PRBS_SADDR_MASK_POS  ),
586
    .PRBS_EADDR         (PRBS_EADDR),
587
    .PRBS_SADDR          (PRBS_SADDR )
588
   )
589
   addr_prbs_gen
590
  (
591
   .clk_i            (clk_i),
592
   .clk_en           (cmd_clk_en),
593
   .prbs_seed_init   (mode_load_pulse),
594
   .prbs_seed_i      (cmd_seed_i[31:0]),
595
   .prbs_o           (prbs_addr)
596
  );
597
end
598
endgenerate
599
 
600
always @ (posedge clk_i) begin
601
if (addr_out[31:8] >= end_addr_i[31:8])
602
    gen_addr_larger <=     1'b1;
603
else
604
    gen_addr_larger <=     1'b0;
605
end
606
 
607
generate
608
if (FAMILY == "SPARTAN6" ) begin : INC_COUNTS_S
609
always @ (posedge clk_i)
610
if (mem_init_done)
611
    INC_COUNTS <= #TCQ  (DWIDTH/8)*(bl_out_reg);
612
else  begin
613
    if (fixed_bl_i == 0)
614
       INC_COUNTS <= #TCQ  (DWIDTH/8)*(64);
615
    else
616
       INC_COUNTS <= #TCQ  (DWIDTH/8)*(fixed_bl_i);
617
    end
618
end
619
endgenerate
620
//converting string to integer
621
//localparam MEM_BURST_INT = (MEM_BURST_LEN == "8")? 8 : 4;
622
localparam MEM_BURST_INT = MEM_BURST_LEN ;
623
 
624
 
625
generate
626
if (FAMILY == "VIRTEX6" ) begin : INC_COUNTS_V
627
    always @ (posedge clk_i) begin
628
 
629
if ( (NUM_DQ_PINS >= 128 && NUM_DQ_PINS <= 144))       //256
630
     INC_COUNTS <= #TCQ  64 * (MEM_BURST_INT/4);
631
 
632
else if ( (NUM_DQ_PINS >= 64 && NUM_DQ_PINS < 128))       //256
633
     INC_COUNTS <= #TCQ  32 * (MEM_BURST_INT/4);
634
else if ((NUM_DQ_PINS >= 32) && (NUM_DQ_PINS < 64))   //128
635
     INC_COUNTS <= #TCQ  16 * (MEM_BURST_INT/4)   ;
636
else if ((NUM_DQ_PINS == 16) || (NUM_DQ_PINS == 24))  //64
637
     INC_COUNTS <= #TCQ  8 * (MEM_BURST_INT/4);
638
else if ((NUM_DQ_PINS == 8) )
639
     INC_COUNTS <= #TCQ  4 * (MEM_BURST_INT/4);
640
end
641
end
642
endgenerate
643
 
644
generate
645
// Sequential Address pattern
646
// It is generated when rdy_i is valid and write command is valid and bl_cmd is valid.
647
reg [31:0] end_addr_r;
648
 
649
always @ (posedge clk_i) begin
650
     end_addr_r <= #TCQ  end_addr_i - DWIDTH/8*fixed_bl_i +1;
651
end
652
 
653
always @ (posedge clk_i) begin
654
if (addr_out[31:24] >= end_addr_r[31:24])
655
    AC3_G_E3 <= #TCQ    1'b1;
656
else
657
    AC3_G_E3 <= #TCQ    1'b0;
658
 
659
if (addr_out[23:16] >= end_addr_r[23:16])
660
    AC2_G_E2 <= #TCQ    1'b1;
661
else
662
    AC2_G_E2 <= #TCQ    1'b0;
663
 
664
if (addr_out[15:8] >= end_addr_r[15:8])
665
    AC1_G_E1 <= #TCQ    1'b1;
666
else
667
    AC1_G_E1 <= #TCQ    1'b0;
668
end
669
 
670
//if (CMD_PATTERN == "CGEN_SEQUENTIAL" || CMD_PATTERN == "CGEN_ALL" ) begin : seq_addr_gen
671
    assign seq_addr = addr_counts;
672
 
673
reg mode_load_pulse_r1;
674
 
675
always @ (posedge clk_i)
676
begin
677
    mode_load_pulse_r1 <= #TCQ  mode_load_pulse;
678
 
679
end
680
 
681
always @ (posedge clk_i)
682
    end_addr_range <= #TCQ    end_addr_i[15:0] - (DWIDTH/8 *bl_out_reg) + 1   ;
683
 
684
always @ (posedge clk_i)
685
    addr_counts_next_r <= #TCQ    addr_counts  + INC_COUNTS   ;
686
 
687
reg cmd_clk_en_r;
688
always @ (posedge clk_i)
689
  cmd_clk_en_r <= #TCQ  cmd_clk_en;
690
always @ (posedge clk_i) begin
691
   if (rst_i[4]) begin
692
        addr_counts <= #TCQ    start_addr_i;
693
        mem_init_done <= #TCQ  1'b0;
694
  end else if (cmd_clk_en_r || mode_load_pulse_r1)
695
    if(addr_counts_next_r>= end_addr_i) begin
696
                addr_counts <= #TCQ    start_addr_i;
697
                mem_init_done <= #TCQ  1'b1;
698
    end else if(addr_counts < end_addr_r)  // address counts get incremented by burst_length and port size each wr command generated
699
                addr_counts <= #TCQ    addr_counts + INC_COUNTS;
700
end
701
 
702
 // end begin
703
//end
704
endgenerate
705
 
706
generate
707
// Fixed Address pattern
708
if (CMD_PATTERN == "CGEN_FIXED" || CMD_PATTERN == "CGEN_ALL" ) begin : fixed_addr_gen
709
    assign fixed_addr = (DWIDTH == 32)?  {fixed_addr_i[31:2],2'b0} :
710
                        (DWIDTH == 64)?  {fixed_addr_i[31:3],3'b0}:
711
                        (DWIDTH <= 128)? {fixed_addr_i[31:4],4'b0}:
712
                        (DWIDTH <= 256)? {fixed_addr_i[31:5],5'b0}:
713
                                         {fixed_addr_i[31:6],6'b0};
714
  end
715
endgenerate
716
 
717
generate
718
// BRAM Address pattern
719
if (CMD_PATTERN == "CGEN_BRAM" || CMD_PATTERN == "CGEN_ALL" ) begin : bram_addr_gen
720
assign bram_rdy_o = run_traffic_i & cmd_clk_en & bram_valid_i | mode_load_pulse;
721
end
722
endgenerate
723
 
724
///////////////////////////////////////////////////////////////////////////
725
//  INSTR COMMAND GENERATION
726
 
727
// tap points are 3,2
728
//`define RD              3'b001
729
//`define RDP             3'b011
730
//`define WR              3'b000
731
//`define WRP             3'b010
732
//`define REFRESH         3'b100
733
// use 14 stages  1 sr16; tap position 1,3,5,14
734
 
735
reg [9:0]force_rd_counts;
736
reg force_rd;
737
always @ (posedge clk_i) begin
738
if (rst_i[4])
739
    force_rd_counts <= #TCQ  'b0;
740
else if (instr_vld) begin
741
    force_rd_counts <= #TCQ  force_rd_counts + 1;
742
    end
743
end
744
 
745
always @ (posedge clk_i) begin
746
if (rst_i[4])
747
    force_rd <= #TCQ  1'b0;
748
else if (force_rd_counts[3])
749
    force_rd <= #TCQ  1'b1;
750
else
751
    force_rd <= #TCQ  1'b0;
752
end
753
 
754
 
755
// adding refresh timer to limit the amount of issuing refresh command.
756
always @ (posedge clk_i) begin
757
if (rst_i[4])
758
   refresh_timer <= #TCQ  'b0;
759
else
760
   refresh_timer <= #TCQ  refresh_timer + 1'b1;
761
 
762
end
763
 
764
always @ (posedge clk_i) begin
765
if (rst_i[4])
766
   refresh_cmd_en <= #TCQ  'b0;
767
//else if (refresh_timer >= 12'hff0 && refresh_timer <= 12'hfff)
768
else if (refresh_timer == 10'h3ff)
769
 
770
   refresh_cmd_en <= #TCQ  'b1;
771
else if (cmd_clk_en && refresh_cmd_en)
772
   refresh_cmd_en <= #TCQ  'b0;
773
 
774
end
775
 
776
always @ (posedge clk_i) begin
777
if (FAMILY == "SPARTAN6")
778
    refresh_prbs <= #TCQ  prbs_instr_b[3] & refresh_cmd_en;
779
else
780
    refresh_prbs <= #TCQ  1'b0;
781
end
782
  //synthesis translate_off
783
always @ (instr_mode_i)
784
  if(instr_mode_i  >2 && FAMILY == "VIRTEX6") begin
785
   $display("Error ! Not valid instruction mode");
786
   $stop;
787
   end
788
  //synthesis translate_on
789
 
790
always @ (posedge clk_i) begin
791
   case(instr_mode_i)
792
         0: instr_out <= #TCQ    bram_instr_i;
793
         1: instr_out <= #TCQ    fixed_instr_i;
794
         2: instr_out <= #TCQ    {2'b00,(prbs_instr_a[0] | force_rd)};
795
         3: instr_out <= #TCQ    {2'b0,prbs_instr_a[0]};  //:  WP/RP
796
         4: instr_out <= #TCQ    {1'b0,prbs_instr_b[0], prbs_instr_a[0]};  //  W/WP/R/RP.
797
         // may be add another PRBS for generating REFRESH
798
//         5: instr_out <= #TCQ    {prbs_instr_b[3],prbs_instr_b[0], prbs_instr_a[0]};  // W/WP/R/RP/REFRESH W/WP/R/RP/REFRESH
799
         5: instr_out <= #TCQ    {refresh_prbs ,prbs_instr_b[0], prbs_instr_a[0]};  // W/WP/R/RP/REFRESH W/WP/R/RP/REFRESH
800
 
801
 
802
         default : instr_out <= #TCQ    {2'b00,prbs_instr_a[0]};
803
   endcase
804
end
805
 
806
generate  // PRBS INSTRUCTION generation
807
// use two PRBS generators and tap off 1 bit from each to create more randomness for
808
// generating actual read/write commands
809
if (CMD_PATTERN == "CGEN_PRBS" || CMD_PATTERN == "CGEN_ALL" ) begin: gen_prbs_instr
810
cmd_prbs_gen #
811
  (
812
    .TCQ               (TCQ),
813
    .PRBS_CMD    ("INSTR"),
814
    .ADDR_WIDTH  (32),
815
    .SEED_WIDTH  (15),
816
    .PRBS_WIDTH  (20)
817
   )
818
   instr_prbs_gen_a
819
  (
820
   .clk_i              (clk_i),
821
   .clk_en             (cmd_clk_en),
822
   .prbs_seed_init     (load_seed_i),
823
   .prbs_seed_i        (cmd_seed_i[14:0]),
824
   .prbs_o             (prbs_instr_a)
825
  );
826
 
827
cmd_prbs_gen #
828
  (
829
    .PRBS_CMD    ("INSTR"),
830
    .SEED_WIDTH  (15),
831
    .PRBS_WIDTH  (20)
832
   )
833
   instr_prbs_gen_b
834
  (
835
   .clk_i              (clk_i),
836
   .clk_en             (cmd_clk_en),
837
   .prbs_seed_init     (load_seed_i),
838
   .prbs_seed_i        (cmd_seed_i[16:2]),
839
   .prbs_o             (prbs_instr_b)
840
  );
841
end
842
endgenerate
843
 
844
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
845
// BURST LENGTH GENERATION
846
// burst length code = user burst length input - 1
847
// mcb_flow_control does the minus before sending out to mcb\
848
// when filling up the memory, need to make sure bl doesn't go beyound its upper limit boundary
849
//assign force_bl1 = (addr_out[31:0] >= (end_addr_i[31:0] - 4*64)) ? 1'b1: 1'b0;
850
// for neighbour pattern, need to limit the bl to make sure it is within column size boundary.
851
 
852
// check bl validity
853
 
854
always @ (posedge clk_i) begin
855
if (addr_out[31:24] >= end_addr_i[31:24])
856
    A3_G_E3 <= #TCQ    1'b1;
857
else
858
    A3_G_E3 <= #TCQ    1'b0;
859
 
860
if (addr_out[23:16] >= end_addr_i[23:16])
861
    A2_G_E2 <= #TCQ    1'b1;
862
else
863
    A2_G_E2 <= #TCQ    1'b0;
864
 
865
if (addr_out[15:8] >= end_addr_i[15:8])
866
    A1_G_E1 <= #TCQ    1'b1;
867
else
868
    A1_G_E1 <= #TCQ    1'b0;
869
 
870
if (addr_out[7:0] > end_addr_i[7:0] - DWIDTH/8* bl_out + 1)
871
    A0_G_E0 <= #TCQ    1'b1;
872
else
873
    A0_G_E0 <= #TCQ    1'b0;
874
end
875
 
876
always @(addr_out,bl_out,end_addr_i,rst_i,buf_avail_r) begin
877
    if (rst_i[5])
878
        force_bl1 =   1'b0;
879
    else if (((addr_out + bl_out* (DWIDTH/8)) >= end_addr_i) || (buf_avail_r  <= 50 && PORT_MODE == "RD_MODE"))
880
        force_bl1 =   1'b1;
881
    else
882
        force_bl1 =   1'b0;
883
end
884
 
885
always @(posedge clk_i) begin
886
   if (rst_i[6])
887
       bl_out_reg <= #TCQ    fixed_bl_i;
888
   else if (bl_out_vld)
889
       bl_out_reg <= #TCQ    bl_out;
890
end
891
 
892
always @ (posedge clk_i) begin
893
   if (mode_load_pulse)
894
        bl_out <= #TCQ    fixed_bl_i ;
895
   else if (cmd_clk_en) begin
896
     case({bl_mode_reg})
897
         0: bl_out <= #TCQ    bram_bl_i  ;
898
         1: bl_out <= #TCQ    fixed_bl_i ;
899
         2: bl_out <= #TCQ    prbs_brlen;
900
         default : bl_out <= #TCQ    6'h1;
901
     endcase
902
   end
903
end
904
 
905
  //synthesis translate_off
906
always @ (bl_out)
907
  if(bl_out >2 && FAMILY == "VIRTEX6") begin
908
   $display("Error ! Not valid burst length");
909
   $stop;
910
   end
911
  //synthesis translate_on
912
 
913
generate
914
if (CMD_PATTERN == "CGEN_PRBS" || CMD_PATTERN == "CGEN_ALL" ) begin: gen_prbs_bl
915
cmd_prbs_gen #
916
      (
917
    .TCQ               (TCQ),
918
    .FAMILY      (FAMILY),
919
    .PRBS_CMD    ("BLEN"),
920
    .ADDR_WIDTH  (32),
921
    .SEED_WIDTH  (15),
922
    .PRBS_WIDTH  (20)
923
   )
924
   bl_prbs_gen
925
  (
926
   .clk_i             (clk_i),
927
   .clk_en            (cmd_clk_en),
928
   .prbs_seed_init    (load_seed_i),
929
   .prbs_seed_i       (cmd_seed_i[16:2]),
930
   .prbs_o            (prbs_bl)
931
  );
932
end
933
 
934
always @ (prbs_bl)
935
if (FAMILY == "SPARTAN6")  // supports 1 throug 64
936
    prbs_brlen =  (prbs_bl[5:0] == 6'b000000) ? 6'b000001: prbs_bl[5:0];
937
else // VIRTEX6 only supports 1 or 2 burst on user ports
938
     prbs_brlen =  6'b000010;
939
endgenerate
940
 
941
endmodule

powered by: WebSVN 2.1.0

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