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

Multiplexador 4-para-1 em Verilog: Projeto e Implementação

O que é um mux ou multiplexador?

Um multiplexador ou mux em resumo, é um elemento digital que transfere dados de uma das N entradas para a saída baseada no sinal de seleção. O caso mostrado abaixo é quando N é igual a 4. Por exemplo, um multiplexador de 4 bits teria N entradas cada uma de 4 bits onde cada entrada pode ser transferida para a saída pelo uso de um sinal de seleção.

sel é uma entrada de 2 bits e pode ter quatro valores. Cada valor na linha de seleção permitirá que uma das entradas seja enviada ao pino de saída out.

sel a b c d out
0   3 7 1 9 3
1   3 7 1 9 7
2   3 7 1 9 1
3   3 7 1 9 9

Um multiplexador 4x1 pode ser implementado de múltiplas formas e aqui você verá duas das formas mais comuns:

Usando instrução assign

module mux_4to1_assign (
    input [3:0] a,  // Entrada de 4 bits chamada a
    input [3:0] b,  // Entrada de 4 bits chamada b
    input [3:0] c,  // Entrada de 4 bits chamada c
    input [3:0] d,  // Entrada de 4 bits chamada d
    input [1:0] sel, // entrada sel usada para selecionar entre a,b,c,d
    output [3:0] out  // Saída de 4 bits baseada na entrada sel
);
// Quando sel[1] é 0, (sel[0]? b:a) é selecionado e quando sel[1] é 1, (sel[0] ? d:c) é tomado
// Quando sel[0] é 0, a é enviada à saída, senão b e quando sel[0] é 0, c é enviada à saída, senão d
assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a);
endmodule

O módulo chamado mux_4x1_assign tem quatro entradas de dados de 4 bits, uma entrada de seleção de 2 bits e uma saída de dados de 4 bits. O multiplexador selecionará a, b, c ou d baseada no sinal de seleção sel usando a instrução assign.

Usando instrução case

Note que o sinal out é declarado como tipo reg porque é usado em um bloco procedural como always.

module mux_4to1_case (
    input [3:0] a,  // Entrada de 4 bits chamada a
    input [3:0] b,  // Entrada de 4 bits chamada b
    input [3:0] c,  // Entrada de 4 bits chamada c
    input [3:0] d,  // Entrada de 4 bits chamada d
    input [1:0] sel, // entrada sel usada para selecionar entre a,b,c,d
    output reg [3:0] out  // Saída de 4 bits baseada na entrada sel
);
// Este bloco always é executado sempre que a/b/c/d/sel muda de valor
// Quando isso acontece, baseado no valor em sel, a saída é atribuída a a/b/c/d
always @ (a or b or c or d or sel) begin
    case (sel)
        2'b00: out <= a;
        2'b01: out <= b;
        2'b10: out <= c;
        2'b11: out <= d;
    endcase
end
endmodule

O módulo chamado mux_4x1_case tem quatro entradas de dados de 4 bits, uma entrada de seleção de 2 bits e uma saída de dados de 4 bits. O multiplexador selecionará a, b, c ou d baseada no sinal de seleção sel usando a instrução case.

Esquemático de Hardware

Ambos os tipos de modelos de multiplexador são sintetizados no mesmo hardware como mostrado na imagem abaixo.

Testbench

module tb_4to1_mux;
// Declara variáveis reg internas para conduzir entradas do projeto
// Declara sinais wire para coletar saída do projeto
// Declara outras variáveis internas usadas no testbench
reg [3:0] a;
reg [3:0] b;
reg [3:0] c;
reg [3:0] d;
wire [3:0] out;
reg [1:0] sel;
integer i;
// Instancia um dos projetos, neste caso, usamos o projeto com instrução case
// Conecta variáveis do testbench declaradas acima com as do projeto
mux_4to1_case mux0 (
    .a(a),
    .b(b),
    .c(c),
    .d(d),
    .sel(sel),
    .out(out)
);
// Este bloco initial é o estímulo
initial begin
    // Inicia um monitor em background para exibir valores no log sempre que a/b/c/d/sel/out muda
    $monitor("[%0t] sel=0x%0h a=0x%0h b=0x%0h c=0x%0h d=0x%0h out=0x%0h", $time, sel, a, b, c, d, out);
    // 1. No tempo 0, conduz valores aleatórios a a/b/c/d e mantém sel = 0
    sel <= 0;
    a <= $random;
    b <= $random;
    c <= $random;
    d <= $random;
    // 2. Muda o valor de sel a cada 5ns
    for (i = 1; i < 4; i = i + 1) begin
        #5 sel <= i;
    end
    // 3. Após o Passo 2 terminar, espera 5ns e finaliza simulação
    #5 $finish;
end
endmodule

Log de Simulação

ncsim> run
[0] sel=0x0 a=0x4 b=0x1 c=0x9 d=0x3 out=0x4
[5] sel=0x1 a=0x4 b=0x1 c=0x9 d=0x3 out=0x1
[10] sel=0x2 a=0x4 b=0x1 c=0x9 d=0x3 out=0x9
[15] sel=0x3 a=0x4 b=0x1 c=0x9 d=0x3 out=0x3
Simulação completa via $finish(1) no tempo 20 NS + 0

Verilog

  1. Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
  2. Dominando Concatenação Verilog: Guia Prático
  3. Entendendo Atribuições em Verilog: Tipos, Sintaxe e Boas Práticas
  4. Verilog Blocking vs Non-Blocking: Diferenças Essenciais Explicadas
  5. Dominando Funções em Verilog para Design RTL Eficiente
  6. Entendendo Tasks em Verilog: Funções vs Tasks, Sintaxe e Uso
  7. Gerador de Clock Verilog: Guia de Design e Implementação
  8. Dominando Funções Matemáticas do Verilog para Design de Hardware Eficiente
  9. Dominando $timeformat do Verilog: Precisão e Controle de Exibição
  10. Entendendo e Imprimindo Timescales do Verilog em Qualquer Escopo