CPLD Verilog intro 1: Light a LED

From DP

Jump to: navigation , search

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.

Tutorial 1 truth table
LED D1 LED D2
ONOFF

Schematic

Cpld-tutorial-external-circuit.png

The XC2C64A and XC9572XL development boards have two LEDs and a push button. We'll light LED D1 in this demo.

CPLD dev board connections
IO pin connection
LED D1 P39
LED D2 P38
Button PB P18

Cpld-intro1.png

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.

Cpld-intro1.png

  • 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

Cpld-itutorial-ise-impact.png

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.

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:

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