maximka 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба Хочу сделать приемник последовательного кода. Есть две линии, если по одной приходит фронт (IN-1), то в выходной параллельный код записываем 1, если по IN_0, то записываем 0. Раньше рисовал все в MAX_PLUS !! c использованием примитивов и насколько помню, что для того чтоб дизайндоктор не ругался все должно быть синхронно, тоесть все это должно синхронизироваться CLK. Quartus 2 пишет ошибки multiply clock edge. Тоесть ему не нравиться IN_1'event и IN_0'event, я и сам чувствую что что-то здесь не то, подскажите как решить поставленную задачу и объясните в чем ошибка. Спасибо. library IEEE; use IEEE.std_Logic_1164.all; entity tg is port( CLK,IN_1,IN_0 : in std_logic; PO : out std_logic_vector(7 downto 0)); end tg; architecture archi of tg is signal tmp : std_logic_vector(7 downto 0); begin shift: process(clk) begin if (IN_1'event and IN_1='1') then tmp <=tmp(6 downto 0)&'1'; end if; if (IN_0'event and IN_0='1') then tmp <=tmp(6 downto 0)&'0'; end if; end process; PO <= tmp; end archi; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба Так в этом и ошибка, на что ругался Квартус. Атрибут сигнала Event означает, что условие истинно только в момент изменения сигнала, то есть это детектор фронта и этот атрибут может синтезироваться только в клоковый вход триггера. В Вашем процессе три таких атрибута - еще один используется неявно в конструкции process(clk). Так как в FPGA нет триггеров с тремя клоками, синтезатор не может синтезировать ваш код. Кроме того, Вы в коде требуете чтобы некоторые действия происходили когда два клока приходят одновременно - клока и одного из входов. С физической точки зрения это бессмыссленно, хоть и допустимо в VHDL. Думаю, Ваши сложности связаны с тем, что Вы хотите использовать атрибут Event для диагностирования фронта в дискретном времени в процессе, а этот атрибут предназначен только для сигналов в непрерывном времени. Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в VHDL есть только один путь - по фронту clk запоминать предыдущее значение сигнала и в условиях явно сравнивать текущее значение с предыдущим, заменив члены IN_x'event на IN_x_prev = '0'. И обеспечить синхронность сигналов IN_x по отношению к clk поставив на входы синхронизаторы, если их еще нет где-нибудь в другом месте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sK0T 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба Quartus 2 пишет ошибки multiply clock edge. Тоесть ему не нравиться IN_1'event и IN_0'event, я и сам чувствую что что-то здесь не то, подскажите как решить поставленную задачу и объясните в чем ошибка. Не так здесь на мой вкус подход к проектированию. Надо делать синхронно, if rising_edge(clk) then и дальше case на четыре варианта линий IN_1 и IN_0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба Хочу сделать приемник последовательного кода. Есть две линии, если по одной приходит фронт (IN-1), то в выходной параллельный код записываем 1, если по IN_0, то записываем 0. Раньше рисовал все в MAX_PLUS !! c использованием примитивов и насколько помню, что для того чтоб дизайндоктор не ругался все должно быть синхронно, тоесть все это должно синхронизироваться CLK. а это вам зачем так подходить к вопросам последовательной передачи - по фронту. что за ТЗ такое и в соответствии с каким стандартом? если уж таким макаром организовывать передачу - то рассматривайте проблему лучше не с точки зрения фронтов а изменения уровней (некоторые скажут что это одно и то же - но это не так) и ещё одна подсказка подумайте в сторону увеличения опорного синхросигнала относительно скорости передачи в несколько раз Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maximka 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба а это вам зачем так подходить к вопросам последовательной передачи - по фронту. что за ТЗ такое и в соответствии с каким стандартом? если уж таким макаром организовывать передачу - то рассматривайте проблему лучше не с точки зрения фронтов а изменения уровней (некоторые скажут что это одно и то же - но это не так) и ещё одна подсказка подумайте в сторону увеличения опорного синхросигнала относительно скорости передачи в несколько раз Задачка для самообучения. Цель - данные из кода Arinc перевести в любой параллельный код. Можно работать и по уровню, но по фронту кажется проще. Из вышепрочитанного пришел к выводу что оптимальный вариант - засинхронизироваться от CLK и ловить перепады сигналов. А кстати, можно ли так писать process( rising_edge(CLK)) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 4 июня, 2006 Опубликовано 4 июня, 2006 · Жалоба Можно работать и по уровню, но по фронту кажется проще. Из вышепрочитанного пришел к выводу что оптимальный вариант - засинхронизироваться от CLK и ловить перепады сигналов. А кстати, можно ли так писать process( rising_edge(CLK)) ? ага верно уловили идею - проблема ловли фронтов в дополнительных схемах по отлавливанию ложных фронтов при шуме и неудобству синтеза в ФПГА элементов чувствительных к фронту информационных(нетактирующих) сигналов - поэтому сажайте регистровую логику на тактирующий сигнал повышенный частоты (х8 или х16) и ловите уровни (повышенная частота нужна для отсеивания ложных перепадов) process( rising_edge(CLK)): нет по ИМХу нельзя rising_edge(CLK)- функция, возвращает булево значение = (clk'event AND clk = '1'), а process (clk) возвращает событие, заносимое в список ассоциированных с процессом инициирующих событий Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maximka 0 5 июня, 2006 Опубликовано 5 июня, 2006 · Жалоба Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в VHDL есть только один путь - по фронту clk запоминать предыдущее значение сигнала и в условиях явно сравнивать текущее значение с предыдущим, заменив члены IN_x'event на IN_x_prev = '0'. И обеспечить синхронность сигналов IN_x по отношению к clk поставив на входы синхронизаторы, если их еще нет где-нибудь в другом месте. А как мне взять предыдущее значение сигнала? Насколько я понимаю в процессе все операции выполняются одновременно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
o-henry 0 5 июня, 2006 Опубликовано 5 июня, 2006 · Жалоба А как мне взять предыдущее значение сигнала? Насколько я понимаю в процессе все операции выполняются одновременно. Заведите еще один процесс, в котором по фронту клока защелкивайте значение сигнала. И в вашем рабочем процессе по фронту клока сравнивайте текущее значение сигнала с этим защелкнутым на предыдущем такте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ishergin 0 5 июня, 2006 Опубликовано 5 июня, 2006 · Жалоба Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в VHDL есть только один путь - по фронту clk запоминать предыдущее значение сигнала и в условиях явно сравнивать текущее значение с предыдущим, заменив члены IN_x'event на IN_x_prev = '0'. И обеспечить синхронность сигналов IN_x по отношению к clk поставив на входы синхронизаторы, если их еще нет где-нибудь в другом месте. А как мне взять предыдущее значение сигнала? Насколько я понимаю в процессе все операции выполняются одновременно. Запомнить можно так например: ... signal IN_x_prev : std_logic; process (clk, rst) begin if rst = '1' then IN_x_prev <= '0'; elsif rising_edge(clk) then IN_x_prev <= IN_x; -- запоминаем end if; end process; .... .... process (clk, rst) begin if rst = '1' then tmp <= (others=>'0'); elsif rising_edge(clk) then if IN_x_prev = '1' then tmp <=tmp(6 downto 0)&'1'; elsif ........... then tmp <=tmp(6 downto 0)&'0'; end if; end if; end process; В Вашем коде нету сигнала сброса, а он должен быть :) В вышенаписанном коде будет задержка на 1 такт из-за конвейера. На форуме гдето был топик по использованию двух клоков, думаю Вам стоит там посмотреть, какие подводные камни могут встретится. Почитайте, например, вот это http://electronix.ru/forum/index.php?showtopic=15633 , там есть ссылки Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 5 июня, 2006 Опубликовано 5 июня, 2006 · Жалоба To maximka Скачайте с сайта xilinx документ xst.pdf (синтезабельное hdl описание счетчиков. триггеров, дешифраторов и т.д. И переведите в лоб свою графику на текст. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maximka 0 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба Ну эту задачу я решил. Теперь пытаюсь ее усложнить. Данный код самосинхронезирующийся. По протоколу передаются 32 бита и как бы признаком конца слова является пауза после 32 бита длительностью 4 такта (пусть 0,5 мкс). Вопрос, как мне сделать анализатор паузы в 4 такта. Пример: library IEEE; use IEEE.std_Logic_1164.all; entity tg is port( RST,CLK,IN_1,IN_0 : in std_logic; PAUSE: out std_logic; PO : out std_logic_vector(7 downto 0)); end tg; architecture archi of tg is shared variable a,b:integer; signal tmp,time : std_logic_vector(7 downto 0); signal pr,IN_1_prev,IN_0_prev :std_logic; begin prev: process(CLK) -- в данном процессе сохраняем предыдущие значения begin if(rising_edge(CLK)) then IN_1_prev<=IN_1; IN_0_prev<=IN_0; a:=a+1; --тут я пытаюсь сделать счетчик клоков end if; end process prev; shift:process(CLK,RST) begin if (RST='1') then --обнулятор tmp<="00000000";--&"00000000"&"00000000"&"00000000"; elsif(rising_edge(CLK)) then if(IN_1='1' and IN_1_prev='0') --если есть перепад по IN_1, то then tmp <=tmp(6 downto 0)&'1'; --в результирующем слове сдвигаем 1. b:=a; --длительность b= одному такту a:=0; --сбрасываем счетчик клоков end if; if(IN_0='1' and IN_0_prev='0')then tmp <=tmp(6 downto 0)&'0'; --аналогично, только сдвигаем не 1, а 0 b:=a; a:=0; end if; end if; --if(a>2)then pr<='1';end if; end process shift; PO <= tmp;-- after 40 ns;--(std_logic_vector)a; PAUSE<=pr; end archi; В принципе так все вроде работает. Теперь надо сделать счетчик паузы по идее надо условие IF(4*b>a)then pr<='1';end if; но куда его не поставлю все время ошибки. подскажите как сделать анализатор паузы и в чем ошибки? И еще вопрос: чем переменная отличается от сигнала? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ishergin 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба Ну эту задачу я решил. Теперь пытаюсь ее усложнить. Данный код самосинхронезирующийся. По протоколу передаются 32 бита и как бы признаком конца слова является пауза после 32 бита длительностью 4 такта (пусть 0,5 мкс). Вопрос, как мне сделать анализатор паузы в 4 такта. Пример: library IEEE; use IEEE.std_Logic_1164.all; entity tg is port( RST,CLK,IN_1,IN_0 : in std_logic; PAUSE: out std_logic; PO : out std_logic_vector(7 downto 0)); end tg; architecture archi of tg is shared variable a,b:integer; signal tmp,time : std_logic_vector(7 downto 0); signal pr,IN_1_prev,IN_0_prev :std_logic; begin prev: process(CLK) -- в данном процессе сохраняем предыдущие значения begin if(rising_edge(CLK)) then IN_1_prev<=IN_1; IN_0_prev<=IN_0; a:=a+1; --тут я пытаюсь сделать счетчик клоков end if; end process prev; shift:process(CLK,RST) begin if (RST='1') then --обнулятор tmp<="00000000";--&"00000000"&"00000000"&"00000000"; elsif(rising_edge(CLK)) then if(IN_1='1' and IN_1_prev='0') --если есть перепад по IN_1, то then tmp <=tmp(6 downto 0)&'1'; --в результирующем слове сдвигаем 1. b:=a; --длительность b= одному такту a:=0; --сбрасываем счетчик клоков end if; if(IN_0='1' and IN_0_prev='0')then tmp <=tmp(6 downto 0)&'0'; --аналогично, только сдвигаем не 1, а 0 b:=a; a:=0; end if; end if; --if(a>2)then pr<='1';end if; end process shift; PO <= tmp;-- after 40 ns;--(std_logic_vector)a; PAUSE<=pr; end archi; В принципе так все вроде работает. Теперь надо сделать счетчик паузы по идее надо условие IF(4*b>a)then pr<='1';end if; но куда его не поставлю все время ошибки. подскажите как сделать анализатор паузы и в чем ошибки? И еще вопрос: чем переменная отличается от сигнала? Спасибо. А зачем Вам пауза, если и так известно скоко бит передается? Задержку легко можно реализовать на конечном автомате. У Вас несинтезируемый код: не надо использовать shared variable. Используйте сигналы, причем не надо присваивать ему одновременно значения в разных процесах, иначе получите сообщение об ошибке (Вы сейчас так делаете для переменной a ). Что касается отличия переменной от сигнала - то посмотрите в любой литературе по VHDL :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MurrVK 0 7 июня, 2006 Опубликовано 7 июня, 2006 (изменено) · Жалоба IMHO: Главным различием переменной и сигнала является то, что значение переменной изменяется непосредственно в момент присвоения ей нового занченя a:=b, теперь при дальнейшем выполнении прцесса, значение a будет b. Значение сигнала изменяется только по окончанию выполнения процесса. Запись вида a<=b только намечает транзакцию, которая выполнится после того как выполнится весь процесс. После этой строки в процессе значение a будет a до конца процесса. По крайней мере я так это понял и вроде как работает :) По эжтому принцыпу можно описать сдвиговый регистр signal a, b0, b1, b2, b3, b4, b5, b6, b7: std_logic; begin shiftreg: process(CLK) is begin if rising_edge(CLK) then b0<=a; b1<=b0; b2<=b1; b3<=b2; b4<=b3; b5<=b4; b6<=b5; b7<=b6; end if; end process; -- Вроде должен получиться 8 битный сдвиговый регистр :) end; Изменено 7 июня, 2006 пользователем Murr Von Kater Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ishergin 0 8 июня, 2006 Опубликовано 8 июня, 2006 · Жалоба IMHO: Главным различием переменной и сигнала является то, что значение переменной изменяется непосредственно в момент присвоения ей нового занченя a:=b, теперь при дальнейшем выполнении прцесса, значение a будет b. Значение сигнала изменяется только по окончанию выполнения процесса. Запись вида a<=b только намечает транзакцию, которая выполнится после того как выполнится весь процесс. После этой строки в процессе значение a будет a до конца процесса. По крайней мере я так это понял и вроде как работает :) По эжтому принцыпу можно описать сдвиговый регистр signal a, b0, b1, b2, b3, b4, b5, b6, b7: std_logic; begin shiftreg: process(CLK) is begin if rising_edge(CLK) then b0<=a; b1<=b0; b2<=b1; b3<=b2; b4<=b3; b5<=b4; b6<=b5; b7<=b6; end if; end process; -- Вроде должен получиться 8 битный сдвиговый регистр :) end; Сдвиг на произвольное количество бит :) http://tams-www.informatik.uni-hamburg.de/...l/shifter8.html -- ссылка приводилась недавно в соседних топиках. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maximka 0 15 июня, 2006 Опубликовано 15 июня, 2006 · Жалоба А зачем Вам пауза, если и так известно скоко бит передается? Задержку легко можно реализовать на конечном автомате. У Вас несинтезируемый код: не надо использовать shared variable. Используйте сигналы, причем не надо присваивать ему одновременно значения в разных процесах, иначе получите сообщение об ошибке (Вы сейчас так делаете для переменной a ). Что касается отличия переменной от сигнала - то посмотрите в любой литературе по VHDL :) Что значит несинтезируемый код и почему не надо использовать Shared value? Мне кажется что это очень удобно использовать для какого-нибудь служебного счетчика например. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться