Problem Av HDL
Problem Av HDL
11.2.1 El boton
Ejemplo 11.1 Un motor electrico viene controlado por un unico boton. Cuando se
pulsa el motor cambia de encendido a apagado. Sintetizar el circuito que controla el
motor mediante una maquina de estados en VHDL.
La solucion a este problema es bastante simple tal y como ya se mostro en el ejemplo
6.3 donde con un simple biestable se solucionaba el problema. Desde un punto de vista
algo mas abstracto se puede pensar en una maquina de estados con dos estados, de
manera que se pasa de uno a otro cada vez que se pulsa el boton. Esto en principio
se puede hacer, pero tiene un problema y es que cuando se pasa de un estado a otro
el boton sigue pulsado, por lo que en realidad se produce una transicion muy rapida
entre estados; solo cuando se suelte el boton se parara, pero es imposible predecir si se
parara en el estado encendido o en el apagado. Para evitar esto lo normal es pensar
en dos estados mas que detengan esta transicion rapida entre estados. La salida solo
dependera del estado del sistema por tanto no es mas que una maquina de Moore:
ENTITY conmutador IS
PORT (boton: IN bit; motor: OUT bit);
END conmutador;
Este segundo caso no se sintetizara bien puesto que a las herramientas de dise~no hay
que especicarles que cosas son activas por
anco de forma explcita, generalmente con el
atributo 'EVENT. Si se metiera esta descripcion en un sintetizador, y luego simularamos
lo sintetizado, descubriramos que efectivamente tiene dos estados pero al pulsar el
boton cambia entre estados de forma rapida tal y como se predijo al principio. En
cambio, si se simula la descripcion tal y como esta, funcionara bien. Aparte de todo
esto, el ejemplo anterior no es precisamente un buen modelo de maquina de estados ya
que la se~nal de sincronizacion, en este caso el boton, se encuentra en cada uno de los
estados, y por otro lado hay algo que no se debera hacer nunca y es cambiar la salida
al tiempo que cambia el estado para que as el estado siguiente tenga la salida que se
le ha especicado; en general, cada estado debera tener especicadas sus salidas. Para
que un sintetizador hubiera interpretado la descripcion anterior como lo que realmente
pone, habra que haberlo hecho as:
ARCHITECTURE para_sintesis OF conmutador IS
TYPE estado IS (apagado,encendido);
SIGNAL presente: estado:=apagado;
BEGIN
PROCESS(boton)
BEGIN
IF boton='1' -- o boton='1' AND boton'EVENT
CASE presente IS
WHEN apagado =>
Esta descripcion es mas interesante ya que en este caso esta mas claro lo que quere-
mos decir y tanto la simulacion como la sntesis coinciden. Quiza alguien podra pensar
que una posible solucion sera poner presente en la lista sensible, pero esto, aunque la
simulacion estara bien, sintetizara otro circuito diferente. O sea, que es aconsejable
seguir un unico modelo para la maquina de estados, que funcione bien para sntesis, y
no salirse de ah.
ENTITY semaforo IS
PORT (sensor,reset,clk: IN std_logic;
semcamin,semcarr: OUT std_logic_vector(0 TO 2));
END semaforo;
salida:
PROCESS(presente)
BEGIN
CASE presente IS
WHEN inicial=>
semcarr<=verde;
semcamin<=rojo;
rescont<=true;
WHEN carramarillo=>
semcarr<=amarillo;
semcamin<=rojo;
END descripcion;
11.2.3 El ascensor
Ejemplo 11.3 Describir el controlador de un ascensor unico en una vivienda de 4
pisos. Las entradas al circuito seran, por un lado, el piso al que el usuario desea
ir mediante 4 botones, y el piso en el que se encuentra el ascensor en un momento
dado. Por otro, habra una celula que detecte la presencia de algun obstaculo en la
puerta, si hay un obstaculo la puerta no debe cerrarse. La salida sera por un lado el
motor (mediante dos bits), y la puerta (un bit). El funcionamiento es bien simple: el
ascensor debe ir al piso indicado por los botones, cuando llegue abrira las puertas que
permaneceran as hasta que se reciba otra llamada. El ascensor no tiene memoria por
lo que si se pulsan los botones mientras el ascensor se mueve, no hara caso.
ENTITY ascensor IS
PORT(boton: IN bit_vector(0 TO 3);
piso: IN bit_vector(1 DOWNTO 0);
clk,reset,celula: IN bit;
motor: OUT bit_vector(0 TO 1);
puerta: OUT bit);
END ascensor;
BEGIN
fsm:
PROCESS(reset,clk)
BEGIN
IF reset='1' THEN presente<=inicial;
ELSIF clk='1' AND clk'EVENT THEN
CASE presente IS
WHEN inicial=>
IF bot/="100" THEN presente<=cerrar;
END IF;
WHEN cerrar=>
IF celula='0' THEN presente<=voy; -- Sin obtaculos
END IF;
WHEN voy=>
IF bot(1 DOWNTO 0)=piso THEN presente<=inicial;
END IF;
END CASE;
END IF;
END PROCESS fsm;
salida:
PROCESS(presente,boton)
BEGIN
CASE presente IS
WHEN inicial=>
motor<="00"; -- Parado
puerta<='1'; -- Abierta
bot<=codifica(boton);
WHEN cerrar=>
motor<="00";
puerta<='1';
WHEN voy=>
puerta<='0'; -- Cerrada
IF bot(2 DOWNTO 0)>piso THEN
motor<="10"; -- Subir
ELSE motor<="01"; -- Bajar
END IF;
END CASE;
END PROCESS salida;
END mover;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY rom IS
PORT( cen: IN std_logic;
direcc: IN std_logic_vector(1 DOWNTO 0);
dato: OUT std_logic_vector(7 DOWNTO 0));
END rom;
PROCESS(direcc)
BEGIN
salida<="XXXXXXXX" AFTER 10 ns;
CASE direcc IS
WHEN "00"=>salida<=TRANSPORT "00000000" AFTER 100 ns;
WHEN "01"=>salida<=TRANSPORT "00000001" AFTER 100 ns;
WHEN "10"=>salida<=TRANSPORT "01010101" AFTER 100 ns;
WHEN "11"=>salida<=TRANSPORT "10101010" AFTER 100 ns;
WHEN OTHERS=> NULL;
END CASE;
END PROCESS;
END modelo;
ENTITY procesador IS
PORT(clk,rst: IN std_logic;
r_w: OUT std_logic;
dir: OUT std_logic_vector(7 DOWNTO 0);
dat: INOUT std_logic_vector(7 DOWNTO 0));
END procesador;
fsm:
PROCESS(clk)
BEGIN
END descripcion;
11.2.6 La lavadora
Ejemplo 11.6 Se pretende sintetizar el chip que controla una lavadora domestica cti-
cia. La lavadora, junto con las entradas y salidas del chip que la controla, se muestran
en la gura 11.1. El funcionamiento se explica a continuacion junto con las entradas y
salidas:
Entradas:
color: Al pulsarse esta tecla se cambia un estado interno de la maquina que indica si
el ciclo de lavado es de ropa de color o no. Inicialmente se supone que no es de
color (estado a cero).
centrifuga: Cada vez que se pulsa cambia un estado interno que indica si se debe
centrifugar o no. Inicialmente se supone que no (estado a cero).
start: Cuando se pulsa se inicia el lavado, una vez en marcha este boton no hace nada.
jabon listo: Indica que el jabon ya se ha introducido en el lavado.
vacio: Indica que el tambor esta vaco de agua.
lleno: Indica que el tambor ya esta lleno de agua.
clk: Reloj para sincronizar de frecuencia 100 Hz.
Salidas:
jabon: Al ponerla a uno coge el jabon del cajetn y lo mete en el tambor en el ciclo de
lavado.
llenar: A uno abre las valvulas del agua para llenar el tambor, se debe monitorizar la
se~nal lleno para saber cuando ponerla a cero para que no entre mas agua.
vaciar: A uno abre las valvulas de salida del agua para desaguar el tambor. La se~nal
de entrada vacio indicara el momento en que no hay mas agua en el tambor.
lento: Un uno en esta se~nal hace que el motor gire, en la direccion indicada por la
se~nal direccion, con un ritmo lento. Esta velocidad se usa en todos los ciclos
menos en el centrifugado.
rapido: Lo mismo que lento pero la velocidad es la de centrifugado, o sea, mas rapida.
Si las se~nales anteriores estan las dos a cero entonces el motor esta parado, si
estan a uno las dos entonces se quema la maquina de lavar.
direccion: a uno indica que el tambor se movera a izquierdas y a cero a derechas. El
tambor debe moverse alternativamente a derecha e izquierda en todos los ciclos
menos en el de centrifugado que se mueve siempre en la misma direccion.
Ciclos de lavado:
Ingeniera Informatica Universidad de Valencia
11.2 Ejemplos para simulacion y sntesis 101
Inicial: es el estado inicial de la maquina y esta esperando a que se pulse start.
Lavado: en este ciclo se coge el jabon, se llena de agua el tambor y se pone en marcha
el motor alternativamente a izquierda y derecha. La duracion es de 10 minutos si
la ropa es de color y 20 minutos si la ropa es blanca o resistente. Cuando acaba
se vaca el agua del tambor.
Aclarado: Se llena el tambor de agua otra vez pero sin jabon. El tambor tambien se
mueve. Dura 5 minutos y hay que vaciar el agua al acabar.
Centrifugado: Si la opcion de centrifugado esta seleccionada entonces entrara en este
ciclo, sino volvera al inicial. Este ciclo consiste en mover el tambor a velocidad
rapida en un unico sentido de giro durante 10 minutos. Al acabar se vuelve al
estado inicial.
color jabon
centrifuga
start llenar
vaciar
jabon_listo
vacio lento
lleno rapido
direccion
clk
ENTITY lavadora IS
PORT (color,centrifuga,start,jabon_listo,vacio,lleno,clk: IN std_logic;
jabon,llenar,vaciar,rapido,lento,direccion: OUT std_logic);
END lavadora;
PROCESS(centrifuga)
BEGIN
IF centrifuga='1' THEN centriaux<=NOT centriaux; END IF;
END PROCESS;
PROCESS(color)
BEGIN
IF color='1' THEN coloraux<=NOT coloraux; END IF;
END PROCESS;
direccion<=diraux;
END sincrona;
ENTITY lavadora2 IS
PORT (color,centrifuga,start,jabon_listo,vacio,lleno,clk: IN std_logic;
jabon,llenar,vaciar,rapido,lento,direccion: OUT std_logic);
END lavadora2;
salida:
PROCESS(presente)
BEGIN
CASE presente IS
WHEN inicial=>
jabon<='0'; llenar<='0'; vaciar<='1';
lento<='0'; rapido<='0'; dirauxd<='0';
tiempores<=TRUE; subtiempores<=TRUE;
WHEN lavado=>
vaciar<='0';
rapido<='0';
IF jabon_listo='0' THEN jabon<='1';
ELSE jabon<='0';
END IF;
IF lleno='0' THEN
llenar<='1';
lento<='0';
tiempores<=TRUE;
ELSE
llenar<='0';
lento<='1';
jabon<='0';
tiempores<=FALSE;
END IF;
IF subtiempo=diezsec THEN
dirauxd<=NOT diraux;
subtiempores<=TRUE;
ELSE
subtiempores<=FALSE;
END IF;
WHEN vacia1=>
jabon<='0';
vaciar<='1';
lento<='0';
rapido<='0';
subtiempores<=TRUE;
tiempores<=TRUE;
llenar<='0';
dirauxd<='0';
WHEN aclarado=>
jabon<='0';
vaciar<='0';
rapido<='0';
IF lleno='0' THEN
llenar<='1';
lento<='0';
tiempores<=TRUE;
contador:
PROCESS(clk)
BEGIN
IF clk='1' THEN
IF subtiempores THEN
subtiempo<=0;
ELSE
subtiempo<=subtiempo+1;
END IF;
IF tiempores THEN
tiempo<=0;
ELSE
tiempo<=tiempo+1;
END IF;
END IF;
END PROCESS contador;
PROCESS(centrifuga)
BEGIN
IF centrifuga='1' THEN centriaux<=NOT centriaux; END IF;
END PROCESS;
PROCESS(color)
BEGIN
IF color='1' THEN coloraux<=NOT coloraux; END IF;
END PROCESS;
PROCESS(clk)
BEGIN
IF clk='1' THEN diraux<=dirauxd;
END IF;
END PROCESS;
direccion<=diraux;
END sincrona2;
11.2.7 El concurso
Ejemplo 11.7 Se pretende realizar el modelo de un chip que controla el funcionamiento
de un programa concurso de television entre tres concursantes. La prueba que tienen que
pasar los tres concursantes es la de contestar a unas preguntas eligiendo una de las tres
respuestas que se le dan, para ello dispone de tres pulsadores cada uno. Hay un operador
humano detras del escenario que controla la maquina. Tiene tres interruptores donde
programa la respuesta correcta (correcto), un pulsador que le sirve para iniciar el juego
(start), otro pulsador que le sirve para indicar otra pregunta (nueva) y un boton de
reset para inicializarlo todo. Una vez presionado start los concursantes deben pulsar
el boton correspondiente a la pregunta que crean correcta. En el momento alguien pulse
se pasa a evaluar su respuesta (como los circuitos van a tener un retraso muy peque~no,
se supone que es imposible que dos jugadores pulsen a la vez). Si el jugador acerto la
respuesta se le sumaran 10 puntos en su marcador, pero si fallo entonces se le restaran
5 puntos. Si ningun jugador contesta en 5 segundos entonces se le restaran 5 puntos al
que tenga mayor puntuacion en ese momento (si hay varios se les resta a todos ellos).
El circuito sabra si la respuesta ha sido correcta comparandola con la que el operador
haya programado en los interruptores correcto antes de iniciar cada pregunta y que
cambiara entre pregunta y pregunta antes de pulsar nueva. Cuando algun jugador llegue
a 100 puntos o mas entonces habra ganado y el juego se parara activandose la salida
correspondiente al jugador que ha ganado. Los marcadores del resto de jugadores se
ponen a cero salvo el del que gano que conserva su valor. As se queda todo en este
estado hasta que el operador le de al reset.
La frecuencia de reloj es ja y vale 1024 Hz. En caso de pregunta acertada, fallada,
o que pasaron los 5 segundos, el operador siempre debera pulsar nueva para hacer otra
pregunta. Los interruptores se ponen y se quedan a uno o a cero hasta que se los cambie
otra vez. Los botones estan a uno mientras se pulsen, el resto del tiempo estan a cero.
En este caso se da una descripcion mas para modelado y simulacion que para sntesis,
ya que si se intenta sintetizar no sale lo que en principio debera ser. La razon es que
cuando se describe una maquina de estados sin sincrona con un reloj, el sintetizador
no lo optimiza por no reconocerlo como maquina de estados, y por otro lado esta el
problema de la interpretacion que hace el sintetizador de la lista sensible; si nos jamos
en el proceso salida, la lista sensible no es mas que la se~nal presente, lo cual signica
que todas las se~nales de este proceso vienen sincronizadas por el cambio de estado, esto
quiere decir que instrucciones como la de sumas 10 puntos, etc, solo tienen lugar una
vez durante el cambio de estado. Si esta descripcion se sintetiza se observa que esto
Ingeniera Informatica Universidad de Valencia
11.2 Ejemplos para simulacion y sntesis 107
no ocurre as, sino que lo que realmente sucede es que la instruccion que suma 10, por
ejemplo, se repite indenidamente con el retraso propio de las puertas mientras el pulso
esta en alto. Esto es as porque el sintetizador supone que todas las se~nales del proceso
estan en la lista sensible y lo sintetiza como logica combinatorial y no funciona bien.
ENTITY ajugar IS
PORT (
-- Reloj de frecuencia fija 1024 Hz;
clk: IN BIT;
-- Diferentes pulsadores o botones del operador:
reset,start,nueva: IN BIT;
-- Contiene la respuesta correcta:
correcto: IN BIT_VECTOR(1 TO 3);
-- Pulsadores de los jugadores A,B,C respectivamente:
pulsaA, pulsaB, pulsaC: IN BIT_VECTOR(1 TO 3);
-- Marcadores de cada jugador A, B y C:
marcaA, marcaB, marcaC: OUT INTEGER RANGE 0 TO 255;
-- Lineas para indicar quien de todos gano:
ganaA, ganaB, ganaC: OUT BIT);
END ajugar;
BEGIN
marcaA<=marcauxA; -- Senyales auxiliares para poder
marcaB<=marcauxB; -- leer la salida
marcaC<=marcauxC;
contador:
PROCESS(clk)
BEGIN
IF clk='1' THEN
IF rescont THEN cuenta<=0; -- Para inicializar la cuenta
ELSE cuenta<=cuenta+1;
END IF;
END IF;
END PROCESS contador;
maquina:
PROCESS(reset,start,nueva,pulsaron,timeout,fin) -- senyales que cambian
BEGIN -- el estado presente.
IF reset='1' THEN presente<=inicial;
ELSE
CASE presente IS
WHEN inicial=>
IF start='1' THEN presente<=responde; END IF;
WHEN responde=>
IF pulsaron THEN presente<=evalua;
ELSIF timeout THEN presente<=tiempo;
END IF;
WHEN evalua=>
IF fin THEN presente<=final;
ELSIF nueva='1' THEN presente<=responde;
salida:
PROCESS(presente)
BEGIN
CASE presente IS
WHEN inicial=>
marcauxA<=0;
marcauxB<=0;
marcauxC<=0;
ganaA<='0';
ganaB<='0';
ganaC<='0';
rescont<=true;
WHEN responde=>
rescont<=false;
WHEN evalua=>
rescont<=true;
IF pulsaA/="000" THEN
IF pulsaA=correcto THEN marcauxA<=marcauxA+10;
ELSIF marcauxA>=5 THEN marcauxA<=marcauxA-5;
END IF;
END IF;
IF pulsaB/="000" THEN
IF pulsaB=correcto THEN marcauxB<=marcauxB+10;
ELSIF marcauxB>=5 THEN marcauxB<=marcauxB-5;
END IF;
END IF;
IF pulsaC/="000" THEN
IF pulsaC=correcto THEN marcauxC<=marcauxC+10;
ELSIF marcauxC>=5 THEN marcauxC<=marcauxC-5;
END IF;
END IF;
WHEN tiempo=>
rescont<=true;
IF marcauxA>=5 AND marcauxA>=marcauxB AND marcauxA>=marcauxC THEN
marcauxA<=marcauxA-5;
END IF;
IF marcauxB>=5 AND marcauxB>=marcauxA AND marcauxB>=marcauxC THEN
marcauxB<=marcauxB-5;
END IF;
IF marcauxC>=5 AND marcauxC>=marcauxB AND marcauxC>=marcauxA THEN
marcauxC<=marcauxC-5;
END IF;
WHEN final=>
IF marcauxA>=100 THEN
marcauxB<=0;
marcauxC<=0;
ganaA<='1';
END IF;
IF marcauxB>=100 THEN
marcauxA<=0;
marcauxC<=0;
ganaB<='1';
END IF;
IF marcauxC>=100 THEN
marcauxB<=0;
marcauxA<=0;
ganaC<='1';
END IF;
END CASE;
END una_solucion;
Aparte de que la maquina de estados no es sncrona con un reloj, hay otra diferencia
con otras descripciones que hemos visto, y es que el contador del tiempo esta situado
en un proceso aparte, que no es raro, y se han utilizado unas se~nales para indicar los
nales de cuenta.
11.2.8 El pin-ball
Ejemplo 11.8 Realizar la descripcion en VHDL del controlador de una maquina de
pin-ball. La maquina tiene un marcador que se incrementa segun donde toque la bola,
tiene dos pivotes de manera que segun de la bola en uno u otro se suman 5 o 10 puntos
respectivamente. Cada 100 puntos se obtiene una bola nueva. Tambien tiene dos tacos
que son los de darle a la bola y otro que sirve para lanzar la bola al principio. Ademas
esta la ranura por donde se mete la moneda.
Para controlar la maquina se necesitan las siguientes entradas:
p uno, p dos: se ponen a '1' cuando la bola choca contra el pivote uno o dos. Van a
servir para saber que valor hay que sumar al marcador; si le da al pivote p uno
se suman 5 y al otro 10.
falta: esta se~nal se pone a '1' cuando se empuja bruscamente la maquina para hacer
trampa. Cuando esta se~nal se pone a uno, los tacos deben paralizarse y quedarse
as hasta que la bola se pierda por el agujero.
nueva: sirve para indicar que se ha introducido una moneda y que empieza la partida
(por simplicidad no se considera el caso en el que se introducen varias monedas
para tener mas partidas.)
pierde: sirve para indicar que se ha perdido la bola por el agujero y que por tanto hay
que restar una bola a las que quedan. Cuando no quedan mas bolas se detiene el
juego.
clk: se~nal de reloj para sincronizar el circuito. Su frecuencia se supone mucho mas alta
que el tiempo que estan activas las se~nales de p uno, p dos, nueva y pierde.
A partir de dichas entradas el circuito debe producir las siguientes salidas:
marcador: Es un bus de 12 lneas que se conecta al marcador electronico de la maquina
y que contiene la cuenta de puntos.
bloqueo: mientras esta a '1' los tacos no funcionan. Debe estar a '1' mientras no se
juega o desde que se movio la maquina bruscamente (falta) hasta que sale una
nueva bola.
n: Cuando se acaban las bolas esta se~nal se pone a '1' para encender un gran panel
luminoso que pone 'Fin de juego. Inserte moneda'.
Tener en cuenta que el marcador no debe ponerse a cero al acabar el juego, sino que
debe hacerlo en el momento de empezar a jugar despues de insertar la moneda.
Como es habitual, el problema se puede solucionar mediante una maquina de estados
que hacemos sncrona para que resulte sencilla la sntesis del circuito.
Se ha utilizado una maquina de estados con un unico proceso, esto en principio no
nos supone ningun problema ya que importa poco que las se~nales de salida esten un
Ingeniera Informatica Universidad de Valencia
110 Utilizacion del lenguaje VHDL
ciclo de reloj retrasadas respecto del cambio de estado, debido a que la se~nal de reloj
se supone de una frecuencia elevada.
Como aspecto novedoso en este ejemplo se puede ver el tratamiento que se ha
seguido con los pulsos producidos por los pivotes y el pulso producido cuando se pierde
la bola (pierde). Ya se comento al inicio del captulo que un error comun se daba en
el tratamiento de pulsos mas largos que la se~nal reloj, que provocaba que una misma
operacion se repitiera una y otra vez mientras dura el pulso. En este caso se ha evitado
creando un pulso auxiliar que tiene la duracion de un pulso de reloj y que por tanto
solo se procesa una vez. Estos pulsos se han creado al nal en los procesos d pierde,
d p uno y d p dos. Por lo dem as el programa sigue las reglas basicas para sntesis vistas
en el resto de ejemplos.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY pinball IS
PORT (p_uno,p_dos,falta,nueva,pierde,clk : IN std_logic;
marcador: OUT integer RANGE 0 TO 4095; -- 12 bits
bloqueo,fin: OUT std_logic);
END pinball;
-- Como estos pulsos de entrada son mucho mas largos que el periodo del reloj
-- se crean estas senyales que son lo mismo pero duran un 'unico pulso.
d_pierde:
PROCESS(pierde,presente)
BEGIN
IF presente=resta OR presente=inicia THEN d_pierde<='0';
ELSIF pierde='1' AND pierde'EVENT THEN d_pierde<='1';
END IF;
END PROCESS;
d_p_uno:
PROCESS(p_uno,presente)
BEGIN
IF presente=suma_cinco OR presente=inicia THEN d_p_uno<='0';
ELSIF p_uno='1' AND p_uno'EVENT THEN d_p_uno<='1';
END IF;
END PROCESS;
d_p_dos:
PROCESS(p_dos,presente)
BEGIN
IF presente=suma_diez OR presente=inicia THEN d_p_dos<='0';
ELSIF p_dos='1' AND p_dos'EVENT THEN d_p_dos<='1';
END IF;
END PROCESS;
END sincrono;
Tabla de Salida
Estado oe we
idle 0 0
start 0 0
writing 0 1
reading 1 0
Diagrama de estados:
idle
Ready=1
Reset=1 Reset=1
Ready=1 Ready=1
writing reading
Reset=1
start
r_w=1
r_w=0
Solución:
library ieee;
use ieee.std_logic_1164.all;
entity exemple_FSM is
port( r_w, ready: in std_logic;
reset, clk: in std_logic;
oe, we: out std_logic);
end exemple_FSM;
B=1
B=0
Bateria
P=1 Baja
Avance
B=0 B=0
A=1
P=1
I=1
Izqu. Parado Dcha. B=0
D=1
P=1
R=1
P=1
Retroceso
B=0
ENTITY controlRobot IS
PORT(
clk,D,I,A,R,P,B: IN bit;
Salida: OUT INTEGER RANGE 0 TO 5);
END controlRobot;
ARCHITECTURE flujo OF controlRobot IS
TYPE estado IS (parado, retroceder, avanzar, izquierda, derecha, BateriaBaja);
SIGNAL presente: estado:=parado;
BEGIN
proceso:PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk='1') THEN
CASE presente IS
WHEN parado =>
IF B='1' THEN
presente<=BateriaBaja;
ELSIF P='1' THEN
presente<=parado;
ELSIF A='1' THEN
presente<=avanzar;
ELSIF R='1' THEN
presente<=retroceder;
ELSIF D='1' THEN
presente<=derecha;
ELSIF I='1' THEN
presente<=izquierda;
ELSE
presente<=parado;
END IF;
WHEN retroceder =>
IF B='1' THEN
presente<=BateriaBaja;
ELSIF P='1' THEN
presente<=parado;
ELSIF R='1' THEN
presente<=retroceder;
ELSIF A='1' THEN
presente<=avanzar;
ELSIF D='1' THEN
presente<=derecha;
ELSIF I='1' THEN
presente<=izquierda;
ELSE
presente<=retroceder;
END IF;
WHEN avanzar =>
IF B='1' THEN
presente<=BateriaBaja;
ELSIF P='1' THEN
presente<=parado;
ELSIF A='1' THEN
presente<=avanzar;
ELSIF R='1' THEN
presente<=retroceder;
ELSIF D='1' THEN
presente<=derecha;
ELSIF I='1' THEN
presente<=izquierda;
ELSE
presente<=avanzar;
END IF;
WHEN derecha =>
IF B='1' THEN
presente<=BateriaBaja;
ELSIF P='1' THEN
presente<=parado;
ELSIF D='1' THEN
presente<=derecha;
ELSIF A='1' THEN
presente<=avanzar;
ELSIF R='1' THEN
presente<=retroceder;
ELSIF I='1' THEN
presente<=izquierda;
ELSE
presente<=derecha;
END IF;
WHEN izquierda =>
IF B='1' THEN
presente<=BateriaBaja;
ELSIF P='1' THEN
presente<=parado;
ELSIF I='1' THEN
presente<=izquierda;
ELSIF A='1' THEN
presente<=avanzar;
ELSIF R='1' THEN
presente<=retroceder;
ELSIF D='1' THEN
presente<=derecha;
ELSE
presente<=izquierda;
END IF;
WHEN BateriaBaja =>
IF B='0' THEN
presente<=parado;
ELSE
presente<=BateriaBaja;
END IF;
END CASE;
END IF;
END PROCESS proceso;
Salida <= 0 WHEN presente=parado ELSE
1 WHEN presente=BateriaBaja ELSE
2 WHEN presente=avanzar ELSE
3 WHEN presente=retroceder ELSE
4 WHEN presente=izquierda ELSE
5;
END flujo;