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

Здравствуйте.

 

Недавно осваиваю VHDL, поэтому сильно не ругайте, если вопрос тривиальный.

Вот несложный текст на VHDL.

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Test is
   Port (
  CLK	: 		in    std_logic;
  SH_OUT	:	out    std_logic
   );
end Test;

ARCHITECTURE TestAr OF Test IS

type TypeShiftReg is array (0 to 4) of std_logic_vector(0 TO 15);
type TypeClock is array (0 to 4) of std_logic;
signal ShiftReg	: TypeShiftReg :=(others => B"1010101010101010"); -- Delay Time Line
signal Clock : TypeClock := B"00000";

begin

 ClkProc : process(CLK)
begin
 for i in 0 to 4 loop
  Clock(i)<=CLK;
 end loop; 
  end process ClkProc;

 Equare : process(Clock)
begin
 for i in 0 to 4 loop
   if rising_edge(Clock(i)) then
     ShiftReg(i)(0) <= '1';
     ShiftReg(i)(1 to 15) <= ShiftReg(i)(0 to 14);
	SH_OUT<=ShiftReg(0)(15);
  end if;	 
 end loop; 
 end process Equare;

end TestAr;

Хочу управлять 5-ю сдвиговыми регистрами со своими независимыми клоками.

Однако при синтезе Quartus выдает сообщение "Error (10822): HDL error at Test.vhd(29): couldn't implement registers for assignments on this clock edge". ModelSim говорит "../Test.vhd(29): (vcom-1450) Actual (indexed name) for formal "s" is not a static signal name" - 29 строка это : if rising_edge(Clock(i)) then .

В Квартусовском хелпе по поводу этой ошибке комментариев нет.

Что здесь не так? И как выйти из положения?

 

Заранее спасибо.

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


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

Попробуйте вместо rising_edge() использовать (Clock(i)'event and Clock(i) = '1')

В этой ситуации тоже ошибки, на тот же условный оператор, но ошибки другие:

Quartus: Error (10818): "Can't infer register for "SH_OUT" at Test.vhd(29) because it does not hold its value outside the clock edge"

ModelSim: "../Test.vhd(29): Attribute "event" requires a static signal prefix."

 

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


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

Попробуйте

x0: for i in 0 to 4 generate 
  Equare : process(Clock(i))
begin
  
    if rising_edge(Clock(i)) then
      ShiftReg(i)(0) <= '1';
      ShiftReg(i)(1 to 15) <= ShiftReg(i)(0 to 14);
        --SH_OUT<=ShiftReg(0)(15);
      end if;     
     
  end process Equare;
end generate;

 

И вот эту строчку: SH_OUT<=ShiftReg(0)(15); надо в отдельный процесс

Изменено пользователем crono

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


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

Попробуйте

....

И вот эту строчку: SH_OUT<=ShiftReg(0)(15); надо в отдельный процесс

 

Эврика! Спасибо большое.

А с точки зрения теории языка - почему моя конструкция не работала?

 

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


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

Эврика! Спасибо большое.

А с точки зрения теории языка - почему моя конструкция не работала?

Думаю из-за того, что loop - последовательный оператор, а generate - параллельный. И в последовательном операторе переменная i - динамическая, а в generate - статическая. Т.е. generate эквивалентен в данном случае 5 процессам, а loop - нет.

А то, что, SH_OUT<=ShiftReg(0)(15); нужно в отдельный процесс, так это из-за того, что если оставить его в generate- то это будет эквивалентно присвоению одному сигналу 5-и других.

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


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

Хочу управлять 5-ю сдвиговыми регистрами со своими независимыми клоками.

....Что здесь не так? И как выйти из положения?

 

Заранее спасибо.

Вообще, не вдаваясь в подробности кода, можно сразу сказать, что 5 разных клоков - это не правильно...

Надо делать все под один системный клок. А на сдвиговые регистры подавать еще и сигнал "разрешения", в том случае, если он работает на более низкой частоте...

А иначе следующий вопрос будет о том, почему теряются воздействия и что-то не всегда работает...

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


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

Какая-то адова мешанина. Зачем вам массив из пяти якобы клоков, взятых из одного сигнала? Используйте везде CLK

Еще, если уж ссмотреть на ваш вариант, есть ощущение, что сигналом является массив Clock в целом, а не каждый из конкретных его элементов, а значит и атрибут 'event (который используется для rising_edge()) применим лишь ко всему массиву в целом, а не отдельным его элементам (это я про rising_edge(Clock(i)) )

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


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

Вообще, не вдаваясь в подробности кода, можно сразу сказать, что 5 разных клоков - это не правильно...

Надо делать все под один системный клок. А на сдвиговые регистры подавать еще и сигнал "разрешения", в том случае, если он работает на более низкой частоте...

А иначе следующий вопрос будет о том, почему теряются воздействия и что-то не всегда работает...

 

В принципе все эти сдвиговые клоки синхронные и порождения от одного клока - основного, поделенного на 10 и с разными фазами. В принципе можно сделать для всех регистров один клок, тогда с разными будет начальное значение счетчика на 10. Мне казалось, что с точки зрения синтеза это эквивалентно.

Пошел переделывать на один клок.

Спасибо.

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


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

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

Так что синтезатор заведет 1 клок на дерево, а остальные пустит по цепям обычной логики. При этом ему (синтезатору) будет очень сложно обеспечить нормальную работу с такими 'клоками'

Кроме этого, вы получите 10 разных клоковых доменов (причем они действительно будут разными, так как одному богу известно какие получатся фазовые сдвиги между клоками, запущенными по цепям логики), после чего все сигналы, которые эти домены пересекают, автоматически станут кросс-доменными, после чего вообще все прекратит работать, так как такие вещи требуют специальной синхронизации (см. ClockDomenCrossing и метастабильные состояние)

 

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


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

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

...

 

Спасибо за ликбез. Уже переделал.

Пока не очень понимаю, как с помощью энейбла осуществлять синхронизацию счетчиков на разные фазы. Полагал, что это удобнее сделать с помощью Set/Reset. Или функционально Enable (разрешение счета) и Set/Reset (присваивание значения) являются одинаково допустимым?

Позвольте еще один вопрос. Пишу, как уже говорил, на VHDL. Синтезирую в Quartus. Как при синтезе система понимает, что данный сигнал Clock, который должен быть разведен в виде клокового дерева?. Глобально намечается 2 клока от 2-х разных PLL (Cyclone IV). Насколько я понимаю, необходимо строить 2 клоковых дерева?

 

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


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

Пока не очень понимаю, как с помощью энейбла осуществлять синхронизацию счетчиков на разные фазы.

Ну как то так (на VHDL не пишу, поэтому могут быть неточности)

process Counter (clock)

begin

if (rising_edge(clock) and MyEnable) begin 
   ...
end

end process;

 

Полагал, что это удобнее сделать с помощью Set/Reset. Или функционально Enable (разрешение счета) и Set/Reset (присваивание значения) являются одинаково допустимым?
Вполне

 

Позвольте еще один вопрос. Пишу, как уже говорил, на VHDL. Синтезирую в Quartus. Как при синтезе система понимает, что данный сигнал Clock, который должен быть разведен в виде клокового дерева?.
Все, что заходит в process в виде if (rising_edge(clk)) (или эквивалента) потенциально является клоком. Синтезатор собирает все такие цепи, затем смотрит их источники. Это должны быть либо внешние пины (возможно пропущенные через буфер), либо DCM/PLL/etc. В зависимости от FPGA могут быть и другие источники для клоков (например в Xilinx Spartan 3 и далее это могут быть специальные клоковые мультиплексоры). Если ограничения на источники соблюдены, то эти цепи назначаются клоками и разводятся на клоковых деревьях.

 

Глобально намечается 2 клока от 2-х разных PLL (Cyclone IV). Насколько я понимаю, необходимо строить 2 клоковых дерева?
Синтезатор их сам построит. Смотрите отчет после синтеза - он должен в нем написать, какие сигналы стали клоками.

 

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


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

Синтезатор их сам построит. Смотрите отчет после синтеза - он должен в нем написать, какие сигналы стали клоками.

Спасибо за вразумление по данному вопросу.

Еще один наверное дилетантский вопрос, скорее теоретический. Не стал открывать новую тему, хотя прямого отношения к клокам и циклам он не имеет.

 

Вопрос касательно правильного использования списка чувствительности для синтеза и различий синтеза и моделирования.

Допустим имеется какой то в общем случае тривиальный код:

signal count : std_logic_vector (4 downto 0);
signal done : std_logic;
process(clk, clr, count_en)
    begin
        if clr = '1' then
            count <= "00000";
        elsif rising_edge(clk) then
            if count_en = '1' then
                count <= count + '1';
        end if;
        end if;
    end process;

Есть асинхронный сигнал сброса clr, заведенный в список чувствительности. Понятно. Есть клок clk, заведенный в список чувствительности, тоже понятно. Но, зачем в список чувствительности заводить count_en? Ведь условие с count_en не будет проверяться до появления Rising Edge clk, а значит бесполезно в списке чувствительности? Есть ли различия для синтеза и моделирования наличия в списке чувствительности этого сигнала?

Какие сигналы должны помещаться в список чувствительности для правильного синтеза, кроме очевидных, с которых начинаются какие-то условные операторы в просеccе?

 

Спасибо и извините, если это общее место.

 

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


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

Но, зачем в список чувствительности заводить count_en?
Незачем. Он там не нужен. Но это часто встречается, особенно у начинающих. Это не ошибка само по себе, но неаккуратненько. Кроме замедления моделирования из-за отработки лишних событий, вреда нет.

 

Есть ли различия для синтеза и моделирования наличия в списке чувствительности этого сигнала?
Нет.

Какие сигналы должны помещаться в список чувствительности для правильного синтеза, кроме очевидных, с которых начинаются какие-то условные операторы в просеccе?
Если этот процесс описывает триггер или логику с трггером/регистром на выходе, то в списке чувствительности должен быть тактовый сигнал и асинхронный сброс, если он используется. Больше ничего не нужно. Если процесс описывает только комбинационную логику, то в списке чувствительности должны быть все используемые входные сигналы.

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


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

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

Это только если сброс асинхронный. Если сброс синхронный, то в списке чувствительности только тактовый сигнал:)

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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