Estoy de acuerdo con Newstein en este caso particular, la mejor solución es tratar esto como un problema de lógica general, escribir la tabla de verdad y luego resolverla, y sospecho que eso es lo que su instructor quiso que hiciera.
Usted pregunta en sus comentarios "cualquier otro enfoque". La solución de "tabla de verdad" funciona con valores pequeños, pero a medida que aumenta el número de bits, cada vez es más difícil de resolver.
Para demostrar esto, consideremos una versión extendida de su problema. Dividiendo un número de 6 bits por 5.
El mayor número posible de 6 bits es 63. 63/5 = 12 resto 3, por lo que necesitamos 4 bits de salida (numerados de 0 a 3, siendo 0 el LSB y 3 el MSB). Pensemos en cómo podríamos hacer esto en un programa de computadora.
Para expresar este programa, usaré un psuedocode con una sintaxis tipo C con ^ usado para potencia y con [] usado para acceder a bits individuales de un número.
remainder=input
bit=3
while (bit > 0) {
if (remainder >= (2^bit)*5) {
output[bit] = 1;
remainder -= (2^bit)*5;
} else {
output[bit] = 0
}
bit--;
}
Entonces, ¿podemos convertir esto en lógica digital combinatoria? En primer lugar tenemos que deshacernos del bucle. Como el bucle tiene un número fijo de iteraciones, podemos desenrollarlo.
remainder=input
if (remainder >= (2^3)*5) {
output[3] = 1;
remainder -= (2^3)*5;
} else {
output[3] = 0
}
if (remainder >= (2^2)*5) {
output[2] = 1;
remainder -= (2^2)*5;
} else {
output[2] = 0
}
if (remainder >= (2^1)*5) {
output[1] = 1;
remainder -= (2^1)*5;
} else {
output[1] = 0
}
if (remainder >= 2^0*5) {
output[0] = 1;
remainder -= (2^0)*5;
} else {
output[0] = 0
}
Ok, nos deshicimos del bucle, pero aún tenemos esas frases tan desagradables. Vamos a reemplazarlos con operadores ternarios.
remainder=input
output[3] = (remainder >= (2^3)*5);
tmp = remainder - (2^3)*5;
remainder = output[3] ? tmp : remainder;
output[2] = (remainder >= (2^2)*5);
tmp = remainder - (2^2)*5;
remainder = output[2] ? tmp : remainder;
output[1] = (remainder >= (2^1)*5);
tmp = remainder - (2^1)*5;
remainder = output[1] ? tmp : remainder;
output[0] = (remainder >= (2^0)*5);
tmp = remainder - (2^0)*5;
remainder = output[0] ? tmp : remainder;
Ok, esa comparación todavía parece desagradable, ¿podemos deshacernos de ella? Sí podemos, podemos explotar las propiedades de Wraparound en desbordamiento para nuestra ventaja.
remainder=input
tmp = remainder - (2^3)*5;
output[3] = ! tmp[3]
remainder = output[3] ? tmp : remainder;
tmp = remainder - (2^2)*5;
output[2] = ! tmp[2]
remainder = output[2] ? tmp : remainder;
tmp = remainder - (2^1)*5;
output[1] = ! tmp[1]
remainder = output[1] ? tmp : remainder;
tmp = remainder - (2^0)*5;
output[0] = ! tmp[0]
remainder = output[0] ? tmp : remainder;
Ya que ahora no tenemos bucles, si las declaraciones u otras complicaciones similares podemos modificar nuestro programa para que cada variable se asigne exactamente una vez.
tmp3 = input - (2^3)*5;
output[3] = ! tmp3[3]
remainder3 = output[3] ? tmp3 : input;
tmp2 = remainder3 - (2^2)*5;
output[2] = ! tmp2[2]
remainder2 = output[2] ? tmp2 : remainder3;
tmp1 = remainder2 - (2^1)*5;
output[1] = ! tmp1[1]
remainder1 = output[1] ? tmp1 : remainder2;
tmp0 = remainder1 - (2^0)*5;
output[0] = ! tmp0[0]
remainder = output[0] ? tmp0 : remainder1;
Ahora podemos reemplazar las variables en nuestro programa con señales y las declaraciones con restadores, no puertas y multiplexores. Los restadores y multiplexores pueden construirse a partir de puertas lógicas básicas.