VHDL language Tutorial
This VHDL language tutorial covers VHDL concepts which include entity,architecture, process,ports of mode,object types,VHDL data types,operators and example VHDL implementation.
VHDL stands for VHSIC Hardware Description language. VHSIC is further abbreviated as Very High Speed Integrated Circuits. VHDL is a programming language which is used for describing the behavior of digital circuits ranging from simple logic gates (few gate counts) to complex logic chips consisting of several million gates. It can be used for both designs as well as for writing Test benches.
Every VHDL design unit consists of an Entity and Architecture declaration, Apart from having configurations, package declarations and package body.
An Entity defines the components input and output port signals (interface). It gives the Black box view of the design. The mode of I/O ports can be in, out, inout or buffer depending upon the design. Every Entity declaration must e accompanied by at least one corresponding Architecture declaration. The entity definition also defines generic parameters if they are used in the module.
The Architecture unit of the design describes the behavior of the design(function of the component). There are mainly 3 types of description style, behavioral, dataflow and structural description.
1.Behavioral description style consists of several process statements. Behavioral description is usually written in sequential, procedural method.
2. Data flow is generally used for describing simple logic blocks, it consists of concurrent statements. All the data paths and control signals are shown in the data flow method.
3. Structural method various components are instantiated and there interconnected. Basically it is used for Interconnecting of components Each method can be used depending on the need of the design.
The Behavioral style of VHDL is very similar to the C language. It uses if-else, case, while and many other similar constructs as in C and the statements inside a process block are executed sequentially as in C.EXAMPLE Entity:
The primary purpose of the Entity is to declare signals in the component s interface. Entity gives the black box views of the module, i.e. the I/O ports as can be seen from fig1.
entity half_adder IS
port ( din1, din2 : in std_logic ; -- Inputs
sum, carry : out std_logic ) ; --outputs
end half_adder ;
Architecture defines the functionality of the circuit with respect to ports.
// data flow method
architecture hf_arch_dataflow of half_adder is
Sum <= din1 xor din2;
Carry <= din and din2;
Now let's use this half_adder component to construct a full_adder. Here we make use of structural coding style figure below shows full adder constructed from two half adder components.
entity full_adder is
port (din1, din2, carry_in : in std_logic ; -- inputs
Sum_out,carry_out : out std_logic) ; -- outputs
architecture full_adder_Arch of full_adder is
port ( din1, din2 : in std_logic; -- Inputs
sum, carry : out std_logic) ; --outputs
signal temp1,temp2,temp3: std_logic; // signal declaration for storing intermediate value
--interconnection of components i.e port mapping
H1: half_adder port map(din1,din2,temp1,temp3);
H2: half_adder port map(temp1,carry_in,sum_out,temp2)
O1:or_gate port map(temp2,temp3,carry_out); --behavioral code for OR gate is described --later in the section
The process block is the core of the behavioral style. Statements within a process block are executed in a sequential manner. Behavioral models are made up exclusively of process blocks. The variables which are passed with a process block is called sensitivity list. The statements enclosed between 'begin' and 'end' keywords are sequentially executed. The all other process blocks in the design run Concurrently with respect to each other.
entity or_gate is
port (in1,in2: in std_logic;
d_out: out std_logic);
architecture behv of or_gates is
process(in1,in2) -process statement
-- compare to truth table
if ((in1='0') and (in2='0')) then
d_out <= '0';
d_out <= '1';
Ports of Mode
The Port mode of the interface describes the direction in which data travels.
IN: In port is unidirectional port. It can be read but cannot be updated within the module.
OUT: Out port can be updated but not read within the module, it carries information outside the module.
INOUT: The inout mode is used for bidirectional mode.
BUFFER: Buffer mode is used for outputs whose values are also required inside the entity
Signals: Signals are used as interconnects between components and also to store temporary values. Signals can be declared internal to architecture and are not available external to the architecture.
Constant: A constant is an object whose value may never be changed during the simulation process.
Variable: Variable is an object whose value may be changed after creation.
counter: process (x,y)
variable counter : integer := -1;
counter:= counter +1;
VHDL data types
Boolean, ("TRUE', "FALSE")
Bit type ("0","1")
Integer types (375,284)
Float types (1.057,0.45)
EXAMPLE VHDL Implementation
Let us implement a simple scrambler/randomizer which is used in IEEE 802.16d standard. as per the circuit shown below.
SCARMBLER VHDL CODE
entity Randomizer is
port(clk : in std_logic;
reset : in std_logic;
load : in std_logic;
seed : in std_logic_vector(14 downto 0);
data_input : in std_logic;
valid_input : in std_logic;
data_output : out std_logic;
valid_output : out std_logic
architecture behaviour of Randomizer is
Signal shift_reg : std_logic_vector(14 downto 0);
signal valid_input1 : std_logic;
signal data_input1 : std_logic;
if reset = '1' then
shift_reg <= (others => '0');
valid_input1 <= '0';
data_input1 <= '0';
valid_output <= '0';
data_output <= '0';
elsif clk'event and clk = '1' then
if load='1' then
shift_reg(0) <= seed(14);
shift_reg(1) <= seed(13);
shift_reg(2) <= seed(12);
shift_reg(3) <= seed(11);
shift_reg(4) <= seed(10);
shift_reg(5) <= seed(9);
shift_reg(6) <= seed(8);
shift_reg(7) <= seed(7);
shift_reg(8) <= seed(6);
shift_reg(9) <= seed(5);
shift_reg(10) <= seed(4);
shift_reg(11) <= seed(3);
shift_reg(12) <= seed(2);
shift_reg(13) <= seed(1);
shift_reg(14) <= seed(0);
elsif valid_input='1' then
shift_reg(14) <= shift_reg(13);
shift_reg(13) <= shift_reg(12);
shift_reg(12) <= shift_reg(11);
shift_reg(11) <= shift_reg(10);
shift_reg(10) <= shift_reg(9);
shift_reg(9) <= shift_reg(8);
shift_reg(8) <= shift_reg(7);
shift_reg(7) <= shift_reg(6);
shift_reg(6) <= shift_reg(5);
shift_reg(5) <= shift_reg(4);
shift_reg(4) <= shift_reg(3);
shift_reg(3) <= shift_reg(2);
shift_reg(2) <= shift_reg(1);
shift_reg(1) <= shift_reg(0);
shift_reg(0) <= shift_reg(13) xor shift_reg(14);
if valid_input1 = '1' then
data_output <= shift_reg(0) xor data_input1;
valid_output <= '1';
data_output <= '0';
valid_output <= '0';
USEFUL LINKS to VHDL CODES
Refer following as well as links mentioned on left side panel for useful VHDL codes.
Read Write RAM
4 bit binary counter
2bit Parallel to serial