Add MIG wrapper and ddr2 constraints

We cannot add the full repository here, because it contains the mig core,
which is not allowed to be redistributed publicy.
This commit is contained in:
Klemens Schölhorn 2018-06-05 15:36:39 +02:00
parent 73af9d6711
commit e1bf43fa47
2 changed files with 510 additions and 0 deletions

269
src/ddr2.ucf Normal file
View File

@ -0,0 +1,269 @@
NET ddr2_a[0] LOC="L30"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[1] LOC="M30"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[2] LOC="N29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[3] LOC="P29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[4] LOC="K31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[5] LOC="L31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[6] LOC="P31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[7] LOC="P30"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[8] LOC="M31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[9] LOC="R28"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[10] LOC="J31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[11] LOC="R29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_a[12] LOC="T31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
#NET ddr2_a[13] LOC="H29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ba[0] LOC="G31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ba[1] LOC="J30"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
#NET ddr2_ba[2] LOC="R31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_cas_n LOC="E31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_cke LOC="T28"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ck_n[0] LOC="AJ29"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ck[0] LOC="AK29"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ck_n[1] LOC="F28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ck[1] LOC="E28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_cs_n LOC="L29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[0] LOC="AF30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[1] LOC="AK31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[2] LOC="AF31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[3] LOC="AD30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[4] LOC="AJ30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[5] LOC="AF29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[6] LOC="AD29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[7] LOC="AE29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[8] LOC="AH27"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[9] LOC="AF28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[10] LOC="AH28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[11] LOC="AA28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[12] LOC="AG25"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[13] LOC="AJ26"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[14] LOC="AG28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[15] LOC="AB28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[16] LOC="AC28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[17] LOC="AB25"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[18] LOC="AC27"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[19] LOC="AA26"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[20] LOC="AB26"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[21] LOC="AA24"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[22] LOC="AB27"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[23] LOC="AA25"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[24] LOC="AC29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[25] LOC="AB30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[26] LOC="W31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[27] LOC="V30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[28] LOC="AC30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[29] LOC="W29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[30] LOC="V27"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[31] LOC="W27"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[32] LOC="V29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[33] LOC="Y27"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[34] LOC="Y26"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[35] LOC="W24"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[36] LOC="V28"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[37] LOC="W25"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[38] LOC="W26"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[39] LOC="V24"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[40] LOC="R24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[41] LOC="P25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[42] LOC="N24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[43] LOC="P26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[44] LOC="T24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[45] LOC="N25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[46] LOC="P27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[47] LOC="N28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[48] LOC="M28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[49] LOC="L28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[50] LOC="F25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[51] LOC="H25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[52] LOC="K27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[53] LOC="K28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[54] LOC="H24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[55] LOC="G26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[56] LOC="G25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[57] LOC="M26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[58] LOC="J24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[59] LOC="L26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[60] LOC="J27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[61] LOC="M25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[62] LOC="L25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dq[63] LOC="L24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[0] LOC="AJ31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[1] LOC="AE28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[2] LOC="Y24"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[3] LOC="Y31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[4] LOC="V25"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[5] LOC="P24"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[6] LOC="F26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dm[7] LOC="J25"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[0] LOC="AA30"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[0] LOC="AA29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[1] LOC="AK27"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[1] LOC="AK28"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[2] LOC="AJ27"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[2] LOC="AK26"; # Bank 21, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[3] LOC="AA31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[3] LOC="AB31"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[4] LOC="Y29"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[4] LOC="Y28"; # Bank 17, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[5] LOC="E27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[5] LOC="E26"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[6] LOC="G28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[6] LOC="H28"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs_n[7] LOC="H27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_dqs[7] LOC="G27"; # Bank 19, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_odt LOC="F31"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_ras_n LOC="H30"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
NET ddr2_we_n LOC="K29"; # Bank 15, Vcco=1.8V, DCI using 49.9 ohm resistors
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_DCI;
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;
################################################################################
# Copied from ddr2_controller #
################################################################################
###############################################################################
# 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_CLK_200" * 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_CLK_200" * 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_CLK_200" * 4;
# The RAM path is only used in cases where Write Latency (Additive Latency +
# (CAS Latency - 1) + (1 in case of RDIMM)) is 2 or below. So these constraints are
# valid for CAS Latency = 3, Additive Latency = 0 and selected part is not RDIMM.
# If Write Latency is higher than 3, then a warning will appear in PAR,
# and the constraint can be ignored as this path does not exist. RAM constraint
# can be safely removed if the warning is not to be displayed.
TIMESPEC "TS_MC_PHY_INIT_DATA_SEL_90" = FROM "TNM_PHY_INIT_DATA_SEL" TO RAMS
"TS_CLK_200" * 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_CLK_200" * 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_CLK_200" * 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_CLK_200" * 4;
###############################################################################
#The following constraint is added to prevent (false) hold time violations on
#the data path from stage1 to stage2 capture flops. Stage1 flops are clocked by
#the delayed DQS and stage2 flops are clocked by the clk0 clock. Placing a TIG
#on the DQ IDDR capture flop instance to achieve this is acceptable because timing
#is guaranteed through the use of separate Predictable IP constraints. These
#violations are reported when anunconstrained path report is run.
###############################################################################
INST "*/gen_dq[*].u_iob_dq/gen*.u_iddr_dq" TIG ;
###############################################################################
# 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
###############################################################################
###############################################################################
#The following constraint is added to avoid the HOLD violations in the trace report
#when run for unconstrained paths.These two FF groups will be clocked by two different
# clocks and hence there should be no timing analysis performed on this path.
###############################################################################
INST "*/u_mem_if_top/u_phy_top/u_phy_io/u_phy_calib/gen_gate[*].u_en_dqs_ff" TNM = EN_DQS_FF;
TIMESPEC TS_FROM_EN_DQS_FF_TO_DQ_CE_FF = FROM EN_DQS_FF TO TNM_DQ_CE_IDDR 3.85 ns DATAPATHONLY;
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.
# The following code has been commented for V5 as the predictable IP will take
# care of placement of these flops by meeting the MAXDELAY requirement.
# These constraints will be removed in the next release.
###############################################################################
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 IOB flip-flop to CE pin for all DQ IDDR's
# for DQS Read Post amble Glitch Squelch circuit
###############################################################################
# Max delay from output of IOB flip-flop 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" 2.4 ns;

241
src/memory_controller.vhd Normal file
View File

@ -0,0 +1,241 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity memory_controller is
port (
-- clocks
sys_clk0: in std_logic;
sys_clk90: in std_logic;
sys_clkdiv0: in std_logic;
sys_clk_locked: in std_logic;
sys_clk_idelay: in std_logic;
sys_reset: in std_logic;
-- read and write requests
request_addr: in std_logic_vector(27 downto 0); -- 256 MiB, no CS (SR)
request_type: in std_logic; -- read (1) or write (0)
request_data: in std_logic_vector(255 downto 0);
request_mask: in std_logic_vector(31 downto 0);
request_valid: in std_logic;
request_ready: out std_logic;
-- read responses
response_data: out std_logic_vector(255 downto 0);
response_valid: out std_logic; -- only asserted for one cycle, no ready
-- physical ddr2 interface
ddr2_dq: inout std_logic_vector(63 downto 0);
ddr2_a: out std_logic_vector(12 downto 0);
ddr2_ba: out std_logic_vector(1 downto 0);
ddr2_ras_n: out std_logic;
ddr2_cas_n: out std_logic;
ddr2_we_n: out std_logic;
ddr2_cs_n: out std_logic_vector(0 downto 0);
ddr2_odt: out std_logic_vector(0 downto 0);
ddr2_cke: out std_logic_vector(0 downto 0);
ddr2_dm: out std_logic_vector(7 downto 0);
ddr2_dqs: inout std_logic_vector(7 downto 0);
ddr2_dqs_n: inout std_logic_vector(7 downto 0);
ddr2_ck: out std_logic_vector(1 downto 0);
ddr2_ck_n: out std_logic_vector(1 downto 0)
);
end memory_controller;
architecture rtl of memory_controller is
signal clk: std_logic;
signal reset_p: std_logic;
type request_states is (
REQ_IDLE,
REQ_WRITE
);
signal request_state: request_states := REQ_IDLE;
type response_states is (
RES_IDLE,
RES_WAIT_SECOND
);
signal response_state: response_states := RES_IDLE;
signal ram_init_done: std_logic;
signal ram_address: std_logic_vector(30 downto 0);
signal ram_command: std_logic_vector(2 downto 0);
signal ram_data_in: std_logic_vector(127 downto 0);
signal ram_mask_in: std_logic_vector(15 downto 0);
signal ram_data_out: std_logic_vector(127 downto 0);
signal ram_enq_address: std_logic;
signal ram_enq_data: std_logic;
signal ram_address_afull: std_logic;
signal ram_data_afull: std_logic;
signal ram_data_valid: std_logic;
signal is_request_ready: std_logic;
signal data_in_high: std_logic_vector(127 downto 0);
signal mask_in_high: std_logic_vector(15 downto 0);
signal data_out_low: std_logic_vector(127 downto 0);
begin
reset_p <= not sys_reset;
-- the lowest three bits pick one of the 8 bytes inside the 64b ram width
ram_address <= "000000" & request_addr(27 downto 3);
-- WRITE is 000 and READ is 001
ram_command <= "00" & request_type;
-- we directly pass the lower half to the mig fifo and only store the
-- upper half for writing on a second cycle (this works because we can
-- still write 12 words to the fifo when the *almost full* signal is
-- asserted by the mig)
ram_data_in <= request_data(127 downto 0) when request_state = REQ_IDLE else
data_in_high;
ram_mask_in <= request_mask(15 downto 0) when request_state = REQ_IDLE else
mask_in_high;
-- to directly pass data to the fifos (see above) we also have to enable
-- the fifo write signals combinatorially, otherwise we miss the first part
ram_enq_address <= is_request_ready and request_valid;
-- the data write signal is only high for write requests and also has to
-- be kept high for a second cycle to write the upper half of the data
ram_enq_data <= '1' when ( (is_request_ready and request_valid) = '1' and
(request_type = '0')
) or (request_state = REQ_WRITE)
else '0';
-- we are only ready if we can write to *both* fifos and everything is
-- fully initialized (we could theoretically only look at the address fifo
-- for read requests)
is_request_ready <= '1' when (ram_init_done = '1') and
(ram_address_afull = '0') and
(ram_data_afull = '0') and
(request_state = REQ_IDLE)
else '0';
request_ready <= is_request_ready;
input: process(clk, sys_reset)
begin
if sys_reset = '1' then
request_state <= REQ_IDLE;
elsif rising_edge(clk) then
case request_state is
when REQ_IDLE =>
if is_request_ready = '1' and request_valid = '1' then
if request_type = '1' then -- READ
request_state <= REQ_IDLE;
else -- WRITE
data_in_high <= request_data(255 downto 128);
mask_in_high <= request_mask(31 downto 16);
request_state <= REQ_WRITE;
end if;
end if;
when REQ_WRITE =>
request_state <= REQ_IDLE;
end case;
end if;
end process input;
-- we pass the higher half directly from the mig
response_data <= ram_data_out & data_out_low;
-- read_valid only asserted for one cycle, must be read immediately
response_valid <= '1' when (response_state = RES_WAIT_SECOND) and
(ram_data_valid = '1')
else '0';
output: process(clk, sys_reset)
begin
if sys_reset = '1' then
response_state <= RES_IDLE;
elsif rising_edge(clk) then
case response_state is
when RES_IDLE =>
if ram_data_valid = '1' then
data_out_low <= ram_data_out;
response_state <= RES_WAIT_SECOND;
end if;
when RES_WAIT_SECOND =>
if ram_data_valid = '1' then
response_state <= RES_IDLE;
end if;
end case;
end if;
end process output;
ddr2_controller: entity work.ddr2_controller port map (
clk0 => sys_clk0,
clk90 => sys_clk90,
clkdiv0 => sys_clkdiv0,
clk200 => sys_clk_idelay,
locked => sys_clk_locked,
sys_rst_n => reset_p,
rst0_tb => open,
clk0_tb => clk,
phy_init_done => ram_init_done,
app_wdf_afull => ram_data_afull,
app_af_afull => ram_address_afull,
rd_data_valid => ram_data_valid,
app_wdf_wren => ram_enq_data,
app_af_wren => ram_enq_address,
app_af_addr => ram_address,
app_af_cmd => ram_command,
rd_data_fifo_out => ram_data_out,
app_wdf_data => ram_data_in,
app_wdf_mask_data => ram_mask_in,
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
);
--~ sys_clk_p : in std_logic;
--~ sys_clk_n : in std_logic;
--~ clk200_p : in std_logic;
--~ clk200_n : in std_logic;
--~ sys_rst_n : in std_logic;
--~ rst0_tb : out std_logic;
--~ clk0_tb : out std_logic;
--~ phy_init_done : out std_logic;
--~ app_wdf_afull : out std_logic;
--~ app_af_afull : out std_logic;
--~ app_wdf_wren : in std_logic;
--~ app_af_wren : in std_logic;
--~ app_af_addr : in std_logic_vector(30 downto 0);
--~ app_af_cmd : in std_logic_vector(2 downto 0);
--~ app_wdf_data : in std_logic_vector(127 downto 0);
--~ app_wdf_mask_data : in std_logic_vector(15 downto 0);
--~ rd_data_fifo_out : out std_logic_vector(127 downto 0);
--~ rd_data_valid : out std_logic;
--~ ddr2_dq : inout std_logic_vector(63 downto 0);
--~ ddr2_a : out std_logic_vector(12 downto 0);
--~ ddr2_ba : out std_logic_vector(1 downto 0);
--~ ddr2_ras_n : out std_logic;
--~ ddr2_cas_n : out std_logic;
--~ ddr2_we_n : out std_logic;
--~ ddr2_cs_n : out std_logic_vector(0 downto 0);
--~ ddr2_odt : out std_logic_vector(0 downto 0);
--~ ddr2_cke : out std_logic_vector(0 downto 0);
--~ ddr2_dm : out std_logic_vector(7 downto 0);
--~ ddr2_dqs : inout std_logic_vector(7 downto 0);
--~ ddr2_dqs_n : inout std_logic_vector(7 downto 0);
--~ ddr2_ck : out std_logic_vector(1 downto 0);
--~ ddr2_ck_n : out std_logic_vector(1 downto 0)
end rtl;