Conversión de binario a BCD

Tengo un número de 8 bits cuyos valores oscilan entre 0 y 99. Necesito convertirlo en una representación BCD de 8 bits adecuada del número usando circuitos digitales.

En caso de que necesite saberlo, el valor original es un valor de temperatura leído de un ADC y lo necesito en BCD para mostrarlo en dos pantallas de 7 segmentos. No puedo usar un microcontrolador.

No tiene sentido que no puedas usar un microcontrolador. Cualquier circuito alternativo ocupará más espacio y será más complejo. Retroceda y descubra cuál es el problema real detrás de la restricción del microcontrolador, luego regrese cuando pueda indicar el problema real.
¿Es la restricción "No puedo usar un microcontrolador" de arriba ("Sednus, quiero que construyas esta temperatura -> cosa de 7 segmentos y, por cierto, no uses un microcontrolador") o de tus propios deseos de evitar programar el microcontrolador?
Cualquier solución práctica requerirá un dispositivo programable de algún tipo: ya sea una EPROM, CPLD o microcontrolador. Podría hacerlo con puertas lógicas discretas, pero eso solo sería práctico si se trata de una tarea. Necesitamos más información antes de poder darle una respuesta aceptable.
Se supone que debo diseñar un controlador de aire acondicionado usando un FPGA. Tengo la mayor parte del diseño hecho. Solo estaba tratando de encontrar una manera simple de realizar esta conversión.
Esto todavía no tiene sentido. ¿Por qué tiene que ser un FPGA? Ciertamente, la velocidad no es necesaria. Un microcontrolador sería más económico y fácil de implementar, y más flexible para cambiar. Díganos cuáles son los requisitos reales, no cuál cree que es la solución.
Es parte de un proyecto de clase...
"Es parte de un proyecto de clase" . Deberías haberlo mencionado al principio. Pero aún no ha respondido por qué no hay microcontrolador.
@Olin Lathrop: si se trata de una tarea, la selección de tecnologías a menudo se restringe artificialmente para enfocarse en el lugar previsto para una lección determinada. Además, este requisito específico tiene soluciones más eficientes dentro de una fpga (tabla ROM) que insertar un núcleo de procesador suave en el diseño si no se necesita para otros fines.
@Chris: Sí, a veces las asignaciones se restringen artificialmente, pero depende del OP decirnos esto. No estaba sugiriendo un núcleo suave en un FPGA, solo usando un pequeño micro. No hay nada aquí que haga que un FPGA sea una mejor solución que solo un micro.
@Olin Lathrop: como se indicó, hay más en el proyecto que esta necesidad de conversión de binario a BCD. Presumiblemente, el FPGA se elige para cumplir con los objetivos funcionales educativos y/o generales. Resolver esta pequeña parte del problema que se logra de manera tan simple con una mesa que no garantiza un núcleo suave ciertamente no garantiza el cableado de un micro externo y traer sus herramientas de soporte, hasta que o a menos que haya alguna razón. no se puede hacer internamente o un mandato educativo para usar el micro externo.

Respuestas (4)

Manera más simple:

Utilice una EPROM/EEPROM de 256 bytes.

El valor de entrada se aplica al bus de direcciones.

La salida en el bus de datos es lo que haya programado para esa dirección, así que prográmelo con una asignación de valores binarios a BCD.

Esta es la solución más simple, especialmente en el número de componentes: 1. Sin embargo, si la razón por la que los microcontroladores no funcionan es que OP no puede programarlos, esto no ayudará.
Él dice que no puede usar uno, no por qué no puede usar uno. Él puede ser perfectamente capaz de usar uno, pero le han dicho que no debe hacerlo.
Es posible que la FPGA no tenga RAM interna, ya sea porque no tiene ninguna o porque ya están todas en uso.
@Mike DeSimone: las herramientas de FPGA pueden implementar pequeñas roms en la propia estructura de FPGA si no hay memorias de bloque disponibles.
Algunas herramientas FPGA pueden hacer eso, y algunas requieren que les digas explícitamente que lo hagan.
@Mike DeSimone: modele una ROM usando primitivas de lenguaje y me sorprendería si hay una herramienta que no pueda implementarla en la estructura. Sin embargo, algunas herramientas son lo suficientemente inteligentes como para reconocer que desea una memoria y sustituirla por una memoria de bloque si hay una disponible y cumple con el comportamiento modelado. Usted mismo parece haber publicado una respuesta que depende de esta capacidad de las herramientas para inferir alguna implementación viable, ya sea perspicaz o ciega.
Recuerdo haber tenido problemas con esto con Quartus II de Altera hace un par de años. Modelar una ROM significaba que la etapa de análisis y síntesis inferiría una ROM usando un bloque de memoria, y luego, en el momento de Fitter, detendría la compilación si eso superaba la cantidad de bloques de memoria disponibles. No podía retroceder la ROM en las puertas en el momento de Fitter. Entonces tuve que hacer algo (una casilla de verificación o algo así) para decirle que forzara la implementación como puertas.

La forma simple y rápida sin ninguna tabla de búsqueda es usar el algoritmo de doble toque . Funciona solo cambiando por 1 y agregando 3 e itera "la cantidad de bits" veces, por lo tanto, es muy eficiente en microcontroladores y arquitecturas sin multiplicación / división y hardware de cambio de barril .

Por ejemplo, para convertir 97 10 = 110 0001 2 a BCD

0000 0000   1100001   Initialization
0000 0001   1000010   Shift (1)
0000 0011   0000100   Shift (2)
0000 0110   0001000   Shift (3)
0000 1001   0001000   Add 3 to ONES, since it was 6
0001 0010   0010000   Shift (4)
0010 0100   0100000   Shift (5)
0100 1000   1000000   Shift (6)
0100 1011   1000000   Add 3 to ONES, since it was 8
1001 0111   0000000   Shift (7)
   9    7

El número se escribe con 7 bits (es decir, el bit más significativo es el bit 6), por lo que terminará después de 7 turnos.

Esta es la mejor solución cuando se restringe para hacer una implementación de VHDL en un FPGA. Ojalá pudiera votar varias veces para dar a tu respuesta una mejor visibilidad...

¿Se supone que debes hacer esto con un FPGA? Escriba un programa en algún lenguaje (C, C++, Python, Perl... no importa, siempre y cuando esté familiarizado con él) que genere el siguiente resultado.

Primero, el preámbulo:

module BinaryToBCD
(
    input [6:0] setting,
    output [3:0] tens,
    output [3:0] ones
)

always @(setting)
begin
    case(setting)

Luego, para cada número del 0 al 99, genera este grupo de líneas:

    7'd__: begin
        tens = 4'd_;
        ones = 4'd_;
    end

Rellene los valores apropiados donde _están. Un ejemplo de Python:

for k in range(100):
    print "    7'd%d: begin" % k
    print "        tens = 4'd%d;" % (k // 10)
    print "        ones = 4'd%d;" % (k % 10)
    print "    end"
    print

Por último, el epílogo:

    default: begin
        tens = 4'hX;
        ones = 4'hX;
    end

    endcase
end

endmodule

Ahora guarde esto como un archivo Verilog .v y aliméntelo a su compilador FPGA y deje que haga el trabajo sucio.

Muchas, muchas cosas en los FPGA se reducen a "escribir el código de cualquier manera que resuelva el problema sin demasiado alboroto y dejar que el compilador haga el trabajo sucio". Los programas generadores de código son tus amigos.

¿El dispositivo tiene que hacer la conversión en un solo paso o puede ser un proceso iterativo?

El método más barato en términos de circuitos es probablemente tener un circuito sincronizado que, cargado con algún número N en formato BCD, y alimentado con una entrada C de un solo bit, se cargará con 2*N+C en el siguiente ciclo de reloj. Alimente dicho circuito con un número binario MSB primero y después de que todos los bits se hayan desplazado, mantendrá ese número en BCD. Este enfoque se puede utilizar con números binarios o BCD de cualquier tamaño, teniendo en cuenta que el acarreo de una etapa no puede afectar inmediatamente el acarreo de la siguiente etapa hasta el próximo ciclo de reloj.

Si se desea, se puede usar el registro BCD para desplazar el número original. Para el caso general, deberá organizar la lógica para que las partes del registro que contienen parte del número en formato binario tengan la lógica BCD deshabilitada para que actúen como palanca de cambios directa. En el caso particular de dos dígitos, uno podría precargar los tres bits inferiores del registro con los tres MSB del número, y los 4 bits superiores con los cuatro bits inferiores del número, y simplemente no molestarse con ninguna lógica BCD para el dígito superior (ya que debería ser 0-9 de todos modos). Cuando se usan más de dos dígitos, se necesita una lógica un poco más sofisticada, pero aún puede valer la pena usar los mismos registros para almacenar el número binario y el resultado BCD.

Por cierto, es posible utilizar el enfoque inverso para convertir un número BCD a binario. Cada dígito debe ser igual a su valor dividido por dos (desplazamiento simple a la derecha), más cinco o cero, según el estado del LSB del siguiente dígito superior.