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 Case em Verilog: Implementação Eficiente de Multiplexadores

A instrução case verifica se a expressão dada corresponde a uma das expressões na lista e desvia conforme necessário. É tipicamente usada para implementar multiplexadores. O construtor if-else pode não ser adequado para muitas condições e sintetizaria em um codificador de prioridade em vez de multiplexador.

Sintaxe

Um case Verilog inicia com case e termina com endcase. A expressão entre parênteses é avaliada exatamente uma vez e comparada com a lista de alternativas na ordem escrita. As instruções para a alternativa correspondente são executadas. Blocos de múltiplas instruções devem ser agrupados entre begin e end.

// 'expressao' deve corresponder a um dos itens (item 1,2,3 ou 4)
case (<expressao>)
  case_item1 : <instrucao_unica>
  case_item2, case_item3 : <instrucao_unica>
  case_item4 : begin <multiplas instruções> end
  default : <instrucao>
endcase

Se nenhum item corresponder, as instruções no default são executadas. O default é opcional, podendo haver apenas um por case. Cases podem ser aninhados.

A execução sai do bloco case sem fazer nada se nenhum item corresponder e não houver default.

Exemplo

O módulo abaixo tem um sinal de seleção de 2 bits para rotear uma de três entradas de 3 bits para a saída out. Um case atribui a entrada correta baseada em sel. Como sel é de 2 bits, tem 22 combinações (0 a 3). O default define saída como 0 se sel for 3.

module my_mux (
  input [2:0] a, b, c,
  input [1:0] sel,
  output reg [2:0] out
);

  always @ (a, b, c, sel) begin
    case(sel)
      2'b00 : out = a;
      2'b01 : out = b;
      2'b10 : out = c;
      default : out = 0;
    endcase
  end
endmodule

Esquema de Hardware

O código RTL é elaborado para obter um esquema representando um multiplexador 4-para-1.

Veja que a saída é zero quando sel=3 e corresponde às entradas atribuídas para outros valores.

Log de Simulação

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0b11 out=0x0
[10] a=0x5 b=0x5 c=0x5 sel=0b10 out=0x5
[20] a=0x1 b=0x5 c=0x6 sel=0b01 out=0x5
[30] a=0x5 b=0x4 c=0x1 sel=0b10 out=0x1
[40] a=0x5 b=0x2 c=0x5 sel=0b11 out=0x0
ncsim: *W,RNQUIE: Simulation is complete.

Em case, a comparação só sucede quando cada bit da expressão corresponde à alternativa incluindo 0, 1, x e z. Se qualquer bit de sel for x ou z, o default executa pois nenhuma alternativa correspondeu, resultando em saída zero.

Log de Simulação com X/Z

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x0
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x0
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x0
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x0
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x0
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x0
ncsim: *W,RNQUIE: Simulation is complete.

Se o case tiver x e z nas alternativas, os resultados serão diferentes.

module my_mux (
  input [2:0] a, b, c,
  input [1:0] sel,
  output reg [2:0] out
);

  always @ (a, b, c, sel) begin
    case(sel)
      2'bxz : out = a;
      2'bzx : out = b;
      2'bxx : out = c;
      default : out = 0;
    endcase
  end
endmodule

Log de Simulação

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x5
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x6
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x7
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x4
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x5
ncsim: *W,RNQUIE: Simulation is complete.

Como case difere de if-else?

O case difere de if-else-if em dois aspectos:

  • Expressões em if-else são mais genéricas; em case, uma única expressão é comparada com múltiplos itens
  • case fornece resultado definitivo quando há valores X e Z na expressão

Verilog

  1. Dominando a Instrução Switch em C#: Sintaxe, Exemplos e Boas Práticas
  2. Instrução Break em C#: Como e Quando Usar
  3. Dominando a Instrução Continue em C#: Como Pular Iterações de Loop Eficazmente
  4. Dominando Switch-Case em C++: Sintaxe, Uso e Exemplos Práticos
  5. Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
  6. Dominando Concatenação Verilog: Guia Prático
  7. Entendendo Atribuições em Verilog: Tipos, Sintaxe e Boas Práticas
  8. Verilog Blocking vs Non-Blocking: Diferenças Essenciais Explicadas
  9. Dominando Funções em Verilog para Design RTL Eficiente
  10. Entendendo Tasks em Verilog: Funções vs Tasks, Sintaxe e Uso