Не со всем предложенным еще ознакомился, но кое что уже видел ранее.
А есть какой-нибудь реальный пример? Ну, например имитатор SRAM на FPGA? Наверняка в такой вещи будут прописываться констрейны. Интересен порядок задаваемых цифр. Ну например, не проще ли устанавливать требования по задержке данных от пина до входа триггера относительно фронта клока в 0 нс и пусть роутер пыжится. А если не получится, не беда, все равно будет самый лучший результат из возможных. А если указывать реалистичное значение, то какое? Как его узнать? Или итерационно? Прописал 5 нс, посмотрел анализатором, что ошибок тайминга не, тогда уменьшил до 4 нс, если появились ошибки, поднял до 4.5нс?
Есть тайминговые группы. Непонятно что это такое. Входная шина данных от АЦП или процессора это тайминговая группа, для которой я должен описать задержки по входу до фронта стробирующего клока? Или это вся логика, используемая для обработки данных от АЦП, включая FIR-фильтры и до двухклокового FIFO, через которую данные передаются в другой клок-домен или в процессор?
Не получается понять все это на примере использования 4-х разрядного счетчика. Т.к. слишком этот пример отстранен от жизни.
К тому же, большинство документации использует sdc-файлы и команды, а Xilinx их не поддерживает. У него свой формат xcf, ncf и ucf. И чтение описания команд этого формата ясности в голове не прибавляет. Просто потому, что не понятно между какими сигналами мне нужно прописывать констрейны, а между какими нет. Ведь даже имена сигналов, что я использую в тексте VHDL уже на этапе синтеза могут стать другими, а при имплементации, где как я полагаю и применяются констрейны, от этих имен сигналов и следа может не остаться.
Одним констрейном я оказывается давно пользуюсь не зная, что это и есть констрейн:
NET "CLKIN" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 80000 kHz;
Если предметно, то убрав все лишнее, приведу на ваш суд то, что у меня получилось. Вернее, то, что у меня не получилось. Куча ошибок по неподдерживаемости параметров взятых из гугла. И попытка описать требования к задержкам входных сигналов процессора OE, WR, RD, CS, как к сигналам клоков. Я предположил, что раз требования по частоте входного клока выполняются и выдается тайминг-анализ, то если я опишу таким образом требования к цифровым сигналам, разводчик расстарается и уменьшит задержки:
Код
NET "clock_p" LOC = P53;
NET "clock_n" LOC = P54;
#
NET "emc_clk" LOC = P128;
NET "emc_ncs1" LOC = P107;
NET "emc_ncs1" PERIOD = 22.5 ns HIGH 33%;
NET "emc_ncs2" LOC = P103;
NET "emc_ncs2" PERIOD = 22.5 ns HIGH 33%;
NET "emc_ncs3" LOC = P104;
NET "emc_ncs3" PERIOD = 22.5 ns HIGH 33%;
NET "emc_addr<17>" LOC = P10;
NET "emc_addr<16>" LOC = P6;
NET "emc_addr<15>" LOC = P114;
NET "emc_addr<14>" LOC = P111;
NET "emc_addr<14>" PERIOD = 15 ns;
NET "emc_nwe" LOC = P94;
NET "emc_nwe" PERIOD = 22.5 ns HIGH 33%;
NET "emc_noe" LOC = P92;
NET "emc_noe" PERIOD = 22.5 ns HIGH 33%;
NET "emc_data<7>" LOC = P125;
NET "emc_data<6>" LOC = P124;
NET "emc_data<5>" LOC = P123;
NET "emc_data<4>" LOC = P122;
NET "emc_data<3>" LOC = P117;
NET "emc_data<2>" LOC = P116;
NET "emc_data<1>" LOC = P113;
NET "emc_data<0>" LOC = P112;
NET "emc_irq" LOC = P98;
#
NET "adc_clkp" LOC = P50;
NET "adc_clkn" LOC = P51;
NET "adc_oeb_a" LOC = P34;
NET "adc_din_a<11>" LOC = P36;
NET "adc_din_a<10>" LOC = P38;
NET "adc_din_a<9>" LOC = P41;
NET "adc_din_a<8>" LOC = P47;
NET "adc_din_a<7>" LOC = P48;
NET "adc_din_a<6>" LOC = P52;
NET "adc_din_a<5>" LOC = P56;
NET "adc_din_a<4>" LOC = P66;
NET "adc_din_a<3>" LOC = P69;
NET "adc_din_a<2>" LOC = P141;
NET "adc_din_a<1>" LOC = P78;
NET "adc_din_a<0>" LOC = P24;
NET "adc_otr_a" LOC = P35;
NET "adc_sens" LOC = P60;
#
NET "spi_sel" LOC = P139;
NET "spi_cs" LOC = P39;
NET "spi_clk" LOC = P71;
NET "spi_miso" LOC = P63;
NET "spi_mosi" LOC = P44;
#
NET "debug_led0" LOC = P74;
NET "debug_led1" LOC = P87;
NET "debug_led2" LOC = P86;
#
NET "clock_n" PERIOD = 20 ns HIGH 50%;
NET "clock_n" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_ncs1" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_ncs1" SLEW=FAST;
NET "emc_ncs1" PERIOD = 10 ns HIGH 50%;
NET "emc_ncs1" IBUF_DELAY_VALUE = 0;
NET "emc_ncs1" IFD_DELAY_VALUE = 0;
NET "emc_ncs2" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_ncs2" SLEW=FAST;
NET "emc_ncs2" PERIOD = 10 ns HIGH 50%;
NET "emc_ncs2" IBUF_DELAY_VALUE = 0;
NET "emc_ncs2" IFD_DELAY_VALUE = 0;
NET "emc_nwe" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_nwe" SLEW=FAST;
NET "emc_nwe" PERIOD = 10 ns HIGH 50%;
NET "emc_nwe" IBUF_DELAY_VALUE = 0;
NET "emc_nwe" IFD_DELAY_VALUE = 0;
NET "emc_noe" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_noe" SLEW=FAST;
NET "emc_noe" PERIOD = 10 ns HIGH 50%;
NET "emc_noe" IBUF_DELAY_VALUE = 0;
NET "emc_noe" IFD_DELAY_VALUE = 0;
NET "emc_addr<17>" SLEW=FAST;
NET "emc_addr<17>" IBUF_DELAY_VALUE = 0;
NET "emc_addr<17>" IFD_DELAY_VALUE = 0;
NET "emc_addr<16>" SLEW=FAST;
NET "emc_addr<16>" IBUF_DELAY_VALUE = 0;
NET "emc_addr<16>" IFD_DELAY_VALUE = 0;
NET "emc_addr<15>" SLEW=FAST;
NET "emc_addr<15>" IBUF_DELAY_VALUE = 0;
NET "emc_addr<15>" IFD_DELAY_VALUE = 0;
NET "emc_addr<14>" SLEW=FAST;
NET "emc_addr<14>" IBUF_DELAY_VALUE = 0;
NET "emc_addr<14>" IFD_DELAY_VALUE = 0;
NET "emc_addr<14>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "emc_data<7>" SLEW=FAST;
NET "emc_data<7>" DRIVE = 16;
NET "emc_data<7>" IBUF_DELAY_VALUE = 0;
NET "emc_data<7>" IFD_DELAY_VALUE = 0;
NET "emc_data<6>" SLEW=FAST;
NET "emc_data<6>" DRIVE = 16;
NET "emc_data<6>" IBUF_DELAY_VALUE = 0;
NET "emc_data<6>" IFD_DELAY_VALUE = 0;
NET "emc_data<5>" SLEW=FAST;
NET "emc_data<5>" DRIVE = 16;
NET "emc_data<5>" IBUF_DELAY_VALUE = 0;
NET "emc_data<5>" IFD_DELAY_VALUE = 0;
NET "emc_data<4>" SLEW=FAST;
NET "emc_data<4>" DRIVE = 16;
NET "emc_data<4>" IBUF_DELAY_VALUE = 0;
NET "emc_data<4>" IFD_DELAY_VALUE = 0;
NET "emc_data<3>" SLEW=FAST;
NET "emc_data<3>" DRIVE = 16;
NET "emc_data<3>" IBUF_DELAY_VALUE = 0;
NET "emc_data<3>" IFD_DELAY_VALUE = 0;
NET "emc_data<2>" SLEW=FAST;
NET "emc_data<2>" DRIVE = 16;
NET "emc_data<2>" IBUF_DELAY_VALUE = 0;
NET "emc_data<2>" IFD_DELAY_VALUE = 0;
NET "emc_data<1>" SLEW=FAST;
NET "emc_data<1>" DRIVE = 16;
NET "emc_data<1>" IBUF_DELAY_VALUE = 0;
NET "emc_data<1>" IFD_DELAY_VALUE = 0;
NET "emc_data<0>" SLEW=FAST;
NET "emc_data<0>" DRIVE = 16;
NET "emc_data<0>" IBUF_DELAY_VALUE = 0;
NET "emc_data<0>" IFD_DELAY_VALUE = 0;