Основы работы в средах Logisim и Quartus Prime Lite
5. Процедурные блоки initial и always
Процедурный блок initial используется в основном для симуляции. Эта конструкция позволяет задавать начальные условия для симулируемой схемы, такие как инициализация регистров или создание масок и тестов.
В симуляциях блоки initial выполняются только один раз в момент старта симуляции. Это делает их идеальными для настройки начальных значений переменных и запуск тестов.
Блок always в Verilog предназначен для описания синхронных и асинхронных схем, а также для сложных комбинационных схем. Он используется для определения логики управления, где состояние выходных сигналов зависит от состояния входных сигналов.
Пример: always @ (posedge clock) . Приведенный код позволяет запускать логику только по фронту тактового сигнала.
В синхронных схемах данный процедурный блок позволяет задавать поведение схемы при определенном тактовом сигнале, что используется для создания регистров и других синхронных элементов.
В асинхронных схемах always применяется для описания поведения схем, которые реагируют на изменения входных сигналов немедленно, без учета тактового сигнала.
Общий вид записи: блока always @(<сигналы>) <действия>, где <сигналы> - это список всех входных сигналов, к которым чувствителен блок. Это список входных сигналов, изменение которых влияет на выходные сигналы этого блока. Выполнение оператора или операторов в блоке <действия> будет приостановлено, до тех пор, пока не произойдет изменение какого-либо из сигналов в списке чувствительности.
В списке чувствительности имена входных сигналов разделяются ключевым словом "or" , например, always @(a or b or d) <statements>.
Иногда гораздо проще и надежней включать в список чувствительности все сигналы. Это делается аналогично примеру: always @* <statements>.
Для присвоения значения сигналам в процедурных блоках initial и always применяются типы данных из класса переменных reg.
Как было отмечено выше reg - переменная, занимающая в памяти определенное число битов (диапазон *… : …+), по умолчанию - 1 бит.
Примеры объявления переменных:
reg a, b, c ; // три скалярные однобитовые переменные
reg signed [7:0] d1, d2; // две 8-битовые переменные со знаком
reg [7:0] Q[0:3][0:15] ; // двумерный массив 8-битовых переменных
reg clock = 0, reset=1; // две переменные типа reg с начальными значениями.
При использовании конструкции always для комбинационных и асинхронных последовательностных схем применяется оператор блокирующего присваивания (=). Операторы выполняются один за другим. Пример:
always @(*) //анализируем все сигналы begin y=a&b; z= a||b; end
Для проектирования последовательностной синхронной логики в блоке always применяется неблокирующее присваивание (<=). В данном случае список чувствительности содержит сигналы от значения которых зависит, когда произойдет сохранение значения переменной.
Пример:
wire d, clk; reg q; always @ (posedge clk) q<=d;
Пример неблокирующего присваивания для получения последовательного регистра приведен в листинге 1.5.
module nonb_trigger ( input d,clk, output reg q,q1,q2,q3); always @(posedge clk) begin q<=d; q1<=q; q2<=q1; q3<=q2; end endmoduleЛистинг 1.5.
Из описания модуля в листинге видно, что значения всех переменных формируются по фронту clk. Первый оператор присваивает переменной q значение с входа d, но при этом другие присваивания не блокируются. Так как значение d еще неизвестно, а оно будет известно только в следующем такте фронта clk, поэтому следует что значение на входе q1 изменится на следующем такте.
RTL представление модуля представлено на рисунке 1.15.
Для описания условий в Verilog применяются условия стандартные для высокоуровневых языков программирования. Пример приведен в листинге 1.4.
Общий вид записи:
if(<условие>) <действие1>; else <действие 2>;
Пример, описывающий применение данной конструкции, показан для D-триггера в листинге 1.6. Если на вход rst поступает лог. "0", триггер сбрасывается. В противном случае происходит неблокирующее присваивание переменной q данных с входа d по фронту сигнала clk.
always @(posedge clk or negedge rst_n) // Анализируем два сигнала begin if (!rst_n) // если вход rst_n переходит в 0 - спад q <= 1'b0; // сбрасываем выход else q <= d; // иначе на выход поступают данные или с переменной d endЛистинг 1.6.
Также в Verilog возможно применение конструкции else if, то есть проверка работы предыдущего условия. Если оно не исполнено, то осуществляется обработка условия в конструкции eslse-if, последующие конструкции не обрабатываются.
В листинге 1.7 приведен код для реализации двухразрядного дешифратора с применением конструкции eslse-if. На рисунке 1.16 приведено RTL представление модуля дешифратора.
module shifr ( input [1:0] in, // вход (2 разряда) output reg [3:0] out // выход (4 разряда) ); // проверка изменения сигналов на входе always @(*) begin // сброс выхода out = 4'b0000; // Дешифрация входного кода if (in == 2'b00) out = 4'b0001; // активен выход 0 else if (in == 2'b01) out = 4'b0010; // активен выход 1 else if (in == 2'b10) out = 4'b0100; // активен выход 2 else if (in == 2'b11) out = 4'b1000; // активен выход 3 else out=4'bxxxx; end endmoduleЛистинг 1.7.
Использование оператора if вводит большие задержки, потому что подразумевает вычисление выражения для сигналов (при моделировании работы схемы) в том порядке, в котором они появляются в модели (выражение в конечной ветви оператора if вычисляется последним).
Правильным и более выразительным вариантом проверки входных условий может быть метод case, который позволяет сделать выбор из многих вариантов (на языке схемотехники мультиплексор со многими входами).
Конструкция case схожа по синтаксису и формату применения с высокоуровневыми языками программирования.
Базовый синтаксис следующий:
case (<проверяемый операнд>) option1: <действие>; option2: <действие >; default: <если не работают условия выше>; endcase
В разделе "Комбинационные схемы" данного курса данная конструкция применяется при описании дешифратора семисегментного индикатора.
В листинге 1.8 приведен пример работы с case для описанного выше двухразрядного дешифратора.
module shifr1 ( input [1:0] in, //вход (2 разряда) output reg [3:0] out // выход (4 разряда) ); // проверка изменения сигналов на входе always @(*) begin // сброс выходов out = 4'b0000; // Дешифрация входного кода case (in) 2'b00: out = 4'b0001; // активен выход 0 2'b01: out = 4'b0010; // активен выход 1 2'b10: out = 4'b0100; // активен выход 2 2'b11: out = 4'b1000; // активен выход 3 default: out = 4'b0000; // по умолчанию сброшен endcase end endmoduleЛистинг 1.8.
На рисунке 1.17 приведена RTL схема данного модуля. Как видно из рисунка схема получила вид дешифратора.
6. Функции в языке Verilog
Для сокращения кода описываемого узла или устройства можно сводить повторяющиеся блоки в функции. Синтаксис функций схож с языком С.
Базовый синтаксис следующий:
Function [<возвращаемый тип>] <имя> ([список портов]) <действия> Endfunction
В листинге 1.9 приведен пример функции, реализующей 8-разрядный сумматора.
function [7:0] sum (input [7:0] a,b);// объявление функции портов и выходного тип данных и //аргумента begin sum=a+b;// реализуемая функция end endfunctionЛистинг 1.9.
На данном этапе обзор языка Verilog и его основных конструкций закончен.
С объемными материалами по разработке на FPGA с использованием Verilog можно ознакомиться:
Также рекомендуется изучение и применение дополнительной литературы и информационных источников:
- Соловьев В.В. Язык Verilog в проектировании встраиваемых систем на FPGA. - М.: Горячая линия - Телеком, 2022. - 440с.: ил.
- Акчурин А.Д., Юсупов К.М. Программирование на языке Verilog [Электронный ресурс] (Дата обращения 08.08.2024)
- Филиал МИРЭА в г. Фрязино Методические рекомендации для проведения лабораторных занятий по курсу "Цифровые системы" МЕ2200 [Электронный ресурс] (Дата обращения 15.07.2024)
- Сайт marsohod.org [Электронный ресурс] (Дата обращения 12.07.2024)
Дополнительная литература
по среде Logisim
- Скаков П.С., Яковлева В.Е. Архитектура ЭВМ: учебно-методическое пособие по лабораторным работам. - Санкт-Петербург: Университет ИТМО, 2023. - 99 с. - экз. [Электронный ресурс] (Дата обращения 15.09.2024)
- Попов Д.И., Лилов И.П. "Организация ЭВМ. Лабораторные работы в программе Logisim" Москва, 2011 [Электронный ресурс] (Дата обращения 15.09.2024)
- George Self Logisim Lab manual [Электронный ресурс] (Дата обращения 31.07.2024)
По языку Verilog HDL и среде Intel Quartus Prime Lite Edition
- Соловьев В.В. Язык Verilog в проектировании встраиваемых систем на FPGA. - М.: Горячая линия - Телеком, 2022. - 440с.: ил.
- Акчурин А.Д., Юсупов К.М. Программирование на языке Verilog [Электронный ресурс] (Дата обращения 08.08.2024)
- Филиал МИРЭА в г. Фрязино Методические рекомендации для проведения лабораторных занятий по курсу "Цифровые системы" МЕ2200 [Электронный ресурс] (Дата обращения 15.07.2024)
- Сайт marsohod.org [Электронный ресурс] (Дата обращения 12.07.2024)