¿Es correcto inicializar un registro en verilog y aplicar la condición con el valor inicial de reg en Verilog?

3

Tengo una pequeña duda relacionada con la condición de inicialización en Verilog. Como en una declaración dada:

module rf(out1,ack,en,a,f,c,d,e,clka);
  input [7:0] a,f,c,d,e;
  input clka, en;
  output reg [7:0] out1;
  output reg ack;
  reg[7:0] b[1:5];
  reg [1:0] first=0; reg [2:0] k;

initial begin
  for (k = 1; k <6; k = k + 1) begin
    b[k] = 0;
  end
end

always @(negedge clka) begin
  if (en==1) begin 
    if (first==0) begin
      first<=1;
    end
    if (first==1) begin 
      first<=2;
      b[1]<=a;            
      b[2]<=f;               
      b[3]<=c;             
      b[4]<=d;            
      b[5]<=e; 
    end
  end
end
endmodule

Inicialicé reg primero = 0; Es correcto ? Ya que está dando un resultado correcto después de la simulación, ¿pero hay algún problema cuando lo sintetizamos? Utilicé la primera condición porque quería ejecutar sentencias escritas dentro de (primer == 1) ejecución después de un pulso de reloj. ¿Es el camino correcto? Si no es así, ¿qué debo hacer si quiero ejecutar algunas declaraciones después de uno o dos pulsos de reloj? Espero haber explicado mi confusión claramente.
P.S:

module median_five_sh(out1,ack,reset,a,f,c,d,e,clka);
input [7:0] a,f,c,d,e;
input clka,reset;
output reg [7:0] out1;
output reg ack;
reg en0,en1,en2,en3,en4,en5,en6,en7,en8,en9;
reg[7:0] b[1:5],tmp;
reg first;
reg [3:0] i1,i2,n1,k;

initial begin
            for (k = 1; k <6; k = k + 1) begin
            b[k] = 0;
            end
end

always @( posedge reset) begin 
en0<=0;en1<=0;en2<=0;en3<=0;en4<=0;en5<=0;en6<=0;en7<=0;en8<=0;en9<=0;
first<=0;
i1<=0;i2<=0;n1<=0;k<=0;
tmp=0;
end

always @(negedge clka) begin
if (reset==1) begin 
statement;
en0<=1;
en1<=1;
.
.
end
end
endmodule

El código anterior está simulando y dando salida correcta pero está dando el error después de la síntesis.
** Error: la señal en0 en la unidad .... está conectada a los siguientes controladores múltiples:
* Quería ejecutar sentencias escritas en siempre @ (restablecimiento de posición) solo una vez mientras estaba inicialmente. Básicamente es su inicialización de variables utilizadas en posterior declaración.

    
pregunta RO.BST

3 respuestas

5

La inicialización de los registros en la declaración es perfectamente sintetizable. Le dice al compilador cuál debe ser el valor de encendido del registro. Por lo general, el valor inicial de los registros siempre es 0, y si elige que se establezcan en 1, básicamente utilizará las optimizaciones de empuje de burbuja para invertir el valor del registro y aún usará 0 como el valor inicial (pero en lo que respecta a su lógica le preocupa que efectivamente sería 1).

Sin embargo, esto no se recomienda para cualquier otra cosa que no sea un bus de datos (calificado por alguna señal válida). ¿Por qué? por lo que sucede si tiene una señal de reinicio en otro lugar en su lógica. Si la mitad de su lógica se reinicia en algún momento y tiene una señal de control que solo tiene un valor inicial de encendido y no un reinicio, entonces sus dos núcleos están desincronizados: uno se encuentra en un buen estado de reinicio conocido, el otro se encuentra en el estado desconocido en que se encontraba cuando se produjo el restablecimiento. Para señales de datos calificadas, un valor de "no importa / desconocido" no importa siempre que la señal similar a válida sea restablecida a un estado conocido de inválido.

La mejor práctica es usar una señal de reinicio para que todos los controles y las señales válidas tengan un valor de reinicio, ya sea síncrono o asíncrono. Esto elimina la necesidad de un requisito de valor de encendido inicial (aún puede agregarlo, pero ya no es necesario). El sintetizador determinará el valor de encendido según el valor de reinicio solicitado.

always @ (<edge> clock or posedge reset) begin
    if (reset) begin
        //Reset value goes in here, this value also determines power-on value.
    end else ...

    end
end
    
respondido por el Tom Carpenter
1

Es generalmente una mala práctica confiar en ese tipo de inicialización en la lógica sintetizada. Por un lado, la inicialización, si es que es compatible, solo se aplica inmediatamente después de la configuración de encendido del FPGA. Esto generalmente solo funciona en FPGAs basados en SRAM; otras tecnologías no admiten la inicialización de encendido en absoluto.

Es mucho mejor tener una entrada de restablecimiento explícito en cada módulo que pone todo en un estado conocido, y este restablecimiento puede generarse por cualquier número de condiciones, incluido el encendido, un botón de restablecimiento manual o varios errores internos. detectores de condiciones.

    
respondido por el Dave Tweed
0

Sí, es completamente legal inicializar los registros a un valor si su RTL apunta a FPGA, como han señalado los demás. Los bloques iniciales también, no son sintetizables en el flujo ASIC. Los valores de inicialización se convertirán en parte del archivo de flujo de bits (si está acostumbrado a los términos de Xilinx), y se cargarán cuando "Configuren" el FPGA. De hecho, Xillinx recomienda no agregar un reinicio explícito, ya que la señal de reinicio debe enviarse a toda su lógica. Pero si planea trasladarlo a un ASIC más tarde, agregar un restablecimiento (preferiblemente sincrónico) es un deber.

No pude evitar notar que está utilizando dos bloques siempre separados para un registro. Es por eso que su herramienta de síntesis se queja de varios controladores. Un bloque siempre se sintetiza en un flop / latch (si está describiendo lógica secuencial), con la lógica dentro del bloque siempre utilizada para determinar la entrada D (& rst) para el fracaso. También se asigna tmp con asignación de bloqueo. En general, se dice que es una mala idea mezclar las asignaciones de bloqueo y no bloqueo en el mismo bloque siempre.

    
respondido por el Pramod

Lea otras preguntas en las etiquetas