Areas to be covered:
CUPL
Programming Language
CUPL
Simulator Language
Usage of the
CUPL Environment
Troubleshooting
File extensions that will be useful to know
PLD | Created by the user Contains all of the logic instructions necessary for your device, i.e. the cupl program itself. |
DOC | Generated by CUPL Contains all of the logic equations that CUPL generated from your program Tells you errors encountered in compiling the program (including location) Provides information about how it fit the compiled logic into the selected device. |
ABS | Generated by CUPL File used by CUPL to perform the simulation |
LST | Generated by CUPL Error Listing file that contains all the original lines of code numbered. All errors are listed at the end with offending line number. |
JED | Generated by CUPL File used by the programmer to actually burn the chip Filename comes from the Name field in the pld file header |
SI | Simulation Input file created by user Contains your list of test vectors |
SO | Simulation Output file generated by CUPL Contains the results of the simulation run including any errors Used for the graphical display of your simulation results |
Reserved Words (not case sensitive)
APPEND | ASSEMBLY | ASSY | COMPANY | CONDITION |
DATE | DEFAULT | DESIGNER | DEVICE | ELSE |
FIELD | FLD | FORMAT | FUNCTION | FUSE |
GROUP | IF | JUMP | LOC | LOCATION |
MACRO | MIN | NAME | NODE | OUT |
PARTNO | PIN | PINNNODE | PRESENT | REV |
REVISION | SEQUENCE | SEQUENCED | SEQUENCEJK | SEQUENCERS |
SEQUENCET | TABLE |
& | # | ( | ) | - |
* | + | [ | ] | / |
: | . | .. | /* | */ |
; | , | ! | ' | = |
@ | $ | ^ |
Number | Base | Decimal Value |
'b'0 | binary | 0 |
'b'1101 | binary | 13 |
'o'663 | octal | 435 |
'D' 92 | decimal | 92 |
'h' BA | hexadecimal | 186 |
'b'[001..100] | binary | range from 1 to 4 |
Number | Base |
'o'0X6 | octal |
'b'11X1 | binary |
'h'[3FXX..7FFF] | hexadecimal (range) |
Most instruction statements end with a semicolon.
All of the header fields are required to be present in the file, but only the Name field is required to have a real value in it. It will be used as the name for the JEDEC output file (the file you will use with the programmer) so it needs to be a valid DOS name (i.e. max of 8 characters). The compiler will perform a check to verify all of the fields are present.
The Device field allows you to set the default device type used in
compilation. I would suggest using this so you don't have to worry about
setting the device manually before compiling (see the device
selection section). The name to put in here will be the name you would
have selected manually. For example, a GAL22V10 would be "g22v10" and a
GAL16V8 would be "g16v8". Note that this field is not required.
e.g.
Pin 1 = !a; /*Assign pin 1 to be "not
a".*/
/*The optional '!' defines the polarity.*/
Pin [2..5] = [b,
c, d, e];
/* assign pin 2=b, pin 3=c, pin 4=d, pin5=e*/
Pin [6,10] =
[f,g]; /*Assign pin 6 to f and pin 7 to g.*/
The polarity selection allows you to choose whether the signal is active
high or active low. Default, without a bang, is active high. This
allows you to simply write equations without having to worry about if the signal
is active high or low. You can simply refer to it as being asserted or
not.
e.g.
Pin 2 = !A;
Pin 3 = !B;
Pin 16 = Y;
Y = A & B; /*Y will be true (high) when both A and B are
*/
/* true (both are low). */
You can also define your pins for a virtual device simply by not putting the pin numbers in. This will allow the compiler to pick pins for the signal. Even though this is possible, I would not suggest using it as it seems to have difficulty with the dynamic assignment and the polarity assignment doesn't apply.
The two key commands that are used for this is Node and PinNode. For exact syntax refer to the manual and online help.
e.g.
FIELD Data = [D0..D7]; /*Assigns Data name
to group of bits.*/
FIELD Control = [strobe,ack,rdy];
/*Also works on individual pins.*/
Rules for Bit fields
1. Never mix indexed and non-indexed
variables in a single field statement.
2. Don't use the same index of
different indexed variable in a field declaration (i.e. A2 and B2 cannot be used
in the same field variable).
e.g.
MIN async_out = 0;
MIN outa
= 2;
MIN Data.D = 4;
Note that Data uses the D extension to specify that that the registered output is the one to be reduced.
Available levels to use:
Level | Amount of minimization (or method) |
0 | No minimization |
1 | Quick minimization |
2 | Quine McCluskey |
3 | Presto |
4 | Expresso |
e.g.
$DEFINE ON 'b'1
$DEFINE OFF
‘b’0
$MACRO and $REPEAT are two other that you might use. Other commands can be found in the documentation. Keep in mind that since these only for the preprocessor, they can be used in any part of the program.
Note: There is no semicolon at the end of the Preprocessor commands
e.g.
$repeat i = [0..7]
$define point{i} 'b'{i}
$repend
This is the same as if the following had been entered.
$define point0 'b'000
$define point1 'b'001
$define point2 'b'010
$define point3
'b'011
$define point4 'b'100
$define
point5 'b'101
$define point6 'b'110
$define point7 'b'111
Operator | Example | Description |
** | 2**3 | Exponential |
* | 2*1 | Multiplication |
/ | 4/2 | Division |
% | 9%8 | Modulus |
+ | 2+4 | Addition |
- | 4-1 | Subtraction |
Function | Base |
LOG2 | Binary |
LOG8 | Octal |
LOG16 | Hexadecimal |
LOG | Decimal |
e.g.
$repeat i = [0..7]
present point{i}
if
score next point{(i+1)%8};
default next point{i};
$repend
This would be equivalent to entering:
present point0
if score next point1;
default next point0;
present point1
if score next
point2;
default next point1;
...
present point7
if score next point0;
default next point7;
Useful extensions for the g22v10 and g16v8 are:
.AR /* Asynchronous Reset of flip-flop
*/
.SP /* Synchronous Preset of
flip-flop */
.OE /* Output Enable
*/
.D /* D input of D-type
flip-flop */
Other extensions can be found in the manual or online
help.
Operator | Example | Description |
! | !A | NOT |
& | A&B | AND |
# | A#B | OR |
$ | A$B | XOR |
e.g.
field mode = [clr,dir];
up = mode:0;
down = mode:1;
clear = mode:[2..3];
This is equivalent to:
up = !clr & !dir;
down = !clr & dir;
clear = (clr &
!dir) # (clr & dir);
The equality operator can also be used with a set of variables that are to be operated on identically. This is valid for only the &, #, and $ operators.
e.g.
[A3,A2,A1,A0]:&
[B3,B2,B1,B0]:#
[C3,C2,C1,C0]:$
are equivalent respectively to:
A3 & A2 & A1 &
A0
B3 # B2 # B1 # B0
C3 $ C2 $ C1 $
C0
e.g.
APPEND Y = A0 & A1;
APPEND Y = B0 & B1;
APPEND Y = C0 & C1;
The three statements are equivalent to the following equation:
Y = (A0 & A1) # (B0 & B1) # (C0 & C1);
The append statement is useful in adding additional terms (such as a reset) to state machine variable.
e.g.
FIELD input = [In3..0];
FIELD output = [out4..0];
TABLE
input => output {
0=>00; 1=>01; 2=>02;
3=>03;
4=>04; 5=>05; 6=>06; 7=>07;
8=>08; 9=>09; A=>10; B=>11;
C=>12; D=>13; E=>14; F=>15;
}
e.g.
PIN [1..4] =
[a12..15];
/*upper 4 addresses*/
PIN 12 =
!RAM_sel;
/*8Kx8 RAM*/
PIN 13 =
!ROM_sel;
/*32Kx8 ROM*/
PIN 14 =
!timer_sel;
/*8253 Timer*/
FIELD address = [a12..15];
FIELD decodes = [RAM_sel, ROM_sel, timer_sel];
TABLE address => decodes {
[1000..2FFF] =>
'b'100;
/* select RAM */
[5000..CFFF] =>
'b'010;
/* select ROM */
F000 =>
'b'001;
/* select timer */
}
Notice that the outputs
are all active low. Therefore in the truth table, when the output is
'b'100, only RAM_sel will be asserted (set to logic 0) while ROM_sel and
timer_sel are deasserted (set to logic 1).
e.g.
PIN [10..11] = [Count1..0];
PIN 4 = up;
PIN 5 = down;
PIN 6 = enabled;
PIN 13 =
stuck;
PIN 14 = two;
FIELD
counter = [Count1..0];
$DEFINE s0 'b'00;
$DEFINE s1 'b'01;
$DEFINE
s2 'b'10;
$DEFINE s3 'b'11;
sequence counter {
present s0
if up & enabled next s1;
if down & enabled next s2;
if enabled & !up & !down next s0 OUT stuck
if !enabled next s0 OUT stuck;
present s1
if up & enabled next s2;
if down & enabled next s0;
default next s1 OUT stuck;
present s2
if up & enabled next s0;
if down & enabled next s1;
default next s2 OUT stuck OUT two;
present s3
next s0;
}
To define multiple state machines, merely set up different variables.
The
default condition is the complement of the other conditional statements so it
can generate a complex expression. In the above example, the default
statement of state s1 is equivalent to the last two if statements in state
s0. See the following section to understand the OUT statement.
CONDITION {
if expr0 OUT var1;
...
...
if exprn OUT var2;
default OUT var3;
}
e.g.
PIN [1,2] = [A,B] ; /* Data Inputs */
PIN 3 = !enable ; /* Enable Input */
PIN
[12..15] = [Y0..3] ; /* Decoded Outputs */
PIN 14 = no_match
; /* Match Output */
CONDITION {
IF enable & !B & !A out Y0;
IF enable & !B & A out Y1;
IF enable & B & !A out Y2;
IF enable & B & A out Y3;
default no_match;
}
The
above default statment is equivalent to:
IF !enable out no_match;
Order lists the order of all of the inputs and outputs for the device.
Vectors then contains the list of the test vectors to be applied to
previously stated inputs and outputs.
e.g.
ORDER: Clock, Input1, Input2, Output;
VECTORS: 1 0 X 0
1 0 0
*
1 0
1 1
Note: Formatting doesn't matter, it uses
white spaces to determine which vector applies to which input or output.
No semicolons are used anywhere in the vector list.
Values that can be used in the Vector table
Test Value |
Used with | Description |
0 | Input | Drive low |
1 | Input | Drive high |
C | Input | Drive (clock) low, high, low (in 1 cycle) |
K | Input | Drive (clock) high, low, high (in 1 cycle) |
L | Output | Test if low |
H | Output | Test if high |
Z | Output | Test for high impedance |
X | Input or Output |
High or Low (don’t care) |
N | Output | not tested |
* | Output | simulator determines what the value is |
' ' | Input | Encloses values to be expanded from a specified BASE |
" " | Output | Encloses values to be expanded from a specified BASE |
e.g.
ORDER: Clock, Input1, Output1;
BASE: hex
VECTORS: C 'F' *
C '0'
*
Normally you will want to use the * on outputs to let the simulator tell you what it has calculated. This way you have an idea of what is actually going on inside. Otherwise, with the ‘L’ and ‘H’, you just know whether or not it is correct. If it's not correct then you will just get CSIM errors.
This is all that is necessary to simulate your file. The graphical display will then use the SO file to generate the picture of your waveforms. If you would like to make the SO file itself easier to read and follow, then you can add more information to the SI file as follows:
e.g.
ORDER: "clock is ", clock, "and input is",
A2..0, ...
Produces the following results in the output file:
0001: Clock is C and input is 000 ...
0002: Clock is C and input is 001 ...
Level of Minimization | Comments |
None | Disables logic minimization during a CUPL compilation. It is useful when working with PROMs, to keep contained product terms from being eliminated. |
Quick | Balances the reduction efficiency, memory usage, and execution time. |
Quine-McCluskey | Provides the highest level of reduction efficiency, but requires more memory and time to compile. |
Presto | Provides a high level of reduction efficiency, but requires less memory and time to compile. This option will perform multiple output minimization in IFL devices. This maximizes product sharing in these types of devices. |
Expresso | Provides a higher level of reduction efficiency than Presto, requires more memory to compile than Presto, but requires less time for compilation. As with Presto, this option will perform multiple output minimization in IFL devices. This maximizes product sharing in these types of devices. |
Q. When I am compiling, I get CSIM errors, but I'm not trying to simulate it
yet.
A. Turn off simulation in the Compiler
Options menu.
Q. It tells me I have too many product terms when I compile it. Now
what do I do
A. Look in the DOC file where it tells how many are available
and how many are used. Now that you know this, you can:
1. Adjust which pin you are using
to get more available product terms (this is part dependent).
2. Change the minimization
options.
3. Change your logic
so it uses less product terms (definitely the most difficult).
Q. When I compile I get an error similar to: "Unable to open RUNFIT.$$$".
A. This generally indicates that CUPL has run out of memory (used it up) so
you need to exit and restart CUPL.