Превышен предел итерации цикла в синтезе, но не в симуляции - PullRequest
2 голосов
/ 17 марта 2019

Я написал код в verilog, который циклически перебирает активные каналы. Идея состоит в том, чтобы пропустить каналы, которые отмечены 0 в векторе активности.

Я тестировал код в симуляторе снимок экрана с симулятором , все работает и работает как положено.

Когда я пытаюсь синтезировать код с помощью Synplify Pro, я получаю сообщение об ошибке: «E CS162 Превышен предел итерации цикла 4000 - добавьте« // loop_limit 8000 »перед созданием цикла test1.v (11)»

Ошибка указывает на состояние цикла (i < 6'b100000).

Поиск ошибки в Google Я нашел распространенную ошибку в похожем коде, имеющем i такой же длины, что и channel, что делает цикл работать неопределенно, потому что 11111 + 1 = 00000.

Кроме того, в программном обеспечении Xilinx есть какая-то ошибка, но я ее не использую.

Есть идеи, почему я получаю эту ошибку или почему она отличается от симуляции? Есть ли способ реализовать эту функцию без цикла?

Это код:

module test1 (
input wire [31:0] activity,
input wire  RESET,
input wire  CLK);

reg [4:0] channel, next_channel;
reg [5:0] i,j;

always @(activity, channel) begin
    next_channel = 5'b0;
    for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
        j = i + {1'b0, channel} + 6'b1;
        if (j>6'b011111)
            j = j - 6'b100000;
        if (activity[j[4:0]]) begin
            next_channel = j[4:0];
            i = 6'b101111;
        end
    end
end

always @(posedge CLK, negedge RESET) begin
    if (RESET == 1'b0)
        channel = 5'b0;
    else
        channel = next_channel;
end

endmodule

1 Ответ

3 голосов
/ 17 марта 2019

Во-первых, число итераций - это не итерации цикла, а скорее компиляция итераций.

Проблема заключается в попытке выйти из цикла в середине (строка i = 6'b101111). Это нельзя развернуть в серию команд. Кажется, что циклы только спасают вас от повторного ввода одной и той же вещи снова и снова и не могут делать ничего более сложного.

Возможным решением было бы ввести все 32 if...else...if...else... так, чтобы при обнаружении первого 1 в activity условие выполнялось, а вы не вводили следующее else. Я думаю, что это будет выглядеть так:

always @(activity, channel) begin
    next_channel = 5'b0;
    if (activity[channel + 1])
        next_channel = channel + 1;
    else if (activity[channel + 2])
            next_channel = channel + 2;  
         else if (activity[channel + 3])
                 next_channel = channel + 3; 
              else if (activity[channel + 4])
                      next_channel = channel + 4; 
    .
    .
    .

Я решил проблему с флагом (как предложено EML ). С этим флагом код разворачивается в 32 повторения одного и того же кода с разными значениями i, и «остановка» достигается путем замены флешки, чтобы условие не выполнялось при дальнейших повторениях.

Код решения:

reg flag;

always @(activity, channel) begin
    next_channel = 5'b0;
    flag = 1;
    for (i = 6'b0; i < 6'b100000 ; i = i + 6'b1) begin
        j = i + {1'b0, channel} + 6'b1;
        if (j>6'b011111)
            j = j - 6'b100000;
        if (activity[j[4:0]] && flag) begin
            next_channel = j[4:0];
            flag = 0;
        end
    end
end

Это прошло синтез и дает ожидаемые результаты в симуляции.

...