# Module 4

Please make sure that you have completed the earlier modules of FPGA course.

Having problems with your code? Do I need to change something? Want a reference solution to the project? Email me at "nospam-hamster@snap.net.nz", after removing the "nospam-" bit. I'll try to get back to you in a day or so.

## Aims of module

• To use more than one 'bit' at a time
• Learn how to manipulate bit vectors

## Using 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 signal 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 like C you can perform operations on all the elements at once. Here is our switches and LEDs project recoded to use buses that are two bits wide:

``` 1: library IEEE;
2: use IEEE.STD_LOGIC_1164.ALL;
3:
4: entity Switches_LEDs is
5:   Port ( switches : in  STD_LOGIC_VECTOR(1 downto 0);
6:          LEDs     : out STD_LOGIC_VECTOR(1 downto 0));
7: end Switches_LEDs;
8:
9: architecture Behavioral of Switches_LEDs is
10: begin
11:   LEDs <= switches;
12: end Behavioral;

```

If desired can address individual bits in a bus:

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

You can combine individual 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 ('}:

```LEDs <= "10";
```

To use the buses you will need to change your constraints file as follows:

```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 4.1 - 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:
```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
• LEDs 4 through 7 show ORing of switches 0 through 3 with switches 4 through 7

## Ready to carry on?

Click here to carry on to the next module.