StewartLittle 41 28 июля, 2015 Опубликовано 28 июля, 2015 · Жалоба Правда напсал чуть корочеНу тогда и последний else можно опустить. :) Но почему всё же первый вариант не прокатил? :05:Навскидку предполагаю, что из-за: а) в VHDL последующая транзакция отменяет предыдущую. б) у Вас два последовательных if'а в одном процессе (и, кстати, их условий нет в списке чувствительности). в) особенностей картусовского синтезатора при обработке совокупности указанных выше условий. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 28 июля, 2015 Опубликовано 28 июля, 2015 · Жалоба Ну тогда и последний else можно опустить. sm.gif Да, пожалуй Вы правы B) Навскидку предполагаю, что из-за: более склоняюсь к последнему... Спасибо за помощь :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strob 0 28 июля, 2015 Опубликовано 28 июля, 2015 · Жалоба более склоняюсь к последнему... А может просто else-ы конфликтуют с "противоположными" if? Не определены действия когда лоу=0, а хай=1. Первый иф говорит перезаписывай значение, а второй - пиши новое в старшие байты. И наоборот. Наверняка там варнинг был соответствующий. ИМХО вина сапра только в том что эррор не выкатил) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Грендайзер 0 28 июля, 2015 Опубликовано 28 июля, 2015 · Жалоба Что значит с "противоположными" if? Есть 2 разных флага, по значению которых необходимо произвести разные действия с общим буфером. ИМХО вина сапра только в том что эррор не выкатил) Дык тут то сапр как раз прав оказался, никакой ошибки нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Strob 0 28 июля, 2015 Опубликовано 28 июля, 2015 (изменено) · Жалоба Что значит ? Есть 2 разных флага, по значению которых необходимо произвести разные действия с общим буфером. В том и дело что действия разные, а буфер один. Строго следуя исходному тексту получаем что при хай=1, а лоу=0, один if требует сохранить текущее значение в буфере, а второй требует переписать старшие разряды. Беда именно в том что Вы сами и прописали такой конфликт задав else в каждом if. Без else я думаю все и в исходном варианте работало бы. Хотя и не лучшим образом. Также работало бы если if wr_tx_udp_data_HIGH = '1' then tx_udp_data_reg(63 downto 32) <= writedata(31 downto 0); else tx_udp_data_reg(63 downto 32) <= tx_udp_data_reg(63 downto 32); end if; if wr_tx_udp_data_LOW = '1' then tx_udp_data_reg(31 downto 0) <= writedata(31 downto 0); else tx_udp_data_reg(31 downto 0) <= tx_udp_data_reg(31 downto 0); end if; Дык тут то сапр как раз прав оказался, никакой ошибки нет. Multi-source error это кажется называется. Хотя тут не уверен. Изменено 28 июля, 2015 пользователем Barktail Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 12 октября, 2016 Опубликовано 12 октября, 2016 (изменено) · Жалоба А можете помочь разобраться как правильнее написать При помощи логики : SDRAM_DQ <= WR_DATA_REG2 WHEN (PRES_STATE = WRITE_STATE) ELSE (OTHERS => 'Z'); Или при помощи синхронного процесса: WRITE_DATA_FROM_MEMORY:PROCESS ( CLK ) BEGIN IF (CLK'EVENT AND CLK = '1') THEN IF (NEXT_STATE = WRITE_STATE) THEN SDRAM_DQ <= WR_DATA_REG1; ELSE SDRAM_DQ <= (OTHERS => 'Z'); END IF; END IF; END PROCESS; Записи эквиваленты с точки зрения функционала. Изменено 12 октября, 2016 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_su 1 13 октября, 2016 Опубликовано 13 октября, 2016 · Жалоба А можете помочь разобраться как правильнее написать При помощи логики : SDRAM_DQ <= WR_DATA_REG2 WHEN (PRES_STATE = WRITE_STATE) ELSE (OTHERS => 'Z'); Или при помощи синхронного процесса: WRITE_DATA_FROM_MEMORY:PROCESS ( CLK ) BEGIN IF (CLK'EVENT AND CLK = '1') THEN IF (NEXT_STATE = WRITE_STATE) THEN SDRAM_DQ <= WR_DATA_REG1; ELSE SDRAM_DQ <= (OTHERS => 'Z'); END IF; END IF; END PROCESS; Записи эквиваленты с точки зрения функционала. Добрый день. Зависит от того, как вам надо. Если надо, чтобы данные SDRAM_DQ фиксировались по фронту CLK, то вторая запись. Если просто мультиплексор, управляемый условием PRES_STATE = WRITE_STATE, то первая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 14 октября, 2016 Опубликовано 14 октября, 2016 · Жалоба Мне необходимо, чтобы в момент когда подана команда записи данных в SDRAM память данные, которые контроллер памяти выдает на шину данных SDRAM памяти были стабильными и не менялись до прихода переднего фронта частоты SDRAM контроллера, которым эти данные и зафиксируются. Для этого мне необходимо чтобы в это время данные были стабильными. Фактически я на "железе" проверил оба варианта, и они работают. Но с точки зрения увеличения максимальной частоты проекта, какой способ более правильный ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 26 октября, 2016 Опубликовано 26 октября, 2016 · Жалоба Возник вопрос по параметризации модуля, который я пишу на VHDL. Допустим есть некий модуль "COMPONENT_MODULE" который что-то умеет делать. В этом модуле есть некий процесс "CONTROL_DATA", который выдает сигнал в зависимости от внешних условий. В проекте более высокого уровня я использую 10 таких модулей. Но сигнал "CONTROL_DATA" мне нужен только от одного из модулей(неважно какого). В остальных модулях данный сигнал мне не нужен. Есть ли в VHDL возможность сделать процесс параметризированным и в зависимости от какой-либо константы описанной в GENERIC области он будет включен/выключен ? На данный момент я просто не использую эти сигналы, но Quartus выдает предупреждение о них. Хотелось бы как-нибудь красиво это описать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tausinov 0 26 октября, 2016 Опубликовано 26 октября, 2016 · Жалоба Возник вопрос по параметризации модуля, который я пишу на VHDL. Допустим есть некий модуль "COMPONENT_MODULE" который что-то умеет делать. В этом модуле есть некий процесс "CONTROL_DATA", который выдает сигнал в зависимости от внешних условий. В проекте более высокого уровня я использую 10 таких модулей. Но сигнал "CONTROL_DATA" мне нужен только от одного из модулей(неважно какого). В остальных модулях данный сигнал мне не нужен. Есть ли в VHDL возможность сделать процесс параметризированным и в зависимости от какой-либо константы описанной в GENERIC области он будет включен/выключен ? На данный момент я просто не использую эти сигналы, но Quartus выдает предупреждение о них. Хотелось бы как-нибудь красиво это описать. IF (condition) GENERATE A: process(.....) .... END GENERATE IF (condition) GENERATE B: process(.....) .... END GENERATE Так на этапе компиляции будет выбрано, какую реализацию процесса использовать. А если ни одно из условий выполняться не будет, то процесса просто не будет. Только вот какого рода варнинг вы хотите убрать? Если выходной порт назначается из этого процесса, то факт того, что он не будет назначаться ниоткуда, не уберет варнинг о том, что порт не используется. Если нужно убрать такой варнинг, то создайте две архитектуры. У 9 модулей будет архитектура без этого сигнала, а у одного с ним. Этот сигнал и используйте дальше. А через параметр задайте подключение входных сигналов ко всем 10 модулям так, чтобы на модуль с нужным выходным сигналом приходили соответствующие данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 26 октября, 2016 Опубликовано 26 октября, 2016 (изменено) · Жалоба IF (condition) GENERATE A: process(.....) .... END GENERATE IF (condition) GENERATE B: process(.....) .... END GENERATE Так на этапе компиляции будет выбрано, какую реализацию процесса использовать. А если ни одно из условий выполняться не будет, то процесса просто не будет. Только вот какого рода варнинг вы хотите убрать? Если выходной порт назначается из этого процесса, то факт того, что он не будет назначаться ниоткуда, не уберет варнинг о том, что порт не используется. Если нужно убрать такой варнинг, то создайте две архитектуры. У 9 модулей будет архитектура без этого сигнала, а у одного с ним. Этот сигнал и используйте дальше. А через параметр задайте подключение входных сигналов ко всем 10 модулям так, чтобы на модуль с нужным выходным сигналом приходили соответствующие данные. Quartus стал выдавать такие сообщения: Warning (12241): 1 hierarchies have connectivity warnings - see the Connectivity Checks report folder В сообщении написано что: clkn Output Info Connected to dangling logic. Logic that only feeds a dangling port will be removed. 1 clkp Output Info Connected to dangling logic. Logic that only feeds a dangling port will be removed. 2 И действительно в проекте у меня остаются "висящими в воздухе" эти выводы у двух серилайзеров. --================================================================ -- Серилайзер для матрицы TX23D38VM0CAA --================================================================ LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY SERILAISER IS PORT ( DATA_IN :IN STD_LOGIC_VECTOR(6 DOWNTO 0); -- Входные данные для серилайзера DATA_CLOCK :IN STD_LOGIC; -- Синхрочастота входных данных CLOCKx7 :IN STD_LOGIC; -- Частота х7 для серилайзера ENABLE :IN STD_LOGIC; -- Сигнал разрешения работы CLKn :OUT STD_LOGIC; -- Отрицательный выход LVDS линии синхрочастоты CLKp :OUT STD_LOGIC; -- Положительный выход LVDS линии синхрочастоты TXn :OUT STD_LOGIC; -- Отрицательный выход LVDS линии данных TXp :OUT STD_LOGIC -- Положительный выход LVDS линии данных ); END SERILAISER; ARCHITECTURE SERILAISER_arc OF SERILAISER IS SIGNAL DATA_REG0 :STD_LOGIC_VECTOR(6 DOWNTO 0); -- Регистр хранения входных данных SIGNAL DATA_REG1 :STD_LOGIC_VECTOR(0 TO 6); -- Регистр1 для передачи в другой клоковый домен SIGNAL DATA_REG2 :STD_LOGIC_VECTOR(0 TO 6); -- Регистр2 для передачи в другой клоковый домен SIGNAL DATA_REG3 :STD_LOGIC_VECTOR(0 TO 6); -- Регистр3 С которого сериализируются данные SIGNAL CLK_CNT :INTEGER RANGE 0 TO 6; -- Счетчик для серилайзера и востановления синхрочастоты BEGIN WRITE_INPUT_DATA:PROCESS ( DATA_CLOCK ) BEGIN IF (DATA_CLOCK'EVENT AND DATA_CLOCK = '1') THEN IF (ENABLE = '1') THEN DATA_REG0 <= DATA_IN; -- По переднему фронту запишем входные данные END IF; END IF; END PROCESS; COUNTER_AND_CROSS_DOAIN_DATA:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN DATA_REG1(0 TO 6) <= DATA_REG0(6 DOWNTO 0); -- Передаем данные через клоковый домен старшим битом вперед. DATA_REG2 <= DATA_REG1; -- Вторая ступень синхронизации IF (CLK_CNT = 6) THEN -- Как только счетчик досчитает до 6 DATA_REG3<= DATA_REG2; -- Перепишем данные последний регистр CLK_CNT <= 0; -- Обнулим счетчик ELSE CLK_CNT <= CLK_CNT + 1; -- Пока счетчик не досчитал до 6 инкрементируем его на 1 END IF; END IF; END IF; END PROCESS; CREATING_MATRIX_CLOCK:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN IF (CLK_CNT >=1 AND CLK_CNT <= 3) THEN -- Подставим фронты синхрочатоты матрицы как в даташите на матрицу CLKp <= '0'; CLKn <= '1'; ELSE CLKp <= '1'; CLKn <= '0'; END IF; END IF; END IF; END PROCESS; TXp <= DATA_REG3(CLK_CNT); TXn <= NOT DATA_REG3(CLK_CNT); END SERILAISER_arc; Вот модуль серилайзера для одной линии LVDS матрицы. В этом модуле так-же формируется сигнал синхрочастоты, матрицы, где фронты подставлены под последовательный поток данных в соответствии с требованиями матрицы. Знаю, что не совсем корректно реализовал этот модуль, поскольку правильно не частоту подставлять под данные, а данные под частоту. Но такой вариант работает, и в железе всё функционирует. Да и если честно частота матрицы небольшая (34 Мгц), думаю это не очень страшно на такой частоте. А полноценно вывести PLL наружу я не могу, свободных выходов PLL у меня нет. В идеале бы осциллографом глянуть форму сигнала. Но это пока мечты. Почитаю умных книжек, посмотрю форумы и сделаю правильно. Но потом. Сейчас мне хочется при помощи GENERIC области включать отключать процесс: CREATING_MATRIX_CLOCK:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN IF (CLK_CNT >=1 AND CLK_CNT <= 3) THEN -- Подставим фронты синхрочатоты матрицы как в даташите на матрицу CLKp <= '0'; CLKn <= '1'; ELSE CLKp <= '1'; CLKn <= '0'; END IF; END IF; END IF; END PROCESS; Спасибо за ответ. Завтра с утра на свежую голову попробую сделать, как Вы советовали. Изменено 28 октября, 2016 пользователем makc code => codebox Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 27 октября, 2016 Опубликовано 27 октября, 2016 (изменено) · Жалоба Спасибо за помощь. В общем теперь модуль выглядит так: --================================================================ -- Серилайзер для матрицы TX23D38VM0CAA --================================================================ LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY SERILAISER IS GENERIC ( CLK_MATRIX : INTEGER := 0 -- 0 disable. 1 enable out signals ); PORT ( DATA_IN :IN STD_LOGIC_VECTOR(6 DOWNTO 0); -- Входные данные для серилайзера DATA_CLOCK :IN STD_LOGIC; -- Синхрочастота входных данных CLOCKx7 :IN STD_LOGIC; -- Частота х7 для серилайзера ENABLE :IN STD_LOGIC; -- Сигнал разрешения работы TXn :OUT STD_LOGIC; -- Отрицательный выход LVDS линии данных TXp :OUT STD_LOGIC; -- Положительный выход LVDS линии данных ----------------------- СИНХРОСИГНАЛ МАТРИЦЫ ВКЛЮЧАЕТСЯ ЕСЛИ ПЕРЕМЕННАЯ CLK_MATRIX = 1----------------------------- CLKn :OUT STD_LOGIC_VECTOR(CLK_MATRIX - 1 DOWNTO 0); -- Отрицательный выход LVDS линии синхрочастоты CLKp :OUT STD_LOGIC_VECTOR(CLK_MATRIX - 1 DOWNTO 0) -- Положительный выход LVDS линии синхрочастоты ); END SERILAISER; ARCHITECTURE SERILAISER_arc OF SERILAISER IS SIGNAL DATA_REG0 :STD_LOGIC_VECTOR(6 DOWNTO 0) := (OTHERS => '0'); -- Регистр хранения входных данных SIGNAL DATA_REG1 :STD_LOGIC_VECTOR(0 TO 6) := (OTHERS => '0'); -- Регистр1 для передачи в другой клоковый домен SIGNAL DATA_REG2 :STD_LOGIC_VECTOR(0 TO 6) := (OTHERS => '0'); -- Регистр2 для передачи в другой клоковый домен SIGNAL DATA_REG3 :STD_LOGIC_VECTOR(0 TO 6) := (OTHERS => '0'); -- Регистр3 С которого сериализируются данные SIGNAL CLK_CNT :INTEGER RANGE 0 TO 6 := 0; -- Счетчик для серилайзера и востановления синхрочастоты BEGIN WRITE_INPUT_DATA:PROCESS ( DATA_CLOCK ) BEGIN IF (DATA_CLOCK'EVENT AND DATA_CLOCK = '1') THEN IF (ENABLE = '1') THEN DATA_REG0 <= DATA_IN; -- По переднему фронту запишем входные данные END IF; END IF; END PROCESS; COUNTER_AND_CROSS_DOAIN_DATA:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN DATA_REG1(0 TO 6) <= DATA_REG0(6 DOWNTO 0); -- Передаем данные через клоковый домен старшим битом вперед. DATA_REG2 <= DATA_REG1; -- Вторая ступень синхронизации IF (CLK_CNT >= 6) THEN -- Как только счетчик досчитает до 6 DATA_REG3<= DATA_REG2; --- Перепишем данные последний регистр CLK_CNT <= 0; -- Обнулим счетчик ELSE CLK_CNT <= CLK_CNT + 1; -- Пока счетчик не досчитал до 6 инкрементируем его на 1 END IF; END IF; END IF; END PROCESS; CLKMATRIX : IF (CLK_MATRIX > 0) GENERATE CREATING_MATRIX_CLOCK:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN IF (CLK_CNT >=2 AND CLK_CNT <= 4) THEN -- Подставим фронты синхрочатоты матрицы как в даташите на матрицу CLKp <= "1"; CLKn <= "0"; ELSE CLKp <= "0"; CLKn <= "1"; END IF; END IF; END IF; END PROCESS; END GENERATE; OUT_DATA_CREATING:PROCESS ( CLOCKx7 ) BEGIN IF (CLOCKx7'EVENT AND CLOCKx7 = '1') THEN IF (ENABLE = '1') THEN TXp <= DATA_REG3(CLK_CNT); TXn <= NOT DATA_REG3(CLK_CNT); END IF; END IF; END PROCESS; END SERILAISER_arc; Чтобы выходные сигналы то-же удалилась я из объявил как CLKn :OUT STD_LOGIC_VECTOR(CLK_MATRIX - 1 DOWNTO 0) При сборке проекта Quartus все ещё выкатывает warning но теперь эти сигналы удаляются. Если их просто объявить как STD_LOGIC, то они остаются, в проекте но никуда не подключатся. Поскольку процесса, создающего этот сигнал нет. Подозреваю что при прошивке ПЛИС они вообще удаляются. Изменено 28 октября, 2016 пользователем makc code => codebox - spoiler Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 192 28 октября, 2016 Опубликовано 28 октября, 2016 · Жалоба Admin: при вставке кода пользуйтесь тегом codebox. Не загромождайте тему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 17 ноября, 2016 Опубликовано 17 ноября, 2016 (изменено) · Жалоба А на сколько допустимо применение в VHDL оператора NULL ? Есть такой код, которой формируется в процессе работ машины состояний: WORK_STATE_MACHINE:PROCESS ( PRESS_STATE ) BEGIN REQ_RD <= '0'; -- По умолчанию нет запроса на чтение REQ_WR <= '0'; -- По умолчанию нет запроса на запись CNT_ENA <= '0'; -- Работа счетчиков запрещена RESET_ALL_COUNTER <= '0'; -- Запрещено сбрасывать сётчики CASE PRESS_STATE IS WHEN IDLE => NULL; -- В состоянии ожидания ничего не делаем WHEN READ_DATA => -- В состоянии чтения SDRAM памяти REQ_RD <= '1'; -- Посылаем запрос на чтение CNT_ENA <= '1'; -- Разрешаем работу счётчиков - формирователей адреса WHEN NEW_FRAME => -- В состоянии поступившего нового кадра RESET_ALL_COUNTER <= '1'; -- Сбрасываем счетчики - формирователи адреса WHEN WRITE_DATA => -- В состоянии записи данных в SDRAM REQ_WR <= '1'; -- Посылаем запро на запись CNT_ENA <= '1'; -- Разрешаем работу счётчиков - формирователей адреса WHEN WAIT_FIFO_READING => NULL; -- В состоянии ожидания опустошения FIFO буфера мтарицы ничего не делаем WHEN OTHERS => NULL; END CASE; END PROCESS; По логике работы есть 2 состояния, в которых мне никакие сигналы формировать не надо. Допустимо ли применять в этом случае оператор NULL. Нет ли каких подводных камней у этого оператора. В книжках ничего толкового про это не написано.... Изменено 17 ноября, 2016 пользователем Flip-fl0p Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 17 ноября, 2016 Опубликовано 17 ноября, 2016 · Жалоба В операторе case вы обязаны перечислить все возможные состояния. Если в каких-то из них ничего делать не надо, то и используется null. CASE PRESS_STATE IS WHEN IDLE => NULL; -- В состоянии ожидания ничего не делаем WHEN WAIT_FIFO_READING => NULL; -- В состоянии ожидания опустошения FIFO буфера мтарицы ничего не делаем WHEN OTHERS => NULL; Тут idle и wait_fifo_reading можно опустить, потому что есть others с таким же (без)действием. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться