Registro de desplazamiento bidireccional Verilog de n bits
En electrónica digital, un registro de desplazamiento es una cascada de flip-flops donde el pin de salida q de un flop está conectado al pin de entrada de datos (d) del siguiente. Debido a que todos los flops funcionan en el mismo reloj, la matriz de bits almacenada en el registro de desplazamiento se desplazará una posición. Por ejemplo, si un registro de desplazamiento a la derecha de 5 bits tiene un valor inicial de 10110 y la entrada al registro de desplazamiento está vinculada a 0, entonces el siguiente patrón será 01011 y el siguiente 00101.
Diseño
Este diseño de registro de desplazamiento tiene cinco entradas y una salida de n bits y el diseño se parametriza usando parameter
MSB para indicar el ancho del registro de desplazamiento. Si n es 4, entonces se convierte en un registro de desplazamiento de 4 bits. Si n es 8, entonces se convierte en un registro de desplazamiento de 8 bits.
Este registro de desplazamiento tiene algunas características clave:
- Se puede habilitar o deshabilitar manejando un pin del diseño
- Puede cambiar tanto a la izquierda como a la derecha cuando se conduce dir
- Si rstn se baja, restablecerá el registro de desplazamiento y la salida será 0
- El valor de los datos de entrada del registro de desplazamiento se puede controlar mediante el pin d
module shift_reg #(parameter MSB=8) ( input d, // Declare input for data to the first flop in the shift register
input clk, // Declare input for clock to all flops in the shift register
input en, // Declare input for enable to switch the shift register on/off
input dir, // Declare input to shift in either left or right direction
input rstn, // Declare input to reset the register to a default value
output reg [MSB-1:0] out); // Declare output to read out the current value of all flops in this register
// This always block will "always" be triggered on the rising edge of clock
// Once it enters the block, it will first check to see if reset is 0 and if yes then reset register
// If no, then check to see if the shift register is enabled
// If no => maintain previous output. If yes, then shift based on the requested direction
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
Esquema de hardware
Banco de pruebas
El banco de pruebas se utiliza para verificar la funcionalidad de este registro de desplazamiento. El diseño se instancia en la parte superior module
y las entradas se manejan con diferentes valores. El comportamiento de diseño para cada una de las entradas se puede observar en el pin de salida.
module tb_sr;
parameter MSB = 16; // [Optional] Declare a parameter to represent number of bits in shift register
reg data; // Declare a variable to drive d-input of design
reg clk; // Declare a variable to drive clock to the design
reg en; // Declare a variable to drive enable to the design
reg dir; // Declare a variable to drive direction of shift registe
reg rstn; // Declare a variable to drive reset to the design
wire [MSB-1:0] out; // Declare a wire to capture output from the design
// Instantiate design (16-bit shift register) by passing MSB and connect with TB signals
shift_reg #(MSB) sr0 ( .d (data),
.clk (clk),
.en (en),
.dir (dir),
.rstn (rstn),
.out (out));
// Generate clock time period = 20ns, freq => 50MHz
always #10 clk = ~clk;
// Initialize variables to default values at time 0
initial begin
clk <= 0;
en <= 0;
dir <= 0;
rstn <= 0;
data <= 'h1;
end
// Drive main stimulus to the design to verify if this works
initial begin
// 1. Apply reset and deassert reset after some time
rstn <= 0;
#20 rstn <= 1;
en <= 1;
// 2. For 7 clocks, drive alternate values to data pin
repeat (7) @ (posedge clk)
data <= ~data;
// 4. Shift direction and drive alternate value to data pin for another 7 clocks
#10 dir <= 1;
repeat (7) @ (posedge clk)
data <= ~data;
// 5. Drive nothing for next 7 clocks, allow shift register to simply shift based on dir
repeat (7) @ (posedge clk);
// 6. Finish the simulation
$finish;
end
// Monitor values of these variables and print them into the logfile for debug
initial
$monitor ("rstn=%0b data=%b, en=%0b, dir=%0b, out=%b", rstn, data, en, dir, out);
endmodule
La hora en que el registro de turnos está habilitado se resalta en verde en el registro que se muestra a continuación. El momento en que cambia su dirección está resaltado en amarillo. El tiempo en que el pin de entrada de datos permanece constante se resalta en azul.
Registro de simulaciónncsim> 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 Simulation complete via $finish(1) at time 430 NS + 0
Verilog
- Tutorial de Verilog
- Concatenación Verilog
- Asignaciones de Verilog
- Bloqueo y no bloqueo de Verilog
- Funciones de Verilog
- Tarea Verilog
- Generador de reloj Verilog
- Funciones matemáticas de Verilog
- Formato de hora de Verilog
- Alcance de la escala de tiempo de Verilog
- Operaciones de E/S de archivos de Verilog