¿Cómo se implementa este simple contador en un FPGA sin reloj?

5

Como parte de una asignación, debo crear estos bloques que se unen a un módulo de nivel superior más grande. (hay mas bloques no fotografiados). Tengo todo funcionando bien, excepto este contador ARRIBA / ABAJO porque realmente no puedo entender cómo esto puede implementarse sin un CLK .

LasseñalesEN_UPyEN_DOWNsonimpulsossimplesquedeberíanaumentarodisminuirunvalorinternode16bits,quesedivideennibblesysecolocaenlasalida.Sientoqueestodeberíaserbastantesimple,peronopuedoresolverlo.

Heintentadomúltiplesenfoques.

1):dentrodeunsoloproceso

count:PROCESS(RESET,EN_UP,EN_DOWN)BEGINif(RESET='1')thencountSignal<=x"0000";
    elsif(rising_edge(EN_UP) and EN_DOWN = '0') then
        countSignal <= countSignal + 1;
    elsif(rising_edge(EN_DOWN) and EN_UP = '0') then
        countSignal <= countSignal - 1;
    end if;
END PROCESS;

Esto finalmente compila sin errores ni advertencias, sin embargo, el compilador termina creando el circuito incorrecto, vinculando el EN_UP al CLK del flip-flip y el EN_DOWN al CE (clock enable) . Si bien sí, eso es parte de la ecuación, no refleja eso para el caso contrario.

2) - Procesos separados

countUP : PROCESS (RESET, EN_UP)
BEGIN
    if(RESET = '1') then
        countSignal <= x"0000";
    elsif(rising_edge(EN_UP) and EN_DOWN = '0') then
        countSignal <= countSignal + 1;
    end if;
END PROCESS;

countDOWN : PROCESS (RESET, EN_DOWN)
BEGIN
    if(RESET = '1') then
        countSignal <= x"0000";
    elsif(rising_edge(EN_DOWN) and EN_UP = '0') then
        countSignal <= countSignal - 1;
    end if;
END PROCESS;

Esto da como resultado: Signal countSignal[15] in unit UD_COUNTER is connected to following multiple drivers:

3) Procesos múltiples con estados Hi-Z

Intenté un intento con Hi-Z que también falló.

    
pregunta krb686

4 respuestas

6

Tienes razón al pensar que tendrás que usar algo para el reloj del contador. De lo contrario, no hay nada que decirle cuándo para contar. O falta el reloj en el diagrama, o tendrá que activar el borde en las habilitaciones, en cuyo caso el circuito que cree que debería haberse sintetizado es imposible, ya que no puede manejar el mismo registro con dos relojes diferentes. Puedes probar algo como:

en_either <= en_up or en_down;

process (en_either, rst)
begin
  if rst = '1' then
    count <= (others => '0');
  elsif rising_edge(en_either) then
    if en_up = '1' then
      count <= count + 1;
    else
      count <= count - 1;
    end if;
  end if;
end process;

Puede haber mejores formas, pero si realmente no puedes tener un reloj, supongo que funcionará. Si las habilitaciones se superponen de alguna manera, por supuesto, esto podría no funcionar como se esperaba.

Como indica el mensaje de error, su versión de dos procesos no funcionará porque está transmitiendo la misma señal de dos procesos diferentes. Puede haber formas de solucionar esto, pero sería mucho más problemático que la versión 1-process.

Como señala David en los comentarios, esto no funcionará correctamente a menos que sus habilitaciones sean libres de rebotes. La fuente de las habilitaciones no está clara en tu publicación.

    
respondido por el fru1tbat
3

No necesita un reloj para esto, pero necesita comprender mejor lo que debe hacer para cada entrada posible dada a su red.

El primer enfoque es el mejor, así que analicemos. Empiezas marcando RESET y eso es genial, eludir lo que venga después es cómo lo haría.

Ahora a la parte difícil. Verifica si EN_DOWN o EN_UP tenían un flanco ascendente, verifica que la otra señal sea cero y actúa en consecuencia. Eso no tiene sentido para mí, al menos dada la (pequeña) especificación que proporciona.

Ya que estás en un proceso en el que ya estás sentado en los bordes, solo comprobaría qué sucedió con el event thingy. Algo como

count : PROCESS (RESET, EN_UP, EN_DOWN)
BEGIN
    if(RESET = '1') then
        countSignal <= x"0000";
    else
        if(EN_UP'EVENT and EN_UP = '1') then
            countSignal <= countSignal + 1;
        end if;
        if(EN_DOWN'EVENT and EN_DOWN = '1') then
            countSignal <= countSignal - 1;
        end if;
    end if;
END PROCESS;

Esto me parece mejor y más fiel a lo que pides.

Para el registro, una forma heurística de hacer esto (para que entiendas que no necesitas un reloj):

tiene su registro de salida de 16 bits hecho con DFF, y dos redes combinacionales que computan salida - 1 y salida + 1. estas dos redes están conectadas a un mux de entrada dual, y la entrada del registro de salida está conectada al mux. Los relojes DFF son el o entre count_up y count_down, mientras que el bit de control mux es uno de ellos. Cuando llega un pulso, el registro se actualiza con el valor correcto.

Si no está satisfecho con la implementación que obtiene después de sintetizar, puede intentar implementar mi última idea y ver si funciona para usted.

    
respondido por el Vladimir Cravero
1

Es posible diseñar un contador a partir de lógica puramente combinatoria, si se le dan dos entradas en lugar de una, y las entradas cambian de estado en un patrón bien definido. Por ejemplo, supongamos que uno tiene dos entradas P y Q, dos valores de ocho bits X e Y, y los calcula de manera combinatoria de la siguiente manera:

When P is high
  X=Y+1
Else
  X=X

When Q is high:
  Y=X+1
Else
  Y=Y

Si P y Q alternativamente se elevan, entonces X e Y contarán el número de veces que lo han hecho, siempre que P y Q nunca sean altos simultáneamente; si alguna vez se superponen, los valores de X e Y no estarán definidos.

Aunque los flip flops han reemplazado en gran medida al estilo anterior de los circuitos, el enfoque de sincronización de dos fases históricamente ha sido bastante popular, especialmente porque en las tecnologías NMOS, dada una velocidad de reloj mínima, se podrían usar circuitos de enclavamiento que eran mucho más baratos que el flip fracasos Considera:

simular este circuito : esquema creado usando CircuitLab

Cada relé debe ser simplemente un NFET único, pero no puedo hacer que simulen correctamente, así que sustituí un relé. Este circuito implementa un contador de división por dos con cinco transistores activos y tres pull-ups pasivos. Implementar un flip flop desencadenado por el borde requeriría más circuitos, por lo que aunque es necesario generar y distribuir dos relojes en lugar de uno, el efecto general es una "victoria".

    
respondido por el supercat
1

A los FPGA realmente no les gusta correr sin un reloj. Obtienes comportamientos inesperadamente locos. Por lo tanto, es mucho mejor utilizar un contador síncrono de subida / bajada con las entradas de subida / bajada muestreadas por un reloj más rápido.

simular este circuito : esquema creado usando CircuitLab

El período de reloj no debe ser más de 1/3 del ancho de pulso ascendente o descendente.

    
respondido por el WhatRoughBeast

Lea otras preguntas en las etiquetas