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

Хочу сделать приемник последовательного кода. Есть две линии, если по одной приходит фронт (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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так в этом и ошибка, на что ругался Квартус. Атрибут сигнала Event означает, что условие истинно только в момент изменения сигнала, то есть это детектор фронта и этот атрибут может синтезироваться только в клоковый вход триггера. В Вашем процессе три таких атрибута - еще один используется неявно в конструкции process(clk). Так как в FPGA нет триггеров с тремя клоками, синтезатор не может синтезировать ваш код.

 

Кроме того, Вы в коде требуете чтобы некоторые действия происходили когда два клока приходят одновременно - клока и одного из входов. С физической точки зрения это бессмыссленно, хоть и допустимо в VHDL.

 

Думаю, Ваши сложности связаны с тем, что Вы хотите использовать атрибут Event для диагностирования фронта в дискретном времени в процессе, а этот атрибут предназначен только для сигналов в непрерывном времени. Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в VHDL есть только один путь - по фронту clk запоминать предыдущее значение сигнала и в условиях явно сравнивать текущее значение с предыдущим, заменив члены IN_x'event на IN_x_prev = '0'. И обеспечить синхронность сигналов IN_x по отношению к clk поставив на входы синхронизаторы, если их еще нет где-нибудь в другом месте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Quartus 2 пишет ошибки multiply clock edge. Тоесть ему не нравиться IN_1'event и IN_0'event, я и сам чувствую что что-то здесь не то, подскажите как решить поставленную задачу и объясните в чем ошибка.

 

Не так здесь на мой вкус подход к проектированию. Надо делать синхронно, if rising_edge(clk) then и дальше case на четыре варианта линий IN_1 и IN_0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хочу сделать приемник последовательного кода. Есть две линии, если по одной приходит фронт (IN-1), то в выходной параллельный код записываем 1, если по IN_0, то записываем 0.

Раньше рисовал все в MAX_PLUS !! c использованием примитивов и насколько помню, что для того чтоб дизайндоктор не ругался все должно быть синхронно, тоесть все это должно синхронизироваться CLK.

а это вам зачем так подходить к вопросам последовательной передачи - по фронту. что за ТЗ такое и в соответствии с каким стандартом? если уж таким макаром организовывать передачу - то рассматривайте проблему лучше не с точки зрения фронтов а изменения уровней (некоторые скажут что это одно и то же - но это не так) и ещё одна подсказка подумайте в сторону увеличения опорного синхросигнала относительно скорости передачи в несколько раз

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а это вам зачем так подходить к вопросам последовательной передачи - по фронту. что за ТЗ такое и в соответствии с каким стандартом? если уж таким макаром организовывать передачу - то рассматривайте проблему лучше не с точки зрения фронтов а изменения уровней (некоторые скажут что это одно и то же - но это не так) и ещё одна подсказка подумайте в сторону увеличения опорного синхросигнала относительно скорости передачи в несколько раз

 

Задачка для самообучения. Цель - данные из кода Arinc перевести в любой параллельный код.

Можно работать и по уровню, но по фронту кажется проще. Из вышепрочитанного пришел к выводу что оптимальный вариант - засинхронизироваться от CLK и ловить перепады сигналов.

 

А кстати, можно ли так писать process( rising_edge(CLK)) ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно работать и по уровню, но по фронту кажется проще. Из вышепрочитанного пришел к выводу что оптимальный вариант - засинхронизироваться от CLK и ловить перепады сигналов.

 

А кстати, можно ли так писать process( rising_edge(CLK)) ?

ага верно уловили идею - проблема ловли фронтов в дополнительных схемах по отлавливанию ложных фронтов при шуме и неудобству синтеза в ФПГА элементов чувствительных к фронту информационных(нетактирующих) сигналов - поэтому сажайте регистровую логику на тактирующий сигнал повышенный частоты (х8 или х16) и ловите уровни (повышенная частота нужна для отсеивания ложных перепадов)

 

process( rising_edge(CLK)):

нет по ИМХу нельзя rising_edge(CLK)- функция, возвращает булево значение = (clk'event AND clk = '1'), а process (clk) возвращает событие, заносимое в список ассоциированных с процессом инициирующих событий

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в VHDL есть только один путь - по фронту clk запоминать предыдущее значение сигнала и в условиях явно сравнивать текущее значение с предыдущим, заменив члены IN_x'event на IN_x_prev = '0'. И обеспечить синхронность сигналов IN_x по отношению к clk поставив на входы синхронизаторы, если их еще нет где-нибудь в другом месте.

 

А как мне взять предыдущее значение сигнала? Насколько я понимаю в процессе все операции выполняются одновременно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как мне взять предыдущее значение сигнала? Насколько я понимаю в процессе все операции выполняются одновременно.

 

Заведите еще один процесс, в котором по фронту клока защелкивайте значение сигнала.

И в вашем рабочем процессе по фронту клока сравнивайте текущее значение сигнала с этим защелкнутым на предыдущем такте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы получить предыдущее состояние сигнала в дискретном времни в процессе в 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 , там есть ссылки

 

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

To maximka

Скачайте с сайта xilinx документ xst.pdf (синтезабельное hdl описание счетчиков. триггеров, дешифраторов и т.д.

И переведите в лоб свою графику на текст.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну эту задачу я решил.

Теперь пытаюсь ее усложнить.

Данный код самосинхронезирующийся. По протоколу передаются 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;

но куда его не поставлю все время ошибки. подскажите как сделать анализатор паузы и в чем ошибки?

 

И еще вопрос: чем переменная отличается от сигнала?

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну эту задачу я решил.

Теперь пытаюсь ее усложнить.

Данный код самосинхронезирующийся. По протоколу передаются 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 :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;

Изменено пользователем Murr Von Kater

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 -- ссылка приводилась недавно в соседних топиках.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем Вам пауза, если и так известно скоко бит передается? Задержку легко можно реализовать на конечном автомате.

У Вас несинтезируемый код: не надо использовать shared variable. Используйте сигналы, причем не надо присваивать ему одновременно значения в разных процесах, иначе получите сообщение об ошибке (Вы сейчас так делаете для переменной a ). Что касается отличия переменной от сигнала - то посмотрите в любой литературе по VHDL :)

 

Что значит несинтезируемый код и почему не надо использовать Shared value? Мне кажется что это очень удобно использовать для какого-нибудь служебного счетчика например.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...