• No se han encontrado resultados

PROCESADOR DIDACTICO ANDREA CRISTINA CAMACHO

N/A
N/A
Protected

Academic year: 2021

Share "PROCESADOR DIDACTICO ANDREA CRISTINA CAMACHO"

Copied!
64
0
0

Texto completo

(1)

PROCESADOR DIDACTICO

ANDREA CRISTINA CAMACHO

UNIVERSIDAD DE LOS ANDES

FACULTAD DE INGENIERIA

DEPARTAMENTO DE ELECTRONICA

BOGOTA CUNDINAMARCA

2005

(2)

PROCESADOR DIDACTICO

ANDREA CRISTINA CAMACHO

Trabajo de grado para optar al título de

Ingeniero Electrónico

Director

FREDY SEGURA

Ingeniero Electrónico

UNIVERSIDAD DE LOS ANDES

FACULTAD DE INGENIERIA

DEPARTAMENTO DE ELECTRONICA

BOGOTA CUNDINAMARCA

2005

(3)

CONTENIDO

Pág.

INTRODUCCION

4

1.

MARCO TEORICO

5

1.1

DEFINICION DEL PROBLEMA

5

1.2

MODELO

DEL

PROCESADOR

6

1.2.1

Set

de

instrucciones

7

1.2.2 Construcción del camino de datos

9

1.2.3 Construcción de la Unidad de Control

12

1.2.4 Construcción de la Unidad de Control de la ALU

13

1.3

SEGMENTACION DE LA ARQUITECTURA

14

2.

DESCRIPCION DE LA ARQUITECTURA EN VHDL

15

2.1

Descripción

de

librerías

y

paquetes

17

2.2

Descripción de las fases de segmentación

24

2.3

Descripción de los registros de segmentación

41

2.4

Modulo

ASIGNACIÓN

_

SALIDAS 44

2.5

Modulo

MIPS

47

3.

DESCRIPCION

DE

LAS

TARJETAS

51

3.1

Tarjeta

de

Programación

51

3.2

Tarjeta

de

Visualización

59

4.

RESULTADOS

62

CONCLUSIONES

63

(4)

INTRODUCCION

Este documento presenta la descripción de diseño descendente seguida para crear el Procesador

Didáctico; un sistema digital hardware/software para diversas aplicaciones pero que

esencialmente se ha construido con el propósito de que se convierta en una herramienta didáctica

que facilite el aprendizaje de arquitecturas de procesador. Con este fin el Procesador Didáctico

esencialmente emula el flujo de datos en tiempo real de un pequeño procesador de 8 bits y un set

reducido de instrucciones basado en la arquitectura MIPS[1].

El sistema esta compuesto básicamente por un diseño arquitectural modelado en VHDL y dos

tarjetas electrónicas que proporcionan el hardware necesario para su implementación y el

seguimiento del flujo de datos en tiempo real de programas construidos en base al set reducido de

instrucciones.

La Tarjeta de Programación basada en un dispositivo de lógica programable (FPGA) aporta el

hardware mínimo para programar la FPGA a través del puerto paralelo del computador por medio

de JTAG, circuiteria de reloj y pruebas, comunicación serial RS-232 y puertos de expansión para

conectar la FPGA con otros sistemas, mientras que la de Visualización cuenta con componentes

como leds y displays que despliegan las señales mas elementales que permiten comprender el

proceso de ejecución de los programas a nivel de microinstrucciones.

En este documento se comentaran las etapas de desarrollo del proyecto, partiendo del estudio de

la arquitectura básica y las modificaciones hechas tanto para optimizar el funcionamiento como el

rendimiento.

Seguidamente se describirá el diseño de las tarjetas impresas, partiendo así el total del proyecto

en dos fases de diseño; una fase de diseño arquitectural y otra fase de diseño de hardware.

Por ultimo se plantea una practica a realizar con el Procesador Didáctico, se evalúa el

funcionamiento del sistema y se dan sugerencias para futuros proyectos.

El documento se divide en cinco capítulos: el capítulo uno contextualiza al lector sobre el

planteamiento del problema, resalta la importancia de la arquitectura MIPS y plantea el modelo

arquitectural del procesador.

El segundo capítulo describe el diseño en VHDL de los diferentes módulos que conforman la

arquitectura y las modificaciones hechas al modelo arquitectural del capitulo uno para optimizar

el funcionamiento y aumentar el rendimiento.

El capitulo tres describe el diseño de las tarjetas de Programación y Visualización.

Finalmente se encuentran los resultados y conclusiones.

(5)

1. MARCO

TEORICO

1.1 DEFINICION DEL PROBLEMA

La comprensión y diseño de diferentes arquitecturas basadas en procesador siempre ha sido

objeto de estudio para su aplicación en distintas ramas, sin embargo en la Universidad de los

Andes no se cuenta con herramientas que faciliten la aplicación de los conocimientos adquiridos

en esta área y que puedan hacer practico y didáctico el aprendizaje.

El Procesador Didáctico se propone como una herramienta de apoyo para el aprendizaje de

materias como arquitectura del computador y sistemas digitales; sin embargo por ser un sistema

versátil podrá ser utilizado para muchas otras aplicaciones electrónicas.

El sistema completo esta conformado por el Core de un procesador de 8 bits y 8 instrucciones

básicas, modelado en VHDL, y dos tarjetas electrónicas.

Figura 1: Descripción del sistema.

Para desarrollar el Core del procesador se selecciono como arquitectura base para el estudio la

arquitectura MIPS (Microprocessor without interlocked pipeline stages), desarrollada por John L.

Hennessy en 1984. Es un con arquitectura RISC desarrollado por MIPS Computer Systems Inc.

Los disenos MIPS son usados en la linea de productos de computador SGI, y han encontrado un

amplio uso en sistemas embebidos, sietemas CE de Windows, y enrutadores Cisco. Las consolas

del Nintendo 64, Sony PlayStation uno y dos y la versión portable usan procesadores MIPS.

A finales de los 90’s se estimaba que uno de cada tres chips RISC era producido en base a un

diseno MIPS.

El procesador MIPS es un modelo clásico de estudio y ofrece un repertorio de instrucciones fácil

de comprender e implementar. El diseño modelado trata de guardar la mayor consistencia posible

con la descripción hecha por Hennessy y Patterson de esta arquitectura [2].

[2] La interfaz hardware/software. DAVID A. PATTERSON-JOHN L. HENNESY. Mc. Graw

Hill. Segunda edición en español - 1995.

(6)

La Tarjeta de Programación basada en un dispositivo de lógica programable (FPGA) aporta el

hardware mínimo para programar la FPGA, a través del puerto paralelo del computador por medio

de JTAG, circuiteria de reloj y pruebas, comunicación serial RS-232 y puertos de expansión para

conectar la FPGA con otros sistemas.

La Tarjeta de Visualización conformada principalmente por un arreglo de dispositivos de

entrada/salida como leds, displays siete segmentos y switches, ha sido creada como una tarjeta de

expansión de la tarjeta de Programación para desplegar las señales de esta.

Las tarjetas electrónicas también pueden usarse para muchas aplicaciones electrónicas, sin

embargo su propósito principal, especialmente para la de Visualización es servir como

herramienta para la docencia. En esta aplicación en particular, la tarjeta de Programación es

configurada por medio de JTAG desde el computador a través del cable paralelo, con la

arquitectura diseñada. La tarjeta de Visualización despliega las señales de salida de la de

Programación permitiendo comprender el proceso de ejecución de los programas en tiempo real a

nivel de microinstrucciones.

El Procesador Didáctico pretende ser una ayuda didáctica para la mejor comprensión del

funcionamiento interno de un procesador. Su modelaje en VHDL ofrece mayor facilidad a

posibles modificaciones, ya que permite hacer cambios modulares, lo que posibilita la

reutilización del código permitiendo desarrollar nuevos modelos arquitecturales y verificar su

funcionamiento.

Este permitiría a profesores y asistentes de laboratorio diseñar prácticas donde se apliquen los

conocimientos teóricos adquiridos en clase.

Los estudiantes podrán aprender tanto en base a la práctica como rediseñando, simulando,

sintetizando y descargando sus diseños en base a la arquitectura MIPS planteada, para comprobar

físicamente su correcto funcionamiento y crear diferentes diseños arquitecturales.

1.2 MODELO DEL PROCESADOR

Para el desarrollo del proyecto como primera medida se hizo un estudio teórico de la arquitectura

MIPS, con el que se obtuvieron nociones elementales acerca de su funcionamiento y

construcción, permitiendo definir el set reducido de instrucciones que se incluirán en el

Procesador Didáctico y construir el camino de datos y las unidades de control en base a los

componentes arquitecturales necesarios para cada instrucción.

El procesador consta de dos componentes principales que deben diseñarse de acuerdo a las

instrucciones que se implementaran en el. El Camino de Datos realiza las operaciones aritméticas

y lógicas; mientras el Control le indica a este y a la Memoria lo que deben hacer de acuerdo a las

instrucciones.

(7)

1.2.1 Set de instrucciones.

Para poder dar órdenes al procesador hay que hablar en su lenguaje. El lenguaje que la maquina

entiende se denomina Repertorio o Set de Instrucciones y esta conformado por las instrucciones

que se implementaran en el procesador.

El repertorio de instrucciones MIPS incluye aproximadamente 140 instrucciones en total entre

instrucciones aritméticas, lógicas, de manipulación de constantes, de comparación, de salto y

bifurcación, de carga, almacenamiento, de desplazamiento de datos, instrucciones de punto

flotante, de excepciones e interrupciones. Sin embargo en este proyecto solo se implementaran

las ocho instrucciones más básicas para hacer un procesador de baja complejidad y de fácil

entendimiento.

Existen diferentes tipos de instrucciones que puede realizar un procesador, dependiendo de los

elementos que se usen dentro del camino de datos y de la información que se requiera procesar.

Las instrucciones a nivel de lenguaje maquina están codificadas en 32 bits que se agrupan en

diferentes campos formando diferentes formatos. Las instrucciones Aritmético-Lógicas, agrupan

estos 32 bits en 6 campos dando origen a la primera clase de formato de instrucciones: el Tipo R.

Figura 2: Formato de instrucciones Tipo R.

Definición de los campos:

• OP: operación de la instrucción. Igual a cero para todas las operaciones Tipo R.

• RS: primer registro del operando fuente.

• RT: segundo registro del operando fuente.

• RD: registro destino; obtiene el resultado de la operación.

• Shamt: cantidad de desplazamiento para corrimientos.

• Function: selecciona la variante de la operación del campo OP.

Entre las instrucciones de este formato, se seleccionaron para ser implementadas en el

Procesador Didáctico las siguientes:

• Suma con desbordamiento: add.

Sintaxis: add rd,rs,rt

Función: rd ← rs+rt

Si hay desbordamiento no se produce la operación.

• Resta con desbordamiento: sub

Sintaxis: sub rd,rs,rt Función: rd ← rs-rt

Si hay desbordamiento no se produce la operación.

(8)

• Producto lógico: and

Sintaxis: and rd,rs,rt Función: rd ← rs AND rt

• Suma lógica: or

Sintaxis: or rd,rs,rt Función: rd ← rs OR rt

• Comparación si menor que con signo: slt

Sintaxis: slt rd,rs,rt Función: Si rs < rt rd ← 1

La comparación supone que tanto rs como rt contienen sendos datos con signo en

complemento a 2.

Los operandos de las instrucciones aritméticas provienen de una serie limitada de posiciones

especiales de almacenamiento de datos de 8 bits denominadas registros. Como solo se realizan

operaciones entre registros, el procesador debe incluir instrucciones que transfieran datos entre la

memoria y los registros.

Instrucciones de transferencia de datos:

• Carga de una palabra de memoria en un registro: lw

Función:

rt

← Mem ( direccion + rs )

Carga en el registro rt el contenido de la posición de memoria direccion + rs.

• Almacenamiento en memoria del contenido de un registro: sw

Función: Mem (direccion + rs ) ← rt

Almacena el contenido del registro rt en la posición de memoria cuya dirección viene dada

por direccion + rs

Las instrucciones de transferencia de datos necesitan un nuevo formato, ya que deben especificar

dos registros y una dirección. Un registro para cargar o almacenar el dato en los registros o en la

memoria respectivamente y otro para calcular la dirección de acceso a memoria sumándolo al

campo dirección de la instrucción.

Si la dirección utilizara uno de los campos de 5 bits del formato, estaría limitada a 32 posiciones

de memoria.

Formato instrucciones tipo I:

Figura 3: Formato de instrucciones Tipo I.

Los formatos se distinguen por los valores del primer campo (OP), que generalmente se conoce

como Código de operación (opcode). Este indica al procesador si tratar la ultima mitad de la

instrucción como 3 campos (tipo R) o como un solo campo (tipo I).

(9)

Para que el procesador pueda tomar decisiones y ejecutar diferentes instrucciones basándose en

los datos de entrada y en los valores obtenidos de algún cálculo, se deben incluir instrucciones

para toma de decisiones e instrucciones de salto condicional.

Instrucción para control de flujo:

• Ramificación condicional si igual: beq

Sintaxis: beq rs, rt, dirección

Función: Si rs = rt PC ← PC + dirección

Para lograr comparar los diferentes campos que caracterizan las instrucciones incluidas se

presenta a continuación un resumen de las ocho instrucciones:

Instrucción Tipo OP [31-26] RS [25-21] RT [20-16] RD [15-11] SHAMT [10-6] FUNCT [5-0] DIR [15-0] ADD R 0 REG REG REG 0 0x 21 o 33 N.A

SUB R 0 REG REG REG 0 0x 22 o 34 N.A AND R 0 REG REG REG N.A 0x 24 o 36 N.A OR R 0 REG REG REG N.A 0x 25 o 37 N.A SLT R 0 REG REG REG N.A 0x2A o 42 N.A

LW I 0x23 REG REG N.A N.A N.A DIR

SW I 0x2B REG REG N.A N.A N.A DIR

BEQ I 4 REG REG N.A N.A N.A DIR

Tabla 1: Instrucciones del Procesador Didáctico.

1.2.2 Construcción del camino de datos.

El Camino de datos es un conjunto de elementos de almacenamiento y cálculo junto con los

buses de datos que los interconectan y las señales de control que regulan su funcionamiento.

Para ejecutar cualquier instrucción se necesita una Memoria para que contenga y suministre las

instrucciones de un programa. La dirección de acceso a la memoria de instrucciones será

especificada por el contador de programa,

este es un registro que contiene la dirección de la

instrucción actual que se esta ejecutando y debe incrementarse para que apunte a la siguiente

instrucción en cada ciclo de reloj.

Para implementar las instrucciones descritas previamente en el Set de instrucciones, se necesita

prácticamente lo mismo. Para cada instrucción, los dos primeros pasos son idénticos:

• Enviar el contador de programa (PC) a una memoria que contenga el código para buscar la

instrucción.

• Leer uno o dos registros utilizando los campos de la instrucción para seleccionar los registros a

leer.

(10)

Después de estos dos pasos las acciones requeridas para completar la instrucción, dependen del

tipo de instrucción. Sin embargo todos los tipos de instrucciones utilizan la ALU después de leer

los registros. Las de referencia a memoria para calcular una dirección efectiva, las

aritmético-lógicas para la ejecución del código de operación y las de salto para realizar comparaciones.

Después de utilizar la ALU, las acciones requeridas para completar los diferentes tipos de

instrucciones difieren. Una instrucción de referencia a memoria necesitara acceder a la memoria

que contenga el dato para completar un almacenamiento o una carga. Una aritmético-lógica

deberá escribir el resultado de la ALU en un registro. Finalmente para una instrucción de salto,

puede ser necesario cambiar la dirección de la siguiente instrucción según el resultado de la

comparación.

Para comenzar a diseñar el camino de datos partimos examinando los principales componentes

necesarios para ejecutar cada tipo de instrucción.

Las instrucciones aritmético-lógicas (tipo R) se realizan entre registros y deben acceder al archivo

de registros para leer los dos operandos a procesar (RT y RD) y para guardar el resultado de la

operación realizada en la ALU en otro registro (RS). En la figura 4 se muestra el camino de datos

para este tipo de instrucción.

Figura 4: Camino de datos para las instrucciones Tipo R.

Si consideramos las instrucciones de carga y almacenamiento. Estas instrucciones calculan una

dirección de acceso a memoria sumando el registro base (RT) al campo de dirección de 16 bits de

la instrucción.

(11)

En un almacenamiento el valor que se va a almacenar debe ser leído del archivo de registros (RS)

y almacenado en la dirección de memoria calculada. Si es una carga, el valor debe ser leído de

memoria y copiado en el registro (RS).

A continuación se puede observar el nuevo camino de datos para adicionar las instrucciones de

carga y almacenamiento.

Figura 5: Camino de datos incluyendo Lw y Sw

Como se comparten los elementos del camino de datos para los diferentes tipos de instrucciones,

se necesitan múltiples conexiones a la entrada de un mismo elemento y una señal de control para

seleccionar las entradas. Un multiplexor debe agregarse en cada elemento compartido del camino

de datos.

Se puede ver que se adiciona un multiplexor para decidir en que registro escribir. El registro

destino para una instrucción de carga se encuentra codificado en la cadena de bits del 20-16 (RT),

mientras que para una tipo R esta del 15-11 (RD). Se debe incluir otro multiplexor en la segunda

entrada de la ALU, ya que esta es o un registro (si se trata de una instrucción tipo R) o el campo

dirección de la instrucción en caso de una instrucción de memoria (Lw o Sw). Uno mas debe

agregarse ya que el valor escrito en el registro proviene de la ALU para una instrucción tipo R o

de memoria para una instrucción de carga.

La instrucción beq (Tipo I) tiene dos registros que se comparan para saber si son iguales y un

desplazamiento de 16 bits. Esta instrucción utiliza la ALU para la comparacion de los operandos

de los registros y adicionalmente necesita calcular la direccion de salto, por lo que es necesario

un sumador para hacer las dos operaciones simultaneamente.

Cuando los dos registros son iguales (RS=RT) la señal de salida Zero de la ALU se pone a ‘1’. Si

esta condicion se cumple y la operación que se esta llevando a cabo es Beq, el PC cambia su

valor a la dirección de destino de salto (PC+1+Direccion) y se dice que se realiza el salto. De lo

(12)

contrario, el PC incrementado (PC+1) debe sustituir al PC actual. Esta decision se toma en el

multiplexor adicionado el cual es controlado por la senal PCSrc proveniente de la unidad de

Control, que describiremos mas adelante.

Figura 6: Camino de datos incluyendo la instrucción Beq.

1.2.3 Construcción de la unidad de control.

La unidad de control genera las señales de que gobiernan el funcionamiento del procesador

dependiendo del código de operación (OP) de la que instrucción que se este leyendo de la

memoria de instrucciones. Esta debe tomar este campo (Instrucción[31-26]) y generar una señal

de escritura para cada elemento de estado, el control para cada multiplexor y el bloque que

controla la ALU.

Descripción de las señales de control:

• PCSrc: Selecciona el nuevo valor del PC entre su valor inmediato y la dirección de salto

• ALUSr: Selecciona el segundo operando de la ALU, entre el segundo registro leído del

archivo de registros y los 16 bits del campo dirección de la instrucción.

• AluOp: Indica la operación a realizar en la ALU.

• RegDst: Selecciona la dirección de registro a escribir RT o RD.

• Branch: Indica que la operación que se esta realizando en Beq.

• RegWrite: Habilita la escritura del bloque de registros.

• MemRead: Habilita la lectura de la memoria.

• MemWrite: Habilita la escritura de la memoria.

• MemtoReg: Selecciona el dato a escribir en el bloque de registros. El resultado de la ALU o el

dato leído de la memoria.

(13)

La inicialización de las líneas de control salvo PCSrc dependen solamente del campo de código

de operación de 6 bits OP. La unidad de control no puede inicializar la señal PCSrc basándose en

el campo de código de operación ya que esta debería inicializarse si la operación es saltar sobre

igual (Branch=1) y si los dos registros son iguales (Zero=1). Por esto se hace una AND entre

estas dos señales provenientes de la Unidad de Control y la ALU respectivamente.

La siguiente tabla define el valor que debe tener cada señal de control para cada instrucción

según el código de operación:

Tabla 2: Señales de control dependiendo del campo OP.

1.2.4 Construcción de la Unidad de Control de la ALU

La unidad de control de la ALU administra las funciones de esta en base al campo function

(Instrucción[5-0]) y la señal de control de 2 bits ALUOP provenientes de la unidad de control

principal, generando una señal de control de 3 bits que selecciona la operación a realizar en la

ALU.

En la Tabla 3 puede verse la correspondencia entre el campo function de la instrucción, la señal

de control ALUOp, la señal de control de la ALU y la operación que esta realiza.

(14)

1.2 Segmentación de la arquitectura.

La ejecución de las instrucciones la podemos separa en varias etapas:

• IF: Búsqueda de la instrucción.

• ID: Decodificación de la instrucción y búsqueda de registros.

• EX: Ejecución de la operación (instrucciones ALU) y calculo de la dirección efectiva

(para accesos a memoria).

• MEM: Logica para decision de saltos y acceso a memoria.

• WB: Escritura de los resultados en el archivo de registros

Se puede segmentar el camino de datos dividiendo la arquitectura en estas 5 etapas por medio de

registros que pasan los valores de una etapa a otra en cada ciclo de reloj, de tal forma que se

realicen 5 instrucciones en cada ciclo de reloj en vez de una, aumentando el rendimiento de la

maquina para la ejecución de un programa. La segmentacion de la arquitectura puede observarse

en la figura 7.

Figura 7: Arquitectura Segmentada.

Los registros de segmentacion pasan tanto los datos procesados de una etapa a la otra, asi como

las senales de control, distribuyendo los datos sincronicamente en cada flanco de subida de reloj.

(15)

2. DESCRIPCION DE LA ARQUITECTURA EN VHDL

Se modelo un procesador MIPS de 8 bits con set reducido de 8 instrucciones y se utilizo la

herramienta ISE de Xilinx para la síntesis y simulación del código en VHDL.

VHDL fue el lenguaje de descripción de hardware que se empleo para la descripción de la

arquitectura, esencialmente por las ventajas que ofrece. Es un lenguaje estándar que se puede

utilizar en diferentes herramientas, permite modelar en todos los niveles de diseño, acepta el uso

de librerías con componentes comúnmente utilizados y es independiente de la tecnología.

Además da la facilidad de hacer un diseño en base a componentes que pueden verificarse y

cambiarse independientemente del resto, permitiendo una simulación rápida y constante que

repercute directamente en la obtención de un menor tiempo de diseño. Todo esto hace que sea

más fácil para el estudiante reutilizar la arquitectura planteada para crear nuevas opciones

arquitecturales.

El desarrollo de la arquitectura diseñada se llevo a cabo siguiendo un proceso de diseño

descendente, dividiendo la arquitectura reiteradamente en unidades funcionales más pequeñas

que facilitaron la verificación para luego unificarlas formando el diseño completo de la

arquitectura MIPS reducida.

Los módulos definidos tratan de guardar la mayor proporción posible con el camino de datos

descrito previamente. Sin embargo el modelo diseñado cambia un poco debido a que fue

necesario incluir un modulo de Anticipación de datos y dos multiplexores para poder realizar

operaciones contiguas que utilicen los mismos registros de datos. Con estos bloques se reducen

los errores por dependencia de datos, los cuales podrían presentarse cuando una instrucción lee

un dato para operarlo mientras otra esta escribiéndolo.

En la figura 9 puede verse la nueva arquitectura segmentada con las unidades de corrección

adicionadas.

Para corregir los errores por dependencia de datos, la unidad de Anticipación recibe como

entradas los campos RS y RT del registro de segmentación ID/EX que especifican que registros

van a leerse, las señal de control RegWrite y el registro destino de los registros de segmentación

EX/MEM y MEM/WB que definen que registro va a escribirse. Con estas entradas la unidad de

anticipación revisa si puede presentarse un error por dependencia de datos al coincidir los

registros de lectura y escritura al estar habilitada la señal RegWrite y anticipa las señales

requeridas, haciendo posible poder tomar las entradas de la ALU desde cualquier registro de

segmentación y no necesariamente del ID/EX, utilizando resultados temporalmente en lugar de

esperar a que se escriban los registros.

Los multiplexores de la ALU seleccionan o los valores normales de los registros o uno de los

valores anticipados.

(16)

Las condiciones para anticipar un dato y localizar la ubicación del resultado son:

• Riesgo EX:

Si (EX/MEM.RegWrite = 1)

Si (EX/MEM.EscribirRegistro = ID/EX.LeerRegistro1) => AluSelA = 01.

Si (EX/MEM.EscribirRegistro = ID/EX.LeerRegistro2) => AluSelB = 01.

• Riesgo MEM:

Si (MEM/WB.RegWrite = 1)

Si (MEM/WB.EscribirRegistro = ID/EX.LeerRegistro1)=> AluSelA = 10.

Si (MEM/WB.EscribirRegistro = ID/EX.LeerRegistro2)=> AluSelB = 10

Figura 9: Arquitectura segmentada con control de riesgos.

En la siguiente tabla puede observarse la relación entre las señales de control de los multiplexores

de anticipación y los operandos de la ALU. Debe recordarse que el operador uno de la ALU

viene especificado directamente por el Multiplexor A, mientras que el B genera el resultado que

será utilizado por otro multiplexor que seleccionara el segundo operador de entrada a la ALU

entre este dato y el campo dirección de la instrucción.

Control Mux Fuente Procedencia de los operándos AluSelA=00 ID/EX Operador1 proviene de los registros normales AluSelA=01 EX/MEM Se anticipa del resultado anterior de la ALU

AluSelA=10 MEM/WB Se anticipa de la memoria de datos o un resultado anterior de la ALU AluSelB=00 ID/EX Operador2 proviene de los registros normales

AluSelB=01 EX/MEM Se anticipa del resultado anterior de la ALU

AluSelB=10 MEM/WB Se anticipa de la memoria de datos o un resultado anterior de la ALU

(17)

DESCRIPCION DE LOS MODULOS

El procesador descrito en VHDL esta conformado básicamente por nueve módulos que

interconectados por medio de señales integran la arquitectura; y un modulo de acople a la tarjeta

de Visualización que transforma las señales binarias de la arquitectura en datos apropiados para

ser desplegados en dicha tarjeta.

Los nueve módulos que conforman la arquitectura son las 5 etapas de segmentación y los cuatro

registros de segmentación que las unen.

A continuación se describirán los submodulos que conforman las etapas de segmentación, los

registros de segmentación, el modulo de acople para visualizar las señales y los paquetes de

funciones, tipos de variables y constantes creadas para realizar la arquitectura.

Todos los módulos deben incluir las siguientes librerías:

• library IEEE;

o

use IEEE.STD_LOGIC_1164.ALL;

o

use IEEE.STD_LOGIC_ARITH.ALL;

o

use IEEE.STD_LOGIC_UNSIGNED.ALL;

• library UNISIM;

o

use UNISIM.VComponents.all;

• USE WORK.CONSTANTES.ALL;

• USE WORK.TIPOS_variables.ALL;

• USE WORK.FUNCIONES.ALL;

Las ultimas tres librerías han sido creadas para definir las constantes, variables globales y las

funciones que se implementaran para realizar el procesador en VHDL.

2.1 DESCRIPCION DE LIBRERIAS Y PAQUETES

2.1.1 Paquete de constantes: define los parámetros de los componentes de almacenamiento:

memoria de instrucciones, banco de registros y memoria de datos.

PACKAGE Constantes IS

CONSTANT DATA_Dirs: NATURAL := 3; --DIRECIONES EN MEMORIA DE DATOS

CONSTANT INST_Dirs: NATURAL := 8; --DIRECCIONES EN MEMORIA DE INSTRUCIONES CONSTANT NUM_Regs: NATURAL := 8; --Numero de registros en el banco de registros.

END Constantes;

2.1.2 Paquete de tipos de variables: define los tipos de variables que se van a usar en el diseño.

library IEEE;

use IEEE.STD_LOGIC_1164.all; USE WORK.Constantes.ALL; PACKAGE tipos_variables IS

(18)

-- PALABRAS DEL PROCESADOR --Tipo para las instrucciones:

SUBTYPE WORD_INST IS STD_LOGIC_VECTOR (31 DOWNTO 0);

--Tipo para los datos: El rango que se pueden representar son -127 al +127, ya que el BIT 7 es el de signo. SUBTYPE WORD IS STD_LOGIC_VECTOR ( 7 DOWNTO 0); --RANGO NUMEROS(-127, +127)

SUBTYPE WORD_1 IS STD_LOGIC_VECTOR(0 DOWNTO 0); SUBTYPE WORD_2 IS STD_LOGIC_VECTOR( 1 DOWNTO 0); SUBTYPE WORD_3 IS STD_LOGIC_VECTOR( 2 DOWNTO 0); SUBTYPE WORD_4 IS STD_LOGIC_VECTOR( 3 DOWNTO 0); SUBTYPE WORD_5 IS STD_LOGIC_VECTOR( 4 DOWNTO 0); SUBTYPE WORD_6 IS STD_LOGIC_VECTOR( 5 DOWNTO 0); SUBTYPE WORD_7 IS STD_LOGIC_VECTOR( 6 DOWNTO 0); SUBTYPE WORD_12 IS STD_LOGIC_VECTOR( 11 DOWNTO 0); SUBTYPE WORD_14 IS STD_LOGIC_VECTOR( 13 DOWNTO 0); SUBTYPE WORD_16 IS STD_LOGIC_VECTOR( 15 DOWNTO 0); SUBTYPE WORD_21 IS STD_LOGIC_VECTOR( 20 DOWNTO 0); SUBTYPE WORD_24 IS STD_LOGIC_VECTOR( 23 DOWNTO 0); SUBTYPE WORD_28 IS STD_LOGIC_VECTOR( 27 DOWNTO 0); SUBTYPE WORD_32 IS STD_LOGIC_VECTOR( 31 DOWNTO 0); SUBTYPE WORD_40 IS STD_LOGIC_VECTOR( 39 DOWNTO 0);

-- Memorias y banco de registros.

TYPE MEM_INST_WORD IS ARRAY (0 TO INST_Dirs-1) OF WORD_INST; TYPE MEM_DATOS_WORD IS ARRAY (0 TO DATA_Dirs-1) OF WORD; TYPE REGISTROS IS ARRAY (0 TO NUM_Regs-1) OF WORD; --BUSES DE CONTROL DE LAS ETAPAS DE SEGMENTACION SUBTYPE CTRL_EX IS WORD_4;

SUBTYPE CTRL_M IS WORD_3; SUBTYPE CTRL_WB IS WORD_2; END tipos_variables;

2.1.3 Paquete de funciones: contiene las funciones para conversión de datos.

PACKAGE FUNCIONES IS

FUNCTION Bin_IntC2(W: WORD) RETURN INTEGER; FUNCTION Bin_Int (W: WORD) RETURN INTEGER; FUNCTION C2 (A: WORD) RETURN WORD;

FUNCTION Int_BinC2(N: INTEGER) RETURN WORD; FUNCTION Int_Bin (N: INTEGER) RETURN WORD;

FUNCTION WORD_5_INT (CADENA: WORD_5) RETURN INTEGER; FUNCTION VISUALIZAR_1_DISPLAY (A: WORD) RETURN WORD_7; FUNCTION VISUALIZAR_2_DISPLAYS (A: WORD_6) RETURN WORD_14; FUNCTION VISUALIZAR_3_DISPLAYS (A: WORD) RETURN WORD_21; FUNCTION VISUALIZAR_INST (A: WORD_12) RETURN WORD_14;

(19)

PACKAGE BODY FUNCIONES IS

---FUNCION BINARIO A ENTERO EN COMPLEMENTO A 2--- FUNCTION Bin_IntC2 (W: WORD) RETURN INTEGER IS

VARIABLE AuxN: INTEGER; BEGIN

IF W(7) = '0' THEN

RETURN(Bin_Int(W));

ELSE

AuxN := Bin_Int(C2(W));

AuxN := AuxN - (2*ABS(AuxN));

RETURN(AuxN);

END IF;

END;

---FUNCION BINARIO A ENTERO--- FUNCTION Bin_Int (W: WORD) RETURN INTEGER IS

VARIABLE AuxN: INTEGER; BEGIN

AuxN := 0;

FOR i IN 6 DOWNTO 0 LOOP IF W(i) = '1' THEN

AuxN := AuxN + (2**i);

END IF;

END LOOP; RETURN(AuxN); END;

---FUNCION COMPLEMENTO A 2--- FUNCTION C2 (A: WORD) RETURN WORD IS

VARIABLE AuxW: WORD; VARIABLE I: INTEGER; BEGIN

FOR i IN 7 DOWNTO 0 LOOP AuxW(i) := NOT A(i); END LOOP;

AuxW := AuxW + 1; RETURN (AuxW);

END;

---FUNCION ENTERO A BINARIO--- FUNCTION Int_Bin (N: INTEGER) RETURN WORD IS

VARIABLE AuxW: WORD; VARIABLE AuxN: INTEGER; BEGIN

AuxN := N;

FOR i IN 6 DOWNTO 0 LOOP

IF ( AuxN >= (2**i)) THEN

AuxW(i) := '1';

AuxN := AuxN - (2**i);

ELSE AuxW(i) := '0'; END IF; END LOOP; RETURN (AuxW); END;

(20)

---FUNCION ENTERO A BINARIO EN COMPLEMENTO A 2--- FUNCTION Int_BinC2 (N: INTEGER) RETURN WORD IS

BEGIN IF N>0 THEN RETURN(Int_Bin(N)); ELSE RETURN(C2(Int_Bin(ABS(N)))); END IF; END;

---FUNCION DE CADENA DE 5 BITS A ENTERO--- FUNCTION WORD_5_INT (CADENA: WORD_5) RETURN INTEGER IS VARIABLE AuxW: WORD_5;

VARIABLE AuxN: INTEGER; BEGIN

AuxW := CADENA;

FOR i IN 4 DOWNTO 0 LOOP

IF AuxW(i) = '1' then

AuxN := AuxN + 2**(i);

ELSE AuxN := AuxN; END IF; END LOOP; RETURN (AuxN); END;

---FUNCION DE CONVERSIO DE UN DATO PARA SER VISUALIZADO EN UN DISPLAY--- FUNCTION VISUALIZAR_1_DISPLAY (A: WORD) RETURN WORD_7 IS

BEGIN CASE A IS WHEN "00000000" => RETURN "0111111"; WHEN "00000001" => RETURN "0000110"; WHEN "00000010" => RETURN "1011011"; WHEN "00000011" => RETURN "1001111"; WHEN "00000100" => RETURN "1100110"; WHEN "00000101" => RETURN "1101101"; WHEN "00000110" => RETURN "1111101"; WHEN "00000111" => RETURN "0000111"; WHEN OTHERS => RETURN "0111111";

END CASE;

END;

---FUNCION DE CONVERSIO DE UN DATO PARA SER VISUALIZADO EN DOS DISPLAYS--- FUNCTION VISUALIZAR_2_DISPLAYS (A: WORD_6) RETURN WORD_14 IS

BEGIN CASE A IS

WHEN "000000" => RETURN "01111110111111"; --0 WHEN "000001" => RETURN "01111110000110";--1 WHEN "000010" => RETURN "01111111011011"; --2 WHEN "000011" => RETURN "01111111001111"; --3 WHEN "000100" => RETURN "01111111100110"; --4 WHEN "000101" => RETURN "01111111101101"; --5 WHEN "000110" => RETURN "01111111111101"; --6 WHEN "000111" => RETURN "01111110000111"; --7 WHEN "001000" => RETURN "01111110111111"; --8 WHEN "001001" => RETURN "01111110000110"; --9 WHEN "001010" => RETURN "00001100111111"; --10 WHEN "001011" => RETURN "00001100000110"; --11 WHEN "001100" => RETURN "00001101011011"; --12 WHEN "001101" => RETURN "00001101001111"; --13 WHEN "001110" => RETURN "00001101100110"; --14 WHEN "001111" => RETURN "00001101101101"; --15 WHEN "010000" => RETURN "00001101111101"; --16 WHEN "010001" => RETURN "00001100000111"; --17

(21)

WHEN "010010" => RETURN "00001100111111"; --18 WHEN "010011" => RETURN "00001100000110"; --19 WHEN "010100" => RETURN "10110110111111"; --20 WHEN "010101" => RETURN "10110110000110"; --21 WHEN "010110" => RETURN "10110111011011"; --22 WHEN "010111" => RETURN "10110111001111"; --23 WHEN "011000" => RETURN "10110111100110"; --24 WHEN "011001" => RETURN "10110111101101"; --25 WHEN "011010" => RETURN "10110111111101"; --26 WHEN "011011" => RETURN "10110110000111"; --27 WHEN "011100" => RETURN "10110110111111"; --28 WHEN "011101" => RETURN "10110110000110"; --29 WHEN "011110" => RETURN "10011110111111"; --30 WHEN "011111" => RETURN "10011110000110"; --31 WHEN "100000" => RETURN "10011111011011"; --32 WHEN "100001" => RETURN "10011111001111"; --33 WHEN "100010" => RETURN "10011111100110"; --34 WHEN "100011" => RETURN "10011111101101"; --35 WHEN "100100" => RETURN "10011111111101"; --36 WHEN "100101" => RETURN "10011110000111"; --37 WHEN "100110" => RETURN "10011110111111"; --38 WHEN "100111" => RETURN "10011110000110"; --39 WHEN "101000" => RETURN "11001100111111"; --40 WHEN "101001" => RETURN "11001100000110"; --41 WHEN "101010" => RETURN "11001101011011"; --42 WHEN "101011" => RETURN "11001101001111"; --43 WHEN "101100" => RETURN "11001101100110"; --44 WHEN "101101" => RETURN "11001101101101"; --45 WHEN "101110" => RETURN "11001101111101"; --46 WHEN "101111" => RETURN "11001100000111"; --47 WHEN "110000" => RETURN "11001100111111"; --48 WHEN "110001" => RETURN "11001100000110"; --49 WHEN "110010" => RETURN "11011010111111"; --50 WHEN "110011" => RETURN "11011010000110"; --51 WHEN "110100" => RETURN "11011011011011"; --52 WHEN "110101" => RETURN "11011011001111"; --53 WHEN "110110" => RETURN "11011011100110"; --54 WHEN "110111" => RETURN "11011011101101"; --55 WHEN "111000" => RETURN "11011011111101"; --56 WHEN "111001" => RETURN "11011010000111"; --57 WHEN "111010" => RETURN "11011010111111"; --58 WHEN "111011" => RETURN "11011010000110"; --59 WHEN "111100" => RETURN "11111010000110"; --60 WHEN "111101" => RETURN "11111010000110"; --61 WHEN "111110" => RETURN "11111011011011"; --62 WHEN "111111" => RETURN "11111011001111"; --63 WHEN OTHERS => RETURN "01111110111111";

END CASE; END;

---FUNCION DE CONVERSION DE UN DATO PARA SER VISUALIZADO EN TRES DISPLAYS--- FUNCTION VISUALIZAR_3_DISPLAYS (A: WORD) RETURN WORD_21 IS

BEGIN

CASE A(6 DOWNTO 0) IS

WHEN "0000000"=>RETURN "011111101111110111111";--0 WHEN "0000001" => RETURN "011111101111110000110"; --1 WHEN "0000010" => RETURN "011111101111111011011"; --2 WHEN "0000011" => RETURN "011111101111111001111"; --3 WHEN "0000100" => RETURN "011111101111111100110"; --4 WHEN "0000101" => RETURN "011111101111111101101"; --5 WHEN "0000110" => RETURN "011111101111111111101"; --6 WHEN "0000111" => RETURN "011111101111110000111"; --7 WHEN "0001000" => RETURN "011111101111110111111"; --8 WHEN "0001001" => RETURN "011111101111110000110"; --9 WHEN "0001010" => RETURN "011111100001100111111"; --10 WHEN "0001011" => RETURN "011111100001100000110"; --11 WHEN "0001100" => RETURN "011111100001101011011"; --12 WHEN "0001101" => RETURN "011111100001101001111"; --13 WHEN "0001110" => RETURN "011111100001101100110"; --14 WHEN "0001111" => RETURN "011111100001101101101"; --15 WHEN "0010000" => RETURN "011111100001101111101"; --16 WHEN "0010001" => RETURN "011111100001100000111"; --17 WHEN "0010010" => RETURN "011111100001100111111"; --18 WHEN "0010011" => RETURN "011111100001100000110"; --19 WHEN "0010100" => RETURN "011111110110110111111"; --20 WHEN "0010101" => RETURN "011111110110110000110"; --21 WHEN "0010110" => RETURN "011111110110111011011"; --22 WHEN "0010111" => RETURN "011111110110111001111"; --23 WHEN "0011000" => RETURN "011111110110111100110"; --24

(22)

WHEN "0011001" => RETURN "011111110110111101101"; --25 WHEN "0011010" => RETURN "011111110110111111101"; --26 WHEN "0011011" => RETURN "011111110110110000111"; --27 WHEN "0011100" => RETURN "011111110110110111111"; --28 WHEN "0011101" => RETURN "011111110110110000110"; --29 WHEN "0011110" => RETURN "011111110011110111111"; --30 WHEN "0011111" => RETURN "011111110011110000110"; --31 WHEN "0100000" => RETURN "011111110011111011011"; --32 WHEN "0100001" => RETURN "011111110011111001111"; --33 WHEN "0100010" => RETURN "011111110011111100110"; --34 WHEN "0100011" => RETURN "011111110011111101101"; --35 WHEN "0100100" => RETURN "011111110011111111101"; --36 WHEN "0100101" => RETURN "011111110011110000111"; --37 WHEN "0100110" => RETURN "011111110011110111111"; --38 WHEN "0100111" => RETURN "011111110011110000110"; --39 WHEN "0101000" => RETURN "011111111001100111111"; --40 WHEN "0101001" => RETURN "011111111001100000110"; --41 WHEN "0101010" => RETURN "011111111001101011011"; --42 WHEN "0101011" => RETURN "011111111001101001111"; --43 WHEN "0101100" => RETURN "011111111001101100110"; --44 WHEN "0101101" => RETURN "011111111001101101101"; --45 WHEN "0101110" => RETURN "011111111001101111101"; --46 WHEN "0101111" => RETURN "011111111001100000111"; --47 WHEN "0110000" => RETURN "011111111001100111111"; --48 WHEN "0110001" => RETURN "011111111001100000110"; --49 WHEN "0110010" => RETURN "011111111011010111111"; --50 WHEN "0110011" => RETURN "011111111011010000110"; --51 WHEN "0110100" => RETURN "011111111011011011011"; --52 WHEN "0110101" => RETURN "011111111011011001111"; --53 WHEN "0110110" => RETURN "011111111011011100110"; --54 WHEN "0110111" => RETURN "011111111011011101101"; --55 WHEN "0111000" => RETURN "011111111011011111101"; --56 WHEN "0111001" => RETURN "011111111011010000111"; --57 WHEN "0111010" => RETURN "011111111011010111111"; --58 WHEN "0111011" => RETURN "011111111011010000110"; --59 WHEN "0111100" => RETURN "011111111111010000110"; --60 WHEN "0111101" => RETURN "011111111111010000110"; --61 WHEN "0111110" => RETURN "011111111111011011011"; --62 WHEN "0111111" => RETURN "011111111111011001111"; --63 WHEN "1000000" => RETURN "011111111111011100110"; --64 WHEN "1000001" => RETURN "011111111111011101101"; --65 WHEN "1000010" => RETURN "011111111111011111101"; --66 WHEN "1000011" => RETURN "011111111111010000111"; --67 WHEN "1000100" => RETURN "011111111111010111111"; --68 WHEN "1000101" => RETURN "011111111111010000110"; --69 WHEN "1000110" => RETURN "011111100001110111111"; --70 WHEN "1000111" => RETURN "011111100001110000110"; --71 WHEN "1001000" => RETURN "011111100001111011011"; --72 WHEN "1001001" => RETURN "011111100001111001111"; --73 WHEN "1001010" => RETURN "011111100001111100110"; --74 WHEN "1001011" => RETURN "011111100001111101101"; --75 WHEN "1001100" => RETURN "011111100001111111101"; --76 WHEN "1001101" => RETURN "011111100001110000111"; --77 WHEN "1001110" => RETURN "011111100001110111111"; --78 WHEN "1001111" => RETURN "011111100001110000110"; --79 WHEN "1010000" => RETURN "011111101111110111111"; --80

(23)

WHEN "1010001" => RETURN "011111101111110000110"; --81 WHEN "1010010" => RETURN "011111101111111011011"; --82 WHEN "1010011" => RETURN "011111101111111001111"; --83 WHEN "1010100" => RETURN "011111101111111100110"; --84 WHEN "1010101" => RETURN "011111101111111101101"; --85 WHEN "1010110" => RETURN "011111101111111111101"; --86 WHEN "1010111" => RETURN "011111101111110000111"; --87 WHEN "1011000" => RETURN "011111101111110111111"; --88 WHEN "1011001" => RETURN "011111101111110000110"; --89 WHEN "1011010" => RETURN "011111100001100111111"; --90 WHEN "1011011" => RETURN "011111100001100000110"; --91 WHEN "1011100" => RETURN "011111100001101011011"; --92 WHEN "1011101" => RETURN "011111100001101001111"; --93 WHEN "1011110" => RETURN "011111100001101100110"; --94 WHEN "1011111" => RETURN "011111100001101101101"; --95 WHEN "1100000" => RETURN "011111100001101111101"; --96 WHEN "1100001" => RETURN "011111100001100000111"; --97 WHEN "1100010" => RETURN "011111100001100111111"; --98 WHEN "1100011" => RETURN "011111100001100000110"; --99 WHEN "1100100" => RETURN "000011001111110111111"; --100 WHEN "1100101" => RETURN "000011001111110000110"; --101 WHEN "1100110" => RETURN "000011001111111011011"; --102 WHEN "1100111" => RETURN "000011001111111001111"; --103 WHEN "1101000" => RETURN "000011001111111100110"; --104 WHEN "1101001" => RETURN "000011001111111101101"; --105 WHEN "1101010" => RETURN "000011001111111111101"; --106 WHEN "1101011" => RETURN "000011001111110000111"; --107 WHEN "1101100" => RETURN "000011001111110111111"; --108 WHEN "1101101" => RETURN "000011001111110000110"; --109 WHEN "1101110" => RETURN "000011000001100111111"; --110 WHEN "1101111" => RETURN "000011000001100000110"; --111 WHEN "1110000" => RETURN "000011000001101011011"; --112 WHEN "1110001" => RETURN "000011000001101001111"; --113 WHEN "1110010" => RETURN "000011000001101100110"; --114 WHEN "1110011" => RETURN "000011000001101101101"; --115 WHEN "1110100" => RETURN "000011000001101111101"; --116 WHEN "1110101" => RETURN "000011000001100000111"; --117 WHEN "1110110" => RETURN "000011000001100111111"; --118 WHEN "1110111" => RETURN "000011000001100000110"; --119 WHEN "1111000" => RETURN "000011010110110111111"; --120 WHEN "1111001" => RETURN "000011010110110000110"; --121 WHEN "1111010" => RETURN "000011010110111011011"; --122 WHEN "1111011" => RETURN "000011010110111001111"; --123 WHEN "1111100" => RETURN "000011010110111100110"; --124 WHEN "1111101" => RETURN "000011010110111101101"; --125 WHEN "1111110" => RETURN "000011010110111111101"; --126 WHEN "1111111" => RETURN "000011010110110000111"; --127 WHEN OTHERS => RETURN "011111101111110111111"; END CASE;

(24)

---FUNCION PARA VISUALIZAR LA INSTRUCCIÓN EN DOS DISPLAYS--- FUNCTION VISUALIZAR_INST (A: WORD_12) RETURN WORD_14 IS

BEGIN

If A(11 downto 6)="000000" then return VISUALIZAR_2_DISPLAYS(A(5 downto 0));

Else return VISUALIZAR_2_DISPLAYS(A(11 downto 6));

end if;

END;

END FUNCIONES;

2.2 DESCRIPCION DE LAS FASES DE SEGMENTACION

2.2.1 FASE IF.

Esta fase recibe como señales de entrada la dirección de salto calculada en la fase EX y la

condición de salto calculada en la fase MEM. Con estas señales el mux que selecciona el nuevo

valor del PC, decide si el nuevo valor del PC será el PC incrementado o el valor de salto.

Con el valor del contador de programa establecido, se lee de la memoria de instrucciones la

instrucción a realizar.

Figura 10: Fase IF

2.2.1.1 Modulo PC:

Este deja simplemente pasar el nuevo valor del PC en cada ciclo de reloj.

Entity PC is

Port ( CLK , RESET : IN STD_LOGIC; Selec_PC : IN WORD; P_C : OUT WORD); End PC;

architecture A of PC is

Begin PROCESS (CLK, RESET, Selec_PC) variable v : WORD;

Begin

IF RESET = '1' THEN --Si se resetea el procesador, el contador de programa vuelve a cero

V := "00000000";

ELSE

IF (CLK'EVENT AND CLK = '1') THEN --Se actualiza el nuevo valor del PC

V := Selec_PC;

END IF;

(25)

P_C <= V;

End process;

end A;

2.2.1.2 Componente MemInstruc:

Este bloque contiene las instrucciones en lenguaje maquina a ser ejecutadas por el procesador. La

memoria de instrucciones es leída de acuerdo con el valor del Contador de programa, que

especifica la dirección de la instrucción a ser realizada.

ENTITY MemInstruc IS

PORT ( Reset : IN STD_LOGIC; Dir : IN WORD;

InstSal : OUT WORD_INST); END MemInstruc;

ARCHITECTURE A OF MemInstruc IS SIGNAL Memoria: MEM_INST_WORD; SIGNAL DIREC: INTEGER;

BEGIN

DIREC <= Bin_IntC2(DIR); --Convierte el valor de el acmpo dirección a un binario en complemento a 2 PROCESS (DIREC, Memoria, Reset )

BEGIN

IF (reset='1') then Se inicializa la Memoria

Memoria(0) <= "10001100000001100000000000000000"; --LW rs=0 rt=6 dir=0

Memoria(1) <= "00000000001000110011100000100010"; --RESTA rs=1 rt=3 rd=7 Memoria(2) <= "10101100000000100000000000000000"; --SW rs=0 rt=2 dir=0 Memoria(3) <= "00000000100000110010100000101010"; --SLT rs=4 rt=3 rd=5 Memoria(4) <= "00000000100000000000100000000111"; --XX Operación no existente Memoria(5) <= "10101100000000100000000000000100"; --SW rs=0 rt=2 dir=4 Memoria(6) <= "00000000110001000001000000100101"; --OR rs=6 rt=4 rd=2 Memoria(7) <= "00010000101000000000000000000010"; --BEQ rs=5 rt=0 dir=2

InstSal <="00000000000000000000000000000000"; ELSE

if (DIREC>=0)AND(DIREC<INST_Dirs) THEN InstSal <= Memoria(ABS(DIREC));

else InstSal <="00000000000000000000000000000000"; End if; END IF; END PROCESS; END A;

2.2.1.3 Componente PC_Add:

Incrementa el valor del PC actual. Recibe como entrada el valor del Contador de programa y lo

incrementa para que apunte en la siguiente dirección secuencial para leer la correspondiente

instrucción a ejecutar del componente Memoria de instrucciones.

Como se ha construido una memoria de instrucciones de 8 posiciones de 32 bits, este componente

se cerciora de poder aumentar el valor del PC para no salirse del rango entre 0 y 7.

Entity PC_Add is

(26)

architecture A of PC_Add is

SIGNAL VAR : WORD; SIGNAL P_C : INTEGER; BEGIN Process(CLK, RESET, PC, VAR)

BEGIN

P_C <= Bin_IntC2(PC);

IF RESET='1' THEN VAR <= "00000000";

ELSE

IF (CLK'EVENT AND CLK='1') THEN

if (P_C>=0 AND P_C<=6)then VAR <= PC + 1;

else VAR <= "00000000"; end if; END IF; END IF; PC4<=VAR; End Process; end A;

2.2.1.4 Componente Mux_PC:

Selecciona el nuevo valor del PC a ser utilizado en el siguiente ciclo de reloj. Si la señal de

control del multiplexor se encuentra activa el nuevo PC será la dirección de salto calculada en la

fase EX o el valor actual incrementado en uno.

Entity mux_PC is

Port ( RESET : IN STD_LOGIC; PCSrc : IN STD_LOGIC; Salto_PC : IN WORD; PC4 : IN WORD; selec_PC : OUT WORD);

end mux_PC;

architecture A of mux_PC is

begin PROCESS (RESET, PCSrc, Salto_PC, PC4) variable var: WORD;

Begin

IF RESET='1' THEN VAR := "00000000";

ELSE

if PCSrc='1' then VAR := Salto_PC;

else VAR := PC4; end if; END IF; selec_PC<=var; End process; end A;

2.2.1.5 Componente Fase IF:

Este componente es simplemente la interconexión de los submodulos previamente descritos.

ENTITY FASE_IF IS

PORT ( Clk, RESET : IN STD_LOGIC; Salto_PC : IN WORD; PCSrc : IN STD_LOGIC;

OUT_PC, OUT_PC4 : INOUT WORD; OUT_INST : OUT WORD_INST ); END FASE_IF;

COMPONENT MUX_PC

PORT ( RESET, PCSrc : IN STD_LOGIC; Salto_PC : IN WORD; PC4 : IN WORD;

(27)

COMPONENT PC_Add

PORT ( CLK, RESET : IN STD_LOGIC; PC : IN WORD;

PC4 : OUT WORD); END COMPONENT;

COMPONENT PC

PORT ( CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; Selec_PC : IN WORD;

P_C : OUT WORD); END COMPONENT;

COMPONENT MemInstruc

PORT ( Reset : IN STD_LOGIC; Dir : IN WORD;

InstSal : OUT WORD_INST); END COMPONENT;

SIGNAL selec_PC : WORD; BEGIN

Component_1 : MUX_PC PORT MAP ( RESET, PCSrc, Salto_PC, OUT_PC4, selec_PC);

Component_2 : PC PORT MAP ( CLK, RESET, selec_PC, OUT_PC);

Component_3 : PC_add PORT MAP ( CLK, RESET, Selec_PC, OUT_PC4);

Component_4 : MemInstruc PORT MAP ( RESET, OUT_PC, OUT_INST);

END A;

2.2.2. FASE ID

Recibe como entradas la instrucción a decodificar, las señales de escritura del bloque de registros,

la dirección de registro a escribir y el dato. Y genera los datos para la etapa de ejecución EX

leídos del archivo de registros, las señales de control para las siguientes etapas y separa la

información de los campos que conforman la instrucción.

El banco de registros es un bloque construido en base a un arreglo con posiciones de datos de 8

bits. La unidad de control esta implementada por medio de un case, que dependiendo de el campo

OP genera el control para las etapas restantes.

Figura 11: Fase ID

2.2.2.1 Componente Decodificacion_Inst:

Este modulo separa los diferentes campos de la instrucción leída de memoria en la fase IF.

entity Decodificacion_Inst is

port ( Inst : IN WORD_INST;

RS, RT, RD : OUT WORD_5; Dir : OUT WORD_16; OUT_Cod_Op : OUT WORD_6; OUT_Cod_FUNC : OUT WORD_6);

(28)

architecture A of Decodificacion_Inst is begin PROCESS (Inst)

BEGIN

OUT_Cod_Op <= INST(31 DOWNTO 26);

RS <= INST(25 DOWNTO 21); --RS (LEER REG 1)

RT <= INST(20 DOWNTO 16); --RT (LEER REG 2)

RD <= INST(15 DOWNTO 11); DIR <= INST(15 DOWNTO 0);

OUT_Cod_FUNC <= INST(5 DOWNTO 0); END PROCESS;

End A;

2.2.2.2 Componente Control:

Crea las señales de control por etapas, para todos los elementos que conforman el camino de

datos dependiendo solamente del código de operación de la instrucción (ver tabla 2).

ENTITY Control IS

PORT ( RESET : IN STD_LOGIC; OpCode : IN WORD_6;

EX : OUT CTRL_EX; M : OUT CTRL_M; WB : OUT CTRL_WB ); END Control;

ARCHITECTURE A OF Control IS

SIGNAL RegDst, AluScr, MemToReg, RegWrite, MemRead, MemWrite, Branch: STD_LOGIC; SIGNAL AluOp: WORD_2;

BEGIN PROCESS(OpCode,RESET) BEGIN

CASE RESET IS

WHEN '1'=> RegDst <= '0'; AluScr <= '0'; MemToReg <= '0'; RegWrite <= '0'; MemRead <= '0'; MemWrite <= '0'; Branch <= '0'; AluOp <= "00";

WHEN '0'=>

CASE OpCode IS

WHEN "000000" => --FORMATO R

RegDst <= '1'; AluScr <= '0'; MemToReg <= '0';

RegWrite <= '1'; MemRead <= '0'; MemWrite <= '0';

Branch <= '0'; AluOp <= "10";

WHEN "100011" => --LW

RegDst <= '0'; AluScr <= '1'; MemToReg <= '1';

RegWrite <= '1'; MemRead <= '1'; MemWrite <= '0';

Branch <= '0'; AluOp <= "00";

WHEN "101011" => --SW

RegDst <= '1'; AluScr <= '1'; MemToReg <= '1';

RegWrite <= '0'; MemRead <= '0'; MemWrite <= '1'; Branch <= '0'; AluOp <= "00";

WHEN "000100" => --BEQ

RegDst <= '1'; AluScr <= '0'; MemToReg <= '1';

RegWrite <= '0'; MemRead <= '0'; MemWrite <= '0';

(29)

WHEN OTHERS=>

RegDst <= '0'; AluScr <= '0'; MemToReg <= '0';

RegWrite <= '0'; MemRead <= '0'; MemWrite <= '0';

Branch <= '0'; AluOp <= "00";

END CASE;

WHEN OTHERS => RegDst <= '0'; AluScr <= '0'; MemToReg <= '0';

RegWrite <= '0'; MemRead <= '0'; MemWrite <= '0';

Branch <= '0'; AluOp <= "00"; END CASE;

EX(0) <= RegDst;

EX(2 DOWNTO 1) <= AluOp; EX(3) <= AluScr; M(0) <= Branch; M(1) <= MemRead; M(2) <= MemWrite; WB(0) <= RegWrite; WB(1) <= MemToReg; END PROCESS; END A;

2.2.2.3 Componente BancoRegistros:

Contiene los registros de 8 bits que se utilizaran para cargar datos de memoria y guardar el

resultado de las operaciones.

Se construyo por medio de un vector de 8 posiciones de 8 bits, los cuales se inicializan con el

dato de la ubicación que ocupan dentro del arreglo, es decir el registro cero contendrá el valor

cero y el registro ocho contendrá el valor 7. Este bloque podrá ser leído en cualquier momento,

pero su escritura esta restringida a cada flanco de subida del reloj y a la activación de la señal

escribir registros RegWrite.

ENTITY BancoRegistros IS

PORT ( Clk, RESET, RegWrite : IN STD_LOGIC; Leer_Reg1, Leer_Reg2 , Reg_Esc : IN WORD_5; Dato_Esc: IN WORD; Dato1,Dato2 : OUT WORD);

END BancoRegistros;

ARCHITECTURE A OF BancoRegistros IS SIGNAL Registros_MATRIX: REGISTROS;

SIGNAL IND_Read_1, IND_Read_2, IND_Write: INTEGER; BEGIN

PROCESS(RESET, Clk, Leer_Reg1, Leer_Reg2, REGISTROS_MATRIX,RegWrite, Reg_Esc, Dato_Esc) BEGIN

IND_Read_1 <= WORD_5_INT(Leer_Reg1); IND_Read_2 <= WORD_5_INT(Leer_Reg2); IND_Write <= WORD_5_INT(Reg_Esc);

IF RESET='1' THEN --se inicializan los registros del 0 al 7 con los números de posición FOR i IN 0 TO Num_Regs-1 LOOP

Registros_MATRIX(i)<=CONV_STD_LOGIC_VECTOR(i,8);

(30)

ELSE -- Escritura

IF (CLK'event AND CLK='1' AND RegWrite='1' AND Reg_Esc>= 0 AND Reg_Esc<Num_Regs) THEN Registros_MATRIX(ABS(IND_Write))<=Dato_Esc;

End if;

-- Lectura

IF (Leer_Reg1>=0) AND (Leer_Reg1<Num_Regs) THEN

Dato1<=Registros_MATRIX(ABS(IND_Read_1)); ELSE Dato1<="00000000"; End if; IF (Leer_Reg2>=0)AND(Leer_Reg2<Num_Regs) THEN Dato2<=Registros_MATRIX(ABS(IND_Read_2)); ELSE Dato2<="00000000"; END IF; END IF; END PROCESS; END A;

2.2.2.4 Componente Fase ID:

En este componente se interconectan los submodulos que lo conforman.

ENTITY FASE_ID IS

PORT( Clk : IN STD_LOGIC; --Clock

RESET : IN STD_LOGIC; --RESET EXTERNO

RegWrite : IN STD_LOGIC; --Escribir Registros

Reg_to_write : IN WORD_5; --Registro a escribir

Dato_a_escr : IN WORD; --Dato a escribir

Inst : IN WORD_INST; --Instrucción

Out_EX : OUT CTRL_EX; --señales de fase EX

Out_M : OUT CTRL_M; --señales de fase MEM

Out_WB : OUT CTRL_WB; --señales de fase WB

Dato1,Dato2 : OUT WORD; --Datos leídos

RD : OUT WORD_5 --campos RD

RT,RS : INOUT WORD_5; --campos RT,RS

Dir : OUT WORD_16; --campos Dirección

OUT_FUNC : OUT WORD_6); --campo function

END FASE_ID;

ARCHITECTURE A OF Fase_ID IS COMPONENT Decodificacion_Inst

PORT( Inst : IN WORD_INST; RS, RT, RD : OUT WORD_5; Dir : OUT WORD_16; OUT_Cod_Op : OUT WORD_6; OUT_Cod_FUNC : OUT WORD_6); END COMPONENT;

COMPONENT Control

PORT( RESET : IN STD_LOGIC; OpCode : IN WORD_6; EX : OUT CTRL_EX;

M : OUT CTRL_M; WB : OUT CTRL_WB); END COMPONENT;

(31)

COMPONENT BancoRegistros

PORT ( Clk : IN STD_LOGIC; RESET : IN STD_LOGIC; RegWrite : IN STD_LOGIC;

Leer_Reg1, Leer_Reg2 : IN WORD_5; Reg_Esc : IN WORD_5; Dato_Esc : IN WORD; Dato1,Dato2 : OUT WORD); END COMPONENT;

SIGNAL Cod_Op: WORD_6; BEGIN

COMPONENT1: Decodificacion_Inst

PORT MAP ( Inst, RS, RT, RD, Dir, Cod_Op, OUT_FUNC); COMPONENTE2: BancoRegistros

PORT MAP ( Clk, RESET, RegWrite, RS, RT, Reg_to_write, Dato_a_escr, Dato1, Dato2); COMPONENTE3: Control

PORT MAP ( RESET, Cod_Op, Out_EX, Out_M, Out_WB); END A;

2.2.3 FASE EX.

Esta conformada por ocho módulos: cuatro multiplexores, un sumador, la ALU y las unidades de

control de la ALU y de anticipación.

Figura 12: Fase EX

2.2.3.1 Componente DIR_Salto:

Es un sumador que calcula la dirección de salto del contador de programa, sumando el valor

inmediato del PC con el campo dirección de la instrucción.

(32)

Entity DIR_SALTO is

port ( PC4 : IN WORD; Dir : IN WORD_16; DirSalto : OUT WORD);

end DIR_SALTO;

architecture A of DIR_SALTO is Begin PROCESS (Dir,PC4) VARIABLE VAR:WORD_16; BEGIN

--CALCULO DIR. DE SALTO VAR := (Dir + PC4);

IF (VAR <= "0000000000000111") THEN DIRSALTO <= VAR(7 DOWNTO 0); ELSE DIRSALTO <= PC4; END IF; END PROCESS; end A;

2.2.3.2 Componente MUX_A:

Multiplexor que selecciona el primer operando de la ALU. Este puede ser el primer dato leído la

unidad de registros o algún valor anticipado cómo el resultado de la ALU o el Dato a escribir en

el banco de registros del anterior ciclo de reloj.

Entity MUX_A is

PORT ( SEL_A : IN WORD_2; Dato1Reg, DATO_MEM_memoria, DATO_WB_dato_esc : IN WORD; Operador_A : OUT WORD);

end MUX_A;

architecture A of MUX_A is

begin PROCESS(SEL_A, Dato1Reg, DATO_MEM_memoria, DATO_WB_dato_esc) begin

CASE SEL_A IS

WHEN "00" => Operador_A <= DATO1Reg;

WHEN "01" => Operador_A <= DATO_MEM_memoria; WHEN "10" => Operador_A <= DATO_WB_dato_esc; WHEN OTHERS => Operador_A <= "10000000";

END CASE;

END PROCESS;

end A;

2.2.3.3 Componente MUX_B:

Multiplexor que selecciona una opción para el primer operando de la ALU, que después podrá ser

seleccionado en el siguiente multiplexor. Este puede ser el segundo dato leído la unidad de

registros o algún valor anticipado cómo el resultado de la ALU o el Dato a escribir en el banco de

registros del anterior ciclo de reloj.

Entity MUX_B is

PORT ( SEL_B : IN WORD_2; Dato2Reg, DATO_MEM_memoria, DATO_WB_dato_esc : IN WORD; Operador_B : OUT WORD);

(33)

architecture A of MUX_B is

Begin PROCESS(SEL_B, Dato2Reg, DATO_MEM_memoria, DATO_WB_dato_esc) begin

CASE SEL_B IS

WHEN "00" => Operador_B <= DATO2Reg;

WHEN "01" => Operador_B <= DATO_MEM_memoria ; WHEN "10" => Operador_B <= DATO_WB_dato_esc; WHEN OTHERS => Operador_B <= "10000000";

END CASE;

END PROCESS; End A;

2.2.3.4 Componente MUX_ALU:

Multiplexor que selecciona el segundo operando de la ALU entre el valor proporcionado por el

componente MUX_B y el campo dirección.

Entity mux_ALU is

PORT ( ALUScr : IN STD_LOGIC; Operador_B : IN WORD;

DIR : IN WORD_16; OP2Alu : OUT WORD);

end mux_ALU;

architecture A of mux_ALU is begin

PROCESS (ALUScr, Dir, Operador_B) --SELECCION DE ENTRADA A LA ALU VARIABLE VAR: WORD_16;

BEGIN

IF (ALUScr='0') THEN

VAR := "00000000" & Operador_B; --DATO2 ES MUX_ANT_B

ELSE VAR := Dir;

END IF;

OP2Alu <= VAR(7 DOWNTO 0); END PROCESS;

end A;

2.2.2.5 Componente ALU:

La Unidad Aritmético Lógica se construyo en base a estamentos IF y CASE dependiendo del la

señal de control de la ALU (ver tabla 3) , con la que se escoge la operación a realizar. Para

establecer la señal Zero, se observa el resultado y se pone la bandera a ‘1’ si este es cero

(“00000000”).

ENTITY Alu IS

PORT ( A,B : IN WORD; Control : IN WORD_3; RESULT : INOUT WORD; Zero : OUT STD_LOGIC); END Alu;

ARCHITECTURE A OF Alu IS BEGIN

PROCESS (A,B,Control) variable R : WORD;

(34)

BEGIN

CASE CONTROL IS

WHEN "000" => R:= (A AND B); -- AND WHEN "001" => R:= (A OR B); -- OR

WHEN "010" => R:= (A + B); -- SUMA

WHEN "110" => R:= (A - B); -- RESTA

WHEN "111" => -- SET ON LESS THAN

IF (A < B) THEN R:= "00000001"; ELSE R:= "00000000"; END IF; WHEN OTHERS => R:= "10000000"; END CASE; RESULT <= R; END PROCESS;

PROCESS(RESULT) BEGIN -- Cálculo de la salida Zero. IF RESULT = "000000000" THEN Zero <= '1'; ELSE Zero <= '0'; END IF; END PROCESS; END A;

2.2.3.6 Componente MUX_REG_DST:

Selecciona el registro que va a ser escrito dependiendo de la operación a ser realizada. Para una

operación tipo R será seleccionado el registro especificado en el campo RD, mientras que para la

de transferencia de datos será el del campo RT.

Entity MUX_REG_DST is

port ( RegDst : IN STD_LOGIC; RD, RT : IN WORD_5;

Reg_Esc : OUT WORD_5);

end MUX_REG_DST; architecture A of MUX_REG_DST is begin PROCESS (RegDst, RD, RT) BEGIN IF (RegDst='0') THEN Reg_Esc <= RT; ELSE Reg_Esc <= RD; END IF; END PROCESS; end A;

Referencias

Documento similar

In addition to the requirements set out in Chapter VII MDR, also other MDR requirements should apply to ‘legacy devices’, provided that those requirements

The notified body that issued the AIMDD or MDD certificate may confirm in writing (after having reviewed manufacturer’s description of the (proposed) change) that the

En estos últimos años, he tenido el privilegio, durante varias prolongadas visitas al extranjero, de hacer investigaciones sobre el teatro, y muchas veces he tenido la ocasión

que hasta que llegue el tiempo en que su regia planta ; | pise el hispano suelo... que hasta que el

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

En junio de 1980, el Departamento de Literatura Española de la Universi- dad de Sevilla, tras consultar con diversos estudiosos del poeta, decidió propo- ner al Claustro de la

Entre nosotros anda un escritor de cosas de filología, paisano de Costa, que no deja de tener ingenio y garbo; pero cuyas obras tienen de todo menos de ciencia, y aun

E Clamades andaua sienpre sobre el caua- 11o de madera, y en poco tienpo fue tan lexos, que el no sabia en donde estaña; pero el tomo muy gran esfuergo en si, y pensó yendo assi