15 / 37 · Conceito
Atribuições não bloqueantes e atualização simultânea
Separe valores anteriores e seguintes para interpretar corretamente contadores e pipelines RTL.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
O lado direito é avaliado a partir do estado anterior
Num bloco sequencial de clock, <= avalia a expressão à direita e aplica o resultado na fase não bloqueanteAtribuição não bloqueante Atribuição escrita com <= em RTL sequencial. Avalia o lado direito e agenda a atualização, permitindo que os registradores da mesma borda calculem a partir do estado anterior.. Permite atualizar vários registradoresRegistrador Circuito que armazena vários bits de estado. Os registradores síncronos deste curso capturam a entrada especificada na borda de clock. Saiba mais na mesma borda sem que a ordem das linhas faça valores recém-escritos atravessarem em cascata.
always_ff @(posedge clk) begin
if (rst) begin
a <= 8'd0;
b <= 8'd0;
end else begin
a <= d;
b <= a;
end
endPartindo de a=b=0 e entradas 5,9,2, os pares posteriores são (5,0), (9,5), (2,9). Interpretar que a segunda linha lê o novo a elimina indevidamente um estágio do pipelinePipeline Estrutura que divide o cálculo em estágios separados por registradores para processar várias entradas de forma sobreposta. Dados, valid e controles devem permanecer alinhados entre os estágios. Saiba mais.
Cada coluna registra uma borda de subidaBorda de subida Instante em que o clock passa de 0 para 1. É diferente do nível alto, que abrange todo o intervalo com CLK=1. Saiba mais. Entradas são anteriores; estados «depois» são posteriores à atualização. O alinhamento mostra a ordem das amostras, não atraso de propagaçãoAtraso de propagação Tempo entre uma mudança de entrada e a estabilização da saída no valor correto. Equivalência lógica e comportamento temporal são propriedades distintas. Saiba mais. Partindo de a=b=0, a captura d enquanto b captura o a anterior: suas linhas ficam deslocadas em um estágio.
Ver os dados da forma de onda
| Sinal | Forma de onda | Valores do barramento |
|---|---|---|
| borda | 234 | E0 → E1 → E2 |
| d | 234 | 5 → 9 → 2 |
| a depois | 234 | 5 → 9 → 2 |
| b depois | 234 | 0 → 5 → 9 |
Por que mudar para atribuições bloqueantes é perigoso
Com a=d; b=a; no mesmo bloco, b pode usar o a já modificado. A ordem de execução em relação a outros blocos sequenciais também pode criar condições de corrida. Use como regra bloqueantes para cálculo combinacional e não bloqueantes para estado; reserve exceções aos casos cujo significado de eventos você consiga explicar.
Evite várias atribuições ao mesmo registrador
Se a mesma execução procedural atribuir q várias vezes por <=, a última atribuição executada pode determinar o resultado. Exponha a prioridade com if / else if / else ou uma variável explícita de próximo estado, em vez de escondê-la entre if independentes. Evite acionar um registrador por vários blocos.
Ao revisar RTL, escreva uma equação de próximo estado por registrador. Se surgirem duas equações ou alguma condição ficar indefinida, revise a prioridade de controle.
Experimente
Com a=1, b=4 inicialmente e a<=b; b<=a; no mesmo bloco de clock, qual é o resultado após uma e duas bordas?
Ler a explicação
Após uma: (a,b)=(4,1); após duas: (1,4). Ambas as atribuições leem o mesmo estado anterior e trocam valores. Com a=b; b=a;, ambas podem terminar com o antigo b conforme a ordem: é outra função.