Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Verilog

Entendendo Atribuições em Verilog: Tipos, Sintaxe e Boas Práticas

Atribuir valores a redes (nets) e variáveis é chamado de atribuição. Existem três formas básicas:

Valores LHS Permitidos

Uma atribuição tem duas partes: lado direito (RHS) e lado esquerdo (LHS), com um símbolo de igual (=) ou menor-igual (<=) entre eles.

Tipo de atribuição Lado esquerdo (LHS)
Procedural
  • Variáveis (vetor/escalar)
  • Seleção de bit ou parte de vetor reg, integer ou time
  • Palavra de memória
  • Concatenação dos itens acima
Contínua
  • Rede (vetor/escalar)
  • Seleção de bit ou parte de vetor net
  • Concatenação de seleções de bit e parte
Procedural Contínua
  • Rede ou variável (vetor/escalar)
  • Seleção de bit ou parte de vetor net

O RHS pode conter qualquer expressão que avalie para um valor final, enquanto o LHS indica uma rede ou variável à qual o valor do RHS está sendo atribuído.

module tb;
  reg clk;
  wire a, b, c, d, e, f;
  reg z, y;
  
  // clk está no LHS e a negação de clk forma o RHS
  always #10 clk = ~clk;
  
  // y é o LHS e a constante 1 é o RHS
  assign y = 1;
  
  // f é o LHS, e a expressão de a,b,d,e forma o RHS
  assign f = (a | b) ^ (d & e);
  
  always @ (posedge clk) begin
    // z é o LHS, e a expressão de a,b,c,d forma o RHS
    z <= a + b + c + d;
  end
  
  initial begin
    // Nomes de variáveis à esquerda formam LHS enquanto 0 é RHS
    a <= 0;
    b <= 0;
    c <= 0;
    d <= 0;
    e <= 0;
    clk <= 0;
  end
endmodule

Atribuição Procedural

Atribuições procedurais ocorrem dentro de procedimentos como always, initial, task e function e são usadas para colocar valores em variáveis. A variável manterá o valor até a próxima atribuição à mesma variável.

O valor será colocado na variável quando a simulação executar esta instrução em algum momento durante o tempo de simulação. Isso pode ser controlado e modificado da forma desejada pelo uso de instruções de controle de fluxo como if-else-if, case e mecanismos de loop.

reg [7:0] data;
integer count;
real period;

initial begin
  data = 8'h3e;
  period = 4.23;
  count = 0;
end

always @ (posedge clk)
  count++;

Atribuição na Declaração de Variável

Um valor inicial pode ser colocado em uma variável no momento de sua declaração. A atribuição não tem duração e mantém o valor até a próxima atribuição à mesma variável. Note que atribuições na declaração para arrays não são permitidas.

module my_block;
  reg [31:0] data = 32'hdead_cafe;
  
  initial begin
    #20 data = 32'h1234_5678;
    // data terá dead_cafe do tempo 0 ao tempo 20
    // No tempo 20, data receberá 12345678
  end
endmodule
reg [3:0] a = 4'b4;
// é equivalente a
reg [3:0] a;
initial a = 4'b4;

Se a variável for inicializada na declaração e no tempo 0 em um bloco initial, a ordem de avaliação não é garantida, podendo resultar em 8'h05 ou 8'hee.

module my_block;
  reg [7:0] addr = 8'h05;
  initial addr = 8'hee;
endmodule
reg [3:0] array [3:0] = 0; // ilegal
integer i = 0, j;           // declara dois integers i,j e i recebe 0
real r2 = 4.5, r3 = 8;      // declara dois reals r2,r3 com 4.5, 8
time startTime = 40;        // declara variável time com valor inicial 40

Blocos e atribuições procedurais serão abordados em mais detalhes em uma seção posterior.

Atribuição Contínua

Clique aqui para um exemplo de simulação passo a passo!

Usada para atribuir valores a redes escalares e vetoriais e ocorre sempre que há uma mudança no RHS. Fornece uma forma de modelar lógica combinacional sem especificar uma interconexão de portas e facilita o acionamento da rede com expressões lógicas.

// Modelo de exemplo de uma porta AND
wire a, b, c;
assign a = b & c;

Sempre que b ou c mudam de valor, toda a expressão no RHS será avaliada e a será atualizada com o novo valor.

Atribuição na Declaração de Rede

Permite colocar uma atribuição contínua na mesma instrução que declara a rede. Note que, como uma rede pode ser declarada apenas uma vez, apenas uma atribuição de declaração é possível para uma rede.

wire penable = 1;

Atribuição Procedural Contínua

São instruções procedurais que permitem expressões serem atribuídas continuamente a redes ou variáveis e são de dois tipos:

assign deassign

Sobrescreve todas as atribuições procedurais a uma variável e é desativado usando o mesmo sinal com deassign. O valor da variável permanecerá o mesmo até que a variável receba um novo valor através de uma atribuição procedural ou procedural contínua. O LHS de um assign não pode ser seleção de bit, parte ou referência a array, mas pode ser uma variável ou concatenação de variáveis.

reg q;
initial begin
  assign q = 0;
  #10 deassign q;
end

force release

Semelhantes às instruções assign - deassign, mas também podem ser aplicadas a redes e variáveis. O LHS pode ser seleção de bit de rede, parte de rede, variável ou rede, mas não pode ser referência a array e seleção de bit/parte de variável. A instrução force sobrescreverá todas as outras atribuições feitas à variável até ser liberada com release.

reg o, a, b;
initial begin
  force o = a & b;
  ...
  release o;
end

Verilog

  1. Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
  2. Dominando Concatenação Verilog: Guia Prático
  3. Dominando Funções em Verilog para Design RTL Eficiente
  4. Entendendo Tasks em Verilog: Funções vs Tasks, Sintaxe e Uso
  5. Gerador de Clock Verilog: Guia de Design e Implementação
  6. Dominando Funções Matemáticas do Verilog para Design de Hardware Eficiente
  7. Dominando $timeformat do Verilog: Precisão e Controle de Exibição
  8. Entendendo e Imprimindo Timescales do Verilog em Qualquer Escopo
  9. Dominando I/O de Arquivos em Verilog: Abrir, Ler, Escrever e Fechar
  10. Guia para Iniciantes em Verilog: Exemplo Hello World