23
UNIVERSIDAD POLITÉCNICA DE VICTORIA MAESTRÍA EN INGENIERÍA ESPECIALIDAD: MECATRÓNICA ASIGNATURA: PROCESADORES DIGITALES CATEDRÁTICO: DR. MARCO AURELIO NUÑO MAGANDA ALUMNO: JOSUÉ HELÍ JIMÉNEZ ARTEAGA REPORTE DE PRÁCTICA: 06

UPV-PD-Tarea06_JHJA

Embed Size (px)

DESCRIPTION

Reporte de práctica de diseño de arquitectura hardware con lenguaje VHDL: Datapath monociclo de procesador MIPS

Citation preview

Page 1: UPV-PD-Tarea06_JHJA

UNIVERSIDAD POLITÉCNICA DE VICTORIA

MAESTRÍA EN INGENIERÍA

ESPECIALIDAD:

MECATRÓNICA

ASIGNATURA:

PROCESADORES DIGITALES

CATEDRÁTICO:

DR. MARCO AURELIO NUÑO MAGANDA

ALUMNO:

JOSUÉ HELÍ JIMÉNEZ ARTEAGA

REPORTE DE PRÁCTICA: 06

Page 2: UPV-PD-Tarea06_JHJA

��

DATAPATH MONOCICLO DEL PROCESADOR MIPS INTRODUCCIÓN

Se implementará el datapath monociclo del procesador MIPS básico, y se harán las modificaciones necesarias para soportar las instrucciones de JR (jump register) y LI (load immediate).

El diseño realizado se verificará utilizando testbenches, almacenando en un archivo de

texto las instrucciones codificadas en binario de un programa.

Figura 1. Diagrama a bloques del datapath monociclo (1)

La operación funcional paso a paso continua del modelo simplificado de la arquitectura MIPS puede ser descrito como:

1. Una instrucción es extraída de la memoria especificada por el Contador de Programa (PC). La instrucción es cargada en el Registro de Instrucciones, el contador de programa es incrementado para apuntar a la siguiente instrucción.

2. Dos códigos de cinco bits Rs y Rt dentro de la instrucción especifican qué espacios del archivo de registros son leídos para obtener dos operandos de 32 bits.

3. Los dos operandos fuente de 32 bits son dirigidos a las entradas de la ALU, donde alguna operación será realizada dependiendo del Código de Operación en la instrucción.

4. El resultado de la operación es almacenado en el archivo de registros en una dirección especificada por el código Rd de 5 bits en el Registro de Instrucciones. Ir al paso 1.(2)

Page 3: UPV-PD-Tarea06_JHJA

��

DESARROLLO Se definirá cada bloque funcional del procesador por separado. Para después hacer las conexiones necesarias según el diagrama, para implementar las funciones requeridas. Para adecuar el diagrama de la figura 1 para soportar las funciones JR y LI, se realizaron los siguientes cambios:

Figura 2. Cambios realizados al datapath para soportar JR

En la ALU que incrementa al Contador de Programa, solo sumara en 1, ya que cada

instrucción del programa estará guardada en líneas numeradas consecutivamente, de 1 en 1. Por la misma razón, no se utilizará el bloque de Corrimiento hacia la Izquierda.

El bloque de control tendrá una funcionalidad de acuerdo a la siguiente tabla de

verdad:

Entrada Salida

Op5 Op4 Op3 Op2 Op1 Op0 RegDst ALUSrc MemToReg RegWrite MemRead MemWrite Branch ALUOp1 ALUOp0

Tipo R 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0

LW 1 0 0 0 1 1 0 1 1 1 1 0 0 0 0

SW 1 0 1 0 1 1 0 1 0 0 0 1 0 0 0

BEQ 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1

JR 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0

LI (ORI) 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0

El código de operación de la instrucción JR definido para MIPS es 000000, pero para

esta práctica, se definió el 000001 para evitar hacer mayores cambios en los demás bloques.

Page 4: UPV-PD-Tarea06_JHJA

��

La instrucción LI era la instrucción original en ensamblador. Ahora se utiliza la instrucción ORI la cual hace una función OR lógica del contenido del registro Rs con la extensión del valor inmediato y almacenado en el archivo de registro Rt.(2)

La unidad de control de la ALU está definida por el siguiente comportamiento: ALUOp Función

ALUOp1 ALUOp0 F5 F4 F3 F2 F1 F0 Operación JrEn 0 0 X X X X X X 0010 0 0 1 X X X X X X 0110 0 1 X X X 0 0 0 0 0010 0 1 X X X 0 0 1 0 0110 0 1 X X X 0 1 0 0 0000 0 1 X X X 0 1 0 1 0001 0 1 X X X 1 0 1 0 0111 0 1 X X X 1 0 0 0 0010 1

A continuación se muestran los códigos de las instrucciones soportadas por el modelo

de datapath de esta práctica: add Rd, Rs, Rt

OpCode Rs Rt Rd Shamt Function 0 0 0 0 0 0 s s s s s t t t t t d d d d d 0 0 0 0 0 1 0 0 0 0 0 and Rd, Rs, Rt

OpCode Rs Rt Rd Shamt Function 0 0 0 0 0 0 s s s s s t t t t t d d d d d 0 0 0 0 0 1 0 0 1 0 0 beq Rs, Rt, Etiqueta

OpCode Rs Rt Inmediato 0 0 0 1 0 0 s s s s s t t t t t i i i i i i i i i i i i i i i I jr Rs

OpCode Rs Function 0 0 0 0 0 0 s s s s s 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 En la implementación se utilizó un código de operación “000001” lw Rt, offset(Rs)

OpCode Rs Rt Offset 1 0 0 0 1 1 s s s s s t t t t t i i i i i i i i i i i i i i i I

Page 5: UPV-PD-Tarea06_JHJA

��

or Rd, Rs, Rt

OpCode Rs Rt Rd Shamt Function 0 0 0 0 0 0 s s s s s t t t t t d d d d d 0 0 0 0 0 1 0 0 1 0 1 ori Rt, Rs, Inmediato

OpCode Rs Rt Inmediato 0 0 1 1 0 1 s s s s s t t t t t i i i i i i i i i i i i i i i i Para implementar la instrucción LI a partir de ORI, se utiliza como Rs el registro $0, cuyo contenido es 0. slt Rd, Rs, Rt

OpCode Rs Rt Rd Shamt Function 0 0 0 0 0 0 s s s s s t t t t t d d d d d 0 0 0 0 0 1 0 1 0 1 0 sub Rd, Rs, Rt

OpCode Rs Rt Rd Shamt Function 0 0 0 0 0 0 s s s s s t t t t t d d d d d 0 0 0 0 0 1 0 0 0 1 0 sw Rt, offset(Rs)

OpCode Rs Rt Offset 1 0 1 0 1 1 s s s s s t t t t t i i i i i i i i i i i i i i i I Tomando como referencia las tablas anteriores, se realizarán programas sencillos para comprobar la funcionalidad del diseño del datapath. Estos programas estarán almacenados en archivos de texto (.TXT), organizados de una instrucción de 32 bits por línea. El bloque de Memoria de Instrucciones almacenará cada línea leída del archivo de texto indicado.

Page 6: UPV-PD-Tarea06_JHJA

��

RESULTADOS Cada paso de la simulación se hará con un ciclo de reloj, en el cual se ejecutará una instrucción completa.

Figura 3. Ciclo de reloj

Prueba: Se realizará la suma de dos números Archivo: Suma.txt

1. Cargar en el registro $1 el valor inmediato de 4 En la figura 4 se observa cómo WDReg = 4 (dato a escribir), y WReg = 1 (dirección del registro en el que se va a escribir). En una primera instancia, solo el registro 0 ($0) está definido con un valor de cero, los demás registros no tienen un valor definido.

Figura 4. Carga de inmediato en registro.

Izquierda: señales del datapath. Derecha: memoria de registros

Page 7: UPV-PD-Tarea06_JHJA

��

2. Carga en el registro $2 el valor de 6. En la memoria de registros se observa cómo

ahora almacena 6 en el registro 2, y en el registro 1, queda guardado el valor almacenado en la instrucción anterior.

Figura 5. Carga de inmediato en registro.

Izquierda: señales del datapath. Derecha: memoria de registros

3. Suma el contenido de los registros 1 y 2, y almacena el resultado en el registro 3

Figura 6. Suma del contenido de dos registros.

Izquierda: señales del datapath. Derecha: memoria de registros

Page 8: UPV-PD-Tarea06_JHJA

��

4. Almacena el contenido del registro 3 (resultado de la suma) en la memoria de datos. En la figura 7 se muestra como WReg = 3 (registro 3), cuyo valor es almacenado en el espacio 0 de la memoria (del lado derecho de la figura)

Figura 7. Almacenamiento en memoria

Izquierda: señales del datapath. Derecha: memoria de datos

5. Salta a la dirección almacenada en el registro 0. Usando la instrucción JR para comenzar nuevamente el programa, salta a la dirección 0. JrEn = 1, por lo tanto, la siguiente dirección será la indicada por AdrIn2, que le indicará al contador de programa volver a comenzar.

Figura 8. Instrucción JR

Page 9: UPV-PD-Tarea06_JHJA

Prueba: Cuenta regresiva de N hasta 0 Archivo: CuentaRegresiva.txt Algoritmo:

1. Almacena 1 en el registro 1 2. Almacena N en el registro 2 3. Resta el contenido del registro 2 menos el del registro 1 y lo almacena en el registro 3 4. Almacena el contenido del registro 3 en el 2, por medio de una suma con cero 5. Compara si el contenido del registro 2 es igual al del registro 0, si es igual, sigue en el

paso 7. 6. Hace un salto hacia el paso 3. 7. Hace un salto al paso 1

Figura 9. Conteo regresivo. En el registro 2 se observa la cuenta con N = 3.

Prueba: Multiplicación de M x N, por medio de sumas Archivo: Multiplicación.txt Algoritmo:

1. Almacena M en el registro 1 2. Almacena N en el registro 2 3. Almacena 0 en el registro 3, valor inicial para las sumas 4. Suma el contenido de los registros 1 y 3, y guarda el resultado en el registro 3 5. Decrementa en 1 el contenido del registro 2 6. Si el contenido del registro 2 es igual a 0, sigue en el paso 8 7. Salta al paso 4 8. Almacena el contenido del registro 3 en la memoria de datos (el resultado de la

multiplicación) 9. Hace un salto al paso 1.

Figura 10. Multiplicación usando sumas. M = 4, N = 3. (4x3 = 1210 = C16)

Page 10: UPV-PD-Tarea06_JHJA

Prueba: Sumatoria de N a 0 Archivo: Sumatoria.txt Algoritmo:

1. Almacena N en el registro 1. Inicializa el registro 4 con 0 2. Almacena el contenido del registro 1 en memoria 0 3. Carga en el registro 3 el contenido de la memoria 0 4. Carga a X con 5. Salta al paso 9 (esto es análogo a una llamada a rutina) 5. Si el contenido del registro 3 es igual a 0, salta al paso 7 6. Salta al paso 4 7. Almacena en memoria 1 el contenido del registro 4 8. Salta al paso 1 9. Suma el contenido de los registros 3 y 4, y almacena en el registro 4 10. Decrementa el contenido del registro 3 y vuelve a almacenar 11. Salta al paso X (regreso de una subrutina, usando la instrucción JR)

Figura 11. Sumatoria de N a 0. Con N = 4. � = 4 + 3 + 2 + 1 + 0 = 1010 = A16

En la gráfica se observa que en la memoria 0 se almacena el número original y

cuando termina de calcular la sumatoria de N hasta 0, la almacena en el registro 1. Prueba: Determinación del menor de 3 números. Archivo: Menor.txt Algoritmo:

1. Carga en un registro diferente cada número 2. Si el contenido del registro 1 es mayor que el del registro 2, salta al paso 5 3. Si el contenido del registro 1 es mayor que el del registro 3, salta al paso 7 4. Almacena el contenido del registro 1 en memoria y salta al paso 1 5. Si el contenido del registro 2 es mayor que el del registro 3, salta al paso 7 6. Almacena el contenido del registro 2 en memoria y salta al paso 1 7. Almacena el contenido del registro 3 en memoria y salta al paso 1

Page 11: UPV-PD-Tarea06_JHJA

���

El menor se almacenará en la dirección 0 de la memoria de datos. Con los números 1, 2 y 3 almacenados en la memoria de registros:

Figura 12. Determinación del menor de 3 números.

Con los números 3, 2 y 5 almacenados en la memoria de registros:

Figura 13. Determinación del menor de 3 números.

Con los números 5, 7 y 3 almacenados en la memoria de registros:

Figura 14. Determinación del menor de 3 números.

Para hacer las comparaciones entre números y determinar cuál es mayor, se usa la instrucción SLT y luego es comparado el resultado con 0 para condicionar los saltos.

Page 12: UPV-PD-Tarea06_JHJA

���

Prueba: Implementación de función XOR, usando AND y OR. Archivo: XOR.txt La función XOR también se puede implementar utilizando compuertas básicas, como se muestra en el siguiente diagrama:

Figura 15. Función XOR con compuertas básicas

A 0000 0000 0000 0000 0000 0000 0000 1010 0000000A B 0000 0000 0000 0000 0000 0000 0000 1101 0000000D

F = A XOR B 0000 0000 0000 0000 0000 0000 0000 0111 00000007

Figura 15. Función XOR

Para esta implementación, se usan las funciones AND, OR. Y para la función NOT, se

incrementa el número y luego se le es restado a 0, almacenándose el resultado en los registros 3 y 4. El resultado de la operación XOR queda guardado en el registro 7.

Page 13: UPV-PD-Tarea06_JHJA

���

CONCLUSIONES Con el desarrollo de la práctica se pudo comprobar el funcionamiento de un datapath simplificado del procesador MIPS. Pudiendo visualizar en el simulador cómo cambiaba cada registro y señal al paso de cada ciclo de reloj, en el cual era ejecutada una instrucción completa. Utilizando el recurso de los testbenches fue más sencillo ejecutar diferentes programas, ya que cada uno estaba guardado en archivos de texto independientes, de otra manera, habría sido necesario cambiar la programación en el diseño en VHDL de la memoria de instrucciones, para cada programa diferente. Además, hacer correcciones en el programa en ensamblador codificado no requería de estar recompilando en cada cambio. REFERENCIAS

(1) Diseño de un procesador. Diapositivas vistas en clase. (2) Britton, Robert L.: MIPS Assembley Language Programming, California State University.

Page 14: UPV-PD-Tarea06_JHJA

���

ANEXOS Código fuente del programa Archivo: ALU.vhd -- LIBRERIAS UTILIZADAS library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all; entity ALU is generic( BITS: integer := 32 -- CANTIDAD DE BITS DE LOS DATOS ); port( A : in STD_LOGIC_VECTOR(BITS-1 downto 0); B : in STD_LOGIC_VECTOR(BITS-1 downto 0); Ctrl : in STD_LOGIC_VECTOR(3 downto 0); Result : out STD_LOGIC_VECTOR(BITS-1 downto 0); Zero : out STD_LOGIC ); end ALU; architecture ALU_arq of ALU is begin -- ALU process(A,B,Ctrl) begin case Ctrl is when "0000" => Result <= A and B; when "0001" => Result <= A or B; when "0010" => Result <= A + B; when "0110" => Result <= A - B; when "0111" => if (A < B) then Result <= (A xor A)+1; else Result <= (A xor A); end if; when "1100" => Result <= A nor B; when OTHERS => end case; -- ESTA CONDICION SE USARA PARA LA IMPLEMENTACION DE SALTOS INCONDICIONALES if (A = B) then Zero <= '1'; else Zero <= '0'; end if; end process; end ALU_arq;

Page 15: UPV-PD-Tarea06_JHJA

���

Archivo: Registros.vhd �-- LIBRERIAS UTILIZADAS library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity Registros is port( RegWrite : in STD_LOGIC; -- RegWrite. HABILITA LA ESCRITURA RReg1 : in STD_LOGIC_VECTOR(4 downto 0); -- READ REGISTER 1 RReg2 : in STD_LOGIC_VECTOR(4 downto 0); -- READ REGISTER 2 WReg : in STD_LOGIC_VECTOR(4 downto 0); -- WRITE REGISTER WData : in STD_LOGIC_VECTOR(31 downto 0); -- WRITE DATA RData1 : out STD_LOGIC_VECTOR(31 downto 0); -- READ DATA 1 RData2 : out STD_LOGIC_VECTOR(31 downto 0) -- READ DATA 2 ); end Registros; architecture Registros_arq of Registros is type regArray is array(0 to 31) of std_logic_vector(31 downto 0); -- 32 REGISTROS signal registro: regArray; -- MEMORIA DE REGISTROS begin process (RReg1, RReg2, WData) begin registro(0) <= "00000000000000000000000000000000"; -- REGISTRO $ZERO if (RReg1'event or RReg1 /= “UUUUU”) then -- LEE LO QUE HAY EN LA DIRECCION RREG1 RData1 <= registro(conv_integer(RReg1)); end if; if (RReg2'event or RReg2 /= “UUUUU”) then -- LEE LO QUE HAY EN LA DIRECCION RREG2 RData2 <= registro(conv_integer(RReg2)); end if; if (RegWrite = '1') then -- ESCRIBE WDATA EN LA DIRECCION WREG registro(conv_integer(WReg)) <= WData; end if; end process; end Registros_arq;

Page 16: UPV-PD-Tarea06_JHJA

���

Archivo: DataMemory.vhd -- LIBRERIAS UTILIZADAS library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity DataMemory is port( MemWrite : in STD_LOGIC; -- HABILITA ESCRITURA MemRead : in STD_LOGIC; -- HABILITA LECTURA Address : in STD_LOGIC_VECTOR(4 downto 0); -- DIRECCION WData : in STD_LOGIC_VECTOR(31 downto 0); -- WRITE DATA RData : out STD_LOGIC_VECTOR(31 downto 0) -- READ DATA ); end DataMemory; architecture DataMemory_arq of DataMemory is -- 32 CELDAS DE 32 BITS type memoArray is array(0 to 31) of std_logic_vector(31 downto 0); signal memoria: memoArray; -- MEMORIA DE DATOS begin process (MemWrite, MemRead, Address’delayed, WData) begin if (MemWrite = '1') then -- ESCRIBE WDATA EN LA DIRECCION ADDRESS memoria(conv_integer(Address)) <= WData; end if; if (MemRead = '1') then -- LEE LO QUE HAY EN LA DIRECCION ADDRESS RData <= memoria(conv_integer(Address)); end if; end process; end DataMemory_arq;

Archivo: Mux2a1.vhd -- LIBRERIA UTILIZADA library IEEE; use IEEE.STD_LOGIC_1164.all; entity Mux2a1 is generic( BITS: integer := 32 -- CANTIDAD DE BITS DE LOS DATOS ); port( A : in STD_LOGIC_VECTOR(BITS-1 downto 0); B : in STD_LOGIC_VECTOR(BITS-1 downto 0); S : in STD_LOGIC; C : out STD_LOGIC_VECTOR(BITS-1 downto 0) ); end Mux2a1; architecture Mux2a1_arq of Mux2a1 is begin -- MULTIPLEXOR 2 A 1 C <= A when (S = '0') else B; end Mux2a1_arq;

Page 17: UPV-PD-Tarea06_JHJA

���

Archivo: SignExt.vhd -- LIBRERIA UTILIZADA library IEEE; use IEEE.STD_LOGIC_1164.all; entity SignExt is port( A : in STD_LOGIC_VECTOR(15 downto 0); B : out STD_LOGIC_VECTOR(31 downto 0) ); end SignExt; architecture SignExt_arq of SignExt is begin -- EXTENSION DE SIGNO B <= "1111111111111111"&A(15 downto 0) when (A(15) = '1') else "0000000000000000"&A(15 downto 0); end SignExt_arq;

Archivo: Control.vhd -- LIBRERIA UTILIZADA library IEEE; use IEEE.STD_LOGIC_1164.all; entity Control is port( OpCode : in STD_LOGIC_VECTOR(5 downto 0); Outputs : out STD_LOGIC_VECTOR(8 downto 0) ); end Control; architecture Control_arq of Control is begin -- FORMATO DE LA SALIDA: -- 8 7 6 5 4 3 2 1 0 -- RegDst ALUSrc MemToReg RegWrite MemRead MemWrite Branch ALUOp1 ALUOp0 Outputs <= "100100010" when (OpCode = "000000") else -- Tipo R "000000010" when (OpCode = "000001") else -- JR "011110000" when (OpCode = "100011") else -- LW "010001000" when (OpCode = "101011") else -- SW "000000101" when (OpCode = "000100") else -- BEQ "010100000"; -- ORI (LI) end Control_arq;

Page 18: UPV-PD-Tarea06_JHJA

���

Archivo: ALUCtrl.vhd �library IEEE; use IEEE.STD_LOGIC_1164.all; entity ALUCtrl is port( Funcion : in STD_LOGIC_VECTOR(5 downto 0); -- INSTRUCCION[5-0] ALUOp : in STD_LOGIC_VECTOR(1 downto 0); -- ALUOp1 ALUOp0 JrEn : out STD_LOGIC; -- LA FUENTE DEL PC Operacion : out STD_LOGIC_VECTOR(3 downto 0) -- MODO DE OPERACION ALU ); end ALUCtrl; architecture ALUCtrl_arq of ALUCtrl is begin process (Funcion, ALUOp) begin if (ALUOp = "00") then -- LW O SW o LI Operacion <= "0010"; -- ALU SUMA else if(ALUOp(0) = '1') then -- BEQ Operacion <= "0110"; -- ALU RESTA else -- TIPO R if(ALUOp(1) = '1') then if (Funcion(3 downto 0) = "0000") then -- FUNCION ADD Operacion <= "0010"; -- ALU SUMA elsif (Funcion(3 downto 0) = "0010") then -- FUNCION SUB Operacion <= "0110"; -- ALU RESTA elsif (Funcion(3 downto 0) = "0100") then -- FUNCION AND Operacion <= "0000"; -- ALU AND elsif (Funcion(3 downto 0) = "0101") then -- FUNCION OR Operacion <= "0001"; -- ALU OR elsif (Funcion(3 downto 0) = "1010") then -- FUNCION SLT Operacion <= "0111"; -- ALU SET-ON-LESS-THAN elsif (Funcion(3 downto 0) = "1000") then -- FUNCION JR Operacion <= "0010"; -- ALU SUMA end if; end if; end if; end if; if (Funcion(3 downto 0) = "1000") then JrEn <= '1'; else JrEn <= '0'; end if; end process; end ALUCtrl_arq;

Page 19: UPV-PD-Tarea06_JHJA

��

Archivo: InstrMemory.vhd -- LIBRERIAS UTILIZADAS library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.NUMERIC_STD.all; use STD.TEXTIO.all; use IEEE.STD_LOGIC_TEXTIO.all; entity InstrMemory is port( ReadAddress: in std_logic_vector(4 downto 0); Instruccion : out STD_LOGIC_VECTOR(31 downto 0) ); end InstrMemory; architecture InstrMemory_arq of InstrMemory is file file_in: text is in "Testbench.txt"; begin x1: process (ReadAddress) -- CADA LINEA DEL ARCHIVO variable line_in: line; -- UNA LINEA DE PROGRAMA variable input_tmp: std_logic_vector(31 downto 0); -- PARA IR ALMACENANDO EL PROGRAMA EN MEMORIA variable Address: integer range 0 to 255 := 0; -- CELDA DE 32 BITS DE MEMORIA DE PROGRAMA subtype memo is std_logic_vector(31 downto 0); type memoArray is array(0 to 31) of memo; -- 32 CELDAS DE 32 BITS variable memoria: memoArray; -- MEMORIA DE INSTRUCCIONES begin l1: while not(endfile(file_in)) loop -- LEE UNA LINEA DEL ARCHIVO readline(file_in, line_in); -- ALMACENA ESA LINEA EN input_tmp read(line_in, input_tmp); -- GUARDA EN MEMORIA UNA LINEA DE PROGRAMA memoria(Address) := input_tmp; Address := Address + 1; end loop l1; -- LEE INSTRUCCION EN MEMORIA Instruccion <= memoria(conv_integer(ReadAddress)); end process; end InstrMemory_arq;

Page 20: UPV-PD-Tarea06_JHJA

��

Archivo: ProgCounter.vhd -- LIBRERIAS UTILIZADAS library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all; entity ProgCounter is port( Clk : in STD_LOGIC; AdrIn : in STD_LOGIC_VECTOR(4 downto 0); AdrOut : out STD_LOGIC_VECTOR(4 downto 0) ); end ProgCounter; architecture ProgCounter_arq of ProgCounter is begin -- CONTADOR DE PROGRAMA process (Clk) begin if Clk'event and Clk='1' then if (AdrIn = "UUUUU" or AdrIn > "11111") then -- PONE EL PC EN 00000 SI ES LA PRIMERA VEZ QUE SE EJECUTA EL PROGRAMA, -- O SI YA TERMINO AdrOut <= "00000"; else AdrOut <= AdrIn; end if; end if; end process; end ProgCounter_arq;

Page 21: UPV-PD-Tarea06_JHJA

���

Archivo: Datapath.vhd -- LIBRERIA UTILIZADA library IEEE; use IEEE.STD_LOGIC_1164.all; entity Datapath is port( Clk : in STD_LOGIC ); end Datapath; architecture Datapath_arq of Datapath is -- SEÑALES INTERMEDIAS signal AdrIn, AdrOut, AdrSig, AdrSig2, WReg, AdrIn2: std_logic_vector(4 downto 0); signal Instruccion, WDReg, RData1, RData2, Extendido, RData2b, Result, RData3: std_logic_vector (31 downto 0); signal CtSignal: std_logic_vector (8 downto 0); signal Z1, Z2, JrEn, Zero, BrZero: std_logic; signal Operacion: std_logic_vector(3 downto 0); -- DATAPATH MONOCICLO begin PC1: entity work.ProgCounter (ProgCounter_arq) port map (Clk, AdrIn2, AdrOut); IM1: entity work.InstrMemory (InstrMemory_arq) port map (AdrOut, Instruccion); AL1: entity work.ALU (ALU_arq) generic map (BITS => 5) port map (AdrOut, "00001", "0010", AdrSig, Z1); CT1: entity work.Control (Control_arq) port map (Instruccion(31 downto 26), CtSignal); MX1: entity work.Mux2a1 (Mux2a1_arq) generic map (BITS => 5) port map (Instruccion(20 downto 16), Instruccion(15 downto 11),CtSignal(8),Wreg); RG1: entity work.Registros (Registros_arq) port map (CtSignal(5),Instruccion(25 downto 21), Instruccion(20 downto 16), Wreg, WDReg, RData1, RData2); SE1: entity work.SignExt (SignExt_arq) port map (Instruccion(15 downto 0), Extendido); MX2: entity work.Mux2a1 (Mux2a1_arq) generic map (BITS => 32) port map (RData2, Extendido, CtSignal(7), RData2b); AL2: entity work.ALU (ALU_arq) generic map (BITS => 5) port map (AdrSig, Extendido(4 downto 0), "0010", AdrSig2, Z2); CT2: entity work.ALUCtrl (ALUCtrl_arq) port map (Instruccion(5 downto 0), CtSignal(1 downto 0), JrEn, Operacion); AL3: entity work.ALU (ALU_arq) generic map (BITS => 32) port map (RData1, RData2b, Operacion, Result, Zero); AN1: entity work.CompuertaAND (CompuertaAND_arq) port map (CtSignal(2), Zero, BrZero); MX3: entity work.Mux2a1 (Mux2a1_arq) generic map (BITS => 5) port map (AdrSig, AdrSig2, BrZero, AdrIn); DM1: entity work.DataMemory (DataMemory_arq) port map (CtSignal(3), CtSignal(4), Result(4 downto 0), RData2, RData3); MX4: entity work.Mux2a1 (Mux2a1_arq) generic map (BITS => 32) port map (Result, RData3, CtSignal(6), WDReg); MX5: entity work.Mux2a1 (Mux2a1_arq) generic map (BITS => 5) port map (AdrIn, Result(4 downto 0), JrEn, AdrIn2); end Datapath_arq;

Page 22: UPV-PD-Tarea06_JHJA

���

TESTBENCHES Archivo: Suma.txt

00110100000000010000000000000100 00110100000000100000000000000110 00000000001000100001100000100000 10101100000000110000000000000000 00000100000000000000000000001000

LI $1, 4 LI $2, 6 ADD $3, $1, $2 SW $3, 0($0) JR $0

Archivo: CuentaRegresiva.txt

00110100000000100000000000000011 00110100000000010000000000000001 00000000010000010001100000100010 00000000011000000001000000100000 00010000010000000000000000000001 00010000000000001111111111111100 00000100000000000000000000001000

LI $2, 3 LI $1, 1 SUB $3, $2, $1 ADD $2, $3, $0 BEQ $2, $0, 1 BEQ $0, $0, -4 JR $0

Archivo: Multiplicacion.txt

00110100000000010000000000000100 00110100000000100000000000000011 00110100000000110000000000000000 00110100000001000000000000000001 00000000011000010001100000100000 00000000010001000010100000100010 00000000000001010001000000100000 00010000010000000000000000000001 00010000000000001111111111111011 10101100000000110000000000000000 00000100000000000000000000001000

LI $1, 4 LI $2, 3 LI $3, 0 LI $4, 1 ADD $3, $3, $1 SUB $5, $2, $4 ADD $2, $5, $0 BEQ $2, $0, 1 BEQ $0, $0, -5 SW $3, 0($0) JR $0

Archivo: Menor.txt

00110100000000010000000000000101 00110100000000100000000000000111 00110100000000110000000000000011 00000000001000100010000000101010 00010000100000000000000000000100 00000000001000110010000000101010 00010000100000000000000000000110 10101100000000010000000000000000 00000100000000000000000000001000 00000000010000110010000000101010 00010000100000000000000000000010 10101100000000100000000000000000 00000100000000000000000000001000 10101100000000110000000000000000 00000100000000000000000000001000

LI $1, 5 LI $2, 7 LI $3, 3 SLT $4, $1, $2 BEQ $4, $0, 4 SLT $4, $1, $3 BEQ $4, $0, 6 SW $1, 0($0) JR $0 SLT $4, $2, $3 BEQ $4, $0, 2 SW $2, 0($0) JR $0 SW $3, 0($0) JR $0

Page 23: UPV-PD-Tarea06_JHJA

���

Archivo: Sumatoria.txt

00110100000000010000000000000100 00110100000000100000000000000001 00110100000001000000000000000000 10101100000000010000000000000000 10001100000000110000000000000000 00110100000111110000000000000111 00010000000000000000000000000101 00010000011000000000000000000001 00010000000000001111111111111100 00110100000001010000000000000001 10101100101001000000000000000000 00000100000000000000000000001000 00000000100000110011000000100000 00000000110000000010000000100000 00000000011000100011000000100010 00000000110000000001100000100000 00000111111000000000000000001000

LI $1, 4 LI $2, 1 LI $4, 0 SW $1, 0($0) LW $3, 0($0) LI $31, 7 BEQ $0, $0, 5 BEQ $3, $0, 1 BEQ $0, $0, -4 LI $5, 1 SW $4, 0($0) JR $0 ADD $6, $4, $3 ADD $4, $6, $0 SUB $6, $3, $2 ADD $3, $6, $0 JR $31

Archivo: XOR.txt

00110100000010000000000000000001 00110100000000010000000000001010 00110100000000100000000000001101 00000000001010000100100000100000 00000000010010000101000000100000 00000000000010010001100000100010 00000000000010100010000000100010 00000000001001000010100000100100 00000000010000110011000000100100 00000000101001100011100000100101 00000100000000000000000000001000

LI $8, 1 LI $1, 10 LI $2, 13 ADD $9, $1, $8 ADD $10, $2, $8 SUB $3, $0, $9 SUB $4, $0, $10 AND $5, $1, $4 AND $6, $2, $3 OR $7, $5, $6 JR $0