No coincidencia entre la simulación de nivel RTL y la simulación posterior a la síntesis usando xilinx xst

3

He escrito un código verilog y la simulación RTL está funcionando bien. Después de esto, sinteticé el diseño utilizando la herramienta XST en Xilinx ISE 13.2. La simulación post-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 manera de depurar netlist nivel post síntesis? ¿Cómo puedo saber qué hace mi herramienta de síntesis (XST) con mi diseño? He incluido parte de mi código fuente. Es para el control de 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

Cada cosa dentro del bloque siempre es del tipo de datos reg y se inicializa correctamente en un bloque inicial separado

Gracias de antemano

    
pregunta Akash Singh

5 respuestas

2

Añade (y usa) una señal de reinicio.

Los FPGA de Xilinx tienen una señal de conjunto / restablecimiento (GSR) global que coloca a todos los registros en su estado predeterminado o como se especifica en la declaración de registro (esto se documenta en Guía del usuario de XST al principio del capítulo 5). AFAIK, el bloque inicial @ se ignora.

Sin embargo, las cosas son caóticas cuando se inicia el FPGA, porque:

  • El GSR es asíncrono.
  • Los PLL no están bloqueados
  • No todos los PLL se bloquean al mismo tiempo
  • Hay condiciones de raza en todas partes

Por lo tanto, 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 mediante AND'ing señales de reinicio asíncronas relevantes, como un pin de reinicio externo, señales bloqueadas de PLL / DCM, y usarlo con un sincronizador, de la siguiente manera:

(Fuente: ¿Cómo puedo restablecer mi FPGA? )

    
respondido por el apalopohapa
1

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 recientemente incrementado. Pero sospecho que ya sabía esto y, en cualquier caso, 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 de tu código es que una vez que llegas al estado 3, te quedas atascado. No proporcionó ningún mecanismo para volver al estado de restablecimiento o al estado 0, que es un diseño inusual, pero tampoco suena como el problema que está preguntando.

    
respondido por el The Photon
1

Aparentemente, hay una característica específica de la herramienta que permite sintetizar los bloques iniciales en su caso. No era consciente de eso cuando escribí esto. Me pregunto por qué agregarían esa característica, porque solo fomentaría un estilo de codificación incorrecto. Una mega función de encendido y reinicio tendría más sentido. Así que toma esta respuesta como un consejo general.

  

Cada cosa dentro del bloque siempre es de tipo de datos reg y es   correctamente inicializado en un bloque inicial separado

Los bloques iniciales generalmente no son sintetizables. Aunque algunas herramientas pueden implementar correctamente el bloqueo 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 los bloques que pretende sintetizar en general, ya que es posible que el comportamiento de síntesis previa y posterior a la síntesis no coincida.

Su bloque no tiene señal de reinicio, y generalmente esto significa que no hay inicialización en el hardware. Para solucionar este problema, agregue una señal de restablecimiento y una condición de restablecimiento a su código. Luego, coloque el contenido del bloque inicial en el nuevo bloque de condición de reinicio.

    
respondido por el travisbartley
0

Le recomendaría tener un bloque combinacional y mover toda la lógica de control allí y solo mantener la lógica de transferencia de datos en el bloque secuencial. No he ejecutado su código, pero creo que en el caso de que el estado sea s0, sus dos si condiciones (si j == 1'b1) y (si {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.

    
respondido por el Spartan_Xtreme
0

No encontré ninguna mención sobre los bloques initial como la forma correcta de inicializar el valor de los registros en 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 los bloques".

Bueno, parece que su herramienta de síntesis no admite la inicialización de registros en bloques initial . Tienes dos opciones:

  1. Defina una señal de reinicio adecuada y utilícela para inicializar su diseño (consulte otras respuestas para obtener explicaciones más detalladas)
  2. Use la sintaxis admitida para la inicialización con restablecimiento interno (página 104): reg [3:0] arb_priority = 4'b1011;

En general, le recomiendo encarecidamente que no utilice las declaraciones initial para las inicializaciones de valores (excepto la inicialización de los contenidos de SRAM y la inicialización de las señales de banco de pruebas).

    
respondido por el Vasiliy

Lea otras preguntas en las etiquetas