Порты Verilog в Generate Loop

По причинам, которых нельзя избежать (требования Qsys), у меня есть несколько модулей Verilog, которые имеют много портов, с которыми было бы намного проще работать, если бы они были упакованы. Чтобы попытаться объяснить, что я имею в виду, вот пример:

module foo #(
    COUNT = 4
) (
    //Interface 0
    input  bar_0,
    output deadbeef_0,

    //Interface 1
    input  bar_1,
    output deadbeef_1,

    //Interface 2
    input  bar_2,
    output deadbeef_2,

    //Interface 3
    input  bar_3,
    output deadbeef_3,
);
...
endmodule

Теперь обычно можно сделать два векторизованных порта (например, input [COUNT-1:0] bar,), однако Qsys не может справиться с этим, если сигналы нужно подавать на разные интерфейсы - вы можете выбрать только целый порт, а не только один бит.

Как вы можете себе представить, это становится очень раздражающим, если внутренне вам нужно получить доступ к портам в чем-то вроде generate цикл, и это особенно проблематично, если у вас есть модуль с интерфейсами, которые имеют 10 портов, которые должны быть записаны 16 раз!

До этого момента я делал ручное добавление отображения в модуль. Снова и пример, чтобы объяснить - продолжая пример выше, у меня было бы что-то вроде этого в теле модуля:

wire [COUNT-1:0] bar;
wire [COUNT-1:0] deadbeef;
generate
if (COUNT > 0) begin
    assign bar[0] = bar_0;
    assign deadbeef_0 = deafbeef[0];
end else begin
    assign deadbeef_0 = 1'b0; //Terminate!
end
if (COUNT > 1) begin
    assign bar[1] = bar_1;
    assign deadbeef_1 = deafbeef[1];
end else begin
    assign deadbeef_1 = 1'b0; //Terminate!
end
...
endgenerate

// deadbeef[] and bar[] can now be used as arrays, woop.

Даже написать пару интерфейсов для двух сигналов в этом примере было невероятно утомительно!

Каждая часть программиста во мне кричит прекратить делать это, и что должен быть лучший путь. И это подводит меня к моему вопросу:

Есть ли простой способ сделать это?

В идеале у меня была бы какая-то форма цикла, которая генерирует эти отображения для меня, генерируя имена сигналов из переменной цикла. Но я не уверен, возможно ли это даже в Verilog.

Кроме того, просто для того, чтобы сделать вещи интересными, я использовал шестнадцатеричное значение для портов, чтобы упростить процесс записи, например:

input bar_0,
input bar_1,
...
input bar_9,
input bar_a,
input bar_b,
...

В идеале решение этой проблемы также могло бы справиться с такими именами, но, если честно, я мог бы легко преобразовать имена в десятичные (bar_10) если это упрощает вещи.


Если вам интересно, в Qsys это очень просто связать интерфейсы с портами, потому что Qsys использует файлы TCL для отображения. В TCL я могу просто использовать цикл for и объединить переменную цикла для создания имен.

1 ответ

Я думаю, в вашем случае, макрос может быть использован для решения вашей проблемы. Таким образом, везде, в вашем коде, вы можете использовать bar как вектор, хотя это не так.

Определите макрос как это:

`define bar(n) bar_``n``
`define deadbeef(n) deadbeef_``n``

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

`bar(0)
`deadbeef(0)
Другие вопросы по тегам