Указание диапазона переменных в Verilog с использованием цикла for

Я пытаюсь написать этот код:

 for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
                    begin : loop_inst

                        if (i < 3)
                        begin
                            if (changed[i] & !done_q[i])
                            begin
                                writedata[3-i] = en[i];
                                writedata[2-i:0] = readdata[2-i:0];
                                writedata[15:4-i] = readdata[15:4-i];
                            end
                        end
                        else
                        ...

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

Есть ли другой обходной путь для этого? Единственный обходной путь, который я знаю, - это запись этих трех операторов CONST раз. Я надеюсь, что мне не придется делать это в конце. Есть ли другое решение?


person typon    schedule 27.07.2011    source источник
comment
Какой это инструмент? Можете ли вы опубликовать минимальный код, который компилируется с ошибкой?   -  person    schedule 27.07.2011
comment
Инструмент Quartus. Ошибка: Ошибка (10734): ошибка Verilog HDL в top.v(733): я не является константой. Я сильно отредактировал свой код, когда разместил его здесь. Это все, что я могу опубликовать.   -  person typon    schedule 27.07.2011


Ответы (1)


Похоже, вы все время пытаетесь скопировать readdata в writedata, но заполняете младшие биты en, если выполняются определенные особые условия. Я также предполагаю, что ваш цикл for находится в блоке always и что вы собираетесь построить комбо-логику.

Цикл for, как вы его написали, не имеет для меня особого смысла с аппаратной точки зрения. Цикл for используется для построения массивов логики, и поскольку вы его написали, у вас будет как минимум 3 логических конуса, пытающихся установить значения на всей шине writedata. (Если он вообще что-то генерирует, это будет какая-то странная структура приоритетов).

Тем не менее, вероятно, ваш компилятор жалуется на выбор диапазона, то есть на writedata[2-i:0], а не на writedata[3-i] = en[i]; (что-либо с : в части select). Если вы хотите сделать что-то в этом духе, вы можете использовать «выбор индексированных частей» ( +: или -:), но в этом случае есть лучшие решения.

Я бы переписал это следующим образом - если я правильно предположил :)

always @( /*whatever*/ ) begin

    // default assignment
    writedata = readdata;

    // overwrite some bits in writedata for special cases
    for(i=0; i<3; i++) begin
        if( changed[i] & !done_q[i] )
             writedata[3-i] = en[i];
    end
end

В этом коде я устанавливаю writedata в readdata, а затем настраиваю результирующее значение writedata, если имеют место особые случаи. Цикл for строит 3 логических конуса, по одному на каждый бит в writedata[3:1]. Я бы перепроверил, соответствует ли битовое отображение тому, что вы намереваетесь, т. Е. Сопоставлению en[2:0] с writedata[1:3].

person Marty    schedule 27.07.2011
comment
большое спасибо! Я такой идиот, что не подумал об этом... конечно, это очевидное решение! Я только что перепроверил, и компилятор Quartus выдавал ошибку только для ранжированных назначений, а не для [3-i]. И вы все правильно поняли :) - person typon; 27.07.2011