Указване на диапазон на променлива във 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): i не е константа. Редактирах силно моя код, когато го публикувах тук. Това е всичко, което мога да публикувам.   -  person typon    schedule 27.07.2011


Отговори (1)


Изглежда, че се опитвате да копирате readdata в writedata през цялото време, но попълвате LSB с en, ако са изпълнени определени специални условия. Също така ще предположа, че цикълът for, който имате, е в блок always и че възнамерявате да изградите комбо логика.

Цикълът for, както сте го написали, няма много смисъл за мен от хардуерна гледна точка. for цикъл се използва за изграждане на масиви от логика и както сте го написали, ще имате поне 3 логически конуса, които се опитват да зададат стойности на цялата writedata шина. (Ако изобщо генерира нещо, това ще бъде някаква странна приоритетна структура).

Това каза, вероятно вашият компилатор се оплаква от избрания диапазон, т.е. writedata[2-i:0], а не writedata[3-i] = en[i]; (всичко с : в избраната част). Ако искате да направите нещо по този начин, можете да използвате „избиране на индексирани части“ ( +: или -:), но в този случай има по-добри решения.

Бих го пренаписал по следния начин - ако приемем, че съм предположил правилно :)

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