CPLD Verilog intro 1: Light a LED
From DP
Contents |
Overview
This is a very simple tutorial to walk you through your first Verilog CPLD design and introduce the ISE Webpack tools.
We only have one goal for this demo: light a LED on the development board. Open the ISE project Verilog-CPLDIntro1LEDon in the XC9572XL or XC2C64A folder.
LED D1 | LED D2 |
---|---|
ON | OFF |
Schematic
The XC2C64A and XC9572XL development boards have two LEDs and a push button. We'll light LED D1 in this demo.
IO | pin connection |
---|---|
LED D1 | P39 |
LED D2 | P38 |
Button PB | P18 |
To turn on LED D1 we need to connect pin 39 (P39) to the power supply inside the CPLD. We'll do this with a simple Verilog example.
Verilog
module CPLDintro1LEDon( LED, //these are the connections to the module that we expose externally LED_INV //external pin number is assigned in the UCF file like this: //NET "LED" LOC = "P39"; //NET "LED_INV" LOC = "P38"; ); output LED;//LED D1 is an output from the module output LED_INV; //LED_INV is also an output reg LED;//a register to output LED reg LED_INV; //a register to output LED_INV always //start of the action section begin LED=1'b1; //Hold the LED D1 on (high) LED_INV=1'b0; //Hold LED D2 off (low) //other states are //1'b1 HIGH //1'b0 LOW //1'bz HiZ (input) end endmodule
The source of CPLDintro1LEDon.v is shown above.
Module
module CPLDintro1LEDon( LED, //these are the connections to the module that we expose externally LED_INV //external pin number is assigned in the UCF file like this: //NET "LED" LOC = "P39"; //NET "LED_INV" LOC = "P38"; ); //... //... //... //... endmodule
This section defines a simple device (module) with two exposed signals, LED and LED_INV.
- LED will be LED D1
- LED_INV will be LED D2
- We'll connect these signals to LED D1 and D2 by assigning the correct pins in the UCF file
Outputs
output LED;//LED D1 is an output from the module output LED_INV; //LED_INV is also an output
The output section declares the exposed signals an input, output, or inout (bidirectional).
- Similar to declaring variable types in C
- input - an input signal to the module, such as a pin driven by a button
- output - an output pin from the module, such as a LED driven by a pin
- inout (bidirectional) - bidirectional pin, can be read and written
Registers
reg LED;//a register to output LED reg LED_INV; //a register to output LED_INV
Signals can come from wires or registers. This section assigns the output signals to a register.
- We declare two registers, each will hold a value that controls a LED
- Also similar to declaring variable types in C
- reg (register) - stores a value, can be read or written in an always block
Always
always //start of the action section begin LED=1'b1; //Hold the LED D1 on (high) LED_INV=1'b0; //Hold LED D2 off (low) //other states are //1'b1 HIGH //1'b0 LOW //1'bz HiZ (input) end
The always section contains the actual logic functions that are performed. It is not run sequentially like a program, these statements define actual logic relationships of the signals.
- LED (LED D1) is turned on by setting the LED register high (1)
- LED_INV (LED D2) is turned off by setting the LED_INV register low (0)
- Another state is input/high impedance. Set this with 1'bz (inout types only)
Assign pin numbers in UCF
#PIN MAP OF DANGEROUSPROTOTYPES.COM CPLD BREAKOUT BOARDS #LICENSE: CC-0 (CREATIVE COMMONS 0) NET "LED" LOC = "P39"; NET "LED_INV" LOC = "P38";
Input and output names in the module are mapped to actual CPLD pin numbers in the UCF file. This is an example UCF file that defines the LED connection on the development boards.
- The Pxx numbers are the actual pin number on the CPLD. Set the LOC (location) of the LED market to P39. Easy.
- ISE has a GUI utility to assign pin numbers, but it doesn't work with CoolRunner-II CPLDs.
We mapped the LED output marker to pin 39, which is attached to LED D1 on the development boards.
Export a JTAG programming file
Most CPLDs are programmed through a 4-wire JTAG interface. ISE programs CPLDs via the IMPACT utility, listed on the design panel as shown.
Only parallel cables and Xilinx USB cables can be used directly from IMPACT. We can also export generic JTAG programming files called (X)SVF. These files can be loaded with an external (X)SVF player utility and output through any JTAG programmer such as the Bus Pirate or Bus Blaster.
- See how to Export (X)SVF from Xilinx ISE Webpack
Program the CPLD
With (X)SVF programming files in hand we're ready to program the CPLD.
Just about any JTAG programmer with an (X)SVF player can now be used to program the CPLD. Here's some examples with our own programmers:
- CPLD programming with Bus Pirate, XSVF loader, and XSVF files
- CPLD programming with Bus Blaster, urJTAG, and SVF files
- More CPLD programming resources
Alternate version
module CPLDintro1LEDon( LED, //these are the connections to the module that we expose externally LED_INV //external pin number is assigned in the UCF file like this: //NET "LED" LOC = "P39"; //NET "LED_INV" LOC = "P38"; ); output LED;//LED D1 is an output from the module output LED_INV; //LED_INV is also an output wire LED;//a wire to output LED wire LED_INV; //a wire to output LED_INV assign LED=1'b1; //Hold the LED D1 on (high) assign LED_INV=1'b0; //Hold LED D2 off (low) //other states are //1'b1 HIGH //1'b0 LOW //1'bz HiZ (input) endmodule
Like most programming languages there is more than one way to do the same task. Here is another example that uses assign instead of the always block.
- LED and LED_INV are wires instead of registers
- Wires cannot be assigned a value in the always block. If you change LED and LED_INV to wires in the always block example there will be a compile error
- Wires are given a value using the assign command
- Assign can use a complex function, as seen in later examples