He escrito un código verilog y la simulación RTL funciona bien. Luego de esto sinteticé el diseño utilizando la herramienta XST en Xilinx ISE 13.2. La simulación posterior a la síntesis está mostrando algunos resultados inesperados. No sé qué salió mal ya que no hubo advertencias durante la simulación. ¿Qué debería hacer ahora? ¿Hay alguna forma de depurar la lista de conexiones del nivel de síntesis posterior? ¿Cómo puedo saber qué está haciendo mi herramienta de síntesis (XST) con mi diseño? He incluido parte de mi código fuente. Es para controlar FSM de mi diseño.
always @ (posedge clock)
begin
case (state) // s0, s1, s2, s3, s_reset are parameters
s_reset:
begin
if(start_proc)
state <= s0;
else
state <= s_reset;
end
s0: begin
pixel_value <= dataOut_bigimage;
pixel_ref <= dataOut_smallimage;
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
if(base_col == 3'b101)
begin
base_row_prev <= base_row;
base_col_prev <= base_col;
base_col <= 3'b000;
base_row <= base_row+1;
end
else
begin
base_col <= base_col+1;
base_col_prev <= base_col;
base_row_prev <= base_row;
end
state <= s1;
end
s1: begin
if (pixel_value <= pixel_ref)
accumulator <= accumulator+1;
else
accumulator <= accumulator;
if({i,j} == 2'b00)
state <= s2;
else state <= s0;
end
s2: begin
if (accumulator > 2'b01)
begin
matchcount <= matchcount+1;
rowmatch[matchcount] <= base_row_prev;
colmatch[matchcount] <= base_col_prev;
end
accumulator <= 2'b00;
if (base_row == 2'b11)
state <= s3;
else
state <= s0;
end
s3: begin
task_done <= 1'b1;
state <= s3;
end
Todo lo que está dentro del bloque siempre es del tipo de datos reg y se inicializa correctamente en un bloque inicial separado
gracias de antemano
Agregue (y use) una señal de reinicio.
Los FPGA de Xilinx tienen una señal de configuración/reinicio global (GSR) que pone todos los registros en su estado predeterminado o como se especifica en la declaración de registro (esto está documentado en la Guía del usuario de XST al comienzo del capítulo 5). AFAIK, el bloque @initial se ignora.
Sin embargo, las cosas son caóticas cuando se inicia el FPGA, porque:
Entonces, los valores iniciales de Flip-Flop después del GSR no son suficientes.
Cree un módulo que genere una señal de reinicio para cada dominio de reloj. Puede crearlo haciendo AND con señales de reinicio asíncronas relevantes, como un pin de reinicio externo, señales bloqueadas de PLL/DCM, y usándolo con un sincronizador, de la siguiente manera:
(Fuente: ¿Cómo restablezco mi FPGA? )
Aquí hay una parte de su código que podría hacer tropezar a alguien nuevo en Verilog:
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
...
En este código, el j
utilizado para la comparación ( if(j==1'b1)
) es el valor antiguo de j
, no el valor recién incrementado. Pero sospecho que ya sabía esto y, de todos modos, si este fuera su problema, lo habría visto en la simulación de comportamiento (a menos que estuviera usando una asignación de bloqueo como j = j+1
cuando hizo la simulación de comportamiento).
Otra cosa extraña sobre su código es que una vez que llega al estado 3, está atascado. No proporcionó ningún mecanismo para volver al estado de reinicio o al estado 0, que es un diseño inusual, pero tampoco parece ser el problema por el que está preguntando.
Aparentemente, hay una característica específica de la herramienta que permite sintetizar bloques iniciales en su caso. Yo no era consciente de eso cuando escribí esto. Me pregunto por qué agregarían esa característica, porque solo fomentaría un mal estilo de codificación. Una megafunción de encendido y reinicio tendría más sentido. Así que toma esta respuesta como un consejo general.
Todo lo que está dentro del bloque siempre es del tipo de datos reg y se inicializa correctamente en un bloque inicial separado
Los bloques iniciales no suelen ser sintetizables. Aunque algunas herramientas pueden implementar correctamente el bloque inicial, no es recomendable confiar en este comportamiento por razones de portabilidad. Por ejemplo, si cambia de herramienta, puede romper su diseño. No debe usarlos en bloques que pretenda sintetizar en general, ya que es posible que el comportamiento previo y posterior a la síntesis no coincida.
Su bloque no tiene señal de reinicio y, por lo general, esto significa que no hay inicialización en el hardware. Para solucionar este problema, agregue una señal de reinicio y una condición de reinicio a su código. Luego, coloque el contenido del bloque inicial en el nuevo bloque de condición de reinicio.
Le aconsejaría que tenga un bloque combinacional y mueva toda la lógica de control allí y solo mantenga la lógica de transferencia de datos en el bloque secuencial. No he ejecutado su código, pero siento que en el caso de que el estado sea s0, sus dos condiciones if (if j==1'b1) y (if {i,j} == 2'b11) podrían ser chocando entre sí. En una simulación de comportamiento normal, la herramienta simula el diseño sin demoras. Sin embargo, después de la síntesis, los retrasos se agregan al diseño y pueden causar el problema de "resultado aleatorio" que está viendo.
if
declaraciones que señaló. No estarían 'chocando' de ninguna manera que yo pueda ver.No encontré ninguna mención acerca de que initial
los bloques son la forma correcta de inicializar el valor de los registros en la Guía del usuario de XTS .
Por otro lado, encontré la siguiente declaración en la página 109: "Dado que los bloques iniciales se ignoran durante la síntesis, solo se discuten siempre los bloques".
Bueno, parece que su herramienta de síntesis no admite la inicialización de registros en initial
bloques. Tienes dos opciones:
reg [3:0] arb_priority = 4'b1011;
En general, le aconsejo enfáticamente que no use initial
declaraciones para inicializaciones de valores (excepto para la inicialización de contenidos SRAM y la inicialización de señales de banco de pruebas).
Tim
akash singh
Tim
Tim
akash singh
Tim