Изменения состояния FSM в Verilog

Я видел следующее, используемое для изменения состояния в модулях Verilog:

state <= 2'b10;

state <= #1 IDLE;

Почему используется ‹=, а не просто =? Какова цель использования № 1? Есть ли разница?

Вот некоторый код Verilog для FSM, который показывает первый используемый. Будет ли он работать так же, если его заменить вторым?

module fsm( clk, rst, inp, outp);

   input clk, rst, inp;
   output outp;

   reg [1:0] state;
   reg outp;

   always @( posedge clk, posedge rst )
   begin
   if( rst )
       state <= 2'b00;
   else
   begin
       case( state )
       2'b00:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b10;
       end

       2'b01:
       begin
            if( inp ) state <= 2'b11;
            else state <= 2'b10;
       end

       2'b10:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b11;
       end

       2'b11:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b10;
       end
       endcase
   end
end

person node ninja    schedule 16.04.2011    source источник


Ответы (2)


В последовательном логическом блоке always, таком как ваш, лучше использовать неблокирующие назначения (<=) вместо блокирующих назначений (=). Моделирование будет лучше отражать фактическую результирующую логику.

В чистом RTL-коде Verilog, если вы используете неблокирующие назначения для всей последовательной логики, не должно быть причин использовать #1 задержки.

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

См. также: Неблокирующие назначения в синтезе Verilog, стили кодирования Это убийство!

Кроме того, лучше использовать parameter для названия каждого из ваших состояний. Намного более осмысленно, если состояние называется IDLE вместо 2'b10.

person toolic    schedule 16.04.2011

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

Чтобы избежать недетерминированного поведения синхронизируемых всегда блоков, вы должны использовать неблокирующие назначения для тех переменных, которые используются в других блоках (нелокальные переменные). Более подробный анализ см. в моем блоге на эту тему:

http://www.sigasi.com/content/verilogs-major-flaw

Инструменты синтеза обычно принимают блокирующие назначения для нелокальных переменных в постоянно синхронизируемых блоках, но на самом деле это ошибка, поскольку они никак не могут гарантировать, что синтезированная логика будет вести себя как модель (поскольку такая модель недетерминирована).

В отличие от того, что вы услышите во многих других, таких как популярные статьи Клиффа Каммингса, нет необходимости использовать только неблокирующие присваивания для локальных переменных. Блокирующие присваивания вполне приемлемы для локальных переменных. Это актуально, поскольку позволяет использовать чистую «переменную» семантику (как в языках программирования) для внутреннего моделирования.

В моделировании в чистом стиле RTL задержки № 1 являются просто накладными расходами.

person Jan Decaluwe    schedule 17.04.2011