Image of Basys 3 Board

One of the Slide Switches and Many LEDs

For this next project I want to explore the on-board slide switches provided by the Basys 3. I want to keep this project simple and focused on the switches. The simplest idea I could come up with was connecting a switch to an LED. Turn one of the switches on and the LED goes on, switch off and the LED goes off. We can do this with a simple combinational circuit. If you don’t recall what a combinational circuit it you may want to read the post on building an Exclusive Or circuit.

I start by creating a new project in Vivado. Next I copy in the Basys-3-master.xdc constraint file. Since this is a combinational circuit we do not need a clk port. So that stays commented out. The IO ports that we do need for this project are sw[0], which I rename to sw0. and at least one of the LEDs. Since I might decide I want to do something with more than one of the LED’s I simply uncomment all 16 of them and do not rename them. In Verilog the led port is actually an array of output ports. In hardware terms you would typically call such an array of ports a bus. You can see my complete constraints file below.

## Switches
set_property PACKAGE_PIN V17 [get_ports {sw0}]
	set_property IOSTANDARD LVCMOS33 [get_ports {sw0}]

## LEDs
set_property PACKAGE_PIN U16 [get_ports {led[0]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN E19 [get_ports {led[1]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN U19 [get_ports {led[2]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN V19 [get_ports {led[3]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN W18 [get_ports {led[4]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
set_property PACKAGE_PIN U15 [get_ports {led[5]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
set_property PACKAGE_PIN U14 [get_ports {led[6]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
set_property PACKAGE_PIN V14 [get_ports {led[7]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
set_property PACKAGE_PIN V13 [get_ports {led[8]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}]
set_property PACKAGE_PIN V3 [get_ports {led[9]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]
set_property PACKAGE_PIN W3 [get_ports {led[10]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]
set_property PACKAGE_PIN U3 [get_ports {led[11]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]
set_property PACKAGE_PIN P3 [get_ports {led[12]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]
set_property PACKAGE_PIN N3 [get_ports {led[13]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]
set_property PACKAGE_PIN P1 [get_ports {led[14]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}]
set_property PACKAGE_PIN L1 [get_ports {led[15]}]
	set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}]

## Configuration options, can be used for all designs
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]

What about the Verilog

I then create a new Verilog and declare the ports we will use. At this point, the module declaration looks like the following. We’ve declared sw0 to be an input (wire) and the led port as a 16-bit output (wire). So far so good.

module sw_led(
    input sw0,
    output [15:0] led
    );
    
endmodule

The sw0 port is physically connected to the switch on the Basys 3 board. When you move the switch the input signal changes logic state. In this case we want to connect the switch to our LED. All that requires is a continuous assignment.

Signal Replication

However, turning on a single LED seems so dull. So to make this a little bit more interesting let’s turn on all the LEDs at the same time. We can do this in Verilog through the use of signal replication. Through the use of the Verilog concatenation operator { } we can manipulate signals in very interesting ways including duplicating, concatenating, and re-ordering the sub-ranges of one or more signal sets. In our case we want to copy the input port sw0 to all 16 of the led ports. With this information in hand, writing the code is straightforward.

module sw_led(
    input sw0,
    output [15:0] led
    );
    
    // replicate the sw0 signal 16 times and assign to led[15:0]
    assign led[15:0] = {16{sw0}};
    
endmodule

Do you see how the concatenation operator works? We tell it to take a collection of signals (in this case just one signal), specified as { sw0 }, and duplicate it 16 times grouping it as a new collection of signals. The duplication of a signal, or collection of signals, is called replication. And then we assign those 16 signals to led[15] through led[0]. When I synthesize this circuit and try it out on the Basys 3, it works as expected. Toggling the switch toggles all 16 LEDs on or off.

And that’s it for now. The source code for this project is here.

If you have feedback, questions or suggestions regarding this post, please leave a comment!

Discover more from FPGA Coding

Subscribe now to keep reading and get access to the full archive.

Continue reading