You are on page 1of 92

CAPITULO V: Ejemplos y aplicaciones prcticas.

En este capitulo demostrara la utilizacin del lenguaje Verilog en sntesis


lgica para la implementacin de circuitos prcticos a travs de una placa
de pruebas, el software de desarrollo ISE de XILINX. Se mostrara los pasos
necesarios para crear un proyecto, escribir el cdigo, herramientas de
sntesis, comprobacin y finalmente implementacin en circuito.
5.1

Descripcin del hardware utilizado.


Para el desarrollo de los ejemplos prcticos se utilizaron 2 placas
electrnicas, la primera, el KIT de desarrollo XC2-XL de la empresa
DIGILENT que posee dos
CPLDs y una placa creada para interfase y manejo de algunos perifricos
que se conecta directamente al kit de desarrollo XC2-XL.

5.1.1

Descripcin del KIT XC2-XL.


El KIT XC2-XL es un a placa de desarrollo para CPLDs que incluye 2 CPLDs,
uno de los
XC2C256-TQ144 Y XC9572XL-VQ44 de la empresa XILINX
mayores fabricantes de CPLDs y FPGAs del mundo.
Esta placa constituye una herramienta muy verstil para el desarrollo y
aprendizaje
de
CPLDs
utilizando
las
herramientas
de
desarrollo,
programacin a travs de un puerto JTAG. Todos los puertos de los 2
CPLDs estn disponibles para su uso en conectores externos

Figura 5.1: Diagrama de bloques de XC2-XL

Entre las caractersticas mas destacadas de este sistema son las siguientes:

1 CPLD XC2C256-TQ144

111

1 CPLD XC9572XL-VQ44
1 puerto JTAG para programacin de los dos CPLDs.
1 oscilador en placa de 1.8432 MHz que puede ser cambiado.
Conectores externos disponibles para todos los pines de los 2 CPLDs.
1 pulsante nico conectado a 1 entrada de cada CPLD.
1 LED para cada uno de los CPLD

Mas detalles de la placa XC2-XL y sus esquemas se pueden encontrar en el


apndice C.
Placa de interfase.

5.1.2

La placa de interfase esta diseada para proveer de varios dispositivos de


interfase y circuitos lgicos adecuados para acoplar los diferentes niveles
de voltaje soportados por los CPLDs. Cave resaltar que los voltajes de
alimentacin del XC2C256 y el XC9572XL son diferentes y se tendr que
tener precaucin al momento de configurar las lneas de i/o de los CPLD.
Se ha provisto de circuitos lgicos 74LV541 y 74HC541 para poder convertir
los niveles de tensin y prestar cierto nivel de proteccin a las lneas de los
CPLDs.
La placa de Interfase cuenta con los siguientes dispositivos:

Teclado matricial de 3x4 teclas


3 pulsantes N.O.
3 interruptores N.O.
1 display de 4 dgitos a 7 segmentos multiplexado
8 LEDs de nodo comn
1 Driver de potencia ULN2803 con fuente variable
1 Interfase serial RS232 con su respectivo conector DB9F
Conectores individuales para perifricos, salidas de las lneas de los
CPLDs y entradas y salidas de los circuitos 74xx541.

D isplay
7 seg

Leds

Fuente
fija

O .C .
D rivers

Fuente
variable

4 digitos

B l o que

7 4LV y 7 4 H C

C o n e ctor He ad er (kit XC2- XL )

Teclado
m atriz

R S232

Pulsantes y
sw itches

C onectores SIP

Figura 5.2: Esquema de bloques de la placa de pruebas.

112

5.2

Breve Introduccin al programa de desarrollo Xilinx ISE.


El KIT de desarrollo XC2-XL incluye 2 CPLDs de XILINX, para poder utilizar
estos chips se utiliza el sistema de desarrollo integrado de XILINX llamado
ISE. La versin utilizada es la 8.1.
Este sistema permite varios mtodos de desarrollo de un sistema basado ya
sea en FPGA o CPLDs, estos mtodos son: lenguajes descriptivos, mediante
el uso del editor grafico o una combinacin de los 2.
ISE provee la facilidad de trabajar con lenguajes descriptivos tales como
ABEL, VHDL y Verilog el cual ser objetos de nuestro estudio. Los mtodos
grficos de diseo digital no sern abordados.
ISE es un poderoso sistema integrado de desarrollo, abarca todas las
herramientas necesarias para realizar un diseo completo digital. Estas
herramientas comprenden, un editor grafico, un editor de texto, programa
de sntesis lgica, un simulador, editores de pines y restricciones, programa
de programacin y algunas herramientas adicionales.
Xilinx ofrece una muy amplia variedad de documentos referentes a sus
productos y aplicaciones, manuales tcnicos, notas de aplicacin y ejemplos
todos ellos disponibles a travs de su direccin de Internet.
En este numeral describiremos los pasos bsicos para crear un diseo
utilizando un dispositivo digital, generar un proyecto, correr el programa de
sntesis, simulacin y por ultimo la programacin del dispositivo.
Antes comenzar con lo antes indicado, citaremos algunas recomendaciones
las cuales seguiremos como guas para el diseo de un sistema digital
utilizando un lenguaje HDL.

Cuando se va a disear un sistema digital necesitamos como primer


paso antes de comenzar a escribir el cdigo ya sea en cualquier
lenguaje HDL es el de tener una idea clara de lo que queremos que
nuestro diseo haga. Es importante definir claramente un diagrama
de bloques, en el cual podamos incluir los mdulos que formaran
parte de nuestro circuito.

Ya sea que utilicemos diseo de arriba abajo o abajo arriba es


necesario definir las lneas necesarias de entrada, salida, seales de
reloj etc.

Otra consideracin muy importante es el de tratar de describir


mdulos pequeos e integrarlos en porciones de cdigo mas
complejas.

113

5.2.1

que estos sean lo mas genricos


Al escribir mdulos tratar de
posibles, esto se consigue con la utilizacin de parmetros en los
mdulos de esta forma si por ejemplo describimos un comparador de
8 bits parametrizando la longitud del comparador necesitaramos
nicamente cambiar el parmetro de 8 a 16 para conseguir un
comparador de 16 bits.

Es recomendable verificar el funcionamiento de los mdulos


descritos, para esto se recomienda utilizar archivos de comprobacin
los cuales se pueden generar automticamente definiendo seales
lgicas o escribiendo el cdigo en el mismo lenguaje HDL.

El modulo TOP o el que contiene a los otros mdulos se recomienda


mantenerlo lo ms pequeo como posible, es decir que contenga las
instancias de los mdulos y las entradas y salidas necesarias.

Por ultimo es bueno revisar despus del proceso de sntesis de los


mdulos el esquema generados para verificar que lo que hemos
descrito en HDL sea lo que habamos pretendido. Para esto ISE
provee 2 opciones de visualizacin del esquema, el primero a nivel
RTL el cual es genrico de acuerdo a la sntesis lgica y el segundo
mas especifico de acuerdo a las tecnologas utilizadas de acuerdo a
los dispositivos y libreras que utiliza la herramienta de sntesis
lgica.

Crear un nuevo proyecto.


Se asume que el programa ISE se encuentra instalado y listo para ser
utilizado. Con este antecedente en el men de programas buscamos la
carpeta de xilinx ISE 8.x y buscamos Project Navigator este enlace abre el
sistema de desarrollo ISE.

La pantalla principal del ISE aparecer como se muestra en la figura 5.3.


Indicados con nmeros se encuentran:
(1). Barra de herramientas
(2). Ventana de archivos fuentes
(3). Ventana de procesos
(4). rea de trabajo, reportes, simulacin, etc.
(5). Ventana de actividades.

114

Figura 5.3: Ventana principal de ISE.

1. Vamos a File > New Project,


aparecer la ventana de Project
Wizard- Create New Project. En este cuadro introduciremos
nombre del proyecto que vamos a crear, la carpeta donde se alojara
el
proyecto
y
en
el
men
de
tipo
de
fuente
para
level,
elegiremos HDL.

el

Top

2. El siguiente cuadro es el de las propiedades del dispositivo que


vamos a utilizar para el diseo, sea este un FPGA o un CPLD.
Escogemos de la lista la pieza adecuada, es recomendable revisar las
hojas tcnicas de la pieza para poder seleccionar correctamente los
parmetros de velocidad, empaquetaduras y categoras. Elegimos la
herramienta de sntesis a XST (VHDL/Verilog) al igual que el
simulador de acuerdo al que se tenga disponible. ISE Simulator
(VHDL/Verilog) viene de paquete con el programa ISE. Tambin es
posible obtener una versin compacta de ModelSim de Mentor
Graphics llamada ModelSimXE que tiene muy buenas caractersticas.
3.

En la opcin para crear una nueva fuente seleccionamos nueva


fuente (new source), de inmediato aparece una ventana con varias
opciones, escogemos verilog Module y le asignamos un nombre. Al
pulsar el botn de siguiente aparece un cuadro para definir los
puertos de nuestro modulo, ah se deber escribir el nombre de las
lneas de entrada y salida, as mismo definir la longitud de los
vectores o si son escalares.

115

4. La siguiente ventana nos muestra un resumen de los parmetros


definidos para nuestro modulo, si algo esta incorrecto se puede
regresar para redefinir los parmetros.
5. A continuacin se nos presenta una vez mas la ventana de creacin
de nueva fuente, ah podremos ver el nombre de nuestro modulo
recin definido. Si se desea incluir mas mdulos se debe repetir el
proceso o tambin es factible aadir ms mdulos posteriormente.
6. Por ultimo tenemos una ventana final de resumen donde se
encuentran los mdulos y el detalle de parmetros para su revisin.
Al pulsar el botn de finish, aparecer en la ventana de trabajo en
cdigo Verilog la definicin del modulo recin creado con la
descripcin de ingresos y salidas. Desde este punto podemos
empezar a escribir el cdigo para nuestro sistema.
En la ventana de archivos fuentes se podr ver tambin el modulo recin
creado bajo el dispositivo que hemos escogido para el diseo.
Si se requiere adicionar un nuevo modulo al sistema basta con posicionarse
en la ventana de fuentes y con el botn derecho del ratn escogemos Add
New Source o si ya tenemos un modulo creado la opcin Add Source, y
seguimos los pasos ya antes vistos.
Una vez definido y descrito el cdigo de nuestro modulo debemos primero
verificar si tenemos errores de sintaxis, para ello usamos en la ventana de
procesos la opcin implement design, extendemos las opciones y buscamos
sinthesize > check syntax, mediante el uso del botn derecho del ratn
corremos el proceso con run o Rerun.
Es importante que en la ventana de archivos fuentes en la lista desplegable
que esta en la parte superior se escoja la opcion Sntesis - Implementation.
En la ventana de actividades en la pestaa console se podr ver los
distintos procesos cuando son ejecutados, as mismo en caso de errores o
mensajes de advertencia se pudran ver los detalles en las respectivas
pestaas.
Una vez corrido el proceso de verificacin de sintaxis, estamos listos para
ejecutar la herramienta sntesis, que es el proceso de transformar el cdigo
HDL en registros de transferencia de nivel o RTL, en este nivel el cdigo se
convierte en elementos regidos por ecuaciones lgicas. Para correr el
proceso de sntesis usamos botn derecho del ratn sobre Sinthesize- XST y
seleccionamos Run o Rerun. De la misma manera los mensajes del proceso
de sntesis y sus errores o advertencias pueden ser observados en la
ventana de Consola y las respectivas especficas.

116

Si el proceso de sntesis ha sido correcto se podr verificar el esquema


generado por nuestro cdigo usando las opciones view RTL schematic o
view Technology schematic. La primera opcin como ya se menciono nos
muestra el circuito de forma general como se ve a nivel de RTL en forma de
compuertas, registros etc. La otra opcin es mas especifica, muestra la
forma de cmo se implementara fsicamente de acuerdo a los recursos del
dispositivo que se utilice, a las libreras del sistema, etc. Este proceso es
una forma mas especifica del dispositivo a usarse.
Para simular nuestro sistema debemos contar con un archivo de pruebas,
para esto se puede crear de 2 formas. La primera mas sencilla
recomendada para sistemas pequeos y personas menos diestras en el
lenguaje HDL es utilizar la herramienta para crear formas de onda provista
por ISE y la segunda crear un archivo de pruebas descrito en un lenguaje
HDL, esta opcin da la facilidad al diseador de realizar las pruebas que el
requiera y de la manera mas conveniente para el, pero se requiere de una
mayor destreza y un manejo mas avanzado del lenguaje. En este caso se
trabajara con la primera opcin.
Para esto, en la ventana de archivos fuentes, seleccionamos del men
desplegable behavioral simulation, sobre esta misma ventana mediante el
botn derecho adicionamos una nueva fuente, la ventana de tipo de fuente
aparecer y seleccionaremos Test Bench WaveForm, le asignaremos un
nombre. A continuacin se nos preguntara a que modulo se desea
relacionar estas formas de onda, seleccionaremos el modulo que deseamos
en caso de existir mas. Por ultimo aparecer una ventana de sumario con
los detalles.
Una vez aceptado aparecer una ventana de configuracin de la forma de
onda, parmetros para definicin de los periodos de reloj en caso de contar
con uno o tiempos de respuesta pueden ser definidos en esta ventan,
adems longitud de la prueba, entre otros parmetros. Una vez definido
esto esta ventana cerrara y en el rea de trabajo aparecer un grafico de
tiempos con las ondas definidas, al igual con las lneas de entrada y salidas
especificadas en nuestro modulo. Mediante el uso del ratn se puede
modificar niveles en entradas al modulo para acondicionar la prueba a
nuestros requerimientos. Una vez terminado este proceso cerraremos la
ventana de formas de onda y aceptaremos cuando se pregunte si
deseamos grabar los cambios.
Al cerrarse esta ventana notaremos que en la ventana de archivos fuentes
se creo el archivo que definimos para la prueba y debajo de este se
encuentra nuestro modulo el cual vamos a probar. En la ventana de
procesos veremos una opcin llamado Xilinx ISE Simulator con 2 procesos,
Generate expected simulation results, y simulate Behavioral model. Si
corremos el primer proceso en la ventana de trabajo aparecer la forma de
onda especificada por nosotros y veremos las salidas de nuestro modulo
como se comportan ante las entradas definidas. La segunda opcin se

117

utiliza para poder hacer un seguimiento paso a paso o continuo por las
definiciones en nuestro cdigo HDL, tambin se presentara un diagrama de
tiempos para su anlisis.
Despus de haber realizado las pruebas necesarias para nuestro modulo y
realizado las correcciones requeridas, el prximo paso seria implementar
nuestro diseo en el dispositivo que se eligi usar. Para esto debemos
definir las restricciones
primero, para esto utilizamos la opcin User
Constraints y corremos el proceso Assign package pins este abrir un
programa llamado PACE en donde podemos asignar los pines a nuestras
entradas y salidas de nuestro modulo, tambin podremos definir los niveles
de voltaje y tipos como LVTTL, CMOS3.3, CMOS2.5 etc. Si requerimos tener
colectores abiertos en las salidas entre otras opciones. Las restricciones
abarcan una gran cantidad de propiedades que se pueden definir, mediante
PACE nicamente seleccionamos las restricciones de emplazamiento en el
chip. Restricciones de tiempos u otras ms avanzadas se las puede definir
utilizando el editor de restricciones o describiendo en un archivo de texto
las restricciones. Xilinx provee todo un manual completo sobre el uso y
propiedades de las restricciones para usarlas tanto en FPGAs y CPLDs. Para
nuestro propsito utilizaremos nicamente restricciones asignadas por
PACE.
Una vez definido nuestras restricciones, buscamos el proceso Implement
Design, que abarca algunos procesos ya utilizados antes y algunos nuevos
que nicamente se pueden correr si tenemos definidas nuestras
restricciones, tales como Fit y Translate. El primero se encarga de encajar
nuestro diseo en el dispositivo seleccionado utilizando las restricciones
definidas y los archivos generados por Translate.
Tambin se corre el proceso que genera los archivos de programacin para
ser implementados en el CPLD o FPGA a travs del programa IMPACT. y el
programa Impact y el respectivo cable de programacin JTAG.
Esta breve explicacin constituye una pequea introduccin al uso del
programa ISE y la implementacin de un diseo a travs de este programa.
La documentacin existente para cada proceso y algunos no citados aqu es
muy extensa. Es recomendable revisar esta informacin para obtener
mayores detalles y caractersticas operativas de ISE.

5.3

Ejemplos Prcticos.
En este numeral se vern algunos ejemplos prcticos a manera didctica de
tal forma que se pueda comprender mejor el proceso de diseo digital
utilizando lenguaje HDL Verilog y el programa de desarrollo ISE.
Los primeros ejemplos demostraran mdulos muy generales y tiles que
sern posteriormente utilizados en otros ejemplos mas complejos.

118

5.3.1

Diseo de un decodificador de BCD a 7 Segmentos multiplexado


para display de LED.
Descripcin:
Se requiere disear un decodificador - manejador para display de 7
segmentos con entrada de BCD y salida de 7 segmentos multiplexados para
cuatro digitos.
Requerimientos:

Ingreso formato BCD


Salida 7 segmentos Activos a nivel lgico 0. Display nodo Comn.
Salida de 4 bits para manejo de transistores PNP para nodos
comunes.

Diseo:
Para lograr este diseo se ha dividido en partes al sistema, primeramente
se ha creado un modulo llamado BCD7SEG que se encarga de codificar la
entrada de BCD en cdigo 7 segmentos activo a nivel lgico 0. La tabla 5.1
muestra el contenido de la tabla creada para la decodificacin.
CODIGO BCD
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

CODIGO 7 SEGMENTOS
0000001
1001111
0010010
0000110
1001100
0100100
0100000
0001111
0000000
0001100
0001000
1100000
1110010
1000010
0110000
0111000

CARCTER
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

TABLA 5.1: Decodificador de BCD-7SEG para display

El modulo de BCD7SEG utiliza una salida a tres estados que se logra con la
seal de entrada de habilitacin "enable", cuando esta lnea se encuentra a
nivel lgico 0 las salidas del decodificador se activan caso contrario
permanecen en alta impedancia. El propsito de esto es de poder unir mas
mdulos de este tipo de acuerdo al numero de
displays que tenga el
sistema y controlar mediante la activacin de "enable" cual de los mdulos
ser activo.

119

El modulo principal se lo ha denominado Display4BCD, este es nuestro


modulo Top. El el se han creado los siguientes componentes: un divisor de
frecuencia que divide la frecuencia del reloj de 1.8432 Mhz para 2048 es
decir baja a una frecuencia de 900Hz que se utilizara para el refresco de los
displays. Un registro de desplazamiento de 4 bits y un contador de 4
estados que se encargan de la activacin de los transistores y 4 instancias
del modulo BCD7SEG para manejo de cada uno de los dgitos.
Se ha definido un vector de 16 bits que lleva la informacin de los datos
BCD a cada uno de los displays, cada cuatro bits forman un dato, es decir
para el decodificador 1 la informacin esta comprendida por el vector [0:3],
para decodificador 2: [7:4], decodificador 3: [11:8] y para el decodificador
4 : [15:11].
Esquema de Bloques:
16
BCD[15:0]

BCD[3:0]

7SEG

BCD7SEG
En
CLK

Divisor

Cont
/
mux

BCD[7:4]

BCD7SEG
En

BCD[11:8]

BCD7SEG
En
D1
7
BCD[15:12]

D2
D3
D4

BCD7SEG

Display4BCD

En

FIGURA 5.4: Modulo Display4BCD

Implementacin del cdigo Verilog HDL:


////////////////////////////////////////////////////////////////////////////////////////////////////
//Modulo Display 4 digitos, toma una entrada de 4 digitos en BDC
//que ingresa por InBCD y la convierte en 7 segmentos para display
//de cuatro digitos multiplexados el vector Data7Seg contiene la
//informacion decodificada, el vector OutEnables contiene las lineas
//de activacion para transistores en los displays. La frecuencia de
//refresco viene dada por CLOCK y el registro divisor. Reset entrada
//general de reset. Se crean 4 instancias de BCD a 7 Segmentos.
////////////////////////////////////////////////////////////////////////////////////////////////////
module Display4BCD(CLK, InBCD, OutEnables, Data7seg);
parameter VALOR_DIVISOR = 12'd2048;
input CLK;

120

input [15:0]InBCD;
output [3:0]OutEnables;
output [6:0]Data7seg;
reg [3:0]OutEnables = 4'b1110;
reg [11:0]Divisor = 12'b0;
reg [3:0]Auxiliar=4'b0001;

BCD7SEG Digito1(OutEnables[0], InBCD[3:0], Data7seg);


BCD7SEG Digito2(OutEnables[1], InBCD[7:4], Data7seg);
BCD7SEG Digito3(OutEnables[2], InBCD[11:8], Data7seg);
BCD7SEG Digito4(OutEnables[3], InBCD[15:12], Data7seg);
always@(posedge CLK)
if(Divisor == VALOR_DIVISOR-1)
begin
Divisor <= 0;
if(Auxiliar[3]==1'b1)
begin
Auxiliar<=4'b0001;
OutEnables[3:0] <= ~Auxiliar;
end
else
begin
Auxiliar <= Auxiliar << 1'b1;
OutEnables <= ~Auxiliar;
end
end
else
Divisor <= Divisor+1;
endmodule
/////////////////////////////////////////////////////////////////////////////////////////
//Modulo de BCD a 7 segmentos, entra 4 bits en BCD y sale
//7 bits a 7 segmentos, la salida se activa solo cuando
//la seal de Enable esta en alto, de lo contrario todas las
//salidas permanecen en alta impedancia.
//////////////////////////////////////////////////////////////////////////////////////////
module BCD7SEG(Enable, Data_BCD, Out7Seg);
input Enable;
input [3:0] Data_BCD;
output reg [6:0] Out7Seg = 7'bzzzzzzz;
always @(Enable or Data_BCD)
if(!Enable)
begin
case (Data_BCD)
4'b0000 : Out7Seg <= 7'b0000001;

// 0

121

4'b0001 : Out7Seg <= 7'b1001111; // 1


4'b0010 : Out7Seg <= 7'b0010010; // 2
4'b0011 : Out7Seg <= 7'b0000110; // 3
4'b0100 : Out7Seg <= 7'b1001100; // 4
4'b0101 : Out7Seg <= 7'b0100100; // 5
4'b0110 : Out7Seg <= 7'b0100000; // 6
4'b0111 : Out7Seg <= 7'b0001111; // 7
4'b1000 : Out7Seg <= 7'b0000000; // 8
4'b1001 : Out7Seg <= 7'b0001100; // 9
4'b1010 : Out7Seg <= 7'b0001000; // A
4'b1011 : Out7Seg <= 7'b1100000; // b
4'b1100 : Out7Seg <= 7'b1110010; // C
4'b1101 : Out7Seg <= 7'b1000010; // d
4'b1110 : Out7Seg <= 7'b0110000; // E
4'b1111 : Out7Seg <= 7'b0111000; // F
default : Out7Seg <= 7'bzzzzzzz; // 0
endcase
end
else
Out7Seg <= 7'bzzzzzzz;
endmodule

Esquema RTL:

FIGURA 5.5: Mdulo Display4BCD en Bloque Generado por XST.

FIGURA 5.6: Mdulo Display4BCD esquemtico Generado por XST.

122

Simulaciones y pruebas:
Para las simulaciones del sistema se defini un archivo tipo Test Bench
utilizando el asistente que proporciona el programa ISE. En este archivo se
defini el valor del reloj, y las entradas de comprobacin que en este caso
es el patrn en BCD 16'h1234.

FIGURA 5.7: Simulacin para mdulo Display4BCD

Los resultados de las simulaciones se los pueden observar en la figura 5.7.


Podemos ver que para cada valor de la habilitacin de las salidas o
activacin de nodos comunes tenemos un valor del cdigo en BCD
cumpliendo los requerimientos que tenamos.
Hay que resaltar que el valor del divisor se redujo de tal forma que se
facilite la simulacin del sistema. Esto se debe tener en cuenta el momento
de realizar las pruebas en circuito real y colocar el valor correcto ya que al
dejar
el
valor
de
pruebas
el
funcionamiento
del
display
no
ser
el
adecuado.
Implementacin Fsica:
Seal
(Salida7Seg_6)
A
B
C
D
E
F
G
(Salida7Seg_0)

Dir

Con A

Con B

Con D

CoolRunner II pin

33

10

34

35

36

37

38

39

123

OUT0

19

21

OUT1

20

22

OUT2

21

23

OUT3

22

24

CLK

TABLA 5.2: Distribucin de pines y conectores Proyecto Display4BCD

La implementacin fsica se la realizo de acuerdo a la tabla 5.2. El modulo


Display4BDC necesita una seal de 16 bits en formato BCD como ingreso al
modulo, lo que se hizo para efectos de prueba es definir internamente un
vector de 16 bits al cual se le dio el valor de prueba 16'h0235 y se lo
verifico en el kit de desarrollo y la placa de interfase, obtenindose los
resultados esperados.

5.3.2

Diseo de un decodificador de teclado de matriz de 3x4 teclas.


Descripcin.
Este diseo propone la implementacin de un decodificador para teclado de
matriz de 3x4 teclas.
Requerimientos.

Manejo de teclado matriz de 4 filas por 3 columnas.


Eliminacin del rebote de las teclas pulsadas.
Almacenamiento de 4 cdigos en 4 registros.
Seal de indicacin de tecla pulsada.

Diseo.
Para la implementacin del manejador de teclado matriz se ha dispuesto
un modulo principal al cual se lo denomin KeyScan.
Este modulo esta
conformado por varios sub-modulos los cuales iremos detallando a
continuacin.

MTXdecoder, que realiza la funcin de generar un pulso en cada fila para el


muestreo. Las lineas de las columnas del teclado son usadas como
ingresos, cuando una tecla es pulsada este bloque recibe la informacin de
la columna y verifica con la fila para establecer el valor de la tecla pulsada.
Una compuerta OR recoge cualquiera de las seales de las columnas y
activan la seal de Triegger del modulo monoestable que realiza la funcion
de antirebotes, al recibir una seal activa a uno dispara un pulso que a su
vez sirve como seal de entrada para un contador decodificador de 2 a 4 el
cual habilita los slip-flop tipo D que capturan el valor del codigo. El modulo
divisor divide la seal de reloj principal en 2 frecuencias F2 y F1 que es =
F2/2
F2 es mas lenta y se usa para generar la base de tiempo del
muestreo.

124

En la figura
5.6 podemos observar el diagrama de bloques del modulo
decodificador de teclado matriz.
Esquema de Bloques:

MTXDecoder

F1

F2

F3

F4

Registro

F1
F2

Q0

D0

Q0

F3

Q1

D1

Q1

F4

Q2

D2

Q2

Q3

D3

Q3

En

C1

C1
C2
C3

Q0
Q1
Q2
Q3

C2
C3

CLK

Registro

Contador Decoder
O_1

D0

Q0

O_2

D1

Q1

O_3

D2

Q2

D3

Q3

O_4

Q4
Q5
Q6
Q7

CLK
En

Divisor
Registro

CLKO_2

CLK

CLK
CLKO_1

D0

Q0

D1

Q1

D2

Q2

D3

Q3

Q8
Q9
Q10
Q11

En
Monoestable
CLK
Pulso
Registro
Trigger
D0

Q0

D1

Q1

D2

Q2

D3

Q3

Q12
Q13
Q14
Q15

En

RDY

KEYSCAN

FIGURA 5.6: Modulo KeyScan, manejador de teclado matriz.

Implementacin del cdigo Verilog HDL:


module KeyScan(CLK, FILAS, COLUMNAS, Q, PULSEOUT);
input CLK;
output PULSEOUT;
output [15:0]Q;
wire [3:0]Q1;
wire [3:0]Q2;
wire [3:0]Q3;
wire [3:0]Q4;
wire CLK2;
wire CLK1;
output [3:0]FILAS;

//Frecuencia / para h4000


//Frecuencia / para h2000

input [2:0] COLUMNAS;


wire [3:0] OUTCODE;

125

wire TRIGGER;
wire [3:0] EnFFD;
wire RDY;
wire Disable;
assign TRIGGER = |COLUMNAS;
assign Q[3:0] = Q1;
assign Q[7:4] = Q2;
assign Q[11:8] = Q3;
assign Q[15:12] = Q4;
PulseGen PULSE(CLK1, TRIGGER, PULSEOUT);
MTXDecoder MTX(CLK2, FILAS, COLUMNAS, OUTCODE);
Divisor DIV(CLK, CLK1, CLK2);
Habilitador SHIFT2(PULSEOUT, EnFFD);
FFD FF1(OUTCODE, EnFFD[0], Q1);
FFD FF2(OUTCODE, EnFFD[1], Q2);
FFD FF3(OUTCODE, EnFFD[2], Q3);
FFD FF4(OUTCODE, EnFFD[3], Q4);
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo decodificador de teclado, utiliza un contador de 4 estados y un
// decodificador de 2 a 4 para generar el pulso de salida para las filas. En
// las columnas recibe la informacin si una tecla ha sido pulsada y la decodifica
//colocando el valor del codigo en OUTCODE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module MTXDecoder(CLK ,FILAS, COLUMNAS, OUTCODE);
input CLK;
output [3:0]FILAS;
input [2:0]COLUMNAS;
output reg [3:0]OUTCODE = 4'b0;
reg [1:0]Contador = 2'b0;
Selector2a4 LS139(Contador, FILAS);

always @(posedge CLK)


begin
if(Contador==2'd3)
Contador <= 0;
else
Contador <= Contador + 1'd1;
end

126

always @(negedge CLK)


begin
case(Contador)
0: begin
case(COLUMNAS)
1: OUTCODE <= 4'd1;
2: OUTCODE <= 4'd2;
4: OUTCODE <= 4'd3;
endcase
end
1: begin
case(COLUMNAS)
1: OUTCODE <= 4'd4;
2: OUTCODE <= 4'd5;
4: OUTCODE <= 4'd6;
endcase
end
2:

begin
case(COLUMNAS)
1: OUTCODE <= 4'd7;
2: OUTCODE <= 4'd8;
4: OUTCODE <= 4'd9;
endcase
end

3: begin
case(COLUMNAS)
1: OUTCODE <= 4'd10;
2: OUTCODE <= 4'd0;
4: OUTCODE <= 4'd12;
endcase
end
endcase
end
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module Selector2a4(S, Salida);
input [1:0] S;
output reg [3:0] Salida=4'b0001;
always@*
case (S)
0:
1:

Salida <= 4'b0001;


Salida <= 4'b0010;

127

2:
3:
endcase

Salida <= 4'b0100;


Salida <= 4'b1000;

endmodule

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo que crea un pulso de duracion igual a N pulsos del reloj de entrada
// definido por CLK, los pulsos se definen en el parametro VALORPULSO, la
// salida es re-trigerable, es decir si se mantiene el valor de TRIGGER en
// 1 la salida repetira el pulso
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module PulseGen(CLK, TRIGGER, PULSEOUT );
input CLK;
input TRIGGER;
output reg PULSEOUT=0;
reg [15:0]Cont = 16'b0;
parameter VALORPULSO = 20;
always @(negedge CLK )
begin
if(TRIGGER & !PULSEOUT)
PULSEOUT <= 1;
else if(PULSEOUT)
begin
if(Cont==VALORPULSO-1)
begin
PULSEOUT <=0;
Cont <= 0;
end
else
Cont <= Cont + 1'b1;
end
end
endmodule
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo que sintetiza un divisor de frecuentcia, tiene como entrada la seal
// de CLK y como salida la seal de CLKOUT, la frecuencia se divide utiliazando
// el parametro VALORDIVISOR, el maximo valor de frecuencia posible a dividir
// es 2^18.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module Divisor(CLK, CLKOUT1, CLKOUT2);

128

input CLK;
output reg CLKOUT1=1;
output reg CLKOUT2=1;
reg [17:0]Cont = 18'b0;
parameter VALORDIVISOR2 = 15'h4000;//16384;//1KHz fecuencia de muestreo
parameter VALORDIVISOR1 = VALORDIVISOR2/2;//15'h2;
always @(posedge CLK)
begin
if(Cont == (VALORDIVISOR1-1))
begin
CLKOUT1 <= ~CLKOUT1;
end
if(Cont == (VALORDIVISOR2-1))
begin
CLKOUT2 <= ~CLKOUT2;
CLKOUT1 <= ~CLKOUT1;
Cont <= 0;
end
else
Cont <= Cont + 1'b1;
end
endmodule
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo que sintetiza un registro de desplazamiento, tiene como entrada la
// seal de CLK y salida un registro de cuatro bits OUTREG, se desplaza un 1
// en OUTREG con cada flanco de subida de CLK
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module Habilitador(CLK, OUTREG);
input CLK;
output [3:0] OUTREG ;
wire [3:0]OUTR;
reg [1:0] aux_cont = 2'b0;
Selector2a4 LS139(aux_cont, OUTR);
assign OUTREG[0] = OUTR[1] & CLK;
assign OUTREG[1] = OUTR[2] & CLK;
assign OUTREG[2] = OUTR[3] & CLK;
assign OUTREG[3] = OUTR[0] & CLK;
always @(posedge CLK)
aux_cont <= aux_cont+ 1'd1;

129

endmodule

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo que sintetiza un FLIP-FLOP tipo D de cuatro canales.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module FFD(D, Enable, Q);
input [3:0]D;
input Enable;
output reg [3:0]Q = 4'b0;
always @(Enable)
if(Enable)
Q <= D;
endmodule

Esquema RTL:

FIGURA 5.8: Mdulo KeyScan en Bloque Generado por XST.

FIGURA 5.9: Mdulo KeyScan esquemtico Generado por XST.

Simulaciones y pruebas:
Para poder
simulaciones
el

verificar el funcionamiento del sistema se realizaron las


de
cada
modulo
por
separado.
Una
vez
comprobado

130

correcto funcionamiento de cada parte se realizo un archivo Test Bench del


modulo KeyScan. Para la simulacin se bajaron los tiempos del divisor de
4'h4000 a 4'h4. El estimulo en las columnas se lo realizo para el codigo "A"
en la figura 5.10,
y el codigo 0, los resultados podemos observarlos
cumpliendo con los requerimientos impuestos.

FIGURA 5.10: Simulacin modulo KeyScan, manejador de teclado matriz.

Implementacin Fsica:
Seal

Dir

Con A

Con B

Con D

CoolRunner pin

A (Salida7Seg_6)

33

10

34

35

36

37

38

G (Salida7Seg_0)

39

OUT0

19

21

OUT1

20

22

OUT2

21

23

OUT3

22

24

CLK

COLUMNAS0

142

COLUMNAS1

140

COLUMNAS2

139

FILAS0

10

136

FILAS1

11

135

FILAS2

12

134

FILAS3

13

133

PULSEOUT

14

132

TABLA 5.3: Distribucin de pines y conectores proyecto KeyScan

Para poder verificar el funcionamiento fsico del sistema se utiliz una


instancia del modulo Display4BCD conectado a la salida del modulo
KeyScan, los pines del CPLD y los respectivos conectores y seales se

131

muestran en la tabla 5.3, El resultado de la prueba fue acorde a lo


esperado.

5.3.3

Diseo de un contador sncrono visualizado, pulsante


inicio/paro, reset, selector de arriba/abajo, selector de conteo
Lento/Rpido y carga por teclado.

de

Descripcin.
Se requiere disear un contador sncrono MOD1000 con entrada para un
pulsante de inicio/paro, entrada de reset y salida para visualizacin en un
display de 4 dgitos a 7 segmentos, tambin debe poseer una entrada de
selector de conteo arriba/abajo y capacidad de carga por teclado.

Requerimientos.

Selector de Inicio/Paro
Selector de conteo Rpido/Lento
Selector de conteo Arriba/Abajo
Entrada de Reset.
Numero MOD 10000
Posibilidad de carga por teclado
Visualizacin en display de LED 7 segmentos.

Diseo.
Para lograr el diseo se ha dividido al circuito en 4 partes, modulo GenCLK,
que se encarga de dividir la frecuencia de acuerdo a la entrada R/L
(Rapido/Lento), modulo Display4BCD, que es el encargado de realizar el
manejo del display de 7 segmentos, modulo KeyScan que maneja el teclado
matricial de 3x4 y modulo contador que es el encargado de realizar el
conteo, este modulo trabaja en BCD directamente, realiza conteo
arriba/debajo de acuerdo a la seal Ar/Ab.
La salida del modulo contador va directamente al modulo Display4BCD para
la visualizacin. Este modulo tambin recibe la informacin del modulo
KeyScan que modifica directamente el valor de los contadores para realizar
la carga por teclado.

132

Esquema de Bloques:

CLK

DISPLAY 7 segmentos

1
7

GenCLK
R/L

Display4BCD
4
1

RST

Hab

Ar/Ab

16

Contador BCD
MOD 1000

CLK
4
16

KeyScan

Contador
FIGURA 5.11: Esquema en bloques Modulo Contador.

Implementacin:
En el codigo descrito a continuacin no se ha incluido el cdigo de los
mdulos Display4BCD y KeyScan ya que estos ya fueron descritos
anteriormente, solamente se encuentra las instancias de estos.

Cdigo Verilog.
//////////////////////////////////////////////////////////////////////////////
//Modulo principal del sistema, incluye el contador,
//el modulo de visualizacion, control de teclado matriz
// y generador de frecuencias de conteo que es un divisor
// de la frecuencia del reloj en 2 frecuencias para alimentar
// al contador
//////////////////////////////////////////////////////////////////////////////
module TOP(CLK, UpDn, ResetG, Enable, SlowFast, OutEnab, Salida7seg,
FILAS, COLUMNAS, PULSEOUT, Carga);
input CLK;
input ResetG;
input UpDn;
input Enable;
input SlowFast;

133

output [3:0] OutEnab;


output [6:0] Salida7seg;
wire [15:0] Salida;
wire InCONT;
wire ResetG;
wire OUTCLK;
output [3:0]FILAS;
input [2:0]COLUMNAS;
wire [15:0]Q;
output PULSEOUT;
wire PULSEOUT;
input Carga;
assign InCONT = OUTCLK;
Contador CONT(InCONT, UpDn, ResetG, Enable, Salida, Q, PULSEOUT);
Display4BCD Display(CLK, Salida, OutEnab, Salida7seg);
GenFrec GENCLOCK(CLK, SlowFast, OUTCLK);
KeyScan KEYPAD(CLK, FILAS, COLUMNAS, Q, PULSEOUT);
Endmodule

//////////////////////////////////////////////////////////////////////////////////////////
//Contador sincrono con entrada Habilitacion, reset,
//cuenta mientras la habilitacion este en estado 1 y hasta un
//maximo definido en el parametro MAX_CONTEO.
//Cuenta en BCD en vector Contador de 16 bits
/////////////////////////////////////////////////////////////////////////////////////////
module Contador(InCONT, UpDn, Reset, Enable, Contador, Q, Carga);
parameter MAX_CONTEO = 16'b1001_1001_1001_1001;
input InCONT;
input Reset;
input UpDn;
input Enable;
output [15:0] Contador;
reg [15:0] Contador;
input [15:0]Q;
input Carga;

initial
Contador[15:0]=16'b0000_0010_0011_0101;

134

always@(posedge InCONT or posedge Reset or posedge Carga)


begin
if(Reset)
Contador [15:0] <= 16'b0;
else if(Carga)
Contador <= Q;
else
begin
if(UpDn & Enable)
begin
if(Contador == MAX_CONTEO)
Contador<=0;
else
begin
if(Contador[3:0]== 9)
begin
Contador[3:0]<= 0;
if(Contador[7:4]== 9)
begin
Contador[7:4]<=0;
if(Contador[11:8]== 9)
begin
Contador[11:8]<=0;
if(Contador[15:12] == 9)
Contador[15:12]<=0;
else
Contador[15:12]<=Contador[15:12]+1;
end
else
Contador[11:8]<=Contador[11:8]+1;
end
else
Contador[7:4]<=Contador[7:4]+1;
end
else
Contador[3:0]<=Contador[3:0]+1;
end
end
else if(Enable)

135

begin
if(Contador == 0)
Contador<=MAX_CONTEO;
else
begin
if(Contador[3:0]== 0)
begin
Contador[3:0] <= 9;
if(Contador[7:4]== 0)
begin
Contador[7:4]<=9;
if(Contador[11:8]== 0)
begin
Contador[11:8]<=9;
if(Contador[15:12]

==

0)
Contador[15:12]<=9;
else
Contador[15:12]<=Contador[15:12]-1;
end
else
Contador[11:8]<=Contador[11:8]-1;
end
else
Contador[7:4]<=Contador[7:4]1;
end
else
Contador[3:0]<=Contador[3:0]-1;
end
end
end
end
endmodule

//////////////////////////////////////////////////////////////////////////////////////////////////
//Modulo generador de clock
//Se encarga de dividir la frecuencia de entrada al contador en 2
//frecuencias para eso se implementa un contador con 2 parametros
//de conteo, SLOW y FAST que estan controlados por la seal de
//SlowFast.
/////////////////////////////////////////////////////////////////////////////////////////////////
module GenFrec(CLK, SlowFast, OUTCLK);

136

parameter DIVISOR_SLOW = 20'd230400;


parameter DIVISOR_FAST = DIVISOR_SLOW / 4;
input CLK;
input SlowFast;
output reg OUTCLK;
reg [19:0]Divisor = 20'b0;
always@(posedge CLK)
if(SlowFast)
begin
if(Divisor == DIVISOR_SLOW)
begin
OUTCLK <= ~OUTCLK;
Divisor <= 0;
end
else
Divisor <= Divisor+1;
end
else
begin
if(Divisor == DIVISOR_FAST)
begin
OUTCLK <= ~OUTCLK;
Divisor <= 0;
end
else
Divisor <= Divisor+1;
end
endmodule

Esquema RTL:

FIGURA 5.12: Esquema en bloques Modulo Contador Generado por XST.

137

FIGURA 5.13a: Esquema esquemtico Modulo Contador generado por XST.

Simulaciones y pruebas:
En las figuras 5.14 a y 5.14b se muestran los diagramas de tiempos para el
contador. Ntese que el valor de Q posee el valor para la carga del
contador. El valor inicial del contador se lo a fijado en 16'd565 y al valor de
la carga en 16'd4660, equivalente a 16'h1234.

FIGURA 5.14a: Esquema esquemtico Modulo Contador generado por XST

FIGURA 5.14b: Esquema esquemtico Modulo Contador generado por XST

Este diagrama de tiempos solo refleja el comportamiento del contador


como tal, no estn considerados los diagramas para los mdulos de display,

138

teclado y divisor ya que estos ya se han probado en funcionamiento


anteriormente.

Implementacin Fsica:
Dir

Con A

A (Salida7Seg_6)

Seal

33

Con B

Con D

CoolRunner pin
10

34

35

36

37

38

G (Salida7Seg_0)

39

OUT0

19

21

OUT1

20

22

OUT2

21

23

OUT3

22

24

CLK

Carga

41

ResetG

39

UpDn

40

Enable

11

35

SlowFast

10

34

OutCLK

40

COLUMNAS0

142

COLUMNAS1

140

COLUMNAS2

139

FILAS0

10

136

FILAS1

11

135

FILAS2

12

134

FILAS3

13

133

PULSEOUT

14

132

TABLA 5.4: Distribucin de pines y conectores proyecto Contador

En la tabla 5.4 podemos observar en los pines utilizados para la


implementacin del contador, ntese que se ha implementado restricciones
en el posicionamiento de los pines, es decir se ha asignado para cada
modulo que hemos venido creando pines del CPLD y acorde a nuestros
nuevos requerimientos hemos adicionado diferentes entradas o salidas al
sistema.
En las pruebas fsicas implementadas en el kit de desarrollo XC2-XL y la
placa de interfase se pudo comprobar el correcto funcionamiento del
sistema implementado.

5.3.4

Diseo de un controlador para motor de pasos.

139

Descripcin.
En esta aplicacin se disear un controlador simple para un
pasos de 4 fases unipolar. Este controlador realizara funciones
como generacin de las seales para las bobinas, movimiento
atrs y habilitacin y des-habilitacin de las salidas al modulo de potencia.
Todas estas funciones se realizaran en modo "FULL-STEP" o
completo.

motor de
simples
adelante,
de paso

Para efectos de prueba del controlador de motor de pasos se creara un


modulo de pruebas el cual realizar las funcion siguiente:
Arranque adelante del motor en velocidad lenta, llegado a los h500 pulsos
el motor se acelera al doble de la velocidad de arranque hasta llegar a los
h999, momento en el cual cambia de direccin, llega nuevamente a los 500
pulsos y desacelera hasta llegar a 0 donde comienza nuevamente la
secuencia. Para visualizar el proceso se utilizara una instancia del modulo
Display4BCD y se creara un contador Up/Dn.

Requerimientos.

Manejo de Motor pasos unipolar de 4 fases.


Generacin de secuencias para desplazamiento adelante y atrs en
paso completo.
Ingreso de una sola seal de reloj o pulsos.
Seal de habilitacin de las salidas.
Modulo de prueba para el motor
Visualizacin del modulo de prueba en display 4 dgitos LED.

Diseo.
Los motores de pasos unipolares de 4 fases poseen 2
una
toma central que comnmente es alimentada con una tensin positiva.
B

bobinados

FIGURA 5.15: Motor De pasos Unipolar de 4 fases

140

con

La figura 5.15 muestra el diagrama de un motor de pasos unipololar de 4


fases.
Para el manejo de este tipo de motores utilizaremos un driver de potencia
ULN2803 el cual posee 8 salidas tipo colector abierto de 0.5A cada una a 40
VDC.
El esquema reducido de conexin para el driver y el motor se muestra en la
figura 5.16.
Vm

Drv Motor Pasos


CLK

A
A
B
B

A/R
Hab.

FIGURA 5.16: Motor De pasos Unipolar de 4 fases

El modulo que se ha creado para manejar el motor de pasos se lo a


denominado MotorDriver , este modulo recibe la entrada de los pulsos a
travs de una seal denominada CLK, el modulo realiza la secuencia de que
alimentar a los drivers de cada fase, que para paso completo o Full-Step
se logra alimentando cada bobina contigua a la vez por un periodo de
tiempo que en este caso vendr dada por el tiempo en alto del pulso de
CLK. Si la seal de A/R esta en 1 la secuencia ser en sentido horario, y si
es 0 la secuencia ser en sentido anti-horario esto determinara el giro del
motor adelante o atrs.
Si la seal de Enable esta habilitada siempre existir una bobina del motor
alimentada manteniendo la posicin, si Enable va a 0 todas las bobinas del
motor sern deshabilitadas.
Esquema de Bloques.

141

DISPLAY 7 segmentos
1

CLK
7Seg
Divisor

Display4BCD

CLK
Enb

InBCD
SloFst
CLK2
16
1
Contador
1
Pulsos

SloFst

U/D
Contador
U/D

CLK
Comparadores
A/R
Hab.

A
A
B
B

Drive r

Drv Motor Pasos


M

ModuloTOP

FIGURA 5.17: Esquema de Bloques para modulo prueba de Motor Pasos

Implementacin:
//////////////////////////////////////////////////////////////////////////////////
// Modulo de Prueba para modulo control de motor de pasos
// genera 2 frecuencias a partir de la frecuencia del
// reloj del sistema, se escoge la frecuencia con la seal
// SloFast. Se utiliza modulos de display, contadores sincronos
// y el divisor de frecuencia, y el modulo de prueba MotorDriver
//////////////////////////////////////////////////////////////////////////////////
module ModuloTOP(CLK, OutEnab, Data7seg, OUTREG, Reset, CLK2);
input CLK, Reset;
output [3:0]OutEnab;
output [6:0]Data7seg;
output CLK2;
wire [15:0] Contador;
wire CLK;
wire CLK2;
reg SloFast=0;
reg Enable=1;
reg F_R=1 ;
output [3:0]OUTREG;
reg [15:0] ValorMAX =16'd16;
reg [15:0] ValorMED =16'd8;
reg Top=0;

142

Display4BCD DISP1(CLK, Contador, OutEnab, Data7seg);


DivisorFrec DIV1(CLK, SloFast, CLK2);
MotorDriver MOT1(CLK2, Enable, OUTREG, F_R);
ContadorSinc CONT1(CLK2, Enable, Reset, F_R, Contador);
always @*
if(Reset)
begin
SloFast <=0;
F_R<=1;
Enable <=1;
Top<=0;
end
else if(Contador == 16'h500 && F_R==1'b1)
SloFast <= 1'b1; // 0
else if(Contador >= 16'h999)
begin
F_R <= 0;
Top<=1;
end
else if(Contador == 16'h500 && F_R==1'b0)
begin
SloFast <= 1'b0;
end
else if(Contador == 0)
begin
F_R<=1;
Enable <=1;
end
endmodule
/////////////////////////////////////////////////////////////////////////////////
// Modulo Divisor Divide la frecuencia de CLK
//para SLO_PARAM1 o SLO_PARAM2 dependiendo
// de la seal SloFast.
/////////////////////////////////////////////////////////////////////////////////
module DivisorFrec(CLK, SloFast, CLK2);
input CLK, SloFast;
output reg CLK2 = 1'b0;
reg [20:0]Divisor = 0;
parameter SLO_PARAM1 = 21'd10000;//0000;
parameter SLO_PARAM2 = 21'd20000;//0000;

143

always@(posedge CLK)
begin
if(SloFast)
begin
if(Divisor >= SLO_PARAM1-1)
begin
Divisor <= 4'b0000;
CLK2 <= ~CLK2;
end
else
Divisor <= Divisor + 1'b1;
end
else
begin
if(Divisor >= SLO_PARAM2-1)
begin
Divisor <= 4'b0000;
CLK2 <= ~CLK2;
end
else
Divisor <= Divisor + 1'b1;
end
end
endmodule
///////////////////////////////////////////////////////////////////
//Modulo MotorDriver
//
///////////////////////////////////////////////////////////////////
module MotorDriver(CLK, Enable, OUTREG, F_R);
input CLK, F_R, Enable;
output [3:0]OUTREG;
wire CLK, F_R, Enable;
GeneradorSecuencia GEN1(CLK, Enable, OUTREG, F_R);
endmodule

//////////////////////////////////////////////////////////////////////////////////////
// Modulo generador de secuencias para drivers de bobinas
// para motor de pasos unipolar
//////////////////////////////////////////////////////////////////////////////////////
module GeneradorSecuencia(CLK, Enable, OUTREG, F_R);
input CLK;
input F_R;
input Enable;
output [3:0] OUTREG ;

144

wire [3:0]OUTR;
reg [1:0] aux_cont = 2'b0;
Selector2a4 LS139(aux_cont, OUTR);

assign OUTREG[0] = (Enable)?(OUTR[2] & CLK):0;


assign OUTREG[1] = (Enable)?(OUTR[3] & CLK):0;
assign OUTREG[2] = (Enable)?(OUTR[0] & CLK):0;
assign OUTREG[3] = (Enable)?(OUTR[1] & CLK):0;
always @(posedge CLK)
if(F_R)
aux_cont <= aux_cont+ 1'd1;
else
aux_cont <= aux_cont- 1'd1;
endmodule
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Modulo contador sincrono con seleccion de Up/Dn, entrada de Enable, selector
//de Slow/Fast, cuando esta en Fast cuenta los pulsos del Reloj. Modificado
//Para pruebas de motor pasos
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module ContadorSinc(CLK, Enable, Reset, UpDn, Contador);
parameter MAX_CONTEO = 16'b0001_0000_0000_0000;
input CLK;
input Enable;
input Reset;
input UpDn;
output reg [15:0] Contador = 16'd1;

always@(posedge CLK or posedge Reset)


begin
if(Reset)
begin
Contador [15:0] <= 16'b0;
end
else if(Enable)
begin
if(UpDn)
begin
if(Contador == MAX_CONTEO)
Contador<=0;

145

else
begin
if(Contador[3:0]== 9)
begin
Contador[3:0]<= 0;
if(Contador[7:4]== 9)
begin
Contador[7:4]<=0;
if(Contador[11:8]== 9)
begin
Contador[11:8]<=0;
if(Contador[15:12] == 1)
Contador[15:12]<=0;
else
Contador[15:12]<=Contador[15:12]+1;
end
else
Contador[11:8]<=Contador[11:8]+1;
end
else
Contador[7:4]<=Contador[7:4]+1;
end
else
Contador[3:0]<=Contador[3:0]+1;
end
end
else
begin
if(Contador == 0)
Contador<=MAX_CONTEO;
else
begin
if(Contador[3:0]== 0)
begin
Contador[3:0] <= 9;
if(Contador[7:4]== 0)
begin
Contador[7:4]<=9;
if(Contador[11:8]== 0)

146

begin
Contador[11:8]<=9;
if(Contador[15:12] == 0)
Contador[15:12]<=9;
else
Contador[15:12]<=Contador[15:12]-1;
end
else
Contador[11:8]<=Contador[11:8]-1;
end
else
Contador[7:4]<=Contador[7:4]-1;
end
else
Contador[3:0]<=Contador[3:0]1;
end
end
end
end
endmodule

Simulaciones y pruebas:
En las figuras 5.18 se muestra el diagramas de tiempos para el modulo
MotorDriver. En las pruebas de funcionamiento se definieron las seales de
entrada de enable, F_R (adelante/Reversa) de la forma indicada para poder
probar las distintas respuestas del modulo, obtenindose los resultados
esperados. Obviamente los valores de los tiempos del reloj son nicamente
para propsitos de prueba.

FIGURA 5.18: Esquema de Tiempos para modulo MotorDriver

147

Implementacin Fsica:
Dir

Con A

A (Salida7Seg_6)

Seal

33

Con B

Con D

CoolRunner pin
10

34

35

36

37

38

G (Salida7Seg_0)

39

OUT0

19

21

OUT1

20

22

OUT2

21

23

OUT3

22

24

CLK

Reset

OUTREG0

36

105

OUTREG1

37

104

OUTREG2

38

103

OUTREG3

39

102

CLK2

40

101

39

TABLA 5.5: Distribucin de pines y conectores proyecto Motor Pasos

5.4

Aplicacin Global: Manejo de un panel de LEDs.

5.4.1 Introduccin.
En los numerales anteriores se revisaron algunos ejemplos prcticos de
diseo digital de hardware. En este numeral se plantea el diseo de un
controlador para un panel de LEDs. bsicamente, esta fu la razn que
motiv el desarrollo del tema del diseo de hardware utilizando el lenguaje
descriptivo Verilog como tema de esta tesis.
Paneles de mensaje variable y paneles grficos basados en diodos emisores
de luz (LEDs), en la actualidad son muy populares. Uno de los mtodos mas
comunes para manejo de tableros de mensajes variables o paneles grficos
es el esquema de multiplexaje de matrices de leds dispuestos en paneles.
El multiplexaje puede tener algunas variantes,
entre los mas utilizados
estn multiplexaje a 2, 4, 8 y algunos ingenieros utilizan valores superiores.
El manejo de paneles multiplexados tiene algunas ventajas en contraste
con los sistemas de manejo directo, entre algunas de estas ventajas
podemos citar: reduccin del consumo de potencia, por lo tanto reduccin
148

del tamao de las fuentes de alimentacin, reduccin del numero de


manejadores o drivers para los LEDs, reduccin de los tamaos de los
circuitos Impresos etc.
As como presenta ventajas, estas no vienen gratis, un sistema
multiplexado compromete en algo el brillo del panel, adems demanda una
velocidad de procesamiento mucho mayor, especialmente en paneles
grandes en los cuales las ratas de refresco de la pantalla son elevadas.
Entonces, uno de los principales problemas, se convierte la velocidad de
procesamiento del sistema, el cual generalmente posee un procesador
central que se encarga de leer los datos de una memoria, procesar la
informacin y enviarla a los respectivos manejadores de cada panel. En
cada panel debe existir un manejador que pueda tomar la informacin y
realizar el multiplexaje de la informacin. En controles mas precisos estos
manejadores tambin controlan la iluminacin del panel y algunos casos
realizan controles de escalas de grises o controles RGB.
Los manejadores comerciales existen de muchos tipos, de interfase serial,
paralela, con control de intensidad de corriente, iluminacin etc. Pero cada
uno de ellos esta diseado para trabajar con un procesador o dispositivo
principal, que controle la operacin de estos y si se requiere multiplexaje el
uso de un procesador adicional es prcticamente obligatorio.
Es por eso que se plantea el diseo de un controlador autnomo para un
panel multiplexado. El diseo aqu expuesto sirve como gua para desarrollo
de futuros controladores mas complejos que puedan incluso realizar el
manejo de escalas de grises mediante el uso de modulacin del ancho de
pulso o PWM.

5.4.2 Descripcin.
Antes de explicar el diseo del controlador es necesario dejar algunos
conceptos en claro. Un tablero de LEDs esta formado por varios mdulos, y
estos mdulos a su vez por varios paneles. Cada panel es un arreglo de n x
m LEDs de acuerdo al criterio de cada diseador. De acuerdo al esquema
de manejo del panel puede un tablero poseer uno o varios procesadores.
El controlador del panel de LEDs multiplexado se ha diseado para
controlar un panel formado por una matriz de 6 x 8 LEDs, el diseo puede
ser acoplado para matrices mas grandes de acuerdo a las necesidades y
capacidades del hardware utilizado.
El concepto para el desarrollo de este manejador es el de eliminar el
procesador de cada panel encargado de realizar las funciones de
comunicacin
y
manejo
de
la
matriz
de
leds,
y
reemplazar
por
un
controlador

que

se

interfase

directamente

al

procesador

principal

de
149

manera paralela (o serial si se quisiera), en las que la tasa de transferencia


es muy elevada, realizar el multiplexaje de los leds manejando los circuitos
drivers para las fuentes y colocando los datos correspondientes a la
informacin enviada en los drenadores.
En la figura 5.19 se muestra un diagrama de bloques del manejador de
panel. El controlador se lo ha diseado con una interfase paralela de 8 bits.
Posee 2 seales de control WR y Stb
que se utiliza para almacenar y
actualizar la informacin del panel.
El controlador del panel esta formado por las siguientes partes:

5.4.2

Interfase de comunicacin paralela de 8 bits


Memoria (buffer In) de 8 bits x 6 para recepcin de la informacin
del panel desde el dispositivo master.
Memoria de actualizacin (buffer Out) de 8 bits x 6 de donde se
toma la informacin para ser desplegada en el panel de acuerdo a
un contador de 6+ estados. Esta informacin maneja los drivers
para las columnas del panel.
Divisor de frecuencia de reloj que trabaja a 1Khz, que alimenta a un
registro de desplazamiento que maneja los drivers para las filas del
panel y as realizar el muestreo.

Descripcin de los pines.


Datos (d0..d7)
Bus de datos por donde el controlador recibe la informacin del procesador
principal.
WR.
Seal de escritura sensible al flanco de subida, mediante un pulso positivo
la informacin presente en las lneas de d0..d7 se almacenan en la memoria
de ingreso BufferIn. El puntero de la memoria de ingreso se incrementa con
cada flanco de subida y se restablece a 0 al recibir un pulso extra en esta
lnea.
Stb.
Seal de actualizacin de la memoria, un pulso positivo en esta lnea causa
que la informacin que se encuentra en la memoria de ingreso Buffer in sea
copiada a la memoria de actualizacin BufferOut.
Es importante que toda la informacin correspondiente a todo el panel sea
cargada en la
memoria de ingreso ya que de otra manera se podra
mostrar informacin errnea.

150

VLED

Mane ja do r Fil a s

F1
F2
F3
F4
F5
F6

C7

C6

C5

C4

C3

C2

C1

DR V
Col u mn as

DRV FILAS

C0

Manejador Columnas

Divisor /
selector

Buffer In (8 bits)

Buffer Out (8 bits)


F1

DatoOut 0

DatoIn 0

F2

DatoOut 1

DatoIn 1

F3

DatoOut 2

DatoIn 2

F4

DatoOut 3

DatoIn 3

F5

DatoOut 4

DatoIn 4

F6

DatoOut 5

DatoIn 5

Cristal
1.832Mhz

Interfase Com.

d0

d7

WR

Stb

Controlador de panel

FIGURA 5.19: Controlador de panel de LEDs

F1-F6
Lneas de salida, activas a nivel bajo, estas lneas se conectan a los drivers
de fuente que alimentan a los nodos de los LEDs.
C1-C8
Lneas de salida, activas a nivel lgico bajo, estas lneas se conectan a los
drivers drenadores. Los ctodos de los LEDs deben conectarse a los
drenadores.
5.4.3

Funcionamiento.
El controlador de panel debe ser controlado por el procesador principal
mediante 10 lneas, 8 de datos y 2 de control la operacin del controlador

151

se realiza de acuerdo a la tabla 5.6. Los estados indicados con una flecha
ascendente indican que la seal es sensible al flanco.
ESTADO
Inactivo
Escribir Dato
Actualizar Datos
Reset Dispositivo

WR
L
H
L
H

Stb
L
L
H
H

Notas
Realiza operacin de actualizacin de pantalla
Debe recibir 6 pulsos/dato + 1 de actualizacin
Actualiza Buffer Out con datos de Buffer In
Reinicia al dispositivo

TABLA 5.6: Operacin del controlador de panel de LEDs

En operacin normal el dispositivo debe ser colocado en estado inactivo, en


este estado el controlador realiza operaciones de actualizacin de la
pantalla, tomando la informacin de la memoria BufferOut y colocndola en
el puerto de salida del manejador de columnas. La informacin en el puerto
es invertida. Un contador de 6 estados se encarga de sincronizar los datos
de la memoria de salida hacia los drivers de columnas y el registro de
desplazamiento que maneja los drivers de filas.
D7

D0

Byte 0
Byte 1
Byte 2
Byte 3
Byte 4
Byte 5

FIGURA 5.20: Disposicin memoria de ingreso y salida con respecto a la matriz de LEDS

La actualizacin de los dato se realiza mediante el contador de 6 estados de


acuerdo a la tabla 5.7.
Contador

Estados
0
1
2
3
4
5

Posicin Memoria
(Columnas)
~Byte 0
~Byte 1
~Byte 2
~Byte 3
~Byte 4
~Byte 5

Reg. Desplazamiento
F1 (111110)
F2 (111101)
F3 (111011)
F5 (110111)
F5 (101111)
F6 (011111)

TABLA 5.7: Operacin del controlador de panel de LEDs

En la figura 5.21 podemos ver el diagrama de tiempos para los ciclos de


escritura en la memoria de ingreso, actualizacin de la memoria de salida
con los datos escritos en la memoria de ingreso y los ciclos de actualizacin
o el barrido de la pantalla con los datos de la memoria BufferOut.

152

WR
X0

D7-D0

X1

X2

X3

X4

X5

X6

Str
C. Est.
B.Out

B
B
0
2

B
B
1
3

B
B
2
4

B
B

B
B
3
5

B
B

B
B

4
0

B
0

5
2

B
B
2

B
1
3

B
B

B
B

3
5

B
4

B
5

B
0

1
3

2
4

3
5

4
0

B
X
1
4

B
X
2
5

X
3

X
X
0
3

X
X

X
X

1
4

2
5

B
0

B
B
1
2

F1
F2
F3
F4
F5
F6

FIGURA 5.21: Ciclos de escritura, actualizacin y barrido para controlador de panel

5.4.4

Implementacin del controlador.


Para implementar el controlador para manejo del panel de LEDs
multiplexado se utiliz el kit de desarrollo XC2-XL con el CPLD XC2C256-144
y la placa de interfase. Adicionalmente se implemento mediante el uso de
una baseta de pruebas un circuito de interfase de potencia para
interconexin con el panel de LEDs. A continuacin se muestra las
diferentes partes del diseo.

Codigo Verilog.
///////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo Top controlador de panel de 6x8 para panel multiplexado
// de LEDs.
// ////////////////////////////////////////////////////////////////////////////////////////////////
module TopLedDrv(CLK, RESET, DataIn, WR, Stb, DataOut, OutSources);
input CLK, RESET;
input [7:0] DataIn;
//PC
input WR, Stb;
output [7:0] DataOut; //LED
output [5:0] OutSources;
wire [5:0] OutN;

//PC
//LED

assign OutSources = ~OutN;

153

Divisor DIV1(CLK, CLKOUT);


Refresco REF1(CLKOUT, RESET, DataIn, WR, Stb, DataOut, OutN);
endmodule
///////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo Divisor
// Divide la frecuencia de entrada para obtener frecuencia de muestreo
// cristal utilizado 1.8432 Mhz.
// Frecuencia de muestreo 1KHz.
// ////////////////////////////////////////////////////////////////////////////////////////////////
module Divisor(CLK, CLKOUT);
input CLK;
output reg CLKOUT=0;
reg [17:0]Cont = 18'b0;
parameter VALORDIVISOR = 16'd1843; //1843
always @(posedge CLK)
begin
if(Cont == (VALORDIVISOR-1))
begin
CLKOUT <= ~CLKOUT;
Cont <= 0;
end
else
Cont <= Cont + 1'b1;
end
endmodule
///////////////////////////////////////////////////////////////////////////////////////////////////
// Modulo Refreso
// Modulo que realiza las funciones completas del controlador, carga
// de datos asincrona en la memoria de ingreso, Actualizacin de
// los datos de la memoria de ingreso a la memoria de salida en un solo
// ciclo de reloj.
// Uso de parmetros para poder implementar manejadores para paneles
// de distintos tamaos
// ////////////////////////////////////////////////////////////////////////////////////////////////
module Refresco(CLK, RESET, DataIn, WR, Stb, DataOut, OutSources);
parameter WORDSIZE = 4'd8;
parameter ADDRZISE = 2'd3;
parameter MEMLONG
input WR, CLK, Stb, RESET;
input [WORDSIZE-1:0]DataIn;
output [WORDSIZE-1:0]DataOut;

= 3'd6;

//7:0
//7:0

154

output reg [MEMLONG-1:0]OutSources=6'b1000;


reg [ADDRZISE-1:0] AddrIn = 0;
//2:0
reg [ADDRZISE-1:0] AddrOut = 0;
reg [WORDSIZE-1:0] RegistroIn [0:MEMLONG-1];
reg [WORDSIZE-1:0] RegOut [0:MEMLONG-1];

//7:0
//7:0

initial
begin
RegOut[0]=1;
RegOut[1]=2;
RegOut[2]=3;
RegOut[3]=4;
RegOut[4]=5;
RegOut[5]=6;
RegistroIn[0]=0;
RegistroIn[1]=0;
RegistroIn[2]=0;
RegistroIn[3]=0;
RegistroIn[4]=0;
RegistroIn[5]=0;
OutSources=6'b1000;
AddrIn = 0;
end
/*********** Carga de Datos **************************/
always@(posedge WR)
if(Stb==0)
begin
if(AddrIn >= MEMLONG)
AddrIn <= 0;
else
begin
RegistroIn[AddrIn] <= DataIn;
AddrIn <= AddrIn + 1'b1;
end
end
always@(posedge Stb)
begin
RegOut[0] <= RegistroIn[0];
RegOut[1] <= RegistroIn[1];
RegOut[2] <= RegistroIn[2];
RegOut[3] <= RegistroIn[3];
RegOut[4] <= RegistroIn[4];
RegOut[5] <= RegistroIn[5];
end
/*********** Barrido del Puerto y Memoria ***********************/
always@(posedge CLK or posedge RESET)
if(RESET)

155

AddrOut <= 0;
else
if(!Stb)
if(AddrOut >= MEMLONG-1)
begin
AddrOut <= 0;
end
else
begin
AddrOut <= AddrOut + 1'b1;
end
always@(posedge CLK or posedge RESET)
begin
if(RESET)
OutSources <= 6'b1000;
else
case (AddrOut)
3'd5 : OutSources <= 6'b000001;
3'd0 : OutSources <= 6'b000010;
3'd1 : OutSources <= 6'b000100;
3'd2 : OutSources <= 6'b001000;
3'd3 : OutSources <= 6'b010000;
3'd4 : OutSources <= 6'b100000;
endcase
end

// 0
// 0
// 0
// 0
// 0
// 0

assign DataOut = ~RegOut[AddrOut];


endmodule
Simulacin.
En la figura 5.21 podemos observar el resultado de las pruebas de
simulacin del controlador. Las escalas de tiempo se han modificado para
efectos de la simulacin. La seal de CLK corresponde a la frecuencia ya
dividida proveniente del cristal.

FIGURA 5.21: Diagrama de tiempos para controlador de panel.

156

Asignacin de pines
La lista siguiente muestra el detalle de las lneas utilizadas en el diseo, se
puede observar el nombre de la lnea, el estndar utilizado, el numero de
pin asignado y el numero de conector del puerto "D" del Kit de desarrollo
que se utiliz para la implementacin.
NET "CLK" LOC = "P38" | IOSTANDARD = LVTTL | SCHMITT_TRIGGER ;
NET "DataIn<0>" LOC = "P53" | IOSTANDARD = LVTTL ;#D32
NET "DataIn<1>" LOC = "P52" | IOSTANDARD = LVTTL ;#D33
NET "DataIn<2>" LOC = "P51" | IOSTANDARD = LVTTL ;#D34
NET "DataIn<3>" LOC = "P50" | IOSTANDARD = LVTTL ;#D35
NET "DataIn<4>" LOC = "P49" | IOSTANDARD = LVTTL ;#D36
NET "DataIn<5>" LOC = "P48" | IOSTANDARD = LVTTL ;#D37
NET "DataIn<6>" LOC = "P46" | IOSTANDARD = LVTTL ;#D38
NET "DataIn<7>" LOC = "P45" | IOSTANDARD = LVTTL ;#D39
NET "DataOut<0>" LOC = "P68" | IOSTANDARD = LVTTL ;#D22
NET "DataOut<1>" LOC = "P66" | IOSTANDARD = LVTTL ;#D23
NET "DataOut<2>" LOC = "P64" | IOSTANDARD = LVTTL ;#D24
NET "DataOut<3>" LOC = "P61" | IOSTANDARD = LVTTL ;#D25
NET "DataOut<4>" LOC = "P60" | IOSTANDARD = LVTTL ;#D26
NET "DataOut<5>" LOC = "P59" | IOSTANDARD = LVTTL ;#D27
NET "DataOut<6>" LOC = "P58" | IOSTANDARD = LVTTL ;#D28
NET "DataOut<7>" LOC = "P57" | IOSTANDARD = LVTTL ;#D29
NET "OutSources<0>" LOC = "P76" | IOSTANDARD = LVTTL ;#D16
NET "OutSources<1>" LOC = "P75" | IOSTANDARD = LVTTL ;#D17
NET "OutSources<2>" LOC = "P74" | IOSTANDARD = LVTTL ;#D18
NET "OutSources<3>" LOC = "P71" | IOSTANDARD = LVTTL ;#D19
NET "OutSources<4>" LOC = "P70" | IOSTANDARD = LVTTL ;#D20
NET "OutSources<5>" LOC = "P69" | IOSTANDARD = LVTTL ;#D21
NET "Stb" LOC = "P56" | IOSTANDARD = LVTTL ;#D30
NET "WR" LOC = "P54" | IOSTANDARD = LVTTL ;#D31
NET "RESET" LOC = "P77" | IOSTANDARD = LVTTL ; #D15

Modulo de Interfase
Para realizar las pruebas fsicas del sistema se utiliz una baseta de pruebas
para implementar la parte de potencia del controlador. En la figura 5.22 se
muestra el esquema utilizado para el propsito. Se puede observar que
para el manejo de las filas del panel, donde se encuentran dispuestos los
nodos de los LEDs de la matriz, se utilizaron transistores PNP 2N3906, las
bases de estros transistores se manejan con las lneas F1..F6 a travs de un
driver 74HCT541. para el manejo de los ctodos de los LEDs del panel se
utiliz otro driver 74HCT541, el cual es activa los LEDs cuando va a un nivel
lgico bajo.
El panel utilizado para las pruebas es una matriz compuesto por 1 LED por
cada pxel, en el que se encuentra un conector tipo "header" de 6
posiciones para manejo de los nodos de la matriz y otro conector del
mismo tipo de 8 posiciones para el manejo de los ctodos de la matriz del
panel.

157

FIGURA 5.22: Esquema del circuito de driver para matriz de LEDs.

5.4.5

Pruebas de funcionamiento.
Como se mencion anteriormente, el controlador realiza las funciones de
barrido de la pantalla con los datos que se encuentran almacenados en la
memoria de actualizacin, esta operacin la realiza de forma automtica.
Para poder comprobar fsicamente el funcionamiento del controlador se
desarrollo un programa de prueba utilizando el lenguaje de programacin
Visual Basic y un puerto paralelo que se conecta a travs de la placa
de
interfase al controlador (CPLD).
Interfase Puerto paralelo.
Se utiliz el puerto paralelo con direccin 0x378 que posee 8 bits de salida
para los datos d0 .. d7 del controlador, en el puerto bi-direccional con
direccin de hardware 0x37A se utilizaron 2 lneas para el manejo de las
seales WR y Str. La conexin de las lneas se muestra en la figura 5.23.

158

13
25

GND
GND
GND
d7
GND
d6
d5
d4
d3
d2
d1
d0
WR

14

Str

FIGURA 5.23: Conector DB25 para puerto paralelo.

Software de prueba.
El software para la prueba se escribi utilizando Microsoft Visual Basic 6.
El propsito de este programa es el de probar la comunicacin con el
modulo de control para el panel.
En el software se generaron tablas de cdigo correspondientes a los
caracteres numricos del 0 a 9.
Con este criterio se puede generar cualquier tipo de carcter que se desee
desplegar en la pantalla. Para la prueba de comunicacin con el modulo es
suficiente desplegar caracteres numricos.
La pantalla de interfase se muestra en la figura 5.24. el programa de
prueba decodifica la informacin de un temporizador y enva de acuerdo a
la tabla 5.8 la informacin del numero a desplegar en la pantalla. La
velocidad de transmisin de los datos puede ser cambiada moviendo el
control de ajuste.

b7

b2

b1

b0

VALOR

B0

B1

B2

B3

B4

B5

b2

b1

b0

VALOR

b7

b6

b6

b5

b5

b4

b4

b3

b3

B0
B1

B2

B3

159

B4

B5

b7

b6

b5

b4

b3

B0

b2

b1

b0

VALOR

B1
B2

B3

B4

B5

b2

b1

b0

VALOR

B1

B2

B3

B4

b7

b6

b5

b4

b3

B0

4
4

b2

b1

b0

VALOR

B3

B4

B5

B5

b7

b6

b5

b4

b3

B0

B1

B2

b7

b2

b1

b0

VALOR

B0

B1

B2

B3

B4

B5

b7

b6

b1

b0

VALOR

B1

B2

B3

B4

B5

b2
1

B0
B1

b4

b3

b5

b4

b3

b2

b6

b5

b4

B0

b7

b6

b5

b3

4
1

b1

b0

VALOR

160

B2

B3

B4

B5

b7

b2

b1

b0

VALOR

B0

B1

B2

B3

B4

B5

b2

b1

b0

VALOR

B0

B1

B2

B3

B4

b7

B5

b6

b6

b5

b5

b4

b4

b3

b3

TABLA 5.8: Tabla de codificacin para caracteres numricos.

En la figura 5.24 observamos la pantalla de interfase para el programa de


pruebas del controlador del panel de LEDs. La descripcin del programa en
lenguaje Visual Basic se describe a continuacin.

FIGURA 5.24: Pantalla de control para prueba de controlador de panel

CODIGO VISUAL BASIC


'...................................................................................................................
Public Declare Sub sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Public Declare Function Inp Lib "inpout32.dll" _
Alias "Inp32" (ByVal PortAddress As Integer) As Integer
Public Declare Sub Out Lib "inpout32.dll" _
Alias "Out32" (ByVal PortAddress As Integer, ByVal Value As Integer)
Public Const WR = 1
Public Const STR = 2
Public Const RESET = 4
Public I As Integer

161

Public Comando As Byte


Public TABLA(10, 6) As Byte
Public Buffer(5) As Byte
Public Tiempo As Integer

'...................................................................................................................
Sub WRITE_PULSE()
Out Val("&H37A"), Val("&H02")
Out Val("&H37A"), Val("&H03")
End Sub

'...................................................................................................................
Sub STROBE_PULSE()
Out Val("&H37A"), Val("&H01")
Out Val("&H37A"), Val("&H03")
End Sub

'...................................................................................................................
Private Sub Com_RESET_Click()
Comando = Inp(Val("&H37A"))
Out Val("&H37A"), (Comando + RESET)
Out Val("&H37A"), (0)
sleep (100)
Out Val("&H37A"), (Comando And (Not (RESET)))
End Sub

'...................................................................................................................
Private Sub EnviaData()
Dim I As Integer
For I = 0 To 5
Out Val("&H378"), Buffer(I)
WRITE_PULSE
Next I
WRITE_PULSE
STROBE_PULSE
End Sub

'...................................................................................................................
Private Sub Cmd_Inicio_Click()
Timer1.Enabled = True
End Sub

'...................................................................................................................
Private Sub Command2_Click()
Dim Valor, I As Integer
Dim ByteL, ByteH As Byte
Dim LOW(5) As Byte, HIGH(5) As Byte
Valor = Val(Text_DATO)

162

ByteH = Valor \ 10
ByteL = Valor - (ByteH * 10)
For I = 0 To 5
LOW(I) = TABLA(ByteL, I)
HIGH(I) = TABLA(ByteH, I)
Buffer(I) = HIGH(I) * 16 Or LOW(I)
Next I
EnviaData
End Sub

'...................................................................................................................
Private Sub Command1_Click()
Timer1.Enabled = False
End Sub

'...................................................................................................................
Private Sub Form_Load()
Out Val("&H37A"), Val("&H03")
Comando = 0
TABLA(0, 0) = 7
TABLA(0, 1) = 5
TABLA(0, 2) = 5
TABLA(0, 3) = 5
TABLA(0, 4) = 5
TABLA(0, 5) = 7
TABLA(0, 0) = 7
TABLA(1, 0) = 1
TABLA(1, 1) = 3
TABLA(1, 2) = 1
TABLA(1, 3) = 1
TABLA(1, 4) = 1
TABLA(1, 5) = 1
TABLA(2, 0) = 7
TABLA(2, 1) = 1
TABLA(2, 2) = 7
TABLA(2, 3) = 4
TABLA(2, 4) = 4
TABLA(2, 5) = 7
TABLA(3, 0) = 7
TABLA(3, 1) = 1
TABLA(3, 2) = 7
TABLA(3, 3) = 1
TABLA(3, 4) = 1
TABLA(3, 5) = 7
TABLA(4, 0) = 5
TABLA(4, 1) = 5
TABLA(4, 2) = 7
TABLA(4, 3) = 1
TABLA(4, 4) = 1
TABLA(4, 5) = 1
TABLA(5, 0) = 7

163

TABLA(5, 1) = 4
TABLA(5, 2) = 7
TABLA(5, 3) = 1
TABLA(5, 4) = 1
TABLA(5, 5) = 7
TABLA(6, 0) = 7
TABLA(6, 1) = 4
TABLA(6, 2) = 7
TABLA(6, 3) = 5
TABLA(6, 4) = 5
TABLA(6, 5) = 7
TABLA(7, 0) = 7
TABLA(7, 1) = 1
TABLA(7, 2) = 1
TABLA(7, 3) = 2
TABLA(7, 4) = 2
TABLA(7, 5) = 2
TABLA(8, 0) = 7
TABLA(8, 1) = 5
TABLA(8, 2) = 7
TABLA(8, 3) = 5
TABLA(8, 4) = 5
TABLA(8, 5) = 7
TABLA(9, 0) = 7
TABLA(9, 1) = 5
TABLA(9, 2) = 7
TABLA(9, 3) = 1
TABLA(9, 4) = 1
TABLA(9, 5) = 7
Slider.Value = 10
Timer1.Interval = Val(Slider.Value) * 50
End Sub

'...................................................................................................................
Private Sub Slider_Change()
If Slider.Value = 0 Then
Timer1.Interval = 1
Else
Timer1.Interval = Val(Slider.Value) * 50
End If
End Sub

'...................................................................................................................
Private Sub Timer1_Timer()
If Tiempo >= 99 Then
Tiempo = 0
Else
Tiempo = Tiempo + 1
Text_DATO.Text = Tiempo
Command2_Click
End If

164

End Sub

'...................................................................................................................

Conclusiones y Recomendaciones.
Despus de el estudio realizado el cual a incluido una extensa explicacin
terica fundamental para el correcto entendimiento de los conceptos que
involucra un diseo digital utilizando lenguaje descriptivo, algunos ejemplos
prcticos en los que se ha tratado de detallar el proceso de diseo,
verificacin y pruebas, vemos que el uso de los lenguajes descriptivos
puede constituir una herramienta muy poderosa para los ingenieros en el
desarrollo de hardware.
Con la introduccin de dispositivos digitales como son CPLDs y
especialmente FPGAs el uso de un lenguaje descriptivo es una necesidad, la
densidad con respecto a elementos lgicos es tan alta que para poder
utilizar estos dispositivos los mtodos tradicionales esquemticos son casi
imposibles de utilizar. En este documento se han descrito ejemplos
relativamente sencillos, pero las aplicaciones actuales de estos elementos
estn enfocados a sistemas digitales de alta complejidad.
Una verdadera industria se ha creado en torno al uso de estos ASICs que
muchas empresas han dedicado sus esfuerzos al desarrollo de lo que en
este mundo digital se conoce con el nombre de "IP" o propiedades
intelectuales, que no son mas que porciones de cdigo debidamente
probados y verificados para diferentes aplicaciones, ejemplo de estos son
puertos seriales, i2c, SPI, controladores de ethernet, USB, PCI, filtros
digitales,
DSPs,
procesadores,
microcontroladores
etc.
Cientos
de
aplicaciones se encuentran disponibles tambin de forma gratuita, as que
antes de comenzar a desarrollar un modulo o circuito, es posible que ya se
encuentre listo nicamente para ser integrado a nuestro diseo. Estas
ventajas se logran al utilizar los lenguajes descriptivos de Hardware ya que
estos son independientes de la tecnologa o dispositivo que se utilice.
Es muy importante tener en cuenta que cuando se trabaja con un lenguaje
descriptivo de Hardware no estamos "programando" software en un
procesador, lo que hacemos es describir hardware el que luego ser
plasmado en un circuito ASIC sea cual fuere, as que los conceptos bsicos
digitales debemos manejarlos muy bien de tal forma de obtener mediante
el cdigo lo que realmente queremos.
En el desarrollo de esta tesis se utiliz un CPLD para las pruebas, estos
dispositivos no son mas que arreglos compuertas similares a los PLDs
comunes tales como 22V10.
En estos dispositivos el uso de memorias
requiere una cantidad significativa de registros los cuales consumen gran
cantidad de los recursos disponibles para solo lograr pequeas porciones de

165

memoria. Los FPGAs en contraste son dispositivos basados en PLAs


(Arreglos Lgicos Programables) los cuales poseen bloques especficos de
memoria con capacidades ya significativas que pueden solucionar estas
necesidades. Adems bloques de circuitos diferenciales especialmente
diseados para comunicacin entre dispositivos, ejemplo de esto sistemas
tenemos los buses SATA o interfases PCI Express que alcanzan velocidades
en el orden de los Ghz.
En conclusin, el xito en el desarrollo de un diseo digital esta basado
primeramente en el uso del dispositivo correcto para la aplicacin y en un
buen diseo del hardware a travs de un lenguaje descriptivo, verificacin
de funcionamiento y el uso de simuladores que nos ayudan a recortar los
tiempos de desarrollo y pruebas.
Despus de un extenso estudio el cual solo constituye una introduccin a
este amplio campo del diseo digital, se puede decir que es muy
importante tener bases fuertes en electrnica digital, circuitos lgicos tales
como registros, flip-flops, registros de desplazamiento y muchos otros
elementos lgicos, ya que al escribir un cdigo en HDL debemos pensar en
el dispositivo que se requiere utilizar y que el cdigo escrito sintetice el
elemento o modulo correcto.

166

APENDICE A.
Lenguaje

Definiciones Formales del

Los
anexos
a
continuacin
especificados
son
tomados
delEstndar
Internacional Documento IEEE1364, IEC61691-4 primera edicin del 2004,
parte 4, "Behavioral Lenguajes, Verilog Hardware Description Lenguajes".

Formal syntax definition


A.1 Source text
A.1.1 Library source text
library_text ::= { library_descriptions }
library_descriptions ::=
library_declaration
| include_statement
| config_declaration
library_declaration ::=
library library_identifier file_path_spec [ { , file_path_spec } ]
[ -incdir file_path_spec [ { , file_path_spec } ] ;
file_path_spec ::= file_path
include_statement ::= include <file_path_spec> ;

A.1.2 Configuration source text


config_declaration ::=
config config_identifier ;
design_statement
{config_rule_statement}
endconfig
design_statement ::= design { [library_identifier.]cell_identifier } ;
config_rule_statement ::=
default_clause liblist_clause
| inst_clause liblist_clause
| inst_clause use_clause
| cell_clause liblist_clause
| cell_clause use_clause
default_clause ::= default
inst_clause ::= instance inst_name
inst_name ::= topmodule_identifier{.instance_identifier}
cell_clause ::= cell [ library_identifier.]cell_identifier
liblist_clause ::= liblist [{library_identifier}]
use_clause ::= use [library_identifier.]cell_identifier[:config]

A.1.3 Module and primitive source text


source_text ::= { description }
description ::=
module_declaration
| udp_declaration
module_declaration ::=
{ attribute_instance } module_keyword module_identifier [ module_parameter_port_list ]
[ list_of_ports ] ; { module_item }
endmodule
| { attribute_instance } module_keyword module_identifier [ module_parameter_port_list ]

Ap.1

[ list_of_port_declarations ] ; { non_port_module_item }
endmodule
module_keyword ::= module | macromodule

A.1.4 Module parameters and ports


module_parameter_port_list ::= # ( parameter_declaration { , parameter_declaration } )
list_of_ports ::= ( port { , port } )
list_of_port_declarations ::=
( port_declaration { , port_declaration } )
|()
port ::=
[ port_expression ]
| . port_identifier ( [ port_expression ] )
port_expression ::=
port_reference
| { port_reference { , port_reference } }
port_reference ::=
port_identifier
| port_identifier [ constant_expression ]
| port_identifier [ range_expression ]
port_declaration ::=
{attribute_instance} inout_declaration
| {attribute_instance} input_declaration
| {attribute_instance} output_declaration

A.1.5 Module items


module_item ::=
module_or_generate_item
| port_declaration ;
| { attribute_instance } generated_instantiation
| { attribute_instance } local_parameter_declaration
| { attribute_instance } parameter_declaration
| { attribute_instance } specify_block
| { attribute_instance } specparam_declaration
module_or_generate_item ::=
{ attribute_instance } module_or_generate_item_declaration
| { attribute_instance } parameter_override
| { attribute_instance } continuous_assign
| { attribute_instance } gate_instantiation
| { attribute_instance } udp_instantiation
| { attribute_instance } module_instantiation
| { attribute_instance } initial_construct
| { attribute_instance } always_construct
module_or_generate_item_declaration ::=
net_declaration
| reg_declaration
| integer_declaration
| real_declaration
| time_declaration
| realtime_declaration
| event_declaration
| genvar_declaration
| task_declaration
| function_declaration
non_port_module_item ::=
{ attribute_instance } generated_instantiation
| { attribute_instance } local_parameter_declaration

Ap.2

| { attribute_instance } module_or_generate_item
| { attribute_instance } parameter_declaration
| { attribute_instance } specify_block
| { attribute_instance } specparam_declaration
parameter_override ::= defparam list_of_param_assignments ;

A.2 Declarations
A.2.1 Declaration types
A.2.1.1 Module parameter declarations
local_parameter_declaration ::=
localparam [ signed ] [ range ] list_of_param_assignments ;
| localparam integer list_of_param_assignments ;
| localparam real list_of_param_assignments ;
| localparam realtime list_of_param_assignments ;
| localparam time list_of_param_assignments ;
parameter_declaration ::=
parameter [ signed ] [ range ] list_of_param_assignments ;
| parameter integer list_of_param_assignments ;
| parameter real list_of_param_assignments ;
| parameter realtime list_of_param_assignments ;
| parameter time list_of_param_assignments ;
specparam_declaration ::= specparam [ range ] list_of_specparam_assignments ;
A.2.1.2 Port declarations
inout_declaration ::= inout [ net_type ] [ signed ] [ range ]
list_of_port_identifiers
input_declaration ::= input [ net_type ] [ signed ] [ range ]
list_of_port_identifiers
output_declaration ::=
output [ net_type ] [ signed ] [ range ]
list_of_port_identifiers
| output [ reg ] [ signed ] [ range ]
list_of_port_identifiers
| output reg [ signed ] [ range ]
list_of_variable_port_identifiers
| output [ output_variable_type ]
list_of_port_identifiers
| output output_variable_type
list_of_variable_port_identifiers
A.2.1.3 Type declarations
event_declaration ::= event list_of_event_identifiers ;
genvar_declaration ::= genvar list_of_genvar_identifiers ;
integer_declaration ::= integer list_of_variable_identifiers ;
net_declaration ::=
net_type [ signed ]
[ delay3 ] list_of_net_identifiers ;
| net_type [ drive_strength ] [ signed ]
[ delay3 ] list_of_net_decl_assignments ;
| net_type [ vectored | scalared ] [ signed ]
range [ delay3 ] list_of_net_identifiers ;
| net_type [ drive_strength ] [ vectored | scalared ] [ signed ]
range [ delay3 ] list_of_net_decl_assignments ;
| trireg [ charge_strength ] [ signed ]
[ delay3 ] list_of_net_identifiers ;

Ap.3

| trireg [ drive_strength ] [ signed ]


[ delay3 ] list_of_net_decl_assignments ;
| trireg [ charge_strength ] [ vectored | scalared ] [ signed ]
range [ delay3 ] list_of_net_identifiers ;
| trireg [ drive_strength ] [ vectored | scalared ] [ signed ]
range [ delay3 ] list_of_net_decl_assignments ;
real_declaration ::= real list_of_real_identifiers ;
realtime_declaration ::= realtime list_of_real_identifiers ;
reg_declaration ::= reg [ signed ] [ range ]
list_of_variable_identifiers ;
time_declaration ::= time list_of_variable_identifiers ;

A.2.2 Declaration data types


A.2.2.1 Net and variable types
net_type ::=
supply0 | supply1
| tri | triand | trior | tri0 | tri1
| wire | wand | wor
output_variable_type ::= integer | time
real_type ::=
real_identifier [ = constant_expression ]
| real_identifier dimension { dimension }
variable_type ::=
variable_identifier [ = constant_expression ]
| variable_identifier dimension { dimension }
A.2.2.2 Strengths
drive_strength ::=
( strength0 , strength1 )
| ( strength1 , strength0 )
| ( strength0 , highz1 )
| ( strength1 , highz0 )
| ( highz0 , strength1 )
| ( highz1 , strength0 )
strength0 ::= supply0 | strong0 | pull0 | weak0
strength1 ::= supply1 | strong1 | pull1 | weak1
charge_strength ::= ( small ) | ( medium ) | ( large )
A.2.2.3 Delays
delay3 ::= # delay_value | # ( delay_value [ , delay_value [ , delay_value ] ] )
delay2 ::= # delay_value | # ( delay_value [ , delay_value ] )
delay_value ::=
unsigned_number
| parameter_identifier
| specparam_identifier
| mintypmax_expression

A.2.3 Declaration lists


list_of_event_identifiers ::= event_identifier [ dimension { dimension }]
{ , event_identifier [ dimension { dimension }] }
list_of_genvar_identifiers ::= genvar_identifier { , genvar_identifier }
list_of_net_decl_assignments ::= net_decl_assignment { , net_decl_assignment }
list_of_net_identifiers ::= net_identifier [ dimension { dimension }]
{ , net_identifier [ dimension { dimension }] }
list_of_param_assignments ::= param_assignment { , param_assignment }

Ap.4

list_of_port_identifiers ::= port_identifier { , port_identifier }


list_of_real_identifiers ::= real_type { , real_type }
list_of_specparam_assignments ::= specparam_assignment { , specparam_assignment }
list_of_variable_identifiers ::= variable_type { , variable_type }
list_of_variable_port_identifiers ::= port_identifier [ = constant_expression ]
{ , port_identifier [ = constant_expression ] }

A.2.4 Declaration assignments


net_decl_assignment ::= net_identifier = expression
param_assignment ::= parameter_identifier = constant_expression
specparam_assignment ::=
specparam_identifier = constant_mintypmax_expression
| pulse_control_specparam
pulse_control_specparam ::=
PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] ) ;
| PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor
= ( reject_limit_value [ , error_limit_value ] ) ;
error_limit_value ::= limit_value
reject_limit_value ::= limit_value
limit_value ::= constant_mintypmax_expression

A.2.5 Declaration ranges


dimension ::= [ dimension_constant_expression : dimension_constant_expression ]
range ::= [ msb_constant_expression : lsb_constant_expression ]

A.2.6 Function declarations


function_declaration ::=
function [ automatic ] [ signed ] [ range_or_type ] function_identifier ;
function_item_declaration { function_item_declaration }
function_statement
endfunction
| function [ automatic ] [ signed ] [ range_or_type ] function_identifier ( function_port_list ) ;
block_item_declaration { block_item_declaration }
function_statement
endfunction
function_item_declaration ::=
block_item_declaration
| tf_input_declaration ;
function_port_list ::= { attribute_instance } tf_input_declaration { , { attribute_instance }
tf_input_declaration }
range_or_type ::= range | integer | real | realtime | time

A.2.7 Task declarations


task_declaration ::=
task [ automatic ] task_identifier ;
{ task_item_declaration }
statement
endtask
| task [ automatic ] task_identifier ( task_port_list ) ;
{ block_item_declaration }
statement
endtask
task_item_declaration ::=
block_item_declaration
| { attribute_instance } tf_input_declaration ;
| { attribute_instance } tf_output_declaration ;

Ap.5

| { attribute_instance } tf_inout_declaration ;
task_port_list ::= task_port_item { , task_port_item }
task_port_item ::=
{ attribute_instance } tf_input_declaration
| { attribute_instance } tf_output_declaration
| { attribute_instance } tf_inout_declaration
tf_input_declaration ::=
input [ reg ] [ signed ] [ range ] list_of_port_identifiers
| input [ task_port_type ] list_of_port_identifiers
tf_output_declaration ::=
output [ reg ] [ signed ] [ range ] list_of_port_identifiers
| output [ task_port_type ] list_of_port_identifiers
tf_inout_declaration ::=
inout [ reg ] [ signed ] [ range ] list_of_port_identifiers
| inout [ task_port_type ] list_of_port_identifiers
task_port_type ::=
time | real | realtime | integer

A.2.8 Block item declarations


block_item_declaration ::=
{ attribute_instance } block_reg_declaration
| { attribute_instance } event_declaration
| { attribute_instance } integer_declaration
| { attribute_instance } local_parameter_declaration
| { attribute_instance } parameter_declaration
| { attribute_instance } real_declaration
| { attribute_instance } realtime_declaration
| { attribute_instance } time_declaration
block_reg_declaration ::= reg [ signed ] [ range ]
list_of_block_variable_identifiers ;
list_of_block_variable_identifiers ::=
block_variable_type { , block_variable_type }
block_variable_type ::=
variable_identifier
| variable_identifier dimension { dimension }

A.3 Primitive instances


A.3.1 Primitive instantiation and instances
gate_instantiation ::=
cmos_switchtype [delay3]
cmos_switch_instance { , cmos_switch_instance } ;
| enable_gatetype [drive_strength] [delay3]
enable_gate_instance { , enable_gate_instance } ;
| mos_switchtype [delay3]
mos_switch_instance { , mos_switch_instance } ;
| n_input_gatetype [drive_strength] [delay2]
n_input_gate_instance { , n_input_gate_instance } ;
| n_output_gatetype [drive_strength] [delay2]
n_output_gate_instance { , n_output_gate_instance } ;
| pass_en_switchtype [delay2]
pass_enable_switch_instance { , pass_enable_switch_instance } ;
| pass_switchtype
pass_switch_instance { , pass_switch_instance } ;
| pulldown [pulldown_strength]
pull_gate_instance { , pull_gate_instance } ;
| pullup [pullup_strength]
pull_gate_instance { , pull_gate_instance } ;

Ap.6

cmos_switch_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal ,


ncontrol_terminal , pcontrol_terminal )
enable_gate_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal ,
enable_terminal )
mos_switch_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal ,
enable_terminal )
n_input_gate_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal { ,
input_terminal } )
n_output_gate_instance ::= [ name_of_gate_instance ] ( output_terminal { , output_terminal } ,
input_terminal )
pass_switch_instance ::= [ name_of_gate_instance ] ( inout_terminal , inout_terminal )
pass_enable_switch_instance ::= [ name_of_gate_instance ] ( inout_terminal , inout_terminal ,
enable_terminal )
pull_gate_instance ::= [ name_of_gate_instance ] ( output_terminal )
name_of_gate_instance ::= gate_instance_identifier [ range ]

A.3.2 Primitive strengths


pulldown_strength ::=
( strength0 , strength1 )
| ( strength1 , strength0 )
| ( strength0 )
pullup_strength ::=
( strength0 , strength1 )
| ( strength1 , strength0 )
| ( strength1 )

A.3.3 Primitive terminals


enable_terminal ::= expression
inout_terminal ::= net_lvalue
input_terminal ::= expression
ncontrol_terminal ::= expression
output_terminal ::= net_lvalue
pcontrol_terminal ::= expression

A.3.4 Primitive gate and switch types


cmos_switchtype ::= cmos | rcmos
enable_gatetype ::= bufif0 | bufif1 | notif0 | notif1
mos_switchtype ::= nmos | pmos | rnmos | rpmos
n_input_gatetype ::= and | nand | or | nor | xor | xnor
n_output_gatetype ::= buf | not
pass_en_switchtype ::= tranif0 | tranif1 | rtranif1 | rtranif0
pass_switchtype ::= tran | rtran

A.4 Module and generated instantiation


A.4.1 Module instantiation
module_instantiation ::=
module_identifier [ parameter_value_assignment ]
module_instance { , module_instance } ;
parameter_value_assignment ::= # ( list_of_parameter_assignments )
list_of_parameter_assignments ::=
ordered_parameter_assignment { , ordered_parameter_assignment } |
named_parameter_assignment { , named_parameter_assignment }
ordered_parameter_assignment ::= expression
named_parameter_assignment ::= . parameter_identifier ( [ expression ] )

Ap.7

module_instance ::= name_of_instance ( [ list_of_port_connections ] )


name_of_instance ::= module_instance_identifier [ range ]
list_of_port_connections ::=
ordered_port_connection { , ordered_port_connection }
| named_port_connection { , named_port_connection }
ordered_port_connection ::= { attribute_instance } [ expression ]
named_port_connection ::= { attribute_instance } .port_identifier ( [ expression ] )

A.4.2 Generated instantiation


generated_instantiation ::= generate { generate_item } endgenerate
generate_item_or_null ::= generate_item | ;
generate_item ::=
generate_conditional_statement
| generate_case_statement
| generate_loop_statement
| generate_block
| module_or_generate_item
generate_conditional_statement ::=
if ( constant_expression ) generate_item_or_null [ else generate_item_or_null ]
generate_case_statement ::= case ( constant_expression )
genvar_case_item { genvar_case_item } endcase
genvar_case_item ::= constant_expression { , constant_expression } :
generate_item_or_null | default [ : ] generate_item_or_null
generate_loop_statement ::= for ( genvar_assignment ; constant_expression ;
genvar_assignment )
begin : generate_block_identifier { generate_item } end
genvar_assignment ::= genvar_identifier = constant_expression
generate_block ::= begin [ : generate_block_identifier ] { generate_item } end

A.5 UDP declaration and instantiation


A.5.1 UDP declaration
udp_declaration ::=
{ attribute_instance } primitive udp_identifier ( udp_port_list ) ;
udp_port_declaration { udp_port_declaration }
udp_body
endprimitive
| { attribute_instance } primitive udp_identifier ( udp_declaration_port_list ) ;
udp_body
endprimitive

A.5.2 UDP ports


udp_port_list ::= output_port_identifier , input_port_identifier { , input_port_identifier }
udp_declaration_port_list ::=
udp_output_declaration , udp_input_declaration { , udp_input_declaration }
udp_port_declaration ::=
udp_output_declaration ;
| udp_input_declaration ;
| udp_reg_declaration ;
udp_output_declaration ::=
{ attribute_instance } output port_identifier
| { attribute_instance } output reg port_identifier [ = constant_expression ]
udp_input_declaration ::= { attribute_instance } input list_of_port_identifiers
udp_reg_declaration ::= { attribute_instance } reg variable_identifier

Ap.8

A.5.3 UDP body


udp_body ::= combinational_body | sequential_body
combinational_body ::= table combinational_entry { combinational_entry } endtable
combinational_entry ::= level_input_list : output_symbol ;
sequential_body ::= [ udp_initial_statement ] table sequential_entry { sequential_entry }
endtable
udp_initial_statement ::= initial output_port_identifier = init_val ;
init_val ::= 1'b0 | 1'b1 | 1'bx | 1'bX | 1'B0 | 1'B1 | 1'Bx | 1'BX | 1 | 0
sequential_entry ::= seq_input_list : current_state : next_state ;
seq_input_list ::= level_input_list | edge_input_list
level_input_list ::= level_symbol { level_symbol }
edge_input_list ::= { level_symbol } edge_indicator { level_symbol }
edge_indicator ::= ( level_symbol level_symbol ) | edge_symbol
current_state ::= level_symbol
next_state ::= output_symbol | output_symbol ::= 0 | 1 | x | X
level_symbol ::= 0 | 1 | x | X | ? | b | B
edge_symbol ::= r | R | f | F | p | P | n | N | *

A.5.4 UDP instantiation


udp_instantiation ::= udp_identifier [ drive_strength ] [ delay2 ]
udp_instance { , udp_instance } ;
udp_instance ::= [ name_of_udp_instance ] ( output_terminal , input_terminal
{ , input_terminal } )
name_of_udp_instance ::= udp_instance_identifier [ range ]

A.6 Behavioral statements


A.6.1 Continuous assignment statements
continuous_assign ::= assign [ drive_strength ] [ delay3 ] list_of_net_assignments ;
list_of_net_assignments ::= net_assignment { , net_assignment }
net_assignment ::= net_lvalue = expression

A.6.2 Procedural blocks and assignments


initial_construct ::= initial statement
always_construct ::= always statement
blocking_assignment ::= variable_lvalue = [ delay_or_event_control ] expression
nonblocking_assignment ::= variable_lvalue <= [ delay_or_event_control ] expression
procedural_continuous_assignments ::=
assign variable_assignment
| deassign variable_lvalue
| force variable_assignment
| force net_assignment
| release variable_lvalue
| release net_lvalue
function_blocking_assignment ::= variable_lvalue = expression
function_statement_or_null ::=
function_statement
| { attribute_instance } ;

A.6.3 Parallel and sequential blocks


function_seq_block ::= begin [ : block_identifier
{ block_item_declaration } ] { function_statement } end

Ap.9

variable_assignment ::= variable_lvalue = expression


par_block ::= fork [ : block_identifier
{ block_item_declaration } ] { statement } join
seq_block ::= begin [ : block_identifier
{ block_item_declaration } ] { statement } end

A.6.4 Statements
statement ::=
{ attribute_instance } blocking_assignment ;
| { attribute_instance } case_statement
| { attribute_instance } conditional_statement
| { attribute_instance } disable_statement
| { attribute_instance } event_trigger
| { attribute_instance } loop_statement
| { attribute_instance } nonblocking_assignment ;
| { attribute_instance } par_block
| { attribute_instance } procedural_continuous_assignments ;
| { attribute_instance } procedural_timing_control_statement
| { attribute_instance } seq_block
| { attribute_instance } system_task_enable
| { attribute_instance } task_enable
| { attribute_instance } wait_statement
statement_or_null ::=
statement
| { attribute_instance } ;
function_statement ::=
{ attribute_instance } function_blocking_assignment ;
| { attribute_instance } function_case_statement
| { attribute_instance } function_conditional_statement
| { attribute_instance } function_loop_statement
| { attribute_instance } function_seq_block
| { attribute_instance } disable_statement
| { attribute_instance } system_task_enable

A.6.5 Timing control statements


delay_control ::=
# delay_value
| # ( mintypmax_expression )
delay_or_event_control ::=
delay_control
| event_control
| repeat ( expression ) event_control
disable_statement ::=
disable hierarchical_task_identifier ;
| disable hierarchical_block_identifier ;
event_control ::=
@ event_identifier
| @ ( event_expression )
| @*
| @ (*)
event_trigger ::=
-> hierarchical_event_identifier ;
event_expression ::=
expression
| hierarchical_identifier
| posedge expression
| negedge expression
| event_expression or event_expression

Ap.10

| event_expression , event_expression
procedural_timing_control_statement ::=
delay_or_event_control statement_or_null
wait_statement ::=
wait ( expression ) statement_or_null

A.6.6 Conditional statements


conditional_statement ::=
if ( expression )
statement_or_null [ else statement_or_null ]
| if_else_if_statement
if_else_if_statement ::=
if ( expression ) statement_or_null
{ else if ( expression ) statement_or_null }
[ else statement_or_null ]
function_conditional_statement ::=
if ( expression ) function_statement_or_null
[ else function_statement_or_null ]
| function_if_else_if_statement
function_if_else_if_statement ::=
if ( expression ) function_statement_or_null
{ else if ( expression ) function_statement_or_null }
[ else function_statement_or_null ]

A.6.7 Case statements


case_statement ::=
case ( expression )
case_item { case_item } endcase
| casez ( expression )
case_item { case_item } endcase
| casex ( expression )
case_item { case_item } endcase
case_item ::=
expression { , expression } : statement_or_null
| default [ : ] statement_or_null
function_case_statement ::=
case ( expression )
function_case_item { function_case_item } endcase
| casez ( expression )
function_case_item { function_case_item } endcase
| casex ( expression )
function_case_item { function_case_item } endcase
function_case_item ::=
expression { , expression } : function_statement_or_null
| default [ : ] function_statement_or_null

A.6.8 Looping statements


function_loop_statement ::=
forever function_statement
| repeat ( expression ) function_statement
| while ( expression ) function_statement
| for ( variable_assignment ; expression ; variable_assignment )
function_statement
loop_statement ::=
forever statement
| repeat ( expression ) statement
| while ( expression ) statement

Ap.11

| for ( variable_assignment ; expression ; variable_assignment )


statement

A.6.9 Task enable statements


system_task_enable ::= system_task_identifier [ ( expression { , expression } ) ] ;
task_enable ::= hierarchical_task_identifier [ ( expression { , expression } ) ] ;

A.7 Specify section


A.7.1 Specify block declaration
specify_block ::= specify { specify_item } endspecify
specify_item ::=
specparam_declaration
| pulsestyle_declaration
| showcancelled_declaration
| path_declaration
| system_timing_check
pulsestyle_declaration ::=
pulsestyle_onevent list_of_path_outputs ;
| pulsestyle_ondetect list_of_path_outputs ;
showcancelled_declaration ::=
showcancelled list_of_path_outputs ;
| noshowcancelled list_of_path_outputs ;

A.7.2 Specify path declarations


path_declaration ::=
simple_path_declaration ;
| edge_sensitive_path_declaration ;
| state_dependent_path_declaration ;
simple_path_declaration ::=
parallel_path_description = path_delay_value
| full_path_description = path_delay_value
parallel_path_description ::=
( specify_input_terminal_descriptor [ polarity_operator ] => specify_output_terminal_descriptor )
full_path_description ::=
( list_of_path_inputs [ polarity_operator ] *> list_of_path_outputs )
list_of_path_inputs ::=
specify_input_terminal_descriptor { , specify_input_terminal_descriptor }
list_of_path_outputs ::=
specify_output_terminal_descriptor { , specify_output_terminal_descriptor }

A.7.3 Specify block terminals


specify_input_terminal_descriptor ::=
input_identifier
| input_identifier [ constant_expression ]
| input_identifier [ range_expression ]
specify_output_terminal_descriptor ::=
output_identifier
| output_identifier [ constant_expression ]
| output_identifier [ range_expression ]
input_identifier ::= input_port_identifier | inout_port_identifier
output_identifier ::= output_port_identifier | inout_port_identifier

A.7.4 Specify path delays

Ap.12

path_delay_value ::=
list_of_path_delay_expressions
| ( list_of_path_delay_expressions )
list_of_path_delay_expressions ::=
t_path_delay_expression
| trise_path_delay_expression , tfall_path_delay_expression
| trise_path_delay_expression , tfall_path_delay_expression , tz_path_delay_expression
| t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression ,
tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression
| t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression ,
tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression ,
t0x_path_delay_expression , tx1_path_delay_expression , t1x_path_delay_expression ,
tx0_path_delay_expression , txz_path_delay_expression , tzx_path_delay_expression
t_path_delay_expression ::= path_delay_expression
trise_path_delay_expression ::= path_delay_expression
tfall_path_delay_expression ::= path_delay_expression
tz_path_delay_expression ::= path_delay_expression
t01_path_delay_expression ::= path_delay_expression
t10_path_delay_expression ::= path_delay_expression
t0z_path_delay_expression ::= path_delay_expression
tz1_path_delay_expression ::= path_delay_expression
t1z_path_delay_expression ::= path_delay_expression
tz0_path_delay_expression ::= path_delay_expression
t0x_path_delay_expression ::= path_delay_expression
tx1_path_delay_expression ::= path_delay_expression
t1x_path_delay_expression ::= path_delay_expression
tx0_path_delay_expression ::= path_delay_expression
txz_path_delay_expression ::= path_delay_expression
tzx_path_delay_expression ::= path_delay_expression
path_delay_expression ::= constant_mintypmax_expression
edge_sensitive_path_declaration ::=
parallel_edge_sensitive_path_description = path_delay_value
| full_edge_sensitive_path_description = path_delay_value
parallel_edge_sensitive_path_description ::=
( [ edge_identifier ] specify_input_terminal_descriptor =>
specify_output_terminal_descriptor [ polarity_operator ] : data_source_expression )
full_edge_sensitive_path_description ::=
( [ edge_identifier ] list_of_path_inputs *>
list_of_path_outputs [ polarity_operator ] : data_source_expression )
data_source_expression ::= expression
edge_identifier ::= posedge | negedge
state_dependent_path_declaration ::=
if ( module_path_expression ) simple_path_declaration
| if ( module_path_expression ) edge_sensitive_path_declaration
| ifnone simple_path_declaration
polarity_operator ::= + | -

A.7.5 System timing checks


A.7.5.1 System timing check commands
system_timing_check ::=
$setup_timing_check
| $hold _timing_check
| $setuphold_timing_check
| $recovery_timing_check
| $removal_timing_check
| $recrem_timing_check
| $skew_timing_check
| $timeskew_timing_check

Ap.13

| $fullskew_timing_check
| $period_timing_check
| $width_timing_check
| $nochange_timing_check
$setup_timing_check ::=
$setup ( data_event , reference_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$hold _timing_check ::=
$hold ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$setuphold_timing_check ::=
$setuphold ( reference_event , data_event , timing_check_limit , timing_check_limit
[ , [ notify_reg ] [ , [ stamptime_condition ] [ , [ checktime_condition ]
[ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ;
$recovery_timing_check ::=
$recovery ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$removal_timing_check ::=
$removal ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$recrem_timing_check ::=
$recrem ( reference_event , data_event , timing_check_limit , timing_check_limit
[ , [ notify_reg ] [ , [ stamptime_condition ] [ , [ checktime_condition ]
[ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ;
$skew_timing_check ::=
$skew ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$timeskew_timing_check ::=
$timeskew ( reference_event , data_event , timing_check_limit
[ , [ notify_reg ] [ , [ event_based_flag ] [ , [ remain_active_flag ] ] ] ] ) ;
$fullskew_timing_check ::=
$fullskew ( reference_event , data_event , timing_check_limit , timing_check_limit
[ , [ notify_reg ] [ , [ event_based_flag ] [ , [ remain_active_flag ] ] ] ] ) ;
$period_timing_check ::=
$period ( controlled_reference_event , timing_check_limit [ , [ notify_reg ] ] ) ;
$width_timing_check ::=
$width ( controlled_reference_event , timing_check_limit ,
threshold [ , [ notify_reg ] ] ) ;
$nochange_timing_check ::=
$nochange ( reference_event , data_event , start_edge_offset ,
end_edge_offset [ , [ notify_reg ] ] ) ;
A.7.5.2 System timing check command arguments
checktime_condition ::= mintypmax_expression
controlled_reference_event ::= controlled_timing_check_event
data_event ::= timing_check_event
delayed_data ::=
terminal_identifier
| terminal_identifier [ constant_mintypmax_expression ]
delayed_reference ::=
terminal_identifier
| terminal_identifier [ constant_mintypmax_expression ]
end_edge_offset ::= mintypmax_expression
event_based_flag ::= constant_expression
notify_reg ::= variable_identifier
reference_event ::= timing_check_event
remain_active_flag ::= constant_mintypmax_expression
stamptime_condition ::= mintypmax_expression
start_edge_offset ::= mintypmax_expression
threshold ::=constant_expression
timing_check_limit ::= expression
A.7.5.3 System timing check event definitions

Ap.14

timing_check_event ::=
[timing_check_event_control] specify_terminal_descriptor [ &&& timing_check_condition ]
controlled_timing_check_event ::=
timing_check_event_control specify_terminal_descriptor [ &&& timing_check_condition ]
timing_check_event_control ::=
posedge
| negedge
| edge_control_specifier
specify_terminal_descriptor ::=
specify_input_terminal_descriptor
| specify_output_terminal_descriptor
edge_control_specifier ::= edge [ edge_descriptor [ , edge_descriptor ] ]
edge_descriptor1 ::=
01
| 10
| z_or_x zero_or_one
| zero_or_one z_or_x
zero_or_one ::= 0 | 1
z_or_x ::= x | X | z | Z
timing_check_condition ::=
scalar_timing_check_condition
| ( scalar_timing_check_condition )
scalar_timing_check_condition ::=
expression
| ~ expression
| expression == scalar_constant
| expression === scalar_constant
| expression != scalar_constant
| expression !== scalar_constant
scalar_constant ::=
1'b0 | 1'b1 | 1'B0 | 1'B1 | 'b0 | 'b1 | 'B0 | 'B1 | 1 | 0

A.8 Expressions
A.8.1 Concatenations
concatenation ::= { expression { , expression } }
constant_concatenation ::= { constant_expression { , constant_expression } }
constant_multiple_concatenation ::= { constant_expression constant_concatenation }
module_path_concatenation ::= { module_path_expression { , module_path_expression } }
module_path_multiple_concatenation ::= { constant_expression module_path_concatenation }
multiple_concatenation ::= { constant_expression concatenation }
net_concatenation ::= { net_concatenation_value { , net_concatenation_value } }
net_concatenation_value ::=
hierarchical_net_identifier
| hierarchical_net_identifier [ expression ] { [ expression ] }
| hierarchical_net_identifier [ expression ] { [ expression ] } [ range_expression ]
| hierarchical_net_identifier [ range_expression ]
| net_concatenation
variable_concatenation ::= { variable_concatenation_value { , variable_concatenation_value } }
variable_concatenation_value ::=
hierarchical_variable_identifier
| hierarchical_variable_identifier [ expression ] { [ expression ] }
| hierarchical_variable_identifier [ expression ] { [ expression ] } [ range_expression ]
| hierarchical_variable_identifier [ range_expression ]
| variable_concatenation

A.8.2 Function calls


constant_function_call ::= function_identifier { attribute_instance }
( constant_expression { , constant_expression } )

Ap.15

function_call ::= hierarchical_function_identifier{ attribute_instance }


( expression { , expression } )
genvar_function_call ::= genvar_function_identifier { attribute_instance }
( constant_expression { , constant_expression } )
system_function_call ::= system_function_identifier
[ ( expression { , expression } ) ]

A.8.3 Expressions
base_expression ::= expression
conditional_expression ::= expression1 ? { attribute_instance } expression2 : expression3
constant_base_expression ::= constant_expression
constant_expression ::=
constant_primary
| unary_operator { attribute_instance } constant_primary
| constant_expression binary_operator { attribute_instance } constant_expression
| constant_expression ? { attribute_instance } constant_expression : constant_expression
| string
constant_mintypmax_expression ::=
constant_expression
| constant_expression : constant_expression : constant_expression
constant_range_expression ::=
constant_expression
| msb_constant_expression : lsb_constant_expression
| constant_base_expression +: width_constant_expression
| constant_base_expression -: width_constant_expression
dimension_constant_expression ::= constant_expression
expression1 ::= expression
expression2 ::= expression
expression3 ::= expression
expression ::=
primary
| unary_operator { attribute_instance } primary
| expression binary_operator { attribute_instance } expression
| conditional_expression
| string
lsb_constant_expression ::= constant_expression
mintypmax_expression ::=
expression
| expression : expression : expression
module_path_conditional_expression ::= module_path_expression ? { attribute_instance }
module_path_expression : module_path_expression
module_path_expression ::=
module_path_primary
| unary_module_path_operator { attribute_instance } module_path_primary
| module_path_expression binary_module_path_operator { attribute_instance }
module_path_expression
| module_path_conditional_expression
module_path_mintypmax_expression ::=
module_path_expression
| module_path_expression : module_path_expression : module_path_expression
msb_constant_expression ::= constant_expression
range_expression ::=
expression
| msb_constant_expression : lsb_constant_expression
| base_expression +: width_constant_expression
| base_expression -: width_constant_expression
width_constant_expression ::= constant_expression

Ap.16

A.8.4 Primaries
constant_primary ::=
constant_concatenation
| constant_function_call
| ( constant_mintypmax_expression )
| constant_multiple_concatenation
| genvar_identifier
| number
| parameter_identifier
| specparam_identifier
module_path_primary ::=
number
| identifier
| module_path_concatenation
| module_path_multiple_concatenation
| function_call
| system_function_call
| constant_function_call
| ( module_path_mintypmax_expression )
primary ::=
number
| hierarchical_identifier
| hierarchical_identifier [ expression ] { [ expression ] }
| hierarchical_identifier [ expression ] { [ expression ] } [ range_expression ]
| hierarchical_identifier [ range_expression ]
| concatenation
| multiple_concatenation
| function_call
| system_function_call
| constant_function_call
| ( mintypmax_expression )

A.8.5 Expression left-side values


net_lvalue ::=
hierarchical_net_identifier
| hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] }
| hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] } [
constant_range_expression ]
| hierarchical_net_identifier [ constant_range_expression ]
| net_concatenation
variable_lvalue ::=
hierarchical_variable_identifier
| hierarchical_variable_identifier [ expression ] { [ expression ] }
| hierarchical_variable_identifier [ expression ] { [ expression ] } [ range_expression ]
| hierarchical_variable_identifier [ range_expression ]
| variable_concatenation

A.8.6 Operators
unary_operator ::=
+ | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
binary_operator ::=
+ | - | * | / | % | == | != | === | !== | && | || | **
| < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<<
unary_module_path_operator ::=
! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
binary_module_path_operator ::=
== | != | && | || | & | | | ^ | ^~ | ~^

Ap.17

A.8.7 Numbers
number ::=
decimal_number
| octal_number
| binary_number
| hex_number
| real_number
real_number1 ::=
unsigned_number . unsigned_number
| unsigned_number [ . unsigned_number ] exp [ sign ] unsigned_number
exp ::= e | E
decimal_number ::=
unsigned_number
| [ size ] decimal_base unsigned_number
| [ size ] decimal_base x_digit { _ }
| [ size ] decimal_base z_digit { _ }
binary_number ::= [ size ] binary_base binary_value
octal_number ::= [ size ] octal_base octal_value
hex_number ::= [ size ] hex_base hex_value
sign ::= + | size ::= non_zero_unsigned_number
non_zero_unsigned_number1 ::= non_zero_decimal_digit { _ | decimal_digit}
unsigned_number1 ::= decimal_digit { _ | decimal_digit }
binary_value1 ::= binary_digit { _ | binary_digit }
octal_value1 ::= octal_digit { _ | octal_digit }
hex_value1 ::= hex_digit { _ | hex_digit }
decimal_base1 ::= '[s|S]d | '[s|S]D
binary_base1 ::= '[s|S]b | '[s|S]B
octal_base1 ::= '[s|S]o | '[s|S]O
hex_base1 ::= '[s|S]h | '[s|S]H
non_zero_decimal_digit ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
decimal_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
binary_digit ::= x_digit | z_digit | 0 | 1
octal_digit ::= x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
hex_digit ::=
x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|a|b|c|d|e|f|A|B|C|D|E|F
x_digit ::= x | X
z_digit ::= z | Z | ?

A.8.8 Strings
string ::= " { Any_ASCII_Characters_except_new_line } "

A.9 General
A.9.1 Attributes
attribute_instance ::= (* attr_spec { , attr_spec } *)
attr_spec ::=
attr_name = constant_expression
| attr_name
attr_name ::= identifier

A.9.2 Comments
comment ::=
one_line_comment

Ap.18

| block_comment
one_line_comment ::= // comment_text \n
block_comment ::= /* comment_text */
comment_text ::= { Any_ASCII_character }

A.9.3 Identifiers
arrayed_identifier ::=
simple_arrayed_identifier
| escaped_arrayed_identifier
block_identifier ::= identifier
cell_identifier ::= identifier
config_identifier ::= identifier
escaped_arrayed_identifier ::= escaped_identifier [ range ]
escaped_hierarchical_identifier4 ::=
escaped_hierarchical_branch
{ .simple_hierarchical_branch | .escaped_hierarchical_branch }
escaped_identifier ::= \ {Any_ASCII_character_except_white_space} white_space
event_identifier ::= identifier
function_identifier ::= identifier
gate_instance_identifier ::= arrayed_identifier
generate_block_identifier ::= identifier
genvar_function_identifier ::= identifier /* Hierarchy disallowed */
genvar_identifier ::= identifier
hierarchical_block_identifier ::= hierarchical_identifier
hierarchical_event_identifier ::= hierarchical_identifier
hierarchical_function_identifier ::= hierarchical_identifier
hierarchical_identifier ::=
simple_hierarchical_identifier
| escaped_hierarchical_identifier
hierarchical_net_identifier ::= hierarchical_identifier
hierarchical_variable_identifier ::= hierarchical_identifier
hierarchical_task_identifier ::= hierarchical_identifier
identifier ::=
simple_identifier
| escaped_identifier
inout_port_identifier ::= identifier
input_port_identifier ::= identifier
instance_identifier ::= identifier
library_identifier ::= identifier
memory_identifier ::= identifier
module_identifier ::= identifier
module_instance_identifier ::= arrayed_identifier
net_identifier ::= identifier
output_port_identifier ::= identifier
parameter_identifier ::= identifier
port_identifier ::= identifier
real_identifier ::= identifier
simple_arrayed_identifier ::= simple_identifier [ range ]
simple_hierarchical_identifier3 ::=
simple_hierarchical_branch [ .escaped_identifier ]
simple_identifier2 ::= [ a-zA-Z_ ] { [ a-zA-Z0-9_$ ] }
specparam_identifier ::= identifier
system_function_identifier5 ::= $[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
system_task_identifier5 ::= $[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }
task_identifier ::= identifier
terminal_identifier ::= identifier
text_macro_identifier ::= simple_identifier
topmodule_identifier ::= identifier
udp_identifier ::= identifier

Ap.19

udp_instance_identifier ::= arrayed_identifier


variable_identifier ::= identifier

A.9.4 Identifier branches


simple_hierarchical_branch3 ::=
simple_identifier [ [ unsigned_number ] ]
[ { .simple_identifier [ [ unsigned_number ] ] } ]
escaped_hierarchical_branch4 ::=
escaped_identifier [ [ unsigned_number ] ]
[ { .escaped_identifier [ [ unsigned_number ] ] } ]

A.9.5 White space


white_space ::= space | tab | newline | eof6
NOTES
1) Embedded spaces are illegal.
2) A simple_identifier and arrayed_reference shall start with an alpha or underscore (_)
character,
shall have at least one character, and shall not have any spaces.
3) The period (.) in simple_hierarchical_identifier and simple_hierarchical_
branch shall not be preceded or followed by white_space.
4) The period in escaped_hierarchical_identifier and escaped_hierarchical_
branch shall be preceded by white_space, but shall not be followed by white_space.
5) The $ character in a system_function_identifier or system_task_identifier shall not be
followed
by white_space. A system_function_identifier or system_task_identifier shall not be escaped.
6) End of file.

IEC 61691-4:2004(E)
IEEE 1364-2001(E)

Ap.20

APENDICE B.
(Keywords)

always
and
assign
automatic
begin
buf
bufif0
bufif1
case
casex
casez
cell
cmos
config
deassign
default
defparam
design
disable
edge
else
end
endcase
endconfig
endfunction
endgenerate
endmodule
endprimitive
endspecify
endtable
endtask
event
for
force
forever
fork
function
generate
genvar
highz0
highz1

Lista de Instrucciones

if
ifnone
incdir
include
initial
inout
input
instance
integer
join
large
liblist
library
localparam
macromodule
medium
module
nand
negedge
nmos
nor
noshowcancelled
not
notif0
notif1
or
output
parameter
pmos
posedge
primitive
pull0
pull1
pulldown
pullup
pulsestyle_onevent
pulsestyle_ondetect
rcmos
real
realtime
reg

release
repeat
rnmos
rpmos
rtran
rtranif0
rtranif1
scalared
showcancelled
signed
small
specify
specparam
strong0
strong1
supply0
supply1
table
task
time
tran
tranif0
tranif1
tri
tri0
tri1
triand
trior
trireg
unsigned
use
vectored
wait
wand
weak0
weak1
while
wire
wor
xnor
xor

IEC 61691-4:2004(E)
IEEE 1364-2001(E)

Ap.21

APENDICE C.
C.1

Kit de desarrollo XC2-XL.

Descripcin.

Ap.22

Ap.23

Ap.24

Ap.25

Ap.26

Ap.27

C.2

Esquemas.

Ap.28

Ap.29

Ap.30

Ap.31

Ap.32

Ap.33

APENDICE D.
D.1

Placa de interfase.

Diseo Esquemtico.

Ap.34

D.2

Circuito Impreso.

TOP LAYER

BOTTOM LAYER

Ap.35

SILK SCREEN

Ap.36

You might also like