Menu
Coddy logo textTech

Atribuição Não Bloqueante

Parte da seção Fundamentos do Journey de Verilog da Coddy — lição 50 de 90.

Na lição anterior, cobrimos a atribuição bloqueante (=), que executa passo a passo. Agora veremos a atribuição não-bloqueante (<=), que executa tudo de uma vez — em paralelo.

A atribuição não bloqueante usa o operador <=. É chamada de "não bloqueante" porque não bloqueia a execução da próxima instrução. Todas as atribuições não bloqueantes em um bloco são executadas ao mesmo tempo.

Sintaxe:

variable <= expression;

Quando usar a Atribuição Não Bloqueante

A atribuição não bloqueante (<=) é usada para lógica sequencial — circuitos que usam um clock e possuem memória. As saídas mudam apenas em uma borda de clock (geralmente a borda de subida).

Exemplos de lógica sequencial:

  • Flip-flops
  • Registradores
  • Contadores
  • Máquinas de estado
  • Registradores de deslocamento

Exemplo de Verilog:

initial begin
  a <= 5;      // Agendado, mas ainda não executado
  b <= a + 2;  // Agendado, usa o valor ANTIGO de a
  c <= b * 3;  // Agendado, usa o valor ANTIGO de b
end

Todas as três atribuições ocorrem ao mesmo tempo usando os valores antigos. Ao final do passo de tempo, todas as atualizações acontecem juntas.

Non-blocking em Blocos Always (Lógica Sequencial)

Non-blocking é usado para lógica sequencial — circuitos que usam um clock e possuem memória (flip-flops, registradores, contadores).

always @(posedge clk) begin
  q <= d;           // q recebe d na borda do clock
  count <= count + 1; // count incrementa na borda do clock
end

Ambas as atribuições ocorrem ao mesmo tempo, usando valores de antes da borda do clock.

Resumo

RegraExplicação
Use <= para lógica sequencialalways @(posedge clk)
Use = para lógica combinacionalalways @(*)
Não bloqueantes executam em paraleloTodas as atribuições ocorrem de uma só vez
Os valores são atualizados no final do passo de tempoNão imediatamente
challenge icon

Desafio

Complete a Atribuição Não-Bloqueante

Adicione as atribuições não-bloqueantes que faltam para fazer este registrador de deslocamento de 2 bits funcionar.

Como funciona:

  • A cada borda de clock, q1 recebe d
  • q2 recebe o valor antigo de q1

O que fazer:

  1. Atribua d a q1 (não-bloqueante)
  2. Atribua q1 a q2 (não-bloqueante)

Folha de consulta

Atribuição não-bloqueante (<=) executa todas as instruções em paralelo — usando valores antigos, atualizando ao final do passo de tempo.

// Todos usam valores ANTIGOS de a e b
a <= 5;
b <= a + 2;  // usa o a antigo
c <= b * 3;  // usa o b antigo

Use <= para lógica sequencial (flip-flops, registradores, contadores) dentro de blocos always sincronizados (clocked):

always @(posedge clk) begin
  q     <= d;           // não-bloqueante
  count <= count + 1;   // não-bloqueante
end
AtribuiçãoUso paraExecuta
<=Lógica sequencial (posedge clk)Em paralelo
=Lógica combinacional (always @(*))Passo a passo

Experimente você mesmo

module shift_register (
  input clk,
  input reset,
  input d,
  output reg q1,
  output reg q2
);
  
  always @(posedge clk or posedge reset) begin
    if (reset) begin
      q1 <= 0;
      q2 <= 0;
    end else begin
      // TODO: Adicionar lógica de deslocamento
      // Passo 1: Atribuir d a q1 (não bloqueante)
      // Passo 2: Atribuir q1 a q2 (não bloqueante)
    end
  end
endmodule
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Fundamentos