Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как защититься от латчей?
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
-=Vitaly=-
Здравствуйте!!

Предположим меется много конструкций типа if -else if-else в блоке always(*) естественно внутри сигналы типа reg, и если не перебираются все варианты if -else if-else, то получится защелка.

Можно ли подобные конструкции (if -else if-else) или что-то похожее применять для переменных типа wire, чтобы быть застрахованным от появления латчей??

В качестве примера:

Код
always@(*)

        if(MAX_DATA>HiTreshold)  
            begin
                FR_EN_UPD<=1'b1;
                if(LDAC!=X_REG && LDAC<LDAC+SUPR )
                    LDAC_UPD<=LDAC+SUPR;
                else
                    LDAC_UPD<=X_REG;
                if(LDAC==X_REG && PRBS_REG!=2'b11)      
                    PRBS_INC_UPD<=1'b1;      
            end      
        //--------------------------------------------------------------------------------------    
        else if    (MAX_DATA<HiTreshold && MAX_DATA>LoTreshold5 && FR_EN_OLD!=1'b1)
            begin
            FR_EN_UPD<=1'b0;
            LDAC_UPD<=LDAC;    
            PRBS_INC_UPD<=1'b0;
            PRBS_DECR_UPD<=1'b0;
            end


СПС blush.gif
id_gene
assign out = (condition) ? in1 : in0;

из вашего пример

wire FR_EN_UPD;
assign FR_EN_UPD = (MAX_DATA>HiTreshold) ? 1'b1 : (MAX_DATA<HiTreshold && MAX_DATA>LoTreshold5 && FR_EN_OLD!=1'b1) ? 1'b0 : 1'bX;

Закрывать условие обязательно по стандарту.
Gate
Цитата(-=Vitaly=- @ Apr 27 2007, 10:26) *
Можно ли подобные конструкции (if -else if-else) или что-то похожее применять для переменных типа wire, чтобы быть застрахованным от появления латчей??

Задайте себе вопрос - а что быть результатом выполнения оператора, если ни один if не реализуется?
lehho
Ну так добавьте ещё else:

Код
always@(*)

        if(MAX_DATA>HiTreshold)  
            begin
                FR_EN_UPD<=1'b1;
                if(LDAC!=X_REG && LDAC<LDAC+SUPR )
                    LDAC_UPD<=LDAC+SUPR;
                else
                    LDAC_UPD<=X_REG;
                if(LDAC==X_REG && PRBS_REG!=2'b11)      
                    PRBS_INC_UPD<=1'b1;      
            end      
        //--------------------------------------------------------------------------------------    
        else if    (MAX_DATA<HiTreshold && MAX_DATA>LoTreshold5 && FR_EN_OLD!=1'b1)
            begin
            FR_EN_UPD<=1'b0;
            LDAC_UPD<=LDAC;    
            PRBS_INC_UPD<=1'b0;
            PRBS_DECR_UPD<=1'b0;
            end

        else
            begin
            FR_EN_UPD<=1'b0;
            LDAC_UPD<=1'b0;    
            PRBS_INC_UPD<=1'b0;
            PRBS_DECR_UPD<=1'b0;
            end


А если не нужен приоритетный шифратор используйте конструкцию case
Doka
если вы синтезируете в Synplify or Precision, то есть изяшное решение в виде конструкции SystemVerilog:
always_comb (для жесткого указания, что внтури блока только логика)
(cравните с always_ff & always_latch)
-=Vitaly=-
Цитата(Doka @ Apr 27 2007, 12:40) *
если вы синтезируете в Synplify or Precision, то есть изяшное решение в виде конструкции SystemVerilog:
always_comb (для жесткого указания, что внтури блока только логика)
(cравните с always_ff & always_latch)


Спасибо, в общем суммируя.

1. Так я писал листинг в начале -это фиговый стиль. Сложно отлавливать латчи.
2. Надо разнести переменные, которые можно описать просто как wire с ?
3. Остальное писать либо через сase, либо перебирать ВСЕ варианты if -else if-else).
4. Использовать вышеуказанные директивы.

В резудьтате из lehho (оптимизированного под мои задачи) получился код
Код
assign FR_EN_UPD=(MAX_DATA<HiTreshold && MAX_DATA>LoTreshold5 && FR_EN_OLD!=1'b1)? 1'b0:1'b1;
    assign PRBS_INC_UPD=(MAX_DATA>HiTreshold && LDAC==X_REG && PRBS_REG!=2'b11) ? 1'b1:1'b0;
    assign PRBS_DECR_UPD=(MAX_DATA>LoTreshold5 || PRBS_REG==2'b00) ? 1'b0: 1'b1;
    
    always@(*)
        //--------------------------------------------------------------------------------------
        if(MAX_DATA>HiTreshold)  
            if(LDAC!=X_REG && LDAC<LDAC+SUPR )
                LDAC_UPD<=LDAC+SUPR;
            else
                LDAC_UPD<=X_REG;
        //--------------------------------------------------------------------------------------    
        else if    (MAX_DATA<HiTreshold && MAX_DATA>LoTreshold5 && FR_EN_OLD!=1'b1)
            LDAC_UPD<=LDAC;    
        //--------------------------------------------------------------------------------------
        else if    (MAX_DATA<LoTreshold5 && MAX_DATA>LoTreshold4)
            if (LDAC>1)
                LDAC_UPD<=LDAC-1;
            else
                LDAC_UPD<=4'd0;    
        //---------------------------------------------------------------------------------------        
        else if    (MAX_DATA<LoTreshold4 && MAX_DATA>LoTreshold3)
            if(LDAC>2)
                LDAC_UPD<=LDAC-2;
            else
                LDAC_UPD<=4'd0;    
        //------------------------------------------------------------------------------------------            
        else if    (MAX_DATA<LoTreshold3 && MAX_DATA>LoTreshold2)
            if(LDAC>3)
                LDAC_UPD<=LDAC-3;
            else          
                LDAC_UPD<=4'd0;    
        //------------------------------------------------------------------------------------------        
        else if    (MAX_DATA<LoTreshold2 && MAX_DATA>LoTreshold1)
            if(LDAC>4)
                LDAC_UPD<=LDAC-4;
            else
                LDAC_UPD<=4'd0;    
        //-----------------------------------------------------------------------------------------            
        else if    (MAX_DATA<LoTreshold1 && MAX_DATA>LoTreshold0)  
            if(LDAC>5)
                LDAC_UPD<=LDAC-5;
            else  
                LDAC_UPD<=4'd0;    
        //-------------------------------------------------------------------------------------------        
        else
            begin
                if(LDAC>6)
                    LDAC_UPD<=LDAC-6;
                else               
                    LDAC_UPD<=4'd0;    
            end

Какие кто может еще дать советы, чтобы неопытным было легче?
SM
Если синтез Synopsys DC, то установите hdlin_check_no_latch в true, и по варнингам отловите их всех поголовно. А квартус и так варнингов понарасскажет. Ну а дальше ручками. Проще всего в самом начале блока поставить "out_var <= x" для всех переменных, а затем хоть тонну if'ов и case. Ну или не "x", а нужные дефолтные значения, если они важны. Для примера:

Код
  always @*
     begin
        out <= 1'bx;
        if (expr_1) out <= in1;
        else if (expr2) out <= in2;
        else if (expr3) out <= in3;
     end


В результате латча не будет гарантировано, но и в случае невыполнения ни одного из условий выход будет в неопределенном (точнее в каком-то определенном на усмотрение синтезатора) состоянии. Вместо 1'bx можно вписать конкретное значение, которое примет выходной сигнал в случае неисполнения ни одного из условий.
urri
Цитата(SM @ Apr 28 2007, 13:49) *
Проще всего в самом начале блока поставить "out_var <= x" для всех переменных, а затем хоть тонну if'ов и case. Ну или не "x", а нужные дефолтные значения, если они важны.


Только присваивание нужно делать блокирующее : "out_var = x" и далее везде
lehho
А вот рекомендации от Synplify:

Код
@W: Latch generated from always block for signal <out1>,
probably caused by a missing assignment in an if or case stmt
Verilog Compiler Warning CL118
Description:
This warning appears if all conditions are not declared in a case statement or if an if statement exists describing purely combinatorial logic. The compiler infers a latch. In the following test case, a latch is generated for signal out1 because the if condition sel = 2'b00 is missing.
module newmux (out1, a, b, c, sel);
input a, b, c;
output out1;
input[1:0] sel;
reg out1;

always@(a or b or c or sel)
begin
   if (sel ==2'b10)
      out1 = a;
   else if (sel == 2'b01)
      out1 = b;
   else if (sel == 2'b11)
      out1 = c;
   end
endmodule

User Action:
Three ways to avoid this warning are:
Complete the if clause by using the else clause in an if-then-else statement.

Always use a default clause in a case statement.

Use the Verilog full_case directive, /* synthesis full_case */, if the case statement includes all possible case choices.

To eliminate the warning in the above test case, edit the code as shown in the corrected test case below.
module newmux (out1, a, b, c, sel);
input a, b, c;
output out1;
input[1:0] sel;
reg out1;

always@(a or b or c or sel)
begin
   if (sel ==2'b10)
      out1 = a;
   else if (sel == 2'b01)
      out1 = b;
   else if (sel == 2'b11)
      out1 = c;
   else out1 = a;
   end
endmodule

Действительно правильнее делать блокирующее прерывание.
Вообще в help на Ваш синтезатор много можно почерпнуть при решении тех или иных проблем.
-=Vitaly=-
Цитата(lehho @ Apr 28 2007, 14:50) *
Действительно правильнее делать блокирующее прерывание.
Вообще в help на Ваш синтезатор много можно почерпнуть при решении тех или иных проблем.

Мудрый совет, но иногда бывает smile3046.gif
lehho
Цитата(lehho @ Apr 28 2007, 15:50) *
Действительно правильнее делать блокирующее прерывание.

Тоже грамотей smile.gif. Правильно писать блокирующие присваивание.

Цитата(-=Vitaly=- @ Apr 28 2007, 16:07) *
Мудрый совет, но иногда бывает smile3046.gif


Да это не совет, так по инерции написал. smile.gif. Сам иной раз сидишь тупишь, а help почитаешь и вот оно.

Скажите Вы какими средствами разработками пользуйтесь? Так людям будет легче правильные наводки давать.
SM
Цитата(urri @ Apr 28 2007, 14:47) *
Только присваивание нужно делать блокирующее : "out_var = x" и далее везде


НЕ ОБЯЗАТЕЛЬНО. Это зависит от того, что дальше за код, причем исключительно в плане использования выходной переменной в качестве входной. В большинстве случаев нахрен не надо.
-=Vitaly=-
Цитата(lehho @ Apr 28 2007, 15:43) *
Тоже грамотей smile.gif. Правильно писать блокирующие присваивание.
Да это не совет, так по инерции написал. smile.gif. Сам иной раз сидишь тупишь, а help почитаешь и вот оно.

Скажите Вы какими средствами разработками пользуйтесь? Так людям будет легче правильные наводки давать.


Я пользуюсь практически всем Активом, Синплифаем, ХST готовлюсь макетировать проект под ASIC.
А с той стороны у меня PKS. Но мне кажется, что тут не столько тулза важна, сколько, как я убедился biggrin.gif прямые руки wink.gif

Вообще писать под асиксы неудобно и стремно, мне по крайней мере wacko.gif
CodeWarrior1241
Мне в универе твердили кое-что по этой теме, свазанное с привязанным к этому посту доком... Говорили что
Цитата
In general, case statements would translate to parallel muxes in hardware. Meanwhile, the use of if – else statements results in priority-based hardware, which can slow down the overall implementation of the design. Thus, only use if – else statement when priority-based hardware is required. Otherwise, use case statements to avoid possible inefficient implementation of the design. While unlikely to produce incorrect outputs, the slowdown caused by large priority-based implementations can cause problems for projects with strict clock frequency targets.

Я в принципе всегда этому следовал, и if-else структур у меня в проектах не так много. Резонно ли это, или совремменым tools все равно?
CaPpuCcino
Цитата(CodeWarrior1241 @ Apr 30 2007, 01:57) *
Мне в универе твердили кое-что по этой теме, свазанное с привязанным к этому посту доком... Говорили что
Я в принципе всегда этому следовал, и if-else структур у меня в проектах не так много. Резонно ли это, или совремменым tools все равно?

по этому поводу в новый стандарт(1800-2005) ввели ключевые слова unique[b/], [b]priority как модификаторы case , if-esle if чтобы определйть однозначно что делать синтезатору
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.