У меня есть модуль systemverilog с МНОЖЕСТВОМ входных сигналов разного размера. Я хочу дополнительно зарегистрировать их перед использованием. Вот мои желаемые критерии для кода, который выполняет эту необязательную регистрацию:
Вот минимальный воспроизводимый пример моего текущего решения:
module optional_register #(
parameter bit REGISTER_INPUTS=1
)(
input wire clk,
input wire a_in,
input wire b_in,
input wire c_in,
input wire d_in,
output logic a_out,
output logic b_out,
output logic c_out,
output logic d_out
);
function assign_inputs();
a_out <= a_in;
b_out <= b_in;
c_out <= c_in;
d_out <= d_in;
endfunction
generate if (REGISTER_INPUTS) begin
always_ff @ (posedge clk)
assign_inputs();
end else begin
always_comb
assign_inputs();
end endgenerate
endmodule
Этот код правильно синтезируется в Vivado 2020.2 как с включенными, так и с выключенными регистрами. Но я обеспокоен тем, что неблокирующие назначения в функции технически недействительны, в соответствии с IEEE Std для Verilog (1364-2001), раздел «10.3.4 Правила функций», в котором говорится:
A function shall not have any nonblocking assignments.
Поэтому меня беспокоит то, что это не будет работать в других синтезаторах и может привести к неожиданному поведению при моделировании. Кто-нибудь может говорить об этом?
Любые другие идеи?
Это код SystemVerilog, вы должны использовать IEEE 1800-2017 LRM.
Неблокирующие назначения разрешены внутри функции, если цель LHS не является переменной с автоматическим временем жизни. Не используйте NBA для назначения выходных данных аргументов или возвращаемого значения функции со статическим временем жизни, поскольку их текущие значения копируются до того, как произойдет обновление NBA.
Вы должны объявить свою функцию без возвращаемого значения.
function void assign_inputs();
Использование NBA в комбинационной логике не является лучшим для производительности моделирования, но, как правило, является приемлемым с точки зрения функциональности.