===== VHDL Entity and Architecture =====
VHDL splits interface (entity) and implementation (architecture). The interface of a circuit is defined in the entity. The implementation is defined in the architecture.
library ieee;
use ieee.std_logic_1164.all;
entity and_gate is
port(
a_i : in std_ulogic;
b_i : in std_ulogic;
y_o : out std_ulogic);
end and_gate;
architecture rtl of and_gate is
begin
y_o <= a_i and b_i;
end architecture rtl;
Listing 1: Entity and Architecture for and_gate
The code in listing 1 describes the full code for a circuit called "and_gate". The entity with the name "and_gate" describes two input ports "a_i" and "b_i" and an output port "y_o". All ports here have the type "std_ulogic" which defines that those ports basically can have a logic 1 or 0 value. (Some other values for simulation purposes are left for now). An entity can have an arbitrary number of inputs and outputs. Each input and output can have a different type.
Figure 1: Block and_gate with a_i and b_i as inputs and y_o as output
Figure 1 shows the block "and_gate" with the inputs and outputs. This represents the entity. The entity code does not imply any functionality. The name "and_gate" is an identifier, i.e. it does not imply that this block actually works as an and gate.
Figure 2: Architecture of "and_gate" which just contains and AND gate.
The architecture with the name "rtl" describes the implementation. Here it is a signal assignment with a boolean expression using the and function. This makes this circuit behave like an AND gate. Figure 2 shows the schematic with the AND gate. As the AND function can be described in one line of code, this block "and_gate" does not make too much sense, but it explains the idea of entity and architecture.
===== Instantiation and hierarchical design =====
Circuits are very often composed of subcircuits. And the subcircuits can themself be composed of subcircuits. This is called hierarchical design. The following example shows a block "mux".
Figure 3: "mux" block with a_i, b_i and s_i inputs and y_o output
Figure 3 shows the block interface of a circuit "mux" which has three inputs a_i, b_i and s_i and an output y_o.
This "mux" is composed of two instances of "and_gate", an "or_gate" and an "inv_gate".
Assume that we have defined not only the "and_gate" but also an "or_gate" and an "inv_gate". The mux circuit shall be composed of the xxx_gate subcircuits as shown in figure 4.
Figure 4: Schematic of "mux"
Figure 4 shows a schematic of a multiplexer using and_gate, or_gate and the inv_gate. The corresponding VHDL code is shown in listing 2.
library ieee;
use ieee.std_logic_1164.all;
entity mux is
port (
a_i : in std_ulogic;
b_i : in std_ulogic;
s_i : in std_ulogic;
y_o : out std_ulogic);
end mux;
architecture structure of mux is
signal s1 : std_ulogic;
signal s2 : std_ulogic;
signal s3 : std_ulogic;
begin
inv_gate_i0 : work.inv_gate
port map(
a_i => s_i,
y_o => s1);
and_gate_i0 : work.and_gate
port map(
a_i => s1,
b_i => a_i,
y_o => s2);
and_gate_i1 : work.and_gate
port map(
a_i => s_i,
b_i => b_i,
y_o => s3);
or_gate_i0 : work.or_gate
port map(
a_i => s2,
b_i => s3,
y_o => y_o);
end architecture structure;
Listing 2: Structural VHDL code that instantiates and_gate, or_gate and inv_gate
The instantiation code introduces the name of the instance. In this example the names of the "and_gate" instances are "and_gate_i0" and "and_gate_i1". The instantiation code instantiates "work.and_gate" which means that there is a component "and_gate" assumed to be in library "work". The "and_gate" component is created in the work library when the corresponding vhdl code that defines the "and_gate" is compiled.
===== Signals =====
Note the signals s1, s2 and s3 in listing 2 which work as internal nets in "mux". But it is also possible to assign the value of an input port to a signal. The value of a signal can also be assign to an output port.
Signals are defined between "architecture" and the following "begin".
===== Multiplexer Code - the real thing =====
The previous code example in listing 2 and listing 1 show the hierarchical design of a multiplexer. Nobody would ever do it like that - it only serves as an example for hierarchical design which is used when the subcircuits have some complexity. The multiplexer function as described in listing 2 can be written in one line of code in VHDL. Listing 3 shows the full code of "mux" with entity and architecture. The function inside the architecture is only one line of code.
library ieee;
use ieee.std_logic_1164.all;
entity mux is
port (
a_i : in std_ulogic;
b_i : in std_ulogic;
s_i : in std_ulogic;
y_o : out std_ulogic);
end mux;
architecture rtl of mux is
begin
y_o <= a_i when s_i = '0' else b_i;
end architecture;
Listing 3: Multiplexer Code in one line