Verilog не может синтезировать при использовании внешнего счетчика внутри блока генерации

Я не могу синтезировать код Verilog в Vivado, симуляция работает правильно. Я объявляю массив localparam, использую внешнюю счетную переменную cnt1 внутри блока генерации, чтобы получить желаемый адрес для параметра. Когда я удаляю переменную cnt1 внутри module1, она может быть синтезирована. Пожалуйста, ребята, дайте мне несколько советов по решению этой проблемы. Я это очень ценю.

module multiply_s1(
input clk,
input rst,
input [9:0]in,
input ena,

output [9:0]out);

localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
reg [1:0] cnt1;//count CC times of GG coeffcient

always@(posedge clk or negedge rst) begin
    if(rst == 0) begin
        cnt1 <= 0;
    end
    else if(ena == 0) begin
        cnt1 <= 0;
    end
    else begin
        if (cnt1 == 3)
            cnt1 <= 0;
        else            
            cnt1 <= cnt1 + 1;
    end
end

genvar i; 
generate
    for (i=0; i<2; i=i+1) 
    begin: mod1          
        module1 mod1(.clk(clk),
                     .rst(rst),
                     .multiplier(in[i*5 +: 5]),
                     .multiplicand(pi_values[(i + cnt1)*5 +: 5]),                        
                     .result(out[i*5 +: 5]));    
   end 
endgenerate

конечный модуль


person France    schedule 30.05.2020    source источник
comment
Пожалуйста, опишите подробнее сообщение об ошибке, предоставленное Vivado.   -  person Khaled Ismail    schedule 30.05.2020
comment
и минимальный полный пример, который мы можем протестировать и проверить. То, что вы опубликовали, является частью модуля, который, в свою очередь, создает экземпляр другого модуля, который здесь не описывается.   -  person mcleod_ideafix    schedule 30.05.2020
comment
Я также редактировал свой код, module1 - это всего лишь 5-битный модульный умножитель.   -  person France    schedule 30.05.2020


Ответы (2)


Не зная, что сказал вам Вивадо, я предполагаю, что ошибка может быть здесь:

[(i + cnt1)*5 +: 5]

cnt1 - это регистр, значение которого известно только «во время выполнения», поэтому Vivado не может знать, какое значение использовать для разбиения вектора pi_values.

Вам понадобится что-то вроде этого:

localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
reg [1:0] cnt1;//count CC times of GG coeffcient

always@(posedge clk or negedge rst) begin
    if(rst == 0)
        cnt1 <= 0;
    else if(ena == 0)
        cnt1 <= 0;
    else
        cnt1 <= cnt1 + 1;
end

reg [0:24] pi_values_rotated;
always @* begin
  case (cnt1)
    0: pi_values_rotated = pi_values;
    1: pi_values_rotated = {pi_values[5:24], pi_values[0:4]};
    2: pi_values_rotated = {pi_values[10:24], pi_values[0:9]};
    3: pi_values_rotated = {pi_values[15:24], pi_values[0:14]};
    default: pi_values_rotated = pi_values;
  endcase
end

genvar i; 
generate
    for (i=0; i<2; i=i+1) 
    begin: mod1          
        module1 mod1(.clk(clk),
                     .rst(rst),
                     .multiplier(in[i]),
                     .multiplicand(pi_values_rotated[i*5 +: 5]),
                     .result(out[i]));
   end 
endgenerate

pi_values_rotated будет вектором pi_values, как видно после применения текущего значения cnt1. Затем вы можете использовать i в качестве единственного значения для генерации ваших экземпляров, которые должны быть приняты сейчас.

person mcleod_ideafix    schedule 30.05.2020
comment
Полностью согласен с вами, синтез не может остановиться. Я понятия не имею, как рассчитать индекс pi_values ​​с предварительно объявленным localparam, зависящим от переменной i и cnt1. - person France; 30.05.2020
comment
Большое Вам спасибо. Оно работает. Что вы думаете об общем методе для больших диапазонов значений pi_values ​​и ввода? - person France; 30.05.2020
comment
Модуль в его нынешнем виде легко модифицировать для больших (по количеству битов) диапазонов. Сложность в том, что у вас больше диапазонов. В этом случае оператор case необходимо изменить, чтобы добавить новые варианты. Я не уверен, что это можно параметризовать с помощью for-generate. - person mcleod_ideafix; 30.05.2020
comment
Следуйте вашему решению, я пытаюсь расширить для большего параметра и ввести, может ли он синтезировать или нет. Еще раз спасибо за вашу помощь. - person France; 30.05.2020

Обратите внимание:

    else begin
        if (cnt1 == 3)
            cnt1 <= 0;
        else            
            cnt1 <= cnt1 + 1;
    end

Это может быть 0, 1, 2 или 3. Это отлично работает в симуляции. Но в синтезе вы постоянно меняете значение cnt1, пытаясь построить логические вентили для mod1, где mod1 использует эту изменяющуюся переменную cnt1. Это конфликт из-за синтеза логических ворот.

Synthesis не может построить ворота для вашего блока генерации, поскольку он создает реальное оборудование и хочет знать детерминированное значение cnt1, чтобы соответствующим образом построить ворота.

Я считаю, что вам нужно разработать архитектуру, которая может обрабатывать максимальное значение cnt1

person Khaled Ismail    schedule 30.05.2020
comment
Ой ошибка моя извините буду редактировать пост. Рассуждения аналогичны @mcleod_ideafix. - person Khaled Ismail; 30.05.2020
comment
да, моя проблема вызвана изменением переменной cnt1 в блоке генерации. - person France; 30.05.2020