Опубликован: 17.03.2025 | Доступ: свободный | Студентов: 0 / 0 | Длительность: 07:30:00
Лекция 1:

Основы работы в средах Logisim и Quartus Prime Lite

Лекция 1: 12345 || Лекция 2 >

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.


Рис. 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.

Рис. 1.16.

Использование оператора 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 схема данного модуля. Как видно из рисунка схема получила вид дешифратора.


Рис. 1.17.

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 можно ознакомиться:

  1. на курсе "Введение в FPGA и Verilog". (НИУ МФТИ).
  2. В рамках "Школы синтеза цифровых схем"

Также рекомендуется изучение и применение дополнительной литературы и информационных источников:

  1. Соловьев В.В. Язык Verilog в проектировании встраиваемых систем на FPGA. - М.: Горячая линия - Телеком, 2022. - 440с.: ил.
  2. Акчурин А.Д., Юсупов К.М. Программирование на языке Verilog [Электронный ресурс] (Дата обращения 08.08.2024)
  3. Филиал МИРЭА в г. Фрязино Методические рекомендации для проведения лабораторных занятий по курсу "Цифровые системы" МЕ2200 [Электронный ресурс] (Дата обращения 15.07.2024)
  4. Сайт marsohod.org [Электронный ресурс] (Дата обращения 12.07.2024)

Дополнительная литература

по среде Logisim

  1. Скаков П.С., Яковлева В.Е. Архитектура ЭВМ: учебно-методическое пособие по лабораторным работам. - Санкт-Петербург: Университет ИТМО, 2023. - 99 с. - экз. [Электронный ресурс] (Дата обращения 15.09.2024)
  2. Попов Д.И., Лилов И.П. "Организация ЭВМ. Лабораторные работы в программе Logisim" Москва, 2011 [Электронный ресурс] (Дата обращения 15.09.2024)
  3. George Self Logisim Lab manual [Электронный ресурс] (Дата обращения 31.07.2024)

По языку Verilog HDL и среде Intel Quartus Prime Lite Edition

  1. Соловьев В.В. Язык Verilog в проектировании встраиваемых систем на FPGA. - М.: Горячая линия - Телеком, 2022. - 440с.: ил.
  2. Акчурин А.Д., Юсупов К.М. Программирование на языке Verilog [Электронный ресурс] (Дата обращения 08.08.2024)
  3. Филиал МИРЭА в г. Фрязино Методические рекомендации для проведения лабораторных занятий по курсу "Цифровые системы" МЕ2200 [Электронный ресурс] (Дата обращения 15.07.2024)
  4. Сайт marsohod.org [Электронный ресурс] (Дата обращения 12.07.2024)
Лекция 1: 12345 || Лекция 2 >