Перейти к содержанию

Vadim_nsk

Участник
  • Публикаций

    65
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Vadim_nsk

  • Звание
    Участник
  • День рождения 01.10.1978

Контакты

  • Сайт
    http://
  • ICQ
    262459945

Информация

  • Город
    г. Новосибирск

Посетители профиля

1 573 просмотра профиля
  1. Спасибо, все стало намного понятней
  2. Цитата(MegaVolt @ Apr 28 2018, 14:58) В какой среде вы работаете? Какая версия interconnecta? В данный момент это ISE14.7 и AXI Interconnect 1.06.a Т.к. в ISE генерирование slave компонента делает убого и через шину IPIF (кажется так называется), я сделал иначе, запустил VIVADO 2016.4, сгенерировал пример slave-компонента в нем и перетащил исходники в ISE. Все работает, но вопросы остались открытыми. Нарыл вот такой документ: https://www.xilinx.com/support/documentatio...rence_guide.pdf все замечательно описано, но вопросы никуда не делись :-)
  3. Цитата(MegaVolt @ Apr 28 2018, 14:38) Как я понимаю нет.переход между доменами делает interconnect Да при том что частота AXI для него будет ваши 24MГц S_AXI_ACLK : in std_logic; это сигнал от AXI_Interconnect и он имеет частоту 100МГц. Я не могу подать свою частоту на шину, т.к. компонент slave и частота шины для него является входным параметром. Вся логика компонента завязана именно на частоте 23.96МГц, а управление осуществляется с шины AXI-lite. Просто мне кажется, что буква "А" в начале названий некоторых сигналов и такой явный акцент в презентациях Zynq, Microblaze на то, что эти сигналы являются ассинхронными служат какой-то цели. Ведь если убрать из названий эти буквы и акцент на ассинхронность, мне также придется переносить все входные сигналы управления в мой клок-домен, а выходные в клок-домен шины. Но в то же время, у буду "знать", что строя свой компонент синхронно с частотой шины, мне вообще не придется ставить пересинхронизацию.
  4. Цитата(MegaVolt @ Apr 28 2018, 14:17) Я так понимаю AXI_interconnect занимается согласованием доменов. В мой Slave компонент приходят такие сигналы: КодS_AXI_ACLK        : in  std_logic; S_AXI_ARESETN    : in  std_logic; S_AXI_AWADDR    : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); S_AXI_AWVALID    : in  std_logic; S_AXI_WDATA        : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); S_AXI_WSTRB        : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); S_AXI_WVALID        : in  std_logic; S_AXI_BREADY        : in  std_logic; S_AXI_ARADDR        : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); S_AXI_ARVALID        : in  std_logic; S_AXI_RREADY        : in  std_logic; S_AXI_ARREADY    : out std_logic; S_AXI_RDATA        : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); S_AXI_RRESP        : out std_logic_vector(1 downto 0); S_AXI_RVALID        : out std_logic; S_AXI_WREADY        : out std_logic; S_AXI_BRESP        : out std_logic_vector(1 downto 0); S_AXI_BVALID        : out std_logic; S_AXI_AWREADY    : out std_logic Предположим, что S_AXI_ACLK имеет частоту 100МГц Вы хотите сказать, что я спокойно могу в своем компоненте работать на частоте 23.96МГц с этими сигналами и AXI_interconnect все разрулит? В нем уже есть 2 ряда D-триггеров в ту и другую сторону? Собственно, у меня тогда три вопроса. 1. Если я вижу в названии сигналов впереди букву "А", я должен относиться к этому сигналу как к асинхронному и пропускать через 2 D-триггера работающие от моего клока? 2. Должен ли я свои выходные сигналы, сформированные от моего клока приводить к частоте AXI чреез 2 D-триггера или это забота AXI_interconnect? 3. Могу ли я ничего этого не делать, строя свой компонент таким образом, чтобы он целиком работал от частоты AXI?
  5. Собственно вопрос в следующем. Есть шина AXI, у нее есть два сигнала ARst и AClk. Как я это понимаю, AXI-master может жить и работать в одном clock-домене, а AXI-slave в другом (клоки то ассинхронные). Это им позволяют сигналы валидности адреса, захвата адреса, валидности данных и захвата данных. Но позвольте... адрес и сигнал валидности адреса выставляется одновременно, следовательно, один из разрядов шины адреса может оказаться в том самом метастабильном состоянии, т.к. шина AXI позволяет сигналам валидности и захвата появиться одновременно или сигналу захвата уже быть установленным. Такая же ситуация и с шиной данных. Так почему там не освещаются вопросы защиты от метастабильного состояния. К сожалению, тут на форуме в поиске нельзя указывать слова из 3-х букв, поэтому AXI не ищется, а в темах о метастабильности не затрагивается шина AXI. Что позволяет шине быть особенной и не иметь единного клока?
  6. Я оставил минимум в проекте, чтобы его можно было бы собрать и увидеть ошибку. Может кто-то выскажет предположение как ее исправить? https://drive.google.com/open?id=1kjMJy_m8k...xislf04o-38OvXM
  7. Платформа: Xilinx ISE 14.7; FPGA Spartan-6; Microblaze system Есть проект где на AXI-lite создан user IP. Для работы с памятью из него наружу торчит BRAM Interface. К этому интерфейсу подключена одним портом bram_block_1.00.a. Другим же портом она подключена с lbm_bram_if_cntrl_3.10.c. Netlist в EDK собирается без проблем, а вот при мепинге в ISE выдается сообщение вида: "PhysDesignRules:1678 - Issue with pin connections and/or configuration on block:<mb_system_top_i/mb_system_i/bram_block_for_nand/bram_block_for_nand/ra mb16bwer_0>:<RAMB16BWER_RAMB16BWER>. When using the DATA_WIDTH_A attribute the port A control pins for the RAMB16BWER must be used." Память используется через интерфейс: Код  port(     io_mem_BRAM_PORT_BRAM_EN : out std_logic;     io_mem_BRAM_PORT_BRAM_WEN : out std_logic_vector(3 downto 0);     io_mem_BRAM_PORT_BRAM_Addr : out std_logic_vector(31 downto 0);     io_mem_BRAM_PORT_BRAM_Din : in std_logic_vector(31 downto 0);     io_mem_BRAM_PORT_BRAM_Dout : out std_logic_vector(31 downto 0);     ...     ); Этот интерфейс уже в моем компоненте наружу торчит через: Код    BRAM_Rst_A        : out std_logic;     BRAM_Clk_A        : out std_logic;     BRAM_En_A        : out std_logic;     BRAM_WE_A        : out std_logic_vector(0 to C_BRAM_DWIDTH/8 + C_ECC*(1+(C_BRAM_DWIDTH/128))-1);     BRAM_Addr_A        : out std_logic_vector(0 to C_BRAM_AWIDTH - 1);     BRAM_WrData_A    : out std_logic_vector(0 to C_BRAM_DWIDTH + C_ECC*8*(1+(C_BRAM_DWIDTH/128))-1);     BRAM_RdData_A    : in std_logic_vector(0 to C_BRAM_DWIDTH + C_ECC*8*(1+(C_BRAM_DWIDTH/128))-1); Файл mpd выглядит следующим образом: Код## Peripheral Options OPTION IPTYPE = PERIPHERAL OPTION IMP_NETLIST = TRUE OPTION HDL = MIXED OPTION IP_GROUP = MICROBLAZE:USER OPTION DWIDTH = 32 OPTION AWIDTH = 32 ### added to support ngc file OPTION RUN_NGCBUILD = TRUE OPTION STYLE = MIX IO_INTERFACE IO_IF = NAND_if ## Bus Interfaces BUS_INTERFACE BUS = S_AXI, BUS_STD = AXI, BUS_TYPE = SLAVE BUS_INTERFACE BUS = BRAM_PORTA, BUS_STD = XIL_BRAM, BUS_TYPE = INITIATOR, SHARES_ADDR=DLMB ## Generics for VHDL or Parameters for Verilog PARAMETER C_S_AXI_PROTOCOL = AXI4LITE, DT = STRING, BUS = S_AXI, VALUES = (AXI4LITE = AXI4LITE), ASSIGNMENT = CONSTANT, TYPE = NON_HDL, ISVALID = (C_ECC == 1) PARAMETER C_S_AXI_ADDR_WIDTH = 32, DT = INTEGER, RANGE = (32), BUS = S_AXI, ASSIGNMENT = CONSTANT, ISVALID = (C_ECC == 1) PARAMETER C_S_AXI_DATA_WIDTH = 32, DT = INTEGER, RANGE = (32), BUS = S_AXI, ASSIGNMENT = CONSTANT, ISVALID = (C_ECC == 1) PARAMETER C_S_AXI_MIN_SIZE = 0x0000000f, DT = std_logic_vector, BUS = S_AXI PARAMETER C_DPHASE_TIMEOUT = 4, DT = INTEGER PARAMETER C_BASEADDR = 0xffffffff, DT = std_logic_vector, PAIR = C_HIGHADDR, ADDRESS = BASE, BUS = S_AXI PARAMETER C_HIGHADDR = 0x00000000, DT = std_logic_vector, PAIR = C_BASEADDR, ADDRESS = HIGH, BUS = S_AXI PARAMETER C_NUM_REG = 2, DT = INTEGER, RANGE = (2), ASSIGNMENT = CONSTANT PARAMETER C_BRAM_AWIDTH = 32, DT = integer, BUS = BRAM_PORTA, RANGE = (32), ASSIGNMENT = CONSTANT PARAMETER C_BRAM_DWIDTH = 32, DT = integer, BUS = BRAM_PORTA, RANGE = (32), ASSIGNMENT = CONSTANT PARAMETER C_ECC = 0, DT = integer, RANGE = (0:1) ## Ports PORT reset = "", DIR = I, SIGIS = RST PORT clk_40MHz = "", DIR = I, SIGIS = CLK PORT clk_40MHz_180 = "", DIR = I, SIGIS = CLK PORT BRAM_Rst_A = BRAM_Rst, DIR = O, BUS = BRAM_PORTA PORT BRAM_Clk_A = BRAM_Clk, DIR = O, BUS = BRAM_PORTA PORT BRAM_En_A = BRAM_En, DIR = O, BUS = BRAM_PORTA PORT BRAM_WE_A = BRAM_WEN, DIR = O, BUS = BRAM_PORTA, VEC = [0 : (C_BRAM_DWIDTH/8 + C_ECC*(1+(C_BRAM_DWIDTH/128)) - 1)], ENDIAN = LITTLE PORT BRAM_Addr_A = BRAM_Addr, DIR = O, BUS = BRAM_PORTA, VEC = [0 : (C_BRAM_AWIDTH - 1)], ENDIAN = LITTLE PORT BRAM_WrData_A = BRAM_Dout, DIR = O, BUS = BRAM_PORTA, VEC = [0 : (C_BRAM_DWIDTH + C_ECC*8*(1+(C_BRAM_DWIDTH/128)) - 1)], ENDIAN = LITTLE PORT BRAM_RdData_A = BRAM_Din, DIR = I, BUS = BRAM_PORTA, VEC = [0 : (C_BRAM_DWIDTH + C_ECC*8*(1+(C_BRAM_DWIDTH/128)) - 1)], ENDIAN = LITTLE При этом, если порт памяти вытащить наружу, на уровень выше, и уже там руками подключить память, то такого сообщения уже нет, все собирается. Но такое решение не удобное, в моем случае, подключил компонент в любой проект и пользуешься, а тут нужно еще и в vhdl верхнего уровня копипастить "нечто" из другого проекта.
  8. Разрешилось все весьма неожиданным образом... Накануне этой проблемы были установлены обновления системы и установлен антивирус. Снес антивирус, обновления откатить не удалось, было принято решение переустановить операционку, но с этим связано несколько трудностей. Пришлось еще раз проверять все обстоятельно. iMPACT работает всегда, а обновление при помощи SDK нет. Нашел где поменять частоту работы JTAG, выяснилось, что при снижении частоты ошибка исчезает и обновление начинает работать, работает и отладка. Вспомнил, что месяц назад на компьютере сгорел источник питания и был заменен на другой б/у-шный. Заменил в компьютере источник питания на новый и проблема исчезла. Вот так, из-за "грязного" питания 5В идущего на USB было обнаружено и справлено куча багов в проекте, встроенном софте, и разработка внешнего девайса привела к "отладке" средства разработки, т.е. ПК :-) Всем спасибо за помощь
  9. Connection to Board Failed Failed to connect to Xilinx hw_server. Check if the hw_server is running and correct TCP port is used. Program FPGA failed Connection to Board Failed Failed to connect to Xilinx hw_server. Check if the hw_server is running and correct TCP port is used. При этом, JTAG подключен через USB. Не оригинальный конечно, но давно работающий XERXES. И вдруг что-то сломалось. На другом компьютере все работает с этим же программатором. Странно то, что на виртуалке тоже сломалось. И не работает только из SDK, из отдельно запущенного iMPACT все работает. Может кто значет в каком файле SDK хранит настройки JTAG? ISE полностью переустановил. Не помогло :-( Но может что осталось в репозитории или в ini-файлах в пользовательской папке, поэтому и сохранился глюк после переустановки системы.
  10. Xilinx ISE+EDK+SDK 14.7 С некоторого времени на всех проектах отвалилась прошивка по JTAG программы. Через iMPACT нормально все шьется. Создал новый проект, не помогает. Открыл старый, заведомо работающий ранее, не работает. Запустил виртуалку, там тоже самое. Переустановил ISE, не помогло. Кто знает что это такое, помогите решить. Что делаем: Создаем новый проект в ISE, добавляем в него Microblaze, оттуда экспортируем драйвера и запускаем SDK. В нем создаем BSP и проект HellowWorld. Собираем прошивку, заливаем через iMPACT, заливается. В SDK собираем проект, запускаем отладку. И в этот момент... получаем всплывающее окно: 1. Check whether board is connected to the system properly. 2. In case of zynq board, check whether Digilent/Xilinx cable switch settings are correct. 3. If you are using Xilinx Platform cable USB, ensure that status LED is green. MicroBlaze is under RESET. Check if the Reset input to MicroBlaze and its Bus Interfaces are connected properly UNABLE to STOP MicroBlaze Картинка тут: https://drive.google.com/file/d/0B2SSFcGVsL...iew?usp=sharing (не знаю как вставить ее сюда иначе)
  11. Цитата(Golikov A. @ Apr 28 2017, 13:29) Я сглупил, объединил два вопроса в одном. Там был второй вопрос. Почему перед спецификацией стоит знак "|"? Это что-то осмысленное? Про одну строку и несколько, ответ понял, спасибо.
  12. Цитата(GAYVER @ Apr 27 2017, 16:19) CODE#Created by Constraints Editor (xc6slx4-tqg144-3) - 2017/04/18 # Termodatchik-1 NET "WIRE[1]" LOC = P100 |IOSTANDARD = LVTTL; NET "UBUF[1]" LOC = P99; NET "UBUF[1]" IOSTANDARD = LVCMOS33; Это ошибка копипаста или что-то осмысленное? Почему в одном случае "|IOSTANDARD", а в другом отдельной строкой и через пробел? Разве нельзя сразу через пробел писать "IOSTANDARD = LVCMOS33" или "|IOSTANDARD = LVCMOS33" для всех сигналов? Вопросы касательно моего примера Цитата(Vadim_nsk @ Apr 25 2017, 17:43) [code]NET "clock_p" LOC = P53; NET "emc_ncs1" LOC = P107; NET "emc_ncs1" PERIOD = 22.5 ns HIGH 33%; NET "emc_ncs1" CLOCK_DEDICATED_ROUTE = FALSE; NET "emc_ncs1" SLEW=FAST; NET "emc_ncs1" IBUF_DELAY_VALUE = 0; NET "emc_ncs1" IFD_DELAY_VALUE = 0; NET "emc_data<7>" LOC = P125; 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; 1. Можно ли к неклоковым сигналам применять параметр "PERIOD = 22.5 ns HIGH 33%;", тем самым как бы задавая частоту следования этого сигнала вместо того, чтобы прописывать путь к следующим сигналам и задержки? (ну, например, если их 5 штук, проще указать один раз период, чем 5 маршрутов, да еще и поддерживать их актуальность при динамичном изменении проекта) 2. Я счет, что это также влияет на скорость переключения, но не уверен: "NET "emc_data<7>" SLEW=FAST;" 3. Посчитал, что ток пина: "DRIVE = 16;" определяет подключение последовательного сопротивления, следовательно, тока заряда емкости нагрузки и скорость фронта, значит переключения. 4. Где-то в документации на сайте Xilinx прочитал, что для пинов данных, зависимых от частоты, задержки по умолчанию устанавливаются не нулевые, чтобы скомпенсировать разницу с величиной задержки буфера клока. А раз так, полезно эти задержки занулить: "IBUF_DELAY_VALUE = 0;", "IFD_DELAY_VALUE = 0;".
  13. Цитата(Golikov A. @ Apr 25 2017, 18:06) во-вторых, можно сгенерить IP корки каких-то сложных блоков типа контроллера DDR памяти или МАС езернета, и там будут приложены файлы ограничений их можно почитать. Спасибо, попробую. 1. Из примера: КодNET "SysCLk" TNM_NET = "SysClk"; TIMESPEC "TS_SysClk" = PERIOD "SysClk" 5 ns HIGH 50%; OFFSET = IN 1.25 ns VALID 2.5 ns BEFORE "SysClk" RISING; OFFSET = IN 1.25 ns VALID 2.5 ns BEFORE "SysClk" FALLING; Я же правильно понимаю, сначала идет: NET описание сигнала, а затем, применительно к этому сигналу идут спецификации: TIMESPEC различные OFFSET Или TIMESPEC и OFFSET это глобальное описание неких сущностей на весь проект? 2. Как описать требуемую задержку выходного сигнала относительно фронта клока вроде понятно, но совсем непонятно, как описать входную задержку сигнала, с учетом того, что он формируется во вне от нашего выходного клока, который также задерживается в выходном буфере oBUFG. Т.е. без осциллографа опять никак, ведь снаружи может набежать сколько угодно.
  14. Не со всем предложенным еще ознакомился, но кое что уже видел ранее. А есть какой-нибудь реальный пример? Ну, например имитатор 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;
  15. Работаю с FPGA Xilinx, Spartan-3e[6] У кого-нибудь есть пример использования временных ограничений (констрейнов)? Документация то понятно. Но как на реальном примере этим всем пользоваться? Интересует что-нибудь очень простенькое, вроде захвата данных с АЦП или шины SRAM с процессором. Я всегда считал, что стробирования входных и выходных сигналов триггерами, расположенными в IOB в моменты, где данные уже устаканились (смотрел осциллографом) достаточное условие для правильного захвата данных. А также, использование клоком, порожденных от одного входного посредством DCM. Но вот столкнулся с тем, что изменение в проекте стали затрагивать правильность захвата данных с АЦП. Люди советуют использовать констрейны. Посмотрел документацию и понял, что этого не достаточно. Не хватает понимания как всем этим пользоваться. Нужны простые примеры от которых можно было бы оттолкнуться в более сложные ситуации. 1. Например, имеем АЦП с параллельной шиной и выходной клок: ADC_clk, ADC_data(11 downto 0). Я всегда смотрю на задержку данных относительно выхода клока и стробирую по фронту в безопасной зоне, имея ввиду, что задержка во входном буфере будет порядка 4 нс. И слежу, чтобы все сигналы проходили через триггеры в IOB. 2. Самый частый пример это шина с каким-нибудь контроллером. Там есть шина адреса, данных, управления. Тут тоже, просто стробирую входные сигналы сначала повышенной частотой, затем рабочей. Оба клока получаются посредством DCM, следовательно синфазны. Таким образом, снижаю задержку на перестробирование и ухожу от метастабильности. Но и тут никогда не использую констрейны, т.к. все сигналы проходят через триггеры в IOB. Говорят, этого недостаточно. А как делать правильно?