aBoomest 0 7 апреля, 2015 Опубликовано 7 апреля, 2015 · Жалоба Добрый день. Прошу прощения за длинный пост. С ПЛИС работаю не впервые, однако возникла проблема. (причем совершенно неожиданно) Не могу скомпилировать проект. В проект добавил только одну кнопку. Написал тестовую программу. Та же ерунда. Итак: В тестовой программе по нажатию кнопки делаю вкл/выкл светодиод. ФАЙЛЫ: UCF Net "Clock" Loc = "C9" | IOStandard = LVCMOS33; Net "Led_2" Loc = "F8" | IOStandard = LVTTL | Slew = Slow | Drive = 8; Net "Btn_Down" Loc = "K17" | IOStandard = LVTTL | PullDown; VHD library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MainBlinkingLed is port (Clock: in std_logic; Btn_Down: in std_logic; Led_2: out std_logic); end MainBlinkingLed; architecture Behavioral of MainBlinkingLed is shared variable Led2: bit := '0'; begin prcBlnkLed2: process(Clock) begin if (Btn_Down = '1') then Led2 := not(Led2); end if; end process prcBlnkLed2; Led_2 <= '1' when Led2 = '0' else '0'; end Behavioral; Проект не компилируется. Не проходит процесс Place&Route Пишет, что вывод Clock "не нагружен" и ещё вот это: ERROR:Place:1018 - A clock IOB / clock component pair have been found that are not placed at an optimal clock IOB / clock site pair. The clock component <Btn_Down_BUFGP/BUFG> is placed at site <BUFGMUX_X2Y1>. The IO component <Btn_Down> is placed at site <IPAD93>. This will not allow the use of the fast path between the IO and the Clock buffer. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .ucf file to demote this message to a WARNING and allow your design to continue. However, the use of this override is highly discouraged as it may lead to very poor timing results. It is recommended that this error condition be corrected in the design. A list of all the COMP.PINs used in this clock placement rule is listed below. These examples can be used directly in the .ucf file to override this clock rule. < NET "Btn_Down" CLOCK_DEDICATED_ROUTE = FALSE; > Схема подключения кнопки: подтянута к земле. При нажатии на на вход ПЛИС подается 3.3В (лог '1'). Если в код добавить функцию rising_edge(Clock) перед if-ом, то все компилируется и работает. Но хотелось изначально асинхронный процесс иметь, а тут получается синхронный. На просторах сети таких примеров с асинхронными схемами море: вот например асинхронный сброс триггера. Ссылка library IEEE; use IEEE.std_logic_1164.all; entity dff_async_rst is port (data, clk, reset : in std_logic; q :out std_logic); end dff_async_rst; architecture behav of dff_async_rst is begin process (clk, reset) begin if (reset = '0') then q <= '0'; elsif (clk'event and clk = '1') then q <= data; end if; end process; end behav; Что делаю не так? Описание ucf для таких сигналов должно быть иное? Или еще какие глупости делаю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 7 апреля, 2015 Опубликовано 7 апреля, 2015 · Жалоба Добрый день. Что делаю не так? Описание ucf для таких сигналов должно быть иное? Или еще какие глупости делаю? Лучше импульс от кнопки лучше синхронизировать с Вашей тактовой частотой на ПЛИС. Затем засинхронизированный импульс подавать на светодиод... Про обработку дребезг кнопки я молчу, чтобы не усложнять... Асинхронно: Led_2 <= '1' when Btn_Down = '1' else '0'; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dima_spb 0 7 апреля, 2015 Опубликовано 7 апреля, 2015 · Жалоба Добрый день. Прошу прощения за длинный пост. С ПЛИС работаю не впервые, однако возникла проблема. (причем совершенно неожиданно) Не могу скомпилировать проект. В проект добавил только одну кнопку. Написал тестовую программу. Та же ерунда. Итак: В тестовой программе по нажатию кнопки делаю вкл/выкл светодиод. ФАЙЛЫ: UCF Net "Clock" Loc = "C9" | IOStandard = LVCMOS33; Net "Led_2" Loc = "F8" | IOStandard = LVTTL | Slew = Slow | Drive = 8; Net "Btn_Down" Loc = "K17" | IOStandard = LVTTL | PullDown; VHD library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MainBlinkingLed is port (Clock: in std_logic; Btn_Down: in std_logic; Led_2: out std_logic); end MainBlinkingLed; architecture Behavioral of MainBlinkingLed is shared variable Led2: bit := '0'; begin prcBlnkLed2: process(Clock) begin if (Btn_Down = '1') then Led2 := not(Led2); end if; end process prcBlnkLed2; Led_2 <= '1' when Led2 = '0' else '0'; end Behavioral; Проект не компилируется. Не проходит процесс Place&Route Пишет, что вывод Clock "не нагружен" и ещё вот это: ERROR:Place:1018 - A clock IOB / clock component pair have been found that are not placed at an optimal clock IOB / clock site pair. The clock component <Btn_Down_BUFGP/BUFG> is placed at site <BUFGMUX_X2Y1>. The IO component <Btn_Down> is placed at site <IPAD93>. This will not allow the use of the fast path between the IO and the Clock buffer. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .ucf file to demote this message to a WARNING and allow your design to continue. However, the use of this override is highly discouraged as it may lead to very poor timing results. It is recommended that this error condition be corrected in the design. A list of all the COMP.PINs used in this clock placement rule is listed below. These examples can be used directly in the .ucf file to override this clock rule. < NET "Btn_Down" CLOCK_DEDICATED_ROUTE = FALSE; > Схема подключения кнопки: подтянута к земле. При нажатии на на вход ПЛИС подается 3.3В (лог '1'). Если в код добавить функцию rising_edge(Clock) перед if-ом, то все компилируется и работает. Но хотелось изначально асинхронный процесс иметь, а тут получается синхронный. На просторах сети таких примеров с асинхронными схемами море: вот например асинхронный сброс триггера. Ссылка library IEEE; use IEEE.std_logic_1164.all; entity dff_async_rst is port (data, clk, reset : in std_logic; q :out std_logic); end dff_async_rst; architecture behav of dff_async_rst is begin process (clk, reset) begin if (reset = '0') then q <= '0'; elsif (clk'event and clk = '1') then q <= data; end if; end process; end behav; Что делаю не так? Описание ucf для таких сигналов должно быть иное? Или еще какие глупости делаю? Проблема и вправду на ровном месте. Расскажу как это делают люди, а там уже сами решайте Вы с нами или наукой заниматься собираетесь. И так! 1. Привязываем подтянутый сигнал от кнопки к своей системной частоте (SYSTEM CLOCK); 2. Выделяем передний и задний фронты (SYSTEM CLOCK). 3. Далее обрабатываем признаки фронтов (передний и задний), а так же длительность между ними на нашей системной частоте. (SYSTEM CLOCK) Это ИМХО самый простой и надежный способ реализации. КСТАТИ, кнопки как правило подтягивают к единице. Считается, что это более помехоустойчивая схема включения. Для чего Вам асинхронный процесс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dima_spb 0 7 апреля, 2015 Опубликовано 7 апреля, 2015 · Жалоба Проблема и вправду на ровном месте. Расскажу как это делают люди, а там уже сами решайте Вы с нами или наукой заниматься собираетесь. И так! 1. Привязываем подтянутый сигнал от кнопки к своей системной частоте (SYSTEM CLOCK); 2. Выделяем передний и задний фронты (SYSTEM CLOCK). 3. Далее обрабатываем признаки фронтов (передний и задний), а так же длительность между ними на нашей системной частоте. (SYSTEM CLOCK) Это ИМХО самый простой и надежный способ реализации. КСТАТИ, кнопки как правило подтягивают к единице. Считается, что это более помехоустойчивая схема включения. Для чего Вам асинхронный процесс? КСтати у меня где-то валялся блочек антидребезга. могу поделиться если нужно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 7 апреля, 2015 Опубликовано 7 апреля, 2015 (изменено) · Жалоба Спасибо всем за ответы. Да, синхронный процесс лучше. Просто очень интересно почему выдает ошибку? Не очень ясно, ибо подобных примеров (асинхронной работы) очень много. А тут раз и не работает. Может кто сталкивался с подобным? Асинхронно: Led_2 <= '1' when Btn_Down = '1' else '0'; А если хочется по нажатию сделать, что по сложнее, как быть? to Dmitriyspb PS: Да, обычно подтягивают к единице. Просто на тестовой (китовой) плате так сделано. В своих схемах как правило подтягиваю к '1'. И плюс обычно кондёрчик не оч большой. Так сказать аппаратная защита от дребезга. PSPS: Спасибо, было бы интересно посмотреть на блок антидребезга. Изменено 7 апреля, 2015 пользователем aBoomest Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 7 апреля, 2015 Опубликовано 7 апреля, 2015 · Жалоба Давайте посмотрим на ваш процесс - prcBlnkLed2: process(Clock) begin if (Btn_Down = '1') then Led2 := not(Led2); end if; end process prcBlnkLed2; Что мы имеем - у процесса есть Clock в списке чувствительности, но нет никакого упоминания о нем (Clock) внутри тела процесса - синтезатору может стать нехорошо :) Далее - строка Led2 := not(Led2);, стоящая под if подразумевает синтез защелки (как минимум), а для этого нужен реальный клок. И синтезатор его нашел :) - то, что стоит в if, т.е. Btn_down. О чем он вам и сообщил - клоковый вход (Btn_down) подведен на пад, который не может быть источником клока. Схема явно не рабочая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aBoomest 0 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба стоящая под if подразумевает синтез защелки (как минимум), а для этого нужен реальный клок. И синтезатор его нашел :) - то, что стоит в if, т.е. Btn_down. О чем он вам и сообщил - клоковый вход (Btn_down) подведен на пад, который не может быть источником клока. Схема явно не рабочая. Эх, супер. Спасибо. Даже не надеялся такой четкий, разложенный по полочкам, ответ получить. Подскажите пожалуйста литературу откуда можно почерпнуть знания подобного рода: "if подразумевает синтез защелки (как минимум), а для этого нужен реальный клок", - про то к синтезу каких схем приводят те или иные конструкции кода. Еще раз спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dima_spb 0 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба Эх, супер. Спасибо. Даже не надеялся такой четкий, разложенный по полочкам, ответ получить. Подскажите пожалуйста литературу откуда можно почерпнуть знания Еще раз спасибо! http://portal-ed.ru/index.php/primery-verilog Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serjj1333 0 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба про то к синтезу каких схем приводят те или иные конструкции кода ИМХО можно глянуть паттерны производителя в ISE/Quartus/что-то-еще. Там приводятся самые базовые рабочие конструкции, на основе которых можно уже собрать рабочую схему. А дальше эксперимент - делается конструкция - смотрится в rtl viewer, если не получается представить как это разведется в голове. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба А если хочется по нажатию сделать, что по сложнее, как быть? Общая схема следующая: Делаем синхронизацию для импульса от кнопки Детектируете передний/задний фронт импульса нажатой кнопки (можете дополнительно использовать схемы антидребезга). По импульсу с детектора переднего/заднего фронта импульса нажатой кнопки запускаете процесс (что хотите обработать/вычислить) на обработку/вычисление. Далее по окончании вычислений/обработки выдаете импульс готовности. Импульсу готовности данных увеличиваете длительность "1" или "0" (в зависимости от схемы подключения светодиода) и выводите на светодиод, чтобы глаз увидел свечение светодиода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба Далее - строка Led2 := not(Led2);, стоящая под if подразумевает синтез защелки (как минимум), а для этого нужен реальный клок. почему оно такое подразумевает если нет clk'event? именно это вроде подразумевает клок... Схема просто не определена полностью, что будет если Btn_Down != '1'? if (Btn_Down = '1') then Led2 := not(Led2); else Led2 := 0; и будет обычный элемент "И" на один вход которого подается Btn_Down, и not Led2 на второй его вход. Да схема будет работать как не пойми что, пока нажата кнопка она будет как генератор менять свои значения, и как кнопку отпустят становиться 0. Но если очень надо именно такое, то почему нет? или же схема вида if (Btn_Down = '1') then Led2 := not(Led2); else Led2 := Led2; это у нас "исключающее ИЛИ" с одним входом Btn_Down, а на другой подан выход Led2. Да эта схема тоже дрянь, по причине того что пока нажата кнопка оно бешено меняется, а как кнопку отпускает замирает в прошлом состоянии. Но если снова надо, то почему нет? А вот без else поведение схемы полностью не определено, и поскольку от того что на выходе могут быть разные варианты в зависимости от того что должно быть на выходе если кнопка не 1, то синтезатор и обиделся... Понятно что вы скорее всего этого не хотели, и хотели чтобы эта схема 1 раз сменила свое состояние когда нажали кнопку, но для этого надо описать это по другому, как раз чтобы кнопка стала клоком для триггера. И нет никакой проблемы если этот сигнал заведен не на клоковую ногу ПЛИС. Надо просто поклясться синтезатору что вы знаете что делаете, и все будет хорошо.... это как раз < NET "Btn_Down" CLOCK_DEDICATED_ROUTE = FALSE; >. Ну естественно сигналы что виляют на результат надо внести в список чувствительности (это если по верилоговски выражаться, я так понимаю это типа под процесс в скобки их запихать) Вот так мне кажется... П.С. Удивительно что синтезатор тоже понял что вы хотели одной смены состояния леда, и начал городить схему где кнопка - клок, хотя из описания этого явно не следует... может у вас в схеме еще где то есть кнопка'event и это относится к этим местам? Перечитал, более того синтезатор не обижается на схему. Он пишет что вы входной сигнал клока никак не нагрузили, и он просто не знает куда его завести, и что вы клоком кнопку используете, и требует подписки что вы в курсе что она с не клокового контакта и все, ничего более... Но почему он так считает для меня реально загадка... П.С.С. завод клока с не клоковой ноги грозит тем что сначала сигнал потянуть в ПЛИС до клокового дерева, а потом уже будут использовать как клок. А это выльется в то что будет большая задержка между фронтом на ноге и фронтом внутри плис. И это серьезно просадит тайминг, но более это ничем не грозит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BSACPLD 15 8 апреля, 2015 Опубликовано 8 апреля, 2015 · Жалоба Добавлю свои пять копеек как давить дребезг. Хоть и на SV, а не на VHDL, но я думаю, алгоритм будет понятен. Кнопка сэмплируется с заданным периодом и по её значению происходит изменение счётчика. Как только счётчик досчитает до максимума или минимума, кнопка считается перешедшей в стабильное состояние. Если счётчик находится в промежуточном состоянии, то подавитель дребезга сохраняет своё предыдущее значение. Итого на выходе схемы имеем отфильтрованный от дребезга сигнал и можем делать с ним всё что захотим. :) `timescale 1 ns / 1 ps module but_filter #( parameter FREQ = 30, // MHz parameter BUT_SAMPLE = 1000 // us ) ( input clk, input but_in, output reg but_out ) ; localparam DIV = BUT_SAMPLE * FREQ ; reg [$clog2(DIV)-1:0] divider = 0 ; reg cout = 1'b0 ; reg [3:0] but_cnt = 0 ; wire max ; wire min ; reg [1:0] but_clk = 0 ; initial begin but_out <= 1'b0 ; end always_ff @(posedge clk) begin if (cout) {cout, divider} <= DIV - 2'd2 ; else {cout, divider} <= divider - 1'b1 ; end always_ff @(posedge clk) begin but_clk <= (but_clk << 1) | but_in ; if (cout) begin casex ({min, max, but_clk[1]}) 3'bx00: but_cnt <= but_cnt + 1'b1 ; 3'b0x1: but_cnt <= but_cnt - 1'b1 ; endcase casex ({min, max}) 2'b01: but_out <= 1'b1 ; 2'b10: but_out <= 1'b0 ; endcase end end assign max = &but_cnt ; assign min = ~|but_cnt ; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 9 апреля, 2015 Опубликовано 9 апреля, 2015 · Жалоба почему оно такое подразумевает если нет clk'event? именно это вроде подразумевает клок...Подразумевает оно потому, что в if нет ветки else и нет никакого безусловного присваивания в Led2. А это значит, что при некоторых условиях (точнее при Btn_Down не равном '1') Led2 должен сохранить свое состояние, а это элемент со внутренней памятью - либо регистр либо защелка. Т.к. 'event отсутствует, то это защелка. Схема просто не определена полностью, что будет если Btn_Down != '1'? Схема вполне себе определена. Если к ней приделать else ветку, то получится другая схема (тоже кривая правда :rolleyes: ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 9 апреля, 2015 Опубликовано 9 апреля, 2015 · Жалоба Понятно. Просто сбило вывод что нужен клок, который в моей вселенной до евента не может появиться... Хотя может это ошибка терминологии, под клоком я понимаю именно фронт, а не уровень, как разрешающий сигнал для latch-ей. И вторая моя ошибка что я не учел деления на защелка и регистр защелка:), в смысле что регистр тоже защелка) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bobi 0 22 апреля, 2015 Опубликовано 22 апреля, 2015 · Жалоба Есть другое предложение - ловить фронт, отсчитывать гарантированное время успокоения, и считывать состояние. Просто и не затратно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться