Верилог-функции
Часто мы обнаруживаем, что определенные фрагменты кода повторяются и вызываются несколько раз в RTL. В основном они не требуют времени моделирования и могут включать сложные вычисления, которые необходимо выполнять с различными значениями данных. В таких случаях мы можем объявить function
и поместите повторяющийся код внутри функции и позвольте ей вернуть результат. Это значительно уменьшит количество строк в RTL, так как теперь все, что вам нужно сделать, это выполнить вызов функции. и передать данные, на которых должны быть выполнены вычисления. На самом деле это очень похоже на функции в C.
Цель функции — вернуть значение, которое должно использоваться в выражении. Определение функции всегда начинается с ключевого слова function
. за которым следует тип возвращаемого значения, имя и список портов, заключенный в круглые скобки. Verilog знает, что определение функции завершено, когда находит endfunction
ключевое слово. Обратите внимание, что функция должна иметь хотя бы один объявленный вход, а возвращаемый тип будет void
. если функция ничего не возвращает.
Синтаксис
function [automatic] [return_type] name ([port_list]);
[statements]
endfunction
Ключевое слово automatic
сделает функцию реентерабельной и элементы, объявленные в задаче, динамически распределяются, а не распределяются между различными вызовами задачи. Это будет полезно для рекурсивных функций и когда одна и та же функция выполняется одновременно N процессами при разветвлении.
Объявления функций
Есть два способа объявить входные данные для функции:
function [7:0] sum;
input [7:0] a, b;
begin
sum = a + b;
end
endfunction
function [7:0] sum (input [7:0] a, b);
begin
sum = a + b;
end
endfunction
Возврат значения из функции
Определение функции неявно создаст внутреннюю переменную с тем же именем, что и у функции. Следовательно, нельзя объявлять другую переменную с тем же именем внутри области действия функции. Возвращаемое значение инициализируется путем присвоения результата функции внутренней переменной.
sum = a + b;
Вызов функции
вызов функции является операндом с выражением и имеет синтаксис, как показано ниже.
reg [7:0] result;
reg [7:0] a, b;
initial begin
a = 4;
b = 5;
#10 result = sum (a, b);
end
Правила функции
- Функция не может содержать операторы с контролем времени, например #. , @ , подождите , позже , отменить
- Функция не может запустить задачу, поскольку она может занять время моделирования, но может вызывать другие функции.
- У функции должен быть хотя бы один вход
- Функция не может иметь неблокирующие назначения или
force-release
илиassign-deassign
- У функции не может быть триггеров
- У функции не может быть выхода или входа.
Рекурсивные функции
Функции, которые вызывают сами себя, называются рекурсивными функциями. В приведенном ниже примере написана рекурсивная функция для вычисления факториала заданного числа.
module tb;
initial begin
integer result = factorial(4);
$display("factorial(4) = %0d", result);
end
function automatic integer factorial(integer i);
integer result = i;
// This function is called within the body of this
// function with a different argument
if (i) begin
result = i * factorial(i-1);
$display("i=%0d result=%0d", i, result);
end else
result = 1;
return result;
endfunction
endmodule
Журнал моделирования xcelium> run i=1 result=1 i=2 result=2 i=3 result=6 i=4 result=24 factorial(4) = 24 xmsim: *W,RNQUIE: Simulation is complete
Verilog