Capítulo 8: PLD's Secuenciales

 

Ejemplos de ProgramaciÓn de PLDs Secuenciales

En el capitulo 4 se vieron las bases sobre la programación de PLD's con CUPL. En esta lección se indicarán algunos ejemplos para aplicaciones particulares desarrolladas en CUPL. Recordando lo visto en el capítulo 4, en este lenguaje el código fuente se dividide en tres partes: Encabezado, asignación de pines de entrada y salida y ecuaciones lógicas.

Los ejemplos ilustrados en esta lección fueron tomados de algunos fabricantes que han desarrollado estos códigos para aplicaciones particulares en sus dispositivos. Se plantea al estudiante analizar el código de estos ejemplos para comprender la forma en que se pueden programar en CUPL.

Ejemplo 8.2.1 - Uso de los flip-flop D en un PLD

Name Flops;
Partno CA0002;
Revision 03;
Date 9/12/95;
Designer G. Woolhiser;
Company Assisted Technology, Inc.;
Location None;
Assembly None;
Device P16R8;

/****************************************************************/
/* */
/* This example demonstrates the use of D-type flip-flops, */
/* and flexibilty of expression with CUPL. The following */
/* are four implementations of a two bit counter. */
/* */
/****************************************************************/
/* Target Devices: PAL16R8, PAL16RP8, EP300 */
/****************************************************************/

Pin 1 = clock;
Pin 2 = reset;
Pin 11 = !enable;

/*
* Outputs: define outputs and output active levels
*/

Pin 19 = qa0; Pin 18 = qa1;
Pin 17 = qb0; Pin 16 = qb1;
Pin 15 = qc0; Pin 14 = qc1;
Pin 13 = qd0; Pin 12 = qd1;

/*
* Logic: examples of two-bit counters using d-type flip-flops
*/

/* two-bit counter example no. 1 */
/* using software emulated exclusive or's */

qa0.d = !reset & !qa0;
qa1.d = !reset & (qa1 $ qa0);

/* two-bit counter example no. 2 */
/* using expanded exclusive or's */

qb0.d = !reset & (!qb0 & !qb1 # !qb0 & qb1);
qb1.d = !reset & (!qb0 & qb1 # qb0 & !qb1);

/* two-bit counter example no. 3 */
/* using bit fields on the right hand side of the equals sign */

field state = [qc1,qc0];

qc0.d = !reset & (state:0 # state:2);
qc1.d = !reset & (state:1 # state:2);

/* two-bit counter example no. 4 */
/* using bit fields on the left hand side of the equals sign */

field q = [qd0,qd1];

q.d = !reset & ([!qd0,qd1] & [!qd1,!qd0] # [!qd0,!qd1] & [qd1,qd0]);

Ejemplo 8.2.2 - Contador Sincrónico de 8 bits con Cargue en Paralelo

Name Count8;
Partno CA0008;
Date 7/19/95;
Revision 01;
Designer Kahl;
Company Assisted Technology;
Assembly None;
Location None;
Device P20X8;

/****************************************************************/
/* */
/* Octal Counter (74LS461) */
/* */
/* 8-bit synchronous counter with parallel load, clear, and */
/* hold capability. The LOAD operation loads the inputs */
/* (D7-D0) into the output register (Q7-Q0). The CLEAR */
/* operation resets the output register to all LOWs. The HOLD */
/* operation holds the previous value regardless of clock */
/* transitions. The increment function adds one to the output */
/* register when the CARRY-IN is true (!ci=LO), otherwise the */
/* operation is a hold. The CARRY-OUT is true (!co=LO) when */
/* the output register (Q7-Q0) is all HIGHs, otherwise false */
/* (!co=HI). */
/****************************************************************/
/** Allowable Target Device Types : PAL20X8 */
/****************************************************************/

/** Inputs **/

PIN 1 = clock ; /* Register Clock */
PIN [2,11] = [instr0..1] ; /* Instruction Type Inputs */
PIN [3..10] = [D0..7] ; /* Data Inputs */
PIN 13 = !out_enable ; /* Register Output Enable */
PIN 23 = !carry_in ; /* Carry-In Input */

/** Outputs **/

PIN 14 = !carry_out ; /* Carry-Out Output */
PIN [15..22] = [Q7..0] ; /* Register Outputs */

/** Declarations and Intermediate Variable Definitions **/

field instruction = [instr1..0]; /* Instruction Field */
clear = instruction:0 ; /* Operation Types */
hold = instruction:1 ;
load = instruction:2 ;
count = instruction:3 ;

/** Logic Equations **/

carry_out = carry_in & [Q0..7]:& ;
!Q0.d = clear # (count # hold) & !Q0 $ load & !D0 # count & carry_in ;
!Q1.d = clear # (count # hold) & !Q1 $ load & !D1 # count & carry_in & Q0 ;
!Q2.d = clear # (count # hold) & !Q2 $ load & !D2 # count & carry_in & [Q0..1]:& ;
!Q3.d = clear # (count # hold) & !Q3 $ load & !D3 # count & carry_in & [Q0..2]:& ;
!Q4.d = clear # (count # hold) & !Q4 $ load & !D4 # count & carry_in & [Q0..3]:& ;
!Q5.d = clear # (count # hold) & !Q5 $ load & !D5 # count & carry_in & [Q0..4]:& ;
!Q6.d = clear # (count # hold) & !Q6 $ load & !D6 # count & carry_in & [Q0..5]:& ;
!Q7.d = clear # (count # hold) & !Q7 $ load & !D7 # count & carry_in & [Q0..6]:& ;

Ejemplo 8.2.3 - Contador Up/Down con Límites

Name CYP_CNT;
Partno CY7C330;
Revision 01;
Date 02-25-95;
Designer Joe Designer;
Company Cypress Semiconductor;
Location U1;
Assembly COUNTER;
Device P7C330;

/*
This design is an up/down counter with preloadable limits. The Lower limits
are loaded into the dedicated input registers on the rising edge of LLC and
the upper limits are loaded into the input registers found in the I/O
macrocells on the rising edge of ULC. The counter begins counting upwards,
when preloading is done, until the upper limit is reached, and then, begins
counting downward. This design, because the equations are already
minimized and in sum of products form, should only be compiled with the
default minimization (-M1 flag).
*/

PIN 1 = CLK; /* Clock used for counting */
PIN 2 = LLC; /* Clock for preloading lower limit */
PIN 3 = ULC; /* Clock for preloading upper limit */

PIN [4..7] = [LL0..3]; /* Lower limit hold registers */
PIN [9..12] = [LL4..7];
PIN 13 = LPL; /* Lower limit preload indications */

/*
Counter output registers. Pin assignments are based on the number of
product terms are available on that pin.
*/

PIN 28 = CNT0; /* Also used for Upper limit loading */
PIN 15 = CNT1; /* Also used for Upper limit loading */
PIN 26 = CNT2; /* Also used for Upper limit loading */
PIN 17 = CNT3; /* Also used for Upper limit loading */
PIN 19 = CNT4; /* Also used for Upper limit loading */
PIN 24 = CNT5; /* Also used for Upper limit loading */
PIN 20 = CNT6;
PIN 23 = CNT7;
PIN 18 = UL6; /* Used for Upper limit loading */
PIN 25 = UL7; /* Used for Upper limit loading */
PIN 27 = UPL;

PINNODE 29 = UEQUAL; /* Upper limit has been reached */
PINNODE 30 = PLDONE; /* Preloading has finished */
PINNODE 31 = LEQUAL; /* Lower limit has been reached */
PINNODE 32 = UP; /* Count direction */

PIN 16 = !RESET; /* Reset signal clears all registers */
PIN 14 = !CNTOE; /* I/O pin OE used for loading upper limit */

PINNODE 45 = UL0; /* Shared input MUX definition */
PINNODE 46 = UL2; /* Shared input MUX definition */
PINNODE 47 = UL5; /* Shared input MUX definition */
PINNODE 48 = UL4; /* Shared input MUX definition */
PINNODE 49 = UL3; /* Shared input MUX definition */
PINNODE 50 = UL1; /* Shared input MUX definition */

UL0.IMUX = CNT0.IOD; /* These definitions are used to */
UL2.IMUX = CNT2.IOD; /* indicate which pin will be fed */
UL5.IMUX = CNT5.IOD; /* through the share feedback MUX.*/
UL4.IMUX = CNT4.IOD;
UL3.IMUX = CNT3.IOD;
UL1.IMUX = CNT1.IOD;

UL0 = CNT0.IOD;
UL2 = CNT2.IOD;
UL5 = CNT5.IOD;
UL4 = CNT4.IOD;
UL3 = CNT3.IOD;
UL1 = CNT1.IOD;

UPL.CKMUX = ULC;
LPL.CKMUX = LLC;
RESET.CKMUX = LLC;
[CNT0..5].CKMUX = ULC; /* Pin 3 will be used for upper preload */
[UL6..7].CKMUX = ULC; /* Pin 3 will be used for upper preload */
[LL0..7].CKMUX = LLC; /* Pin 2 will be used for lower preload */

[CNT0..7].SR = RESET.DQ; /* Count register will be reset with pin 16 */

[CNT0..7].OEMUX = CNTOE; /* Output enable will be controlled by pin 14 */

/*
Count equations. Note how the use of the XOR terms significantly reduces the
number of product terms that are needed. This allows this complex design to
fit into the device.
*/

!CNT0.D = !CNT0
$ PLDONE
# !LL0.DQ & LPL.DQ & CNT0
# !CNT0 & UL0 & UPL.DQ
# LL0.DQ & LPL.DQ & !CNT0
# CNT0 & !UL0 & UPL.DQ ;

!CNT1.D = !CNT1
$ !LL1.DQ & LPL.DQ & !PLDONE & CNT1
# LL1.DQ & LPL.DQ & !PLDONE & !CNT1
# UPL.DQ & !PLDONE & !UL1 & CNT1
# UPL.DQ & !PLDONE & UL1 & !CNT1
# CNT0 & PLDONE & !UP
# !CNT0 & PLDONE & UP ;

!CNT2.D = !CNT2
$ !LL2.DQ & LPL.DQ & CNT2 & !PLDONE
# LL2.DQ & LPL.DQ & !CNT2 & !PLDONE
# UPL.DQ & CNT2 & !UL2 & !PLDONE
# UPL.DQ & !CNT2 & UL2 & !PLDONE
# CNT0 & PLDONE & !UP & CNT1
# !CNT0 & PLDONE & UP & !CNT1;

!CNT3.D = !CNT3
$ !LL3.DQ & LPL.DQ & !PLDONE & CNT3
# LL3.DQ & LPL.DQ & !PLDONE & !CNT3
# UPL.DQ & !PLDONE & !UL3 & CNT3
# UPL.DQ & !PLDONE & UL3 & !CNT3
# CNT0 & CNT2 & PLDONE & !UP & CNT1
# !CNT0 & !CNT2 & PLDONE & UP & !CNT1;

!CNT4.D = !CNT4
$ !LL4.DQ & LPL.DQ & !PLDONE & CNT4
# LL4.DQ & LPL.DQ & !PLDONE & !CNT4
# UPL.DQ & !PLDONE & !UL4 & CNT4
# UPL.DQ & !PLDONE & UL4 & !CNT4
# CNT0 & CNT2 & PLDONE & !UP & CNT3 & CNT1
# !CNT0 & !CNT2 & PLDONE & UP & !CNT3 & !CNT1;

!CNT5.D = !CNT5
$ !LL5.DQ & LPL.DQ & CNT5 & !PLDONE
# LL5.DQ & LPL.DQ & !CNT5 & !PLDONE
# UPL.DQ & CNT5 & !UL5 & !PLDONE
# UPL.DQ & !CNT5 & UL5 & !PLDONE
# CNT0 & CNT2 & PLDONE & CNT4 & !UP & CNT3 & CNT1
# !CNT0 & !CNT2 & PLDONE & !CNT4 & UP & !CNT3 & !CNT1;

!CNT6.D = !CNT6
$ !LL6.DQ & LPL.DQ & !PLDONE & CNT6
# LL6.DQ & LPL.DQ & !PLDONE & !CNT6
# UPL.DQ & !PLDONE & CNT6 & !UL6.DQ
# UPL.DQ & !PLDONE & !CNT6 & UL6.DQ
# CNT0 & CNT2 & CNT5 & PLDONE & CNT4 & !UP & CNT3 & CNT1
# !CNT0 & !CNT2 & !CNT5 & PLDONE & !CNT4 & UP & !CNT3 & !CNT1;

!CNT7.D = !CNT7
$ !LL7.DQ & LPL.DQ & CNT7 & !PLDONE
# LL7.DQ & LPL.DQ & !CNT7 & !PLDONE
# UPL.DQ & !UL7.DQ & CNT7 & !PLDONE
# UPL.DQ & UL7.DQ & !CNT7 & !PLDONE
# CNT0 & CNT2 & CNT5 & PLDONE & CNT6 & CNT4 & !UP & CNT3 & CNT1
# !CNT0 & !CNT2 & !CNT5 & PLDONE & !CNT6 & !CNT4 & UP & !CNT3 & !CNT1;

/* Direction of count */

UP.D = UP
$ !UEQUAL & !UP & PLDONE
# !LEQUAL & UP & PLDONE
# UPL.DQ & !PLDONE & !UP
# LPL.DQ & !PLDONE & UP;

/* Has the lower limit been reached */

LEQUAL.D = LL6.DQ & !CNT6
# !LL7.DQ & CNT7
# LL7.DQ & !CNT7
# LL3.DQ & !CNT3
# !LL5.DQ & CNT5
# LL5.DQ & !CNT5
# !LL1.DQ & CNT1
# LL0.DQ & !CNT0
# !LL2.DQ & CNT2
# !LL4.DQ & CNT4
# LL4.DQ & !CNT4
# !LL0.DQ & CNT0
# LL1.DQ & !CNT1
# !LL6.DQ & CNT6
# !LL3.DQ & CNT3
# LL2.DQ & !CNT2;

/* Has preloading finished */

PLDONE.D = !LPL.DQ & !UPL.DQ ;

/* Has the upper limit been reached */

UEQUAL.D = !CNT6 & UL6.DQ
# !UL7.DQ & CNT7
# UL7.DQ & !CNT7
# UL3 & !CNT3
# CNT5 & !UL5
# !CNT5 & UL5
# !UL1 & CNT1
# !CNT0 & UL0
# CNT2 & !UL2
# !UL4 & CNT4
# UL4 & !CNT4
# CNT0 & !UL0
# UL1 & !CNT1
# CNT6 & !UL6.DQ
# !UL3 & CNT3
# !CNT2 & UL2;

Ejemplo 8.2.4 - Contador Up/Down de 16 bits

Name Tcounter;
Partno CA0020;
Date 6/9/95;
Revision 01;
Designer Kahl;
Company Personal CAD Systems, Inc.;
Assembly None;
Location None;
Device ep600;

/****************************************************************/
/* */
/* 16 Bit Synchronous Up/Down Counter */
/* */
/* This is a 16-bit up/down counter with built-in shift */
/* register using toggle flip-flops. The various modes are */
/* controlled by the signals CNTUP (1 = count up) */
/* SHIFT (1 = shift) */
/* SHLFT (1 = shift left) */
/****************************************************************/
/* Allowable Target Device Types : EP600 */
/****************************************************************/

/** Inputs **/

Pin 1 = clock1; /* Counter Clock 1 */
Pin 13 = clock2; /* Counter Clock 2 */
Pin 2 = data_in; /* Serial Shift Data Input */
Pin 11 = cntup; /* Count Up/Down Mode Control */
Pin 14 = shift; /* Shift/Count Mode Control */
Pin 23 = shlft; /* Shift Left Mode Control */

/** Outputs **/

Pin [3..10,15..22] = [q0..15]; /* Counter/Shifter Outputs */

/** Declarations and Intermediate Variable Definitions **/

count_up = !shift & cntup & !shlft;
count_down = !shift & !cntup & !shlft;
shift_left = shift & !cntup & shlft;
shift_right = shift & !cntup & !shlft;
reset_count = shift & cntup & shlft; /* Counter Reset Command */

Field counter = [q15..0]; /* Declared Counter Field */

/** Logic Equations **/

counter.t = 'h'0001 & (count_up & 'b'1 /* BIT 0 (LSB) */
# count_down & 'b'1
# shift_left & (data_in $ q0)
# shift_right & (q0 $ q1))
# 'h'0002 & (count_up & q0 /* BIT 1 */
# count_down & !q0
# shift_left & (q0 $ q1)
# shift_right & (q1 $ q2))
# 'h'0004 & (count_up & [q0..1]:& /* BIT 2 */
# count_down & ![q0..1]:&
# shift_left & (q1 $ q2)
# shift_right & (q2 $ q3))
# 'h'0008 & (count_up & [q0..2]:& /* BIT 3 */
# count_down & ![q0..2]:&
# shift_left & (q2 $ q3)
# shift_right & (q3 $ q4))
# 'h'0010 & (count_up & [q0..3]:& /* BIT 4 */
# count_down & ![q0..3]:&
# shift_left & (q3 $ q4)
# shift_right & (q4 $ q5))
# 'h'0020 & (count_up & [q0..4]:& /* BIT 5 */
# count_down & ![q0..4]:&
# shift_left & (q4 $ q5)
# shift_right & (q5 $ q6))
# 'h'0040 & (count_up & [q0..5]:& /* BIT 6 */
# count_down & ![q0..5]:&
# shift_left & (q5 $ q6)
# shift_right & (q6 $ q7))
# 'h'0080 & (count_up & [q0..6]:& /* BIT 7 */
# count_down & ![q0..6]:&
# shift_left & (q6 $ q7)
# shift_right & (q7 $ q8))
# 'h'0100 & (count_up & [q0..7]:& /* BIT 8 */
# count_down & ![q0..7]:&
# shift_left & (q7 $ q8)
# shift_right & (q8 $ q9))
# 'h'0200 & (count_up & [q0..8]:& /* BIT 9 */
# count_down & ![q0..8]:&
# shift_left & (q8 $ q9)
# shift_right & (q9 $ q10))
# 'h'0400 & (count_up & [q0..9]:& /* BIT 10 */
# count_down & ![q0..9]:&
# shift_left & (q9 $ q10)
# shift_right & (q10 $ q11))
# 'h'0800 & (count_up & [q0..10]:& /* BIT 11 */
# count_down & ![q0..10]:&
# shift_left & (q10 $ q11)
# shift_right & (q11 $ q12))
# 'h'1000 & (count_up & [q0..11]:& /* BIT 12 */
# count_down & ![q0..11]:&
# shift_left & (q11 $ q12)
# shift_right & (q12 $ q13))
# 'h'2000 & (count_up & [q0..12]:& /* BIT 13 */
# count_down & ![q0..12]:&
# shift_left & (q12 $ q13)
# shift_right & (q13 $ q14))
# 'h'4000 & (count_up & [q0..13]:& /* BIT 14 */
# count_down & ![q0..13]:&
# shift_left & (q13 $ q14)
# shift_right & (q14 $ q15))
# 'h'8000 & (count_up & [q0..14]:& /* BIT 15 (MSB) */
# count_down & ![q0..14]:&
# shift_left & (q14 $ q15)
# shift_right & (q15 $ data_in)) ;

counter.ar = reset_count; /* Resets the Counter */



Universidad Nacional de Colombia
Carrera 30 No 45-03 - Edificio 477
Bogotá D.C. - Colombia
PBX: 3165000
webmaster@unal.edu.co

Aviso Legal - Copyright
Gobierno en LíneaAgencia de Noticias UN