// Copyright 2010 Altera Corporation. All rights reserved. // Altera products are protected under numerous U.S. and foreign patents, // maskwork rights, copyrights and other intellectual property laws. // // This reference design file, and your use thereof, is subject to and governed // by the terms and conditions of the applicable Altera Reference Design // License Agreement (either as signed by you or found at www.altera.com). By // using this reference design file, you indicate your acceptance of such terms // and conditions between you and Altera Corporation. In the event that you do // not agree with such terms and conditions, you may not use the reference // design file and please promptly destroy any copies you have made. // // This reference design file is being provided on an "as-is" basis and as an // accommodation and therefore all warranties, representations or guarantees of // any kind (whether express, implied or statutory) including, without // limitation, warranties of merchantability, non-infringement, or fitness for // a particular purpose, are specifically disclaimed. By making this reference // design file available, Altera expressly does not recommend, suggest or // require that this reference design file be used in combination with any // other product not provided by Altera. ///////////////////////////////////////////////////////////////////////////// `timescale 1 ps / 1 ps // baeckler - 12-15-2009 // clk _|^|_|^|_|^|_|^|_|^| // rdreq _|^^^|________ // data > 1'b1) ^ rdbin_next; wire [RAM_ADDR_WIDTH:0] sync_wrptr; always @(posedge rdclk or posedge rdarst) begin if (rdarst) begin rdbin <= 0; rdgray <= 0; end else begin rdbin <= rdbin_next; rdgray <= rdgray_next; end end always @(posedge rdclk) begin rdempty <= (rdgray_next == sync_wrptr); end ////////////////////////////////////////// // write pointers ////////////////////////////////////////// reg [RAM_ADDR_WIDTH:0] wrgray = 0, wrbin = 0 /* synthesis preserve */; initial wrfull = 1'b1; //timing modification //wire [RAM_ADDR_WIDTH:0] wrbin_next = wrbin + (wrreq & ~wrfull); wire [RAM_ADDR_WIDTH:0] wrbin_plus = wrbin + 1'b1 /* synthesis keep */; wire [RAM_ADDR_WIDTH:0] wrbin_next = (~wrfull & wrreq) ? wrbin_plus : wrbin; wire [RAM_ADDR_WIDTH:0] wrgray_next = (wrbin_next >> 1'b1) ^ wrbin_next /* synthesis keep */; wire [RAM_ADDR_WIDTH:0] sync_rdptr; always @(posedge wrclk or posedge wrarst) begin if (wrarst) begin wrbin <= 0; wrgray <= 0; wrfull <= 1'b1; end else begin wrbin <= wrbin_next; wrgray <= wrgray_next; wrfull <= (wrgray_next == {sync_rdptr[RAM_ADDR_WIDTH] ^ 1'b1, sync_rdptr[RAM_ADDR_WIDTH-1] ^ 1'b1, sync_rdptr[RAM_ADDR_WIDTH-2:0]}); end end ////////////////////////////////////////// // domain synchronizers ////////////////////////////////////////// // stall the write a little more to give it time to settle in the RAM // before reporting over to the read side reg [RAM_ADDR_WIDTH:0] wrgray_rr; reg [RAM_ADDR_WIDTH:0] wrgray_r /* synthesis preserve */ /* synthesis ALTERA_ATTRIBUTE = "-name SDC_STATEMENT \"set_false_path -from [get_keepers *mlab_dcfifo*wrgray_r\[*\]]\" " */; always @(posedge wrclk or posedge wrarst) begin if (wrarst) begin wrgray_r <= 0; wrgray_rr <= 0; end else begin wrgray_rr <= wrgray; wrgray_r <= wrgray_rr; end end // stall the pointers randomly for faux domain crossing chatter wire [RAM_ADDR_WIDTH:0] wrgray_r_late, rdgray_late; generate if (SIM_DELAYS) begin random_delay rd0 ( .din(rdgray), .dout(rdgray_late) ); defparam rd0 .D_INCREMENT = 2; // stall by 0..7 increments defparam rd0 .WIDTH = RAM_ADDR_WIDTH+1; random_delay rd1 ( .din(wrgray_r), .dout(wrgray_r_late) ); defparam rd1 .D_INCREMENT = 20; defparam rd1 .WIDTH = RAM_ADDR_WIDTH+1; end else begin assign wrgray_r_late = wrgray_r; assign rdgray_late = rdgray; end endgenerate reg [SYNC_STAGES * (RAM_ADDR_WIDTH+1)-1:0] syn0 = 0 /* synthesis preserve */; always @(posedge wrclk or posedge wrarst) begin if (wrarst) syn0 <= 0; else syn0 <= {syn0[(SYNC_STAGES-1) * (RAM_ADDR_WIDTH+1)-1:0], rdgray}; end reg [SYNC_STAGES * (RAM_ADDR_WIDTH+1)-1:0] syn1 = 0 /* synthesis preserve */; always @(posedge rdclk or posedge rdarst) begin if (rdarst) syn1 <= 0; else syn1 <= {syn1[(SYNC_STAGES-1) * (RAM_ADDR_WIDTH+1)-1:0], wrgray_r}; end assign sync_rdptr = syn0[SYNC_STAGES * (RAM_ADDR_WIDTH+1)-1 : (SYNC_STAGES-1) * (RAM_ADDR_WIDTH+1)]; assign sync_wrptr = syn1[SYNC_STAGES * (RAM_ADDR_WIDTH+1)-1 : (SYNC_STAGES-1) * (RAM_ADDR_WIDTH+1)]; ////////////////////////////////////////// // storage array ////////////////////////////////////////// wire [LABS_WIDE-1:0] pein, peout; assign {parity_err,pein} = {peout,1'b0}; reg wer = 1'b0; //always @(posedge wrclk or posedge wrarst) begin // if (wrarst) wer <= 1'b0; // else wer <= wrreq & !wrfull; //end always @(*) begin wer = wrreq & !wrfull; end genvar i; generate for (i=0; i