Как привязать интерфейс к нескольким портам без дублирования кода?

В этом примере, как мне создать один оператор привязки интерфейса, который можно повторно использовать для обоих портов модуля:

module adderSubtractor2(
  input            clk,
  input [7:0]      a0,
  input [7:0]      b0,
  input            doAdd0, // if this is 1, add; else subtract
  output reg [8:0] result0
`ifdef HAS_UNIT_2
  ,
  input [7:0]      a1,
  input [7:0]      b1,
  input            doAdd1, // if this is 1, add; else subtract
  output reg [8:0] result1  
`endif
);
  // ...
endmodule

interface adderSubtractor_if(
  input bit clk,
  input [7:0] a,
  input [7:0] b,
  input       doAdd,
  input [8:0] result
);
  // ...
endinterface: adderSubtractor_if

// BIND STATEMENT(S) HERE

// The test that will be run on the DUT
program automatic test(adderSubtractor_if addSub);
  initial begin
    // do stuff with interface
  end
endprogram // test

// The top level testbench.
module testbench;
  reg clk;
  adderSubtractor2 dut(.clk (clk));
  test test0(dut.adderSubtractor_if0);
`ifdef HAS_UNIT_2
  test test1(dut.adderSubtractor_if1);
`endif

  // ...
endmodule // testbench

person Victor Lyuboslavsky    schedule 22.06.2013    source источник
comment
Я не могу понять, что вы пытаетесь сделать. Вы определили интерфейс, но не используете его вообще. Вы спрашиваете об использовании интерфейсов или о том, как вы можете создать переменное количество интерфейсов для вашего модуля?   -  person Vasiliy    schedule 23.06.2013
comment
Я добавил дополнительные строки в приведенный выше пример, чтобы показать, как будет подключаться интерфейс.   -  person Victor Lyuboslavsky    schedule 23.06.2013


Ответы (2)


Я считаю, что то, что вы ищете, это параметризуемый интерфейс.

В общем, маскировать порты с помощью `ifdef очень рискованно, и у вас должны быть очень веские причины для этого. Эта тема уже обсуждалась здесь.

Я не вижу причин использовать `ifdef в вашем случае. Ты сможешь:

  1. определить параметр NUM_OF_INSTANCES

  2. определите все (кроме clk и rst) порты вашего модуля как упакованные массивы. то есть

    введите [1:NUM_OF_INSTANCES][7:0] а;

  3. используйте оператор generate for внутри модуля для создания экземпляров нескольких сумматоров

  4. Используйте параметризуемый интерфейс и привяжите его к портам модуля обычным способом.

Надеюсь это поможет.

person Vasiliy    schedule 23.06.2013
comment
В моем случае порты модуля adderSubtractor2 и весь код внутри этого модуля исправлены - код исходит от другой команды, и они не будут его менять. Каков мой выбор с точки зрения проверки? - person Victor Lyuboslavsky; 23.06.2013
comment
Стреляйте в дизайнера, написавшего код. Если это так, я предлагаю вам добавить отдельные привязки для каждого подмодуля (конечно, под `ifdef). Код с макросами, который вы написали (даже если он работает), выглядит странно, и люди, которые будут смотреть на ваш код в будущем, пострадают. Вы все равно будете страдать - вам придется добавлять эти `ifdefs в каждое место в вашем коде. Это очень плохой дизайн, и если его нельзя изменить, код проверки будет плохим. Я могу придумать несколько других вариантов, связанных с преобразованием определений в параметры, но они также уродливы и могут не работать. - person Vasiliy; 23.06.2013
comment
Кстати, вы не возражаете, если я добавлю ссылку на эту страницу для обсуждения `ifdefs по сравнению с генерацией? Я думаю, что этот пример показывает сильное злоупотребление `ifdefs. - person Vasiliy; 23.06.2013
comment
Конечно, добавляйте :). Спасибо за комментарии. - person Victor Lyuboslavsky; 23.06.2013

Вы можете использовать макросы:

`define BIND_ADD_SUB(INDEX) \
bind adderSubtractor2 adderSubtractor_if adderSubtractor_if``INDEX``( \
  .clk(clk), \
  .a(a``INDEX``), \
  .b(b``INDEX``), \
  .doAdd(doAdd``INDEX``), \
  .result(result``INDEX``) \
); \

`BIND_ADD_SUB(0)
`ifdef HAS_UNIT_2
`BIND_ADD_SUB(1)
`endif

Затем передайте dut.adderSubtractor_if0 и dut.adderSubtractor_if1 на свой тестовый стенд.

person Victor Lyuboslavsky    schedule 22.06.2013