¿Qué son exactamente las arquitecturas de instrucción de ciclo único?

Obtuve el siguiente texto del trabajo de laboratorio 2 del curso de arquitectura informática de CMU. De hecho, estoy tratando de hacer este laboratorio por mis propios intereses y de ninguna manera soy un estudiante de CMU.

La máquina tiene una microarquitectura de un solo ciclo: cada instrucción tarda exactamente un ciclo en ejecutarse . Aparte de la corrección (tal como se define en las especificaciones arquitectónicas), esta es la única restricción que estamos imponiendo a la microarquitectura de la máquina. Siempre que se satisfagan estas dos restricciones (es decir, corrección y ciclo único ), puede implementar la microarquitectura de la forma que desee. Para guiarlo a lo largo del camino, proporcionamos una descripción abstracta de la microarquitectura de un solo ciclo como discutimos en clase.

  1. El estado arquitectónico de la máquina (excluyendo la memoria) se almacena en registros: el contador de programa y los registros de propósito general
  2. Hay un cable global llamado "reloj" que está conectado a todos los registros.
  3. Cuando un registro ve un flanco ascendente en el reloj, el registro captura la "instantánea" instantánea de los valores en su entrada. A partir de ese momento, el registro retiene los valores capturados y los envía a su salida.
  4. La salida de los registros se alimenta a un circuito combinacional que consta de puertas lógicas (por ejemplo, ADD). A su vez, la salida de las compuertas lógicas se retroalimenta como entrada a los registros.
  5. En el siguiente flanco ascendente del reloj, el registro vuelve a capturar los valores en su entrada

.

Mi duda: Me pide que implemente arquitectura de ciclo único pero los puntos numerados del 1 al 5 no parece que sean de ciclo único.

Asuma la instrucción SUMAR R1, R2, R3. De acuerdo con los pasos del 1 al 5, esto tomará dos ciclos de reloj y no 1 ciclo de reloj.

  • En el borde pos de un ciclo de reloj, los registros de dirección (dirección en el archivo de registro) R1 y R2 se enclavarán y los valores de estos registros se enviarán a ALU para su adición.

  • En el siguiente pos-flanco, la salida de ALU se escribirá de nuevo en regiSter R3.

Entonces, en realidad está tomando dos ciclos, ¿verdad? Entonces, ¿por qué se llama instrucción de ciclo único?

Si lo observa, puede argumentar que 1 instrucción tarda 2 ciclos en aparecer en la salida; sin embargo, si hace varias instrucciones, es efectivamente 1 ciclo por instrucción, es decir, 10 instrucciones tardan 11 ciclos, 100 instrucciones tardan 101 ciclos.
Debe hacer que su ALU calcule el resultado dentro del mismo ciclo de reloj para que también se escriba en R3 en el mismo ciclo de reloj. Solo entonces habrá alcanzado la ejecución de ciclo único. (es decir, si bien las consideraciones de @ BeB00 son interesantes, son irrelevantes)
En realidad, incluso ese no es realmente el caso. Nunca puede mirar directamente el contenido de ningún registro, solo intente leer el contenido a través de una instrucción de lectura. Si activa su instrucción de adición, cronometra la CPU una vez, luego activa su instrucción de lectura y cronometra la CPU una vez, obtendrá el resultado correcto. editar: esta es una respuesta a mi comentario anterior
@ BeB00 sería una instrucción de tres ciclos.
@MarcusMüller Cuando digo activar, me refiero a tener el código de operación relevante en el circuito de control
@ BeB00 no importa. La definición es clara: la instrucción debe haber terminado antes de que entre el siguiente reloj.
@MarcusMüller Parece que en su pregunta, su alu es combinatorio, pero tiene razón en que todo debe suceder dentro de ese ciclo.
@MarcusMüller correcto, entonces cuando digo activar, no me refiero al reloj. Cuando digo reloj, me refiero a ejecutar la operación que está cargada en
@MarcusMüller sí, el resultado debe volver a escribirse en R3 en el mismo ciclo para que sea una instrucción de un solo ciclo. Pero necesito otro borde +ve para fijar el resultado en R3, ¿verdad?
@Jsmith, mi punto es que el resultado que se engancha en R3 es parte de la siguiente instrucción
@BeB00 El punto es que lee R3 primero en los instantes posteriores al siguiente ciclo de reloj, cuando el valor ya está bloqueado. Entonces, el efecto de ADDque R3 tenga un nuevo valor en el próximo ciclo, tiene lugar en el ciclo actual.
@MarcusMüller que es lo que dije antes
@BeB00 si eso es correcto, ¿cuál será el caso con la siguiente instrucción inmediata que intenta escribir algo en el registro R3? ¿Qué escritura tendrá lugar? ¿El de ADD o el siguiente que escribe en R3?
@Jsmith, la escritura Agregar se llevará a cabo, ya que sucede instantáneamente. La próxima escritura ocurrirá en el próximo posedge.
En un nivel físico, imagino que hay cosas que impiden que ocurra una condición de carrera y que la entrada del registro cambie antes de que ocurra el bloqueo, aunque imagino que incluso si no lo hubiera, el retraso en la propagación de la puerta evitaría que suceda.
No es suficiente para su propia respuesta, pero probablemente era más barato tener un solo ciclo... Cada puerta/sistema solo se puede usar una vez por ciclo... MIPS también tiene varios ciclos con hardware diferente, lo que parece más popular

Respuestas (6)

La única forma que conozco de hacer que la lectura y la escritura sucedan en el mismo ciclo de reloj es que las lecturas de registro se activen en el borde positivo y las escrituras de registro se activen en el borde negativo (o viceversa), y luego hacer que sus datos la lógica de ruta se propaga completamente dentro de un período de medio reloj. En una arquitectura de un solo ciclo, en realidad es solo una diferencia semántica, un poco de engaño.

En esquemas de reloj más sofisticados, es posible que tenga múltiples fases de reloj, por lo que la relación de 'activación de borde' no necesita ser simétrica como la describí. Cuando su núcleo está canalizado, esto realmente es importante para fines de corrección, de modo que no tenga una carrera entre las etapas de lectura de registro y escritura diferida.

Creo que está justificado que esté confundido acerca de cómo se relacionan las lecturas y las escrituras en el archivo de registro, pero eso requiere que profundice un poco más en la implementación a nivel de transistor de un registro de un solo bit. Creo que encontrará que hay una carrera si ambos eventos (lectura y escritura) son activados por el mismo borde del reloj y su lógica combinacional puede propagar un cambio antes de que el estado del registro esté completamente bloqueado. Eche un vistazo a esta página web para ver una deconstrucción lógica de un flip flop D activado por borde.

Advertencia: la instrucción de ciclo único puede ser un movimiento de marketing.

Considere la hoja de datos para PIC18F4xK22.

En la mayoría de los lugares notables, verá lo siguiente:

Todas las instrucciones son de un solo ciclo, excepto las ramas del programa.

¿Suena bien? Pero enterrado en algún lugar del documento, verá lo siguiente:

Un “Ciclo de Instrucción” consta de cuatro ciclos Q: Q1 a Q4.

Así, en realidad, su instrucción ejecuta 4 relojes del sistema.

Dije esto en los comentarios, pero está un poco fragmentado.

Básicamente, tiene razón en que se necesitarían dos ciclos de reloj para ejecutar una instrucción ADD y luego bloquearla en un registro.

Sin embargo , cuando ejecuta la siguiente instrucción, esto bloquea el resultado anterior en el registro, por lo que si ejecuta dos ADD seguidos, obtendrá el resultado correcto y solo tomará dos ciclos.

Como una especie de aparte, tener un resultado bloqueado en un registro solo es relevante si desea ejecutar una instrucción en él. Si el último comando en su código fue un ADD, y no cronometró nuevamente después de eso, los registros no contendrían el último resultado, pero no importa porque no los vuelve a leer. Tan pronto como ejecute una instrucción nuevamente para leerlos, se bloquearán y luego se ejecutará su instrucción, dando el resultado correcto.

Una forma de evitar este tipo de cosas sería hacer que los registros se enganchen en el flanco descendente, pero esto limitaría su velocidad a la mitad y no sería muy útil.
Ha dicho que dos ADD consecutivos tomarán 2 ciclos de reloj. no serian 3? Digamos que tenemos AGREGAR R1, R2, R3 y luego AGREGAR R4, R5, R6. En pos-flanco 1 se leerán R1 y R2. En pos-edge 2, se reescribirá R3 y se leerán R4 y R5. En pos-flanco 3, R3 de la segunda instrucción se reescribirá. ¿Estoy correcto? (no importa que el resultado de la primera adición no se use y se sobrescriba con la siguiente instrucción en este ejemplo)
Sí, pero todavía se considera 2 ciclos. Ese tercer ciclo, donde ocurre la reescritura, puede ser cualquier instrucción, incluido NOP. Si escribió un programa que tenía 10 instrucciones de largo, cualesquiera que fueran esas instrucciones, el programa se ejecutaría correcta y completamente si sincronizara el procesador 10 veces.
Bien, entiendo, entonces, ¿qué hay de tratar de leer R3 inmediatamente después de escribir R3? Me refiero a algo como AGREGAR R1, R2, R3 y luego AGREGAR R3, R3, R3. Habrá problemas cuando se lea R3 antes o mientras se escribe R3 de ADD anterior, ¿verdad?
Entonces, cuando queremos leer R3 después de ADD R1, R2, R3, tenemos que incluir un NOP en el medio, de lo contrario, ¿es un error?
No. El primer resultado de ADD se escribe antes de que ocurra el segundo ADD. Podría darse el caso de que, durante unos nanosegundos después de la posición 2, el circuito de adición combinatoria obtenga un resultado incorrecto debido al retraso de la propagación; sin embargo, esto se actualizará al resultado correcto antes del final del segundo reloj.
Esta es en realidad una de las cosas que limita la velocidad del reloj. Si cronometra demasiado rápido, obtendrá este resultado incorrecto y causará problemas.
@Jsmith: Sí, tratar de leer R3 inmediatamente después de escribir R3 es un peligro de lectura tras escritura . Lo más simple es incluir un NOP entre, pero muchos diseñadores de CPU implementan el reenvío de datos para hacer que la instrucción que lee R3 se lea desde la salida de la ALU.

¡Es una arquitectura de ciclo único! Cuando la suma r1,r2,r3 entra en el decodificador combinacional, decodifica el mensaje y le dice a la ALU que haga la suma de r1,r2 y el resultado es una entrada para registrar r3. Ahora el valor de la suma se puede volver a escribir en el siguiente flanco ascendente del reloj o en el flanco descendente (preferido). Como la reescritura no afecta la parte del decodificador de la microarquitectura, se decodificará la siguiente instrucción y así sucesivamente. Espero eso ayude.

no hay ninguna razón por la que no pueda implementar esto en un solo ciclo, al comienzo del ciclo, los registros emiten su valor actual, su decodificador de instrucciones ve y suma, ve los registros de entrada y produce la suma de esos elementos, también ve el destino y, de forma combinada, alimenta el resultado en la entrada a r3 en el flanco ascendente que finaliza este ciclo único, r3 obtiene la suma de r1 y r2. No hay razón para usar un borde descendente ni nada por el estilo.

Ahora, si los registros hubieran estado en un archivo de registro, entonces sí, tiene un problema mucho mayor, no puede leer las dos entradas en un solo reloj sin cambiar la definición de un reloj (usar el borde descendente es hacer trampa que solo cambia la definición de un reloj en dos relojes).

Con los registros separados entre sí con su propia entrada y salida y sin contar la memoria (a veces también puede hacer esto), puede hacer fácilmente una máquina de un solo ciclo. Al comienzo del ciclo, las salidas del registro están listas, en combinación, calcula las entradas del registro antes del final del ciclo.

Si los registros están acoplados en tres estados a busA y busB tan pronto como se decodifican los códigos de operación, y esos buses internos enrutan los operandos a ALU, con la función ALU seleccionada de esa pequeña parte del código de instrucción, y el registro de destino tiene la La salida ALU se presenta a los pines de entrada de ese registro, luego el siguiente ciclo de reloj (todas las acciones de reloj ocurren en todo el MCU en el mismo borde), luego tiene un MCU de un solo ciclo de reloj.

Depende de usted definir los comportamientos tristate para implementar esto.