Как мы все знаем, существует два основных языка описания оборудования (HDL), используемых для разработки FPGA:Верилог и VHDL, VHDL появился раньше, чем Verilog, и благодаря простоте синтаксиса и схожести с языком C Verilog широко используется крупными компаниями.
На самом деле я выучил язык VHDL в колледже. Позже, поскольку компания использовала Verilog, я снова выучил Verilog. К счастью, у меня есть основа языка C, и Verilog быстро начал работать.
Существуют три основные версии стандартных документов Verilog, а именно:Верилог-1995, Верилог-2001, Верилог-2005, опубликованы IEEE. Последним стандартом Verilog является версия 2005. По сравнению с двумя предыдущими версиями версия 2005 проще и гибче.
Хотя некоторые официальные коды, такие как некоторые основные коды IP Xilinx, по-прежнему основаны на стандарте Verilog-2001, чтобы быть совместимыми с предыдущими инструментами синтеза, я по-прежнему настоятельно рекомендую вам использовать последний стандарт Verilog-2005.
Таким образом, эта статья основана на стандарте синтаксиса IEEE-2005, а именно «IEEE P1364-2005/D3: проект стандарта для аппаратного обеспечения Verilog®. Язык описания" официальный стандартный документ. Посмотреть в конце статьиОфициальный стандартный документ IEEE-2005получить метод.
Хорошая спецификация кода может улучшить читаемость, возможность повторного использования, простоту и ясность кода, что также является проявлением профессионального качества.
наша цель:Write Nowhere, Read Everywhere
Каково содержание?
-
название
- именование файлов
- наименование порта
- именование переменных
- наименование параметра
-
структура
- весь кадр
- портовая декларация
- Пробелы и отступы делают код более понятным
- Скобки улучшают читаемость
-
создавать экземпляр
-
Примечания
-
разное
-
Загрузка стандарта IEEE-2005
название
Именование в основном включает в себя имена файлов и модулей, имена портов, имена переменных, имена параметров и т. д. В двух словах:содержательно, коротко и легко читается, главное этоне используйте пиньинь!
именование файлов
Имя файла и имя модуля совпадают, и в один файл записывается только один модуль.
Имена файлов должны быть осмысленными, короткими и легко читаемыми.Используйте строчные буквы для имен файлов и разделяйте имена файлов символами подчеркивания.
- Базовый модуль класса драйвера назван с использованием
drv_xxx
тип, например:drv_led.v
,drv_i2c.v
,drv_ad7606.v
- Последовательный порт отправляет байт:
uart_tx_byte.v
- Асинхронный и синхронный FIFO, с указанием глубины и ширины:
fifo_async_512_16.v
иfifo_sync_256_64.v
Имя файла TestBench запрашивает имя исходного файла, за которым следует _tb, например, исходный файлdrv_led.v
, соответствующий файл тестового стенда называетсяdrv_led_tb.v
Модули верхнего уровня единообразно именуются какtop.v
,илиtop_project_name.v
, например, верхний уровень примера проекта чтения и записи EEPROM называетсяtop_eeprom_demo.v
наименование порта
Именование портов такое же, как и имя файла, с однородным использованием строчных букв и разделением их символами подчеркивания.
Если это модуль верхнего уровня и подключен к фактическому выводу FPGA, добавьте_pad_i
,_pad_o
,_pad_io
чтобы назвать его, указывая, что он подключен к фактическому аппаратному выводу FPGA.
именование переменных
- Унифицированное использование тактовых сигналов
clk
Имя, если это конкретная тактовая частота, вы можете добавить тактовую частоту после, напримерclk_50m
- Сигнал сброса именуется сначала единообразно, если он активен на низком уровне, после него добавляется _n, например
rst_n
- Именование флаговых битов:
flag_rise/flag_fall/flag_clr
- Добавлено наименование зарегистрированного сигнала ударов
_reg
:reg rxd_reg
- Добавить суффикс для именования регистров сдвига
_sreg
:reg [3:0] busy_sreg
Некоторые распространенные сокращения:
сокращение | все заклинания | значение |
---|---|---|
rst | reset | перезагрузить |
clk | clock | Часы |
rd | read | читать |
wr | write | написать |
addr | address | адрес |
ack | acknowledge | отклик |
Более распространенные аббревиатуры имен портов и переменных можно найти в следующих статьях:
blog.CSDN.net/сердечная ручка мечты…
наименование параметра
Параметры в Verilog аналогичны определениям в языке C, есть следующие две категории.localparam
иparameter
, разница между ними заключается в том, что первый не может передавать параметры во время создания экземпляра, а второй может передавать параметры во время создания экземпляра.
Для других переменных имена файлов все в нижнем регистре, только определения параметров имеютобработка всех заглавных букв, когда вам нужно определить некоторые константы, вы можете указать значимое имя через объявление параметра. как:
parameter LED_ON = 1'b0;
parameter LED_OFF = !LED_ON;
parameter BAUD_RATE = 115200;
parameter TIME_100MS = 25_000_000;
Состояние конечного автомата обычно определяется с помощью localparam и указанием осмысленного имени, единообразно с использованием формата Sn_NAME и указанием разрядности. как:
localparam S0_IDLE = 4'd0;
localparam S1_START = 4'd1;
localparam S2_DOING = 4'd2;
localparam S3_END = 4'd3;
localparam S_FINISH = 4'd4;
localparam S_ERROR = 'd5;//auto adaptive
структура
весь кадр
Рекомендуется, чтобы файл модуля Verilog был записан в следующей структуре.
/* 1.文件头: 说明版权信息,文件功能,作者,版本历史等 */
/* 2.端口声明: input/output/inout */
/* 3.宏定义: `define */
/* 4.参数定义: localparam/parameter */
/* 5.寄存器定义: reg */
/* 6.线网类型定义: wire */
/* 7.互联定义: assign */
/* 8.时序逻辑描述: always */
Пример:
/* 1.file head */
/***********************************************************
Copyright 2021 'wechat:mcu149'. All rights reserved.
FileName: drv_led.v
Function: led driver
Author : mcu149
SVN :
SVN Revision: 1490
SVN Date: 2021-06-05 19:49:49
Revision:
2020-09-09: Rev 1.0
2020-10-01: Rev 1.1
************************************************************/
/* 2.input/output/inout */
module drv_led(
//Inputs
input rst_n,
input clk_50m,
input en,
//Outputs
output led1,
output reg led2 = 0 //define initial value is 0
);
/* 3.define */
/* 4.parameter/localparam */
parameter TIME_500MS = 32'd25_000_000;
/* 5.reg */
reg [31:0] cnt = 0;
/* 6.wire */
wire flag_toggle = (cnt == TIME_500MS);
/* 7.assign */
assign led1 = (en == 0) ? 0 : cnt[20];
/* 8.always block */
always @ (posedge clk_50m) begin
if(!rst_n)
cnt <= 0;
else if(flag_toggle)
cnt <= 0;
else
cnt <= cnt + 1;
end
always @ (posedge clk_50m) begin
if(!rst_n)
led2 <= 0;
else if(!en)
led2 <= 0;
else if(en) begin
if(flag_toggle)
led2 <= !led2;
end
end
endmodule
портовая декларация
Входные порты объединяются, выходные порты объединяются, а двунаправленные порты объединяются. Если выходному сигналу необходимо определить начальное значение, его можно указать непосредственно при определении порта, что также является новой функцией, добавленной в Verilog-2005.
На этом этапе некоторые друзья могут быть разделены по функциям, например, по соединению одного и того же чипа.
Преимущество разделения ввода и вывода заключается в том, что при создании экземпляра легко различить, что является вводом, а что — выходом.
Пробелы и отступы делают код более понятным
- Добавление пробела к обоим концам оператора может сделать структуру программы более понятной и читаемой.
- Стиль отступа принимает стиль KR, то есть начало пишется в конце строки и не занимает отдельной строки, а конец занимает отдельную строку.
- Отступ равномерно использовать 4 пробела вместо клавиши TAB
- Если/else и другие операторы состоят только из одной строки, то begin-end можно не указывать.
- Разумно добавляйте пустые строки, чтобы различать блоки, и разделяйте разные всегда блоки символами новой строки.
Ниже приведены спецификации написания этих двух кодов: Разумные отступы и разумное увеличение пробелов значительно повышают удобочитаемость.
Скобки улучшают читаемость
В школе есть несколько экзаменационных вопросов, чтобы проверить владение учениками различными операторскими приоритетами, даны некоторые античеловеческие вопросы.
Выполнение практического проекта не похоже на экзамен, преследуется читабельность и простота использования, поэтому при использовании нескольких операторов, чтобы повысить читаемость и избежать двусмысленности, не скупитесь на скобки для обозначения приоритета операций.
создавать экземпляр
Создание экземпляра можно рассматривать как душу разработки FPGA.Процесс создания экземпляра на самом деле является процессом вызова аппаратного модуля.Например, мы используем Verilog для описания модуля декодера 3-8, который можно использовать в разных местах (создание экземпляра) он , и названные ut0/ut1/ut2 и т. д., а также могут указывать параметры во время создания экземпляра, такие как модули отправки и получения последовательного порта, для достижения совместимости с различными скоростями передачи данных путем указания разных параметров.
- Порядок создания экземпляра и объявления порта согласован, входные порты размещаются вместе, а выходные порты размещаются вместе.
- Для многобитных сигналов необходимо указывать ширину в битах при создании экземпляра для повышения удобочитаемости.
- Модуль верхнего уровня только создает экземпляр модуля и не записывает никаких операторов управления.
Пример:
wire [7:0] rx_data;
wire rx_done;
wire rx_err;
/* 串口接收1字节 */
uart_rx_byte #(
.BAUD_RATE(32'd115200),
.EN_PARITY(2'd0), //0:无校验位, 1:奇校验, 2:偶校验
.EN_STOP_2(1'b0) //1:使能2位停止位
)uart_rx_byte_0(
// Inputs
.clk(clk_32m),
.rst_n(rst_n),
.rxd(uart_rxd),
// Outputs
.data_rx(rx_data[7:0]), //指定位宽
.done(rx_done),
.err(rx_err)
);
Примечания
Не верьте, какой код является лучшим комментарием! Я не отрицаю, что код некоторых людей написан очень хорошо, с разумными именами и понятным форматом.
Но я не думаю, что вы дошли до того момента, когда нет гарантии, что каждый сможет прочитать некомментированный код. Комментарии предназначены не только для просмотра другими, но и для них самих.Хорошая память не так плоха, как плохое письмо.
Унифицированное использование аннотаций/**/
аннотацию или используйте//
Смешанное использование, см. личные привычки!
- Функция переменной должна быть аннотирована после каждого определения переменной.
- Каждая всегда блокирующая функция требует комментария
- Значение состояния конечного автомата должно быть аннотировано
- Комментарии должны быть добавлены после условного оператора
- Модификация кода, комментарии также должны быть изменены соответствующим образом
разное
- Разумное использование generate for может определять и создавать экземпляры модулей в пакетах, уменьшая объем кода и улучшая читаемость.
- Использование задач и функций в тестовом стенде может повысить эффективность
- Операция сдвига заменена операцией сращивания и заполнения 0, которая легче читается.
- Последовательная логика единообразно использует неблокирующее присваивание, то есть
<=
символ - Строка символов не должна превышать 80 символов. Если она слишком длинная, ее следует обработать переносом
- Сначала существует дизайн верхнего уровня, а затем функции подмодуля разделяются, или подход снизу вверх.
- Модульная конструкция для улучшения возможности повторного использования модуля
- Старайтесь не использовать if/else, если вы можете использовать case
- переменная типа reg, проверьте, защелкивается ли она по мере необходимости
Загрузка стандарта IEEE-2005 Verilog
Обратите внимание на общедоступную учетную запись (ID: обучение разработке электронных схем) справочный ответ [Стандарт Verilog】ПолучатьIEEE_Verilog_1364_2005.pdfСтандартный документ.
Отрицательный пример спецификации кода Verilog, вы можете обратиться к:Как написать код Verilog, который не могут поддерживать мои коллеги?