Verilog Shift Register con dos entradas

0

Estoy intentando crear un registro de desplazamiento de 32 bits en Verilog con dos entradas, DATA0 y DATA1. Los DATOS se conducen a un nivel bajo para ingresar un 0 al registro y los DATOS se conducen a un nivel bajo para ingresar un 1 al registro. DATA0 y DATA1 se mantienen altos cuando no se están utilizando.

El problema con el que me estoy topando es que cuando tengo un DATO bajo, reemplaza todos los bits en el registro con ceros. DATA1 funciona bien, cambiando el registro y agregando un uno al final. Mi código es el siguiente:

module shift(
databits,   //The register
reset   ,   // reset Input
DATA0   ,   //Input for a 0
DATA1           //Input for a 1
);

//------------Output Ports--------------
    output [31:0] databits;
//------------Input Ports--------------
     input reset, DATA0, DATA1;
//------------Internal Variables--------
     reg [31:0] databits;
//-------------Code Starts Here-------

always @(posedge reset or negedge DATA0 or negedge DATA1) begin

    if(reset) begin
        databits <= 0;
    end

    //If DATA0 triggered this, write a 0
    else if (~DATA0) begin
        databits <= databits << 1;
    end

    //If DATA1 triggered this, write a 1
    else if (~DATA1) begin
        databits <= { databits[30:0], 1'b1 };
    end

end

endmodule

Intenté usar DATA0 para ingresar también algunos en el registro, pero sobrescribió a todos los reigsters con unos. Tengo entendido que el bloque siempre debe ejecutarse una vez cuando DATA0 baja, por lo que no entiendo por qué está haciendo esto.

    

1 respuesta

1

Tal como está, tiene un registro de desplazamiento cuyo reloj es DATA0 y DATA1. Esto no se puede sintetizar ya que los FPGA no tienen flip flops de doble reloj.

Para que funcione, necesitarás dos cosas:

  1. Un solo reloj lo suficientemente rápido para muestrear las señales DATA0 y DATA1
  2. Lógica de detección de bordes para las señales DATA0 y DATA1.

La detección de bordes es algo bastante sencillo de hacer:

module fallingEdge (
    input clock,
    input signal,

    output reg edge
);

reg signalDly;

always @ (posedge clock) begin
    signalDly <= signal; //Delay signal by one clock cycle.
    edge <= signalDly && !signal; //If the signal was high in the last cycle but low now, it must be a falling edge
end

endmodule

La salida de ese bloque será alta para exactamente un ciclo de reloj cuando haya un flanco descendente de la señal de datos.

Necesitará un detector de bordes para cada uno de los DATOS y DATOS1 que resultarán en dos nuevas señales (por ejemplo, EDGE0 y EDGE1).

Su registro de desplazamiento se sincroniza con su señal de 'reloj' (1), y simplemente verifica las señales de borde en ese bloque. Si EDGE0 es alto, marque en 0. Si EDGE1 es alto, marque en 1. Si ambos son altos al mismo tiempo, deberá decidir si 0 o 1 tiene prioridad.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas