Sie sind auf Seite 1von 19

SEP SNEST DGEST

INSTITUTO TECNOLÓGICO DE TOLUCA

REPORTE
Proyecto: microprocesador ruta de datos con
unidad de control

Diseño digital con vhdl

Ing. Electrónica

Profesor:
Carlos Eduardo Torres Reyes

P R E S E N T A N:

 Somera Castro Aldrich Alexis


15281237

 Tapia Conteras Jorge Eduardo


16281459

Metepec, Estado de México, a 12 de junio de 2020


Introducción:
El presente documento, tiene como objetivo, la explicación del proyecto final de la
materia VHDL. La máquina realizada al final del curso, pone a prueba las
competencias y habilidades adquiridas durante el mismo, además, nos refiere una
pequeña introducción a la asignatura de “Microcontroladores”.
Para la realización de éste proyecto, fue necesaria la aplicación de los temas
vistos en clase, los cuales son:
 Máquinas de estados
 Registros
 Instanciamiento por bloques
 Unidade lógica aritmética
Éste proyecto tiene objetivo la simulación y función general de un
microprocesador. Para llegar a ello, se tuvo que pasar por diferentes etapas y
proyectos, entre esos proyectos se encuentran:
 Memoria RAM
Los proyectos mencionados con anterioridad fueron de suma importancia, debido
a que, son base fundamental para la programación e instanciamiento final de
nuestro proyecto.
Está de más mencionar que el documento cuenta con las especificaciones
solicitadas por el profesor.

Objetivo:
Construir un microprocesador que con una ruta de datos y unidad de control en
vhdl de 8 bits capaz de realizar múltiples operaciones lógicas y aritméticas sin que
se desperdicien datos anteriores para poder aplicar alguna otra operación con
ayuda de multiples bloques que se mostraran a continuación:
Desarrollo:
La ruta de datos de un microprocesador, es una parte fundamental del mismo para
la programación en VHDL.
La ruta de datos, se compone de diferentes bloques, cada uno de ellos, con una
tarea específica y fundamental para el correcto funcionamiento de la máquina. Los
bloques contenidos en ella, serán descritos a continuación:

1.- BANCO DE REGISTROS


Arreglo de cero a siete que contiene vectores lógicos de tamaño de 1 byte.
Contiene registros sobre los cuales se puede escribir. Este bloque se compone de
cinco entradas y dos salidas:
Cada registro se va actualizando por los estados de presente a futuro y de futuro a
presente a continuación se pude ver el código y en la figura 1 se muestra el banco
de registros:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity BR_TOP is
port(
D: in unsigned (7 downto 0);
DA,AA,BA: in std_logic;
clk,RW: in std_logic; --actializa cada registro
salA,salB: out unsigned(7 downto 0)

);
end entity BR_TOP;

architecture una of BR_top is


signal r0_reg,r1_reg,ba_reg,bb_reg:unsigned(7 downto 0);
signal r0_next,r1_next,ba_next,bb_next:unsigned (7 downto 0);

begin
-- Actualizar registros con clk, reset
process(clk)
begin
if (clk'event and clk='1') then
r0_reg <= r0_next;
r1_reg <= r1_next;
ba_reg <= ba_next;
bb_reg <= bb_next;
end if;
end process;

-- Asignaciones a ***_next
process ( ba_reg,bb_reg,BA,AA,DA,D,r0_reg,r1_reg,RW) is
begin
r0_next <= r0_reg;
r1_next <= r1_reg;
ba_next <= ba_reg;
bb_next <= bb_reg;

if RW <='1' then --si es 1 escribe dato en registro


if DA <='0' then
r0_next <= D; --entrada D
else
r1_next<=D;

end if;
else
null;
end if;

if AA <='0' then
ba_next <=r0_reg;
else
ba_next<=r1_reg;
end if;

if BA <='0' then
bb_next <=r0_reg;
else
bb_next<=r1_reg;
end if;

end process;

-- Salidas
process (ba_reg,bb_reg) is
begin
salA <= ba_reg;
salB <= bb_reg;

end process;
end architecture una;
Figura.1

2.- MULTIPLEXOR B
A través de él, se da el paso al conjunto de bit’s que servirán como dirección para
la memoria. Contiene tres entradas y una salida como se puede ver a continuación
el código y en la figura 2 se muestra el multiplexor:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity MUXB_TOP is
port(
R: in unsigned(7 downto 0); --entrada del relleno de ceros
B: in unsigned(7 downto 0); --entrada del banco de registos
MB: in std_logic; --selector
SALMUXB: out unsigned( 7 downto 0) --salida que conecta memoria y alu.
);
end entity MUXB_TOP ;

architecture una of MUXB_TOP is


begin
with MB select
SALMUXB <= B when'0', --dato externo
R when'1';

end architecture una;


Figura. 2

3.- ALU(unidad aritmética lógica)

Bloque fundamental de nuestra máquina, ejecuta operaciones lógicas y aritméticas


con los datos provenientes del banco de registros. Contiene tres entradas y dos
salidas, A y B para realizar operaciones. En la figura 3 se puede observar el
circuito de nuestra alu.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity ALU_TOP is
port(
A,B:in unsigned(7 downto 0);
ope:in unsigned(2 downto 0); --selector
salalu:out unsigned(7 downto 0);
FC:out bit --activa el acarreo
);

end entity ALU_TOP;

architecture una of ALU_TOP is

begin

Process (ope, A, B)is


begin
FC <= '0';
case ope is
when "000" =>
salalu <= A and B;
when "001" =>
salalu <= A or B;
when "010" =>
salalu <= A xor B;
when "011" =>
salalu <= not A;
when "100" =>
salalu <= A SLL 1; --desplazamiento a la izquierda
when "101" =>
salalu <= B SRL 1; --desplazamiento a al derecha
when "110" =>
salalu <= A - B;
when others=>
salalu<=A+B;
if ((A(7)='1' AND B(7)='1')AND (A(6)='1' AND B(6)='1')) THEN
FC<='1';
ELSE
FC<='0';
END IF;
end case;
end process;

Figura. 3
4.- MEMORIA
Se utilizó una memoria ram 8x8 para poder leer y escribir los datos para las
direcciones de entrada y salida para poder ingresar datos. En la figura se puede
ver el circuito de nuestra memoria.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ram8x8_TOP is
port(
a:in Unsigned(2 downto 0);
oe,we: in std_logic;
din: in unsigned(7 downto 0);
dout: out unsigned(7 downto 0)
);

end entity ram8x8_TOP;

architecture una of ram8x8_TOP is


type arregloram is array (7 to 0)of
unsigned(7 downto 0);
signal miram: arregloram; --
begin
process(a,din,oe,we,miram)is
begin
if oe='0' and we='1' then --lectura
dout <= miram(to_integer (a)); --señal
else
dout <= (others => 'Z');
end if;

if we='0' and oe='1' then --escritura

miram(to_integer(a))<= din; --direntrada


end if;

if we='0' and oe='0' then


dout <= miram(to_integer(a)); --señal
end if;
end process;
end architecture una;
Figura. 4

5. MULTIPLEXOR D
Se usa de igual forma el mismo multiplexor B solo que en este se añaden una
salida de la unidad aritmética lógica y otra salida de datos el código es el siguiente
y en la figura 5 se pude observar el circuito.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity MUXD_TOP is
port(
salalu, saldatos: in unsigned(7 downto 0); --salida del alu y salida de datos
MD: in std_logic; --selecor
SALMUXD: out unsigned( 7 downto 0) --salida del multiplexor D
);
end entity MUXD_TOP ;

architecture una of MUXD_TOP is


begin
with MD select
SALMUXD <= salalu when'0',
saldatos when'1';

end architecture una;

Figura. 5
6.- INSTANCIAMIENTO DE RUTA DE DATOS

Se llevó a cabo el Instanciamiento interno de nuestra ruta de datos uniendo cada


una de las etapas anteriores como el banco de registros, multiplexor B, la unidad
aritmética lógica, memoria ram 8x8 y el multiplexor D, y creando señales para la
conexión entre cada uno de los componentes que los conforman la cual, fue de la
siguiente manera:

En la figura 6 se puede observar la unión de cada uno de los componentes que


tiene nuestra ruta de datos:
Figura 6

La siguiente parte que se realizo fue la unidad de control la cual está constituida
por un oscilador, un contador, una memoria de instrucciones (memoria rom8x8) y
un descodificador de instrucciones que a continuación se mostraran:

1.- OSCILADOR Y CONTADOR

Las entradas son nuestro clk y reset y nuestra salida la pusimos con la variable
“b”. Conforme nuestro oscilador vaya produciendo señales va ir funcionando
nuestro contador y a la vez va ir cambiando cada estado.

En nuestro caso ocupamos 7 estados y conforme vayan ejecutándose cada


estado nos va a mostrar a la salida que es de 3 bits y esta a su vez va hacer la
entrada de nuestra memoria de instrucciones. Como se puede observar en el
siguiente código. En la figura 7 se muestra su circuito.

port(
rst, clk : in std_logic;
b : out std_logic_vector (2 downto 0));

end entity conta_top;


architecture una of conta_top is
type states is (E0,E1,E2,E3,E4,E5,E6,E7);
signal wait_gen: states;
signal clk2 : std_logic;
begin
inicio: process (clk2, rst)
begin
if rst = '1' then wait_gen <= E0;
elsif rising_edge (clk2) then
case wait_gen is
when E0 => wait_gen <= E1;
when E1 => wait_gen <= E2;
when E2 => wait_gen <= E3;
when E3 => wait_gen <= E4;
when E4 => wait_gen <= E5;
when E5 => wait_gen <= E6;
when E6 => wait_gen <= E0;
when others => wait_gen <= E0;
end case;

Figura .7

2.- MEMORIA DE INSTRUCCIONES

En la memoria de instrucciones (memoria rom) vamos a tener las instrucciones a


realizar que en nuestro casa van hacer 8 instrucciones de 8 bits y se van ir
ejecutando conforme al contador.
La salida de nuestra memoria va ser la entrada de nuestro descodificador.
En el siguiente código se pude ver parte de nuestra memoria. En la figura 8 se
puede observar su circuito.

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;

entity mem_top is

port(
ad: in std_logic_vector(2 downto 0);
instru: out std_logic_vector(7 downto 0);
oe: in std_logic;
cs: in std_logic
);
end entity mem_top;

architecture una of mem_top is


type arregloROM is array (0 TO 7) of std_logic_vector(7 downto 0);

--Forma de declarar constante


constant miROM: arregloROM
:=("00001000","00000111","00000110","00000101","00000100","00000011","00000010","000000
01");

Figura 8

3.- DESCODIFICADOR DE INSTRUCCIONES

El descodificador está compuesto por una entrada y una salida y como su nombre
lo dice nos va a convertir un dato en binario de 8 bits a una salida de 14 bits, que
la salida será nuestra palabra de control la cual va ir activando cada bit
correspondiente a la ruta de datos y cada palabra de control será una instrucción.
Como se podrá observar a continuación el código. En la figura 9 se verá su
circuito.

entity descodificador_top is
port(

entrada: in std_logic_vector(7 downto 0);


salida: out unsigned (13 downto 0));
end descodificador_top ;

architecture una of descodificador_top is


begin

with entrada select


salida<= "00000000000000" when "00000001",--ingresamos dato
"00001000011000" when "00000010", --guarda dato en memoria
"00000100011000" when "00000011", --lee dato
"00000001111000" when "00000100", --operacion suma
"00000101111000" when "00000101",
"00000001001000" when "00000110", --operacion or
"00000101001000" when "00000111",
"00000001001001" when others; --dezplazamiento a la
izquierda
end una;

Figura 9

En la figura 10 se observara el diagrama de nuestra unidad de control.


Figura 10

Por último se mostrara el instanciamiento de nuestra unidad de control con la ruta


de datos, como se observara en el siguiente código. En la figura 11 se observara
el diagrama de nuestro procesador el vual incluye su unidad de control y su ruta
de datos.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity process_top is
port(
rst, clk : in std_logic;
oe,cs: in std_logic;
Din: in unsigned(7 downto 0);
SAL:out unsigned(7 downto 0);
FC:out bit
);

end entity process_top;

architecture una of process_top is

signal salida: unsigned (13 downto 0);


begin

u1:work.conme_top(una)
port map(rst=>rst, clk=>clk, oe=>oe,cs=>cs, salida=>salida );
u2:work.ruta_top(una)
port map(clk=>clk, Rw=>salida(8),Dir=>salida(13 downto
11),oe=>salida(10),we=>salida(9),Da=>salida(0),Aa=>salida(1),Ba=>salida(2),MB=>salida(3),MD
=>salida(7),R=>Din,ope=>salida(6 downto 4), SAL=>SAL,FC=>FC);

end una;
Figura 11

En la figura 12 se mostrara la simulación de nuestro procesador el cual va a


realizar tres operaciones las cuales serán una suma, una operación lógica OR y
un desplazamiento a la izquierda. El dato a ingresar será un 4 en binario y va
hacer la suma por el mismo número el cual nos dará un resultado de 8 en binario,
después realizara la operación OR con el dato numero 4 el cual nos dará un 12 en
binario y a este resultado por ultimo le realizara un desplazamiento a la izquierda
lo cual nos dará como resultado un 24 en binario.

En la parte izquierda se observara nuestras entradas que serán clk, oe, cs, reset y
nuestro dato de entrada, también estarán lo que son nuestras salidas como FC
(bandera de acarreo) y nuestra salida externa en la cual se van ir mostrando los
resultados de cada operación hecha.
Figura 12
Comentarios:
La ruta de datos es una parte fundamental para poder nuestro propio procesador
con las especificaciones e instrucciones que se nos puedan asignar. Lo que
genera algunas complicaciones es el banco de registro, asignar las direcciones
correctamente y como poder manipularla con la unidad de control dentro del
mismo procesador. Lo que vimos que nos faltó hacer es que en el banco de
registros se guardara cada dato en cada uno de los registros y en nuestro caso se
guardaba en paralelo el dato en los dos registros que teníamos.

Referencias:
Tal y como se dice en Fundamentos de diseño lógico y de computadoras (Morris
Mano, 2005) La ALU es una parte fundamental para el desarrollo de una ruta de
datos porque es un circuito digital que calcula operaciones aritméticas y
operaciones lógicas, entre valores de los argumentos.

Das könnte Ihnen auch gefallen