---
description: In this lab, we are going to talk about how to use components, which allows you to create and use/reuse your old component and to organize your design into multiple components, then we will talk about test benches, which allows you to easily verify and test your VHDL code.
---
<h1 style='border: none'><center>Hardware Description Languages Lab 3</center></h1>
<h2 style='border: none'><center>Using Components & Test Benches</center></h2>
<h5><center>The Islamic University of Gaza<br>Engineering Faculty<br>Department of Computer Engineering</center></h5>
<h6>Author: Mohammed Nafiz ALMadhoun<span style="float:right">2021/02/26</span></h6>
---
<p style='text-align:justify'>
In this lab, we are going to talk about how to use components, which allows you to create and use/reuse your old component and to organize your design into multiple components, then we will talk about test benches, which allows you to easily verify and test your VHDL code.
</p>
## Using components
The first thing we will talk about is ssignals, which are wires, we will use these s to connect components together, and more!
### Signals
To create a signal, you will need to write
```vhdl=
signal name : type;
```
for example:
```vhdl=
architecture test of test is
signal not_a : std_logic;
begin
not_a = not a;
-- anything!
end architecture;
```
Notice that we've created a signal called `not_a` and its type is `std_logic`.
### Declaring components
To use an entity as a component, you should declare this component in the architecture that will use that entity, for example:
```vhdl=
architecture full_adder of full_adder is
component half_adder port(
a, b: in std_logic;
s, c: out std_logic
);
end component;
begin
```
### Instacting a components
Now after declaring the components you want to use, you can now create instances of this component and map its ports to your signals, for example:
```vhdl=
library ieee;
use ieee.std_logic_1164.all;
entity full_adder is port(
a, b, cin: in std_logic;
s, cout : out std_logic
);
end entity;
architecture full_adder of full_adder is
component half_adder port(
a, b: in std_logic;
s, c: out std_logic
);
end component;
signal s1, c1, s2, c2: std_logic;
begin
ha1: component half_adder port map (a, b, s1, c1);
ha2: component half_adder port map (a => s1, b => cin, s => s2, c => c2);
s <= s2;
cout <= c1 or c2;
end architecture;
```
Notice in lines `19`,`20`, we created two instances of the `half_adder` component.
We named the first instance `ha1`, and we mapped it to our signals `a`, `b`, `s1`, `c1`, which will be mapped in the component declaration order.
In line `20`, we created `ha2` and mapped each signals with its name.
## Test Benches
A Test bench is just a regular VHDL file, which will use your entities and assert expected results, to write a test bench you will create a new VHDL file, then change its type to `VHDL Test Bench File`.
<center>

Figure 1: VHDL File Proparites.
</center>
Then you should edit your simulation settings and choose `Compile test bench`.
<center>

Figure 2: Simulation Settings.
</center>
Then click on `Test Benches`, and add your test bench to the list of test benches.
<center>

Figure 3: Adding a file as a test bench.
</center>
### Test Process
To write a test code, you will create an empty entity (doesn't have any inputs or outputs), then you will create an architecture for that entity.
The architecture of a test bench will usually contain processes, the processes behave like a sequential code, so don't expect a test bench to be synthesised.
And don't forget that you will use the tested entity as a component, so you should declare it and create an instance of it inside the architecture, for example:
```vhdl=
library ieee;
use ieee.std_logic_1164.all;
entity ha_testbench is
end entity;
architecture ha_testbench of ha_testbench is
component half_adder port(
a, b: in std_logic;
s, c: out std_logic
);
end component;
signal a, b, s, c: std_logic;
begin
uut: half_adder port map (a, b, s, c);
...
```
Notice that we have signals declared, so we could change the inputs and read the outputs of the component.
Now, we will create a process, which contains some signal assessment, waiting statements, and assertion statements, notice that this is just a simple test bench.
```vhdl
begin
uut: half_adder port map (a, b, s, c);
process begin
a <= '0';
b <= '0';
wait for 100 ns;
assert s = '0' and c = '0' report "Case 0,0 fail!";
a <= '1';
b <= '0';
wait for 100 ns;
assert s = '1' and c = '0';
a <= '0';
b <= '1';
wait for 100 ns;
assert s = '1' and c = '0';
a <= '1';
b <= '1';
wait for 100 ns;
assert s = '0' and c = '1';
wait; -- just waiting forever!
end process;
end architecture;
```
Now after running the simulator, you will notice that the signals will show up in the wave view, and if there is any fail assertion it will be reported in the console.
<center>

Figure 4: Wave view
</center>
## Lab Tasks
### Task 1: 4 Bit Adder
In this task, you should create 3 entites, `half_adder`, `full_adder`, and `adder_4bit`.
As you might expect, the `adder_4bit`, should use the `full_adder`, and it should have 3 inputs and 2 outputs:
- `a` 4-bit input
- `b` 4-bit input
- `c` 1-bit input
- `s` 4-bit output
- `cout` 1-bit output
### Task 2: Create a test bench for the full adder
In this task, you should create a test bench for your full adder, and it should cover all possible values.
###### tags: `VHDL` `IUG`
<center>End Of Lab 3</center>