Введение
Если посмотреть в любую книгу по программированию, то почти все они начинаются с программы "Hello World". Если вы написали такую программу, то можете быть уверены, что можете кое-что сделать на этом языке. Так что, я собираюсь показать, как написать такую программу на Verilog, перед тем, как приступить к программе счетчика.
Я тоже хочу показать Вам как написать программу "hello world" , а затем разработать "counter" /счетчик/ в Verilog.
Программа "Hello World"
Verilog Code:
//----------------------------------------------------- // “это моя первая программа в Verilog // Имя конструкции : hello_world // Имя файла : hello_world.v // Функция : Эта программа распечатает 'Hello World by Deepak' // Кодер : Deepak //----------------------------------------------------- module hello_world ; initial begin $display ("Hello World by Deepak"); #10 $finish; end endmodule // Конец модуля hello_world
Слова в голубом цвете - комментарии, темно красном - зарезервированные слова. Любая программа в Verilog начинается с зарезервированного слова 'module' <module_name>. В выше представленном обзаце 8-я строка содержит модуль hello_world. (Примечание: Перед заявленным модулем у нас могут быть предписания пред-процессаора компилятора такие как 'include', 'define')
[Эти директивы играют ту же роль, что и в языке C) или микропроцессоры, содержащие тысячи транзисторов. Поэтому: in). Сclude включает содержимое внешних файлов, а defin). Сe представляет механизм замены текста.]
Строка 10 содержит начальный блок: этот блок выполняется только один раз после начала вычислений при time=0 (0ns). Этот блок содержит два предписания, содержащиеся в начале 10-й строки и в конце 13-той строки. В Verilog, если у Вас вставляется несколько строк в блоке, Вам необходимо указать "begin" и "end" /"начало" и "конец"/. Модуль заканчивается зарезервированным словом 'endmodule', в нашем случае - в строке 15.
Результат выполнения программы "Hello World"
Hello World by Deepak
Конструктивный блок счетчика
Clock |
Тактовые импульсы |
Reset |
Логический сброс |
Enable |
Логическое включение |
Counter |
Счетчик |
Counter out |
Выход счетчика |
Спецификация счетчика
- 4-х бит синхронный счетчик.
- Синхронный сброс с активным высоким уровнем сигнала.
- Разрешающий сигнал с активным высоким уровнем.
Реализация счетчика
Verilog Code:
//----------------------------------------------------- // Это моя вторая Конструкция в Verilog // Название Конструкции : first_counter (первый чсетчик) // Имя файла : first_counter.v // Функции : Это 4-х битовый суммирующий счетчик с // синхронным сбросом высокого уровня и // с разрешающим сигналом активного высокого уровня //----------------------------------------------------- module first_counter ( clock , // запуск входа счетчика reset , // синхронный сброс с активным высоким уровнем сигнала enable , // Разрешающий сигнал для счетчика с активным высоким уровнем counter_out // 4-х битовый вектор выхода счетчика ); Конец списка портов //-------------Input Ports----------------------------- (порты ввода) input clock ; input reset ; input enable ; //-------------Output Ports----------------------------(порты ввода) output [3:0] counter_out ; //-------------Input ports Data Type-------------------(тип данных портов ввода) // По правилам - все порты ввода должны быть шинами wire clock ; wire reset ; wire enable ; //-------------Output Ports Data Type------------------(тип данных портов вывода) // Портами вывода могут быть ячейки памяти (reg) или шины reg [3:0] counter_out ; //------------Отсюда начинается код ------------------------- // Поскольку это счетчик с запуском по положительному фронту, //В список чувствительности блока, записанного ниже, добавляем положительный // фронт сигнала clock. always @ (posedge clock) begin : COUNTER // Имя блока // При каждом положительном фронте сигнала clock мы проверяем вход reset<br />// Если на входе reset логическая единица, мы загружаем в выход счетчика нули (4'b0000) if (reset == 1'b1) begin counter_out <= #1 4'b0000; end // Если на входе reset ноль, мы увеличиваем содержание счетчика else if (enable == 1'b1) begin counter_out <= #1 counter_out + 1; end end // Конец блока счетчика end // Коней модуля счетчика
Модуль тестирование счетчика
Любая цифровая схема, независимо от ее сложности, должна проходить проверку правильности своей работы. Для счетчика необходимо иметь тактовый сигнал и логику сброса. После выхода счетчика из сброса, на вход разрешения подается разрешающий уровень и происходит проверка выходных сигналов на предмет правильности счета. Так делается на реальном счетчике и то же самое делается при помощи Verilog.
Test case |
Тестовый случай |
Clock gen |
Генерация тактового импульса |
Reset logic |
Логический сброс |
Enable logic |
Логическое включение |
Counter |
Счетчик |
Monitor/Checker |
Монитор/устройство проверки |
Рабочее окружение (тестбенч) для счетчика состоит из тактового генератора, управления сбросом, управления разрешением работы и логикой сравнения выхода с требуемыми значениями.
Verilog Code:
`include "first_counter.v" module first_counter_tb(); // Объявление ввода как регистра, а вывода как шины reg clock, reset, enable; wire [3:0] counter_out; // Инициализация всех переменных initial begin $display ("time\t clk reset enable counter"); $monitor ("%g\t %b %b %b %b", $time, clock, reset, enable, counter_out); clock = 1; // начальное значение тактов счетчика reset = 0; // задание начального значения сброса enable = 0; // задание начального сигнала разрешения #5 reset = 1; // активировать сброс #10 reset = 0; // деактивировать сброс #10 enable = 1; // активировать разрешение #100 enable = 0; // деактивировать разрешение #5 $finish; // завершить симуляцию end // Генератор тактовых импульсов always begin #5 clock = ~clock; // переключение вывода clock каждые 5 тактов end // Подключить проверяемое устройство first_counter U_counter ( clock, reset, enable, counter_out ); endmodule
Code:
<span style="color: black; font-size: small;"> time clk reset enable counter 0 1 0 0 xxxx 5 0 1 0 xxxx 10 1 1 0 xxxx 11 1 1 0 0000 15 0 0 0 0000 20 1 0 0 0000 25 0 0 1 0000 30 1 0 1 0000 31 1 0 1 0001 35 0 0 1 0001 40 1 0 1 0001 41 1 0 1 0010 45 0 0 1 0010 50 1 0 1 0010 51 1 0 1 0011 55 0 0 1 0011 60 1 0 1 0011 61 1 0 1 0100 65 0 0 1 0100 70 1 0 1 0100 71 1 0 1 0101 75 0 0 1 0101 80 1 0 1 0101 81 1 0 1 0110 85 0 0 1 0110 90 1 0 1 0110 91 1 0 1 0111 95 0 0 1 0111 100 1 0 1 0111 101 1 0 1 1000 105 0 0 1 1000 110 1 0 1 1000 111 1 0 1 1001 115 0 0 1 1001 120 1 0 1 1001 121 1 0 1 1010 125 0 0 0 1010 </span>