# Using VHDL to Describe a 3-8 Decoder and a 7-segment Display

## Objectives

```
Learn Selected Signal Assignment Statement
Distinguish three different types:  Integer, Natural, and Positive
Use Signals in VHDL
Build circuits to test your 3-8 decoder and 7-segment display

```

We have examined some simple VHDL entities and design entry procedures. We also learned the concurrent signal assignment statements and some of the rules and options available to us when we create a design in VHDL. In this lab, let's learn a new statement in making VHDL files.

### 1. Selected Signal Assignment Statement

We have seen that a Boolean Expression can be used in a VHDL file. Sometimes, the format of an expression in the VHDL can be hard to read and prone to errors in the typing. There is another method to encode a Boolean function in the VHDL program, which is called selected signal assignment statement. This statement allows us to assign alternative values to an object, based on the status of a reference signal. The form of the statement is:
```
WITH  __expression SELECT

__signal <= __expression WHEN __constant_value,

__expression WHEN __constant_value,

__expression WHEN __constant_value,

__expression WHEN __constant_value;

```
This type of statement can be used to encode an SOP Boolean expression, as represented by a truth table.

For example, if we know that a circuit has the following truth table:

```
D2  D1  D0   Y
--------------
0   0   0    0
0   0   1    0
0   1   0    1
0   1   1    0
1   0   0    0
1   0   1    0
1   1   0    0
1   1   1    1
--------------
```
we can represent the corresponding expression in VHDL as follows, assuming we have defined d as type BIT_VECTOR(2 downto 0):
```
WITH d SELECT

y <= '1' WHEN "010",
'1' WHEN "111",
'0' WHEN others;

```
This statement can be interpreted as saying, "when the value of d is either "010" or "111", the output y is set to '1'.
Otherwise, set the value of y to '0'." The keyword others is used to specify all cases other than those explicitly selected.

Using LogicWorks to create a VHDL file for the above example, we can obtain the following:

```
library IEEE;
use IEEE.std_logic_1164.all;

entity Ex250 is

port(
d	: in	std_logic_vector(2 downto 0);
y	: out	std_logic
);

end Ex250;

architecture arch1 of Ex250 is

begin

-- Your VHDL code defining the model goes here
WITH d SELECT

y <= '1' WHEN "010",
'1' WHEN "111",
'0' WHEN others;

end arch1;

```
We can see the simulation through I/O Panel or Circuits window.

### 2. Integer, Natural, and Positive

• Integers are positive and negative whole numbers.
• The VHDL INTEGER type consists of the range of positive and negative
numbers that can be represented by the number of bits supported by
the computer for which a given VHDL compiler is designed.
• There are two subsets of INTEGER, called NATURAL and POSITIVE.
• NATURAL is the set of all integers greater than or equal to 0.
• POSITIVE is the set of all integers greater than or equal to 1.
• Constants in all these types are written in VHDL without quotes (e.g. y <= 5;).
We can define a multi-bit port of type INTEGER without specifying how many bits the port must have.
The VHDL compiler will calculate the required number of bits, based on the range of the possible Boolean combinations of the port.

For example, a 3-bit input port can be specified by either of the following two ways:

```
d: IN BIT_VECTOR(2 downto 0);

d: IN INTEGER RANGE 0 to 7;

```

#### Example 1:

Now let's look at a full example. Let's assume that a digital circuit is specified by the following truth table:
```
D2  D1  D0   Y
--------------
0   0   0    0
0   0   1    1
0   1   0    0
0   1   1    0
1   0   0    0
1   0   1    1
1   1   0    1
1   1   1    0
--------------

```
Here is the VHDL code to describe the operation of the circuit.
```
library IEEE;
use IEEE.std_logic_1164.all;

entity EX253 is

port(
D	: in	std_logic_vector (2 downto 0);
Y	: out	std_logic
);

end EX253;

architecture arch1 of EX253 is

begin

-- Your VHDL code defining the model goes here
with d select
y <= '1' when "001",
'1' when "101",
'1' when "110",
'0' when others;
end arch1;

```
Here is the VHDL code with d specified as type INTEGER.
```
library IEEE;
use IEEE.std_logic_1164.all;

entity EX254 is

port(
D	: in	integer range 0 to 7;
Y	: out	std_logic
);

end EX254;

architecture arch1 of EX254 is

begin

-- Your VHDL code defining the model goes here
with d select
y <= '1' when 1,
'1' when 5,
'1' when 6,
'0' when others;
end arch1;

-- Note that the output, y, is of type STD_LOGIC.
-- It is assigned constant value in single quotes.
-- The values of d is of type INTEGER.
-- They are specified without quotes.

```

### 3. Signals in VHDL

Signal is an internal connection within a VHDL architecture that connects parts of the design together.
A signal acts like a connecting wire inside the design.

#### Multi-Bit Signals

Let's assume that we have a digital circuit with the following function block representation and truth table:
```

A B C   W X Y Z
---------------
0 0 0   1 0 0 0
0 0 1   0 1 0 0
0 1 0   0 1 1 0
0 1 1   1 0 0 1
1 0 0   0 1 1 0
1 0 1   0 0 0 1
1 1 0   1 0 0 1
1 1 1   0 0 1 0
---------------

```
The Boolean expressions can be easily obtained by using K-map. Although we can use concurrent signal assignment statements for the four outputs, with the truth table above, selected signal assignment statements may come handier. To explore more about selected signal assignment statements, we are going to use it for this example. We need a signal name for inputs and a signal name for outputs. These names can represent multi-bit objects of type BIT_VECTOR, STD_LOGIC_VECTOR. or INTEGER, but they must still have only one name. For example, the following statement is wrong:
```	-- Illegal syntax

WITH a, b, c, SELECT
w, x, y, z <= "1000" WHEN "000",
etc.

```
To use selected signal assignment statement, we can create a signal that bundles together the inputs into a single group of type BIT_VECTOR, STD_LOGIC_VECTOR. or INTEGER. We also need a multi-bit signal for all outputs that we can use in a selected signal assignment statement and "peel off" the various bits and map them to single-bit outputs.

A signal is a VHDL construct used for connecting internal parts of a design, something like a internal connecting wire. The following diagram shows the general idea. Ports A, B, and C come into the entity as separate ports. Inside the design they are bundled together like a 3-wire cable in the signal called inputs. (Note: "inputs" here is a user defined name; it could be any name at all, as long as it conforms to the rules for valid VHDL names. "inputs" is chosen because it is descriptive of the function and easy to type.)

```

```

To bundle the ports together, we can concatenate, or link, the ports together using the & operator. The VHDL statement is

```	inputs <= a & b & c;
```
This has the effect of mapping the input ports to the internal signal in the correct order.
```
Input Ports Mapped to a 3-Bit Signal "inputs"

inputs(2) 	inputs(1)	inputs(0)
-----------------------------------------
a		   b 		   c

```
We can also achieve the same thing by individually mapping the input ports to the internal signal one bit at a time,
using the separate statements, as follows:
```
inputs(2) <= a;
inputs(1) <= b;
inputs(0) <= c;

```
Similarly, we can get the following for the output:
```
w <= outputs(3);
x <= outputs(2);
y <= outputs(1);
z <= outputs(0);

```
```
Signal "outputs" Mapped to Output Ports

outputs(3) 	outputs(2)	outputs(1)	outputs(0)
----------------------------------------------------------
w		   x 		   y		   z

```
The complete VHDL file for the circuit in this example is given below.
Signals are declared in between the first line of the architecture body and the BEGIN statement.
Signals require a type to be assigned, but not a mode, as they are totally internal to the design.
A signal is considered as global. That means it is valid through the whole architecture body.
```
library IEEE;
use IEEE.std_logic_1164.all;

entity Ex256 is

port(
a	: in	std_logic;
b	: in	std_logic;
c	: in	std_logic;
w	: out	std_logic;
x	: out	std_logic;
y	: out	std_logic;
z	: out	std_logic
);

end Ex256;

architecture arch1 of Ex256 is
-- Declare signals
signal inputs : STD_LOGIC_VECTOR(2 downto 0);
signal outputs : STD_LOGIC_VECTOR(3 downto 0);
begin

-- Your VHDL code defining the model goes here
inputs <= a & b & c;
with inputs select
outputs <= "1000" when "000",
"0100" when "001",
"0110" when "010",
"1001" when "011",
"0110" when "100",
"0001" when "101",
"1001" when "110",
"0010" when "111",
"0000" when others;

w <= outputs(3);
x <= outputs(2);
y <= outputs(1);
z <= outputs(0);
end arch1;

```

#### Single-Bit Signal

Signals do not have to be multi-bit objects. They can be used as single-bit objects any time it is useful to connect two parts of a design internally.
Now let's examine the following logic diagram:
```

```
The corresponding Boolean expression can be written in
```	Y = ((not A) and B) or (A and (not B)) or ((not C) and D)
```
or
```	Y = (A xor B) or ((not C) and D)
```
The output of the top OR gate does not feed an output port pin and is thus entirely internal to the design. We can represent the connection between the OR gates as a signal. We can call it a_xor_b. A VHDL file that implements this circuit is as follows:
```
library IEEE;
use IEEE.std_logic_1164.all;

entity Signal_Ex258 is

port(
a       : in    std_logic;
b       : in    std_logic;
c       : in    std_logic;
d       : in    std_logic;
y       : out   std_logic;
);

end Signal_Ex258;

architecture arch1 of Signal_Ex258 is
-- Declare signal
signal a_xor_b : STD_LOGIC;
begin

-- Define signal in terms of ports a and b

a_xor_b <= ((not A) and B) or (A and (not B));

-- Combine signal with ports c and d

y <= a_xor_b or ((not C) and D);

end arch1;

```

#### Combining Single- and Multi-Bit Signals

From the above two sub-sections, we have learned how to combine several ports into a signal and how to create internal signals of single-bit width. It is also possible in VHDL to concatenate multiple and single-bit objects into one multi-bit object.

For example, suppose we have a 3-bit port defined by

```	d: IN STD_LOGIC_VECTOR(2 downto 0);
```
and a single-bit port defined by
```	enable: IN STD_LOGIC;
```
We can combine the ports into signal by
first, define the signal:
```	signal inputs: STD_LOGIC_VECTOR(3 downto 0);
```

second, concatenate the ports into the signal:
```	inputs <= enable & d;
```
The above is equivalent to the following four statements:
```	inputs(3) <= enable;
inputs(2) <= d(2);
inputs(1) <= d(1);
inputs(0) <= d(0);
```
Another way to write the following statements would be:
```	inputs(3) <= enable;
inputs(2 downto 0) <= d;
```
Note: VHDL assigns elements of a vector from left-to-right. Therefore, d is assigned to inputs in the correct order.