microprocesador basico 8 bits - fpga.pdf
TRANSCRIPT
UNIVERSIDAD NACIONAL DE RIO CUARTO
FACULTAD DE INGENIERIA
TRABAJO PRÁCTICO FINAL
PROGRAMACION LÓGICA PARA INGENIERIA - 469
“MICROPROCESADOR BASICO DE 8 BITS”
Oggier Germán Elías - 34414615
Cardozo Hernán - 32095939
AÑO: 2012
Microprocesador Básico de 8 bits
CONTENIDOS
INTRODUCCION 1
COMPONENTES, CODIGO VHDL Y SIMULACION 3
PUERTO DE ENTRADA 3
SIMULACION DEL PUERTO DE ENTRADA 4
MEMORIA RAM 32X8 5
SIMULACION DE RAM 32X8 8
PC – PROGRAM COUNTER 9
SIMULACION DEL PC 10
ALU-ACUMULADOR 11
SIMULACION ALU_ACUMULADOR 13
IR - REGISTRO DE INSTRUCCIÓN 14
SIMULACION DEL IR 15
PUERTO DE SALIDA 16
SIMULACION PUERTO SALIDA 17
UC - UNIDAD DE CONTROL 18
SIMULACION UC 24
TRATAMIENTO DEL CLOCK 26
DSM 26
PRESCALER 26
SIMULACION PRESCALER 26
GENERADOR_CLOCK 27
SIMULACION GENERADOR_CLOCK 27
TOP LEVEL 28
Simulación Top LEVEL, Seguimiento de los Estados 31
Esquemático Top Level 35
CONEXIÓN DE LA FPGA 36
CONCLUSION 37
BIBLIOGRAFIA CONSULTADA 38
Microprocesador Básico de 8 bits
[Escribir texto] Página 1
INTRODUCCION
El presente trabajo final tiene como objetivo realizar un microprocesador básico de 8 bits (1 byte), el cual
consta de los siguientes componentes síncronos:
1- Puerto de Entrada
2- Memoria RAM de programa y datos
3- Unidad aritmético lógica con acumulador
4- PC – Contador de programa
5- IR – Registro de instrucción
6- Puerto de salida
7- Unidad de control
Estos comparten un único bus de direcciones por el que se intercambian datos y son coordinados por la
unidad de control.
El microprocesador debe ser capaz de ejecutar las siguientes instrucciones:
Dirección de memoria donde
buscar almacenar el dato
Load 000
Store 001
Add 010
Sub 011
Jzn 100
Jmp 101
Outport 110
Inport 111
Microprocesador Básico de 8 bits
[Escribir texto] Página 2
Microprocesador Básico de 8 bits
[Escribir texto] Página 3
COMPONENTES, CODIGO VHDL Y SIMULACION
A continuación se analizaran cada componente por separado y finalmente se realizara la Unidad
de Control que los coordinara y el top level que los conectara.
PUERTO DE ENTRADA library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Puerto_entrada is
Port ( swich_0 : in STD_LOGIC;
swich_1 : in STD_LOGIC;
swich_2 : in STD_LOGIC;
swich_3 : in STD_LOGIC;
bus_micro : inout STD_LOGIC_VECTOR (7 downto 0);
clock : in STD_LOGIC;
reset : in STD_LOGIC;
cargar_bus : in STD_LOGIC);
end Puerto_entrada;
architecture Behavioral of Puerto_entrada is
signal entrada: std_logic_vector (7 downto 0):= "00000000";
begin
bus_micro <= entrada when cargar_bus = '1' else (others => 'Z') ;
process (reset, clock, swich_0,swich_1,swich_2,swich_3)
variable entrada_aux: std_logic_vector (7 downto 0):= "00000000";
begin
if reset = '1' then
entrada_aux := "00000000";
elsif (clock'event and clock = '1') then
entrada_aux(7):= '0' ;
entrada_aux(6):= '0' ;
entrada_aux(5):= '0' ;
entrada_aux(4):= '0';
entrada_aux(3):= swich_3 ;
entrada_aux(2):= swich_2 ;
entrada_aux(1):= swich_1 ;
entrada_aux(0):= swich_0 ;
end if ;
entrada <= entrada_aux ;
end process ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 4
La entidad del Puerto de entrada consta de 8
entradas y una salida que es el Bus_micro, este es un Std
logic vector de 8 bits
En la arquitectura se crea una señal llamada
“entrada” de 8 bits que será la que se asignara al Bus
cuando la unidad de control haga llegar un 1 por la
entrada cargar_bus
Si cargar_bus no está en 1, la salida Bus_micro se
pondrá en alta impedancia (Z) que equivale a
desconectar la entidad del bus.
Se crea un Process sensible al clock, reset y a las 5
entradas provenientes de la FPGA.
Dentro del Process se crea una variable llamada “entrada_aux” de 8 bits la cual se pondrá en
“00000000” si el puerto de entrada se encuentra en reset, pero si no es así y además hay un flanco
ascendente del clock los 3 bits más significativos se pondrán en „0‟ mientras que los otros 5 serán las 5
entradas .
Luego esta variable “entrada_aux” se le asigna a la señal entrada que se utiliza como ya se
menciono.
SIMULACION DEL PUERTO DE ENTRADA
Se le da un „1‟ al swich_0 y al swich_2, pero no serán enviadas al bus hasta que a los 150 ns cargar_bus =
„1‟. Luego, a los 200ns esta señal se le da un „0‟ y el componente ya no tiene conexión con el Bus.
Microprocesador Básico de 8 bits
[Escribir texto] Página 5
MEMORIA RAM 32X8 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity RAM is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
ce : in STD_LOGIC;
lectura_ram : in STD_LOGIC;
cargar_dir : in STD_LOGIC;
cargar_dat : in STD_LOGIC;
bus_micro : inout STD_LOGIC_VECTOR (7 downto 0));
end RAM;
architecture Behavioral of RAM is
type memory is array (0 to 31) of std_logic_vector (7 downto 0);
signal ram_leida : std_logic_vector (7 downto 0);
signal ram328 : memory;
begin
bus_micro <= ram_leida when lectura_ram = '1' else (others => 'Z') ;
process (clock, reset, ce, cargar_dir,cargar_dat, bus_micro)
variable reg_dir : std_logic_vector (7 downto 0);
variable reg_dat : std_logic_vector (7 downto 0);
begin
ram328(0)<= "00000111";
ram328(1)<= "11101000";
ram328(2)<= "01001000";
ram328(3)<= "00101001";
ram328(4)<= "11001001";
ram328(5)<= "10001010";
ram328(6)<= "10101011";
ram328(7)<= "00000000";
--ram328(8)<= "00000001";
--ram328(9)<= "00000000"; -- sera escrita luego por el resultado de la ALU_acum
ram328(10)<="00000001";
ram328(11)<="00000000";
ram328 (12 to 31) <= (others => "00000000");
if reset = '1' then
reg_dir := "00000000";
reg_dat := "00000000";
elsif (ce = '1' and clock'event and clock = '1') then
if cargar_dir = '1' then
reg_dir := bus_micro;
Microprocesador Básico de 8 bits
[Escribir texto] Página 6
ram_leida <= ram328(conv_integer(reg_dir));
end if;
if cargar_dat = '1' then
reg_dat := bus_micro;
IF REG_DIR = "00001000" THEN
ram328(8) <= reg_dat;
ELSIF REG_DIR = "00001001" THEN
ram328(9) <= reg_dat;
end if;
END IF;
end if;
end process;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 7
La entidad de la RAM consiste en 9 entradas:
-Cargar datos
-Cargar dirección
-ce: Chip Enable
-Lectura_ram
-reset
-Clock
Y un Bus INOUT que es el Bus_micro de 8 bits
En la arquitectura se crea una señal llamada “ram_leida” de
8 bits cuyo contenido se especifica luego y que se cargara al
Bus_micro cuando la señal lectura ram = „1‟.
Se crea una señal llamada ram328 del tipo memoria, este tipo es un arreglo de 32 vectores estándar
logic de 8 bits en el que los primeros 7 filas del arreglo corresponden al programa (opcode + dirección),
los siguientes 5 a los datos y al resto se les asigna “00000000”.
Se crea un Process sensible al clock, reset, chip Enable, cargar dirección y Bus_micro.
Dentro del Process se crea una variable llamada reg_dir (registro de dirección) a la cual se le asignara el
byte presente en el Bus_micro cuando la señal cargar_dir = „1‟. Luego, El byte que se encuentre en esa
dirección indicada por el registro de dirección se le asignara a la señal ram_leida.
Se crea también una variable llamada reg_dat a la cual se le asignara el byte presente en el Bus_micro
cuando la señal cargar_dat = „1‟. El byte que se almaceno en reg_dat se cargara a la posición 9 de la
RAM, este dato es el proveniente del acumulador.
Lo explicado en los dos párrafos previos tienen lugar si hay un flanco ascendente del clock y si el chip
enable = „1‟.
Si reset = „1‟ entonces tanto reg_dat como reg_dir serán “00000000”.
Microprocesador Básico de 8 bits
[Escribir texto] Página 8
SIMULACION DE RAM 32X8
A los 100ns se le asigna al Bus_micro el byte “00000011” (3), al asignarle un „1‟ a las señales ce y cargar_dir,
a la variable Ram_leida se le asignara el byte que se encuentra en dicha posición.
A los 220ns, Lectura_ram = „1‟ por lo que se le asigna al Bus_micro lo que se almaceno en la variable
Ram_leida, si se observa en el código VHDL en la posición 3 se encontraba el byte “00101001”.
A los 320ns, se le asigna al Bus_micro el byte “00001101” suponiendo que este es el byte proveniente del
acumulador, al hacer cargar_dat = „1‟, este valor será almacenado en la posición 9 de la RAM.
Para corroborar lo expuesto en el párrafo anterior, a los 420ns se le asigna al Bus_micro el byte “00001001”
(9) y al hacer cargar_dir = „1‟, se le asignara a la variable Ram_leida el byte que se encuentre en la
posición 9. Al hacer luego Lectura_ram = „1‟ , se le asigno al Bus_micro el valor “00001101” que se
esperaba.
Al hacer finalmente Lectura_ram = „0‟, se desconecta la RAM del Bus.
Microprocesador Básico de 8 bits
[Escribir texto] Página 9
PC – PROGRAM COUNTER library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
entity PC is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
cargar_pc_bus : in STD_LOGIC;
CARGAR_BUS_PC : in STD_LOGIC;
incrementar : in STD_LOGIC;
Bus_micro : inout STD_LOGIC_VECTOR (7 downto 0));
end PC;
architecture Behavioral of PC is
signal contador: std_logic_vector (7 downto 0) ;
begin
bus_micro <= contador when cargar_pc_bus = '1' else (others => 'Z') ;
process (reset, clock, incrementar, CARGAR_BUS_PC, BUS_MICRO)
variable contador_aux: integer ;
begin
IF CLOCK'EVENT AND CLOCK='1' THEN
IF INCREMENTAR = '1' THEN
CONTADOR_AUX := CONTADOR_AUX+1;
ELSIF CARGAR_BUS_PC = '1' THEN
CONTADOR_AUX := CONV_INTEGER(BUS_MICRO);
ELSIF RESET = '1' THEN
CONTADOR_AUX := 0 ;
END IF;
END IF;
CONTADOR<= CONV_STD_LOGIC_VECTOR(CONTADOR_AUX, 8);
end process ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 10
La entidad del PC consta de 5 entradas y del Bus_micro que
es INOUT de 8 bits.
En la arquitectura se crea una señal llamada “contador” de 8
bits inicializado en y cuyo contenido será asignado al
Bus_micro cuando la señal cargar_pc_bus = „1‟.
Se crea un Process
Se crea dentro del Process la variable contador_aux de tipo
integer
Si hay un flanco ascendente del clock y si la señal incrementar = „1‟ entonces a la señal contador_aux se
le suma 1. Pero si CERGAR_BUS_PC = „1‟ , la cuenta pasara a ser la indicada por el bus.
Si reset = „1‟ , entonces contador_aux = 0.
Luego, Finalmente contador_aux se convierte en tipo std_logic_vector y se asigna a la señal contador la
cual saldrá al bus de acuerdo a lo explicado anteriormente.
SIMULACION DEL PC
A los 0.00 µs reset = „1‟ inicializando la cuenta en 0.
A los 0.01µs, reset= „0‟, incrementar = „1‟ y cargar_pc_bus = „1‟ por lo que comenzara a contar y a mostrar
en el bus por cada ciclo de clock hasta que reciba una señal cargar_bus_pc = „1‟ y se deje de
incrementar.
Al ocurrir esto, La cuenta tomara automáticamente el valor que tiene el dato en el bus, en el caso
simulado, se carga 00000001, valor que será utilizado luego en la instrucción JZN, y la cuenta seguirá a
partir de dicho valor.
Se pone en Alta impedancia el bus para que no tenga conflictos al seguir mostrando la cuenta a los
0.10µs donde cargar_pc_bus = „1‟
Microprocesador Básico de 8 bits
[Escribir texto] Página 11
ALU-ACUMULADOR
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all; --para sumar y restar con std_logic_vector
entity ALU_ACUM is
Port ( BUS_micro : inout STD_LOGIC_vector (7 downto 0);
OPCODE_ALU : in std_logic ;
RESET : in STD_LOGIC;
operar: in STD_LOGIC;
bus_acum : in std_logic ;
alu_bus : in std_logic ;
z_flag: out STD_LOGIC;
CLOCK : IN std_logic);
end ALU_ACUM;
architecture Behavioral of ALU_ACUM is
signal acum_aux : STD_LOGIC_vector(7 downto 0) ;
begin
bus_micro <= acum_aux when alu_bus = '1' else (others => 'Z') ;
z_flag <= '1' when acum_aux="00000000" else '0';
process (clock, reset, opcode_alu, bus_acum, operar )
variable acum : STD_LOGIC_vector(7 downto 0) ;
begin
if reset = '1' then
acum := "00000000" ;
elsif (clock'event and clock= '1') then
if bus_acum = '1' then
acum := bus_micro;
end if ;
if operar = '1' then
if opcode_alu = '0' then
acum := bus_micro + acum ;
elsif opcode_alu = '1' then
acum := acum - bus_micro;
end if;
end if;
end if;
acum_aux <= acum;
end process ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 12
La entidad del Alu_Acum, consta de 6 entradas y dos salidas, una de
ella es z_flag, es un indicador del estado del acumulador y además el
Bus_micro que es INOUT.
La señal OPCODE_ALU establece que operación realizara la ALU, en
nuestro caso la ALU realiza solo dos operaciones, suma („0‟)y resta
(„1‟).
En la arquitectura se crea una señal llamada “acum_aux” de 8 bits
cuyo contenido será asignado al Bus_micro cuando la señal alu_bus =
„1‟.
Siempre que acum_aux = “00000000”, z_flag = „1‟.
Se crea un Process sensible al clock, reset, opcode_alu, bus_acum y operar.
Dentro del Process se crea una variable llamada acum (Acumulador) a la cual se le asignara el byte
presente en el Bus_micro cuando la señal bus_acum = „1‟. De este modo se ha cargado el acumulador
con lo que estaba en el Bus que puede ser, por ejemplo, el dato leído desde la RAM.
Si bus_acum no está mas en „1‟ y la señal operar = „1‟ entonces el OPCODE_ALU dirá si se suma o se resta
el byte presente en el acumulador con el byte presente en el Bus_micro.
La señal operar evita que la ALU siga operando por cada flanco ascendente de clock, ya que las
operaciones se realizan dentro de un Process sensible al clock.
Si reset= „1‟, entonces el acumulador = “00000000”.
Antes de finalizar el Process se le asigna a la señal acum_aux lo que se encuentra en acum.
Microprocesador Básico de 8 bits
[Escribir texto] Página 13
SIMULACION ALU_ACUMULADOR
A los 10ns, reset = „1‟ y aunque la variable acum no saldrá al Bus_micro se puede apreciar esta situación
porque el z_flag = „1‟.
A los 110ns, reset = „0‟ y bus_acum =‟1‟, de este modo, el byte que se encontraba en el Bus_micro, en este
caso “00000111” (7) se introducirá en el acumulador a través de la variable acum,
A los 130ns, bus_acum =‟0‟ por lo que el acumulador no tomara más datos del Bus y este toma el valor de
“00000001” (1).
A los 310ns operar = „1‟ y OPCODE_ALU se encontraba en „1‟ por lo que se realizara la resta 7-1, (7 del
acumulador con 1 del Bus).
A los 330ns, previo a haber dejado el Bus en alta impedancia para evitar conflictos, alu_bus = „1‟ por lo
que el resultado (6) es enviado al Bus_micro.
Finalmente a los 380ns alu_bus = „0‟ por lo que el componente se desconecta del Bus.
Microprocesador Básico de 8 bits
[Escribir texto] Página 14
IR - REGISTRO DE INSTRUCCIÓN library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity IR is
Port ( CLOCK : in STD_LOGIC;
RESET : in STD_LOGIC;
CARGAR_IR_BUS : in STD_LOGIC;
CARGAR_BUS_IR : in STD_LOGIC;
BUS_MICRO : inout STD_LOGIC_VECTOR (7 downto 0);
OPCODE : out STD_LOGIC_VECTOR (2 downto 0));
end IR;
architecture Behavioral of IR is
signal DIRECCION : STD_LOGIC_VECTOR (7 downto 0) := "00000000";
signal DATO : STD_LOGIC_VECTOR (7 downto 0) := "00000000";
begin
BUS_MICRO <= DIRECCION when CARGAR_IR_BUS = '1' else (others => 'Z') ;
DATO <= BUS_MICRO when CARGAR_BUS_IR = '1' ;
PROCESS(CLOCK, RESET, DATO)
BEGIN
IF RESET = '1' THEN
OPCODE <= "000" ;
DIRECCION <= "00000000" ;
ELSIF ( clock'event and clock= '1') then
OPCODE (2) <= DATO(7) ;
OPCODE (1) <= DATO(6) ;
OPCODE (0) <= DATO(5) ;
DIRECCION (7) <= '0' ;
DIRECCION (6) <= '0' ;
DIRECCION (5) <= '0' ;
DIRECCION (4) <= DATO(4) ;
DIRECCION (3) <= DATO(3) ;
DIRECCION (2) <= DATO(2) ;
DIRECCION (1) <= DATO(1) ;
DIRECCION (0) <= DATO(0) ;
END IF;
END PROCESS;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 15
La entidad del registro de instrucción consta de 4
entradas y dos salidas, una de ellas es el OPCODE de 3 bits es
el que será luego conectado a la unidad de control, la otra
salida es el Bus_micro, que es INOUT, ya que de el se tomara
el byte para ser almacenado en la señal DATO y hacia el se
dirijira la señal DIRECCION que luego será leida por el puerto
de direcciones de la RAM.
En la arquitectura se crea una señal llamada “DIRECCION”
de 8 bits cuyo contenido será asignado al Bus_micro cuando
la señal CARGAR_IR_BUS= „1‟.
Se crea también una señal llamada “DATO” al cual se le asignara el byte que se encuentre en el
Bus_micro cuando la señal CARGAR_BUS_IR = „1‟.
Se crea un Process sensible al CLOCK, RESET y DATO.
Luego si RESET = „1‟ entonces se le asignara un “000” a OPCODE y un “00000000” a DIRECCIÓN.
Si RESET = „0‟ y además hay un flanco ascendente del CLOCK, se le asignara a OPCODE los 3 bits más
significativos de la señal DATO, y a DIRECCION los 5 bits menos significativos de dicha señal.
SIMULACION DEL IR
Se le asigna al Bus_micro el byte “00100011” simulando asi que este es el proveniente de la
memoria RAM. Como la señal CARGAR_BUS_IR = „1‟, este byte será almacenado en la señal DATO, ya
puede observarse que el OPCODE es “001” que son los 3 bits más significativos.
La señal DIRECCION no será enviada al Bus_micro hasta que a los 120ns la señal CARGAR_IR_BUS =
„1‟ , previo a realizar esto el Bus_micro debió haber estado almenos un instante en alta impedancia para
evitar conflictos.
A los 320ns CARGAR_IR_BUS = „0‟ por lo que el componente se desconectara del Bus.
Microprocesador Básico de 8 bits
[Escribir texto] Página 16
PUERTO DE SALIDA library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Puerto_Salida is
Port ( Bus_micro : in STD_LOGIC_VECTOR (7 downto 0);
bus_a_salida : in STD_LOGIC;
salida_micro : out STD_LOGIC_VECTOR (7 downto 0);
reset : in STD_LOGIC;
clock : in STD_LOGIC);
end Puerto_Salida;
architecture Behavioral of Puerto_Salida is
signal salida: std_logic_vector (7 downto 0);
begin
salida_micro <= salida when bus_a_salida = '1' else (others => 'Z');
process(clock, reset, Bus_micro)
begin
if reset = '1' then
salida <= "00000000" ;
elsif (clock'event and clock = '1') then
salida <= Bus_micro ;
end if ;
end process ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 17
La entidad del Puerto de salida consta de 4 entradas y
una salida que es la salida del microprocesador.
El Bus_micro forma parte en este caso de la entrada.
En la arquitectura se crea una señal llamada “salida” de 8 bits
cuyo contenido será asignado a salida_micro cuando la señal
bus_a_salida = „1‟.
Se crea un Process sensible al clock, reset, y Bus_micro .
Si reset= „1‟ se le asignara un “00000000” a la señal salida, pero si reset = „0‟ y además hay un flanco de
clock ascendente se le asignara a salida lo que se encuentra en Bus_micro.
SIMULACION PUERTO SALIDA
Primero se carga Bus_micro el byte “00000111”, como bus_a_salida =‟1‟ este byte será expuesto a
la salida_micro,
A los 100ns se realiza una prueba del reset y como bus_a_salida sigue en „1‟ entonces en salida_micro se
expondrá un “00000000”,
A los 200ns la señal de reset = „0‟ y de ese modo la salida_micro expone nuevamente lo que se encuentra
en un bus.
A los 300ns la señal bus_a_salida=‟0‟ por lo que el componente se desconecta de la salida del
microprocesador.
Microprocesador Básico de 8 bits
[Escribir texto] Página 18
UC - UNIDAD DE CONTROL library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity UC is
Port ( opcode : in STD_LOGIC_VECTOR (2 downto 0);
z_flag : in STD_LOGIC;
clock : in STD_LOGIC;
reset : in STD_LOGIC;
--PUERTO_ENTRADA
cargar_bus : out STD_LOGIC;
--RAM
cargar_dat : out STD_LOGIC;
cargar_dir : out STD_LOGIC;
lectura_RAM : out STD_LOGIC;
ce : out STD_LOGIC;
--PC
CARGAR_BUS_PC : out STD_LOGIC;
cargar_PC_BUS : out STD_LOGIC;
incrementar : out STD_LOGIC;
--ALU_ACUM
alu_bus : out STD_LOGIC;
bus_acum : out STD_LOGIC;
opcode_alu : out STD_LOGIC;
operar : out STD_LOGIC;
--IR
cargar_bus_IR : out STD_LOGIC;
cargar_IR_bus : out STD_LOGIC;
-- PUERTO DE SALIDA
bus_a_salida : OUT STD_LOGIC);
end UC;
architecture Behavioral of UC is
--LOS SIGUIENTES ESTADOS SERAN EJECUTADOS PARA FLANCOS DESCENDENTES DE CLOCK
--PARA QUE LOS DISPOSITIVOS QUE UTILICEN LAS SEÑALES EMITIDAS POR ESTE COMPONENTE
--CUANDO TIENEN UN FLANCO ASCENDENTE YA TENGAN PREVIO A ESE MOMENTO ESTAS SEÑALES EN 1
type ESTADOS is ( ESTADO_RESET,
ESTADO_1,-- PC-->BUS ,
ESTADO_2,-- DESCONECTA
ESTADO_3,-- RAM-->IR
ESTADO_4,-- DESCONECTA
ESTADO_5, --IR->RA,M
ESTADO_6,--DESCONECTA
ESTADO_LOAD_A,
ESTADO_LOAD_B,
ESTADO_STORE_A,
ESTADO_STORE_B,
ESTADO_ADD_A,
ESTADO_ADD_B,
ESTADO_SUB_A,
ESTADO_SUB_B,
ESTADO_JZN_A,
ESTADO_JZN_B,
Microprocesador Básico de 8 bits
[Escribir texto] Página 19
ESTADO_JMP_A,
ESTADO_JMP_B,
ESTADO_OUTPORT_A,
ESTADO_OUTPORT_B,
ESTADO_INPORT_A,
ESTADO_INPORT_B);
signal estado: ESTADOS;
SIGNAL prox_estado: ESTADOS:= ESTADO_1 ;
begin
----------------------------..:: BLOQUE MEMORIA ::..---------------------------------------
PROCESS (CLOCK, RESET)
begin
if reset = '1' then
estado<= estado_reset;
elsif (clock'event and clock = '0') then -- si hay un flanco descendente
estado <= prox_estado ;
end if;
end process ;
-----------------------..:: BLOQUE FUNCION DE TRANSICION ::..-------------------------------
PROCESS (ESTADO, opcode)
begin
case estado is
when estado_reset =>
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_1 =>
cargar_pc_bus <= '1' ;
ce <= '1' ;
cargar_dir <= '1' ;
PROX_ESTADO <= ESTADO_2 ;
when ESTADO_2 =>
cargar_dir <= '0' ;
ce <= '0' ;
Microprocesador Básico de 8 bits
[Escribir texto] Página 20
cargar_PC_BUS <= '0' ;
incrementar <= '1' ;
PROX_ESTADO <= ESTADO_3 ;
when ESTADO_3 =>
incrementar <= '0' ;
lectura_RAM <= '1' ;
cargar_bus_IR <= '1' ;
PROX_ESTADO <= ESTADO_4 ;
when ESTADO_4 =>
lectura_RAM <= '0' ;
cargar_bus_IR <= '0' ;
PROX_ESTADO <= ESTADO_5 ;
when ESTADO_5 => -- EN ESTE ESTADO SE DEFINIRA EL CAMINO A SEGUIR SEGUN EL OPCODE
cargar_IR_bus <= '1' ;
cargar_dir <= '1' ; -- CARGA EN EL PUERTO DE DIRECCIONES DE LA RAM LO QUE
ACOMPAÑA AL OPCODE, ESTO SE UTILIZARA LUEGO
ce <= '1' ;
PROX_ESTADO <= ESTADO_6 ;
when ESTADO_6 =>
cargar_IR_bus <= '0' ;
cargar_dir <= '0' ;
ce <= '0' ;
CASE OPCODE IS
when "000" => --LOAD (CARGA EL ACUMULADOR CON EL DATO INDICADO POR EL PUERTO DE DIRECCIONES DE LA RAM (MAR))
PROX_ESTADO <= ESTADO_LOAD_A ;
when "001" => --STORE (ALMACENA EL VALOR DEL ACUMULADOR EN LA POSICION INDICADA POR EL MAR)
PROX_ESTADO <= ESTADO_STORE_A ;
when "010" => --ADD (SUMA EL VALOR QUE SE ENCUENTRA EN LA DIRECCION INDICADA POR MAR CON LO QUE ESTA EN EL ACUM)
PROX_ESTADO <= ESTADO_ADD_A ;
when "011" => --SUB (RESTA EL VALOR QUE SE ENCUENTRA EN LA DIRECCION INDICADA POR MAR CON LO QUE ESTA EN EL ACUM)
PROX_ESTADO <= ESTADO_SUB_A ;
when "100" => --JZN (SI LA Z_FLAG = 0 SALTAR A LA DIRECCION DE PROGRAMA INDICADA POR LA MAR)
PROX_ESTADO <= ESTADO_JZN_A ;
when "101" => --JMP (SALTAR A LA DIRECCION DE PROGRAMA INDICADO POR LA MAR)
PROX_ESTADO <= ESTADO_JMP_A ;
when "110" => -- OUTPORT
PROX_ESTADO <= ESTADO_OUTPORT_A ;
when OTHERS => --INPORT
PROX_ESTADO <= ESTADO_INPORT_A ;
END CASE ;
Microprocesador Básico de 8 bits
[Escribir texto] Página 21
when ESTADO_LOAD_A =>
ce<='1';
lectura_RAM <= '1' ;
BUS_ACUM <= '1' ;
PROX_ESTADO <= ESTADO_LOAD_B ;
when ESTADO_LOAD_B =>
ce<='0';
lectura_RAM <= '0' ;
BUS_ACUM <= '0' ;
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_STORE_A =>
ALU_BUS <= '1' ;
CE <= '1';
CARGAR_DAT <= '1';
PROX_ESTADO <= ESTADO_STORE_B ;
when ESTADO_STORE_B =>
ALU_BUS <= '0' ;
CE <= '0';
CARGAR_DAT <= '0';
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_ADD_A =>
ce<='1';
LECTURA_RAM <= '1' ;
OPERAR <= '1' ;
OPCODE_ALU <= '0' ;
PROX_ESTADO <= ESTADO_ADD_B ;
when ESTADO_ADD_B =>
ce<='0';
LECTURA_RAM <= '0' ;
OPERAR <= '0' ;
OPCODE_ALU <= '1' ;
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_SUB_A =>
ce<='1';
LECTURA_RAM <= '1' ;
OPERAR <= '1' ;
OPCODE_ALU <= '0' ;
PROX_ESTADO <= ESTADO_SUB_B ;
when ESTADO_SUB_B =>
Microprocesador Básico de 8 bits
[Escribir texto] Página 22
ce<='0';
LECTURA_RAM <= '0' ;
OPERAR <= '0' ;
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_OUTPORT_A =>
ce<='1';
LECTURA_RAM <= '1';
bus_a_salida <= '1';
PROX_ESTADO <= ESTADO_OUTPORT_B ;
when ESTADO_OUTPORT_B =>
ce<='0';
LECTURA_RAM <= '0';
bus_a_salida <= '0';
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_INPORT_A =>
cargar_bus <= '1';
CE <= '1';
CARGAR_DAT <= '1' ;
PROX_ESTADO <= ESTADO_INPORT_B ;
when ESTADO_INPORT_B =>
cargar_bus <= '0';
CE <= '0';
CARGAR_DAT <= '0' ;
PROX_ESTADO <= ESTADO_1;
when ESTADO_JZN_A =>
IF Z_FLAG = '0' THEN
LECTURA_RAM <= '1' ;
CARGAR_BUS_PC <= '1' ;
PROX_ESTADO <= ESTADO_JZN_B ;
ELSE
PROX_ESTADO <= ESTADO_1 ;
END IF;
when ESTADO_JZN_B =>
LECTURA_RAM <= '0' ;
CARGAR_BUS_PC <= '0' ;
Microprocesador Básico de 8 bits
[Escribir texto] Página 23
PROX_ESTADO <= ESTADO_1 ;
when ESTADO_JMP_A =>
ce<='1';
LECTURA_RAM <= '1' ;
CARGAR_BUS_PC <= '1' ;
PROX_ESTADO <= ESTADO_JMP_B ;
when ESTADO_JMP_B =>
ce<='0';
LECTURA_RAM <= '0' ;
CARGAR_BUS_PC <= '0' ;
PROX_ESTADO <= ESTADO_1 ;
END case ;
END process ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 24
La entidad de la Unidad de Control de 4 entradas y
16 salidas que serán instanciadas luego en el Top Level con
las entradas de los demás componentes
En la arquitectura se crean dos señales, estado y
prox_estado, ellos serán del tipo ESTADO el cual consta de
21 estados, los primeros 5 son comunes a todos los tipos de
instrucción ya son los encargados de realizar la búsqueda y
decodificación de la instrucción.
En el Estado 5, se crea un nuevo CASE el cual
selecciona el camino a seguir de acuerdo al opcode
proveniente del IR. Dichos caminos serán los demás estados,
en los cuales como se observa en el código tienen dos
partes, una A y otra B, la parte B se realiza para desactivar
todas las señales activadas por la parte A y que no se
utilizan en el estado siguiente para asi evitar conflictos
SIMULACION UC
Como se observa, se realizo la simulación para los Opcode referidos a LOAD (“000”) y a OUTPORT (“110”)
En el primer flanco descendente (0 seg) que da inicio al primer periodo que la simulación muestra, la
dirección señalada por el PC se almacena en el puerto de memoria de la RAM .
Durante el segundo periodo, se incrementa el PC
En el tercero se lee de la RAM y se habilita la señal “Cargar_Bus_ir” y de este modo el dato de la RAM
ubicado en la posición indicada en el periodo uno es llevado al IR
Microprocesador Básico de 8 bits
[Escribir texto] Página 25
En el cuarto periodo, el Ir ya habrá decodificado el dato que ingreso en el ciclo anterior y la dirección es
almacenada en el puerto de direcciones de la RAM y el opcode estaría ingresando a la unidad de
control por medio de la entrada “Opcode”, que en este caso fue simulado como “000”
En el quinto Periodo es donde la UC sigue al ESTADO_LOAD_A en donde el dato indicado en el ciclo
anterior es cargado en el acumulador
En el Sexto periodo que sería ESTADO_LOAD_B, se deshabilitan las señales habilitadas en el ciclo anterior.
En el Séptimo inicia una nueva etapa de búsqueda y decodificación y se simula un nuevo opcode “110”
para llegar así en el periodo 15 en donde se ejecuta el ESTADO_OUTPORT_A seguido del
ESTADO_OUTPORT_B en donde se deshabilitan las señales habilitadas en el estado anterior y comienza
nuevamente una nueva etapa de Búsqueda, Decodificación y ejecución de la instrucción.
Microprocesador Básico de 8 bits
[Escribir texto] Página 26
TRATAMIENTO DEL CLOCK Como se pretende que físicamente, osea con la placa en funcionamiento, se logren observar en los
Leds las salidas resultantes del microprocesador es que se deberá reducir la frecuencia del clock, desde
los 50 Mhz al orden de los 6 Hz
Esto se debe hacer en tres etapas y cada una de ellas ejecutada por distintos componentes (DSM,
PRESCALER y GENERADOR_CLOCK, en este orden) que luego serán instanciados en el Top level entre la
entrada de clock del microprocesador al DSM y la salida del GENERADOR_CLOCK a la entrada de clock
de cada componente.
DSM
Es el componente encargado de reducir la señal de clock de 50MHz a 10Mhz, y lo realiza
dividiendo el clock por 10
PRESCALER
Como Prescaler se utiliza un contador binario (binary counter) el cual recibirá del DSM una señal de
Clock a 10Mhz y al contar 250000 de estos ciclos de reloj genera en una de sus salidas llamada “thresh0 “
un pulso que será utilizado luego por el GENERADOR_CLOCK .
SIMULACION PRESCALER
Primer pulso
Microprocesador Básico de 8 bits
[Escribir texto] Página 27
GENERADOR_CLOCK library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity GENERADOR_CLOCK is
Port ( DESDE_PRESCALER : in STD_LOGIC;
CLOCK_GENERADO : out STD_LOGIC);
end GENERADOR_CLOCK;
architecture Behavioral of GENERADOR_CLOCK is
begin
PROCESS (DESDE_PRESCALER)
VARIABLE VAR_CLOCK_GEN: STD_LOGIC := '0';
BEGIN
IF (DESDE_PRESCALER'EVENT AND DESDE_PRESCALER = '1' ) THEN
VAR_CLOCK_GEN := NOT VAR_CLOCK_GEN ;
END IF ;
CLOCK_GENERADO<= VAR_CLOCK_GEN;
END PROCESS ;
end Behavioral;
La entidad del GENERADOR_CLOCK consta de 1 entrada
proveniente del Prescaler y una salida que será instanciada al resto
de los componentes.
En la arquitectura se crea una se crea un Process sensible a la señal
“Desde_Prescaler”
Dentro del Process se crea una variable llamada VAR_CLOCK_GEN inicializada en „0‟, la cual será
negada cada vez que ocurra un flanco ascendente de la señal Desde_Prescaler.
Finalmente la variable es asignada a la señal „CLOCK_GENERADO‟.
Osea, al recibir el primer pulso, la señal se pone en „1‟ y al recibir el segundo se pone en „0‟. Si el pulso que
hace elevarlo fue generado a los 400.000 ciclos de clock y se necesitaron otros 400.000 ciclos mas para
bajar la señal, quiere decir que el conjunto Prescaler - Clock_Generado utilizo 800.000 ciclos provenientes
del DSM. y este ultimo tenia a su salida 5.000.000 de ciclos de clock por segundo
De modo que 5.000.000
800.000= 6,25 osea que la señal final de clock será de 6,25 Mhz del orden de los 6 Hz que
se pretendían.
SIMULACION GENERADOR_CLOCK
Microprocesador Básico de 8 bits
[Escribir texto] Página 28
TOP LEVEL library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TOP_LEVEL is
Port ( SWICH_TOP_0 : in STD_LOGIC;
SWICH_TOP_1 : in STD_LOGIC;
SWICH_TOP_2 : in STD_LOGIC;
SWICH_TOP_3 : in STD_LOGIC;
CLOCK_50M : in STD_LOGIC; --para probar el bus (clock_top) y desconectar los
tratamientos de clock
PAUSA: in STD_LOGIC;
reset_TOP : in STD_LOGIC;
--test_bus: out STD_LOGIC_VECTOR (7 downto 0);
LEDS : out STD_LOGIC_VECTOR (7 downto 0));
end TOP_LEVEL;
architecture Behavioral of TOP_LEVEL is
-------------------DECLARACION DE COMPONENTES--------------------------------
--component PARA_PRUEBA_MICRO is
-- Port ( desde_bus : in STD_LOGIC_VECTOR (7 downto 0);
-- hacia_salida : out STD_LOGIC_VECTOR (7 downto 0));
--end component;
COMPONENT UC IS
Port ( opcode : in STD_LOGIC_VECTOR (2 downto 0);
z_flag : in STD_LOGIC;
clock : in STD_LOGIC;
reset : in STD_LOGIC;
cargar_bus : out STD_LOGIC;
cargar_dat : out STD_LOGIC;
cargar_dir : out STD_LOGIC;
lectura_RAM : out STD_LOGIC;
ce : out STD_LOGIC;
CARGAR_BUS_PC : out STD_LOGIC;
cargar_PC_BUS : out STD_LOGIC;
incrementar : out STD_LOGIC;
alu_bus : out STD_LOGIC;
bus_acum : out STD_LOGIC;
opcode_alu : out STD_LOGIC;
operar : out STD_LOGIC;
cargar_bus_IR : out STD_LOGIC;
cargar_IR_bus : out STD_LOGIC;
bus_a_salida : OUT STD_LOGIC);
END COMPONENT;
COMPONENT ALU_ACUM IS
Port ( BUS_micro : inout STD_LOGIC_vector (7 downto 0);
OPCODE_ALU : in std_logic ;
RESET : in STD_LOGIC;
operar: in STD_LOGIC;
bus_acum : in std_logic ;
alu_bus : in std_logic ;
z_flag: out STD_LOGIC;
CLOCK : IN std_logic);
END COMPONENT;
Microprocesador Básico de 8 bits
[Escribir texto] Página 29
COMPONENT IR IS
Port ( CLOCK : in STD_LOGIC;
RESET : in STD_LOGIC;
CARGAR_IR_BUS : in STD_LOGIC;
CARGAR_BUS_IR : in STD_LOGIC;
BUS_MICRO : inout STD_LOGIC_VECTOR (7 downto 0);
OPCODE : out STD_LOGIC_VECTOR (2 downto 0));
END COMPONENT;
COMPONENT PC IS
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
cargar_pc_bus : in STD_LOGIC;
CARGAR_BUS_PC : in STD_LOGIC;
incrementar : in STD_LOGIC;
Bus_micro : inout STD_LOGIC_VECTOR (7 downto 0));
END COMPONENT;
COMPONENT RAM IS
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
ce : in STD_LOGIC;
lectura_ram : in STD_LOGIC;
cargar_dir : in STD_LOGIC;
cargar_dat : in STD_LOGIC;
bus_micro : inout STD_LOGIC_VECTOR (7 downto 0));
END COMPONENT;
COMPONENT PUERTO_ENTRADA IS
Port ( swich_0 : in STD_LOGIC;
swich_1 : in STD_LOGIC;
swich_2 : in STD_LOGIC;
swich_3 : in STD_LOGIC;
bus_micro : inout STD_LOGIC_VECTOR (7 downto 0);
clock : in STD_LOGIC;
reset : in STD_LOGIC;
cargar_bus : in STD_LOGIC);
END COMPONENT;
COMPONENT PUERTO_SALIDA IS
Port ( Bus_micro : in STD_LOGIC_VECTOR (7 downto 0);
bus_a_salida : in STD_LOGIC;
salida_micro : out STD_LOGIC_VECTOR (7 downto 0);
reset : in STD_LOGIC;
clock : in STD_LOGIC);
END COMPONENT;
COMPONENT CAMBIO_RELOJ --DSM
PORT( CLKIN_IN : IN std_logic;
RST_IN : IN std_logic;
CLKDV_OUT : OUT std_logic;
CLKIN_IBUFG_OUT : OUT std_logic;
CLK0_OUT : OUT std_logic;
LOCKED_OUT : OUT std_logic);
END COMPONENT;
COMPONENT PRESCALER_CLK
Microprocesador Básico de 8 bits
[Escribir texto] Página 30
PORT (clk : IN STD_LOGIC;
thresh0 : OUT STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(16 DOWNTO 0));
END COMPONENT;
COMPONENT GENERADOR_CLOCK
Port ( DESDE_PRESCALER : in STD_LOGIC;
CLOCK_GENERADO : out STD_LOGIC);
END COMPONENT;
SIGNAL CABLE_OPCODE : STD_LOGIC_VECTOR (2 DOWNTO 0);
SIGNAL CABLE_Z_FLAG : STD_LOGIC;
SIGNAL CABLE_BUS_MICRO : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL CABLE_CARGAR_BUS : STD_LOGIC;
SIGNAL CABLE_CARGAR_DAT : STD_LOGIC;
SIGNAL CABLE_CARGAR_DIR : STD_LOGIC;
SIGNAL CABLE_LECTURA_RAM : STD_LOGIC;
SIGNAL CABLE_CE : STD_LOGIC;
SIGNAL CABLE_CARGAR_BUS_PC : STD_LOGIC;
SIGNAL CABLE_CARGAR_PC_BUS : STD_LOGIC;
SIGNAL CABLE_INCREMENTAR : STD_LOGIC;
SIGNAL CABLE_ALU_BUS : STD_LOGIC;
SIGNAL CABLE_BUS_ACUM : STD_LOGIC;
SIGNAL CABLE_OPCODE_ALU : STD_LOGIC;
SIGNAL CABLE_OPERAR : STD_LOGIC;
SIGNAL CABLE_BUS_IR : STD_LOGIC;
SIGNAL CABLE_IR_BUS : STD_LOGIC;
SIGNAL CABLE_BUS_A_SALIDA : STD_LOGIC;
SIGNAL CLOCK_TOP : STD_LOGIC;
SIGNAL CABLE_A_PRESCALER : STD_LOGIC;
SIGNAL CABLE_A_GENERADOR_CLOCK : STD_LOGIC;
begin
--componente0: para_prueba_micro port map (cable_bus_micro,test_bus);
COMPONENTE1: UC PORT MAP (CABLE_OPCODE,CABLE_Z_FLAG,CLOCK_TOP,RESET_TOP,
CABLE_CARGAR_BUS,CABLE_CARGAR_DAT,CABLE_CARGAR_DIR,CABLE_LECTURA_RAM,
CABLE_CE,CABLE_CARGAR_BUS_PC,CABLE_CARGAR_PC_BUS,CABLE_INCREMENTAR,
CABLE_ALU_BUS,CABLE_BUS_ACUM,CABLE_OPCODE_ALU,CABLE_OPERAR, CABLE_BUS_IR,
CABLE_IR_BUS, CABLE_BUS_A_SALIDA);
COMPONENTE2: ALU_ACUM PORT MAP (CABLE_BUS_MICRO,CABLE_OPCODE_ALU, RESET_TOP,CABLE_OPERAR,
CABLE_BUS_ACUM,CABLE_ALU_BUS, CABLE_Z_FLAG,CLOCK_TOP );
COMPONENTE3: IR PORT MAP (CLOCK_TOP, RESET_TOP,CABLE_IR_BUS, CABLE_BUS_IR, CABLE_BUS_MICRO, CABLE_OPCODE );
COMPONENTE4: PC PORT MAP (CLOCK_TOP, RESET_TOP, CABLE_CARGAR_PC_BUS, CABLE_CARGAR_BUS_PC,
CABLE_INCREMENTAR,CABLE_BUS_MICRO );
COMPONENTE5: RAM PORT MAP (CLOCK_TOP, SET_TOP,CABLE_CE,CABLE_LECTURA_RAM,CABLE_CARGAR_DIR,CABLE_CARGAR_DAT,
CABLE_BUS_MICRO );
COMPONENTE6: PUERTO_ENTRADA PORT MAP (SWICH_TOP_0,SWICH_TOP_1, SWICH_TOP_2,SWICH_TOP_3,CABLE_BUS_MICRO,
CLOCK_TOP, RESET_TOP,CABLE_CARGAR_BUS );
COMPONENTE7: PUERTO_SALIDA PORT MAP (CABLE_BUS_MICRO,CABLE_BUS_A_SALIDA, LEDS, RESET_TOP,CLOCK_TOP );
COMPONENTE8: CAMBIO_RELOJ PORT MAP (CLOCK_50M, PAUSA,CABLE_A_PRESCALER, OPEN, OPEN, OPEN ) ;
COMPONENTE9: PRESCALER_CLK PORT MAP (CABLE_A_PRESCALER, CABLE_A_GENERADOR_CLOCK, OPEN ) ;
COMPONENTE10: GENERADOR_CLOCK PORT MAP (CABLE_A_GENERADOR_CLOCK, CLOCK_TOP ) ;
end Behavioral;
Microprocesador Básico de 8 bits
[Escribir texto] Página 31
Simulación Top LEVEL, Seguimiento de los Estados
Lo que se busca en esta instancia es
realizar un seguimiento de lo que se encuentra
en el BUS, para así lograr encontrar en qué
momento puede llegar a haber un problema,
comparando lo que se espera que este en ese
momento en el BUS con lo que realmente allí
esta.
Para llevar esto a cabo se creo un componente provisorio que instanciaba el Bus_Micro con una
salida llamada “Test_Bus” por medio de la cual se genera una „‟ventana‟‟ que permite observar que es lo
que va sucediendo dentro del Bus.
Este componente se eliminara luego de corroborar el correcto funcionamiento.
Se dejan de lado por el momento los cambios de reloj para poder realizar la simulación y se prueba con
un clock dado por la misma simulación. Se instanciaran nuevamente al finalizar la prueba.
ESTADO Time (µs) ACCION TEST_BUS
RESET 0:00 Todos los componentes están en Reset y ninguno se ha conectado con el BUS ZZZZZZZZ
1 0.01 (PC->RAM)La cuenta del PC en este caso 0 se traslada al registro de direcciones de la RAM
(MAR)
00000000
2 0.02 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.03 (RAM->IR)El dato en la posición indicada por la MAR (00000000) correspondiente al dato
00000111 se almacena en el IR, el opcode decodificado será (000) o sea LOAD
00000111
4 0.04 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.05 (IR->RAM) la dirección decodificada es 00000111 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00000111
6 0.06 Se desconecta el IR y la RAM ZZZZZZZZ
LOAD_A 0.07 (RAM->ACUM) El dato indicado por la MAR (posición 00111 = 7) se traslada al acumulador,
allí se encuentra el dato 00000000
00000000
LOAD_B 0.08 Se desconecta la RAM y el Acumulador, ZZZZZZZZ
1 0.09 (PC->RAM)La cuenta del PC en este caso 1 se traslada al registro de direcciones de la RAM
(MAR)
00000001
2 0.10 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.11 (RAM->IR)El dato en la posición indicada por la MAR (00000001) correspondiente al dato
11101000 se almacena en el IR, el opcode decodificado será (111) o sea IMPORT
11101000
4 0.12 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.13 (IR->RAM) la dirección decodificada es 11101000 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001000
6 0.14 Se desconecta el IR y la RAM ZZZZZZZZ
Microprocesador Básico de 8 bits
[Escribir texto] Página 32
IMPORT_A 0.15 (PUERTO_ENTRADA-> RAM) En nuestro caso tenemos en 1 los dos swichs menos significativos
por lo que en el puerto de entrada tendremos un 00000011 y esto se grabara en la posición 8
de la RAM
00000011
IMPORT_B 0.16 Se desconecta el PUERTO_ENTRADA y la RAM ZZZZZZZZ
1 0.17 (PC->RAM)La cuenta del PC en este caso 2 se traslada al registro de direcciones de la RAM
(MAR)
00000010
2 0.18 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.19 (RAM->IR)El dato en la posición indicada por la MAR (00000011) correspondiente al dato
11101000 se almacena en el IR, el opcode decodificado será (010) o sea ADD
01001000
4 0.20 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.21 (IR->RAM) la dirección decodificada es 01001000 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001000
6 0.22 Se desconecta el IR y la RAM ZZZZZZZZ
ADD_A 0.23 (RAM->ALU_ACUM) Se traslada el dato de la RAM (el que fue señalado por la MAR) a la
ALU_ACUM donde se sumara con el dato almacenado previamente en el Acumulador
La dirección almacenada en la MAR es 01000 (posición 8) por lo que en el bus se
transportara el dato 00000011
00000011
ADD_B 0.24 Se desconecta la RAM y la ALU_ACUM ZZZZZZZZ
1 0.25 (PC->RAM)La cuenta del PC en este caso 3 se traslada al registro de direcciones de la RAM
(MAR)
00000011
2 0.26 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.27 (RAM->IR)El dato en la posición indicada por la MAR (00000011) correspondiente al dato
00101001 se almacena en el IR, el opcode decodificado será (001) o sea STORE
00101001
4 0.28 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.29 (IR->RAM) la dirección decodificada es 00101001 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001001
6 0.30 Se desconecta el IR y la RAM ZZZZZZZZ
STORE_A 0.31 (ACUM ->RAM) Se traslada el dato del Acumulador, que es el resultado de ADD 0+1 = 1 =
00000011. a la RAM y se almacenara en la posición indicada por la MAR 01001 = posición 9
00000011
STORE_B 0.32 Se desconecta la RAM y el ALU_ACUM, ZZZZZZZZ
1 0.33 (PC->RAM)La cuenta del PC en este caso 4 se traslada al registro de direcciones de la RAM
(MAR)
00000100
2 0.34 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.35 (RAM->IR)El dato en la posición indicada por la MAR (00000100) correspondiente al dato
11001001 se almacena en el IR, el opcode decodificado será (110) o sea OUTPORT
11001001
4 0.36 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.37 (IR->RAM) la dirección decodificada es 11001001 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001001
Microprocesador Básico de 8 bits
[Escribir texto] Página 33
6 0.38 Se desconecta el IR y la RAM ZZZZZZZZ
OUTPORT_A 0.39 (RAM(9)->PUERTO_SALIDA) Traslada al puerto de salida lo que se almaceno en la posición 9
de la RAM osea el resultado de la suma 00000011
00000011
OUTPORT_B 0.40 Se desconecta la RAM y el Puerto_Salida ZZZZZZZZ
1 0.41 (PC->RAM)La cuenta del PC en este caso 5 se traslada al registro de direcciones de la RAM
(MAR)
00000101
2 0.42 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.43 (RAM->IR)El dato en la posición indicada por la MAR (00000101) correspondiente al dato
10001010 se almacena en el IR, el opcode decodificado será (100) o sea JZN
10001010
4 0.44 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.45 (IR->RAM) la dirección decodificada es 11001001 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001010
6 0.46 Se desconecta el IR y la RAM ZZZZZZZZ
JZN_A 0.47 Como en este caso Z_flag = 0 ya que el acumulador es distinto de cero (en su última escritura
quedo con 00000011) se realiza un traslado (RAM->PC) el PC, leera el dato recibido, en este
caso lo que se encontraba en la posición 8 de la RAM (00000001) y el PC seguirá su cuenta
desde 1 . Osea salteara la instrucción LOAD e ira directamente a la instrucción IMPORT
00000001
JZN_B 0.48 Se desconecta el PC y la RAM ZZZZZZZZ
1 0.49 (PC->RAM)La cuenta del PC en este caso 1 se traslada al registro de direcciones de la RAM
(MAR)
00000001
… … … …
SI SIGUEN ESTANDO ACTIVADOS LOS DOS SWICHS, LA CUENTA QUE SE VERA EN LOS LEDS SERA 3,6,9,12, ETC…
OUTPORT_A 0.79
(RAM(9)->PUERTO_SALIDA) Traslada al puerto de salida lo que se almaceno en la posición 9
de la RAM osea el resultado de la suma 00000110 (6) 00000110
Microprocesador Básico de 8 bits
[Escribir texto] Página 34
PARA PROBAR LA INSTRUCCIÓN JMP SE REALIZA UNA NUEVA SIMULACION SIN ACTIVAR NINGUN SWICH, EN ESTE CASO, ZFLAG=’1’ YA
QUE EL ACUMULADOR SERA CERO
OUTPORT_A 0,39 (RAM(9)->PUERTO_SALIDA) Traslada al puerto de salida lo que se almaceno en la posición 9
de la RAM osea el resultado de la suma 0000000 (6)
00000000
OUTPORT_B 0.40 Se desconecta la RAM y el Puerto_Salida ZZZZZZZZ
1 0.41 (PC->RAM)La cuenta del PC en este caso 5 se traslada al registro de direcciones de la RAM
(MAR)
00000101
2 0.42 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.43 (RAM->IR)El dato en la posición indicada por la MAR (00000101) correspondiente al dato
10001010 se almacena en el IR, el opcode decodificado será (100) o sea JZN
10001010
4 0.44 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.45 (IR->RAM) la dirección decodificada es 10001010 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001010
6 0.46 Se desconecta el IR y la RAM ZZZZZZZZ
JZN_A 0.47 Como en este caso Z_flag =1, se cargara coo próximo esado el ESTADO_1 ZZZZZZZZ
1 0.48 (PC->RAM)La cuenta del PC en este caso 6 se traslada al registro de direcciones de la RAM
(MAR)
00000110
2 0.49 Se incrementa el PC y se desconecta el PC y la MAR del BUS ZZZZZZZZ
3 0.50 (RAM->IR)El dat o en la posición indicada por la MAR (00000110) correspondiente al dato
10101011 se almacena en el IR, el opcode decodificado será (101) o sea JMP
10101011
4 0.51 Se desconecta la RAM y el IR, ZZZZZZZZ
5 0.52 (IR->RAM) la dirección decodificada es 10101011 o sea los últimos 5 bits del dato cargado en
el estado 3 completado con ceros. y se almacena en la MAR de la RAM
00001011
6 0.53 Se desconecta el IR y la RAM ZZZZZZZZ
JMP_A 0.54 (RAM->PC) El PC seguirá su cuenta con el dato que ha sido cargado, dato proveniente de la
posición indicada por la MAR (11) que corresponde el numero 00000000
00000000
JMP_B 0.55 Se desconecta la RAM y el PC ZZZZZZZZ
1 0.56 (PC->RAM)La cuenta del PC en este caso 0 se traslada al registro de direcciones de la RAM
(MAR)
00000000
… ….. …. …
Microprocesador Básico de 8 bits
[Escribir texto] Página 35
Esquemático Top Level
Microprocesador Básico de 8 bits
[Escribir texto] Página 36
CONEXIÓN DE LA FPGA
El puerto de salida del microprocesador se conectará a los 8 leds discretos que provee el
kit de la spartan 3-E, para visualización de resultados .
Se utilizará el push-button (pin K17 ) del kit para el reset del microprocesador y el push-
button (pin D18) para poner en pausa el clock y por ende el microprocesador.
Los bits menos significativos del puerto de entrada estarán cableados en los switches que
tiene la placa de desarrollo.
Microprocesador Básico de 8 bits
[Escribir texto] Página 37
CONCLUSION
Al llevar a cabo el presente trabajo final se logro hacer uso de gran parte de las herramientas
proporcionadas por el curso, como una máquina de estado para la Unidad de control, un array y un tipo
de señal creada por nosotros mismos para el caso de la RAM entre muchas otras herramientas
empleadas.
Este trabajo en especial, al realizarlo componente por componente y luego sincronizarlo y ver
como era el traslado de datos de un componente a otro y que dato se encontraba en el bus en cada
momento sirvió para comprender el funcionamiento de un microprocesador básico de 8 bits y todas las
secuencias que se llevan a cabo durante su funcionamiento.
Logro observarse lo que se encontraba en el bus al crear un componente especial y provisorio
llamado “Para prueba micro” que se desarrollo con el fin de rastrear un error que impedía ver el resultado
esperado en la salida Leds al correr el programa de prueba dos veces con dos swichs activados. Se
esperaría que la salida mostrara un 3, luego un 6, luego un 9 etc, pero siempre mostraba un 3. El error se
encontró a los 0.34us de simulación cuando el dato que se trasladaba de la RAM al IR terminaba en
01000 cuando debería terminar en 01001, de ese modo se cargaría en la MAR un 00001000 y se estaría
sacando luego por el Puerto de Salida lo contenido el la posición 8 de la RAM que solo contiene lo que se
encuentra en el puerto de entrada. Soluciones más practicas seguramente se hubieran encontrado, pero
la tabla que se fue generando sirvio además para analizar ciclo a ciclo el traslado de datos por lo que se
finalizo y se agrego al informe.
Al contar con un único Bus bidireccional por el que tanto datos como direcciones eran
transportados, sincronizar este microprocesador fue un desafío que se logro superar realizando en la UC
una maquina de estado ordenada y prolija en el que en un ciclo se cargan los datos y en el otro se
desconectaban todos los dispositivos utilizados en el estado anterior para así asegurar que no se
produzcan “cortocircuitos o choque” de datos. Por ejemplo el ciclo de desconexión del PC y la RAM del
bus se logro aprovechar para incrementar el PC.
Como se observa en el apartado “Simulación Top LEVEL, Seguimiento de los Estados” los estados
referidos a búsqueda y decodificación de la instrucción se repiten previamente a la ejecución de cada
instrucción por lo que fue de mucha importancia optimizarlos, al igual que los otros estados referidos a la
ejecución.
Para lograr optimizarlo, la Unidad de Control emite sus señales al haber un flanco descendente del
clock, ya que conociendo el comportamiento de cada componente, que algunas acciones no son
concurrentes y las ejecutan para flancos ascendentes, se logra que la señal emitida por la UC este
disponible en sus entradas previo al ascenso del clock y así realizar en un solo ciclo la comunicación con
la UC y la ejecución de la acción requerida.
La optimización llego un total de 6 ciclos para búsqueda y decodificación. Lo normal es entre 1 y 6
ciclos para cada fase. La ejecución de las instrucciones utiliza dos ciclos.
Microprocesador Básico de 8 bits
[Escribir texto] Página 38
BIBLIOGRAFIA CONSULTADA
Circuit Design With VHDL – Pedroni
VHDL Lenguaje para Sintesis y Modelado de Circuitos – Pardo
Apuntes de cátedra de Programación Lógica para Ingeniería UNRC
Notas de Clase 2012