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
|