data out: out
-percolate up: DDR2_CAS_B 1
-percolate up: DDR2_CKE 2
-percolate up: DDR2_RAS_B 1
-percolate up: DDR2_WE_B 1
-percolate up: DDR2_ODT 2
-percolate up: DDR2_CS0_B 2
-percolate up: DDR2_CLK_N 2
-percolate up: DDR2_CLK_P 2
-percolate up: DDR2_A 14
-percolate up: DDR2_BA 3
-percolate inout: DDR2_DQ 64
-percolate up: DDR2_DM 8
-percolate inout: DDR2_DQS_N 8
-percolate inout: DDR2_DQS_P 8
-
-percolate inout: I2C_DDR2_SCL 1
-percolate inout: I2C_DDR2_SDA 1
-
-percolate down: CLKBUF_Q1_N 1
-percolate down: CLKBUF_Q1_P 1
+percolate down: clk200_p 1
+
+percolate inout: ddr2_dq 64
+percolate inout: ddr2_dqs 8
+percolate inout: ddr2_dqs_n 8
+percolate up: ddr2_a 13
+percolate up: ddr2_ba 2
+percolate up: ddr2_ras_n 1
+percolate up: ddr2_cas_n 1
+percolate up: ddr2_we_n 1
+percolate up: ddr2_cs_n 1
+percolate up: ddr2_odt 1
+percolate up: ddr2_cke 1
+percolate up: ddr2_dm 8
+percolate up: ddr2_ck 2
+percolate up: ddr2_ck_n 2
== TeX ==============================================================
== FPGA ==============================================================
-// Nearly all of this was copied from Greg Gibeling's work; copyright shown below:
-
-// Everything here was copied from
-// GateLib/Firmware/DRAM/Hardware/DDR2SDRAM/Test/FPGA_TOP_ML505_DDR2SDRAMTest.v
-
-//==============================================================================
-// Section: License
-//==============================================================================
-// Copyright (c) 2005-2008, Regents of the University of California
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// - Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// - Neither the name of the University of California, Berkeley nor the
-// names of its contributors may be used to endorse or promote
-// products derived from this software without specific prior
-// written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//==============================================================================
-
-parameter
- ClockFreq = 200000000,
- BAWidth = 2,
- RAWidth = 13,
- CAWidth = 10,
- DWidth = 128, // 128b SDR internal transfers
- UWidth = 8, // This will almost ALWAYS be 8
- BurstLen = 2, // 256b total burst, 2 words DWidth words at SDR, or 4 external words at DDR
- EnableMask = 1,
- EnableECC = 0,
- Board = 0;
-
-localparam
- UCount = DWidth / UWidth,
- // 128b/8 = 16b per mask means per-byte masking
- MWidth = (EnableECC || (EnableMask == 0)) ? 0 : UCount,
- // Unused lower address bits, the -1 is to get a proper log2
- UAWidth = `log2(UCount-1),
- TAWidth = CAWidth + RAWidth + BAWidth,
- // Note that the components are in order according to where in the
- // address they appear, the -1 is to account for DDR
- AWidth = TAWidth + UAWidth - 1,
- ECheck = EnableECC ? 2 : 0,
- ECorrect = EnableECC ? 1 : 0,
- CWidth = 3,
- EHWidth = `max(`log2(ECheck), 1),
- ERWidth = `max(`log2(ECheck), 1);
-
-wire Reset;
-assign Reset = !rst;
-
-reg [AWidth-1:0] CommandAddress;
-reg [CWidth-1:0] Command;
-wire CommandReady;
-reg CommandValid;
-
-wire [DWidth-1:0] DataIn;
-wire [MWidth-1:0] DataInMask;
-reg DataInValid;
-wire DataInReady;
-
-wire [DWidth-1:0] DataOut;
-wire [EHWidth-1:0] DataOutErrorChecked;
-wire [ERWidth-1:0] DataOutErrorCorrected;
-wire DataOutValid;
-reg DataOutReady;
-
-wire Clock_IBUFG;
-wire Clock, ClockD2, ClockP90;
-wire Clock_DCM, ClockD2_DCM, ClockP90_DCM;
-wire Locked;
-
-reg [`WORDWIDTH:0] out_d;
+// clocking //////////////////////////////////////////////////////////////////////////////
+
+wire clk0;
+wire clkdiv0;
+wire clk0_unbuffered;
+wire clkdiv0_unbuffered;
+wire dcm_lock;
+
+BUFG clk200_p_buf (.I(clk200_p), .O(clk200_p_buffered));
+BUFG clk0_fb_buf (.I(clk0_unbuffered), .O(clk0_fb));
+BUFG clk0_fb_buf2 (.I(clk0_unbuffered), .O(clk0));
+BUFG clkdiv0_bufg (.I(clkdiv0_unbuffered), .O(clkdiv0));
+
+DCM
+ #(
+ .CLKIN_PERIOD (10.0),
+ .DLL_FREQUENCY_MODE ("LOW"),
+ .DUTY_CYCLE_CORRECTION ("TRUE"),
+ .CLKDV_DIVIDE (2),
+ .FACTORY_JF (16'hF0F0)
+ ) ddr2_dcm (
+ .CLKIN (clk),
+ .CLKFB (clk0_fb),
+ .CLKDV (clkdiv0_unbuffered),
+ .CLK0 (clk0_unbuffered),
+ .CLK90 (clk90),
+ .LOCKED (dcm_lock),
+ .RST (rst)
+ );
+
+// controller instance ////////////////////////////////////////////////////////////////////////
+
+wire phy_init_done;
+wire app_wdf_afull;
+wire app_af_afull;
+reg app_wdf_wren;
+reg [63:0] app_wdf_data;
+reg app_af_wren;
+reg [2:0] app_af_cmd;
+reg [30:0] app_af_addr;
+wire rd_data_valid;
+wire [63:0] rd_data_fifo_out;
+
+reg read_waiting;
+reg [7:0] mask;
+reg [6:0] burst_count;
+
+ddr2_sdram # (
+ .BANK_WIDTH(2), // # of memory bank addr bits.
+ .CKE_WIDTH(1), // # of memory clock enable outputs.
+ .CLK_WIDTH(2), // # of clock outputs.
+ .COL_WIDTH(10), // # of memory column bits.
+ .CS_NUM(1), // # of separate memory chip selects.
+ .CS_WIDTH(1), // # of total memory chip selects.
+ .CS_BITS(0), // set to log2(CS_NUM) (rounded up).
+ .DM_WIDTH(8), // # of data mask bits.
+ .DQ_WIDTH(64), // # of data width.
+ .DQ_PER_DQS(8), // # of DQ data bits per strobe.
+ .DQS_WIDTH(8), // # of DQS strobes.
+ .DQ_BITS(6), // set to log2(DQS_WIDTH*DQ_PER_DQS).
+ .DQS_BITS(3), // set to log2(DQS_WIDTH).
+ .ODT_WIDTH(1), // # of memory on-die term enables.
+ .ROW_WIDTH(13), // # of memory row and # of addr bits.
+ .ADDITIVE_LAT(0), // additive write latency.
+ .BURST_LEN(4), // burst length (in double words).
+ .BURST_TYPE(0), // burst type (=0 seq; =1 interleaved).
+ .CAS_LAT(3), // CAS latency.
+ .ECC_ENABLE(0), // enable ECC (=1 enable).
+ .APPDATA_WIDTH(128), // # of usr read/write data bus bits.
+ .MULTI_BANK_EN(1), // Keeps multiple banks open. (= 1 enable).
+ .TWO_T_TIME_EN(1), // 2t timing for unbuffered dimms.
+ .ODT_TYPE(1), // ODT (=0(none),=1(75),=2(150),=3(50)).
+ .REDUCE_DRV(0), // reduced strength mem I/O (=1 yes).
+ .REG_ENABLE(0), // registered addr/ctrl (=1 yes).
+ .TREFI_NS(7800), // auto refresh interval (ns).
+ .TRAS(40000), // active->precharge delay.
+ .TRCD(15000), // active->read/write delay.
+ .TRFC(105000), // refresh->refresh, refresh->active delay.
+ .TRP(15000), // precharge->command delay.
+ .TRTP(7500), // read->precharge delay.
+ .TWR(15000), // used to determine write->precharge.
+ .TWTR(7500), // write->read delay.
+ .HIGH_PERFORMANCE_MODE("TRUE"), // # = TRUE, the IODELAY performance mode is set to high.
+ // # = FALSE, the IODELAY performance mode is set to low.
+ .SIM_ONLY(0), // = 1 to skip SDRAM power up delay.
+ .DEBUG_EN(0), // Enable debug signals/controls.
+ // When this parameter is changed from 0 to 1,
+ // make sure to uncomment the coregen commands
+ // in ise_flow.bat or create_ise.bat files in
+ // par folder.
+ .CLK_PERIOD(10000), // Core/Memory clock period (in ps).
+ .DQS_IO_COL(16'b0000000000000000), // I/O column location of DQS groups
+ // (=0, left; =1 center, =2 right).
+ .DQ_IO_MS(64'b01110101_00111101_00001111_00011110_00101110_11000011_11000001_10111100),
+ // Master/Slave location of DQ I/O (=0 slave).
+ .RST_ACT_LOW(1) // =1 for active low reset, =0 for active high.
+) ddr2_sdram (
+ .sys_rst_n (!rst),
+
+ .ddr2_dq (ddr2_dq),
+ .ddr2_a (ddr2_a),
+ .ddr2_ba (ddr2_ba),
+ .ddr2_ras_n (ddr2_ras_n),
+ .ddr2_cas_n (ddr2_cas_n),
+ .ddr2_we_n (ddr2_we_n),
+ .ddr2_cs_n (ddr2_cs_n),
+ .ddr2_odt (ddr2_odt),
+ .ddr2_cke (ddr2_cke),
+ .ddr2_dm (ddr2_dm),
+ .ddr2_dqs (ddr2_dqs),
+ .ddr2_dqs_n (ddr2_dqs_n),
+ .ddr2_ck (ddr2_ck),
+ .ddr2_ck_n (ddr2_ck_n),
+
+ .phy_init_done (phy_init_done),
+
+ .app_wdf_afull (app_wdf_afull),
+ .app_af_afull (app_af_afull),
+ .rd_data_valid (rd_data_valid),
+ .rd_data_fifo_out (rd_data_fifo_out),
+
+ .app_wdf_wren ((~phy_init_done) ? 0 : app_wdf_wren),
+ .app_wdf_data ((~phy_init_done) ? 0 : app_wdf_data),
+ .app_wdf_mask_data ((~phy_init_done) ? 0 : mask),
+
+ .app_af_wren ((~phy_init_done) ? 0 : app_af_wren),
+ .app_af_cmd (app_af_cmd),
+ .app_af_addr (app_af_addr),
+
+ .dcm_lock (dcm_lock),
+ .clk0 (clk0),
+ .clk90 (clk90),
+ .clkdiv0 (clkdiv0),
+
+ .clk200 (clk200_p_buffered)
+ );
+
+// custom code //////////////////////////////////////////////////////////////////////////////
+
+reg [37:0] out_d;
assign out_d_ = out_d;
-assign DDR2_BA[2] = 1'b0;
-assign DDR2_CS0_B[1] = 1'b1;
-assign DDR2_ODT[1] = 1'b0;
-assign DDR2_CKE[1] = 1'b0;
-
-IBUFGDS ClockIBufG(.I(CLKBUF_Q1_P), .IB(CLKBUF_Q1_N), .O(Clock_IBUFG));
-DCM_BASE
- #(
- .CLKIN_PERIOD(5.0),
- .CLKDV_DIVIDE(2.0),
- .DLL_FREQUENCY_MODE("HIGH"),
- .DUTY_CYCLE_CORRECTION("TRUE"),
- .FACTORY_JF(16'hF0F0)
- )
- DCMBase(
- .CLK0(Clock_DCM),
- .CLK180( ),
- .CLK270( ),
- .CLK2X( ),
- .CLK2X180( ),
- .CLK90(ClockP90_DCM),
- .CLKDV(ClockD2_DCM),
- .CLKFX( ),
- .CLKFX180( ),
- .LOCKED(Locked),
- .CLKFB(Clock),
- .CLKIN(Clock_IBUFG),
- .RST(Reset));
- // synthesis attribute CLKIN_PERIOD of DCMBase is "5.0"
- // synthesis attribute CLKDV_DIVIDE of DCMBase is "2.0"
- // synthesis attribute DLL_FREQUENCY_MODE of DCMBase is "HIGH"
- // synthesis attribute DUTY_CYCLE_CORRECTION of DCMBase is "TRUE"
- // synthesis attribute FACTORY_JF of DCMBase is "16'hF0F0"
- BUFG ClockBufG(.I(Clock_DCM), .O(Clock));
- BUFG ClockP90BufG(.I(ClockP90_DCM), .O(ClockP90));
- BUFG ClockD2BufG(.I(ClockD2_DCM), .O(ClockD2));
-
-DDR2SDRAM DDR2SDRAM(
- .Clock(Clock),
- .ClockD2(ClockD2),
- .ClockP90(ClockP90),
- .Reset(Reset),
- .Locked(Locked),
- .ClockF200(Clock),
- .Initialized( ),
- .PoweredUp( ),
-
- .CommandClock(clk),
- .DataInClock(clk),
- .DataOutClock(clk),
- .CommandReset(Reset),
- .DataInReset(Reset),
- .DataOutReset(Reset),
-
- .CommandAddress(CommandAddress),
- .Command(Command),
- .CommandValid(CommandValid),
- .CommandReady(CommandReady),
- .DataIn(DataIn),
- .DataInMask(DataInMask),
- .DataInValid(DataInValid),
- .DataInReady(DataInReady),
- .DataOut(DataOut),
- .DataOutErrorChecked(DataOutErrorChecked),
- .DataOutErrorCorrected(DataOutErrorCorrected),
- .DataOutValid(DataOutValid),
- .DataOutReady(DataOutReady),
- .DDR2_DQ(DDR2_DQ),
- .DDR2_A(DDR2_A),
- .DDR2_BA(DDR2_BA[1:0]),
- .DDR2_RAS_B(DDR2_RAS_B),
- .DDR2_CAS_B(DDR2_CAS_B),
- .DDR2_WE_B(DDR2_WE_B),
- .DDR2_CS0_B(DDR2_CS0_B[0]),
- .DDR2_ODT(DDR2_ODT[0]),
- .DDR2_CKE(DDR2_CKE[0]),
- .DDR2_DM(DDR2_DM),
- .DDR2_DQS_P(DDR2_DQS_P),
- .DDR2_DQS_N(DDR2_DQS_N),
- .DDR2_CLK_P(DDR2_CLK_P),
- .DDR2_CLK_N(DDR2_CLK_N));
- defparam DDR2SDRAM.UWidth = UWidth;
- defparam DDR2SDRAM.BAWidth = BAWidth;
- defparam DDR2SDRAM.RAWidth = RAWidth;
- defparam DDR2SDRAM.CAWidth = CAWidth;
- defparam DDR2SDRAM.DWidth = DWidth;
- defparam DDR2SDRAM.BurstLen = BurstLen;
- defparam DDR2SDRAM.EnableMask = EnableMask;
- defparam DDR2SDRAM.EnableECC = EnableECC;
- defparam DDR2SDRAM.Board = Board;
- defparam DDR2SDRAM.MultiClock = 1;
-
- assign DataIn = inDataWrite_d;
- assign DataInMask = 16'b1111111111111111;
-
- always @(posedge clk) begin
-
- if (!rst) begin
- `reset
- CommandValid <= 0;
- DataOutReady <= 0;
- end else begin
- `flush
- `cleanup
-
- CommandValid <= 0;
- DataInValid <= 0;
-
- if (`out_empty) begin
- DataOutReady <= 1;
- end
+// grossly inefficient -- always uses only the first word of a burst!
+always @(posedge clk) begin
+ if (rst) begin
+ `reset
+ app_wdf_wren <= 0;
+ app_af_wren <= 0;
+ read_waiting <= 0;
+ burst_count <= 0;
+
+ end else begin
+ `cleanup
+
+ mask <= 8'b11111111;
+ if (burst_count == 0 || burst_count == 1) begin
+ app_wdf_wren <= 0;
+ app_af_wren <= 0;
+ end else if ((burst_count > 1) && (app_af_cmd == 3'b000)) begin
+ app_af_wren <= ~burst_count[0];
+ end
- if (DataOutReady && DataOutValid && `out_empty) begin
- out_d <= { 1'b0, DataOut[`WORDWIDTH-1:0] };
- `fill_out
- DataOutReady <= 0;
-
- end else if (DataOutReady && CommandReady && DataInReady && `out_empty) begin
- if (`inAddrWrite_full && `inDataWrite_full) begin
- `drain_inDataWrite
- `drain_inAddrWrite
- CommandAddress <= inAddrWrite_d;
- Command <= 3'b000;
- CommandValid <= 1;
- DataInValid <= 1;
- out_d <= { 1'b1, 37'b0 };
- `fill_out
- DataOutReady <= 0;
- end else if (`inAddrRead_full) begin
- `drain_inAddrRead
- CommandAddress <= inAddrRead_d;
- CommandValid <= 1;
- Command <= 3'b001;
- DataInValid <= 0;
- DataOutReady <= 1;
- end
+ if (burst_count > 0) begin
+ burst_count <= burst_count - 1;
+ end else if ((~read_waiting) && rd_data_valid) begin
+ /* wait */
+ end else if (read_waiting) begin
+ if (rd_data_valid) begin
+ read_waiting <= 0;
+ out_d <= { 1'b0, rd_data_fifo_out[36:0] };
+ `fill_out
end
+ end else if (app_wdf_afull || app_af_afull) begin
+ /* wait */
+ end else if (`inAddrWrite_full && `inDataWrite_full && `out_empty) begin
+ `drain_inDataWrite
+ `drain_inAddrWrite
+ app_wdf_data <= inDataWrite_d;
+ app_af_addr <= { inAddrWrite_d, 2'b00 };
+ app_af_cmd <= 3'b000;
+ app_af_wren <= 1;
+ app_wdf_wren <= 1;
+ burst_count <= 7;
+ out_d <= { 1'b1, 37'b0 };
+ mask <= 8'b00000000;
+ `fill_out
+ end else if (`inAddrRead_full && `out_empty) begin
+ `drain_inAddrRead
+ app_af_addr <= { inAddrRead_d, 2'b00 };
+ app_af_cmd <= 3'b001;
+ app_af_wren <= 1;
+ burst_count <= 3;
+ read_waiting <= 1;
end
end
+end
+
+== UCF ==============================================================
+
+Net clk200_p PERIOD = 5 ns HIGH 50%; # 200Mhz
+
+#NET "*/u_ddr2_infrastructure/sys_clk_ibufg" TNM_NET = "SYS_CLK";
+Net "ddr2_0/clk0" TNM_NET = "SYS_CLK";
+TIMESPEC "TS_SYS_CLK" = PERIOD "SYS_CLK" 10 ns HIGH 50 %;
+
+#NET "*/u_ddr2_infrastructure/clk200_ibufg" TNM_NET = "SYS_CLK_200";
+Net clk200_p TNM_NET = "SYS_CLK_200";
+TIMESPEC "TS_SYS_CLK_200" = PERIOD "SYS_CLK_200" 5 ns HIGH 50 %;
+
+# suggested by
+# http://www.xilinx.com/support/answers/31606.htm
+# NET "clk_0" TNM_NET = "SYS_clk_0";
+# TIMESPEC "TS_SYS_clk_0" = PERIOD "SYS_clk_0" 5 ns HIGH 50 %;
+# NET "clk_90" TNM_NET = "SYS_clk_90";
+# TIMESPEC "TS_SYS_clk_90" = PERIOD "SYS_clk_90" "TS_SYS_clk_0" PHASE 1.25 ns HIGH 50 %;
+
+################################################################################
+# I/O STANDARDS
+################################################################################
+
+NET "ddr2_dq[*]" IOSTANDARD = SSTL18_II_DCI;
+NET "ddr2_a[*]" IOSTANDARD = SSTL18_II;
+NET "ddr2_ba[*]" IOSTANDARD = SSTL18_II;
+NET "ddr2_ras_n" IOSTANDARD = SSTL18_II;
+NET "ddr2_cas_n" IOSTANDARD = SSTL18_II;
+NET "ddr2_we_n" IOSTANDARD = SSTL18_II;
+NET "ddr2_cs_n" IOSTANDARD = SSTL18_II;
+NET "ddr2_odt" IOSTANDARD = SSTL18_II;
+NET "ddr2_cke" IOSTANDARD = SSTL18_II;
+NET "ddr2_dm[*]" IOSTANDARD = SSTL18_II;
+#NET "sys_clk_p" IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
+#NET "sys_clk_n" IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
+#NET "clk200_p" IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
+#NET "clk200_n" IOSTANDARD = LVDS_25 | DIFF_TERM = TRUE;
+#NET "sys_rst_n" IOSTANDARD = LVCMOS18;
+#NET "phy_init_done" IOSTANDARD = LVCMOS18;
+#NET "error" IOSTANDARD = LVCMOS18;
+NET "ddr2_dqs[*]" IOSTANDARD = DIFF_SSTL18_II_DCI;
+NET "ddr2_dqs_n[*]" IOSTANDARD = DIFF_SSTL18_II_DCI;
+NET "ddr2_ck[*]" IOSTANDARD = DIFF_SSTL18_II;
+NET "ddr2_ck_n[*]" IOSTANDARD = DIFF_SSTL18_II;
+
+################################################################################
+# Location Constraints
+################################################################################
+
+NET "ddr2_dq[0]" LOC = "AF30" ; #Bank 17
+NET "ddr2_dq[1]" LOC = "AK31" ; #Bank 17
+NET "ddr2_dq[2]" LOC = "AF31" ; #Bank 17
+NET "ddr2_dq[3]" LOC = "AD30" ; #Bank 17
+NET "ddr2_dq[4]" LOC = "AJ30" ; #Bank 17
+NET "ddr2_dq[5]" LOC = "AF29" ; #Bank 17
+NET "ddr2_dq[6]" LOC = "AD29" ; #Bank 17
+NET "ddr2_dq[7]" LOC = "AE29" ; #Bank 17
+NET "ddr2_dq[8]" LOC = "AH27" ; #Bank 21
+NET "ddr2_dq[9]" LOC = "AF28" ; #Bank 21
+NET "ddr2_dq[10]" LOC = "AH28" ; #Bank 21
+NET "ddr2_dq[11]" LOC = "AA28" ; #Bank 21
+NET "ddr2_dq[12]" LOC = "AG25" ; #Bank 21
+NET "ddr2_dq[13]" LOC = "AJ26" ; #Bank 21
+NET "ddr2_dq[14]" LOC = "AG28" ; #Bank 21
+NET "ddr2_dq[15]" LOC = "AB28" ; #Bank 21
+NET "ddr2_dq[16]" LOC = "AC28" ; #Bank 21
+NET "ddr2_dq[17]" LOC = "AB25" ; #Bank 21
+NET "ddr2_dq[18]" LOC = "AC27" ; #Bank 21
+NET "ddr2_dq[19]" LOC = "AA26" ; #Bank 21
+NET "ddr2_dq[20]" LOC = "AB26" ; #Bank 21
+NET "ddr2_dq[21]" LOC = "AA24" ; #Bank 21
+NET "ddr2_dq[22]" LOC = "AB27" ; #Bank 21
+NET "ddr2_dq[23]" LOC = "AA25" ; #Bank 21
+NET "ddr2_dq[24]" LOC = "AC29" ; #Bank 17
+NET "ddr2_dq[25]" LOC = "AB30" ; #Bank 17
+NET "ddr2_dq[26]" LOC = "W31" ; #Bank 17
+NET "ddr2_dq[27]" LOC = "V30" ; #Bank 17
+NET "ddr2_dq[28]" LOC = "AC30" ; #Bank 17
+NET "ddr2_dq[29]" LOC = "W29" ; #Bank 17
+NET "ddr2_dq[30]" LOC = "V27" ; #Bank 17
+NET "ddr2_dq[31]" LOC = "W27" ; #Bank 17
+NET "ddr2_dq[32]" LOC = "V29" ; #Bank 17
+NET "ddr2_dq[33]" LOC = "Y27" ; #Bank 17
+NET "ddr2_dq[34]" LOC = "Y26" ; #Bank 17
+NET "ddr2_dq[35]" LOC = "W24" ; #Bank 17
+NET "ddr2_dq[36]" LOC = "V28" ; #Bank 17
+NET "ddr2_dq[37]" LOC = "W25" ; #Bank 17
+NET "ddr2_dq[38]" LOC = "W26" ; #Bank 17
+NET "ddr2_dq[39]" LOC = "V24" ; #Bank 17
+NET "ddr2_dq[40]" LOC = "R24" ; #Bank 19
+NET "ddr2_dq[41]" LOC = "P25" ; #Bank 19
+NET "ddr2_dq[42]" LOC = "N24" ; #Bank 19
+NET "ddr2_dq[43]" LOC = "P26" ; #Bank 19
+NET "ddr2_dq[44]" LOC = "T24" ; #Bank 19
+NET "ddr2_dq[45]" LOC = "N25" ; #Bank 19
+NET "ddr2_dq[46]" LOC = "P27" ; #Bank 19
+NET "ddr2_dq[47]" LOC = "N28" ; #Bank 19
+NET "ddr2_dq[48]" LOC = "M28" ; #Bank 19
+NET "ddr2_dq[49]" LOC = "L28" ; #Bank 19
+NET "ddr2_dq[50]" LOC = "F25" ; #Bank 19
+NET "ddr2_dq[51]" LOC = "H25" ; #Bank 19
+NET "ddr2_dq[52]" LOC = "K27" ; #Bank 19
+NET "ddr2_dq[53]" LOC = "K28" ; #Bank 19
+NET "ddr2_dq[54]" LOC = "H24" ; #Bank 19
+NET "ddr2_dq[55]" LOC = "G26" ; #Bank 19
+NET "ddr2_dq[56]" LOC = "G25" ; #Bank 19
+NET "ddr2_dq[57]" LOC = "M26" ; #Bank 19
+NET "ddr2_dq[58]" LOC = "J24" ; #Bank 19
+NET "ddr2_dq[59]" LOC = "L26" ; #Bank 19
+NET "ddr2_dq[60]" LOC = "J27" ; #Bank 19
+NET "ddr2_dq[61]" LOC = "M25" ; #Bank 19
+NET "ddr2_dq[62]" LOC = "L25" ; #Bank 19
+NET "ddr2_dq[63]" LOC = "L24" ; #Bank 19
+NET "ddr2_a[12]" LOC = "T31" ; #Bank 15
+NET "ddr2_a[11]" LOC = "R29" ; #Bank 15
+NET "ddr2_a[10]" LOC = "J31" ; #Bank 15
+NET "ddr2_a[9]" LOC = "R28" ; #Bank 15
+NET "ddr2_a[8]" LOC = "M31" ; #Bank 15
+NET "ddr2_a[7]" LOC = "P30" ; #Bank 15
+NET "ddr2_a[6]" LOC = "P31" ; #Bank 15
+NET "ddr2_a[5]" LOC = "L31" ; #Bank 15
+NET "ddr2_a[4]" LOC = "K31" ; #Bank 15
+NET "ddr2_a[3]" LOC = "P29" ; #Bank 15
+NET "ddr2_a[2]" LOC = "N29" ; #Bank 15
+NET "ddr2_a[1]" LOC = "M30" ; #Bank 15
+NET "ddr2_a[0]" LOC = "L30" ; #Bank 15
+NET "ddr2_ba[1]" LOC = "J30" ; #Bank 15
+NET "ddr2_ba[0]" LOC = "G31" ; #Bank 15
+NET "ddr2_ras_n" LOC = "H30" ; #Bank 15
+NET "ddr2_cas_n" LOC = "E31" ; #Bank 15
+NET "ddr2_we_n" LOC = "K29" ; #Bank 15
+NET "ddr2_cs_n" LOC = "L29" ; #Bank 15
+NET "ddr2_odt" LOC = "F31" ; #Bank 15
+NET "ddr2_cke" LOC = "T28" ; #Bank 15
+NET "ddr2_cke[1]" LOC = "U30" ;
+NET "ddr2_dm[0]" LOC = "AJ31" ; #Bank 17
+NET "ddr2_dm[1]" LOC = "AE28" ; #Bank 21
+NET "ddr2_dm[2]" LOC = "Y24" ; #Bank 21
+NET "ddr2_dm[3]" LOC = "Y31" ; #Bank 17
+NET "ddr2_dm[4]" LOC = "V25" ; #Bank 17
+NET "ddr2_dm[5]" LOC = "P24" ; #Bank 19
+NET "ddr2_dm[6]" LOC = "F26" ; #Bank 19
+NET "ddr2_dm[7]" LOC = "J25" ; #Bank 19
+NET "sys_clk_p" LOC = "H14" ; #Bank 3
+NET "sys_clk_n" LOC = "H15" ; #Bank 3
+NET "clk200_p" LOC = "L19" ; #Bank 3
+NET "clk200_n" LOC = "K19" ; #Bank 3
+NET "sys_rst_n" LOC = "E9"; #Bank 20
+#NET "phy_init_done" LOC = "H18" ; #Bank 3
+NET "error" LOC = "F6"; #Bank 12
+NET "ddr2_dqs[0]" LOC = "AA29" ; #Bank 17
+NET "ddr2_dqs_n[0]" LOC = "AA30" ; #Bank 17
+NET "ddr2_dqs[1]" LOC = "AK28" ; #Bank 21
+NET "ddr2_dqs_n[1]" LOC = "AK27" ; #Bank 21
+NET "ddr2_dqs[2]" LOC = "AK26" ; #Bank 21
+NET "ddr2_dqs_n[2]" LOC = "AJ27" ; #Bank 21
+NET "ddr2_dqs[3]" LOC = "AB31" ; #Bank 17
+NET "ddr2_dqs_n[3]" LOC = "AA31" ; #Bank 17
+NET "ddr2_dqs[4]" LOC = "Y28" ; #Bank 17
+NET "ddr2_dqs_n[4]" LOC = "Y29" ; #Bank 17
+NET "ddr2_dqs[5]" LOC = "E26" ; #Bank 19
+NET "ddr2_dqs_n[5]" LOC = "E27" ; #Bank 19
+NET "ddr2_dqs[6]" LOC = "H28" ; #Bank 19
+NET "ddr2_dqs_n[6]" LOC = "G28" ; #Bank 19
+NET "ddr2_dqs[7]" LOC = "G27" ; #Bank 19
+NET "ddr2_dqs_n[7]" LOC = "H27" ; #Bank 19
+NET "ddr2_ck[0]" LOC = "AK29" ; #Bank 21
+NET "ddr2_ck_n[0]" LOC = "AJ29" ; #Bank 21
+NET "ddr2_ck[1]" LOC = "E28" ; #Bank 19
+NET "ddr2_ck_n[1]" LOC = "F28" ; #Bank 19
+
+################################################################################
+#IDELAYCTRL Location Constraints
+################################################################################
+
+INST "*/IDELAYCTRL_INST[0].u_idelayctrl" LOC=IDELAYCTRL_X0Y1;
+INST "*/IDELAYCTRL_INST[1].u_idelayctrl" LOC=IDELAYCTRL_X0Y2;
+INST "*/IDELAYCTRL_INST[2].u_idelayctrl" LOC=IDELAYCTRL_X0Y6;
+
+###############################################################################
+# Define multicycle paths - these paths may take longer because additional
+# time allowed for logic to settle in calibration/initialization FSM
+###############################################################################
+
+# MIG 2.1: Eliminate Timegroup definitions for CLK0, and CLK90. Instead trace
+# multicycle paths from originating flip-flop to ANY destination
+# flip-flop (or in some cases, it can also be a BRAM)
+# MUX Select for either rising/falling CLK0 for 2nd stage read capture
+INST "*/u_phy_calib/gen_rd_data_sel*.u_ff_rd_data_sel" TNM = "TNM_RD_DATA_SEL";
+TIMESPEC "TS_MC_RD_DATA_SEL" = FROM "TNM_RD_DATA_SEL" TO FFS
+"TS_SYS_CLK" * 4;
+# MUX select for read data - optional delay on data to account for byte skews
+#INST "*/u_usr_rd/gen_rden_sel_mux*.u_ff_rden_sel_mux" TNM = "TNM_RDEN_SEL_MUX";
+#TIMESPEC "TS_MC_RDEN_SEL_MUX" = FROM "TNM_RDEN_SEL_MUX" TO FFS
+#"TS_SYS_CLK" * 4;
+# Calibration/Initialization complete status flag (for PHY logic only) - can
+# be used to drive both flip-flops and BRAMs
+INST "*/u_phy_init/u_ff_phy_init_data_sel" TNM = "TNM_PHY_INIT_DATA_SEL";
+TIMESPEC "TS_MC_PHY_INIT_DATA_SEL_0" = FROM "TNM_PHY_INIT_DATA_SEL" TO FFS
+"TS_SYS_CLK" * 4;
+TIMESPEC "TS_MC_PHY_INIT_DATA_SEL_90" = FROM "TNM_PHY_INIT_DATA_SEL" TO RAMS
+"TS_SYS_CLK" * 4;
+# Select (address) bits for SRL32 shift registers used in stage3/stage4
+# calibration
+INST "*/u_phy_calib/gen_gate_dly*.u_ff_gate_dly" TNM = "TNM_GATE_DLY";
+TIMESPEC "TS_MC_GATE_DLY" = FROM "TNM_GATE_DLY" TO FFS "TS_SYS_CLK" * 4;
+#INST "*/u_phy_calib/gen_rden_dly*.u_ff_rden_dly" TNM = "TNM_RDEN_DLY";
+#TIMESPEC "TS_MC_RDEN_DLY" = FROM "TNM_RDEN_DLY" TO FFS "TS_SYS_CLK" * 4;
+INST "*/u_phy_calib/gen_cal_rden_dly*.u_ff_cal_rden_dly"
+ TNM = "TNM_CAL_RDEN_DLY";
+TIMESPEC "TS_MC_CAL_RDEN_DLY" = FROM "TNM_CAL_RDEN_DLY" TO FFS
+ "TS_SYS_CLK" * 4;
+
+###############################################################################
+# DQS Read Post amble Glitch Squelch circuit related constraints
+###############################################################################
+
+###############################################################################
+# LOC placement of DQS-squelch related IDDR and IDELAY elements
+# Each circuit can be located at any of the following locations:
+# 1. Unused "N"-side of DQS differential pair I/O
+# 2. DM data mask (output only, input side is free for use)
+# 3. Any output-only site
+###############################################################################
+
+INST "*/gen_dqs[0].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y96";
+INST "*/gen_dqs[0].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y96";
+INST "*/gen_dqs[1].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y58";
+INST "*/gen_dqs[1].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y58";
+INST "*/gen_dqs[2].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y62";
+INST "*/gen_dqs[2].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y62";
+INST "*/gen_dqs[3].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y100";
+INST "*/gen_dqs[3].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y100";
+INST "*/gen_dqs[4].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y102";
+INST "*/gen_dqs[4].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y102";
+INST "*/gen_dqs[5].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y256";
+INST "*/gen_dqs[5].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y256";
+INST "*/gen_dqs[6].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y260";
+INST "*/gen_dqs[6].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y260";
+INST "*/gen_dqs[7].u_iob_dqs/u_iddr_dq_ce" LOC = "ILOGIC_X0Y262";
+INST "*/gen_dqs[7].u_iob_dqs/u_iodelay_dq_ce" LOC = "IODELAY_X0Y262";
+
+###############################################################################
+# LOC and timing constraints for flop driving DQS CE enable signal
+# from fabric logic. Even though the absolute delay on this path is
+# calibrated out (when synchronizing this output to DQS), the delay
+# should still be kept as low as possible to reduce post-calibration
+# voltage/temp variations - these are roughly proportional to the
+# absolute delay of the path
+###############################################################################
+
+INST "*/u_phy_calib/gen_gate[0].u_en_dqs_ff" LOC = SLICE_X0Y48;
+INST "*/u_phy_calib/gen_gate[1].u_en_dqs_ff" LOC = SLICE_X0Y29;
+INST "*/u_phy_calib/gen_gate[2].u_en_dqs_ff" LOC = SLICE_X0Y31;
+INST "*/u_phy_calib/gen_gate[3].u_en_dqs_ff" LOC = SLICE_X0Y50;
+INST "*/u_phy_calib/gen_gate[4].u_en_dqs_ff" LOC = SLICE_X0Y51;
+INST "*/u_phy_calib/gen_gate[5].u_en_dqs_ff" LOC = SLICE_X0Y128;
+INST "*/u_phy_calib/gen_gate[6].u_en_dqs_ff" LOC = SLICE_X0Y130;
+INST "*/u_phy_calib/gen_gate[7].u_en_dqs_ff" LOC = SLICE_X0Y131;
+
+# Control for DQS gate - from fabric flop. Prevent "runaway" delay -
+# two parts to this path: (1) from fabric flop to IDELAY, (2) from
+# IDELAY to asynchronous reset of IDDR that drives the DQ CE's
+# This can be relaxed by the user for lower frequencies:
+# 300MHz = 850ps, 267MHz = 900ps. At 200MHz = 950ps.
+# In general PAR should be able to route this
+# within 900ps over all speed grades.
+NET "*/u_phy_io/en_dqs*" MAXDELAY = 600 ps;
+NET "*/u_phy_io/gen_dqs*.u_iob_dqs/en_dqs_sync" MAXDELAY = 850 ps;
+
+###############################################################################
+# "Half-cycle" path constraint from IDDR to CE pin for all DQ IDDR's
+# for DQS Read Post amble Glitch Squelch circuit
+###############################################################################
+
+# Max delay from output of IDDR to CE input of DQ IDDRs = tRPST + some slack
+# where slack account for rise-time of DQS on board. For now assume slack =
+# 0.400ns (based on initial SPICE simulations, assumes use of ODT), so
+# time = 0.4*Tcyc + 0.40ns = 1.6ns @333MHz
+INST "*/gen_dqs[*].u_iob_dqs/u_iddr_dq_ce" TNM = "TNM_DQ_CE_IDDR";
+INST "*/gen_dq[*].u_iob_dq/gen_stg2_*.u_iddr_dq" TNM = "TNM_DQS_FLOPS";
+TIMESPEC "TS_DQ_CE" = FROM "TNM_DQ_CE_IDDR" TO "TNM_DQS_FLOPS" 1.9 ns;
+
+###############################################################################
+# MIG 2.2: Prevent unrelated logic from being packed into any slices used
+# by read data capture RPM's - if unrelated logic gets packed into
+# these slices, it could cause the DIRT strings that define the
+# IDDR -> fabric flop routing to become unroutable during PAR stage
+# (unrelated logic may require routing resources required by the
+# DIRT strings - MAP does not currently take into account DIRT
+# strings when placing logic
+###############################################################################
+
+AREA_GROUP "DDR_CAPTURE_FFS" GROUP = CLOSED;
+
+###############################################################################
+# Location constraints for DQ read-data capture flops in fabric (for 2nd
+# stage capture)
+###############################################################################
+
+INST "*/gen_dq[0].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y42; # AF30 X0Y22 *
+INST "*/gen_dq[1].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y43; # AK31 X0Y23
+INST "*/gen_dq[2].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y45; # AF31 X0Y25
+INST "*/gen_dq[3].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y46; # AD30 X0Y26
+INST "*/gen_dq[4].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y41; # AJ30 X0Y21
+INST "*/gen_dq[5].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y42; # AF29 X0Y22 ***
+INST "*/gen_dq[6].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y44; # AD29 X0Y24
+INST "*/gen_dq[7].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y44; # AE29 X0Y24
+INST "*/gen_dq[8].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y28; # AH27 X0Y8 ***
+INST "*/gen_dq[9].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y32; # AF28 X0Y12
+INST "*/gen_dq[10].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y33; # AH28 X0Y13
+INST "*/gen_dq[11].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y34; # AA28 X0Y14
+INST "*/gen_dq[12].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y26; # AG25 X0Y6
+INST "*/gen_dq[13].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y28; # AJ26 X0Y8 *
+INST "*/gen_dq[14].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y33; # AG28 X0Y13
+INST "*/gen_dq[15].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y34; # AB28 X0Y14
+INST "*/gen_dq[16].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y35; # AC28 X0Y15
+INST "*/gen_dq[17].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y36; # AB25 X0Y16 ***
+INST "*/gen_dq[18].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y38; # AC27 X0Y18
+INST "*/gen_dq[19].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y39; # AA26 X0Y19
+INST "*/gen_dq[20].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y36; # AB26 X0Y16 *
+INST "*/gen_dq[21].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y37; # AA24 X0Y17
+INST "*/gen_dq[22].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y38; # AB27 X0Y18
+INST "*/gen_dq[23].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y39; # AA25 X0Y19
+INST "*/gen_dq[24].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y46; # AC29 X0Y26
+INST "*/gen_dq[25].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y49; # AB30 X0Y29 ***
+INST "*/gen_dq[26].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y53; # W31 X0Y33
+INST "*/gen_dq[27].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y55; # V30 X0Y35
+INST "*/gen_dq[28].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y49; # AC30 X0Y29 *
+INST "*/gen_dq[29].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y52; # W29 X0Y32
+INST "*/gen_dq[30].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y54; # V27 X0Y34 ***
+INST "*/gen_dq[31].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y56; # W27 X0Y36
+INST "*/gen_dq[32].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y52; # V29 X0Y32
+INST "*/gen_dq[33].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y56; # Y27 X0Y36
+INST "*/gen_dq[34].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y58; # Y26 X0Y38
+INST "*/gen_dq[35].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y59; # W24 X0Y39
+INST "*/gen_dq[36].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y54; # V28 X0Y34 *
+INST "*/gen_dq[37].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y57; # W25 X0Y37
+INST "*/gen_dq[38].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y58; # W26 X0Y38
+INST "*/gen_dq[39].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y59; # V24 X0Y39
+INST "*/gen_dq[40].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y120; # R24 X0Y100
+INST "*/gen_dq[41].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y121; # P25 X0Y101
+INST "*/gen_dq[42].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y122; # N24 X0Y102
+INST "*/gen_dq[43].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y123; # P26 X0Y103
+INST "*/gen_dq[44].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y120; # T24 X0Y100
+INST "*/gen_dq[45].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y121; # N25 X0Y101
+INST "*/gen_dq[46].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y123; # P27 X0Y103
+INST "*/gen_dq[47].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y124; # N28 X0Y104
+INST "*/gen_dq[48].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y124; # M28 X0Y104
+INST "*/gen_dq[49].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y126; # L28 X0Y106
+INST "*/gen_dq[50].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y132; # F25 X0Y112
+INST "*/gen_dq[51].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y133; # H25 X0Y113
+INST "*/gen_dq[52].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y125; # K27 X0Y105
+INST "*/gen_dq[53].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y126; # K28 X0Y106
+INST "*/gen_dq[54].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y133; # H24 X0Y113
+INST "*/gen_dq[55].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y134; # G26 X0Y114
+INST "*/gen_dq[56].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y134; # G25 X0Y114
+INST "*/gen_dq[57].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y136; # M26 X0Y116
+INST "*/gen_dq[58].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y137; # J24 X0Y117
+INST "*/gen_dq[59].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y138; # L26 X0Y118
+INST "*/gen_dq[60].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y135; # J27 X0Y115
+INST "*/gen_dq[61].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y136; # M25 X0Y116
+INST "*/gen_dq[62].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y138; # L25 X0Y118
+INST "*/gen_dq[63].u_iob_dq/gen_stg2_*.u_ff_stg2a_rise" RLOC_ORIGIN = X0Y139; # L24 X0Y119
-== Test ==============================================================
-#expect 0
+== Test ==============================================================
+#expect 20
+#expect 16
+#expect 12
#ship debug : Debug
#ship ddr : DDR2
debug.in:
- recv, deliver;
+ set ilc=*; recv, deliver;
ddr.out:
- collect;
- set flags a=!c,b=b;
- send to debug.in;
- collect;
- set flags a=!c,b=b;
- send to debug.in;
-ddr.inAddrWrite:
- set word=0;
- deliver;
- deliver;
-ddr.inDataWrite:
- set word=1;
- deliver;
- deliver;
+ set ilc=3; collect;
+ send token to ddr.inAddrRead;
+ set ilc=3; collect, send to debug.in;
+ddr.inAddrWrite:
+ set word= 0x1; deliver;
+ set word= 0x10; deliver;
+ set word=0x100; deliver;
+ddr.inDataWrite:
+ set word=20; deliver;
+ set word=16; deliver;
+ set word=12; deliver;
+
+ddr.inAddrRead:
+ recv token;
+ set word= 0x1; deliver;
+ set word= 0x10; deliver;
+ set word=0x100; deliver;
== Constants ========================================================