Error de descripción síncrona incorrecta en VHDL

0

El proceso debe reaccionar en los bordes ascendentes y descendentes de MainClk. La única diferencia es que también puede restablecer las variables si se cumplen las condiciones de reloj ascendente. Como manejo todas las posibles condiciones del reloj por separado, ¿por qué me da un error?

ERROR:Xst:827 - "D:/Projects/Xilinx/blincker/blinker_mod.vhd" line 47: Signal PixlCounter cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

Aquí está el script:

COUNT4: PROCESS(MainClk)
BEGIN
    IF RISING_EDGE(MainClk) THEN
        IF  Stop = '1' OR SLEEP = '1' THEN
                FastCounter :=(OTHERS => '0');
                PixlCounter :=(OTHERS => '0');
        ELSIF (MainCounter >= 35) THEN
                IF FastCounter >= 3 THEN
                    FastCounter := (OTHERS => '0');
                    PixlCounter :=  PixlCounter + 1;
                ELSE FastCounter := FastCounter + 1;
                END IF;
        ELSE NULL;
        END IF;

    ELSIF FALLING_EDGE(MainClk) THEN
        IF (MainCounter >= 35) THEN
            IF FastCounter >= 3 THEN
                FastCounter := (OTHERS => '0');
                PixlCounter :=  PixlCounter + 1;
            ELSE FastCounter := FastCounter + 1;
            END IF;
        ELSE NULL;
        END IF;
    ELSE NULL;
    END IF;
END PROCESS COUNT4;

EDIT

Dado que el proceso se produce al cambiar MainClk (el clima está subiendo o bajando), ¿por qué no es práctico simplemente verificar si está subiendo o bajando si MainClk = '1' o = '0':

    COUNT4: PROCESS(MainClk)
BEGIN
    IF MainClk = '1' THEN
        IF  Stop = '1' OR Sleep = '1' THEN
                FastCounter :=(OTHERS => '0');
                PixlCounter :=(OTHERS => '0');
        ELSIF (MainCounter >= 35) THEN
                IF FastCounter >= 3 THEN
                    FastCounter := (OTHERS => '0');
                    PixlCounter :=  PixlCounter + 1;
                ELSE FastCounter := FastCounter + 1;
                END IF;
        ELSE NULL;
        END IF;

    ELSE
        IF (MainCounter >= 35) THEN
            IF FastCounter >= 3 THEN
                FastCounter := (OTHERS => '0');
                PixlCounter :=  PixlCounter + 1;
            ELSE FastCounter := FastCounter + 1;
            END IF;
        ELSE NULL;
        END IF;
    END IF;
END PROCESS COUNT4;
    
pregunta Nazar

2 respuestas

1

El hardware FPGA no permite sincronizar ambos bordes en un flip-flop.

Lo que puedes hacer es usar un reloj de doble velocidad para realizar un proceso en ambos bordes del reloj original. Una vez que tienes un reloj de doble velocidad, es cuestión de crear una señal oscilante que indique si está cayendo o subiendo. De la siguiente manera:

signal rising_edge : std_logic;

...

COUNT4: PROCESS(MainClkx2)
BEGIN
    IF RST = '1' THEN
    -- Change as needed
        rising_edge <= '0';
    ELSIF RISING_EDGE(MainClkx2) THEN
        rising_edge <= not rising_edge;
        if (rising_edge = '1') then 
            -- rising edge stuff
            IF  Stop = '1' OR SLEEP = '1' THEN
                    FastCounter :=(OTHERS => '0');
                    PixlCounter :=(OTHERS => '0');
            ELSIF (MainCounter >= 35) THEN
                IF FastCounter >= 3 THEN
                    FastCounter := (OTHERS => '0');
                    PixlCounter :=  PixlCounter + 1;
                ELSE 
                    FastCounter := FastCounter + 1;
                END IF;
            END IF;
        ELSIF (rising_edge = '0') then
            -- Falling Edge Stuff
            IF FastCounter >= 3 THEN
                FastCounter := (OTHERS => '0');
                PixlCounter :=  PixlCounter + 1;
            ELSE 
                FastCounter := FastCounter + 1;
            END IF;
        END IF;
    END IF;
END PROCESS COUNT4;

El reloj de doble velocidad crea un flanco ascendente tanto para el caso "ascendente" como "descendente" mientras se trabaja dentro de las limitaciones de hardware. La señal rising_edge indica en qué "mitad" del reloj de velocidad normal estamos en marcha.

La desventaja de esto es que está trabajando con un reloj de doble velocidad, lo que significa que el cierre de tiempo será más difícil de lograr. Puede ser una buena idea reducir partes del diseño que deben estar en este reloj y dejar todo lo demás en un reloj inferior.

    
respondido por el stanri
3

¿Por qué me da un error?

Hay un solo controlador para cada señal en un proceso, no puedes sincronizar los mismos elementos de almacenamiento en ambos bordes de un reloj. La síntesis no tratará una variable diferente de una señal. No es responsabilidad del lenguaje VHDL asegurarse de que las variables compartidas se operen correctamente, aunque puede imaginar que PixelCounter y FastCounter solo pueden asignarse en este proceso.

Una posible solución

Como lo intentaste y vemos la palabra píxel, supongo que te enfrentas a un límite de rendimiento y no puedes simplemente duplicar la velocidad del reloj.

Pruebe dos procesos, FastCounter / PixelCounter con nombres diferentes, operando en las dos fases del reloj. Usted incrementa en dos, pero un conjunto tiene una constante LSB '0' y el otro '1'. Los incrementadores son más cortos en 1, los contadores reales de FastCounter, PixelCounter tienen una longitud más corta.

Un mux 2: 1 con MainClk ya que la selección es más rápida que el incremento en el PixelCounter. Debería bloquear la selección con (detener o SLEEP).

En algún lugar, puede necesitar un retraso de medio reloj en algunas señales que requieren registros de tuberías en la fase de reloj opuesta.

(Detener o SLEEP) también restablece ambos conjuntos de contadores.

Y ahora ...

Se da cuenta de que, en cambio, puede simplemente multiplexar las constantes LSB y usar un solo conjunto de contadores en un solo proceso, pero el proceso de averiguar cómo acelerar los contadores le dio la respuesta. Funciona porque los contadores acortados aumentan a la mitad de la velocidad o durante un período de un MainClk.

La expresión MainCounter >= 35 le dice qué fase de MainClk se usa en la selección del multiplexor LSB.

Si me hubieras proporcionado declaraciones, lo habría editado. ¿Son las variables globales FastCounter y PixelCounter?

    
respondido por el user8352

Lea otras preguntas en las etiquetas