CPLD Verilog intro 3: Inverse LED toggle

From DP

Jump to: navigation , search

Contents

Overview

In tutorial 3 we build on the simple push button example in tutorial 2. We'll add logic that inverts the output of button 1 on LED D2.

Tutorial 3 truth table
Button PB LED D1LED D2
Pressed OFF ON
NOT pressed ONOFF

Schematic

Cpld-tutorial-external-circuit.png

In this demo we'll use both LEDs and the push button connected to the CPLD.

CPLD dev board connections
IO pin connection
LED D1 P39
LED D2 P38
Button BP P18
The XC2C64A CPLD has internal pullup resistors
R1 is unpopulated on the XC2C64A development board

Verilog

Cpld-demo3.png

module CPLDIntro3LEDinverse(
    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:
     BUTTON //
                //NET "LED"            LOC =  "P39";
                //NET "LED_INV"        LOC =  "P38";
    );        //NET "BUTTON"        LOC =  "P18";
 
 
    output LED;//LED D1 is an output from the module
    output LED_INV; //LED_INV is also an output
 
    input BUTTON; //button is an input signal
 
    reg LED;//a register to output LED
    reg LED_INV; //a register to output LED_INV
 
    wire BUTTON; //input button is a wire
 
    always @ (BUTTON) //start of the action section
    begin
        LED=BUTTON; //Set reg LED to the value of wire BUTTON
        LED_INV=!BUTTON; //Set reg LED_INV opposite of wire BUTTON
    end
 
endmodule

We only make one minor change to the always section of the part 5 Verilog.

        LED_INV=!BUTTON; //Set reg LED_INV opposite of wire BUTTON

This adds sets LED_INV (D2) to the opposite (!=) state of wire BUTTON.

  • Input from the push button enters the CPLD through wire BUTTON
  • The BUTTON wire connects to reg LED (D1) as before
  • Reg LED_INV (D2) is set to be the opposite (|=) of the BUTTON wire.

UCF

XC9572 UCF

Cpld-demo3.png

#PIN MAP OF DANGEROUSPROTOTYPES.COM CPLD BREAKOUT BOARDS
#lICENSE: CC-0 (CREATIVE COMMONS 0)
#http://dangerousprototypes.com/docs/XC9500XL_CPLD_breakout_board
#http://dangerousprototypes.com/docs/CoolRunner-II_CPLD_breakout_board
NET "LED"            LOC =  "P39";
NET "BUTTON"        LOC =  "P18";
NET "LED_INV"        LOC =  "P38";

Input and outputs from the module are mapped to actual CPLD pin numbers in the UCF file. This is an example UCF file that defines the three IO connections on the development boards.

  • The Pxx numbers are the actual pin number on the CPLD. Easy.

We mapped the BUTTON input market to pin 18. The LED output marker connects to pin 39 (D1), and LED_INV connects to pin 38 (D2).

XC2C64A

Cpld-xc2c-ledinv.png

#PIN MAP OF DANGEROUSPROTOTYPES.COM CPLD BREAKOUT BOARDS
#lICENSE: CC-0 (CREATIVE COMMONS 0)
#http://dangerousprototypes.com/docs/XC9500XL_CPLD_breakout_board
#http://dangerousprototypes.com/docs/CoolRunner-II_CPLD_breakout_board
NET "LED"            LOC =  "P39";
NET "LED_INV"        LOC =  "P38";
NET "BUTTON"         LOC =  "P18";
NET "BUTTON"         PULLUP;

The XC2C64A version is the same, except we use the internal pull-up resistor instead of R1 on the development board.

Alternate version

module CPLDIntro2Ledbutton(
    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:
     BUTTON //
                //NET "LED"            LOC =  "P39";
                //NET "LED_INV"        LOC =  "P38";
    );        //NET "BUTTON"        LOC =  "P18";
 
 
    output LED;//LED D1 is an output from the module
    output LED_INV; //LED_INV is also an output
 
    input BUTTON; //button is an input signal
 
    wire LED;//a register to output LED
    wire LED_INV; //a register to output LED_INV
 
    wire BUTTON; //input button is a wire
 
    assign LED=BUTTON; //Set reg LED to the value of wire button
    assign LED_INV=!BUTTON; //Hold LED D2 off (low)
                    //other states are
                    //1'b1 HIGH 
                    //1'b0 LOW
                    //1'bz HiZ (input)
endmodule

This example uses all wires and the assign command instead of registers and an always block.

  • Wires cannot be manipulated in an always block like registers
  • Wires are assigned a value with the assign command