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

Registrador de Deslocamento Bidirecional de N Bits em Verilog – Projeto e Implementação

Na eletrônica digital, um registrador de deslocamento é uma cascata de flip-flops onde o pino de saída q de um flop é conectado ao pino de entrada de dados (d) do próximo. Como todos os flops trabalham no mesmo clock, o array de bits armazenado no registrador de deslocamento será deslocado em uma posição. Por exemplo, se um registrador de deslocamento à direita de 5 bits tem um valor inicial de 10110 e a entrada do registrador de deslocamento está ligada a 0, então o próximo padrão será 01011 e o seguinte 00101.

Projeto

Este projeto de registrador de deslocamento tem cinco entradas e uma saída de n bits e o projeto é parametrizado usando parameter MSB para significar a largura do registrador de deslocamento. Se n é 4, então se torna um registrador de deslocamento de 4 bits. Se n é 8, então se torna um registrador de deslocamento de 8 bits.

Este registrador de deslocamento tem alguns recursos principais:

module shift_reg #(parameter MSB=8) (
    input d,      // Declara entrada para dados ao primeiro flop no registrador de deslocamento
    input clk,    // Declara entrada para clock para todos os flops no registrador de deslocamento
    input en,     // Declara entrada para enable para ligar/desligar o registrador de deslocamento
    input dir,    // Declara entrada para deslocar em direção esquerda ou direita
    input rstn,   // Declara entrada para resetar o registrador para um valor padrão
    output reg [MSB-1:0] out  // Declara saída para ler o valor atual de todos os flops neste registrador
);
// Este bloco always será "sempre" disparado na borda de subida do clock
// Uma vez que entra no bloco, primeiro verifica se reset é 0 e se sim então reseta registrador
// Se não, então verifica se o registrador de deslocamento está habilitado
// Se não => mantém saída anterior. Se sim, então desloca baseado na direção solicitada
always @ (posedge clk)
    if (!rstn) out <= 0;
    else begin
        if (en)
            case (dir)
                0: out <= {out[MSB-2:0], d};
                1: out <= {d, out[MSB-1:1]};
            endcase
        else out <= out;
    end
endmodule

Esquemático de Hardware

Testbench

O testbench é usado para verificar a funcionalidade deste registrador de deslocamento. O projeto é instanciado no module superior e as entradas são conduzidas com diferentes valores. O comportamento do projeto para cada uma das entradas pode ser observado no pino de saída out.

module tb_sr;
parameter MSB = 16; // [Opcional] Declara um parâmetro para representar número de bits no registrador de deslocamento
reg data;   // Declara uma variável para conduzir d-input do projeto
reg clk;    // Declara uma variável para conduzir clock ao projeto
reg en;     // Declara uma variável para conduzir enable ao projeto
reg dir;    // Declara uma variável para conduzir direção do registrador de deslocamento
reg rstn;   // Declara uma variável para conduzir reset ao projeto
wire [MSB-1:0] out; // Declara um wire para capturar saída do projeto
// Instancia projeto (registrador de deslocamento de 16 bits) passando MSB e conecta com sinais do TB
shift_reg #(MSB) sr0 (
    .d(data),
    .clk(clk),
    .en(en),
    .dir(dir),
    .rstn(rstn),
    .out(out)
);
// Gera clock período = 20ns, freq => 50MHz
always #10 clk = ~clk;
// Inicializa variáveis para valores padrão no tempo 0
initial begin
    clk <= 0;
    en <= 0;
    dir <= 0;
    rstn <= 0;
    data <= 'h1;
end
// Conduz estímulo principal ao projeto para verificar se funciona
initial begin
    // 1. Aplica reset e desassserta reset após algum tempo
    rstn <= 0;
    #20 rstn <= 1;
    en <= 1;
    // 2. Por 7 clocks, conduz valores alternados ao pino de dados
    repeat (7) @ (posedge clk) data <= ~data;
    // 4. Muda direção e conduz valor alternado ao pino de dados por mais 7 clocks
    #10 dir <= 1;
    repeat (7) @ (posedge clk) data <= ~data;
    // 5. Não conduz nada por próximos 7 clocks, permite registrador simplesmente deslocar baseado em dir
    repeat (7) @ (posedge clk);
    // 6. Finaliza a simulação
    $finish;
end
// Monitora valores destas variáveis e imprime no log para debug
initial $monitor("rstn=%0b data=%b, en=%0b, dir=%0b, out=%b", rstn, data, en, dir, out);
endmodule

O tempo quando o registrador de deslocamento está habilitado está destacado em verde no log abaixo. O tempo quando ele muda sua direção está destacado em amarelo. O tempo quando o pino de entrada de dados permanece constante está destacado em azul.

Log de Simulação

ncsim> run
rstn=0 data=1, en=0, dir=0, out=xxxxxxxxxxxxxxxx
rstn=0 data=1, en=0, dir=0, out=0000000000000000
rstn=1 data=1, en=1, dir=0, out=0000000000000000
rstn=1 data=0, en=1, dir=0, out=0000000000000001
rstn=1 data=1, en=1, dir=0, out=0000000000000010
rstn=1 data=0, en=1, dir=0, out=0000000000000101
rstn=1 data=1, en=1, dir=0, out=0000000000001010
rstn=1 data=0, en=1, dir=0, out=0000000000010101
rstn=1 data=1, en=1, dir=0, out=0000000000101010
rstn=1 data=0, en=1, dir=0, out=0000000001010101
rstn=1 data=0, en=1, dir=1, out=0000000001010101
rstn=1 data=1, en=1, dir=1, out=0000000000101010
rstn=1 data=0, en=1, dir=1, out=1000000000010101
rstn=1 data=1, en=1, dir=1, out=0100000000001010
rstn=1 data=0, en=1, dir=1, out=1010000000000101
rstn=1 data=1, en=1, dir=1, out=0101000000000010
rstn=1 data=0, en=1, dir=1, out=1010100000000001
rstn=1 data=1, en=1, dir=1, out=0101010000000000
rstn=1 data=1, en=1, dir=1, out=1010101000000000
rstn=1 data=1, en=1, dir=1, out=1101010100000000
rstn=1 data=1, en=1, dir=1, out=1110101010000000
rstn=1 data=1, en=1, dir=1, out=1111010101000000
rstn=1 data=1, en=1, dir=1, out=1111101010100000
rstn=1 data=1, en=1, dir=1, out=1111110101010000
Simulação completa via $finish(1) no tempo 430 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