Изменения состояния FSM в Verilog - PullRequest
0 голосов
/ 16 апреля 2011

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

state <= 2'b10;

state <= #1 IDLE;

Почему <= используется, а не только =? Какова цель использования # 1? Это имеет значение? </p>

Вот код 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

Ответы [ 2 ]

7 голосов
/ 17 апреля 2011

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

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

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

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

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

2 голосов
/ 17 апреля 2011

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

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

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

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

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

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

...