¿Hay una forma más optimizada de hacer un incrementador que un sumador completo?

Estoy diseñando un microprocesador muy simple como proyecto para ayudar a aprender VHDL. Así que necesito algo para incrementar el contador de programa de 8 bits. Tendré que incrementarlo en dos. ¿Hay un mejor diseño (ya sea más rápido o menos lógica requerida para la misma velocidad) que usar un sumador completo de 8 bits? También estoy interesado en lo mismo si solo necesita aumentar la PC en 1.

No sé casi nada sobre VHDL y tal vez lo des por sentado cuando hablas de un sumador completo, así que lo siento si ese es el caso, pero para mejorar el rendimiento tienes el "sumador de avance".
Por cierto: enlace por si acaso en.wikipedia.org/wiki/Carry_look-ahead_adder
@JaimePardos, todas las ALU usan este o un dispositivo más avanzado para aumentar la velocidad. Esperar retrasos de 32 bits de acarreo no es aceptable en un procesador moderno.

Respuestas (5)

Hmmm, todo esto depende de qué es exactamente lo que estás tratando de aprender. Un contador o sumador en VHDL es muy fácil:

  signal count  :std_logic_vector (7 downto 0) := (others=>'0');
  . . .
  process (clk)
  begin
    if rising_edge(clk) then
      if count_enable='1' then
        count <= count + 1;  -- could be +2 also
      end if;
    end if;
  end process;

¡Y eso es! El compilador VHDL normalmente sintetizará un sumador completo para esto, y luego optimizará todo lo que no sea necesario, terminando con una especie de semisumador. Lo bueno de hacerlo de esta manera es que su código es legible y fácil de entender y el compilador se ocupa de descubrir la mejor manera de implementarlo.

Ahora, si está tratando de aprender sobre sumadores y contadores, entonces mi pequeño fragmento de código no lo ayudará mucho. En ese caso, debe implementar un medio sumador de forma manual y difícil.

Después de mirarlo por un tiempo tratando de encontrar una manera más eficiente, me conformé con usar el sumador completo proporcionado por VHDL:S <= (I) + ("00000010");
Además, una buena herramienta de síntesis elegirá automáticamente una implementación adecuada en función de sus limitaciones, es decir, ondulación si la velocidad no es importante y CLA u otra implementación optimizada si lo es.

En realidad, no necesita un sumador completo para incrementar en 1; usar medios sumadores donde la primera entrada se establece en 1, y los bits de acarreo están conectados en cadena al siguiente bit. Sin embargo, no estoy seguro de si hay una manera mejor de hacerlo.

Se puede incrementar en dos ignorando el primer bit de un número y usando el mismo método anterior.

NOTA: no soy un experto en VHDL, no puedo decir si esto podría ser más rápido, pero debería ser menos lógico.

Editar: Además, hay una patente vencida para un incrementador binario simple que podría ser de interés: http://www.freepatentsonline.com/3989940.pdf

Bueno, tampoco soy un experto, pero supongo que mientras no haya "bucles" en el hardware (es decir, en serie), menos lógica siempre debería ser mejor.
Para su edición. Guau, había olvidado lo densos que son los PDF de patentes.

Tal vez pueda usar un contador binario creado a partir de flip-flops JK , uno en el que puede cargar el valor del bit en cada flip-flop y luego simplemente cambiar el reloj. Contar de 2 significaría cargar todo menos el bit menos significativo en el contador, ya que ese bit nunca cambia.

Probablemente esto no sea mejor que una implementación de medio sumador, pero tal vez sea más fácil de entender :)

Lo que necesita específicamente es una serie de T-triggers + un montón de puertas AND. Debe pasar la señal de 'alternar' al bit n solo si todos los bits anteriores eran 1. Esto es mucho más rápido que el sumador completo, no requiere llevar adelante y consume muchos menos transistores.

PD. Hace algún tiempo me hacía exactamente la misma pregunta ;-)

Lo que está describiendo no es más rápido en un FPGA que usar un sumador completo o medio normal, y requiere más recursos lógicos. Esto no es intuitivo al principio, pero quédate conmigo aquí. Si estuviera implementando la lógica a partir de puertas sin procesar y flip-flops, entonces podría tener razón. Pero los FPGA no son compuertas sin procesar ni flip-flops. Los FPGA son estructuras lógicas fijas pero semiprogramables, y estas estructuras incluyen cadenas de transporte dedicadas que han sido cableadas para ser súper rápidas. Mucho más rápido que la "lógica normal", y usarlos libera la lógica normal para, bueno, la lógica normal.
Creo que las cadenas de transporte generalmente se usan mejor para aplicaciones que requieren sumadores completos; Sin embargo, el punto clave debe ser especificar lo que uno quiere que haga el hardware y dejar que el software FPGA descubra la mejor manera de implementarlo dados los recursos de chip que existen. Si hay suficientes otras cosas matemáticas para usar cualquier cadena de transporte dedicada que exista, un incrementador se puede hacer bastante bien en la lógica ordinaria. Si los recursos de la cadena de transporte están disponibles, puede ser bueno usarlos. El software FPGA debería poder resolverlo.
No veo donde dice que es para un FPGA. En esto estoy de acuerdo contigo.

Ciertamente parece que debería haber una simplificación: ¡después de todo, una de las entradas está limitada a un valor fijo que es el mismo cada vez!

Desafortunadamente, eso solo es suficiente para obtener una pequeña reducción en la cantidad de puertas, pero no una gran reducción en el tiempo para completar. Esto se debe a que obtiene sumadores más simples: solo tienen 1 entrada más acarreo, por lo que los sumadores básicos tienen aproximadamente 1/3 menos puertas. Pero el retraso está determinado por los acarreos, que no se reducen, todavía deben ondear toda la cadena. Entonces, no obtienes una aceleración significativa. Y, si quiere ir rápido, al menos la mitad de las puertas se ocupan de los acarreos, por lo que 1/3 de ganancia se reduce a aproximadamente 1/6 menos de puertas en general. Al final, aproximadamente la misma velocidad y el 85% del tamaño de un sumador completo.