Diseño de CPU muy simple en LogiSim

8

Actualmente soy estudiante de secundaria en la escuela secundaria, y me ha interesado la ingeniería informática / eléctrica, específicamente el diseño de microprocesadores. Leí el Código de Charles Petzold y comencé a leer el Wikibook de diseño de microprocesador (que parece estar incompleto). Al leer el Código , entiendo la lógica básica detrás de una CPU, y comencé a construir uno en LogiSim. El Capítulo 17 en Código detalla la CPU que quiero construir, pero los circuitos carecen de componentes clave: señales de reloj y decodificación de instrucciones. Algunas de las señales de reloj parecen ser bastante obvias (la PC parece necesitar una señal de reloj constante), pero otras (como cómo bloquear los valores de RAM) he tenido que pensar y tratar de trabajar.

Puedo construir un acumulador que funcione (no se puede llamar con precisión una ALU, creo, porque carece de la parte L) que cambia entre suma y resta con una sola entrada, y entiendo que esto es todo lo que necesito para la parte aritmética - Una vez que funcionen los códigos de operación de salto, puedo implementar la multiplicación y la división en el código. La parte con la que estoy luchando es la decodificación de instrucciones. A través de algunas búsquedas en Google, veo que cada código de operación debe interpretarse como múltiples microinstrucciones, pero no sé cómo necesito que esto funcione. Actualmente, mi decodificador de instrucciones es solo un circuito de análisis combinacional con una única salida binaria para cada código de operación, 13 en total.

La forma en que funciona el código es que tiene un valor de código de 8 bits (solo uso el byte de gama baja), y luego dos valores de dirección de 8 bits separados que luego combino para ser la entrada de dirección de 16 bits a la RAM. Para bloquear los valores, tengo un contador separado que cuenta hasta 10b y luego se restablece a 00b. Es la entrada del reloj para cada pestillo a su vez (para los tres pestillos, hay a, byc. Los segundos relojes tienen un be 1 mientras que b & c son 0, luego b es 1 y 1 & c son 0, luego c es uno y 1 yb son 0, luego se restablece). Pero en instrucciones como ADD 000Ah, la PC salta a 000AH ... que se supone que debe agregarse al acumulador, pero en realidad se engancha en el pestillo del código, y luego se interpreta como el próximo código de operación, lo que hace que todo funcione loco.

Siento que me falta una gran información sobre la decodificación de instrucciones y cómo necesito hacer señales de reloj ...

Aquí están los archivos .circ de LogiSim: https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdder.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitAdderSubtractor.circ https: // dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitInverter.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/8BitLatch.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/ ID.circ https://dl.dropboxusercontent.com/u/61676438/PetzoldMk5/PetzoldMk5.circ

PetzoldMk5 es la CPU principal y depende de los otros archivos que se importarán como bibliotecas.

Aquí hay una lista de códigos de operación (todos binarios):

Load                 0001
Add                  0010
Add w/ Carry         0011
Sub                  0100
Sub w/ Borrow        0101
Jump                 0110
Jump w/ Carry        0111
Jump W/ 0            1000
Jump w/o C           1001
Jump W/o 0           1010
Store                1011
Halt                 1100
Reset                1101
Will Hodges
fuente
1
¿Está dispuesto a compartir su archivo Logisim CPU .circ existente? Y solo para hacer la vida un poco más complicada, debe leer detenidamente y comprender la ayuda de Logisim, bajo el título de "Propagación de valor". Si no lo has hecho ya. (Es posible que, dado todo el trabajo que ya ha aplicado. ¡
Me
@ Jonk gracias por las bonitas palabras. Edición de la publicación con los archivos .circ asociados.
Will Hodges
¿Son esos 6 archivos, en total, entonces? (Supongo que esto es para LogiSim 2.7.1, 2011?)
jonk
@jonk sí, lo es, en ambas preguntas
Will Hodges el
¿Cómo manejas la resta? ¿Utiliza / Q desde un pestillo de entrada a una de las entradas A / B de su ALU y modifica el arrastre? ¿O algún otro método?
jonk

Respuestas:

3

Odio publicar un "solo enlace" como respuesta, pero creo que deberías estar al tanto del trabajo de Warren Toomey con las CPU en Logisim, ya que probablemente sea exactamente lo que estás buscando.

Él tiene un par de tutoriales construyendo hasta una CPU razonablemente simple aquí ...

http://minnie.tuhs.org/CompArch/Tutes/

Y si eso no flota en su bote, él tiene una CPU más sofisticada aquí ...

http://minnie.tuhs.org/Programs/UcodeCPU/

... Todo lo cual está bien explicado y tiene descargas a archivos .circ.


Otra gran CPU / computadora DIY, y posiblemente más funcional, es Magic-1 que se encuentra en http://www.homebrewcpu.com/ . Aunque no se realiza en Logisim, está bastante bien documentado, incluidas imágenes, esquemas y descripciones. También es más que una CPU en un simulador. Tiene un compilador ANSI C, un sistema operativo y algún software. También tiene la clara ventaja de haber sido construido en hardware. De hecho, ¡actualmente está funcionando y sirviendo páginas web!


Finalmente, The Elements of Computing Systems y el sitio asociado nand2tetris.org se presentan como el recurso de información # 1 recomendado para construir su propia computadora desde cero cada vez que la miro. Creo que gran parte del contenido (¿Todo?) Es gratuito. YouTube estaría de acuerdo; Muchas personas han realizado proyectos a partir de esta única fuente.

Charlie
fuente
1
¡Echar un vistazo al video de Youtbue de Ben Eater sobre la construcción de una computadora de tablero de pan de 8 bits también es muy útil!
Francis Cugler
1

Creo que te estás perdiendo un aspecto clave de cómo funcionan las ALU. Por lo general, cada bit del acumulador está conectado a cada uno de los diversos bloques de funciones a través de un demultiplexor. Usando un byte de comando, se selecciona la función y cada bit del acumulador se conecta a la entrada adecuada del bloque de funciones. El tamaño del demultiplexor determina cuántas funciones puede manejar la ALU. En mi ejemplo muy crudo que se muestra a continuación, una ALU con una entrada de 4 bits podría hacer referencia a 16 funciones diferentes utilizando el demultiplexor:

Conexión del acumulador a varios bloques de funciones dentro de una ALU

Tenga en cuenta que en la mayoría de las CPU, este diseño está optimizado en un lío de puertas para reducir el recuento de transistores.

Se pueden usar más funciones al tener un registro de comando más grande, pero esto también requeriría más ciclos de reloj para cargar el comando.

Recomiendo leer el siguiente libro si desea obtener más información sobre el diseño digital: Fundamentals of Logic Design 7th ed.

Takide
fuente
Este tipo de respuesta confunde las instrucciones con las operaciones de ALU. Específicamente, este demultiplexor solo se usaría para seleccionar qué operación aritmética elegir para una instrucción aritmética. Alimentaría el demultiplexor con, digamos, 3 bits de una instrucción de 8 bits, para elegir qué operación aritmética. Necesita un mecanismo completamente separado para decodificar y secuenciar instrucciones en general. Como comentario aparte, la mayoría de las CPU que he visto no usan un demultiplexor como este en la ALU, sino que usan un desorden optimizado de puertas para realizar la operación correcta.
Ken Shirriff
1
@KenShirriff Hice algunos cambios para mayor claridad. Siéntase libre de hacer algunas ediciones como mejor le parezca.
Takide
1

Parece que estás en el camino correcto.

Cuando planifique sus microinstrucciones, deberá definir claramente en su propia mente el patrón de "tráfico" para su movimiento de datos a través de sus diversos bloques. Realizar un ADD requerirá múltiples pasos. Si tiene registros de retención para sus dos operandos de ALU, deberá cargarlos desde la RAM o algún registro o bus. Si tiene un bus interno compartido, es posible que deba cargar un operando a la vez. Una vez que sepa qué bytes (dirección, literal inmediato, datos RAM, puntero) necesitan moverse hacia dónde, planifique el orden del movimiento de los bytes a través de los buses dentro y fuera de los diversos registros. Es posible que se quede atascado y necesite agregar un registro de retención interno porque debe conservarse algún valor intermedio hasta el siguiente paso de microinstrucción.

Creo que lo que sospecha que falta es la complejidad requerida para que la lógica tome la instrucción o el código de operación y lo traduzca a múltiples estados dentro de su CPU. Puede ser complejo, pero es posible crear una máquina de estados algo simple y luego expandirla con conceptos lógicos básicos.

Por ejemplo, supongamos que está creando los pasos de microinstrucciones para una operación MOVE. Esto podría describirse libremente en 3 pasos: 1) Afirmar los contenidos del registro de origen en el bus interno, 2) estropear el reloj de escritura del registro de destino, 3) Desactivar los contenidos del registro de origen del bus interno. Los pasos 1) a 3) describen el tiempo para una habilitación de salida de registro (OE) y una habilitación de escritura de registro (WE) que podría distribuirse selectivamente a cualquier registro de origen y cualquier registro de destino conectado al bus interno compartido con demultiplexores.

Si no tiene mucha práctica creando Máquinas de estado finito, podría ser útil observar los diferentes enfoques para darle otro elemento fundamental para generar las señales de control desde su micro-secuenciador.

Quedarse con eso. La cantidad de conocimiento que adquiera será fenomenal. Y con suerte te divertirás mucho.

Empresario
fuente