Skip to content

Basic I/O-2: Leds, Buttons, Switches and DIP-Switches

Leds

Leds are the simplest of the output devices.  A led is basically a “light bulb” with two pins. One of the pins is known as “cathode”, the other pin is called “anode”.  The longer leg is the anode.

A led will emit light only when the anode is 1 and cathode is zero. In all the other cases, it will not emit light.

Anode Cathode Will it emit light?
0 0 no
0 1 no
1 0 YES
1 0 no

In most cases, cathode of the diode is permanently connected to zero.

Switches and Buttons

Switches and buttons are the simplest input devices.

A button is a hardwire device with a 1-bit output. This output becomes 1 when the button is pressed. It is 0 when the button is released.

A switch is a button with two positions. In one position, its output is permanently 1. In the other position, its output is permanently 0. Pressing the switch (or shifting it to left or right) will change its output. Switches can be said to be “buttons with memory”.

Using Leds and buttons in Verilog

During the pin assignment stage,

  • A button must be connected to an input variable
  • A led must be connected to an output variable.

Then, that input variable’s value will follow button’s value: Whenever the button is pressed, the input variable will take the vaule 1. Otherwise, it will be zero. An the led will get on or off depending on the value of the output variable to which it was assigned. Whenever the output variable becomes 1, it will get on. Otherwise, it will get off.

Example 1: Let us write a module module which will burn a led if a button is pressed

module button_to_led(sw,led);
input logic sw;        //during pin assignment, assign to a button
output logic led;      //during pin assignment, assign to a led

     assign led = sw;
	
endmodule

Example 2: Let us write a module which will count how many times a button is pressed and display the result as a 4-bit binary number. Note that a buttonpress is defined as pressing and releasing a button.
module bounced_switch(sw,led,clk);
input logic sw;                //during pin assignment, assign to a button
output logic [3:0] count;      //during pin assignment, assign each bit to a led
logic old;

     always_ff @posedge(clk)
     begin
         old <= x;
         if ( old == 1'b0 & x == 1'b1 )     //detect the edge
             count <= count+ 4'b1;
     end	
endmodule

Debouncing

In most cases, example 1 will not work properly.

DIP Switches and Buttons

DIP switch is a set of electric switches that are packaged together dual in-line package (DIP).

Debouncing Problem

All mechanical components (DIP-switches, pushbuttons etc) suffer from debouncing problem. Whenewer the position of a switch is changed or a button is pushed, it takes approximately 20ms for the switch/button output to settle into its new value.

Let us try to clarify this problem by means of an example: Assume that the output of the unpressed button is 0. Now somebody presses the button and its output eventually settle at 1. But immediately after it is being pressed, its output will oscillate between 0 and 1 before being settled into 1. This is called “bouncing”. In practical terms, we can say that after being pressed, the output of the button will be unavailable for 20 ms.

Now assume that the person who pressed the button released it. The button output will eventually settle to 0. But immediately after it is being released, its output will oscillate between 0 and 1 before being settled into 0. In practical terms, we can say that after being pressed, the output of the button will be unavailable for 20 ms.

It is possible to buy “debounced switches and buttons” in the market. These components have additional hardware ingredients inside them which filter out the 20ms oscillations and give a clean 0-1 or 1-0 transition to the user. The four buttons on your De0-nano kits are all debounced. Naturally, such components are more expensive..

In sequential designs working under a clock, bouncing buttons werak havoc. Such buttons must be “debounced” before use. We will se how this is done in a future chapter.

module debounced_switch(ds,clk,display,grounds);
input logic ds;
input clk;
output logic [6:0] display;
output logic [3:0] grounds;

logic [15:0] number;
logic [31:0] buffer;	
logic state;
logic [25:0]clk1;

//clk1 signal oscilates with 50MHz/2^16 = 775 Hz
//which means, a period of clk1 is 0.0013 sec
//as the debounce period is 20ms, we need to wait 20 clocks 
//for a clean signal    
always_ff @(posedge clk)//
	clk1<=clk1+1;
	
always_ff @(posedge clk1[15])


begin
   buffer <= {buffer[30:0],ds};
	case (state)
			1'b0:
				begin
					if(&(buffer)== 1) // or if(buffer == 32'b1)
						begin
							number<=number + 1;
							state<=1;
						end
				end
			1'b1:
				begin
				   if(|(buffer) == 0) // or if(buffer == 32'b0)
						state<=0;
				end
		endcase
end

sevensegment ss1 (.datain(number), .grounds(grounds), .display(display), .clk(clk));

initial 
	begin
		number=0;
		state=0;
		buffer = 32'b0;
	end	

	
endmodule