Maquinas de estado en WINCUPL

Les dejo la siguiente aportación de como definir una máquina de estados finita en WinCUPL
si no quieres copiar el código, les dejo un archivo de txt que lo incluye
Máquinas de estado con WincuPL

Empezamos por definir los estados con #DEFINE

$DEFINE S0 'b'000 // En este caso llamamos a este estado SO para no tener que estar
/* escribiendo su representacion binaria 000 en este caso */
$DEFINE S1 'b'110 // nota que no necesariamente sigue un orden binario
// ya que #DEFINE solo le dice a Winucpl que sustituya S1 por 110

Una vez definidos los estados, definimos la máquina de estados finita(FSM).
Para ello utilizamos la siguiente estructura
SEQUENCE nombre
{
La definición completa de la máquina de estado esta comprendido entre estos curly braces
}

Para declarar los estados usamos la palabra PRESENT, debe haber un PRESENT por cada estado
que deseamos

PRESENT S0 /* Define estado S0 */
PRESENT S1 /* Define estado S1 */

Ahora viene lo interesante:
ya que dependiendo del tipo de máquina que deseamos (Syncronica ó asincrónica)
usamos diferentes definiciones de las transiciones.
/* TABLA 1. Transiciones posibles en CUPL .
Statement Description
IF NEXT Transición condicional al siguiente estado
IF NEXT OUT Transición condicional al siguiente estado con salida Sincrónica
NEXT Transición Incondicional al siguiente estado
NEXT OUT Transición Incondicional al siguiente estado con salida Asincrónica
OUT salida asyncronica Incondicional
IF OUT salida asincrónica condicional
usamos DEFAULT después de un IF como sustituto de ELSE
DEFAULT NEXT Transición condicional al siguiente estado si el IF no se cumplió
DEFAULT OUT Transición condicional al siguiente estado con salida Asyncronica
DEFAULT NEXT OUT Transición condicional al siguiente estado con salida sincrónica
*/
Un ejemplo aclara un poco

/* Uso Field para agrupar salidas o entradas a una palabra en este caso estados*/
/* me agrupa las salidas Q3,Q2,Q1,Q0 */

FIELD estados = [Q3, Q2, Q1, Q0] ;

/* Defino los estados por comodidad sigo el binario */
$DEFINE S0 'b' 0000 /* Rojo - - - */
$DEFINE S1 'b' 0001 /* Rojo Naranja - - */
$DEFINE S2 'b' 0010 /* - Naranja - - */
$DEFINE S3 'b' 0011 /* - Naranja Verde - */
$DEFINE S4 'b' 0100 /* - - Verde - */
$DEFINE S5 'b' 0101 /* - Naranja Verde - Ahora en reversa */
$DEFINE S6 'b' 0110 /* - Naranja - - Ahora en reversa*/
$DEFINE S7 'b' 0111 /* Rojo Naranja - - Ahora en reversa */
$DEFINE S8 'b' 1000 /* Rojo - - Cuenta Ahora en reversa */

/* y defino la máquina de estados por medio de las transiciones entre estados
/* máquina Asyncronica no entradas solo el reloj el cúal cambia los estados
// Nota: Solo el GAL22V10 tiene Reset asincrónico (.AR), la 16V8 o la 20v8 solo
// puede ser usada con Reset Sincrónico.
Nota: aunque no esta documentado, se puede usar // para hacer un comentario de linea
como lo hace c++.
También aunque no esta documentado, WinCUPL no acepta acentos o guiones, ni
siquiera en los comentarios */
SEQUENCE estados
{
PRESENT S0
OUT Rojo ; // Forzo la Salida Rojo mientras este en el estado
IF Rst NEXT S1; // Entrada Rst= 1 lleva la transición al estado S1
DEFAULT NEXT S0 ; // Entrada Rst = 0 me mantiene en el mismo estado
PRESENT S1
OUT Rojo, Naranja ; // Dos salidas, se tienen que separar con una coma
IF Rst NEXT S2; // Entrada Rst= 1 lleva la transición al estado S1
DEFAULT NEXT S0 ; // Entrada Rst = 0 me lleva al estado de restauración S0
PRESENT S2
OUT Naranja ; // No olviden el ;
IF Rst NEXT S3; // Si hay mas variables usar un operador lógico ej.
DEFAULT NEXT S0 ; // Rst & Q3
PRESENT S3
OUT Naranja, Verde ; // y continuamos con los demás estados
IF Rst NEXT S4;
DEFAULT NEXT S0 ;
PRESENT S4
OUT Verde ; // observa que la salida solo depende del estado
IF Rst NEXT S5; // y no de las entradas.
DEFAULT NEXT S0 ;
PRESENT S5
OUT Naranja, Verde ; // Pero la transicion depende de las entradas y
IF Rst NEXT S6; // y tambien puede de los estados anteriores.
DEFAULT NEXT S0 ;
PRESENT S6
OUT Naranja ; /* Forzo la Salida Naranja */
IF Rst NEXT S7;
DEFAULT NEXT S0 ;
PRESENT S7
OUT Rojo, Naranja ; /* Forzo la Salidas Rojo y Naranja */
IF Rst NEXT S8;
DEFAULT NEXT S0 ;
PRESENT S8
OUT Rojo, Cuenta; /* Forzo la Salidas Rojo y Cuenta */
IF Rst NEXT S1;
DEFAULT NEXT S0 ;
}

Ahora veamos el otro caso, la declaración de los estados es el mismo
pero las transiciones no lo son

SEQUENCE estados
{
PRESENT S0
// Entrada Rst= 1 lleva la transición al estado S1
IF Rst NEXT S1 OUT Rojo ; // y la salida cambia con la transición
// como cuando definimos entrada /salida
DEFAULT NEXT S0 ; // Entrada Rst = 0 me mantiene en el mismo estado
PRESENT S1
IF Rst NEXT S2 OUT Rojo, Naranja ;
DEFAULT NEXT S0 ; // Entrada Rst = 0 me lleva al estado de restauración S0
PRESENT S2
IF Rst NEXT S3 OUT Naranja ; // Si hay mas variables usar un operador lógico ej.
DEFAULT NEXT S0 ; // Rst & Q3
// y continuamos con los demás estados
PRESENT S3
IF Rst NEXT S4 OUT Naranja, Verde;
DEFAULT NEXT S0 ;
PRESENT S4
// observa que la salida depende del estado anterior y la(s) entrada(s)
IF Rst NEXT S5 OUT Verde ;; // que causan la transición.
DEFAULT NEXT S0 ;
PRESENT S5
IF Rst NEXT S6 OUT Naranja, Verde ; // También que se usa DEFAULT como si
DEFAULT NEXT S0 ; // fuera el "ELSE" del condicional "IF"
PRESENT S6
IF Rst NEXT S7 OUT Naranja ;
DEFAULT NEXT S0 ;
PRESENT S7
IF Rst NEXT S8 OUT Rojo, Naranja ;
DEFAULT NEXT S0 ;
PRESENT S8
IF Rst NEXT S1 OUT Rojo, Cuenta; // fácil verdad?
DEFAULT NEXT S0 ;
}
 

Adjuntos

  • Acerca de maquinas de estado.txt
    6.2 KB · Visitas: 59
Última edición por un moderador:
Seguí los ejemplos anteriores para hacer un circuito secuencial sincrono "contador ascendente y descendente "
0-15 15-0, pero al compilarlo en wincupl y poner 9 estados, aparecen ciertas advertencias y al usar los 15 estados, aparecen errores.
Les agradecería su ayuda. El circuito usa 9 salidas y 3 entradas incluyendo el reloj, las 9 salidas son para 2 display de 7 segmentos (7 para un display y los otros 2 para hacer el 1 en el otro display) las entradas son reloj y para realizar adelante y atras en el conteo. Uso pld 22v10c

Código:
Name     Contador AD ;
PartNo   10 ;
Date     12/12/2014 ;
Revision 01 ;
Designer Engineer ;
Company  Kami ;
Assembly None ;
Location  ;
Device   p22v10 ;

/* EDGAR ENRIQUE TEK TORRES */

/* *************** INPUT PINS *********************/
PIN 1=CLK; /* */ 
PIN 2=DER; /* */
PIN 3=IZQ; /* */

/* *************** OUTPUT PINS *********************/
PIN 14=S0; /* */
PIN 15=S1; /* */
PIN 16=S2; /* */
PIN 17=S3; /* */
PIN 18=S4; /* */
PIN 19=S5; /* */
PIN 20=S6; /* */
PIN 21=S7; /* */
PIN 22=S8; /* */
PIN 23=S9; /* */

FIELD CONT=[S0,S1,S2,S3,S4,S5,S6,S7,S8,S9];

$define S0 'b'111111000
$define S1 'b'011000000
$define S2 'b'110110100
$define S3 'b'111100100
$define S4 'b'011001100
$define S5 'b'101101100
$define S6 'b'101111100
$define S7 'b'111000000
$define S8 'b'111111100
$define S9 'b'111101100
$define S10 'b'111111011
$define S11 'b'011000011
$define S12 'b'110110111
$define S13 'b'111100111
$define S14 'b'011001111
$define S15 'b'101101111

SEQUENCE CONT{
present S0 next S1;

present S1
if IZQ&DER next S1;
if !IZQ&DER next S2;
if IZQ&!DER next S9;

present S2
if IZQ&DER next S2;
if !IZQ&DER next S3;
if IZQ&!DER next S1;

present S3
if IZQ&DER  next S3;
if !IZQ&DER next S4;
if IZQ&!DER next S2;

present S4
if IZQ&DER  next S4;
if !IZQ&DER next S5;
if IZQ&!DER next S3;

present S5
if IZQ&DER  next S5;
if !IZQ&DER next S6;
if IZQ&!DER next S4;

present S6
if IZQ&DER  next S6;
if !IZQ&DER next S7;
if IZQ&!DER next S5;

present S7
if IZQ&DER  next S7;
if !IZQ&DER next S8;
if IZQ&!DER next S6;

present S8
if IZQ&DER  next S8;
if !IZQ&DER next S9;
if IZQ&!DER next S7;

present S9
if IZQ&DER  next S9;
if !IZQ&DER next S0;
if IZQ&!DER next S8;

present S10
if IZQ&DER  next S10;
if !IZQ&DER next S11;
if IZQ&!DER next S9;

present S11
if IZQ&DER  next S11;
if !IZQ&DER next S12;
if IZQ&!DER next S10;

present S12
if IZQ&DER  next S12;
if !IZQ&DER next S13;
if IZQ&!DER next S11;

present S13
if IZQ&DER  next S13;
if !IZQ&DER next S14;
if IZQ&!DER next S12;

present S14
if IZQ&DER  next S14;
if !IZQ&DER next S15;
if IZQ&!DER next S13;

present S15
if IZQ&DER  next S15;
if !IZQ&DER next S0;
if IZQ&!DER next S14;

}
 
Última edición por un moderador:
Atrás
Arriba