Inicializar correctamente un registro de desplazamiento (Verilog)

2

He estado luchando con un programa Verilog muy simple. Es un registro de desplazamiento de 4 bits que se gira en cada ciclo de reloj y controla cuatro LED. (Como puede ver, soy nuevo en los FPAG y HDL).

El problema : debajo del código se sintetiza sin advertencias y se programa con éxito en el FPGA. Luego, al comenzar, no pasa nada, los LED permanecen apagados. La entrada i_Switch_1 se agregó para que algo suceda y, de hecho, cuando presiono el interruptor, los LED comienzan a girar.

Aquí está el código de Verilog:

Versión 1 (falla)

module top
   (input i_Clk, 
    input i_Switch_1,
    output o_LED_1,
    output o_LED_2,
    output o_LED_3,
    output o_LED_4
   );

     reg [3:0]shift_reg;

     initial
         shift_reg = 4'b0001;   // has no effect

     always @(posedge i_Clk)
     begin
         shift_reg <= i_Switch_1 ? 4'b0001 : {shift_reg[2:0], shift_reg[3]};
     end

     assign o_LED_1 = shift_reg[0];
     assign o_LED_2 = shift_reg[1];
     assign o_LED_3 = shift_reg[2];
     assign o_LED_4 = shift_reg[3];

 endmodule

Evaluación : mi conclusión hasta ahora es que shift_reg no se ha inicializado en 1. La vista RTL a continuación muestra que no se sintetiza ninguna inicialización.

Leíenmuchoslugaresqueelbloqueinicialessintetizable,porloqueahoraestoyrealmenteconfundido.

Pregunta1:¿Mievaluaciónescorrecta?

Pregunta2:Suponiendoquemievaluaciónescorrecta,¿cuáleselremedio?Heintentadovariascosasyningunadeellasfunciona:

  • Rutaenelpindereinicio,peroesonopareceestarpermitido.
  • Utiliceunacomparacióndeshift_reg==0(versión2acontinuación)
  • Useunabanderais_init(versión3acontinuación)

Estoyempezandoacreerqueestoyobteniendoalgofundamentalmenteincorrecto.¿Quéestápasando?

Versión2(falla)

shift_reg<=(shift_reg==0||i_Switch_1)?1:{shift_reg[2:0],shift_reg[3]}

Versión3(falla)

regis_init;initialis_init=0;//Musthavethisorelsetheis_initgetsoptimizedout!always@(posedgei_Clk)beginif(~is_init||i_Switch_1)beginis_init<=1;shift_reg<=4'b0001;endelsebeginis_init<=1;shift_reg<={shift_reg[2:0],shift_reg[3]};endend

Configuración:LatticeSemiiCE40HX1K(nandlandgoboard)coniCEcube2,laherramientadesíntesisesSynplifyPro.

-

Actualizar

Estofuncionaaquí:

Versión4(éxito)

reg[3:0]shift_reg=0;always@(posedgei_Clk)begincase(shift_reg)1:shift_reg<=2;2:shift_reg<=4;4:shift_reg<=8;8:shift_reg<=1;default:shift_reg<=1;endcaseend

Peroelresultadodelasíntesisestáalgohinchado:

    
pregunta mcmayer

2 respuestas

3

En muchos casos, los FPGA no son compatibles con los valores iniciales de encendido de nada excepto 0. Sé que no todos los FPGA de Altera con los que he trabajado. De hecho, de acuerdo con la hoja de datos para su FPGA, esta es la caso:

  

Cada DFF también se conecta a una señal de reinicio global que se afirma automáticamente inmediatamente después de la configuración del dispositivo.

El reinicio global sugiere 0, se establecería si tuviera como resultado un 1.

Para evitar esto, lo que hacen algunas herramientas de síntesis es algo que se llama burbuja de empuje: todo lo que debería inicializarse a 1 se inicializa a 0 y no se agrega una puerta a la salida. Sin embargo, parece que en su caso la herramienta de síntesis no está haciendo esto correctamente. Puedes intentarlo manualmente si quieres:

...
shift_reg <= {shift_reg[2:1], !shift_reg[0], shift_reg[3]};
...
assign o_LED_1 = !shift_reg[0];

Aunque eso no es particularmente útil a largo plazo.

También puede probar la forma alternativa de especificar el valor inicial y ver si la herramienta de síntesis hace un mejor trabajo:

reg [3:0] shift_reg = 4'b0001;

-

En cualquier caso, generalmente no solemos confiar en un valor inicial para registros y lógica. En su lugar, tenemos una señal de reinicio global y cláusulas de reinicio en la lógica. Esto nos permite poder establecer todos los registros en un estado conocido en cualquier momento sin tener que hacer un ciclo de alimentación.

En su ejemplo con el conmutador, parece que su código con el conmutador ha inferido correctamente una señal de reinicio ( R_PAT I presume) que se maneja como se espera en i_Switch_1 . Sin embargo, normalmente utilizamos un formato algo diferente para las señales de reinicio:

always @ (posedge clock) begin
    if (reset) begin
        // Do stuff here when in reset
    end else begin
        // Do stuff here when not in reset
    end
end
    
respondido por el Tom Carpenter
2

La declaración de procedimiento estructurado "inicial" no es sintetizable. Para inicializar el valor cuando se enciende su fpga, puede iniciar el valor del registro al dar el valor en el momento de la declaración. por ejemplo.

reg [3:0]shift_reg= 4'b0000;

    
respondido por el Hesham Ahmad

Lea otras preguntas en las etiquetas