AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_ui_wr_data.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 : ui_wr_data.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 // User interface write data buffer. Consists of four counters,
67 // a pointer RAM and the write data storage RAM.
68 //
69 // All RAMs are implemented with distributed RAM.
70 //
71 // Whe ordering is set to STRICT or NORM, data moves through
72 // the write data buffer in strictly FIFO order. In RELAXED
73 // mode, data may be retired from the write data RAM in any
74 // order relative to the input order. This implementation
75 // supports all ordering modes.
76 //
77 // The pointer RAM stores a list of pointers to the write data storage RAM.
78 // This is a list of vacant entries. As data is written into the RAM, a
79 // pointer is pulled from the pointer RAM and used to index the write
80 // operation. In a semi autonomously manner, pointers are also pulled, in
81 // the same order, and provided to the command port as the data_buf_addr.
82 //
83 // When the MC reads data from the write data buffer, it uses the
84 // data_buf_addr provided with the command to extract the data from the
85 // write data buffer. It also writes this pointer into the end
86 // of the pointer RAM.
87 //
88 // The occupancy counter keeps track of how many entries are valid
89 // in the write data storage RAM. app_wdf_rdy and app_rdy will be
90 // de-asserted when there is no more storage in the write data buffer.
91 //
92 // Three sequentially incrementing counters/indexes are used to maintain
93 // and use the contents of the pointer RAM.
94 //
95 // The write buffer write data address index generates the pointer
96 // used to extract the write data address from the pointer RAM. It
97 // is incremented with each buffer write. The counter is actually one
98 // ahead of the current write address so that the actual data buffer
99 // write address can be registered to give a full state to propagate to
100 // the write data distributed RAMs.
101 //
102 // The data_buf_addr counter is used to extract the data_buf_addr for
103 // the command port. It is incremented as each command is written
104 // into the MC.
105 //
106 // The read data index points to the end of the list of free
107 // buffers. When the MC fetches data from the write data buffer, it
108 // provides the buffer address. The buffer address is used to fetch
109 // the data, but is also written into the pointer at the location indicated
110 // by the read data index.
111 //
112 // Enter and exiting a buffer full condition generates corner cases. Upon
113 // entering a full condition, incrementing the write buffer write data
114 // address index must be inhibited. When exiting the full condition,
115 // the just arrived pointer must propagate through the pointer RAM, then
116 // indexed by the current value of the write buffer write data
117 // address counter, the value is registered in the write buffer write
118 // data address register, then the counter can be advanced.
119 //
120 // The pointer RAM must be initialized with valid data after reset. This is
121 // accomplished by stepping through each pointer RAM entry and writing
122 // the locations address into the pointer RAM. For the FIFO modes, this means
123 // that buffer address will always proceed in a sequential order. In the
124 // RELAXED mode, the original write traversal will be in sequential
125 // order, but once the MC begins to retire out of order, the entries in
126 // the pointer RAM will become randomized. The ui_rd_data module provides
127 // the control information for the initialization process.
128 
129 `timescale 1 ps / 1 ps
130 
132  (
133  parameter TCQ = 100,
134  parameter APP_DATA_WIDTH = 256,
135  parameter APP_MASK_WIDTH = 32,
136  parameter ECC = "OFF",
137  parameter nCK_PER_CLK = 2 ,
138  parameter ECC_TEST = "OFF",
139  parameter CWL = 5
140  )
141  (/*AUTOARG**/
142  // Outputs
143  app_wdf_rdy, wr_req_16, wr_data_buf_addr, wr_data, wr_data_mask,
144  raw_not_ecc,
145  // Inputs
146  rst, clk, app_wdf_data, app_wdf_mask, app_raw_not_ecc, app_wdf_wren,
147  app_wdf_end, wr_data_offset, wr_data_addr, wr_data_en, wr_accepted,
148  ram_init_done_r, ram_init_addr
149  );
150 
151  input rst;
152  input clk;
153 
154  input [APP_DATA_WIDTH-1:0] app_wdf_data;
155  input [APP_MASK_WIDTH-1:0] app_wdf_mask;
156  input [2*nCK_PER_CLK-1:0] app_raw_not_ecc;
157  input app_wdf_wren;
158  input app_wdf_end;
159 
160  reg [APP_DATA_WIDTH-1:0] app_wdf_data_r1;
161  reg [APP_MASK_WIDTH-1:0] app_wdf_mask_r1;
162  reg [2*nCK_PER_CLK-1:0] app_raw_not_ecc_r1 = 4'b0;
163  reg app_wdf_wren_r1;
164  reg app_wdf_end_r1;
165 
166  reg app_wdf_rdy_r;
167 
168  //Adding few copies of the app_wdf_rdy_r signal in order to meet
169  //timing. This is signal has a very high fanout. So grouped into
170  //few functional groups and alloted one copy per group.
171  (* equivalent_register_removal = "no" *)
172  reg app_wdf_rdy_r_copy1;
173  (* equivalent_register_removal = "no" *)
174  reg app_wdf_rdy_r_copy2;
175  (* equivalent_register_removal = "no" *)
176  reg app_wdf_rdy_r_copy3;
177  (* equivalent_register_removal = "no" *)
178  reg app_wdf_rdy_r_copy4;
179 
180  wire [APP_DATA_WIDTH-1:0] app_wdf_data_ns1 =
181  ~app_wdf_rdy_r_copy2 ? app_wdf_data_r1 : app_wdf_data;
182  wire [APP_MASK_WIDTH-1:0] app_wdf_mask_ns1 =
183  ~app_wdf_rdy_r_copy2 ? app_wdf_mask_r1 : app_wdf_mask;
184  wire app_wdf_wren_ns1 =
185  ~rst && (~app_wdf_rdy_r_copy2 ? app_wdf_wren_r1 : app_wdf_wren);
186  wire app_wdf_end_ns1 =
187  ~rst && (~app_wdf_rdy_r_copy2 ? app_wdf_end_r1 : app_wdf_end);
188 
189  generate
190  if (ECC_TEST != "OFF") begin : ecc_on
191  always @(app_raw_not_ecc) app_raw_not_ecc_r1 = app_raw_not_ecc;
192  end
193  endgenerate
194 
195 // Be explicit about the latch enable on these registers.
196  always @(posedge clk) begin
197  app_wdf_data_r1 <= #TCQ app_wdf_data_ns1;
198  app_wdf_mask_r1 <= #TCQ app_wdf_mask_ns1;
199  app_wdf_wren_r1 <= #TCQ app_wdf_wren_ns1;
200  app_wdf_end_r1 <= #TCQ app_wdf_end_ns1;
201  end
202 
203 // The signals wr_data_addr and wr_data_offset come at different
204 // times depending on ECC and the value of CWL. The data portion
205 // always needs to look a the raw wires, the control portion needs
206 // to look at a delayed version when ECC is on and CWL != 8. The
207 // currently supported write data delays do not require this
208 // functionality, but preserve for future use.
209  input wr_data_offset;
210  input [3:0] wr_data_addr;
211  reg wr_data_offset_r;
212  reg [3:0] wr_data_addr_r;
213  generate
214  if (ECC == "OFF" || CWL >= 0) begin : pass_wr_addr
215  always @(wr_data_offset) wr_data_offset_r = wr_data_offset;
216  always @(wr_data_addr) wr_data_addr_r = wr_data_addr;
217  end
218  else begin : delay_wr_addr
219  always @(posedge clk) wr_data_offset_r <= #TCQ wr_data_offset;
220  always @(posedge clk) wr_data_addr_r <= #TCQ wr_data_addr;
221  end
222  endgenerate
223 
224 // rd_data_cnt is the pointer RAM index for data read from the write data
225 // buffer. Ie, its the data on its way out to the DRAM.
226  input wr_data_en;
227  wire new_rd_data = wr_data_en && ~wr_data_offset_r;
228  reg [3:0] rd_data_indx_r;
229  reg rd_data_upd_indx_r;
230  generate begin : read_data_indx
231  reg [3:0] rd_data_indx_ns;
232  always @(/*AS**/new_rd_data or rd_data_indx_r or rst) begin
233  rd_data_indx_ns = rd_data_indx_r;
234  if (rst) rd_data_indx_ns = 5'b0;
235  else if (new_rd_data) rd_data_indx_ns = rd_data_indx_r + 5'h1;
236  end
237  always @(posedge clk) rd_data_indx_r <= #TCQ rd_data_indx_ns;
238  always @(posedge clk) rd_data_upd_indx_r <= #TCQ new_rd_data;
239  end
240  endgenerate
241 
242 // data_buf_addr_cnt generates the pointer for the pointer RAM on behalf
243 // of data buf address that comes with the wr_data_en.
244 // The data buf address is written into the memory
245 // controller along with the command and address.
246  input wr_accepted;
247  reg [3:0] data_buf_addr_cnt_r;
248  generate begin : data_buf_address_counter
249 
250  reg [3:0] data_buf_addr_cnt_ns;
251  always @(/*AS**/data_buf_addr_cnt_r or rst or wr_accepted) begin
252  data_buf_addr_cnt_ns = data_buf_addr_cnt_r;
253  if (rst) data_buf_addr_cnt_ns = 4'b0;
254  else if (wr_accepted) data_buf_addr_cnt_ns =
255  data_buf_addr_cnt_r + 4'h1;
256  end
257  always @(posedge clk) data_buf_addr_cnt_r <= #TCQ data_buf_addr_cnt_ns;
258 
259  end
260  endgenerate
261 
262 // Control writing data into the write data buffer.
263  wire wdf_rdy_ns;
264  always @( posedge clk ) begin
265  app_wdf_rdy_r_copy1 <= #TCQ wdf_rdy_ns;
266  app_wdf_rdy_r_copy2 <= #TCQ wdf_rdy_ns;
267  app_wdf_rdy_r_copy3 <= #TCQ wdf_rdy_ns;
268  app_wdf_rdy_r_copy4 <= #TCQ wdf_rdy_ns;
269  end
270  wire wr_data_end = app_wdf_end_r1 && app_wdf_rdy_r_copy1 && app_wdf_wren_r1;
271  wire [3:0] wr_data_pntr;
272  wire [4:0] wb_wr_data_addr;
273  wire [4:0] wb_wr_data_addr_w;
274  reg [3:0] wr_data_indx_r;
275  generate begin : write_data_control
276 
277  wire wr_data_addr_le = (wr_data_end && wdf_rdy_ns) ||
278  (rd_data_upd_indx_r && ~app_wdf_rdy_r_copy1);
279 
280 // For pointer RAM. Initialize to one since this is one ahead of
281 // what's being registered in wb_wr_data_addr. Assumes pointer RAM
282 // has been initialized such that address equals contents.
283  reg [3:0] wr_data_indx_ns;
284  always @(/*AS**/rst or wr_data_addr_le or wr_data_indx_r) begin
285  wr_data_indx_ns = wr_data_indx_r;
286  if (rst) wr_data_indx_ns = 4'b1;
287  else if (wr_data_addr_le) wr_data_indx_ns = wr_data_indx_r + 4'h1;
288  end
289  always @(posedge clk) wr_data_indx_r <= #TCQ wr_data_indx_ns;
290 
291 // Take pointer from pointer RAM and set into the write data address.
292 // Needs to be split into zeroth bit and everything else because synthesis
293 // tools don't always allow assigning bit vectors seperately. Bit zero of the
294 // address is computed via an entirely different algorithm.
295  reg [4:1] wb_wr_data_addr_ns;
296  reg [4:1] wb_wr_data_addr_r;
297  always @(/*AS**/rst or wb_wr_data_addr_r or wr_data_addr_le
298  or wr_data_pntr) begin
299  wb_wr_data_addr_ns = wb_wr_data_addr_r;
300  if (rst) wb_wr_data_addr_ns = 4'b0;
301  else if (wr_data_addr_le) wb_wr_data_addr_ns = wr_data_pntr;
302  end
303  always @(posedge clk) wb_wr_data_addr_r <= #TCQ wb_wr_data_addr_ns;
304 
305 // If we see the first getting accepted, then
306 // second half is unconditionally accepted.
307  reg wb_wr_data_addr0_r;
308  wire wb_wr_data_addr0_ns = ~rst &&
309  ((app_wdf_rdy_r_copy3 && app_wdf_wren_r1 && ~app_wdf_end_r1) ||
310  (wb_wr_data_addr0_r && ~app_wdf_wren_r1));
311  always @(posedge clk) wb_wr_data_addr0_r <= #TCQ wb_wr_data_addr0_ns;
312 
313  assign wb_wr_data_addr = {wb_wr_data_addr_r, wb_wr_data_addr0_r};
314  assign wb_wr_data_addr_w = {wb_wr_data_addr_ns, wb_wr_data_addr0_ns};
315 
316  end
317  endgenerate
318 
319 // Keep track of how many entries in the queue hold data.
320  input ram_init_done_r;
321  output wire app_wdf_rdy;
322  generate begin : occupied_counter
323  //reg [4:0] occ_cnt_ns;
324  //reg [4:0] occ_cnt_r;
325  //always @(/*AS*/occ_cnt_r or rd_data_upd_indx_r or rst
326  // or wr_data_end) begin
327  // occ_cnt_ns = occ_cnt_r;
328  // if (rst) occ_cnt_ns = 5'b0;
329  // else case ({wr_data_end, rd_data_upd_indx_r})
330  // 2'b01 : occ_cnt_ns = occ_cnt_r - 5'b1;
331  // 2'b10 : occ_cnt_ns = occ_cnt_r + 5'b1;
332  // endcase // case ({wr_data_end, rd_data_upd_indx_r})
333  //end
334  //always @(posedge clk) occ_cnt_r <= #TCQ occ_cnt_ns;
335  //assign wdf_rdy_ns = !(rst || ~ram_init_done_r || occ_cnt_ns[4]);
336  //always @(posedge clk) app_wdf_rdy_r <= #TCQ wdf_rdy_ns;
337  //assign app_wdf_rdy = app_wdf_rdy_r;
338  reg [15:0] occ_cnt;
339  always @(posedge clk) begin
340  if ( rst )
341  occ_cnt <= #TCQ 16'h0000;
342  else case ({wr_data_end, rd_data_upd_indx_r})
343  2'b01 : occ_cnt <= #TCQ {1'b0,occ_cnt[15:1]};
344  2'b10 : occ_cnt <= #TCQ {occ_cnt[14:0],1'b1};
345  endcase // case ({wr_data_end, rd_data_upd_indx_r})
346  end
347  assign wdf_rdy_ns = !(rst || ~ram_init_done_r || (occ_cnt[14] && wr_data_end && ~rd_data_upd_indx_r) || (occ_cnt[15] && ~rd_data_upd_indx_r));
348  always @(posedge clk) app_wdf_rdy_r <= #TCQ wdf_rdy_ns;
349  assign app_wdf_rdy = app_wdf_rdy_r;
350 
351 `ifdef MC_SVA
352  wr_data_buffer_full: cover property (@(posedge clk)
353  (~rst && ~app_wdf_rdy_r));
354 // wr_data_buffer_inc_dec_15: cover property (@(posedge clk)
355 // (~rst && wr_data_end && rd_data_upd_indx_r && (occ_cnt_r == 5'hf)));
356 // wr_data_underflow: assert property (@(posedge clk)
357 // (rst || !((occ_cnt_r == 5'b0) && (occ_cnt_ns == 5'h1f))));
358 // wr_data_overflow: assert property (@(posedge clk)
359 // (rst || !((occ_cnt_r == 5'h10) && (occ_cnt_ns == 5'h11))));
360 `endif
361  end // block: occupied_counter
362  endgenerate
363 
364 // Keep track of how many write requests are in the memory controller. We
365 // must limit this to 16 because we only have that many data_buf_addrs to
366 // hand out. Since the memory controller queue and the write data buffer
367 // queue are distinct, the number of valid entries can be different.
368 // Throttle request acceptance once there are sixteen write requests in
369 // the memory controller. Note that there is still a requirement
370 // for a write reqeusts corresponding write data to be written into the
371 // write data queue with two states of the request.
372  output wire wr_req_16;
373  generate begin : wr_req_counter
374  reg [4:0] wr_req_cnt_ns;
375  reg [4:0] wr_req_cnt_r;
376  always @(/*AS**/rd_data_upd_indx_r or rst or wr_accepted
377  or wr_req_cnt_r) begin
378  wr_req_cnt_ns = wr_req_cnt_r;
379  if (rst) wr_req_cnt_ns = 5'b0;
380  else case ({wr_accepted, rd_data_upd_indx_r})
381  2'b01 : wr_req_cnt_ns = wr_req_cnt_r - 5'b1;
382  2'b10 : wr_req_cnt_ns = wr_req_cnt_r + 5'b1;
383  endcase // case ({wr_accepted, rd_data_upd_indx_r})
384  end
385  always @(posedge clk) wr_req_cnt_r <= #TCQ wr_req_cnt_ns;
386  assign wr_req_16 = (wr_req_cnt_ns == 5'h10);
387 
388 `ifdef MC_SVA
389  wr_req_mc_full: cover property (@(posedge clk) (~rst && wr_req_16));
390  wr_req_mc_full_inc_dec_15: cover property (@(posedge clk)
391  (~rst && wr_accepted && rd_data_upd_indx_r && (wr_req_cnt_r == 5'hf)));
392  wr_req_underflow: assert property (@(posedge clk)
393  (rst || !((wr_req_cnt_r == 5'b0) && (wr_req_cnt_ns == 5'h1f))));
394  wr_req_overflow: assert property (@(posedge clk)
395  (rst || !((wr_req_cnt_r == 5'h10) && (wr_req_cnt_ns == 5'h11))));
396 `endif
397  end // block: wr_req_counter
398  endgenerate
399 
400 
401 
402 // Instantiate pointer RAM. Made up of RAM32M in single write, two read
403 // port mode, 2 bit wide mode.
404  input [3:0] ram_init_addr;
405  output wire [3:0] wr_data_buf_addr;
406  localparam PNTR_RAM_CNT = 2;
407  generate begin : pointer_ram
408  wire pointer_we = new_rd_data || ~ram_init_done_r;
409  wire [3:0] pointer_wr_data = ram_init_done_r
410  ? wr_data_addr_r
411  : ram_init_addr;
412  wire [3:0] pointer_wr_addr = ram_init_done_r
413  ? rd_data_indx_r
414  : ram_init_addr;
415  genvar i;
416  for (i=0; i<PNTR_RAM_CNT; i=i+1) begin : rams
417  RAM32M
418  #(.INIT_A(64'h0000000000000000),
419  .INIT_B(64'h0000000000000000),
420  .INIT_C(64'h0000000000000000),
421  .INIT_D(64'h0000000000000000)
422  ) RAM32M0 (
423  .DOA(),
424  .DOB(wr_data_buf_addr[i*2+:2]),
425  .DOC(wr_data_pntr[i*2+:2]),
426  .DOD(),
427  .DIA(2'b0),
428  .DIB(pointer_wr_data[i*2+:2]),
429  .DIC(pointer_wr_data[i*2+:2]),
430  .DID(2'b0),
431  .ADDRA(5'b0),
432  .ADDRB({1'b0, data_buf_addr_cnt_r}),
433  .ADDRC({1'b0, wr_data_indx_r}),
434  .ADDRD({1'b0, pointer_wr_addr}),
435  .WE(pointer_we),
436  .WCLK(clk)
437  );
438  end // block : rams
439  end // block: pointer_ram
440  endgenerate
441 
442 
443 // Instantiate write data buffer. Depending on width of DQ bus and
444 // DRAM CK to fabric ratio, number of RAM32Ms is variable. RAM32Ms are
445 // used in single write, single read, 6 bit wide mode.
446  localparam WR_BUF_WIDTH =
447  APP_DATA_WIDTH + APP_MASK_WIDTH + (ECC_TEST == "OFF" ? 0 : 2*nCK_PER_CLK);
448  localparam FULL_RAM_CNT = (WR_BUF_WIDTH/6);
449  localparam REMAINDER = WR_BUF_WIDTH % 6;
450  localparam RAM_CNT = FULL_RAM_CNT + ((REMAINDER == 0 ) ? 0 : 1);
451  localparam RAM_WIDTH = (RAM_CNT*6);
452  wire [RAM_WIDTH-1:0] wr_buf_out_data_w;
453  reg [RAM_WIDTH-1:0] wr_buf_out_data;
454  generate
455  begin : write_buffer
456  wire [RAM_WIDTH-1:0] wr_buf_in_data;
457  if (REMAINDER == 0)
458  if (ECC_TEST == "OFF")
459  assign wr_buf_in_data = {app_wdf_mask_ns1, app_wdf_data_ns1};
460  else
461  assign wr_buf_in_data =
462  {app_raw_not_ecc_r1, app_wdf_mask_ns1, app_wdf_data_ns1};
463  else
464  if (ECC_TEST == "OFF")
465  assign wr_buf_in_data =
466  {{6-REMAINDER{1'b0}}, app_wdf_mask_ns1, app_wdf_data_ns1};
467  else
468  assign wr_buf_in_data = {{6-REMAINDER{1'b0}}, app_raw_not_ecc_r1,//app_raw_not_ecc_r1 is not ff
469  app_wdf_mask_ns1, app_wdf_data_ns1};
470 
471  wire [4:0] rd_addr_w;
472 
473 assign rd_addr_w = {wr_data_addr, wr_data_offset};
474  always @(posedge clk) wr_buf_out_data <= #TCQ wr_buf_out_data_w;
475  genvar i;
476  for (i=0; i<RAM_CNT; i=i+1) begin : wr_buffer_ram
477  RAM32M
478  #(.INIT_A(64'h0000000000000000),
479  .INIT_B(64'h0000000000000000),
480  .INIT_C(64'h0000000000000000),
481  .INIT_D(64'h0000000000000000)
482  ) RAM32M0 (
483  .DOA(wr_buf_out_data_w[((i*6)+4)+:2]),
484  .DOB(wr_buf_out_data_w[((i*6)+2)+:2]),
485  .DOC(wr_buf_out_data_w[((i*6)+0)+:2]),
486  .DOD(),
487  .DIA(wr_buf_in_data[((i*6)+4)+:2]),
488  .DIB(wr_buf_in_data[((i*6)+2)+:2]),
489  .DIC(wr_buf_in_data[((i*6)+0)+:2]),
490  .DID(2'b0),
491  .ADDRA(rd_addr_w),
492  .ADDRB(rd_addr_w),
493  .ADDRC(rd_addr_w),
494  .ADDRD(wb_wr_data_addr_w),
495  .WE(wdf_rdy_ns),
496  .WCLK(clk)
497  );
498  end // block: wr_buffer_ram
499  end
500  endgenerate
501 
502  output [APP_DATA_WIDTH-1:0] wr_data;
503  output [APP_MASK_WIDTH-1:0] wr_data_mask;
504  assign {wr_data_mask, wr_data} = wr_buf_out_data[WR_BUF_WIDTH-1:0];
505  output [2*nCK_PER_CLK-1:0] raw_not_ecc;
506  generate
507  if (ECC_TEST == "OFF") assign raw_not_ecc = {2*nCK_PER_CLK{1'b0}};
508  else assign raw_not_ecc = wr_buf_out_data[WR_BUF_WIDTH-1-:4];
509  endgenerate
510 
511 endmodule // ui_wr_data
512 
513 // Local Variables:
514 // verilog-library-directories:(".")
515 // End: