Download as pdf or txt
Download as pdf or txt
You are on page 1of 37

ENGINEERING DEPARTMENT, JADAVPUR UNIVERSITY

Very High Speed


Integrated Circuit
Hardware Description
Language (VHDL)
The Programming Language For Configurable
Hardware
Biswajit Bhattacharyya

The content is the short summary of the topic as mentioned. Reader is advised to study further
for acquiring an in-depth knowledge.
biswajitb

VHDL is the abbreviation of VHSIC Hardware Description Language, where VHSIC


stands for Very High Speed Integrated Circuit.

VHDL, as a programming language, consists of two types of declarations:

 Entity declaration

 Architecture declaration

■ Entity declaration:

Entity is a black box representing the hardware terminals (ports) only. In entity
declaration, following things are declared:
1) Name of the black box, called Entity name.
2) Signal labels, i.e., name of the signal-terminals (ports)
3) Signal types (e.g., whether a signal is in the form of bit etc.)
4) Signal direction (e.g., in, out etc.)

The figure shows an entity:

Here x, y and z are labels for signals. The labels are inscribed within the entity as black
box.

■ Architecture declaration:

Architecture represents functionality of entity in terms of relation among i/o signals. Thus
architecture is the circuit realization of functions.

2
biswajitb

#1. Example: Develop an AND gate in VHDL.

Solution:

Name of the entity for the present application is arbitrarily given as and2. In the present
case, this is the entity name.
The relation among x, y and z is defined within architecture declaration.

Here, exm1 is the name of the architecture wherein an AND function, as an example, is
implemented.

Evidently, there may have numerous relations among x, y and z, and a number of
architectures exm1, exm2, exm3 etc. (architecture name may be anything else) may be
defined against a single entity. Thus, all these architectures will be a part of this particular
entity.

Here is the complete source code:

library ieee;
use ieee.std_logic_1164.all;

entity and21 is
port (x,y: in BIT; z:out BIT);
end entity and21;

architecture exm1 of and21 is


begin
z <= x and y;
end architecture exm1;

3
biswajitb

Note:

1) The first two lines are mandatory, significance of which will be explained later.

2) Underlined words are keywords.

3) For the entity and2 (user-given name), there may be multiple architectures like
exm1, exm2, exm3 etc., or any other name given by user.

4) ‘and’ is the key word representing standard logical function AND.

5) The keyword ‘port’ specifies the signal-terminals, and type as well as the
direction of the signals.

6) ‘<=’ is the assignment operator indicating that the signal, generated as a result
of AND operation between x and y, is assigned (placed) to a signal, called z.

The above program, implementing and-gate, should be tested now with external signals
applied to ports (terminals) of entity.

It is assumed that a and b are the name of the input signals connected to entity labels x
and y, respectively. Thus,

These signals are externally generated in the laboratory through a hardware setup, called
testbench. However, in software environment, a testbench program is used to generate
and connect the signals to the internal labels x, y and z of the entity and2.

Here is the testbench program:

library ieee;
use ieee.std_logic_1164.all;

entity tb_and2 is
end entity tb_and2;

architecture io of tb_and2 is

4
biswajitb

signal a,b,c: BIT;


begin
g1: entity WORK.and21(exm1) port map(x=>a, y=>b, z=>c);
a <= '0', '1' after 100 ns;
b <= '0', '1' after 150 ns, '0' after 300 ns;
end architecture io;

Note:

1) A characteristic feature of the testbench is to have a blank entity. This means


no new signal is defined. Some other entities that already exist, are being used by the
program for applying external signals.

2) The statement:

g1: entity WORK.and2(exm1) port map(x=>a, y=>b, z=>c);

is called instantiation statement. It is because the entity and2 of architecture


exm1 is called and incorporated in the program for use. g1 is one instance of existing
gate and2. There may be multiple instances of the same or different gates with any other
names like g2, g3, or with entirely different names as per the choice of programmer.

The command port map establishes a mapping between x and a, between y and
b, and also between z and c.

The direction of mapping is always from internal label to external label, irrespective of
the type of the signals.

Timing diagram of input and output signals are shown below.

5
biswajitb

Both the files must be compiled simultaneously under a common project environment.
The testbench program runs on top of other programs as if the signals are generated in a
test bench and connected down to targeted hardware.

#2. Example: Develop an OR gate in VHDL.

Solution:

library ieee;
use ieee.std_logic_1164.all;

entity or21 is
port(x,y: in BIT; z:out BIT);
end entity or21;

architecture exm1 of or21 is


begin
z <= x or y;
end architecture exm1;

#3. Example: Develop a NOT gate in VHDL.

Solution:

library ieee;
use ieee.std_logic_1164.all;

entity not1 is
port(x:in BIT; z:out BIT);
end entity not1;

6
biswajitb

architecture exm1 of not1 is


begin
z <= not x;
end architecture exm1;

#4. Example: Develop one XOR gate in VHDL.

Solution:

library ieee;
use ieee.std_logic_1164.all;

entity xor2 is
port(a, b:in BIT; c:out BIT);
end entity xor2;

architecture exm1 of xor2 is


signal p, q, r, s: BIT;
begin
g1: entity WORK.not1(exm1) port map(x => a, z => p);
g2: entity WORK.not1(exm1) port map(x => b, z => q);
g3: entity WORK.and2(exm1) port map(x => p, y => b, z => r);
g4: entity WORK.and2(exm1) port map(x => q, y => a, z => s);
g5: entity WORK.or2(exm1) port map(x => r, y => s, z => c);
end architecture exm1;

7
biswajitb

Three signals p, q and r are defined within architecture. They are neither in, nor out as
they are used as interface between gates. With respect to some gates, they act as input
signals, to others they act as output signals.

Here is the testbench program:

library ieee;
use ieee.std_logic_1164.all;

entity tb_xor2 is
end entity tb_xor2;

architecture io of tb_xor2 is
signal u, v, w : BIT;
begin
gx: entity WORK.xor2(exm1) port map(a => u, b => v, c => w);
u <= '0', '1' after 100 ns, '0' after 200 ns;
v <= '0', '1' after 150 ns, '0' after 300 ns, '1' after 420 ns;
end architecture io;

■ Signal types and logic states:

In previous programs, all signals were of type BIT. Each of BIT variables may have two
values only – ‘0’ and ‘1’, written in program within single quote.

8
biswajitb

As a whole, there are nine values (logic states). These are:

‘U’ - Uninitialized
‘X’ - Forcing (i.e., strong) unknown
‘0’ - Forcing 0
‘1’ - Forcing 1
‘Z’ - High impedance
‘W’ - Weak unknown
‘L’ - Weak 0
‘H’ - Weak 1
‘-’ - Don’t care

These are defined as per IEEE standard 1164.

If it is required to develop a signal with three logic states like ‘0’, ‘1’ and ‘Z’ only, then
one could define a variable tri_var (defined with arbitrary name by user) like:

Type tri_var is (‘0’, ‘1’, ‘Z’);

However, there is a problem in this definition. If two signals of type tri_var is connected
to the same node, such that one signal forces a ‘1’ upon the node while the other forces a
‘0’, then the resulting state of the node will remain undefined. The actual state of the
node depends on the particular state of the signal having greater power.
Thus, a function must be defined to decide a result out of such a conflicting situation.
This is called resolution function. A resolution function may be defined for signals of
type tri_var as:

0 1 Z
0 0 0 Z
1 0 1 Z
Z Z Z Z

It is apparent that if Z is one input, output from the system will be always Z, irrespective
of the other input. Except Z acting as input, if 0 is an input, output must be 0 irrespective
of whether the other input is 0 or 1. Thus, in this system, Z has the highest power (effect)
and 1 as the lowest.

The resolution function may be defined in other ways also.

However, a resolution function for all nine variables is already defined in IEEE standard
1164. This is:

9
biswajitb

U X 0 1 Z W L H -
U U U U U U U U U U
X U X X X X X X X X
0 U X 0 X 0 0 0 0 X
1 U X X 1 1 1 1 1 X
Z U X 0 1 Z W L H X
W U X 0 1 W W W W X
L U X 0 1 L W L W X
H U X 0 1 H W W H X
- U X X X X X X X X
Resolution function for nine variables

The table (resolution function) as shown above is constructed according to the following
logic:

U makes all into U <= highest priority


X makes all but previous type into X
- makes all but previous types into –
0 makes all but previous types into 0
(except that it makes 1 into X)
1 makes all but previous types into 1
Z makes all but previous types into nothing
W makes all but previous types into W
L makes all but previous types into L
H makes all but previous types into H <= lowest priority

The variable type std_logic supports these nine states along with the resolution function
mentioned above.

Hence, in the program we incorporate library IEEE and then use IEEE.std_logic_1164.all
within it.

Note:

In general, the two following lines:

Library IEEE;
Use IEEE.std_logic_1164.all;

should appear before each entity declaration and will apply to any architecture(s)
declared for that entity.

If more than one entity declaration appears in a file (for instance, of a model and of its
testbench), the library and use statements must appear before each entity. In other
words, VHDL scope rules apply to design units and not to the files in which these design
units are declared.

10
biswajitb

#5. Example: Develop one Tri-stated gate in VHDL.

Solution:

Tri-stated gate: architecture

library ieee;
use ieee.std_logic_1164.all;

entity tristate is
port(a, en: in std_logic; z: out std_logic);
end entity tristate;

architecture exm1 of tristate is


begin
z <= a when en = '1' else 'Z';
end architecture exm1;

Test bench for Tri-stated gate:

library ieee;
use ieee.std_logic_1164.all;

entity test_tristate is
end entity test_tristate;

11
biswajitb

architecture io of test_tristate is
signal p,q,r: std_logic;
begin
g1: entity WORK.tristate(exm1) port map (a=>p, en=>q, z=>r);
p <='1', '0' after 100 ns, '1' after 250 ns, '0' after 500 ns;
q <= '1', '0' after 130 ns, '1' after 280 ns, '0' after 460 ns;
end architecture io;

#6. Example: Develop one 2-to-4 Decoder in VHDL.

Solution:

12
biswajitb

A1 A0 Z3 Z2 Z1 Z0
0 0 0 0 0 1
0 1 0 0 1 0
1 0 0 1 0 0
1 1 1 0 0 0

Truth Table

The program is:

library ieee;
use ieee.std_logic_1164.all;

entity decoder2to4 is
port (a: in std_logic_vector(1 downto 0);
z: out std_logic_vector(3 downto 0));
end entity decoder2to4;

architecture exm1 of decoder2to4 is


begin
z <= "0001" when a= "00" else
"0010" when a= "01" else
"0100" when a= "10" else
"1000" when a= "11" else
"XXXX";
end architecture exm1;

Test bench for decoder 2 to 4:

library ieee;
use ieee.std_logic_1164.all;

entity test_decoder2to4 is
end entity test_decoder2to4;

architecture io of test_decoder2to4 is
signal ain: std_logic_vector(1 downto 0);
signal zout: std_logic_vector(3 downto 0);
begin
g1:entity WORK.decoder2to4(exm1) port map(a=> ain, z=>
zout);
ain <= "00", "01" after 150 ns, "10" after 300 ns;
end architecture io;

13
biswajitb

Note:

1) Bit-values of a vector is written within double quotation marks (“ ”).

2) Last else containing “XXXX” may be omitted. At this, when all four conditions of a
are false, z continues to take last value that was assigned to it earlier. This is the
implementation of latched action.

Same thing can alternatively be represented as



else
unaffected;

3) Each of when – else pair is checked one by one until a match is found.

→ Alternate architecture for the previous decoder:

architecture exm2 of decoder2to4 is


begin
with a select
z < = “0001” when “00”,
“0010” when “01”,
“0100” when “10”,
“1000” when “11”,
“XXXX” when others;
end architecture a;

Note:

1) In with – select statement, all the alternatives are checked simultaneously, unlike the
checking strategy in when – else statement.

2) Therefore, when others clause must be written to cover all possible combinations,
otherwise compilation will fail.

3) Same pattern must not be included in more than one branch.

4) Furthermore, the patterns must be constants so that these can be determined when the
VHDL is being compiled, NOT dynamically in the course of a simulation.

5) If more than one input pattern gives the same output, the patterns can be listed by use
of OR – symbol, such as

14
biswajitb

z < = “0001” when “00”,


“0010” when “01”| “10”| “11”,
“XXXX” when others;

#7. Example: Develop one n to 2 n Decoder in VHDL.

Solution:

We set two quantities of type std_logic_vector, a and z. Size of a is n, and that of z is


2n-1. Thus, size of both the quantities depends on n.

For any particular pattern of input bits in vector a, only one output bit from the vector z
will be 1. This 1 is kept initially at z(0).
Now, if the vector a represents a number m, this 1 in z has to be rotated by m positions.
Thus, a = “000 … 000” makes z(0) = 1, all other bits in z being at 0;
a = “000 … 001” makes z(1) = 1, all other bits in z being at 0;
a = “000 … 010” makes z(2) =1, all other bits in z being at 0; and so on.

Various commands of shift operations are:

sll

sla

15
biswajitb

srl

sra

rol

ror

Note:

1) The target Z must be of bit_vector type…


… a bit_vector can have either ‘0’, or, ‘1’.
After shift operation, bit_vector needs be converted to std_logic_vector by using a
function ‘to_StdLogicVector’ – defined in ‘ieee.std_logic_1164.all’ package

2) Convert A of bit_vector type in to unsigned number…


Convert unsigned number in to integer type …by using function to_integer – defined in
‘ieee.numeric_std’ package

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity decoder is
generic (n: positive);
port(a: in std_logic_vector(n-1 downto 0);
z: out std_logic_vector(2**n-1 downto 0));
end entity decoder;

16
biswajitb

architecture exm1 of decoder is


constant z_out : bit_vector(2**n-1 downto 0):= x"01";
begin
z <= to_StdLogicVector (z_out sll to_integer(unsigned(a)));
end architecture exm1;

The corresponding testbench program is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity test_decoder is
end entity test_decoder;

architecture io of test_decoder is
constant n : natural := 3;
signal s: std_logic_vector(n-1 downto 0);
signal y: std_logic_vector(2**n-1 downto 0);
begin
g1: entity WORK.decoder(exm1) generic map(n)
port map(s, y);
s <= "000", "001" after 200 ns, "110" after 300 ns;
end architecture io;

#8. Example: Develop one 4-to-2 Priority Encoder in VHDL.

Solution:

a(3) a(2) a(1) a(0) y(1) y(0) v (valid)


0 0 0 0 0 0 0
0 0 0 1 0 0 1
0 0 1 - 0 1 1
0 1 - - 1 0 1
1 - - - 1 1 1

17
biswajitb

library ieee;
use ieee.std_logic_1164.all;

entity priority4to2 is
port (a: in std_logic_vector(3 downto 0);
y: out std_logic_vector(1 downto 0);
v: out std_logic);
end entity priority4to2;

architecture exm1 of priority4to2 is


begin
with a select
y <= "00" when “0001’’,
"01" when “001-’’,
“10" when “01--’’,
"11" when “1---’’,
“00“ when others;
v <= ‘1’ when a(0)=‘1’ or a(1)=‘1’ or a(2)=‘1’ or a(3)=‘1’
else ‘0’;
end architecture exm1;

Note:

The logic ‘-’ in VHDL is just another logic. It is not the conventional don’t care state. It
does not include all other logic states in std_logic.

Following program includes the don’t care condition in true sense:

architecture exm2 of priority4to2 is


begin
with a select
y <= “11" when a(3)=‘1’ else
"10" when a(2)=‘1’ else
“01" when a(1)=‘1’ else
“00" when a(0)=‘1’ else
“00”;
v <= ‘1’ when a(0)=‘1’ or a(1)=‘1’ or a(2)=‘1’ or a(3)=‘1’
else ‘0’;
end architecture exm2;

18
biswajitb

Programming Style in VHDL

 Structural
Uses component instantiations
-- already used.
 Dataflow
Uses concurrent signal assignment
-- already used.
 Sequential
Resembles conventional programming language
1) Subprograms
i. Procedures
ii. Functions
2) Processes

#9. Example: Develop a 4-to-2 Priority Encoder through sequential style of


programming in VHDL.

Solution:

architecture exm3 of priority4to2 is


begin
process(a) is
begin
if a(3) =‘1’ then
y <= “11”;
v <= ‘1’;
elsif a(2) =‘1’ then
y <= “10”;
v <= ‘1’;
elsif a(1) =‘1’ then
y <= “01”;
v <= ‘1’;
elsif a(0) =‘1’ then
y <= “00”;
v <= ‘1’;
else
y <= “00”;
v <= ‘0’;
end if;
end process;
end architecture exm3;

19
biswajitb

Note:

1) The process has a sensitivity list with one signal a.

2) The process is evaluated only when the signals in the sensitivity list changes.
Thus, the sensitivity list includes all signals that might cause an output to change.
Here, a is a vector and the process is evaluated when any bit of a changes.

3) If an assignment is made to a signal in one path through a process, an assignment


should be made to that signal in all paths.
Otherwise, the VHDL model will simulate correctly, but the synthesis tool will infer that
latches exist in the hardware.

Sequential looping construct

#. Option – 1 :

for n in N downto 1 loop




end loop;

#. Option – 2 :

for n in 1 to N loop


end loop;

Constant:
N = maximum loop count
Variable:
n = takes decremented / incremented value

If the vector x is defined as x(0 to N-1)


i.e., x={x0 x1 x2 x3, … , xN-1}
Then x’RANGE = {0, 1, 2, 3, … , N-1} = (0 to N-1)
And x’Reverse_RANGE = {N-1, N-2, … , 1, 0} = (N-1 downto 0)

If the vector x is defined as x(N-1 downto 0)


i.e., x={xN-1, xN-2, … , x1, x0}
Then x’RANGE = {N-1, N-2, … , 1, 0} = (N-1 downto 0)
And x’Reverse_RANGE = {0, 1, 2, 3, … , N-1} = (0 to N-1)
These ’RANGE or ’Reverse_RANGE are called attributes.

20
biswajitb

1) The ascending & descending nature of the indices of x is defined in entity using to &
downto, respectively.

2) The attribute of x is used in architecture.

3) The size is specified automatically in architecture depending on the declaration in


entity.

#10. Example: Develop one 2 n to n Pr iority Encoder in VHDL.

Solution:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity priority is
generic (n:positive);
port (a: in std_logic_vector(2**n-1 downto 0);
y: out std_logic_vector(n-1 downto 0);
v: out std_logic);
end entity priority;

architecture exm1 of priority is


begin
prc: process(a) is
v<=‘0’;
y<= (others=>’0’);
for k in a’range loop
if a(k)=‘1’ then
y<=std_logic_vector(to_unsigned(k,n));
v<=‘1’;
exit;

21
biswajitb

end if;
end loop;
end process prc;
end architecture exm1;

The corresponding testbench program is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity test_priority is
end entity test_priority;

architecture io of test_priority is
constant n : natural := 3;
signal ain: std_logic_vector(2**n-1 downto 0);
signal yout: std_logic_vector(n-1 downto 0);
signal vout: std_logic;
begin
g1: entity WORK.priority(exm1) generic map(n)
port map(ain, yout, vout);
ain <= "0000 0000", “0000 0110" after 150 ns, “0100 0000" after 300 ns,
“0001 0011” after 400 ns;
end architecture io;

#11. Example: Develop a full adder circuit in VHDL.

Solution:

a,b : Two 1-bit inputs


sum = a ⊕ b ⊕ c;
sum : 1-bit output
cin : Input carry bit cout = a.b + b.cin + cin.a;
cout : Output carry bit

library ieee;
use ieee.std_logic_1164.all;

22
biswajitb

entity fulladder is
port(a, b, cin: in std_logic;
sum, cout: out std_logic);
end entity fulladder;

architecture exm1 of fulladder is


begin
sum <= a xor b xor cin;
cout <= (a and b) or (b and cin) or (cin and a);
end architecture exm1;

#12. Example: Develop a ripple adder circuit in VHDL.

Solution:

The n-bit ripple adder circuit is a combination of n number of full adder circuits,
connected in cascade.

Following figure demonstrates a 4-bit ripple adder.

23
biswajitb

In general, the k-th full adder block, where k varies from 0 to n-1, is shown below.

cy(0) = Crin, for k = 0


cy(n) = Crout, for k = n

library ieee;
use ieee.std_logic_1164.all;

entity ripple_adder is
generic (n:positive);
port(ar, br: in std_logic_vector(n-1 downto 0);
crin: in std_logic;
sumr: out std_logic_vector(n-1 downto 0);
crout: out std_logic);
end entity ripple_adder;

architecture exm1 of ripple_adder is


signal cy: std_logic_vector(1 to n-1);
begin
g: for k in 0 to n-1 generate
inp: if k=0 generate
f0: entity WORK.fulladder port map
(ar(k), br(k), crin, sumr(k), cy(k+1));
end generate inp;
mid: if k>0 and k<n-1 generate
fk: entity WORK.fulladder port map
(ar(k), br(k), cy(k), sumr(k), cy(k+1));
end generate mid;
outp: if k=n-1 generate
fe: entity WORK.fulladder port map
(ar(k), br(k), cy(k), sumr(k), crout);
end generate outp;
end generate g;
end architecture exm1;

24
biswajitb

The corresponding testbench program is given below.

library ieee;
use ieee.std_logic_1164.all;

entity test_ripple_adder is
end entity test_ripple_adder;

architecture io of test_ripple_adder is
constant n : natural := 4;
signal A, B, S: std_logic_vector(n-1 downto 0);
signal Ci, Co: std_logic;
begin
g1: entity WORK.ripple_adder(exm1) generic map(n)
port map(A, B, Ci, S, Co);
Ci <= ‘0’, ‘1’ after 110 ns, ‘0’ after 300 ns;
A <= “0000”, “1101” after 150 ns, “0111” after 200 ns;
B <= “0000”, “1011” after 150 ns, “1101” after 200 ns;
end architecture io;

In this program, absolute time may be replaced by relative time … The corresponding
architecture of testbench program is given herewith.

architecture ioX of test_ripple_adder is


constant n : natural := 4;
signal A, B, S: std_logic_vector(n-1 downto 0);
signal Ci, Co: std_logic;
begin
g1: entity WORK.ripple_adder(exm1) generic map(n)
port map(A, B, Ci, S, Co);
process is
begin

Ci <= ‘0’;
A <= “0000”;
B <= “0000”;
wait for 110 ns;

Ci <= ‘1’;
wait for 40 ns;
A <= x“d”;
B <= “1011”;
wait for 50 ns;

25
biswajitb

A <= “0111”;
B <= x“d”;
wait for 100 ns;

Ci <= ‘0’;
wait;

end process;
end architecture ioX;

Note:

1) without any inclusion of final wait statement, the process will simply repeat.

2) This process does not have sensitivity list.

3) Execution of Process with sensitivity list, depends on change in signal present in the
list. It does not depend on any specific time. Hence, wait and sensitivity list do not
coexist.

VHDL Model of Sequential Logic Block…

#1. SR Latch:

Solution:

S R Q
0 0 Q = Q =1
0 1 0
1 0 1
1 1 LS

library ieee;
use ieee.std_logic_1164.all;

entity SR_latch1 is
port(S, R: in std_logic;
Q, Qbar: out std_logic);
end entity SR_latch1;

architecture exm1 of SR_latch1 is

26
biswajitb

begin
prc: process (R,S) is
begin
case std_logic_vector(R,S) is
when “00” =>
Q <= ‘1’;
Qbar <= ‘1’;
when “01” =>
Q <= ‘1’;
Qbar <= ‘0’;
when “10” =>
Q <= ‘0’;
Qbar <= ‘1’;
when others =>
null;
end case;
end process prc;
end architecture exm1;

Note:
Q <= not Qbar is wrong as type of Qbar is out, and hence it cannot be read.

#2. D Latch:

Solution:

EN D Q
0 X LS
1 0 0
1 1 1

library ieee;
use ieee.std_logic_1164.all;

entity D_latch is
port(D, EN: in std_logic;
Q: out std_logic);
end entity D_latch;

architecture exm1 of D_latch is


begin
prc: process (D,EN) is
begin

27
biswajitb

if (EN=‘1’) then
Q <= D;
end if; -- No ‘else’ means that a latch holds the
end process prc; -- last value under ‘else’ condition.
end architecture exm1;

#3. D Flipflop (Edge-triggered):

Solution:
CLK D Q
0 X LS
1 X LS
+ve edge 0 0
+ve edge 1 1

library ieee;
use ieee.std_logic_1164.all;

entity D_FF is
port(D, CLK: in std_logic;
Q: out std_logic);
end entity D_FF;

architecture exm1 of D_FF is


begin
prc: process (CLK) is
begin
if rising_edge(CLK) then
Q <= D;
end if;
end process prc;
end architecture exm1;

#4. D Flipflop (Edge-triggered) with Asynchronous Set / Reset:

Solution:

28
biswajitb

Assumed that ‘Set’ has higher priority than ‘Reset’ signal.

library ieee;
use ieee.std_logic_1164.all;

entity D_FF_RS is
port(D, clock, reset, set: in std_logic;
Q: out std_logic);
end entity D_FF_RS;

architecture exm1 of D_FF_RS is


begin
prcs: process (clock, reset, set) is
begin
if (set = ‘0’) then
Q <= ‘1’;
elsif (reset = ‘0’) then
Q <= ‘0’;
elsif rising_edge(clock) then
Q <= D;
end if;
end process prcs;
end architecture exm1;

#5. D Flipflop (Edge-triggered) with Synchronous Set / Reset:

Solution:

Here, circuit pin-outs are same. However, ‘reset’ signal has higher priority over ‘set’.

architecture exm2 of D_FF_RS is


begin
prcs: process (clock) is
begin
if rising_edge(clock) then
if (reset = ‘0’) then
Q <= ‘0’;
elsif (set = ‘0’) then
Q <= ‘1’;
else
Q <= D;

29
biswajitb

end if;
end if;
end process prcs;
end architecture exm2;

#6. D Flipflop (Edge-triggered), two outputs, Asynchronous Reset:

Solution:

library ieee;
use ieee.std_logic_1164.all;

entity Dff is
port(D, reset, CLK: in std_logic;
Q, Qbar: out std_logic);
end entity Dff;

architecture exm1 of Dff is


signal state: std_logic; -- signal cannot be declared
begin -- within process
prs: process (CLK, reset) is
begin
if (reset = ‘0’) then
state <= ‘0’;
elsif rising_edge(CLK) then
state <= D; -- D goes to ‘state’ only
end if; -- after process suspends.
end process prs;
Q <= state; -- Now state is updated,
Qbar <= not state; -- hence Q & Qbar too
end architecture exm1;

Note:

If assignment of Q, Qbar were within process, i.e.,

30
biswajitb

state <= D;
Q <= state;
Qbar <= not state;

Then all the assignments take effect simultaneously just after process suspends…

This means …

state <= new value of D;


Q <= old value of state;
Qbar <= complement of old value of state;

… all in same time

Thus,
Q is not updated with new value of D. It requires one more cycle for such update.
As if, two flipflops are in series – interpretation taken by synthesis tool.
Alternate architecture where assignment will be within process …

architecture exm2 of Dff is


begin
prs: process (CLK, reset) is
variable state: std_logic; -- variable can be declared
begin -- within process only
if (reset = ‘0’) then
state := ‘0’; -- Assignment to variable
elsif rising_edge(CLK) then -- takes effect immediately
state := D;
end if;
Q <= state; -- New value of state goes to Q.
Qbar <= not state; -- Same is true for Qbar also.
end process prs;
end architecture exm2;

Note:

Variable is visible only within process.

#7. Register (Parallel in Parallel out :PIPO):

Solution:

31
biswajitb

library ieee;
use ieee.std_logic_1164.all;

entity pipo_reg is
generic (n: natural := 8);
port(D : in std_logic_vector(n-1 downto 0);
clock, reset: in std_logic;
Q : out std_logic_vector(n-1 downto 0));
end entity pipo_reg;

architecture exm1 of pipo_reg is


begin
proc: process (clock, reset) is
begin
if (reset = ‘0’) then
Q <= (others => ‘0’);
elsif rising_edge(clock) then
Q <= D;
end if;
end process proc;
end architecture exm1;

#8. Register (Serial in Parallel out :SIPO):

Solution:

library ieee;
use ieee.std_logic_1164.all;

entity sipo_reg is
generic (n: natural := 8);
port(Si : in std_logic;
clock, reset: in std_logic;
Q : out std_logic_vector(n-1 downto 0);
CLK: in std_logic);
end entity sipo_reg;

32
biswajitb

architecture exm1 of sipo_reg is


begin
proc: process (CLK) is
variable reg: std_logic_vector(n-1 downto 0);
begin
if rising_edge(CLK) then
reg:= Si & reg(n-1 downto 1);
Q <= reg;
end if;
end process proc;
end architecture exm1;

#9. Up / Down counter:

Solution:

The control signal upcount has higher priority over downcount.

library ieee;
use ieee.std_logic_1164.all;

entity counter_ud is
generic (n: natural := 8);
port(clock, IC, upcount, downcount: in std_logic;
count : out std_logic_vector(n-1 downto 0));
end entity counter_ud;

architecture exm1 of counter_ud is


begin
proc: process (clock, IC) is -- unsigned type
variable cnt: unsigned(n-1 downto 0); -- supports ‘+’
begin -- operator
if IC = ‘1’ then
cnt := (others => ‘0’);

33
biswajitb

elsif rising_edge(clock) and upcount = ‘1’ then


cnt:= cnt + 1;
elsif rising_edge(clock) and downcount = ‘1’ then
cnt:= cnt – 1;
end if;
count <= std_logic_vector(cnt);
end process proc;
end architecture exm1;

#10. Clock Generator:

Solution:

Objective: To generate two signals whose frequencies are given by


f clock1x = f clock
f clock
f cloclNd =
2N

34
biswajitb

library ieee;
use ieee.std_logic_1164.all;

entity clkgenN is
generic (N: natural := 4);
port(clock: in std_logic;
clock1x, clockNd : out std_logic);
end entity clkgenN;

architecture exm1 of clkgenN is


signal clocktemp: std_logic:= ‘0’;
begin
clock1x <= clock;
prc: process (clock) is
variable clkcount: integer range 0 to N-1:=N-1;
begin
if rising_edge(clock) then
if (clkcount = N-1)then
clkcount:= 0;
clocktemp <= not clocktemp;
else
clkcount:= clkcount + 1;
end if;
end if;
end process prc;
clockNd <= clocktemp;
end architecture exm1;

The corresponding testbench program is given below.

library ieee;
use ieee.std_logic_1164.all;

entity test_clkgenN is
end entity test_clkgenN;

architecture io of test_clkgenN is
signal clkin: std_logic:= ‘0’;
signal clkout1, clkoutN: std_logic;
begin
gx: entity WORK. clkgenN(exm1)port map
(clkin, clkout1, clkoutN);
clkin <= not clkin after 100 ns;
end architecture io;

35
biswajitb

#11. Develop a ROM containing an LUT of sine wave data:

Solution: It is assumed that number of data available within the ROM is 2M-1.

Data is available in sequence at each input edge of CLK.

Expression of LUT:

x(n) = 128 + (255 − 128) sin( ⋅ n), 0 ≤ n ≤ N − 1, N = 64.
N
X n = round [ x(n)]

The array of values are: [128 140 153 165 177 188 199 209 218 226 234
240 245 250 253 254 255 254 253 250 245 240
234 226 218 209 199 188 177 165 153 140 128
116 103 91 79 68 57 47 38 30 22 16
11 6 3 2 1 2 3 6 11 16 22
30 38 47 57 68 79 91 103 116]

The corresponding plot is:

library ieee;
use ieee.std_logic_1164.all;

use ieee.numeric_std.all;
entity sine_ROM is
generic (M: natural := 6; N: natural :=8);
port(CSbar, CLK, RDbar: in std_logic;
data: out std_logic_vector(N-1 downto 0));
end entity sine_ROM;

36
biswajitb

architecture exm1 of sine_ROM is


type ROM_array is array(0 to 2**M-1) of
std_logic_vector(N-1 downto 0);
constant rom: ROM_array := (x"80", x"8C", x"99", x"A5",
x"B1", x"BC", x"C7", x"D1",
x"DA", x"E2", x"EA", x"F0",
x"F5", x"FA", x"FD", x"FE",

x"FF", x"FE", x"FD", x"FA",


x"F5", x"F0", x"EA", x"E2",
x"DA", x"D1", x"C7", x"BC",
x"B1", x"A5", x"99", x"8C",

x"80", x"74", x"67", x"5B",


x"4F", x"44", x"39", x"2F",
x"26", x"1E", x"16", x"10",
x"0B", x"06", x"03", x"02",

x"01", x"02", x"03", x"06",


x"0B", x"10", x"16", x"1E",
x"26", x"2F", x"39", x"44",
x"4F", x"5B", x"67", x"74");

begin
prc: process(CLK) is
variable addr : integer range 0 to 2**M-1 := 63;
begin
if rising_edge(CLK) and CSbar = '0' and RDbar = '0' then

if addr = 63 then
addr := 0;
else
addr := addr + 1;
end if;

data <= rom(addr);


end if;
end process prc;
end architecture exm1;

37

You might also like