0% found this document useful (0 votes)
97 views30 pages

Intro Vhdl1

This document provides an introduction to VHDL including code structure, concurrent and sequential code, data types, verification, and implementation. It outlines key VHDL concepts like libraries, entities, architectures, components, ports, signals, variables, processes, and data types. Examples are provided to illustrate concepts like full adders, multiplexers, generate statements, and clocked sequential logic. The document compares VHDL's inherent concurrency to hardware and discusses code styles for processes, signals, and variables.

Uploaded by

pandaros000
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
97 views30 pages

Intro Vhdl1

This document provides an introduction to VHDL including code structure, concurrent and sequential code, data types, verification, and implementation. It outlines key VHDL concepts like libraries, entities, architectures, components, ports, signals, variables, processes, and data types. Examples are provided to illustrate concepts like full adders, multiplexers, generate statements, and clocked sequential logic. The document compares VHDL's inherent concurrency to hardware and discusses code styles for processes, signals, and variables.

Uploaded by

pandaros000
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

An Introduction to VHDL

Outline
1. Introduction
2. Code Structure
3. Concurrent Code
4. Sequential Code
5. Data Types-Attributes
6. Verification & Implementation
Electronic Design Automation
High level VHDL code, Register Transfer
Level (RTL)
Low level VHDL code, Gate Level Netlist
Cell Layouts, Interconnections in GDSII
format(ASIC), bitstream (FPGA)
Example Full Adder
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 full_adder;
architecture Behavioral of full_adder is
begin
s <= a xor b xor cin;
cout <= (a and b) or (a and cin) or (b and cin);
end Behavioral;
Library declarations:
Commonly used VHDL types,
codes etc.
Entity:
Input and Output ports of the
circuit are defined
Architecture:
Functionality of the circuit is
defined(coded).
Digital Circuit
Combinational
Logic
Storage
Elements
Inputs Outputs
clock
Concurrent Code
architecture Behavioral of mycircuit is
begin
cs1: statement-1
cs2: statement-2

Sub_module1:module1 port map();


Sub_module2:module1 port map();

Proc1: process
Proc2: process
end Behavioral;
VHDL is inherently
concurrent. Inside the
architecture body, there can
be multiple:
1- concurrent statements
2- sub-module instantiation
3- process blocks
Concurrent Statements- WHEN
entity mux is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
c : in STD_LOGIC;
d : in STD_LOGIC;
s : in STD_LOGIC_VECTOR (1 downto 0);
y : out STD_LOGIC);
end mux;
architecture Behavioral of mux is
begin
y <= a when s="00" else
b when s="01" else
c when s="10" else
d;
end Behavioral;
This is a 4-to-1 multiplexor
example.
Concurrent Statements- WITH/SELECT
entity mux is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
c : in STD_LOGIC;
d : in STD_LOGIC;
s : in STD_LOGIC_VECTOR (1 downto 0);
y : out STD_LOGIC);
end mux;
architecture with_sel of mux is
begin
with s select
y <= a when "00",
b when "01",
c when "10",
d when others;
end with_sel;
This is a 4-to-1 multiplexor
example.
Concurrent Code- GENERATE
signal a:std_logic_vector(15 downto 0);
signal b:std_logic_vector(7 downto 0);

my_generate:for i in 0 to 7 generate
b(i)<=a(i) and a(i+8);
end generate;
FOR/GENERATE allows
several instances of a
hardware to be created

b(0)<=a(0) and a(8);


b(1)<=a(1) and a(9);
b(2)<=a(2) and a(10);
b(3)<=a(3) and a(11);
b(4)<=a(4) and a(12);
b(5)<=a(5) and a(13);
b(6)<=a(6) and a(14);
b(7)<=a(7) and a(15);
=
adder_4
Sub-Module Instantiation
FULL
ADDER
FULL
ADDER
FULL
ADDER
a(0)
b(0)
a(1)
b(1)
a(2)
b(2)
s(0)
s(1)
s(2)
architecture Behavioral of adder_4 is
component full_adder is
Port ( a,b,cin : in STD_LOGIC;
s,cout : out STD_LOGIC );
end component;
signal carryout:std_logic_vector(2 downto 0);
begin
bit0:full_adder
port map( a=>a(0),b=>b(0),cin=>'0',s=>s(0),cout=>carryout(0));
bit1:full_adder
port map( a=>a(1),b=>b(1),cin=> carryout(0) ,s=>s(1),cout=>carryout(1));
bit2:full_adder
port map( a=>a(2),b=>b(2),cin=> carryout(1) ,s=>s(2),cout=>carryout(2));
bit3:full_adder
port map( a=>a(3),b=>b(3),cin=> carryout(2) ,s=>s(3),cout=>open);
end Behavioral;
FULL
ADDER
a(3)
b(3)
s(3)
Sequential Code
Sequential codes in VHDL are programmed in:
1- Processes
2- Functions
3- Procedures
Example 16-Bit clocked adder
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
entity clocked_adder is
Port ( clk,rst : in STD_LOGIC;
a,b : in STD_LOGIC_VECTOR (15 downto 0);
c : out STD_LOGIC_VECTOR (15 downto 0));
end clocked_adder;
architecture Behavioral of clocked_adder is
begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
c<=a+b;
end if;
end process;
end Behavioral;
Commonly used libraries
Process:
c is assigned to zero when
rst=1. At the rising edge of
clk the sum of a and b is
assigned to c.
Snthesis & Simulation of 16-Bit clocked
Adder
Process Block
architecture Behavioral of clocked_adder is
Begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
c<=a+b;
end if;
end process;
end Behavioral;
Process sensitivity list: the code in the
process body is executed when one of
the signals in the list change
Process WAIT UNTIL Statement
process(clk)
begin
if rising_edge(clk) then
if rst='1' then
c<=x"0000";
else
c<=a+b;
end if;
end if;
end process;
process
begin
wait until rising_edge(clk);
if rst='1' then
c<=x"0000";
else
c<=a+b;
end if;
end process;
=
wait until must be the first statement in the process, multiple signals can not be used
with wait until
Process WAIT FOR
clk_process :process
begin
clk <= '0';
wait for 5ns;
clk <= '1';
wait for 5ns;
end process;
wait for is used for only simulations, it
causes waiting for a specified amount of
time.
It is useless (and forbidden) for synthesis.
Since there is no such hardware structure.
Process FOR LOOP
process(clk,rst)
begin
if rst='1' then
dout<=x"0000";
elsif rising_edge(clk) then
for i in 0 to 15 loop
dout(i)<=din(15-i);
end loop;
end if;
end process;
for loop eases code writing.
process(clk,rst)
begin
if rst='1' then
dout<=x"0000";
elsif rising_edge(clk) then
dout(0)<=din(15);
dout(1)<=din(14);
dout(2)<=din(13);

end if;
end process;
=
Process clock signal
process(clk)
begin
if rising_edge(clk) then
counter<=counter+'1';
elsif falling_edge(clk) then
counter<=counter+'1';
end if;
end process;
Bad Code
process(clk)
begin
counter<=counter+'1';
end process;
Valid Code
The counter increments at every clock
edge, rising and falling.
Signals
entity pipelined_adder is
Port ( clk,rst : in STD_LOGIC;
a,b : in STD_LOGIC_VECTOR (15 downto 0);
c : out STD_LOGIC_VECTOR (15 downto 0));
end pipelined_adder;
architecture Behavioral of pipelined_adder is
signal a_d1:STD_LOGIC_VECTOR (15 downto 0):=x"0000";
signal b_d1:STD_LOGIC_VECTOR (15 downto 0):=x"0000";
begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
a_d1<=a;
b_d1<=b;
c<=a_d1+b_d1;
end if;
end process;
end Behavioral;
Signals are declared in btw
arcitecture and begin statements
Signals are used for:
Internal processing
Inter-process communication
Instantiation of sub-circuits
Order of signal assignments
begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
a_d1<=a;
b_d1<=b;
c<=a_d1+b_d1;
end if;
end process;
end Behavioral;
begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
c<=a_d1+b_d1;
b_d1<=b;
a_d1<=a;
end if;
end process;
end Behavioral;
=
The order of the signal assignments is not important, since all signals are assigned at the
same time(at the rising edge of clk)
Variables
architecture Behavioral of sat_adder is
begin
process(clk,rst)
variable tmp_c:STD_LOGIC_VECTOR (15 downto 0);
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
tmp_c:=a+b;
if tmp_c > conv_std_logic_vector(1000,16) then
c<= conv_std_logic_vector(1000,16) ;
else
c<=tmp_c;
end if;
end if;
end process;
end Behavioral;
Variables are declared in processes
before the begin statement.
Variables are used for sequential
computations.
tmp_c is assigned to sum of a and b,
then this value is saturated if it is
greater than 1000.
Order of variable assignments
process(clk,rst)
variable tmp_c:STD_LOGIC_VECTOR (15 downto
0);
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
tmp_c:=a+b;
if tmp_c > conv_std_logic_vector(1000,16) then
c<= conv_std_logic_vector(1000,16) ;
else
c<=tmp_c;
end if;
end if;
process(clk,rst)
variable tmp_c:STD_LOGIC_VECTOR (15 downto
0);
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
if tmp_c > conv_std_logic_vector(1000,16) then
c<= conv_std_logic_vector(1000,16) ;
else
c<=tmp_c;
end if;
tmp_c:=a+b;
end if;

The order of the variable assignments is important, variables are similar to the variables
of programming languages(C, C++, pascal etc)
Data Types
Data Types apply to ports, signals and variables.
signal a_int : integer range 0 to 2**16-1;
-- An integer in range 0 to 65535
signal a_signed : signed(15 downto 0);
-- 16 bit signed signal
signal a_unsigned: unsigned(15 downto 0);
-- 16 bit unsigned signal
signal a_slv : std_logic_vector(15 downto 0);
-- 16 bit logic vector
Operators
Logical Operators:
NOT
AND
OR
NAND
NOR
XOR
XNOR
Arithmetic Operators:
+ :Addition
- :Subtraction
* :Multiplication
/ :Divison
** :Exponention
MOD :Modulus
REM :Remainder
ABS :Absolute value
Comparison Operators:
= :Equal
/= :Not Equal
< :Less Than
> :Greater Than
<= :Less than or equal
>= :Greater than or equal
Attributes
Data Attributes:
Signal D:std_logic_vector(7 downto 0);
DLOW returns 0
DHIGH returns 7
DLength returns 8
Signal Attributes:
sEVENT returns true if an event occurs on s
sACTIVE returns true if s=1
Generic
entity gen_adder is
generic( data_length:integer:=8 );
Port ( clk,rst : in STD_LOGIC;
a,b : in STD_LOGIC_VECTOR (data_length-1 downto 0);
c : out STD_LOGIC_VECTOR (data_length-1 downto 0));
end gen_adder;
architecture Behavioral of gen_adder is
signal a_d1:STD_LOGIC_VECTOR (data_length-1 downto 0);
signal b_d1:STD_LOGIC_VECTOR (data_length-1 downto 0) ;
begin
process(clk,rst)
begin
if rst='1' then
c<=x"0000";
elsif rising_edge(clk) then
a_d1<=a;
b_d1<=b;
c<=a_d1+b_d1;
end if;
end process;
end Behavioral;
Generics are defined in entitys.
Generics allow generic circuits to
be designed. In this example the
width of the adder is adjustable
through data_length.
Test_adder
Verification
adder
process
Create a vhdl test bench file
Instantiate the circuit to be verified as a sub module in the test bench file
Create stimulus signals for the input signals.
Run a vhdl simulation and observe the output signals.
Timing
1-Period: Maximum clock frequency that the design can work
2-input-to-clock
3-clock-to-output
Example: Simple ALU
process(clk,rst)
variable tmp_mul:std_logic_vector(31 downto 0);
begin
if rst='1' then
c<=(others=>'0');
elsif rising_edge(clk) then
a_d1<=a;
b_d1<=b;
if instruction="000" then
c<=a_d1 and b_d1;
elsif instruction="001" then
c<=a_d1 or b_d1;
elsif instruction="010" then
c<=a_d1 + b_d1;
elsif instruction="011" then
c<=a_d1 -b_d1;
elsif instruction="100" then
c<=b_d1 -a_d1;
elsif instruction="101" then
tmp_mul:=a_d1*b_d1;
c<=tmp_mul(31 downto 16);
end if;
end if;
end process;
simple_alu
a
b
c
instruction
Simple ALU on Xilinx Virtex4 and 90nm
ASIC
239 MHz Clock
1 DSPs
48 FFs
86 LUTs
831MHz Clock
12944 u
2
114x114
Area

You might also like