Как я могу назначить аргументы модуля в Verilog? - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть модуль Verilog, который имеет очень длинный список необходимых входов и выходов.

module mymodule(clock,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16,S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24);

Я пытаюсь написать тестовый стенд для этого модуля. Есть ли умный способ предоставить аргументы в виде массива. Около половины аргументов являются входными данными, а другая половина - выходными. Я попытался сделать что-то подобное, основываясь на своем ограниченном опыте verilog.

reg clk = 0;
reg inputs[16:0] = 0;
wire outputs[23:0];

mymodule tc(clk, inputs, outputs);     

Я хочу, чтобы переменные «входы» действовали как массив, который будет содержать все входы, а «выходы» также будут выполнять то же самое.

Я также хочу иметь возможность установить все входы на случайные значения

inputs = $random; 

Есть ли способ сделать это в Verilog или мне нужно инициализировать все переменные вручную?

Ответы [ 3 ]

0 голосов
/ 10 февраля 2020

Поскольку модуль определен с отдельными портами, каждый порт должен быть подключен индивидуально. Verilog не предоставляет встроенный способ автоматического подключения портов.

SystemVerilog имеет .* подключений, но работает только тогда, когда имя net / var соответствует имени порта. Таким образом, с SystemVerilog вы можете связаться с промежуточным назначением. (Примечание: все современные симуляторы Verilog поддерживают большинство, если не все, функции SystemVerilog. Просто измените вымирание файла с .v на .sv, чтобы включить)

logic clock;
logic [15:0] inputs;
wire [22:0] outputs;
wire m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16;
wire S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24;
assign {m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16} = inputs;
assign outputs = {S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24};
mymodule tc( .* );

Для Более чистое решение, я рекомендую плагин Emacs Verilog-Mode (существует оболочка vim ). Этот инструмент был специально создан для упрощения подключения к длинному списку портов и выполнения других повторяющихся задач, общих для проектов Verilog. Например, нижеприведенный код будет расширен до соединения индекс-индекс

/* mymodule AUTO_TEMPLATE (
  .m@       (inputs[\1]),
  .S@       (outputs[\1]),
); */
mymodule dut (/*AUTOINST*/);

Два следующих шаблона будут расширяться со смещением, за исключением m18, который явно подключается к inputs[13]. (я выбрал m18, потому что заметил, что нет m14 и он определен между m13 и m15)

/* mymodule AUTO_TEMPLATE (
  .m@       (inputs[@"(- \1 1)"]),
  .S@       (outputs[@"(- \1 6)"]),
); */
mymodule dut (
  .m18      (inputs[13]),
   /*AUTOINST*/);

или

/* mymodule AUTO_TEMPLATE (
  .m18      (inputs[13]),
  .m@       (inputs[@"(- \1 1)"]),
  .S@       (outputs[@"(- \1 6)"]),
); */
mymodule dut (/*AUTOINST*/);
0 голосов
/ 13 февраля 2020

Вы можете использовать директиву define для объединения отдельных битов в массивы в вашем тестовом стенде:

`define inputs {m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16}
`define outputs {S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24}

Затем вы можете использовать $ random task:

initial
begin

...

`inputs = $random;

...

end
0 голосов
/ 10 февраля 2020

Помимо использования какого-то рода генерации кода, в обычном Verilog вы должны подключать все порты по отдельности. Вы можете сделать что-то вроде:

reg  [2:0] inp = $random;
wire [2:0] outp;

mymodule my (clk, inp[1:0], inp[2], outp[1:0], outp[2], ...);

, чтобы присвоить все одному и тому же вектору, но все равно нужно все это напечатать.

...