Различия между сигналами и переменными в VHDL
В предыдущем уроке мы изучали объявление переменной внутри процесса. Переменные идеальны для локальной алгоритмической работы, но невидимы за пределами этого процесса. Когда нужно разделить значение с другими частями проекта, используется сигнал.
Сигналы объявляются в декларативной области архитектуры — то есть между строкой architecture <architecture_name> of <entity_name> is и ключевым словом begin.
Этот пост входит в серию базовых уроков VHDL.
Синтаксис объявления сигнала:signal <name> : <type>;
Сигнал может быть объявлен с начальным значением:signal <name> : <type> := <initial_value>;
Упражнение
В этом видеоуроке мы учимся объявлять сигнал и узнаем ключевое различие между переменной и сигналом.
Итоговый код, созданный в этом уроке:
entity T06_SignalTb is end entity; architecture sim of T06_SignalTb is signal MySignal : integer := 0; begin process is variable MyVariable : integer := 0; begin report "*** Process begin ***"; MyVariable := MyVariable + 1; MySignal <= MySignal + 1; report "MyVariable=" & integer'image(MyVariable) & ", MySignal=" & integer'image(MySignal); MyVariable := MyVariable + 1; MySignal <= MySignal + 1; report "MyVariable=" & integer'image(MyVariable) & ", MySignal=" & integer'image(MySignal); wait for 10 ns; report "MyVariable=" & integer'image(MyVariable) & ", MySignal=" & integer'image(MySignal); end process; end architecture;
Вывод консоли симулятора ModelSim:
VSIM 2> run # ** Note: *** Process begin *** # Time: 0 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=1, MySignal=0 # Time: 0 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=2, MySignal=0 # Time: 0 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=2, MySignal=1 # Time: 10 ns Iteration: 0 Instance: /t06_signaltb # ** Note: *** Process begin *** # Time: 10 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=3, MySignal=1 # Time: 10 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=4, MySignal=1 # Time: 10 ns Iteration: 0 Instance: /t06_signaltb # ** Note: MyVariable=4, MySignal=2 # Time: 20 ns Iteration: 0 Instance: /t06_signaltb ...
Анализ
Мы создали сигнал и переменную с одинаковым начальным значением 0. Хотя мы обращались к ним одинаково в процессе, вывод консоли показывает принципиальное различие. Ключевые отличия:
- Переменные используют оператор
:=и обновляются немедленно внутри процесса. - Сигналы используют оператор
<=; новое значение планируется и вступает в силу только когда процесс приостанавливается (например, на оператореwait). - Если сигналу присваивается несколько значений до возобновления процесса, «побеждает» только последнее присваивание, так как ранние запланированные значения перезаписываются.
В нашем примере первые два инкремента MySignal были потеряны, потому что они были перезаписаны до того, как оператор wait for 10 ns; приостановил процесс и обновил сигнал. Последующий инкремент появляется после приостановки, соответствую ожидаемому поведению.
Вывод
- Используйте переменные для временных значений, требующих немедленного локального обновления.
- Используйте сигналы, когда нужно передать изменения другим процессам или компонентам.
- Помните: присваивания сигналов планируются и фиксируются только при паузе процесса; множественные присваивания без паузы приведут к выживанию только последнего значения.
Перейти к следующему уроку »
VHDL
- Освоение знаковых и беззнаковых типов в VHDL: практические инсайты
- Переменные в VHDL: практические примеры и правила для надежного дизайна
- Облачные вычисления против традиционных: практическое сравнение
- Создание списков строк в VHDL: лучшие практики и пример
- Корректное завершение симуляции VHDL-тестбенча
- Реализация PWM-контроллера в VHDL: проектирование, симуляция и FPGA-демо
- Генерация случайных чисел в VHDL: от Uniform к OSVVM
- Использование внутрипроцессных процедур для более чистого проектирования FSM на VHDL
- Освоение функций VHDL: практическое руководство по эффективному дизайну
- Система навигации Beidou: как она отличается от GPS