Thursday 12 January 2017

Using signal buses

You have now worked with signals one bit at a time, but that soon becomes tedious. What if you have thirty-two bits of data to work with? There must be a much simpler way. . . and there is.

Using STD_LOGIC_VECTORs

In VHDL you can create signals that have more than one element in them (a bit like arrays in other languages).

The most common of these complex signals is a STD_LOGIC_VECTOR, which is conceptually a bundle of wires. Unlike most languages where usually one end of the range is implicitly defined, in VHDL you have to be explicit about the high and low element in the array, using ’(x downto y)’ - note that ’x’ is usually greater than or equal to ’y’!

Unlike arrays in languages such as ’C’ you can perform operations on all the elements at once. Here is our switches and LEDs project re-coded to use buses that are two bits wide:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Switches_LEDs is
Port ( switches : in STD_LOGIC_VECTOR(1 downto 0);
LEDs : out STD_LOGIC_VECTOR(1 downto 0));
end Switches_LEDs;
architecture Behavioral of Switches_LEDs is
begin
LEDs <= switches;
end Behavioral;

If desired, you can address individual bits in a bus:

LEDs(0) <= switches(0);
LEDs(1) <= switches(1);

You can concatenate signals into a bus using the ’&’ operator. This code sample swaps the bits around so switch 0 lights LED 1 and switch 1 lights LED 0:

LEDs <= switches(0) & switches(1);

The important thing to remember is that like binary numbers the higher number bits are "to the left" of lower numbered bits - usually the opposite way that you think of an array.

Oh, and much like character arrays in C the other tricky bit is that constant expressions for

STD_LOGIC_VECTOR use double
quotes ("), instead of single quotes (’) - single quotes are used for individual elements.

This will work:
LEDs <= "10";
But this will throw an error:
LEDs <= ’10’;
To use the buses you will need to change your constraints file as follows:
# Constraints for Papilio One
NET switches(1) LOC = "P3" | IOSTANDARD=LVTTL;
NET switches(0) LOC = "P4" | IOSTANDARD=LVTTL;
NET LEDs(1) LOC = "P16" | IOSTANDARD=LVTTL;
NET LEDs(0) LOC = "P17" | IOSTANDARD=LVTTL;
# Constraints for the Basys2
NET switches(1) LOC = "L3" | IOSTANDARD=LVTTL;
NET switches(0) LOC = "P11" | IOSTANDARD=LVTTL;
NET LEDs(1) LOC = "M11" | IOSTANDARD=LVTTL;
NET LEDs(0) LOC = "M5" | IOSTANDARD=LVTTL;

 Project - More LEDs and switches

• Modify your project to use buses.
• Extend the width of the buses to 8 bits ("(7 downto 0)"), and add the additional constraints for LEDs 2 through 7, and switches 2 through 7 to the .ucf file. To save you trolling through the documentation, here are the signal locations:

# Constraints for Papilio One
NET LEDs(7) LOC = "P5" | IOSTANDARD=LVTTL;
NET LEDs(6) LOC = "P9" | IOSTANDARD=LVTTL;
NET LEDs(5) LOC = "P10" | IOSTANDARD=LVTTL;
NET LEDs(4) LOC = "P11" | IOSTANDARD=LVTTL;
NET LEDs(3) LOC = "P12" | IOSTANDARD=LVTTL;
NET LEDs(2) LOC = "P15" | IOSTANDARD=LVTTL;
NET LEDs(1) LOC = "P16" | IOSTANDARD=LVTTL;
NET LEDs(0) LOC = "P17" | IOSTANDARD=LVTTL;
NET switches(7) LOC = "P91" | IOSTANDARD=LVTTL;
NET switches(6) LOC = "P92" | IOSTANDARD=LVTTL;
NET switches(5) LOC = "P94" | IOSTANDARD=LVTTL;
NET switches(4) LOC = "P95" | IOSTANDARD=LVTTL;
NET switches(3) LOC = "P98" | IOSTANDARD=LVTTL;
NET switches(2) LOC = "P2" | IOSTANDARD=LVTTL;
NET switches(1) LOC = "P3" | IOSTANDARD=LVTTL;
NET switches(0) LOC = "P4" | IOSTANDARD=LVTTL;
# Constraints for the Basys2
NET LEDs(7) LOC = "G1" | IOSTANDARD=LVTTL;
NET LEDs(6) LOC = "P4" | IOSTANDARD=LVTTL;
NET LEDs(5) LOC = "N4" | IOSTANDARD=LVTTL;
NET LEDs(4) LOC = "N5" | IOSTANDARD=LVTTL;
NET LEDs(3) LOC = "P6" | IOSTANDARD=LVTTL;
NET LEDs(2) LOC = "P7" | IOSTANDARD=LVTTL;
NET LEDs(1) LOC = "M11" | IOSTANDARD=LVTTL;
NET LEDs(0) LOC = "M5" | IOSTANDARD=LVTTL;
NET switches(7) LOC = "N3" | IOSTANDARD=LVTTL;
NET switches(6) LOC = "E2" | IOSTANDARD=LVTTL;
NET switches(5) LOC = "F3" | IOSTANDARD=LVTTL;
NET switches(4) LOC = "G3" | IOSTANDARD=LVTTL;
NET switches(3) LOC = "B4" | IOSTANDARD=LVTTL;
NET switches(2) LOC = "K3" | IOSTANDARD=LVTTL;
NET switches(1) LOC = "L3" | IOSTANDARD=LVTTL;
NET switches(0) LOC = "P11" | IOSTANDARD=LVTTL;

Test that it works as expected.
• Change the project to wire switches 0 through 3 to LEDs 4 through 7, and switches 4 through 7 to LEDs 0 through 3
• The AND, OR, NOT and related operators also work on buses. Change the project so that LEDs 0 through 3 show ANDing of switches 0 through 3 with switches 4 through 7, and LEDs 4 through 7 show ORing of switches 0 through 3 with switches 4through 7

No comments:

Post a Comment