Jump to content

    
Sign in to follow this  
Golikov

Зачем запись вида reg <= reg на verilog?

Recommended Posts

Всем привет!

 

Есть описания вида

 

always @(posedge clk)
  begin
     if(....)
       reg <= input;
     else
       reg <= reg;
  end

 

или эквивалент

 

always @(posedge clk)
  begin
     reg <= reg;

     if(....)
       reg <= input1;
     if(....)
       reg <= input2;
     .....
  end

 

Кто знает зачем используется явное указание что без выполнения условий reg <= reg, то есть как бы сохраняет свое значение?

 

У меня есть теория что это перенесенное из описания типа

 

always @(en, input)
  begin
     if(en)
       reg <= input;
     else
       reg <= reg;
  end

 

что в них используется как способ защиты от лачей, и утянуто в синхронную схему просто потому что уже забыли зачем оно было нужно... Но может есть еще аргументы? Кто что знает про это?

Share this post


Link to post
Share on other sites

"reg <= reg" можно и не писать, компилятор сам догадывается что регистр должен хранить своё значение. В Квартусе так по крайней мере.

Share this post


Link to post
Share on other sites
Вопрос не в том что получиться из схемы. Вопрос откуда это взялось, кто это придумал, и зачем....

Ну я, по наивности своей, думаю это для удобства чтения: хош - пиши для ясности, хош - не пиши для краткости.

 

Share this post


Link to post
Share on other sites

Такой код может встретиться у людей, которые таким образом пытаются бороться с latch-ами, не понимая причину их образования. Корректно описанная схема не требует такой избыточности и latch-ей в ней не будет.

Share this post


Link to post
Share on other sites

ну строго говоря в описании под клоком латча не будет даже если описывать схему некорректно...

 

Ну то есть Вы тоже считаете что это просто перенесенный прием без понимания смысла происходящего.

 

У кого еще есть какие мнения?

Share this post


Link to post
Share on other sites
Ну то есть Вы тоже считаете что это просто перенесенный прием без понимания смысла происходящего.

У кого еще есть какие мнения?

Такой прием породит уже явный latch для сохранения состояния сигнала при описании в always_comb. Так что это предположение выглядит странным.

 

Другое дело, если это огрызок от описания, в котором разделяется комбинационное присвоение в always_comb и присвоение в отдельном always_ff

Но тогда там в always_comb должно быть именно сохранения сигнала с триггера:

...
else reg_comb = reg_ff;

Share this post


Link to post
Share on other sites
Такой прием породит уже явный latch для сохранения состояния сигнала при описании в always_comb. Так что это предположение выглядит странным.

 

Именно. Просто немного не так выразился. Чтобы latch-а не было требуется доопределить все состояния регистра в случае использования case или if. Вот народ и начинает писать reg <= reg. Во-первых, это не имеет вообще никакого смысла для синхронных блоков, а для комбинационных генерирует всё тот же latch.

 

Что так:

module top
(
    input   wire    ena,
    input   wire    din,
    output  wire    dout,
    input   wire    clk
);
    reg data;
    assign dout = data;

    always @* begin
        if (ena) begin
            data <= din;
        end
    end
endmodule

 

Что этак:

 

module top
(
    input   wire    ena,
    input   wire    din,
    output  wire    dout,
    input   wire    clk
);
    reg data;
    assign dout = data;

    always @* begin
        if (ena) begin
            data <= din;
        end else begin
            data <= data;
        end
    end
endmodule

 

В обоих случаях будет latch, т.к. в первом варианте регистр сохраняет значение неявно, во втором явно.

f88fa51fa0c7t.jpg

 

Чтобы latch-a не было, можно сделать хотя бы так:

module top
(
    input   wire    ena,
    input   wire    din,
    output  wire    dout,
    input   wire    clk
);
    reg data;
    assign dout = data;

    always @* begin
        if (ena) begin
            data <= din;
        end else begin
            data <= 1'b1; // 1'b0
        end
    end
endmodule

 

91b52d03debdt.jpg

Edited by Inanity

Share this post


Link to post
Share on other sites
    always @* begin
        if (ena) begin
            data <= din;

Плохо написано. Используйте в комбинационных блоках только блокирующее присваивание.

Это избавит от многих потенциальных проблем в симуляции.

Share this post


Link to post
Share on other sites
Всем привет!

 

Есть описания вида

 

always @(posedge clk)
  begin
     if(....)
       reg <= input;
     else
       reg <= reg;
  end

Нормальный код, хотя обычно нижние две строки опускают как само собой разумеющееся

 

или эквивалент

 

always @(posedge clk)
  begin
     reg <= reg;

     if(....)
       reg <= input1;
     if(....)
       reg <= input2;
     .....
  end

Это кривой код, поскольку производится два параллельный присваивания. Компилятор на этот код должен вывалиться с ошибкой.

 

Кто знает зачем используется явное указание что без выполнения условий reg <= reg, то есть как бы сохраняет свое значение?

Именно потому, что в железе триггер сохраняет свое значение. Об этом уже писали выше.

 

Тул понимает определенные конструкции языка как триггер, а определенные как латч. Этого достаточно, чтобы хорошо писать RTL.

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

 

Про "способ защиты от латчей" вообще очень странная фраза. Если использовали конструкцию триггера - будет триггер, если описали латч - будет латч. А если в коде нечто непонятное, то нужно не от латчей защищаться, а брать и читать учебник.

Share this post


Link to post
Share on other sites

always @(posedge clk)

begin

if(....)

reg <= input;

else

reg <= reg;

end

По мне все правильно, хотя напоминает всего лишь обратный перевод от

always @(posedge clk)

reg <= (....) ? input : reg

То есть на входе регистра ставится коммутатор 2 в 1, что избавляет от возможных гонок при синхронизации одним общим clk. Подразумевается, что это только малая часть от какой-то схемы.

Share this post


Link to post
Share on other sites
Плохо написано. Используйте в комбинационных блоках только блокирующее присваивание.

Это избавит от многих потенциальных проблем в симуляции.

это нюансы, разговор о другом

 

В обоих случаях будет latch, т.к. в первом варианте регистр сохраняет значение неявно, во втором явно.

запись на вход выхода - это не лачь, а имитация лача. В ксалинксе есть такой техблок лачь и потому разводиться в лачь. А в альтере, например, тех блока лачь нету, и он даже в случае описания "честного" лача делает блок с заводом выхода на вход для сохранения значения.

 

так что описание с else reg = reg это более строгое описание того что вы хотите при отсутствии технологического элемента.

 

 

Чтобы latch-а не было требуется доопределить все состояния регистра...

чтобы не было латча надо описывать не латч, это единственное что спасет:)

 

 

 

Нормальный код, хотя обычно нижние две строки опускают как само собой разумеющееся

Вы смогли прочитать и понять вопрос? попробуйте еще разок

 

 

Это кривой код, поскольку производится два параллельный присваивания. Компилятор на этот код должен вывалиться с ошибкой.

Компилятор, а на самом деле синтезатор в отличии от кое кого знает стандарт и потому вместо вываливания с ошибкой реализует правильный результат по стандарту. Самое смешное что проверить что будет надо минут 5, но нет....

 

Про "способ защиты от латчей" вообще очень странная фраза. Если использовали конструкцию триггера - будет триггер, если описали латч - будет латч. А если в коде нечто непонятное, то нужно не от латчей защищаться, а брать и читать учебник.

про учебник неплохо сказано, рекомендую Вам последовать своей рекомендации ;) Если интересно могу пояснить зачем это делают, но это выходит за рамки данного вопроса.

 

 

Share this post


Link to post
Share on other sites
это нюансы, разговор о другом

нифига себе нюансы.

по такому плохо написанному коду следует вывод о том, что человек, писавший такой код - "плавает", плохо понимает матчасть, и как следствие, от него можно ожидать любой "лепнины", в том числе в виде reg <= reg, в тех местах, где он сомневается, как правильно описать блок.

 

Never attribute to malice that which can be adequately explained by stupidity.

Share this post


Link to post
Share on other sites
То есть на входе регистра ставится коммутатор 2 в 1, что избавляет от возможных гонок при синхронизации одним общим clk. Подразумевается, что это только малая часть от какой-то схемы.

то есть по вашему для записи вида

always @(posedge clk)
   reg <= input;

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

 

по такому плохо написанному коду следует вывод о том, что человек, писавший такой код - "плавает"

то что человек плавает видно не по этому, а по тому что он использует конструкцию вида reg <= reg; под клоком. Но вопрос в другом откуда это пошло.

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

 

нифига себе нюансы.

и не будьте так категоричны насчет того что можно использовать только = для комбинаторики, ровно как что можно использовать только <= под клоком. Можно всякое, особенно если знаешь что делаешь:)

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this