Условное приращение в блоке генерации

Я хочу создать 256 экземпляров foo. Поэтому у меня есть два вложенных цикла генерации. Однако мне нужна отдельная индексная переменная l для правильного выбора сигнала.

genvar j, i, l;
generate
  l = 0;
  for(j = 0; j < 16; j++)
  begin
    for(i = 0; i < 16; i++) begin
      foo bar
      (
        .a_i(a_i[(l+1)*8-1:l*8]),
        .b_i(b_i[(j+1)*8-1:j*8]),
        .c_o(c_i[i][j])
      );

      if(i < 15)
        l = (l + 1) % 16;
    end
  end
endgenerate

К сожалению, эта конструкция не работает. Как добавить l к этой генерации, чтобы получить правильный выбор входных сигналов?


person Razer    schedule 20.08.2015    source источник


Ответы (2)


genvar может быть назначен только в качестве индекса в цикле for. Так что оставьте это как выражение:

genvar j, i;
generate
  for (j = 0; j < 16; j++) begin
    for (i = 0; i < 16; i++) begin
      foo bar (
        // prefix 1'b0 for correct sign extinction, 4'() does casting
        .a_i(a_i[{1'b0,4'(i-j)}*8 +: 8]), 
        .b_i(b_i[j*8 +: 8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate

+: предназначен для нарезки массива, допуская переменный индекс и постоянное смещение. Это более лаконично и проще в обслуживании, чем указание msb:lsb, и его можно синтезировать. См. 'Индексирование векторов и массивов с помощью +:' и 'Что такое `+:` и `-:`?

Вы также можете комбинировать этот метод с подходом parameter dave_59:

genvar j, i;
generate
  for (j = 0; j < 16; j++) begin
    for (i = 0; i < 16; i++) begin
     // defining the parameter with a data type to insure it is a unsigned 4 bit value
      parameter bit [3:0] l = (i-j);
      foo bar (
        .a_i(a_i[l*8 +: 8]),
        .b_i(b_i[j*8 +: 8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate
person Greg    schedule 20.08.2015
comment
Как это создает правильный шаблон для l (индекс для a_i)? л = {0, 1, 2, ... 14, 15, 15, 0, 1, 2 ... 13, 14, 14, 15, ...} - person Razer; 20.08.2015
comment
Я думаю, вы хотите a_i[((i-j)%16)*8 +: 8] Сейчас я оставлю это как комментарий, обновлю свой ответ, когда он будет проверен. - person Greg; 20.08.2015
comment
Да, это то, что я хочу. Однако вычитание должно быть приведено к беззнаковому, потому что оператор по модулю работает по-разному с отрицательными числами: a_i[(unsigned'(i-j) % 16) *8 +: 8] - person Razer; 20.08.2015
comment
Я собирался предложить: {1'b0,4'(i-j)}. Несколько способов сделать это. Я обновил свой ответ. - person Greg; 20.08.2015

Используйте условный оператор ?: и сделайте l параметром

genvar j, i;
generate
  l = 0;
  for(j = 0; j < 16; j++)
  begin
    for(i = 0; i < 16; i++) begin
      parameter l = (i < 15) ? ((l + 1) % 16) : 0;
      foo bar
      (
        .a_i(a_i[(l+1)*8-1:l*8]),
        .b_i(b_i[(j+1)*8-1:j*8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate
person dave_59    schedule 20.08.2015
comment
Как определяется l? Как обычный инт? Я получаю следующее сообщение об ошибке: Следующее выражение должно быть константой. Выражение: ((i ‹ 15) ? ((l + 1) % 16) : 0) - person Razer; 20.08.2015