Unit 1 HDL Design
Unit 1 HDL Design
Unit 1 HDL Design
Introduction to VHDL
What is VHDL?
B
F
D
Entity
entity AOI is
port ( A , B , C , D : in STD_LOGIC ;
F : out STD_LOGIC ) ;
end AOI ;
architecture V1 of AOI is
begin
F <= not ( ( A and
B ) or ( c and D ) )
;
end V1 ;
Entity Declaration
B O
F
C
CD
D
architecture V2 of AOI is
signals AB, CD, O : STD_LOGIC ;
begin
AB <= A and B after 2 NS;
CD <= C and D after 2
NS;
O <= AB or CD after 2 NS;
F <= not O after 1 NS;
end V2 ;
Operator Used in VHDL
Concurrent Statements
• VHDL statements are grouped into sequential and
concurrent statements. Concurrent statements are
used in data flow and structural descriptions.
Sequential statements are used in bahavioral
descriptions
Example
…. Expression N;
Example
Architecture Beh of My_nand is
Begin
C<=‘0’when a<=‘1’and b<=‘1’ else
‘1’;
- Example write a VHDL program of 4:1 Mux by using when statements
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mux is
Port (I0,I1,I2,I3 : in std_logic;
sel:std_logic_vector(1 downto 0);
z: out std_logic);
end mux;
architecture Behavioral of mux is
begin
z<=I0 when sel=“00” else
I1 when sel="01“ else
I2 when sel= "10“ else
I3 ;
end Behavioral;
Selective signal assignment( with-select statement)
Syntax
With expression select
Target<=expression1 when choice1,
expression2 when choice2,
expression3 when choice3,
…
Expression N when others,
- All possible choices should be enumerated
- Compared to the when statement, in the with statement choice is limited
to the choices provided by the with expression whereas for the when
statement, each choice can be a separate expression
- With statement does not have any priority.
- Example write a VHDL program of 4:1 Mux by using With select
statements
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mux is
Port (I0,I1,I2,I3 : in std_logic;
sel:std_logic_vector(1 downto 0);
z: out std_logic);
end mux;
architecture Behavioral of mux is
begin
with sel select z<=I0 when "00",
I1 when "01",
I2 when "10",
I3 when"11",
'0' when others;
end Behavioral;
Concurrent Statements
A concurrent signal assignment is triggered by an
event on a signal. An event is a change in value.
A
B 2 NS
AB
AB <= A and B after 2 NS;
CD <= C and D after 2 NS;
O <= AB or CD after 2 NS;
F <= not O after 1 NS;
AB
F
Process Statement
• In architecture all process are concurrent.
• In VHDL, Process statements contains only sequential
statement.
entity MUX2 is
port (SEL, A, B: in STD_LOGIC;
F: out STD_LOGIC);
end MUX2;
SEL
A
F
SELB
B
architecture STRUCTURE of MUX2 is
component INV
port (A: in STD_LOGIC;
F: out STD_LOGIC);
end component;
component AOI
port (A, B, C, D: in STD_LOGIC;
F: out STD_LOGIC);
end component;
signal SELB: STD_LOGIC;
begin
G1: INV port map(SEL,
SELB);
G2: AOI port map(SEL, A, SELB, B, F);
end STRUCTURE;
Variables
Previously we have looked at signals as
electrical connections or “pieces of wires”.
Variables can be pieces of wire too, but they can also
be more abstract.
Variables can represent wires, registers, or be used to
store intermediate values in abstract calculations.
variable V: STD_LOGIC;
variable V: STD_LOGIC;
process (A, B, C)
variable V: Std_logic; [ V = ’U’ ]
begin
V := A nand B; [ V = ’1’ ]
V := V nor C; [ V = ’0’ ]
F <= not V;
end process;
process
(F) begin
... A variable can be used ONLY inside the
end process. So, if we want a value passed
process; between processes, we MUST use a signal.
Structural Description
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity COMP4 is
port ( A, B : in STD_LOGIC_VECTOR ( 3 downto 0);
F : out STD_LOGIC) ;
end COMP4;
use WORK.GATESPKG.all ;
architecture STRUCT of COMP4 is
signal x : STD_LOGIC_VEXTOR ( 0 to 3 );
begin
u0: xnor2 port map (a(0) , b(0) , x(0)) ;
u1: xnor2 port map (a(1) , b(1) , x(1)) ;
u2: xnor2 port map (a(2) , b(2) , x(2)) ;
u3: xnor2 port map (a(3) , b(3) , x(3)) ;
u4: and4 port map (x(0) , x(1) , x(2) , x(3) , F) ;
end STRUCT;
Process Statement Execution
proc_x : process
begin
x <= a and b and c;
wait on a , b , c ;
end process;
if C1 = '0' then A
V := A; V
else
V := B; B
end if
In the example below the if statement does not have an else part,
but the assignment V within the if still synthesizes to a
multiplexer.
V
V
End case;
Invalid:- values 2 to 15 are not covered by choices
Ex-3
Case value is
When 0 to 10=>out_1<=‘1’;
When 5 to 15=>out_1<=‘0’;
End case;
Invalid:- Choices 5 to 10 overlap
It is possible to cover several cases in the same when branch
by separating the values with vertical bars. In this example
the branch is executed if ADDRESS is:
16, 20, 24 or 28.
case ADDRESS is
when 16 | 20 | 24 | 28 =>
A <= '1';
B <= '1';
end case;
Null Statments
Does not perform any action
Can be used to indicatn some that when some conditions are
met no action is to be performed
Example
case SEL is when "00" => F <= a;
when "01" => F <= a;
when "10" => F <= b;
when "11" => F <= c;
when others <= null;
end case;
Each branch can also include any number of sequential
statements including other nested case statements as well!!
case ADDRESS is
when 16 | 20 | 24 | 28 =>
A <= '1';
B <= '1';
end case;
The null statement means do nothing
A <= '0';
B <= '0';
case ADDRESS is
when 0 to 7 =>
A <= '1';
when 8 to 15 =>
B <= '1';
when 16 | 20 | 24 |
28 =>
A <= '1';
B <= '1';
when others =>
null;
It is possible also to cover a whole range using the case statement.
case ADDRESS is
when 0 to 7 =>
A <= '1';
when 8 to 15 =>
B <= '1';
when 16 | 20 | 24 |
28 =>
A <= '1';
B <= '1';
end case;
If ADDRESS is:
1) =9
2) =19
What will be the values of A and B?
A <= '0';
B <= '0';
case ADDRESS is
when 0 to 7 =>
A <= '1';
when 8 to 15 =>
B <= '1';
when 16 | 20 | 24 |
28 =>
A <= '1';
B <= '1';
for I in 0 to 3 loop
F(I) <= A(I) and B(3-I);
V := V xor A(I);
end loop;
for I in 0 to 3 loop
F(I) <= A(I) and B(3-I);
V := V xor A(I);
if V = 'X' then
I := 4;
end if;
end loop;
FOR Loop are synthesized by making
multiple copies of the logic synthesized
inside the loop, one copy for each possible
value of the loop parameter.
process (A, B) A(0)
F(0)
B(3)
variable V: Std_logic;
begin
A(1)
V := '0'; B(2)
F(1)
for I in 0 to 3 loop
F(I) <= A(I) and B(3-I); A(2)
V := V xor A(I); B(1)
F(2)
end loop;
G <= V; A(3)
end B(0)
F(3)
process;
0
A(0
)
A(1
) A(2) G
A(3
)
ClockGenerator_1: process
begin
for I in 1 to 1000 loop
Clock <= '0';
wait for 5 NS;
Clock <= '1';
wait for 10 NS;
end loop;
wait;
end process
ClockGenerator_
1;
ClockGenerator_2: process
begin
while NOW < 15 US loop
Clock <= '0';
wait for 5 NS;
Clock <= '1';
wait for 10 NS;
end loop;
wait;
end process
ClockGenerator_
2;
ClockGenerator_3: process
begin
loop
Clock <= '0';
wait for 5 NS;
Clock <= '1';
wait for 10
NS;
exit when NOW >= 15 US;
end loop;
wait;
end process
ClockGenerator_3;
Sequential Logic:Latches
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity LATCH is
port (ENB, D: in STD_LOGIC;
Q: out STD_LOGIC);
end;
architecture BEHAVIOUR of
LATCH
is
begin
proce
ss
(EN
B,
D)
begin
process (ENB, D)
begin
if ENB = '1' then
Q <= D;
end if;
end process;
process (Clock)
begin
Q0 <= D0;
Q1 <= D1;
end if;
end process;
Each signal has a signal attribute S’EVENT, which has a boolean value True
or False.
S’Evant changes during any delta in which there is an event on the
signal (i.e. signal changes value).
process
begin
...
S <=
'1';
wait for 10 NS;
S <= '1';
wait for 10 NS;
S <= '0';
wait for 10 NS;
S <= '0';
...
Rising_edge and Falling_edge Functions
Testing for a clock edge is such a common requirement that the package
std_logic_1164 includes standard functions Rising_edge and
Falling_edge .
The functions are given a signal of type STD_LOGIC and return a value
which is either True or False.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
...
process (Clock)
begin
if RISING_EDGE(Clock) then
Q <= D;
end if;
end process;
process (Clock)
begin
if Clock'EVENT and Clock = '1' then
Q <= D;
end if;
end process;
process (Clock)
begin
if RISING_EDGE(Clock) then
Q <= D;
end if;
end process;
...
signal Count :
STD_LOGIC_VECTOR(7 downto 0);
begin
process (Clock, Reset)
begin Loa
Dat Rese
if Reset = '0' then a d
t
Count <= "00000000"; Count
elsif RISING_EDGE(Clock) then
if Load = '1' then '1'
Count <= Data;
else + Cloc
k
>
Another_Flipflop: process
begin Rese
wait until Clock = '1'; t
if Reset = '1' then Q
Q <= '0'; Dat
else a
Q <= D;
end if;
end process; Cloc >
k
Another_Flipflop: process
begin
wait until RISING_EDGE(Clock);
F<= A & B;
• Concatenation can also be used to
concatenate arrays with single bits, or even
bits with bits.
F(3) = A
F(2) = B
F(1) = C
F(0) = unchanged
• Shift and rotate operations can be
performed in one line by combining
concatenation with slice names.
“0111”