Вы находитесь на странице: 1из 209

VHDL coding tips and tricks

Get interesting tips and tricks in VHDL programming

Home
VHDL FAQs
Example Codes
Testimonials
About me
Disclaimer
Homework or Project

SUNDAY, OCTOBER 3, 2010

A 3 bit Magnitude Comparator using logic gates


I have been getting lot of requests asking for VHDL code for digital comparators. In this post I have
shared a 3 bit comparator which is designed using basic logic gates such as XNOR, OR, AND etc. The
code was tested using a testbench code which tested the design for all the 81 combinations of inputs.
See the code below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity comparator is
port( a,b : in unsigned(2 downto
compared
a_eq_b : out std_logic;
a_le_b : out std_logic;
a_gt_b : out std_logic
);
end comparator;

0);

--3 bit numbers to be

--a equals b
--a less than b
--a greater than b

architecture gate_level of comparator is


signal temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9 : std_
logic := '0';
BEGIN
temp1 <= not(a(2) xor b(2));

--XNOR gate with 2 inputs.

temp2
temp3
temp4
temp5
temp6
temp7
temp8
temp9

<=
<=
<=
<=
<=
<=
<=
<=

not(a(1) xor b(1)); --XNOR gate with 2 inputs.


not(a(0) xor b(0)); --XNOR gate with 2 inputs.
(not a(2)) and b(2);
(not a(1)) and b(1);
(not a(0)) and b(0);
a(2) and (not b(2));
a(1) and (not b(1));
a(0) and (not b(0));

a_eq_b <=
a_le_b <=
; --for a
a_gt_b <=
; --for a

temp1 and temp2 and temp3; -- for a equals b.


temp4 or (temp1 and temp5) or (temp1 and temp2 and temp6)
less than b
temp7 or (temp1 and temp8) or (temp1 and temp2 and temp9)
greater than b

end gate_level;
The testbench code for testing the design is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal a : unsigned(2 downto 0) := (others => '0');
signal b : unsigned(2 downto 0) := (others => '0');
--Outputs
signal a_eq_b : std_logic;
signal a_le_b : std_logic;
signal a_gt_b : std_logic;
signal i,j : integer;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.comparator PORT MAP (
a => a,
b => b,
a_eq_b => a_eq_b,
a_le_b => a_le_b,
a_gt_b => a_gt_b
);
-- Stimulus process

stim_proc: process
begin
for i in 0 to 8 loop
for j in 0 to 8 loop
a <= to_unsigned(i,3); --integer to unsigned type
conversion
b <= to_unsigned(j,3);
wait for 10 ns;
end loop;
end loop;
end process;
END;
A part of the simulation waveform is given below:

Note:- For viewing the full results simulate the program yourself. The code was tested using Xilinx ISE
12.1 version. But it will work with almost all the compilers.The code is also synthesisable.
Posted by vipin at 10:43 AM

Reactions:
Labels: comparator, examples, Gate level model
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
ChrisOctober 6, 2010 11:31 AM
This is very academic. I am not a fan of design at this level. For FPGA's its actually detrimental.
In
any
useful
design,
the
user
would
just
use:
x
<=
'1'
when
(unsigned(a)
<
unsigned(b))
else
'0';
This scales well, even beyond the 31b limit of integers.
Reply
2.
vipinOctober 6, 2010 11:47 AM
@Chris : yes you are right Chris. I wrote this code from a academic point of view. In real project
no body will write separate module for just a comparison. This post was for VHDL beginners for
learning gate level modeling.
Reply
RELATED SEARCHES:

Page break by AutoPager. Page(

).

LoadPages

TUESDAY, SEPTEMBER 14, 2010

How to use "generate" keyword for multiple instantiation?


Generate statement is a concurrent statement used in VHDL to describe repetitive structures.You
can use generate statement in your design to instantiate multiple modules in two ways: the FOR-way and
the IF-way.
FOR-way is explained through a PISO(parallel in serial out) register example I have discussed
earlier.The original post can be accessedhere. I have modified the Gate level modeling code available in
that post using "generate" statement.

--Library declaration.
library ieee;
use ieee.std_logic_1164.all;
--4 bit Parallel In Serial Out shift register(LSB is out first)
entity PISO is
port ( Serial_out : out std_logic;
Parallel_In : in std_logic_vector(3 downto 0);
--Load=1 means register is loaded parallely and Load=0 means
right shift by one bit.
Load : in std_logic;
Clk : in std_logic
);
end PISO;
architecture gate_level of PISO is
signal D,Q,Load_value : std_logic_vector(3 downto 0):="0000";
signal i : integer := 0;
begin
Load_value <= Parallel_In;
Serial_out <= Q(3);
--entity instantiation of the D flipflop using "generate".
F : --label name
for i in 0 to 3 generate
--D FF is instantiated 4 times.
begin --"begin" statement for "generate"
FDRSE_inst : entity work.example_FDRSE port map
--usual
port mapping
(Q => Q(i),
CLK => Clk,
CE => '1',
RESET => '0',
D => D(i),
SET => '0');
end generate F; --end "generate" block.
--The D inputs of the flip flops are controlled with the load
input.
--Two AND gates with a OR gate is used for this.
D(0) <= Load_value(3) and Load;

D(1) <= (Load_value(2) and Load) or (Q(0) and not(Load));


D(2) <= (Load_value(1) and Load) or (Q(1) and not(Load));
D(3) <= (Load_value(0) and Load) or (Q(2) and not(Load));
end gate_level;
I hope the above code is self explanatory.The for loop is used to instantiate as many number of modules
as we want to instantiate.Next I will give an example on the IF-way using a Johnson counter example.
The Johnson counter is explained with the help of VHDL code in one of my previous posts.Check it
out here.I have modified the code using flip-flops available in this post.
The modified code is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity johnson_counter is
port (
DAT_O : out unsigned(3 downto 0);
RST_I : in std_logic;
CLK_I : in std_logic
);
end johnson_counter;
architecture Behavioral of johnson_counter is
signal D,Q : unsigned(3 downto 0):="0000";
signal not_Q4 : std_logic:='0';
begin
not_Q4 <= not Q(3);
DAT_O <= Q;
F : for i in 0 to 3 generate
begin
F0 : if ( i = 0 ) generate --The IF condition to for the
"first" FF only.
begin U1 : entity work.example_FDRSE port map --usual
port mapping
(Q => Q(0),
CLK => CLK_I,
CE => '1',
RESET => RST_I,
D => not_Q4,
SET => '0');
end generate F0;
F1 : if ( i /= 0 ) generate --generating the rest of the
three FF's.
begin U2 : entity work.example_FDRSE port map
--usual
port mapping
(Q => Q(i),
CLK => CLK_I,
CE => '1',
RESET => RST_I,
D => Q(i-1),
SET => '0');

end generate F1;


end generate F;
end Behavioral;
So as you can see from the examples using "generate" keyword makes your design simple to
understand and saves your time.
Posted by vipin at 5:40 PM

Reactions:
Labels: examples, generate, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

MONDAY, SEPTEMBER 13, 2010

Measure the time period/Frequency of an input Pulse


This article is about how to find the time period of an input pulse using a simple counter and some
adders.In some applications you may have a pulse input which has unknown or varying frequency.And
you may need to find out this frequency.In this design I have two parts.
First part is a counter which keeps on incrementing at the system clock frequency.When this
counter reaches its maximum value it resets automatically and counts up again.The second part is
triggered at every positive edge of the pulse input.So this part is triggered once every clock cycle of the
pulse.In the second part we simply subtracts the last count from the current count to get the time
period of the pulse in terms of the time period of the system clock.
For example if you see the simulation waveform I have attached at the bottom of this page you can see
how this works:
1) pulse goes to '1' at 10 ns. Prev_Count is made "1000" which is the curr_count at 10 ns.
2) pulse goes to '0' at 110 ns. Nothing happens here. But all this time curr_count keeps on counting with
the system clock.
3) pulse goes to '1' at 160 ns. Now we calculate (Curr_count - Prev_count ) = (16000 - 1000) =15000.
This is how we get 15000 as the time period of the pulse input in terms of system clock. For getting
the exact time period is ns you have to multiply the time period of system clock with the calculated value.
Here we multiply 15000 with 10 ps = 150 ns.
4)For all this to work with good precision the frequency of the system clock should be very high
compared to the frequency of pulse input. Otherwise the module will output the time period as "0" and
a '1' will be asserted in the ERR_O output.
5)Whenever we calculate the time period of the pulse we update the prev_count with the current value of
count.
6)Note that at time 1460.004 ns, at the new positive edge of pulse cycle we have a new time period
calculated which is 130000 in relative terms or 1300 ns in absolute scale.
The code for the design is given below:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pulse_counter is
port ( DAT_O : out unsigned(47 downto 0);
ERR_O : out std_logic; --This is '1' if the pulse freq is
more than clk freq.
Pulse_I : in std_logic;
CLK_I : in std_logic
);
end pulse_counter;
architecture Behavioral of pulse_counter is
signal Curr_Count,Prev_Count : unsigned(47 downto 0):=(others => '0
');
begin
--Increment Curr_Count every clock cycle.This is the max freq which
can be measured by the module.
process(CLK_I)
begin
if( rising_edge(CLK_I) ) then
Curr_Count <= Curr_Count + 1;
end if;
end process;
--Calculate the time period of the pulse input using the current
and previous counts.
process(Pulse_I)
begin
if( rising_edge(Pulse_I) ) then
--These different conditions eliminate the count overflow
problem
--which can happen once the module is run for a long time.
if( Prev_Count < Curr_Count ) then
DAT_O <= Curr_Count - Prev_Count;
ERR_O <= '0';
elsif( Prev_Count > Curr_Count ) then
--X"F_F" is same as "1111_1111".
--'_' is added for readability.
DAT_O <= X"1_0000_0000_0000" - Prev_Count +
Curr_Count;
ERR_O <= '0';
else
DAT_O <= (others => '0');
ERR_O <= '1'; --Error bit is inserted here.
end if;
Prev_Count <= Curr_Count; --Re-setting the Prev_Count.
end if;
end process;
end Behavioral;

The testbench code used for testing the design is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal Pulse_I : std_logic := '0';
signal CLK_I : std_logic := '0';
--Outputs
signal DAT_O : unsigned(47 downto 0);
signal ERR_O : std_logic;
-- Clock period definitions
constant CLK_I_period : time := 10 ps;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.pulse_counter PORT MAP (
DAT_O => DAT_O,
ERR_O => ERR_O,
Pulse_I => Pulse_I,
CLK_I => CLK_I
);
-- Clock process definitions
CLK_I_process :process
begin
CLK_I <= '0';
wait for CLK_I_period/2;
CLK_I <= '1';
wait for CLK_I_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 10 ns;
--1 (time period is 15000*10 ps here)
Pulse_I <= '1';
wait for 100 ns;
Pulse_I <= '0';
wait for 50 ns;
Pulse_I <= '1';
--2 (Error because freq of pulse is less than system
clock)
wait for 3 ps;
Pulse_I <= '0';
wait for 1 ps;
Pulse_I <= '1';

--3 (time period is 130000*10 ps here)


wait for 300 ns;
Pulse_I <= '0';
wait for 1000 ns;
Pulse_I <= '1';
wait;
end process;
END;
The simulation wave form is shown below:

Markers are added in the waveform for clearly understanding the positive edges of the pulse wave.Go
through the wave form along with the codes and the explanation given above.
Posted by vipin at 4:07 PM

Reactions:
Labels: Frequency measurement, useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
ParulAugust 19, 2011 12:36 PM
really helpful!
Reply
2.
t&amp;amp;tApril 28, 2012 12:35 AM
hello
my
friend,
i
dont
understand
this
line:
DAT_O
<=
X"1_0000_0000_0000"
Prev_Count
+
Curr_Count;
and I dont understand why you use unsigned numbers. Can you help me? thank you
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

MONDAY, SEPTEMBER 13, 2010

Example : 4 bit Johnson Counter with testbench

LoadPages

A Johnson counter is a digital circuit which consists of a series of flip flops connected together in a
feedback manner.The circuit is special type of shift register where the complement output of the last
flipflop is fed back to the input of first flipflop.This is almost similar to ring counterwith a few extra
advantages.When the circuit is reset all the flipflop outputs are made zero. For n-flipflop Johnson counter
we have a MOD-2n counter. That means the counter has 2n different states.
The circuit diagram for a 3 bit Johnson counter is shown below:

The VHDL code for 4 bit Johnson counter is shown below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity johnson_counter is
port (
DAT_O : out unsigned(3 downto 0);
RST_I : in std_logic;
CLK_I : in std_logic
);
end johnson_counter;
architecture Behavioral of johnson_counter is
signal temp : unsigned(3 downto 0):=(others => '0');
begin
DAT_O <= temp;
process(CLK_I)
begin
if( rising_edge(CLK_I) ) then
if (RST_I = '1') then
temp <= (others => '0');
else
temp(1) <= temp(0);
temp(2) <= temp(1);
temp(3) <= temp(2);
temp(0) <= not temp(3);
end if;
end if;
end process;

end Behavioral;
The testbench code used for testing the design is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb2 IS
END tb2;
ARCHITECTURE behavior OF tb2 IS
--Inputs
signal RST_I : std_logic := '0';
signal CLK_I : std_logic := '0';
--Outputs
signal DAT_O : unsigned(3 downto 0);
-- Clock period definitions
constant CLK_I_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.johnson_counter PORT MAP (
DAT_O => DAT_O,
RST_I => RST_I,
CLK_I => CLK_I
);
-- Clock process definitions
CLK_I_process :process
begin
CLK_I <= '0';
wait for CLK_I_period/2;
CLK_I <= '1';
wait for CLK_I_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
RST_I <= '1';
wait for 2 ns;
RST_I <= '0';
wait for 2 ns;
RST_I <= '1';
wait for 1 ns;
RST_I <= '0';

wait;
end process;
END;
The simulation waveform is given below:

Posted by vipin at 12:52 PM

Reactions:
Labels: Behavior level model, counters, examples
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
harshFebruary 4, 2011 10:05 PM
cud ny1 guide plz y here the word other being used,is it a keyword??
Reply
2.
vipinFebruary 4, 2011 10:13 PM
Check
in
this
http://vhdlguru.blogspot.com/2010/02/arrays-and-records-in-vhdl.html

link:

Reply
3.
arepex92March 28, 2011 8:51 PM
how to convert ring counter circuit to johnson counter circuit?can you show are circuit?step by
step??
Reply
4.
sumeetApril 17, 2011 11:16 PM
signal

temp

unsigned(3

why other =>'0' is used in this signal statement


Reply
Add comment

downto

0):=(others

=>

'0');

RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

MONDAY, SEPTEMBER 13, 2010

Example : 4 bit Ring Counter with testbench


A ring counter is a digital circuit which consists of a series of flip flops connected together in a feedback
manner.The circuit is special type of shift register where the output of the last flipflop is fed back to the
input of first flipflop.When the circuit is reset, except one of the flipflop output,all others are made zero.
For n-flipflop ring counter we have a MOD-n counter. That means the counter has n different states.
The circuit diagram for a 4 bit ring counter is shown below:

I have written a VHDL code for a 4-bit ring counter which has the following states:
0001 - 0010 - 0100 - 1000 ....
The code is posted below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ring_counter is
port (
DAT_O : out unsigned(3 downto 0);
RST_I : in std_logic;
CLK_I : in std_logic
);
end ring_counter;
architecture Behavioral of ring_counter is
signal temp : unsigned(3 downto 0):=(others => '0');
begin
DAT_O <= temp;
process(CLK_I)
begin
if( rising_edge(CLK_I) ) then
if (RST_I = '1') then
temp <= (0=> '1', others => '0');
else

temp(1)
temp(2)
temp(3)
temp(0)
end if;
end if;
end process;

<=
<=
<=
<=

temp(0);
temp(1);
temp(2);
temp(3);

end Behavioral;
The testbench code used for testing the design is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal RST_I : std_logic := '0';
signal CLK_I : std_logic := '0';
--Outputs
signal DAT_O : unsigned(3 downto 0);
-- Clock period definitions
constant CLK_I_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.ring_counter PORT MAP (
DAT_O => DAT_O,
RST_I => RST_I,
CLK_I => CLK_I
);
-- Clock process definitions
CLK_I_process :process
begin
CLK_I <= '1';
wait for CLK_I_period/2;
CLK_I <= '0';
wait for CLK_I_period/2;
end process;
-- Stimulus process
stim_proc: process
begin

RST_I <=
wait for 2
RST_I <=
wait for
RST_I <=
wait for
RST_I <=
wait;
end process;

'1';
ns;
'0';
5 ns;
'1';
1 ns;
'0';

END;
The simulation wave form is given below:

Posted by vipin at 12:34 PM

Reactions:
Labels: Behavior level model, counters, examples
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

THURSDAY, SEPTEMBER 9, 2010

Examples for Gate Level and Behavior Level Designs


This article is about the two major type of modeling available in VHDL - Gate Level and Behavior level.
In gate level modeling the module is implemented in terms of logic gates and interconnections between
these gates.Design at this level is similar to describing a circuit in terms of a gate level logic diagram.
In Behavior level(Algorithmic level) modeling a module is implemented in terms of the desired design
algorithm without the concern for the hardware circuit elements.Designing at this level is the highest
abstraction level provided by VHDL.
For understanding the difference between the two models I have designed a PISO(Parallel In Serial Out)
in both the models. See the behavioral level code below:

--Library declaration.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity piso is
PORT(

Serial_out : OUT std_logic;


Parallel_In : IN std_logic_vector(3 downto 0);
Load : IN std_logic;
Clk : IN std_logic
);
end piso;
architecture Behavioral of piso is
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
process(Clk)
begin
if(rising_edge(Clk)) then
if( Load ='0' ) then --Do the serial right shifting here.
Serial_Out <= Load_value(3);
Load_value(3) <= Load_value(2);
Load_value(2) <= Load_value(1);
Load_value(1) <= Load_value(0);
Load_value(0) <= '0';
else
--Load the registers with a new value to shift.
Load_value <= Parallel_In;
end if;
end if;
end process;
end Behavioral;
If you check the code above then you can see that the code is written using some if..else.. statements.
We havent used any digital circuit elements like flip-flops,gates,registers etc. The code describes the
working in a language similar to a high level language like C (but there are lot of difference between C
and VHDL, and they are not even comparable).
Now let us check the Gate level code:

--Library declaration.
library ieee;
use ieee.std_logic_1164.all;
--4 bit Parallel In Serial Out shift register(LSB is out first)
entity PISO is
port ( Serial_out : out std_logic;
Parallel_In : in std_logic_vector(3 downto 0);
--Load=1 means register is loaded parallely and Load=0
means right shift by one bit.
Load : in std_logic;
Clk : in std_logic
);
end PISO;
architecture gate_level of PISO is
signal D1,D2,D3,D4,Q1,Q2,Q3,Q4 : std_logic :='0';
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
Load_value <= Parallel_In;
Serial_out <= Q4;

--entity instantiation of the D flipflop.It is instantiated 4 times


to make 4 bit register.
FDRSE1 : entity work.example_FDRSE --MSB
port map (
Q => Q1,
CLK => Clk,
CE => '1',
RESET => '0',
D => D1,
SET => '0'
);
FDRSE2 : entity work.example_FDRSE
port map (
Q => Q2,
CLK => Clk,
CE => '1',
RESET => '0',
D => D2,
SET => '0'
);
FDRSE3 : entity work.example_FDRSE
port map (
Q => Q3,
CLK => Clk,
CE => '1',
RESET => '0',
D => D3,
SET => '0'
);
FDRSE4 : entity work.example_FDRSE --LSB
port map (
Q => Q4,
CLK => Clk,
CE => '1',
RESET => '0',
D => D4,
SET => '0'
);
--The D inputs of the flip flops are controlled with the load
input.
--Two AND gates with a OR gate is used for this.
D1 <= Load_value(3) and Load;
D2 <= (Load_value(2) and Load) or (Q1 and not(Load));
D3 <= (Load_value(1) and Load) or (Q2 and not(Load));
D4 <= (Load_value(0) and Load) or (Q3 and not(Load));
end gate_level;
In the above code you can notice the following features of Gate level code:
1)We have used VHDL gate level primitives like not,and,or etc in the program.
2)The flip flop required for implementing the 4 bit register was instantiated separately. The flip flop code

was taken from one of my earlier post and it is another example of behavior level modeling.Check the flip
flop code here.
3)We havent used a "process" statement in the program.
4)The above code is also an example of Structural level modeling where we use a hierarchy of
modules.For example the D flip flop is considered as a black box from the PISO module's point of
view.Once the flip flop (or generally any other module) is designed and verified we can use it any number
of times any where in a bigger design.This type of design is called structural level design. Some more
examples can be found here : 4 bit synchronous UP counter.
5)You can find more example codes for gate level modeling here : 3 to 8 decoder using basic logic
gates and 4 bit ripple carry adder.
I have written the following testbench code for verifying my design.You can edit and check for more input
combination for learning purpose.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal Parallel_In : std_logic_vector(3 downto 0) := (others => '0
');
signal Load : std_logic := '0';
signal Clk : std_logic := '0';
--Outputs
signal Serial_out : std_logic;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.PISO PORT MAP (
Serial_out => Serial_out,
Parallel_In => Parallel_In,
Load => Load,
Clk => Clk
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 25 ns;
load <= '1';
parallel_in <= "1011";
wait for 10 ns;

load<='0';
wait for 60 ns;
load <= '1';
parallel_in <= "1101";
wait for 10 ns;
load<='0';
wait;
end process;
END;
The simulation result is shown below:

Note:- I have instantiated modules using the "entity instantiation" method. If you are new to this method
please read this article.
Posted by vipin at 2:09 PM

Reactions:
Labels: Behavior level model, examples, Gate level model, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
DanielDecember 7, 2010 2:06 AM
This

is

great

website

and

some

fantastic

information.

However every programme I write or compile I seem to have errors! When I compile this one I
get
"ERROR:Simulator:754
Signal
EXCEPTION_ACCESS_VIOLATION
received
ERROR:Simulator:754
Signal
EXCEPTION_ACCESS_VIOLATION
received"
What
is
it
and
why
do
i
get
it
twice?
I get it when i try and simulate. I am using xilinx 12.3 (I went to 12.3 as I was getting them with
12.2)
Thanks
Reply
2.
DanielDecember 7, 2010 11:54 PM
Ive
solved
it,
uninstall
embassy
trust
suite
from
laptop.
as
per
http://forums.xilinx.com/t5/Archived-ISE-issues/Any-idea-about-quot-ERROR-Simulator-754quot/m-p/20835

Thanks
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

WEDNESDAY, SEPTEMBER 8, 2010

Example : D Flip-Flop with Asynchronous Clear,Set and Clock


Enable
As per the request from readers I have decided to post some basic VHDL codes for beginners in
VHDL. This is the second one in the series, a basic D Flip-Flop with Asynchronous Clear,Set and
Clock Enable(negedge clock).The code is self explanatory and I have added few comments for easy
understanding.

--library declaration for the module.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--This is a D Flip-Flop with Asynchronous Clear,Set and Clock
Enable(negedge clock).
--Note that the clear input has the highest priority,preset being
the next highest
--priority and clock enable having the lowest priority
entity example_FDCPE is
port(
Q : out std_logic;
-- Data output
CLK :in std_logic;
-- Clock input
CE :in std_logic;
-- Clock enable input
CLR :in std_logic; -- Asynchronous clear input
D :in std_logic;
-- Data input
PRE : in std_logic
-- Asynchronous set input
);
end example_FDCPE;
architecture Behavioral of example_FDCPE is
circuit.
begin

--architecture of the

--"begin" statement for architecture.

process(CLR,PRE,CLK) --process with sensitivity list.


begin --"begin" statment for the process.
if (CLR = '1') then
Q <= '0';
else

--Asynchronous clear input

if(PRE = '1') then --Asynchronous set input


Q <= '1';
else
if ( CE = '1' and falling_edge(CLK) ) then
Q <= D;
end if;
end if;
end if;
end process;

--end of process statement.

end Behavioral;
Note :- This is a flip flop which is defined in the Xilinx language template for spartan-3.If you synthesis
this design it will use exactly one flip flop and some buffers alone.It will not use any LUT's for the
implementation.
Posted by vipin at 3:33 PM

Reactions:
Labels: examples, flipflops
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:
1.
Xu Whai TuckSeptember 9, 2010 12:00 AM
Thank

you

for

your

wonderful

post

but

as

am

newbie

in

VHDL.

How about an example of shift register that can increment, shift left , shift right ?
Thanks again ^_^
Reply
2.
vipinSeptember 9, 2010 9:47 PM
may not be exactly as per your requirement but I have written code for a PISO shift register
here:
http://vhdlguru.blogspot.com/2010/09/examples-for-gate-level-and-behavior.html
Using this you can try to code the module you want.
Reply
3.
laxmanJuly 19, 2011 5:44 PM
good

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

WEDNESDAY, SEPTEMBER 8, 2010

Example : D Flip-Flop with Synchronous Reset,Set and Clock


Enable
As per the request from readers I have decided to post some basic VHDL codes for beginners in VHDL.
This is the first one, a basic D Flip-Flop with Synchronous Reset,Set and Clock Enable(posedge
clock).The code is self explanatory and I have added few comments for easy understanding.

--library declaration for the module.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--This is a D Flip-Flop with Synchronous Reset,Set and Clock
Enable(posedge clk).
--Note that the reset input has the highest priority,Set being the
next highest
--priority and clock enable having the lowest priority.
entity example_FDRSE is
port(
Q : out std_logic;
-- Data output
CLK :in std_logic;
-- Clock input
CE :in std_logic;
-- Clock enable input
RESET :in std_logic; -- Synchronous reset input
D :in std_logic;
-- Data input
SET : in std_logic
-- Synchronous set input
);
end example_FDRSE;
architecture Behavioral of example_FDRSE is --architecture of the
circuit.
begin --"begin" statement for architecture.
process(CLK) --process with sensitivity list.
begin --"begin" statment for the process.
if ( rising_edge(CLK) ) then --This makes the process
synchronous(with clock)
if (RESET = '1') then
Q <= '0';
else
if(SET = '1') then
Q <= '1';
else
if ( CE = '1') then
Q <= D;
end if;

end if;
end if;
end if;
end process; --end of process statement.
end Behavioral;
Note :- This is a flip flop which is defined in the Xilinx language template for spartan-3.If you synthesis
this design it will use exactly one flip flop and some buffers alone.It will not use any LUT's for the
implementation.
Posted by vipin at 1:59 PM

Reactions:
Labels: examples, flipflops
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
AWAISMarch 2, 2011 1:58 AM
test bench?????
Reply
2.
vipinMarch 2, 2011 8:44 AM
@awais : I left the testbench for this module as an exercise to students. Read this post and write
a
similar
testbench.
http://vhdlguru.blogspot.com/2010/03/positive-edge-triggered-jk-flip-flop.html
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

).

LoadPages

FRIDAY, AUGUST 13, 2010

Careful RAM designing for reducing power consumption in


FPGA

I will discuss some points which will be helpful for reducing the power
reduction in an FPGA in this post.Mainly I am concentrating on the power
dissipation caused by the RAM.These points are selected from the Xilinx
white paper for Virtex-5 system power design considerations.But I will note
down the points which will apply for any Xilinx FPGA.
There are two primary types of power consumption in FPGA's: static and
dynamic power. Static power is consumed due to transistor leakage.

Dynamic power is consumed by toggling nodes as a function of voltage,


frequency, and capacitance.The leakage current is directly proportional to
the speed of the processor,operating voltage of the processor and junction(or
die) temperature.So static power increases from Virtex 4 FPGA to Virtex 5
FPGA.On the other hand dynamic power reduces from Virtex 4(90 nm device)
to Virtex 5(65 nm device).This is because dynamic power is directly
proportional to the voltage of operation and the capacitance(this includes the
transistor parasitic capacitance and metal interconnect capacitance).From
Virtex 4 to Virtex 5, these two parameters decrease and so we get around 40
%reduction in dynamic power.
You can get more details from the pdf link I have shared above.
Xilinx has given some tips in reducing the power consumption by
designing RAM's intelligently.I am writing down them one by one:
1)Choose the right RAM primitive for your design.When choosing a
RAM organization within the target architecture, the width, depth,and
functionality must be considered. Choosing the right memory facilitates the
selection of the most power-efficient resource for the end design.
2)Ensure that, the block RAM is only enabled when data is needed
from it.This is because the power requirements of a block RAM is directly
proportional to the amount of time it is enabled.Normally for ease of coding
the enable signal is always "ON".But for power sensitive applications take
some extra effort to make use of enable signal of RAM.
Another tip regarding enable signal is explained in the following example.Say
you want a 2k x 8 bit RAM in your design.Then use four 512 x 8 bit RAM's for
this.Now use a seperate a enable signal for each RAM.This needs some extra
logic, but at any time only one RAM will be ON , so we can save around 75%
of the power.
3)Ensure the WRITE_MODE of RAM is set properly.If the block RAM
contents are never read during a write, the RAM power can be reduced by a
significant amount with the selection of the NO_CHANGE mode rather than
the default WRITE_FIRST mode.This mode can be set easily if you are using
the core generator GUI to create the RAM module.
Note:- It would be wise to see the Xilinx white paper on power reduction for
your particular FPGA before start the coding for your design.This will be
helpful in getting useful tips which are device specific.
Posted by vipin at 6:12 PM

Reactions:
Labels: xilinx tips
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:

1.
DeepaJune 5, 2012 10:25 AM
how can i contact you personally
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

10

).

LoadPages

THURSDAY, AUGUST 12, 2010

Using Xilinx primitives in your design-An example


Xilinx has provided a library named "UNISIM" which contains the component declarations
for all Xilinx primitives and points to the models that will be used for simulation.This library
is used during functional simulation and contains descriptions for all the device primitives, or
lowest-level building blocks.
In this post I will show you how to use a primitive in your design.In the example I am using
the primitive named "RAMB16_S2" which is 8k x 2 Single-Port RAM for Spartan-3E FPGA. This
primitive is instantiated twice to make 8k x 4 single port RAM.
The code is given below.Note that I have made the code in the form of a testbench.So the
below code is not synthesisable.This code is just for guiding you, how to use Xilinx primitives
in your design.The code is well commented. So I hope I need not explain about the
working of the code.Here in order to create a 8k x 4 RAM I used two 8k x 2 RAM's side by
side.One RAM used to store the LSB 2 bits of the data while the 2nd RAM is used to store the
MSB 2 bits of the data.Note that the address is same for both the RAM's.
See the way I have instantiated the primitive in the design.Also don't forget to add the UNISIM library to
the design.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--Remember to add this library when you use xilinx primitives from
Language templates.
library unisim;
use unisim.vcomponents.all;
entity ram_test is
end ram_test;
architecture Behavioral of ram_test is
--signal declarations.
signal clk,en,ssr,we : std_logic:='0';
signal Dout,Din : std_logic_vector(3 downto 0):="0000";

signal addr : std_logic_vector(12 downto 0):=(others => '0');


begin
--RAMB16_S2 is 8k x 2 Single-Port RAM for Spartan-3E.We use this to
create 8k x 4 Single-Port RAM.
--Initialize RAM which carries LSB 2 bits of the data.
RAM1 : RAMB16_S2 port map (
DO => Dout(1 downto 0),
-- 2-bit Data Output
ADDR => ADDR, -- 13-bit Address Input
CLK => CLK,
-- Clock
DI => Din(1 downto 0),
-- 2-bit Data Input
EN => EN,
-- RAM Enable Input
SSR => SSR,
-- Synchronous Set/Reset Input
WE => WE
-- Write Enable Input
)
--Initialize RAM which carries MSB 2 bits of the data.
RAM2 : RAMB16_S2 port map (
DO => Dout(3 downto 2),
-- 2-bit Data Output
ADDR => ADDR, -- 13-bit Address Input
CLK => CLK,
-- Clock
DI => Din(3 downto 2),
-- 2-bit Data Input
EN => EN,
-- RAM Enable Input
SSR => SSR,
-- Synchronous Set/Reset Input
WE => WE
-- Write Enable Input
);
--100 MHz clock generation for testing process.
clk_process : process
begin
wait for 5 ns;
clk <= not clk;
end process;
--Writing and Reading RAM.RAM has a depth of 13 bits and has a
width of 4 bits.
simulate : process
begin
en <='1';
we <= '1';
--Write the value "i" at the address "i" for 10 clock
cycles.
for i in 0 to 10 loop
addr <= conv_std_logic_vector(i,13);
din <= conv_std_logic_vector(i,4);
wait for 10 ns;
end loop;
we<= '0';

--Read the RAM for addresses from 0 to 20.


for i in 0 to 20 loop
addr <= conv_std_logic_vector(i,13);
wait for 10 ns;
end loop;
end process;
end Behavioral;
Posted by vipin at 10:08 PM

Reactions:
Labels: xilinx tips
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

11

).

LoadPages

THURSDAY, AUGUST 5, 2010

Random number generator in VHDL(cont from a prev post)


This post is a continuation of my previous post about random number generator in VHDL.I have used
a LFSR(Linear feedback shift register) for creating a random sequence last time.But thanks to one of
my blog readers, Chris, the code given in that post was partially wrong.The problem was that the tap
values I have taken for feeding back the shift register was wrong.This resulted in a non-maximum length
sequence.For example as Chris pointed out, in the older code, when the register size is 32 bits the
sequence period is 2^21-1 and not 2^32-1 as claimed.
So I have written another code which uses the correct tap values to ensure that the sequence
generated is of maximum length.The project is uploaded at opencores.org and can be downloaded for
free.The code take cares of register sizes from 3 bit to 168 bits.The tap values were referred from a Xilinx
documentation about LFSR.
The project can be downloaded from here.After downloading extract the contents of the file.The codes
and documentation is available in the folder named "trunk".
Currently the project is in alpha stage.Please let me know if you find any bugs in the code or any sort of
comments.
Hope the project is useful.
Posted by vipin at 11:12 AM

Reactions:
Labels: LFSR
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
ChrisAugust 8, 2010 12:05 PM
This code is actually done in a fairly nice way -- at least from the perspective of the function. My
biggest concern is the async load and async enables. Both can be async, which is almost
always a bad idea. Async signals need VERY careful attention to avoid errors. They are
particularly
good
at
destroying
state
machines
and
control
logic.
This is because there is data and clock skew, thus each LUT+FF that uses the async signal as
an input will receive each bit of the signal at a slightly different time. (or will get a clock edge at a
slightly
different
time)
For the LFSR case, initializing to something like 0001 can cause the design to fail. If load is
deasserted near a clock edge (at any clock rate), then the lsb might shift in a 0 (if load = 0 at this
FF). If the upper bits still have load asserted (eg, there is a longer delay from load to these FF's),
then they will stay 0's. Thus the LFSR will transition from 0001 to 0000. At this point, the LFSR is
stuck.
Also, async loads are often used in interview questions as something to avoid.
Reply
2.
vipinAugust 17, 2010 6:50 PM
@Chris: As per your comments I have modified the code a little and have uploaded the new
version.
Please
check
it
out.
I
have
removed
the
input
"out_enable"
as
it
is
not
necessary.
Also the setting the seed functionality is made synchronous instead of asynchronous.
Reply
3.
music champDecember 19, 2010 12:27 AM
can
u
please
thanx in advance

provide

me

code

for

binary

multiplier.......

Reply
4.
MattSeptember 13, 2011 8:28 PM
Mr.

Vipin,

I have implemented this module in order to produce white noise as an audio source, but the
frequency
response
I
am
getting
is
not
flat.
The low end is cut off and rises inverse-exponentially to a flat PSD at around 8kHz (Fs =
44100Hz).
Therefore
the
white
noise
sounds
very
high-pass
filtered.
Do you have any idea why this is happening? I have tried with different word lengths and seed

values

without

any

Here
is
a
link
showing
http://www.photostand.co.za/images/934h5nswi8annoh10xr.png

luck.
the

PSD:

Thank you!
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

12

).

LoadPages

SUNDAY, JULY 25, 2010

Binary counter IP core in Xilinx Core Generator


Even though a custom VHDL program can be written very easily for a
counter, Xilinx Core Generator provides free Counter IP core.This can be used
if you want to save time and your code need many extra functionality. The
counter can be up to 256 bits wide.
This tutorial is for binary counter version 11.0 and I am using xilinx 12.1 webpack for
this project.But without any major changes you can follow the same rules for other
versions of the IP.
The counter IP can be viewed under the category , Basic elements -> Counters.I have
written a tutorial earlier, on how to create a core generator project and about its
simulation. If this is your first project using Core generator then I suggest you go
through it first . It is availablehere.
Now double click on the binary counter IP, for setting the generic parameters
as required.A new window similar to the one shown below will show up:

Now I will go through the general settings and their meaning.


1)Component name : Name of the module you want .
2)Implement using : You have two options here DSP blocks and fabric. If you select
DSP then the Core generator will use the in built DSP blocks available in the FPGA chip
for making the counter. Selecting Fabric will result in only usage of available Look up
tables and flip flops. If you want the counter to be very wide enough then select the
Fabric option.
3)Output width : Width of the counter output. If you choose n then the counter can
count up to the max value value 2^n-1.
4)Increment value : This is the value by which counter value gets incremented or
decremented in each step.
5)Loadable : If you want the counter value to be changed at any stage make it
loadable.This will introduce a std_logic and a std_logic_vector input in the IP port
list.When load=1 the value available at the input std_logic_vector port will replace the
counter value after some latency cycles.
6)Restrict Count : Fix a maximum count value.Use this if your final count value is not
2^n-1.
7)Count mode: You have three options UP,DOWN and UPDOWN. They have their
usual meanings with respect to a counter.
8)Sync Threshold output : If you select this then when the count value is equal to the
Threshold value given, the std_logic signal will go high for one clock cycle.
9)Clock Enable : Enables the clock.This input should be high for the core to work
properly.This is also an example of gated clock.
10)Synchronous clear : Clear the output at the clock edge when activated.
11)Synchronous set : Set the output at the clock edge when activated.
12)Synchronous Init : Initialize the count value(output) at the clock edge when
activated.Initialization value can be set by you.
13)Power-on reset init value : The count value when the module is switched ON.

14)Latency configuration : Give the latency(delay). Select automatic for optimal


latency settings.
I have tested some of the features of the IP core. The settings I have used are given in
the image shown above. The testbench code I have used is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity blog_cg is
end blog_cg;
architecture Behavioral of blog_cg is
signal clk,sset,load,thresh0 : std_logic:='0';
signal l,q : std_logic_vector(2 downto 0):="000";
component counter IS
port (
clk: IN std_logic;
sset: IN std_logic;
load: IN std_logic;
l: IN std_logic_VECTOR(2 downto 0);
thresh0: OUT std_logic;
q: OUT std_logic_VECTOR(2 downto 0));
END component;
begin
UUT : counter port map(clk,sset,load,l,thresh0,q);
--Generate 2 ns clock.
clock : process begin
clk <= '0';
wait for 1 ns;
clk <= '1';
wait for 1 ns;
end process;
--Generate the required inputs for testing/simulation.
simulate : process begin
wait for 3 ns;
sset<='1';
wait for 2 ns;
sset<='0';
load <='1';
l<="101";

wait for 2 ns;


load <= '0';
l<="000";
wait;
end process;
end Behavioral;

Here is the simulation waveform:

If you look carefully, you can notice that there is a delay of one clock cycle in affecting the output value
after applying sset and load control signals.This is the latency value the I made "automatic" in the IP core
setting.If you make it manual, then this delay can be set as per your wish.
Posted by vipin at 11:03 PM

Reactions:
Labels: core generator
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

13

).

LoadPages

SATURDAY, JULY 24, 2010

KEEP HIERARCHY : A synthesis option in XST.


For those who doesnt know about what this topic about, I am trying to talk about the "keep hierarchy"
option available in the xilinx synthesis options.This option along with many other options can be viewed
or changed by going through the following steps:
1)Right clicking on the synthsis-XST in the processes tab.
2)Click on Properties to get the window shown below in the image.
3)Click on synthesis options in the category side.
4)Look down on the right side of the window for the "Keep Hierarchy" option and change it to No or yes.

Now I want to list out some points about this "Keep Hierarchy" option:
1)This particular option is used for designs which has more than one VHDL code in the design.I mean a
design which may contain a top module and some components.
2)Whenever the XST starts synthesis process it tries to optimize the design for the particular selected
architecture.Now when we select the option as "keep hierarchy yes" then XST will only optimize by
taking each component at a time.This is faster in terms of synthesis time but optimization has limited
reach.
3)when we select the option as "keep hierarchy no" then XST will optimize the whole design at one
single pass.This is time consuming but results in better optimization results.
Let me prove the above points with the help of an example.The code I have used is already published in
this blog.It is "4 bit Synchronous UP counter(with reset) using JK flip-flops".
I copied these codes into a new project directory and synthesized the design using the option "Keep
Hierarchy: yes" first. The following synthesis results were showed up:
Device utilization summary:
--------------------------Selected Device : 5vlx30ff324-3
Slice Logic Utilization:
Number of Slice Registers:
Number of Slice LUTs:
Number used as Logic:

4 out of 19200 0%
6 out of 19200 0%
6 out of 19200 0%

Slice Logic Distribution:


Number of LUT Flip Flop pairs used: 10
Number with an unused Flip Flop:
6 out of 10 60%
Number with an unused LUT:
4 out of 10 40%
Number of fully used LUT-FF pairs: 0 out of 10 0%
Number of unique control sets:
4
Minimum period: 1.565ns (Maximum Frequency: 639.141MHz)

Now I ran the XST again with the option "Keep Hierarchy: no".This time I got different results:
Slice Logic Utilization:
Number of Slice Registers:
Number of Slice LUTs:
Number used as Logic:

4 out of 19200 0%
4 out of 19200 0%
4 out of 19200 0%

Slice Logic Distribution:


Number of LUT Flip Flop pairs used:
8
Number with an unused Flip Flop:
4 out of
Number with an unused LUT:
4 out of
Number of fully used LUT-FF pairs: 0 out of
Number of unique control sets:
3

8 50%
8 50%
8 0%

Minimum period: 1.101ns (Maximum Frequency: 908.348MHz)


You can see that there is a 300 MHz increase in the operating frequency when the hierachy is not
kept.Even the resource usage become minimal in the second case.
Another observation you can make is from the Technology Schematic viewer in XST. For the first case the
RTL viewer will show you sub blocks in the main block which may contain LUT's and flipflops.But in the
second case there wont be any sub blocks available at all.Only LUT's and flipflops will be available
directly under the main block.This is what I meant by saying that the XST will optimize the design taking
as a whole.You can verify this yourself by clicking on the "View Technology schematic" option under
synthesis-XST.
Posted by vipin at 4:41 PM

Reactions:
Labels: xilinx tips
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
UnknownApril 22, 2012 9:03 AM
Your example is too simple. In my case, keeping hierarchy was slower by 20%, as the final
design had to route signals further on the FPGA fabric, and use higher fan-outs.
I think that not keeping hierarchy only makes sense if you are running short on resources...
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

14

).

LoadPages

MONDAY, JUNE 14, 2010

How to use Core generator to build IP cores?


The CORE Generator is a design tool that delivers parameterized Intellectual Property (IP) designs

optimized for Xilinx FPGAs.The CORE Generator provides ready-made functions which includes the
following:
-FIFOs and memories
-Communication IP's
-IIR and FIR filters
-FFTs
-Standard bus interfaces such as PCI and PCI-X,
-Connectivity and networking interfaces (Ethernet, SPI-4.2, RapidIO, CAN and PCI Express)
IP cores supporting many basic functions are included with the CORE Generator software and do not
require a license key. More complex system level cores require purchase and installation of an additional
license key.
The below image shows the core generator GUI.

In the image the numbers indicates the different parts of the interface.
1-Title Bar
2-Menu Bar
3-IP Selection Window
4-Toolbar
5-Information Window
6-Transcript Window
7-Status Bar
Let us learn how to generate an IP, in core generator.For example take the simplest IP, comparator.As
per the datasheet, The comparator is used to create comparison logic that performs many functions such
as A = B, A < B, A <=B etc. A and B are external ports of up to 256 bits wide and B can optionally be set
to a constant value.There many other options available. Refer to data sheet for more.
Follow the steps for generating an IP core:
1)Go to Menu bar and select File -> New project.Type in the project name and select the device you want
the IP core to be generated along with other options.
2)Once the project is created click on "View by Function" to get the above shown type of image.
3)Then click on basic elements category in the IP selection window.
4)Select comparators,then double click on "comparator".In the image shown above I have comparator
version 9.0.You may have a higher or lower version.But that doesnt make much difference.
5)The Comparator IP page where you can change the settings of the IP will look like this:

Type the component name as "mycomparator".In the example we want to check whether a signed signal
"a" is less than "b".The width(size) of the signal is 20 bits.Select Non-registered output.To know the
detailed explanation of these settings click on "View Data sheet".Click on Next to go to page 2.
6)Leave the settings on this page as such and click on Finish button.The software will now generate the
core as shown in the below image.

7)The following files will be generated for 'mycomparator' in the specified directory:
mycomparator.ngc:
Binary Xilinx implementation netlist file containing the information required to implement the module in a
Xilinx (R) FPGA.
mycomparator.vhd:
VHDL wrapper file provided to support functional simulation. This file contains simulation model
customization data that is passed to a parameterized simulation model for the core.
mycomparator.vho:
VHO template file containing code that can be used as a model for instantiating a CORE Generator
module in a VHDL design.
mycomparator.xco:(this is the file to be added to your main project)
CORE Generator input file containing the parameters used to regenerate a core.
mycomparator_xmdf.tcl:
ISE Project Navigator interface file. ISE uses this file to determine how the files output by CORE
Generator for the core can be integrated into your ISE project.
mycomparator_c_compare_v9_0_xst_1.ngc_xst.xrpt,mycomparator_flist.txt,mycomparator_readm
e.txt etc.
8)Now let us see how you can use this core in your main design code.

Suppose I have a vhdl code where i want to use this 20 bit comparator as a component.Then what you
have to do is, open the generated vhd file by core generator and copy the below type content.
port (
a: IN std_logic_VECTOR(19 downto 0);
b: IN std_logic_VECTOR(19 downto 0);
a_lt_b: OUT std_logic);
We need the port declaration for instantiating comparator.Add these lines to the main code as shown like
this:
component mycomparator
port (
a: IN std_logic_VECTOR(19 downto 0);
b: IN std_logic_VECTOR(19 downto 0);
a_lt_b: OUT std_logic);
end component;
9)Now right click on the Xilinx ISE project in Xilinx Window and click on Add source file.Select the
"mycomparator.xco" file generated before.
10)Now run the code as usual.
Note :- This is just an example of how to use Core generator in general.The actual settings of different
IP's may be very much different and I recommend you to go through the data sheet for specific
functionalities.For any doubt contact me.
Posted by vipin at 3:28 PM

Reactions:
Labels: core generator
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
GuruMay 16, 2012 3:10 AM
I
1.code
2.code

have
for
CUT(circuit

for

have
1.how
2.how
3.how

two
generating
under
test,it
can

the
to
to

to

codes
pattern
circuit)

simple

foolowing

to
incorporate
test
manually introduce
SA0/SA1/Delay
show
that
the
CUT
is
fault

hope
thanks in advance

different
test
be
any

get

doubts,

patterns
into
CUT
fault in
selected
test points
after
introducing
manual
fault
your

guidance.

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

15

).

LoadPages

MONDAY, APRIL 26, 2010

How to implement State machines in VHDL?


A finite state machine (FSM) or simply a state machine, is a model of behavior composed of a finite
number of states, transitions between those states, and actions.It is like a "flow graph" where we can see
how the logic runs when certain conditions are met.
In this aricle I have implemented a Mealy type state machine in VHDL.The state machine bubble
diagram in the below figure shows the operation of a four-state machine that reacts to a single input
"input" as well as previous-state conditions.

The code is given below:

library ieee;
use IEEE.std_logic_1164.all;
entity mealy is
port (clk : in std_logic;
reset : in std_logic;
input : in std_logic;
output : out std_logic
);
end mealy;
architecture behavioral of mealy is
type state_type is (s0,s1,s2,s3); --type of state machine.
signal current_s,next_s: state_type; --current and next state
declaration.
begin
process (clk,reset)
begin
if (reset='1') then
current_s <= s0; --default state on reset.
elsif (rising_edge(clk)) then
current_s <= next_s;
--state change.
end if;
end process;

--state machine process.


process (current_s,input)
begin
case current_s is
when s0 =>
--when current state is "s0"
if(input ='0') then
output <= '0';
next_s <= s1;
else
output <= '1';
next_s <= s2;
end if;
when s1
if(input
output
next_s
else
output
next_s
end if;

=>;
--when current state is "s1"
='0') then
<= '0';
<= s3;
<= '0';
<= s1;

when s2 =>
--when current state is "s2"
if(input ='0') then
output <= '1';
next_s <= s2;
else
output <= '0';
next_s <= s3;
end if;
when s3 =>
if(input
output
next_s
else
output
next_s
end if;
end case;
end process;

--when current state is "s3"


='0') then
<= '1';
<= s3;
<= '1';
<= s0;

end behavioral;
I think the code is self explanatory.Depending upon the input and current state the next state is
changed.And at the rising edge of the clock, current state is made equal to next state.A "case" statement
is used for jumping between states.
The code was synthesised using Xilinx XST and the results are shown below:

--------------------------------------------------------States
Transitions
Inputs
Outputs
Clock
Reset
Reset type
Reset State
Power Up State
Encoding
Implementation

4
8
1
4
clk (rising_edge)
reset (positive)
asynchronous
s0
s0
Automatic
LUT

--------------------------------------------------------Optimizing FSM on signal with Automatic encoding.


------------------State | Encoding
------------------s0 | 00
s1 | 01
s2 | 11
s3 | 10
------------------Minimum period: 0.926ns (Maximum Frequency: 1080.030MHz)
Minimum input arrival time before clock: 1.337ns
Maximum output required time after clock: 3.305ns
Maximum combinational path delay: 3.716ns
The technology schematic is shown below:

As you can see from the schematic, XST has used two flipflops for implementing the state
machine.The design can be implemented in hardware using many FSM encoding algorithms.The
algorithm used here is "Auto" which selects the needed optimization algorithms during the synthesis
process.Similarly there are other algorithms like one-hot,compact,gray,sequential,Johnson,speed1
etc.The required algorithm can be selected by going to Process -> Properties -> HDL options -> FSM
encoding algorithm in the main menu.Now select the required one, from the drop down list.
More information about these options can be found here.
A very popular encoding method for FSM is One-Hot, where only one state variable bit is set, or "hot," for
each state.The synthesis details for the above state machine implementation using One-hot method is
given below:
Optimizing FSM on signal with one-hot encoding.
-------------------

State | Encoding
------------------s0 | 0001
s1 | 0010
s2 | 0100
s3 | 1000
------------------Minimum period: 1.035ns (Maximum Frequency: 966.464MHz)
Minimum input arrival time before clock: 1.407ns
Maximum output required time after clock: 3.418ns
Maximum combinational path delay: 3.786ns
The Technology schematic is shown below:

The main disadvantage of One-hot encoding method can be seen from the schematic.It uses 4 flip
flops while, binary coding which is explained in the beginning of this article, uses only 2 flip flops.In
general, for implementing a (2^n) state machine , binary method take n-flip flops while one hot
method takes (2^n) flip flops.
But there are some advantages with one-hot method:
1)Because only two bits change per transition, power consumption is small.
2)They are easy to implement in schematics.
Posted by vipin at 9:20 AM

Reactions:
Labels: state machine
Email ThisBlogThis!Share to TwitterShare to Facebook

14 comments:
1.

melenithApril 26, 2010 2:41 PM


Can you please clarify what does &lt and &gt stand for in code ?
Reply
2.
vipinApril 26, 2010 2:49 PM
@melenith: sorry for the mistake.That was a problem with the syntax highlighter I have used.I
have
fixed
it.Please
check
again.

Thanks for pointing out the mistake.


Reply
3.
FredrikApril 29, 2010 8:00 PM
very nice blog! keep up the good work :)
Reply
4.
NadavMay 5, 2010 1:03 AM
When I write VHDL or Verilog I like to use automated tools. C-to-Verilog.com is a website which
allows you to compiler your C code into hardware circuits. It has a great pipelining algorithm for
superb performance.
Reply
5.
marvin2kMay 19, 2010 7:21 PM
Hi,
thanks

for

all

the

explanations,

great

work!

Do you know if it's possible to create some of the "Technology schematic" Graphs from the
commandline? Something which could work out of a Makefile, perhaps...
Reply
6.
RafaelOctober 29, 2010 8:15 AM
Hi,
I

guys!
have

Can
I

to

make

anybody
even

don't

vhdl

project

help
know

what

to

me,
vhdl

my

engineering
with

is

exactly

course...

suggestions?
able

to

do...

Tks!
Reply
7.
foamFebruary 8, 2011 9:19 AM
State machines are easier to design, maintain, etc. when kept in a single process, and are also
less error-prone.

Reply
8.
vipinFebruary 8, 2011 9:28 AM
@foam : I do agree. See this post. I have did
http://vhdlguru.blogspot.com/search/label/state%20machine

it

with

single

process.

Reply
9.
rajFebruary 17, 2011 3:09 AM
can i get one hot code for FSM using 9 state flip flops in behavioral and structural
Reply
10.
vipinFebruary 17, 2011 9:00 AM
@raj : Please see the above example and code it yourself. I only do customized codes for a fee.
Reply
11.
xyzOctober 31, 2011 10:43 AM
This comment has been removed by the author.
Reply
12.
RithDecember 6, 2011 11:20 AM
Can
Thanks

plz

post

testbench

code

for

this

fsm.

Reply
13.
mitbalApril 25, 2012 12:55 PM
Why can't you just use one signal to remember the state instead of two? Like signal_state
instead of current_s and next_s, and assign the next state according the current value of
signal_state.
What

is

the

Thank you very much...


Reply

difference?

Would

you

care

to

explain?

14.
blogzworldMay 21, 2012 9:15 PM
Can you explain the state machine too.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

16

).

LoadPages

MONDAY, APRIL 19, 2010

8 bit Binary to BCD converter - Double Dabble algorithm


I have written a function for converting a 8-bit binary signal into a 12 bit BCD ( consisting of 3 BCD
digits).An algorithm known as "double dabble" is used for this.The explanation for the algorithm can be
found here.
The function code is given below:

function to_bcd ( bin : std_logic_vector(7 downto 0) ) return std_l


ogic_vector is
variable i : integer:=0;
variable bcd : std_logic_vector(11 downto 0) := (others => '0');
variable bint : std_logic_vector(7 downto 0) := bin;
begin
for i in 0 to 7 loop -- repeating 8 times.
bcd(11 downto 1) := bcd(10 downto 0); --shifting the bits.
bcd(0) := bint(7);
bint(7 downto 1) := bint(6 downto 0);
bint(0) :='0';
if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is
greater than 4.
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is
greater than 4.
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 7 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit
is greater than 4.
bcd(11 downto 8) := bcd(11 downto 8) + "0011";

end if;
end loop;
return bcd;
end to_bcd;
Some sample inputs and the corresponding outputs are shown below:
bin = "01100011" , output = "0000 1001 1001" (99).
bin = "11111110" , output = "0010 0101 0100" (254).
bin = "10111011" , output = "0001 1000 0111" (187).
The code is synthesisable, and the cell usage statistics for Virtex-5 FPGA is shown below:
# BELS
#
GND
#
LUT3
#
LUT4
#
LUT5
#
LUT6
#
MUXF7
# IO Buffers
#
IBUF
#
OBUF

: 24
:1
:1
:2
: 12
:7
:1
: 20
:8
: 12

Note :- The code can be modified to convert any length binary number to BCD digits.This require very
little change in the code.
Posted by vipin at 2:22 PM

Reactions:
Labels: BCD converter
Email ThisBlogThis!Share to TwitterShare to Facebook

16 comments:
1.
marvin2kMay 21, 2010 4:32 PM
Hi,
is it possible to create these netlist-graphics from the command-line using xilinx tools?
Reply
2.
vipinMay 21, 2010 4:35 PM
@marvin2k
:
See
this
link
http://www.xilinx.com/itp/xilinx4/data/docs/xst/command_line9.html
Reply

from

xilinx.

3.
marvin2kMay 21, 2010 4:52 PM
@vipin: this is to synthesize a design? I meant something like the "RTL Viewer" mentioned in
other posts (sorry, in fact I wanted to post in another blogentry of your blog...) to view the
generated netlist.
Reply
4.
vipinMay 21, 2010 4:55 PM
There
is
a
command
like
this
in
that
link
:
run -ifn watchvhd.vhd -ifmt VHDL -ofn watchvhd.ngc -ofmt NGC -p xcv50-bg256-6 -opt_mode
Speed
-opt_level
1
This will generate the ngc file.You have to open this file with a xilinx ngc file viewer.
Reply
5.
marvin2kMay 21, 2010 5:39 PM
Yes, and my question was if one can invoke such a tool from the commandline... sorry for this
much text...
Reply
6.
vipinMay 21, 2010 5:42 PM
I havent explored command line options till.I guess you should try whatever is given in that
link.Also share your experience here.
Reply
7.
rourabNovember 15, 2010 4:06 PM
could we make it for n bit??
Reply
8.
vipinNovember 15, 2010 4:21 PM
@rourab : yes. you just have to understand the concept.you can make it for n bit. But the code
will be more complicated.
Reply

9.
rourabNovember 16, 2010 12:47 PM
function to_bcd ( bin : std_logic_vector((n-1) downto 0) ) return std_logic_vector is
variable
i
:
integer:=0;
variable
j
:
integer:=1;
variable
bcd
:
std_logic_vector(((4*q)-1)
downto
0)
:=
(others
=>
'0');
variable
bint
:
std_logic_vector((n-1)
downto
0)
:=
bin;
begin
for
i
bcd(((4*q)-1)
bcd(0)
bint((n-1)
bint(0)

in
0
downto
downto

to
1)

:=

n-1
loop
bcd(((4*q)-2)
:=
1)
:=

-downto

repeating
8
times.
0);
--shifting
the
bits.
bint(n-1);
bint((n-2)
downto
0);
:='0';

l1:
for
j
in
1
to
q
loop
if(i < n-1 and bcd(((4*q)-1) downto ((4*q)-4)) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(((4*q)-1)
downto
((4*q)-4))
:=
bcd(((4*q)-1)
downto
((4*q)-4))
+
"0011";
end
end
end
return
end to_bcd;

if;
loop

l1;
loop;
bcd;

Reply
10.
rourabNovember 16, 2010 12:52 PM
the previous code i have written in generic form ,where q is the number bcd digit,in that case i
got the desire result up to 9 but when it exceed over 9 it gives the A,B,C,D,E,F. i cant get my
mistake,
Reply
11.
rourabNovember 16, 2010 5:32 PM
vipin i have solved my problem just replacing the q by j in the inner loop
Reply
12.
AleksandarNovember 19, 2010 8:05 AM
rourab, please, can you tell me which q you replaced by j in the inner loop?
I wrote similar code, but without generic parameter, and I had same problem (A,B,C..F).
Reply

13.
rourabNovember 19, 2010 11:14 AM
function to_bcd ( bin : std_logic_vector((n-1) downto 0) ) return std_logic_vector is
variable
i
:
integer:=0;
variable
j
:
integer:=1;
variable
bcd
:
std_logic_vector(((4*q)-1)
downto
0)
:=
(others
=>
'0');
variable
bint
:
std_logic_vector((n-1)
downto
0)
:=
bin;
begin
for
i
bcd(((4*q)-1)
bcd(0)
bint((n-1)
bint(0)

in
0
downto

to
1)

downto

:=

n-1
loop
bcd(((4*q)-2)
:=
1)
:=

-downto

repeating
8
times.
0);
--shifting
the
bits.
bint(n-1);
bint((n-2)
downto
0);
:='0';

l1:
for
j
in
1
to
q
loop
if(i < n-1 and bcd(((4*j)-1) downto ((4*j)-4)) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(((4*j)-1)
downto
((4*j)-4))
:=
bcd(((4*j)-1)
downto
((4*j)-4))
+
"0011";
end

if;

end
end
return
end

loop

l1;
loop;
bcd;
to_bcd;

this is my code
Reply
14.
AleksandarNovember 19, 2010 9:59 PM
rourab,
thank you very much, but I still have problem with this code, even when its generic.
I wanted to convert 24-bit binary to 32-bit bcd and I inserted your function into my code, where I
defined
q
:=
8,
because
(4*q)-1)
would
be
32
bits.
When
My

wanna

do

8-bit

bin

to

12-bit

bcd,

question

need

to

define

:=

3.
is:

What is relation between n and q, what is relation between number of bits for input (bin) and
number
of
bits
for
output
(bcd)?
Please, answer again...I am beginner and your little help is very great for me.
Sory for my bad english, i hope that you can understand me.
Reply
15.

AleksandarNovember 20, 2010 12:58 AM


I found answer for my question, but I need help for implementing that solution.
Relation

between

and

is

**********************************************
q
=

round(n*(log(2)))

where
q
must
be
rounded
**********************************************

to

greater

integer

for

!!!,
example:

for
q

n
=

=
round

24
(32*(log

and

(2)))=

round

it

(24*0.3010)=round

would
(7.224)=

be:
8

I need help for implement this calculus for generic parameter (I want to make automatic calculus
q
=
f(n)).
Is this possible to be done with "real" data type,could we use not-synthesizable data type for
generic parameter , to make synthesizable entity ?
Reply
16.
binduswethaerNovember 8, 2011 3:50 PM
how to implement for D-ALGORITHM IN TESTING OF VLSI CIRCUITS" IN VHDL OR
VERILOG?"
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

17

).

LoadPages

MONDAY, APRIL 19, 2010

Recursive functions in VHDL


In this article I will write about recursive functions in VHDL.Recursion is a method of defining functions
in which the function being defined calls itself. The idea is to execute a task in a loop, in a self similar way.
When comes to VHDL, you cannot blindly write a recursive code in your design.Recursive logic has the
disadvantage of eating up lot of resources in FPGA. I have explained these points with the help of an
example.
Let us see what is the objective of the code,I have written.Here I am doing repetitive XOR operation on
a 16 bit signal,until the result obtained is 2 bit. For example if the signal is "1111001100010101" ,then I am
doing the following steps:
MSB 8 bits of signal : 11110011
LSB 8 bits of signal : 00010101
XOR operation
: 11100110 ( call this signal as 'x1')

MSB 4 bits of x1 : 1110


LSB 4 bits of x1 : 0110
XOR operation : 1000 ( call this signal as 'x2')
MSB 2 bits of x2 : 10
LSB 2 bits of x2 : 00
XOR operation : 10 ( this should be the result obtained when the code is simulated)
Now normally if you want to do such a program you have to define a lot of temporary signals for x1,x2
etc.This makes the code more complicated and difficult to understand.
But to make the code short and simple ,you can write a recursive function like shown below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity recursion is
port ( num : in std_logic_vector(15 downto 0);
exor_out : out std_logic_vector(1 downto 0)
);
end recursion;
architecture Behavioral of recursion is
function exor( num : std_logic_vector ) return std_logic_vector is
variable numf : std_logic_vector(num'length-1 downto 0):=(others =>
'0');
variable exorf : std_logic_vector((num'length/2)-1 downto
0):=(others => '0');
begin
numf := num;
if(num'length = 4) then
exorf := numf(1 downto 0) xor numf(3 downto 2);
else
exorf := exor(numf(num'length-1 downto num'length/2)) xor exo
r(numf((num'length/2)-1 downto 0));
end if;
return exorf;
end exor;
begin
exor_out <= exor(num);
end Behavioral;
Now let us analyse the code.
1)function exor( num : std_logic_vector ) return std_logic_vector is :
The function is defined in a general sense.This means the function "exor" takes a std_logic_vector" of
any length as input and outputs another std_logic_vector.
2)variable numf : std_logic_vector(num'length-1 downto 0):=(others => '0');

This is the signal on which XOR operation has to be performed.The num'length attribute is used to get
the size of the input argument.This value is initialized to zero.
3)variable exorf : std_logic_vector((num'length/2)-1 downto 0):=(others => '0');
This is the result of XOR operation.The result always has half the size of the input.
4) if(num'length = 4) then
exorf := numf(1 downto 0) xor numf(3 downto 2);
else
exorf := exor(numf(num'length-1 downto num'length/2)) xor exor(numf((num'length/2)-1
downto 0));
end if;
On the 4th line, I am calling the function exor in a recursive way.Each time the function is called only
half of the signal gets passed to the function.The recursive call is continued until the size of the signal
becomes 4.Note that how, exor function calls itself , each time passing only a part of the input applied to
it until it reaches a critically small size(which is 4 here).
Now let us see how this code is synthesised.The Technology schematic view of the design is shown
below:

By analyzing the figure you can see that there are 4 LUT's used to implement the logic-Two 4 input
LUT's and two 5 input LUT's.the connection can be understood from the below block diagram:

From the figure you can see that for implementing the logic relativly more resources are used.This is
the disadvantage of recursive functions in VHDL. In C and other high level languages recursion is
implemented using stack and, there the main issue is stack overflow.But in a HDL like VHDL, the
resources may get heavily used for even simple codes.The synthesis tool implements the logic by
replicating the function in separate hardware components.This means that if a function calls 10 times

itself, then the resources will be used nearly 10 times than that , when an individual block is implemented.
The same thing if we implement with the help of a clock,then you need to use only two XOR
gates.But in that case the block will take 8 clock cycles to compute the output.But the recursive function
defined here uses more logic resources to compute the output in less time.
Note :- Use recursive functions when you have enough logic gates in your FPGA, and speed is your main
concern.
Posted by vipin at 11:13 AM

Reactions:
Labels: functions
Email ThisBlogThis!Share to TwitterShare to Facebook

5 comments:
1.
JosyJune 1, 2010 2:14 PM
I do not agree that recursive function programming uses more resources that the more used for loop or so. I have several simple examples where the recursive method generates the same
logic usage, but where the RTL diagram is much smaller and a lot easier to understand.
Reply
2.
vipinJune 1, 2010 3:18 PM
@Josy : I didnt say that recursive functions uses more logic gates than loops.They uses the
same amount of logic.But if you keep the logic clock controlled then the logic gate usage will be
lesser.
You can post some examples if you have.
Reply
3.
anubhavAugust 3, 2010 7:50 PM
@ josy - please post few examples about what you said
Reply
4.
WilliamOctober 23, 2010 11:57 PM
Why don't you use num directly in place of numf?
Reply
5.
vipinOctober 24, 2010 12:07 AM

@William : you can use num.I just used numf. There is no particular reason behind it.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

18

).

LoadPages

WEDNESDAY, APRIL 14, 2010

VLSI Interview Questions - Part 2


This is part -2 of the interview questions series.Hope it is useful.
1)For the circuit shown below, what should the function F be, so that it produces an output of the
same frequency (function F1), and an output of double the frequency (function F2).

a. F1= NOR gate and F2= OR gate


b. F1=NAND gate and F2= AND gate
c. F1=AND gate and F2=XOR gate
d. None of the above
Ans : (d) . (Hint : Assume a small delta delay in the NOT gate).
2)The maximum number of minterms realizable with two inputs (A,B) is:
Ans : For n bits the max number minterms is, (2^n).
For n=2, no. of minterms = (2^2) = 4.
http://www.iberchip.net/VII/cdnav/pdf/75.pdf
3)The maximum number of boolean expressions with two inputs (A,B) is:
Ans : For n bits the max number boolean expressions are, 2^(2^n).
For n=2, no. of boolean expressions = 2^(2^2) = 2^4 = 16.
http://www.iberchip.net/VII/cdnav/pdf/75.pdf
4) A ring counter that counts from 63 to 0 will have ______ D flip-flops,
but a binary counter that counts from 63 to 0 will have _____ D flip-flops
Ans : For ring counter 64. for binary counter 6.
5) Why cache memory is used in computers?
Cache memory is used to increase the speed of memory access by processor.Unlike the
main(physical) memory cache memory is small and has very short access time.The most recent data
accessed by processor is stored in cache memory.This will help the processor to save time bacause time
is not wasted in accessing the same data from the main memory again and again.
A good example is that ,if processor is executing a loop 1000 times involving many variables(so that the
CPU registers available are all used up) then the value of these variables can be stored in cache
memory.This will make the loop execution faster.
In designing cache, cache miss probability and hit probability determines the efficiency of the cache and
the extend to which the average memory access time can be reduced.

6) How will you design a sequence detector?


See this link:
http://web.cs.mun.ca/~paul/cs3724/material/web/notes/node23.html
7) What is setup time and holdtime?
Setup time is the minimum amount of time before the clocks active edge by which the data must be
stable for it to be detected correctly. Any violation in this will cause incorrect data to be captured.
(Analogy for setup time: Suppose you have to catch a train and the train leaves at 8:00.Say you live 20
minutes away from the station, when should you leave your house?
Ans : at 7:40 -> set up time is 20 mins in this case)
Hold time is the minimum amount of time after the clocks active edge during which the data must be
stable. Any violation in this required time causes incorrect data to be latched.
(Suppose your friend needs help in boarding the train and train only allows 5 mins for boarding.How long
should you stay after you have arrived?
Ans : Atleast 5 mins -> Hold time is 5 mins )
A very good tutorial with examples about setup time and hold time can be found at this link:
http://nigamanth.net/vlsi/2007/09/13/setup-and-hold-times/
8)What is the difference between Moore and Mealy state machines?
Ans : Moore and Mealy state machines are two ways of designing a state machine. Moore
state machines are controlled in such a way that the outputs are a function of the previous
state and the inputs. However, Mealy state machines are controlled in a way such that the
Outputs may change with a change of state OR with a change of inputs.A Moore state
machine may require more states(but less complexity) than a Mealy state machine to
accomplish the same task.
Posted by vipin at 4:56 PM

Reactions:
Labels: interview Q's
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:
1.
LeoDecember 30, 2010 1:28 PM
Hi
I

read

this

Pls
Let

try
me

Source: IT
Best
Jonathan.
Reply

post

show

other

times.

It

to
source

that
interview

is

very

keep
may

be

good

useful.
posting.

for

community.
questions
regards

2.
mishtiJune 22, 2012 11:12 AM
hi
For
Question
-2
The maximum number of minterms realizable with two inputs (A,B) is:2^n
which
comes
out
to
be
4.
There can be only four min terms for the input combinations:(0,0),(0,1),(1,0) and (1,1)
Please correct me if i am wrong.
Reply
3.
vipinJune 22, 2012 11:47 AM
Thanks mishti for noticing the error. I have updated it. See this link for more explanation.
http://www.iberchip.net/VII/cdnav/pdf/75.pdf
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

19

).

LoadPages

WEDNESDAY, APRIL 14, 2010

VLSI Interview questions - Part 1


Here are some common interview questions asked by some VLSI companies.Try to learn the concept
used in solving the questions rather than blindly going through the answers.If you have any doubts drop
me a note in the comment section.
1)Design a full adder using halfadders.
Ans :

2) Find the value of A,B,C in the following circuit ,after 3 clock cycles. (ST Microelectronics)

This is a simple Ring counter.An n-bit ring counter has n states.The 3-bit counter shown above has 3
states and they are : 100 , 010 , 001 , 100 and so on..
So after 3 clock cycles A,B,C = 100.
3) Design XOR gate using 2:1 MUX.

(Intel)

Ans :
4) If A=10 and B=20, without using temporary register how can you interchange the two things?
(Intel)
Ans :
Perform the following operations sequentially:
A = A xor B;
B = A xor B;
A = A xor B;
Now A=20 and B=10.
5)What is the expression for
output 'y' in the following circuit?

Ans : (In the notation I have used,A' means not(A), and AB means (A and B).
y = ( A'B'C + AB'C' + A'BC + ABC' )
= ( A'C (B+B') + AC' (B+B') )
= A'C + AC'
= A xor C.
6)The input combination to find the stuck at '0' fault in the following circuit is: (Texas Instruments)

Ans : X is always zero in the above circuit. So P is always zero whatever the value of A,B,C or D is.
To check the fault at X, make either inputs C or D zero, and A,B as '1'.So the input combination is "1101".
7)Consider a two-level memory hierarchy system M1 & M2. M1 is accessed first and on miss M2 is
accessed. The access of M1 is 2 nanoseconds and the miss penalty (the time to get the data from
M2 in case of a miss) is 100 nanoseconds. The probability that a valid data is found in M1 is 0.97.
The average memory access time is:
Ans : This question is based on cache miss and success probability.
Average memory access time = (Time_m1 * success_prob ) + ( (Time_m1 + Time_m2) * miss_prob)
= ( 2* 0.97 ) + ( (2+100) * (1- 0.97) )
= 1.94 + 3.06 = 5 ns.
8)Interrupt latency is the time elapsed between:
a. Occurrence of an interrupt and its detection by the CPU
b. Assertion of an interrupt and the start of the associated ISR
c. Assertion of an interrupt and the completion of the associated ISR
d. Start and completion of associated ISR.
Ans : (b). ISR means Interrupt service routine.
These are only some of the questions I have seen.More questions will be up soon.Get the updates
by subscribing to VHDLGURU.If you want answers, for questions related to VLSI,digital etc. then you
can contact me here.
Posted by vipin at 12:57 PM

Reactions:
Labels: interview Q's
Email ThisBlogThis!Share to TwitterShare to Facebook

5 comments:
1.
gregoNovember 5, 2010 6:46 PM
Hi
I

like

You

create

this
good

Please
Let

me

Source: Top
Best
Peter

post:

material

for

community.

keep
introduce

other

material

that

posting.
may

interview

be

good

for

net

community.
questions
rgs

Reply
2.
AlexMarch 14, 2011 12:29 PM
Are those real questions? Don't get me wrong, but they are too easy. Could you please post
more
complex
questions?
And thanks for your blog! There are some really useful posts here.
Reply
3.
vipinMarch 14, 2011 12:35 PM
@Alex : they are real questions. But depends on the VLSI company the complexity of the
question changes.
Reply
4.
SreekJune 21, 2011 12:13 PM
thanks for the Q&As
Reply

5.
Anuj Kumar MishraJuly 18, 2012 4:18 PM
Can u explain Question number 4 ......
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

20

).

LoadPages

WEDNESDAY, APRIL 14, 2010

What is a Gated clock and how it reduces power consumption?


Gated clock is a well known method for reducing power consumption in synchronous digital circuits.By
this method the clock signal is not applied to the flip flop when the circuit is in idle condition.This reduces
the power consumption.
In a digital corcuit the power consumption can be accounted due to the following factors:
1) Power consumed by combinatorial logic whose values are changing on each clock edge
2) Power consumed by flip-flops.

Of the above two, the second one contributes to most of the power usage.
A flip flop consumes power whenever the applied clock signal changes,due to the charging
and discharging of the capacitor.If the frequency of the clock is high then the power
consumed is also high.Gated clock is a method to reduce this frequency.
Consider the following VHDL code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity normalclk is
port( clk : in std_logic;
load : in std_logic;
i : in std_logic;
o : out std_logic
);
end normalclk;
architecture Behavioral of normalclk is
BEGIN
process(clk)
begin
if(rising_edge(clk)) then
if(load ='1') then
o <= i;
end if;
end if;
end process;
end Behavioral;
The code if synthesized will look like this:(RTL schematic on the left side and technology schematic on the
right side)

As you can see the clock is always applied to the flip flop and this results in considerable loss in power
due to frequent charging and discharging of the capacitor.
Now let us modify the above piece of code , by using gated clock.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity gatedclk is
port( clk : in std_logic;
load : in std_logic;
i : in std_logic;

o : out std_logic
);
end gatedclk;
architecture Behavioral of gatedclk is
signal gclk : std_logic;
BEGIN
gclk <= clk and load;
process(gclk)
begin
if(rising_edge(gclk)) then
o <= i;
end if;
end process;
end Behavioral;
The synthesized design will look like this:(RTL schematic on top and technology schematic on bottom)

Note the AND operation between load and clk signal.Here the clock to the flip flop "FD" is said to be
gated.The code's purpose is that ,the output has to change only when load is '1' at the rising edge of
clock.So it is useless to drive the flip flop when the load signal is '0'.If the load signal changes very rarely,
then the above gated clock code will result in a low power design.
Apart from the advantage of reducing power consumption it has some disadvantages :
1) As you can see when you use gated clock, the buffer used in of type IBUF (input buffer) .But when the
clock is not gated, synthesis tool uses BUFGP buffer ( which is faster and used normally as a buffer for
clocks).This may result in a small delay.
2) In a synthesis point of view the gate controller takes more area and make the design more
complicated.
Posted by vipin at 11:11 AM

Reactions:
Labels: gated clock
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
ChrisJuly 26, 2010 1:30 PM

Xilinx
This

has
type

several
of

code

guides
is,

talking

unfortunantly,

about
even

why
taught

this
in

is

some

bad

college

idea.
courses.

The issue is that you've moved the clock out of the low-skew global clock routing. This isn't really
that bad for most college designs -- 50MHz and slower designs are very easy to do on a V5. but
once you look at 250MHz+ designs, you start to notice that 2ns+ of skew is actually significant.
Another issue is that you must make sure the clock enable meets setup/hold times for the clock.
otherwise (with skew) some elements may get clocked, others might not. In this case, that
means
that
"load"
must
be
synchronous
to
clk.
for an FPGA, its probably better to use BUFGMUX, BUFG_CTRL, or BUFG_CE, as these use
the global routing. the comments about setup/hold for the "enable" still apply though.
Reply
2.
Northstar75September 7, 2011 3:36 AM
The principle of using gated clocks comes originally from ASIC design where the designer has
full control over signal path delays, setup and hold times, etc. In an FPGA however, i would
rather
not
use
it
unless
one
is
begging
for
trouble.
First of all, it's not needed. Using the enable input of the flip-flop will archive the same but the
timing analysis will not be compromised. Concerning the power consumption, it's the switching
of the flip-flop which uses power. So it terms of power consumption it makes no difference
disabling
the
clock
or
just
not
enabling
the
flip-flop.
Second, combinatorial logic doesn't have a clock, it changes if the input values change and this
input values normally come from flip-flops. If the flip-flop doesn't change the combinatorial logic
won't
change
either.
Beside the fact that a design with gated clocks will use more resoures as you've shown in the
RTL schematic, there's a much more important point. You'r timing behaviour can/will become
unpredictable. Because in an FPGA it's not only about the RTL level, there are also the path
delays after Place&Route. The global lines in an FPGA have a kind of "fixed" and predictable
delay. Using combinatorial logic to gate the clock means using some input signal to control/gate
the clock. And this signal is routed via the normal routing network, which means the timing will
change with every P&R. So a perfectly working design might not work the next time you change
something and go through synthesis and P&R again, even if your change is completely
unrelated
to
the
part
with
the
gated
clock.
So unless you want to go through really nasty debugging sessions with a high propability of not
finding the cause of your problems,stay away from gated clocks in FPGAs and other
programmable devices!
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

21

).

LoadPages

TUESDAY, APRIL 13, 2010

Synchronous Vs Asynchronous resets in VHDL


In your design you may need to initialize all your signals to a predetermined state.This is done by
applying a reset signal.A reset signal can change the system in two ways: Synchronous and

asynchronous.In this article I have tried to explain the advantages and disadvantages of both the
methods and how exactly it is implemented in hardware.

Synchronous Reset :
A synchronous reset signal can be applied as shown below :

process(clk)
begin
if(rising_edge(clk)) then
if(reset = '0') then --reset is checked only at the rising edge of
clock.
o <= i;
else
o <= '0';
end if;
end if;
end process;
The code is synthesised to the following block in FPGA: (truth table of FDR flip flop is also given)

In the schematic diagram FDR is a single D-type flip-flop with data (D) and synchronous reset (R) inputs
and data output (Q). The synchronous reset (R) input, when High, overrides all other inputs and resets
the Q output Low on the 0 to 1 clock (C) transition. The data on the D input is loaded into the flip-flop
when R is Low during the 0 to1 clock transition.If you analyze the above code you can see that the value
of reset changes the signal 'o' only at the rising edge of the clock.This method has the
following advantages:
1)The reset applied to all the flip-flops are fully synchronized with clock and always meet the reset
recovery time.
2)In some cases, synchronous reset will synthesis to smaller flip-flops.
Synchronous resets have some disadvantages also:
1)If the reset applied is for a small duration then the clock edge may not be able to capture the
reset signal.Thus if you are synchronous resets make sure that your reset signal stays active for enough
time so that it get captured by the clock.
2)Also the change in reset doesn't immediately reflect in the associated signals.

Asynchronous reset :
Now let us have a look at the asynchronous reset :

process(clk,reset)
begin
if(reset = '0') then --change in reset get immediately reflected
on signal 'o'.
if(rising_edge(clk)) then
o <= i;
end if;
else
o <= '0';

end if;
end process;
The code is synthesised to the following in FPGA. (the truth table of the particular flip-flop is also given)

In the schematic FDC is a single D-type flip-flop with data (D) and asynchronous clear (CLR) inputs and
data output (Q). The asynchronous CLR, when High, overrides all other inputs and sets the Q output Low.
The data on the D input is loaded into the flip-flop when CLR is Low on the 0 to 1 clock transition.If you
analyse the code you can see that when the reset goes high , immediately signal 'o' will become
'0'.It doesn't wait for clock change.Now let us look at the advantages of this method:
1)High speed can be achieved.
2)Data can be reset without waiting for the clock edge.
The disadvantages are:
1) Asynchronous resets have metastability problems. By metastability what I mean is that,the clock and
reset have no relationship.So if the reset changes from 1 to 0 at the rising edge of the clock, the output is
not determinate. The reset input has to follow the reset recovery timerule.This time is a kind of setup
time condition on a flip-flop that defines the minimum amount of time between the change in reset signal
and the next rising clock edge.If the signal doesn't follow this set up time then it may create metastability
problems.
Note :- As you can see both the methods have their own advantages and disadvantages.And selecting
one of the method depends upon your design requirement.There is another method of resetting the
signals known as "Asynchronous Assertion, Synchronous De-assertion" which is the best method of
resetting signals.This will be discussed in the next article.
Posted by vipin at 8:18 PM

Reactions:
Labels: resets
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
ChrisJuly 26, 2010 10:44 AM
the other advantage to synchronous resets is that the synchronous set (for FPGAs) can now be
used
by
logic.
Xilinx
has
a
whitepaper
on
this.
a large disadvantage is that it is a large net, and can limit clock rate unless pipelined. This can
be
an
issue
for
coregen/other
IP.
some elements, like DSP48's, only have sync resets.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

22

).

LoadPages

TUESDAY, APRIL 13, 2010

Process sensitivity list Vs Synthesis-ability


For some of you this is a common error while synthesisng the code :
"One or more signals are missing in the process sensitivity list". In this article I will explain if there is any
relation between the process sensitivity list and synthesis results.
Let us take an example.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity blog1 is
port( a,b : in unsigned(3 downto 0);
c,d : out unsigned(3 downto 0);
clk : in std_logic;
rst : in std_logic
);
end blog1;
architecture Behavioral of blog1 is
BEGIN
--Synchronous process(some flipflop's are used for implementation)
process(clk,rst)
begin
if(rst = '1') then
c<="0000";
elsif(rising_edge(clk)) then
c<=a;
end if;
end process;
--combinational process(some LUT's are used for implementation)
process(a,b)
begin
d <= a and b;
end process;
end Behavioral;
The testbench code used for testing the functionality of the code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;

ARCHITECTURE behavior OF tb IS
--Inputs
signal a : unsigned(3 downto 0) := (others => '0');
signal b : unsigned(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
signal rst : std_logic := '0';
--Outputs
signal c : unsigned(3 downto 0);
signal d : unsigned(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.blog1 PORT MAP (
a => a,
b => b,
c => c,
d => d,
clk => clk,
rst => rst
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
b<="1111";
a<="1001";
wait for 20 ns;
a<="1010";
rst<='1';
wait for 30 ns;
rst<='0';
a<="1011";
wait;
end process;
END;
We will first check the simulation results for the above code.See the below image:

Ok. So the code is working well as per the simulation results. Now let us synthesis the code using Xilinx
ISE. Synthesis process also finished successfully.For your future reference make a copy of the synthesis
report somewhere.
Now let us make a small change in the process sensitivity list of the above code.
Use process(rst) instead of process(clk,rst).
Also use process(b) instead of process(a,b).
Simulate the design once more using the same testbench code. I am giving the waveform I got below:

What did you notice between the new waveform and old waveform. Since we have removed the "clk" and
"a" from the process sensitivity lists the output signals stopped changing with respect to changes in
inputs.So effectively the code is not working in the simulation.That is a big problem. But is this change
going to be reflected in the synthesis results also?
Let us synthesis the new design and see.We got the following warning after synthesis:
"One or more signals are missing in the process sensitivity list. To enable synthesis of FPGA/CPLD
hardware, XST will assume that all necessary signals are present in the sensitivity list. Please note that
the result of the synthesis may differ from the initial design specification. The missing signals are:".
Compare the new and old synthesis reports to check whether this warning has any effect on the synthesis
results. To your surprise you will see that there is no change in both the reports.Both the codes have
resulted in the same synthesis result.
So what about the warning? After going through some of the forums I found the folowing reasons:
1) Usually the behavior in the equations inside a process is what is intended, the sensitivity list is just a
bookkeeping chore.It doesnt have anything to do with synthesis.
2) Technically what XST(Xilinx synthesis tool) have implemented is not what your VHDL code says to do
as per the VHDL language definition. They are taking somewhat of a guess about what you really
intended to do.By violating the language specification they implement it the way they think you 'really'
want it and kick out a warning to let you know that the actual implementation will operate differently than
your simulation shows.
(Thanks to KJ)
Conclusion :- Sensitivity list has nothing to do with synthesis.But without the proper sensitivity list, the
process will not work in simulation.So as a good practice include all the signals which are read inside the
process, in the sensitivity result. The results may be varied if you are using some other tool.I have used
Xilinx ISE 12.1 version for the analysis.
Posted by vipin at 11:16 AM

Reactions:
Labels: sensitivity list, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:

1.
vipinApril 13, 2010 3:26 PM
A small note :- In spite of the fact that it does not give any errors it is not advisable to follow this
practice.Mentioning signals in the process sensitivity list will ensure that the logic is clearly
defined for the process.Also this will increase the readability of the program.
Reply
2.
zhensofaJune 29, 2010 5:15 AM
Do we need to include 'a 'in the sensitive list like this: process(clk,r,a)? Becasue the value of a is
assigned
to
b
if(rising_edge(clk))
b<=a;

then

Reply
3.
vipinJune 29, 2010 11:04 AM
@zhensofa : no, no need to include.if you are getting any warnings in this case then you can
ignore them.
Reply
4.
vipinSeptember 23, 2010 10:34 AM
Also remember that for a clocked process you may need not include the signals in the process
sensitivity list, which are read at the clock edge.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

23

).

LoadPages

THURSDAY, APRIL 8, 2010

Difference between rising_edge(clk) and (clk'event and clk='1')


Only few VHDL programmers know that there is something called "rising_edge()" function.Even those
who know about it, they still stick to the old fashioned clk'event and clk='1' method of finding an edge
transition of clock.So in this article I will explain the difference between rising_edge or falling_edge
function and clk'event based edge detection.
Consider the following snippet:

clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;

--for 0.5 ns signal is '0'.


--for next 0.5 ns signal is '1'.

process(clk)
begin
if(rising_edge(clk)) then
xr<= not xr;
end if;
if(clk'event and clk='1') then
x0 <= not x0;
end if;
end process;
If you run the above code the output will look like this:

Now you may ask where is the difference? There is no difference in this case.But let us see another
example:

clk_process :process
begin
clk <= 'Z';
----------Here is the change('Z' instead of
'0').
wait for clk_period/2; --for 0.5 ns signal is '0'.
clk <= '1';
wait for clk_period/2; --for next 0.5 ns signal is '1'.
end process;
process(clk)
begin
if(rising_edge(clk)) then
xr<= not xr;
end if;
if(clk'event and clk='1') then
x0 <= not x0;
end if;
end process;
Now the output will look like this:

Does this ring any bells?You can see that the signal 'xr' doesn't change at all,but x0 changes as in the first
code.Well this is the basic difference between both the methods.To get a clear view look at
the rising_edge function as implemented in std_logic_1164 library:

FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS


BEGIN
RETURN (s'EVENT AND (To_X01(s) = '1') AND
(To_X01(s'LAST_VALUE) = '0'));
END;
As you can see the function returns a value "TRUE" only when the present value is '1' and the last
value is '0'.If the past value is something like 'Z','U' etc. then it will return a "FALSE" value.This makes the
code, bug free, beacuse the function returns only valid clock transitions,that means '0' to '1'.All the rules
and examples said above equally apply to falling_edge() function also.
But the statement (clk'event and clk='1') results TRUE when the present value is '1' and there is an edge
transition in the clk.It doesnt see whether the previous value is '0' or not.
You can take a look at all the possible std_logic values here.
Note :- Use rising_edge() and falling_edge() functions instead of (clk'event and clk='1') statements in your
designs.
Posted by vipin at 8:22 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

7 comments:
1.
Bhargav A.KMarch 17, 2011 6:01 PM
WOW.... Ur GOOD.... I Never Knew This
Reply
2.
bhavesh mishraApril 26, 2011 10:05 PM
you have explained it beautifully !!
Reply
3.
Rob DDecember 27, 2011 12:19 PM

Thanks, This helped me out a lot!


Reply
4.
Rob DDecember 28, 2011 3:54 AM
This comment has been removed by the author.
Reply
5.
Nguyen Ngoc HoangJanuary 2, 2012 9:09 PM
What
I

is

the
am

mean

of
not

sentence

"Does
a

this
ring
negative

any

bells?".
English.

Your explain is very good.thank you very much!


Reply
6.
solosysFebruary 14, 2012 8:06 PM
In a practical sense, can this happen with a real clock 1, Z, 1, Z,...
Reply
7.
danielMarch 10, 2012 12:36 PM
good
explanation.
@solosys, if the clock has a weak pull-up, then your 'Z' will be '1', and in this case, there will not
be any transition since it's a '1' to '1'. So (clk'event and clk='1') will fire, but again rising_edge(clk)
will not fire, because the previous value was 'Z' (and at the board level, it's weakly pulled to '1').
So, rising_edge() and falling_edge() will really check if there is a transition from '0' to '1' (or '1' to
'0'), and like vipin said, makes it safe and bug free.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

24

).

LoadPages

THURSDAY, APRIL 1, 2010

Combinatorial Frequency Multiplier Circuit in VHDL


This article is about frequency multiplier in VHDL.Frequency multiplier??? Did you mean Frequency
divider?No,you heard me right,I mean multiplier.And the interesting thing is that this is a
combinational circuit which doubles the frequency applied to it.The digital circuit for this is given below:

Now analyse the above circuit.Assume a practical NOT gate instead of an ideal one.Then you can see
the following timing diagram:

As you can see, because of the delay in the NOT gate the "notclk" signal is not an exact invert of the clk
signal.After the XOR operation you will get the "output" signal as shown above.If you analyse the
frequency of the output signal it is double that of clk signal.But the duty cycle of the output signal is not
50%.
A VHDL code can be written for this code.But since the Xilinx ISE simulator just ignores the gate delays
we cannot see the above output in the simulation level.Also for actually applying a delay in hardware you
need to use a clock buffer as shown in the code.

--Library declarations
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
Library UNISIM;
--for including the Language template "BUFG"
use UNISIM.vcomponents.all;
-------------------------------------------entity test is
port (clk : in std_logic; --input clock
a : out std_logic;
--output signal which changes with "clk"
signal
--output signal which changes with "frequency multiplied clock"
signal
b : out std_logic
);
end test;
architecture Behavioral of test is
signal c1,O,a2 : std_logic:='0';
signal count,count2 : std_logic_vector(31 downto 0):=(others => '0'
);
begin
BUFG_inst : BUFG
port map (
O => O,
-- Clock buffer output
I => c1
-- Clock buffer input
);
c1<=not clk;
a2 <= clk xor O;

b<=count(28);
a<=count2(28);

--original

--counter with modified clock


process(a2)
begin
if(rising_edge(a2)) then
count <= count+'1';
if(count="11111111111111111111111111111111") then
count <=(others =>'0');
end if;
end if;
end process;
--counter with original clock
process(clk)
begin
if(rising_edge(clk)) then
count2 <= count2+'1';
if(count2="11111111111111111111111111111111") then
count2 <=(others =>'0');
end if;
end if;
end process;
end Behavioral;
If you analyse the code ,you can see that I have two counters running at different
frequencies.And the actual output signals are the 28th MSB bit of these counter values.Why
this extra piece of code is needed?
As I said the delay in NOT will be neglected in simulation results.So only way to verify your
result is to synthesis it and try it in a FPGA board.I tried this code in Virtex 5 FPGA(package :
ff136,Device : XC5VSX50T).The clock frequency I gave was 100 MHz.The doubling of the
frequency is verified by 2 LED's one running at the input clock and another running at output
clock.But at 100 MHz the ON/OFF process of the LED's cannot be seen by the human eyes.So
you have to divide both the frequencies by a fixed number.That is why I have chosen a 32 bit
counter and used its 28th bit to drive the LED.
When I ran the code I got the following results:
LED1(original clk) LED2(doubled clk)
off
off
off
on
on
off
on
on
off
off
From the way the LED's are ON/OFF, we can see that the clock actually doubled in frequency!!! And it is
acting like a 2-bit counter.
Note :- This kind of circuit is the only possible type of combinatorial circuit for doubling frequency.
Posted by vipin at 4:15 PM

Reactions:
Labels: frequency multiplier
Email ThisBlogThis!Share to TwitterShare to Facebook

6 comments:
1.
TifossiApril 11, 2010 7:42 PM
This
is
a
very
Thanks
A Masters Student in the US

useful

blog,

keep

up

the

good

work.

Reply
2.
ChrisJuly 26, 2010 10:15 AM
This post is dangerously misleading. there is no reason to think this is a "good idea". the only
reason it works is because the author is lucky and also running a slow clock.
Xilinx

has

several

app

notes

and

guides

that

tell

you

not

to

do

the

above.

I suggest using something like a DCM or PLL. in some cases a BUFR will work. This will avoid
the build-dependent runt pulses.
Reply
3.
vipinJuly 26, 2010 10:20 AM
@Chris : This post was written just from a digital point of view.I am not expecting people to use
this
method
in
their
actual
project,
for
getting
a
higher
frequency.
But from a learner's point of view it is good to try out something new than just learn the theory.
Reply
4.
shivaAugust 5, 2010 5:08 PM
good one..
Reply
5.
VENDE-SEJune 27, 2011 12:16 AM
Hi. Have you tried adding 2 NOT ports to increase delay before going into the xor to try make the
duty cycle correct?
Reply

6.
vipinJune 27, 2011 12:25 AM
@vende : No.I havent tried it yet. But the delay in gates is small, so it may not make a huge
difference. Also simply adding NOT gates without any buffers between them may not work,since
XST
may
optimize
and
remove
the
extra
gates.
Anyway
if
you
try
it
please
let
me
know
the
results.
Also this is just an idea to play with. Dont use it in serious projects to get a higher freq.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

25

).

LoadPages

WEDNESDAY, MARCH 31, 2010

Reading and Writing files in VHDL - An easy way of testing


design
If your design has a large array of inputs then you cannot put them in the testbench program.It will
make the testbench code very difficult to read.In such cases it is advisable to store the inputs in a text
file and read it from that file.Even you can have an output file,where you can store your output values.
In the example I have shown,I have two files.First one is named as "1.txt" and is my input file.The
values will be read from this file and simply copied to the second file named "2.txt". The example is meant
for just a basic introduction for file handling in VHDL.There are pretty large number of options when
it comes to file handling,but I will post them in future.

--include this library for file handling in VHDL.


library std;
use std.textio.all; --include package textio.vhd
--entity declaration
entity filehandle is
end filehandle;
--architecture definition
architecture Behavioral of filehandle is
--period of clock,bit for indicating end of file.
signal clock,endoffile : bit := '0';
--data read from the file.
signal
dataread : real;
--data to be saved into the output file.
signal
datatosave : real;
--line number of the file read or written.
signal
linenumber : integer:=1;
begin

clock <= not (clock) after 1 ns;

--clock with time period 2 ns

--read process
reading :
process
file
infile
: text is in "1.txt";
--declare input file
variable inline
: line; --line number declaration
variable dataread1
: real;
begin
wait until clock = '1' and clock'event;
if (not endfile(infile)) then
--checking the "END OF FILE" is not
reached.
readline(infile, inline);
--reading a line from the file.
--reading the data from the line and putting it in a real type
variable.
read(inline, dataread1);
dataread <=dataread1;
--put the value available in variable in a
signal.
else
endoffile <='1';
--set signal to tell end of file read file
is reached.
end if;
end process reading;
--write process
writing :
process
file
outfile : text is out "2.txt"; --declare output
file
variable outline : line;
--line number declaration
begin
wait until clock = '0' and clock'event;
if(endoffile='0') then
--if the file end is not reached.
--write(linenumber,value(real
type),justified(side),field(width),digits(natural));
write(outline, dataread, right, 16, 12);
-- write line to external file.
writeline(outfile, outline);
linenumber <= linenumber + 1;
else
null;
end if;
end process writing;

end Behavioral;
The contents of files 1.txt and 2.txt are shown below:

Now let us discuss about the textio.vhd package and its general features.
It offers the following new data types:
type LINE is access STRING; -- A LINE is a pointer to a STRING value
type TEXT is file of STRING; -- A file of variable-length ASCII records.
type SIDE is (RIGHT, LEFT); -- For justifying output data within fields.
subtype WIDTH is NATURAL; -- For specifying widths of output fields.
It offers a large number of functions to read and write to a file.You can see the list of all functions and
the arguments used here.
In the example program given above I have two different processes,one for reading from the file and
another for writing into the file.
endfile() is a function which is used to check whether the end of the file is reached.It returns a '1' when
end of file is reached.
The data cannot be read directly into a signal.That is why I have first read it into a variable and then
assigned it into a signal.
Every time you write something into the file or read something from the file,the line number is internally
incremented.
Note :- One advantage of file handling in VHDL is that,you can test a large number of input
combinations for checking the integrity of your design.Sometimes the automatically generated test
cases(with the help of a program) can be easily used without much changes in the testbench code.
Posted by vipin at 7:59 PM

Reactions:
Labels: file handling
Email ThisBlogThis!Share to TwitterShare to Facebook

14 comments:
1.
hankFebruary 9, 2011 9:34 PM
hi,
I

tried

same

approach

to

read

and

write

file..

my
error

msg

compiler
was

setting
smthing
like

is
:

this

for
is

for

vhdl93
vhdl87

wat i came to know is that in vhdl93 the way to read and write file is different(ref: appendix of
Parry),,
can u plz tell us that hw to do it for vhdl93 as part of my design can only be compiled using
vhdl93
only,,
thanks for writing great posts
Reply
2.
vipinFebruary 10, 2011 7:21 PM
@hank : check this link now,for the file reading and writing codes.I will update my blog with a
relevant
post
later
on
the
same
topic.
http://eesun.free.fr/DOC/vhdlref/refguide/language_overview/test_benches/reading_and_writing
_files_with_text_i_o.htm
Reply
3.
hankFebruary 16, 2011 10:19 PM
hi,,
thanks
for
the
nice
link.
I
have
one
more
doubt..
watever literature i saw on this topic..most of them have one thing common: a part of code is
with the rising edge and another part is with the falling edge..like in ur above example u r doing
writitng
on
falling
edge..
why
is
it
happening
dis
way??plz
explain..
I was planning something in which i can read a file and apply those i/p directly on one of my
ports
..the
whole
thing
on
rising
edge
only..
suggest smthing..
Reply
4.
vipinFebruary 16, 2011 11:06 PM
Dont worry about the rising and falling edge thing. Its just that I am waiting for some time for
updating
the
signals.
Read
->
wait
for
some
time
->
the
write.
check the code in the new link. It doesnt require any thing like that. Only thing you have to make
sure is that, value written to the file is proper.You can do it in whichever way you want.I
introduced here a half clock cycle delay.If you want you can use one whole clock cycle delay.
Reply
5.
rinoantinodaJune 9, 2011 8:29 PM
very
nice
blog..
how to make the comparison. Read -> Process -> Write. For example: if the files 1.txt contains:
0
1

2
3
4
5
with the formula if the input >= 3 then the output = 5 else the output = 0
i
want
to
make
the
output
file
2.txt
be
:
0
0
0
5
5
5
I always fail when modifying the above program, whether it's because if statemens I still do not
know.
thankyou if you want to help..
Reply
6.
rinoantinodaJune 10, 2011 12:14 PM
hii.. this is very helpful link, thanx for your information. I've tried several ways to get results like I
want.
for
example,
by
using
the
following
code:
...
signal
X
:
integer
:=3;
...
if
(endoffile
=
'0')
then
dataread
=0
when
dataread
<=X
else
dataread
=5;
write(outline,
dataread,
right,
3,
1);
linenumber
<=
linenumber
+
1;
else
null;
end
if;
what's wrong with my structure code. command error on modelsim -> near "=": expecting <=
or :=
Reply
7.
vipinJune 10, 2011 12:20 PM
@rino : You can simply modify the above program to get what you want(comparison). Read an
element.And inside a if condition write whatever value you want to write to the other file.
If you need help with your projects contact me.
Reply
8.
rinoantinodaJune 12, 2011 12:31 AM
OK..
i'm finished my project with comparison. the problem for how to make the comparison just if
condition. same with you said. thanx for guide. i like this blog
Reply

9.
hanNovember 22, 2011 10:20 PM
Hello,
Sorry
I'm
It

I'm

making
loads
wav

so
But

Korean
for
Drum
files

I
I

as

want
find

can't

Student

studying

VHDL.
english....

my

loop
drum

machine
for
beat
from
sd
to
appropriate

any

my
card

use
example

term
then
SD
or

project.
play
it.
Card
solutions....

May I borrow your hand???


Reply
Replies

1.
ChrisMarch 26, 2012 2:14 AM
Hi,
Thanks for this interesting and practical VHDL example. I spend a lot of my time
at work writing VHDL components and I'm always looking for better ways of
testing them. I have previously discounted text file driven testing because of the
complexities of handling strings and files in the language, however your example
makes
it
look
quite
simple!
I

look

forward

to

reading

more

posts

in

the

future

Chris, www.beesnotincluded.com
Reply

10.
Puneet ThakralApril 18, 2012 8:15 PM
hi
how
we
can
simulate
this
program..
can you tell me procedure what i have to write in signal and wave form window...
regards...
Reply
Replies

1.
vipinJuly 16, 2012 3:33 PM
you dont need to create a waveform.. simply click on "simulate".
Reply

11.
Shahul HamedJuly 16, 2012 3:27 PM
hi....wher to store input and output file prior to simulating??????
Reply
Replies

1.
vipinJuly 16, 2012 3:34 PM
store it in text files. the name of the file names are given in the code.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

MONDAY, MARCH 29, 2010

26

).

LoadPages

How to test your design without writing a seperate test bench


program?
Once you have finished writing code for your design,you need to test whether it is working or
not.Usually this is done by writing a testbench code.Your module to be tested ( known as UUT - Unit
Under Test) is declared as a component in this testbench code and inputs are set with required timings.
So everything is fine.You just write a testbench code for your design and simulate.Verify the
results.Now what is this article about?One disadvantage of the above method is that you need to write lot
of unnecessary code in the form of component initiation,signal declarations etc., for testing your
design.Testbench code also needs a new file.For big modules this is fine.But what if you are just playing
around with VHDL and needs to test arbitrary designs with different input and output formats.Then writing
different testbench files for each of them will definitly waste your time.
So for small codes,you can put your testbench code in your main design file.I have explained it with
the help of "counter" example givenhere.The code is divided by comment lines so that you can get a good
overview of what I have done.

-------------------------Library declarations are not changed


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-------------------------------------------entity test is
------------------------Port declaration Taken out from original
code.
--port (clk : in std_logic;
-count : out std_logic_vector(3 downto 0);
-reset :in std_logic
-);
-------------------------------------------end test;
architecture Behavioral of test is
signal c : std_logic_vector(3 downto 0) :=(others => '0');
-------------------------new signals are added here
constant clk_period : time := 1 ns;
--time period of clk.
--declare the inputs and outputs of your design as signals.
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal count : std_logic_vector(3 downto 0);
--------------------------------------------------begin
----------------------------process for generating clock.
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;

end process;
--------------------------------------End of clock generation
----------------------Simulation process(Set inputs here)
stim_proc: process
begin
wait for 7 ns;
reset <='1';
wait for 3 ns;
reset <='0';
wait for 17 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
--------------------------End of simulation process
-------------------------Here comes your original code.
count <= c;
process(clk,reset)
begin
if(clk'event and clk='1') then
if(c = "1111") then
c <="0000";
end if;
c <= c+'1';
end if;
if(reset='1') then
c <=(others => '0');
end if;
end process;
end Behavioral;
The changes I have made are :
1) Your entity doesnt have any input or output declarations.
2)All your original inputs and outputs are declared as signals in the code.
3)If your design is clock driven then declare a constant for period of clock as follows:
constant clk_period : time := 1 ns; --time period of clk= 1ns.
4)Write the indicated code for clock generation process.
5)Define another process for applying the simulation inputs with proper timing.The contents of this
process depends upon the logic you want to test and the test values.
6)Finally your original code is pasted as shown.
Posted by vipin at 4:35 PM

Reactions:
Labels: testbench

Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

27

).

LoadPages

MONDAY, MARCH 29, 2010

Fixed Point Operations in VHDL : Tutorial Series Part 3


This article is a continuation of the tutorial series on fixed_pkg library.In this article I will talk
about,arithmetical operations on fixed point signals.I assume that you have read Part 1 and Part 2 of the
series.
If you have gone through Part 2 of the series then you must have seen that assigning a signal results
in rounding off the value if the range of the output signal is not sufficient.Yes,this is a great advantage of
fixed_pkg.It is designed so that there is no possibility of an overflow.This is different from "numeric_std"
library which simply neglect the underflow and overflow bits.In order to make sure that overflow doesn't
happen we have to carefully design the size of output signals based on input signal size and the operation
performed.The following table shows the Results range for different kind of operations:

In the table A'left means the left most array index and A'right means the right most array index.The
functions max and min are defined as follows:
max(a,b) = a if a > b else b.
min(a,b) = a if a < b else b.
The operations supported by the package for unsigned types are:
+, , *, /, rem, mod, =, /=, <, >, >=, <=, sll, srl, rol, ror, sla, sra.
The operations supported by the package for signed types are:
+, , *, /, rem, mod, =, /=, <, >, >=, <=, sll, srl, rol, ror, sla, sra, abs, - (unary).
Without going much into the explanations I will directly explain their use with the help of some examples.
Examples for addition:

signal n1,n2 : ufixed(4 downto -3);


signal n3 : ufixed(5 downto -3);
begin
n1 <= to_ufixed (5.75,n1);
-- n1 = "00101110" = 5.75

n2 <= to_ufixed (6.5,n2);


-- n2 = "00110100" = 6.5
n3 <= n1+n2;
-- n3 = "001100010" = 12.25
--See that the range of 'n3' is 5 downto -3 but that of 'n1' and
'n2' is 4 downto -3.
If the range of n3 is 4 downto -3 then the result will be:
n3 = "00110001" = 6.125.
So it is very important to declare the output signal ranges as per the above table.

--For signed numbers:


signal s1,s2 : sfixed(4 downto -3);
signal s3 : sfixed(5 downto -3);
s1 <= to_sfixed (5.75,s1);
-- s1 = "00101110" = 5.75
s2 <= to_sfixed (-6.5,s2);
-- s2 = "11001100" = -6.5
s3 <= s1+s2;
-- s3 = "111111010" = -0.75
Examples for Subtraction:

n1 <= to_ufixed (5.75,n1);


n2 <= to_ufixed (6.5,n2);
n3 <= n2-n1;

-- n1 = "00101110" = 5.75
-- n2 = "00110100" = 6.5
-- n3 = "000000110" = 0.75

s1 <= to_sfixed (5.75,s1);


s2 <= to_sfixed (-6.5,s2);
s3 <= s2-s1;

-- s1 = "00101110" = 5.75
-- s2 = "11001100" = -6.5
-- s3 = "110011110" = -12.25

Examples for multiplication:

signal n1,n2 : ufixed(4 downto -3);


signal n3 : ufixed(9 downto -6);
signal s1,s2,s3 : sfixed(4 downto -3);
signal s4,s5 : sfixed(9 downto -6);
n1 <= to_ufixed (5.75,n1);
n2 <= to_ufixed (6.5,n2);
n3 <= n2*n1;
37.375

-- n1 = "00101110" = 5.75
-- n2 = "00110100" = 6.5
-- n3 = "0000100101011000" =

s1 <= to_sfixed (5.75,s1);


s2 <= to_sfixed (-6.5,s2);
s4 <= s2*s1;
-37.375

-- s1 = "00101110" = 5.75
-- s2 = "11001100" = -6.5
-- s4 = "1111011010101000" =

s3 <= to_sfixed (-5.75,s1);


s5 <= s3*s2;
37.375

-- s3 = "11010010" = -5.75
-- s5 = "0000100101011000" =

Examples for Remainder:

signal n1 : ufixed(4 downto -3);


signal n2 : ufixed(2 downto -4);
signal n3 : ufixed(2 downto -3);

-- see how range of n3 is

declared here.
signal s1 : sfixed(4 downto -3);
signal s2 : sfixed(2 downto -4);
signal s3 : sfixed(2 downto -3);
declared here.

-- see how range of s3 is

n1 <= to_ufixed (7.25,n1);


n2 <= to_ufixed (1.5,n2);
n3 <= n1 rem n2;

-- n1 = "00111010" = 7.25
-- n2 = "0011000" = 1.5
-- n3 = "001010" = 1.25

s1 <= to_sfixed (-7.25,s1);


s2 <= to_sfixed (-1.5,s2);
s3 <= s1 rem s2;

-- s1 = "11000110" = -7.25
-- s2 = "1101000" = -1.5
-- s3 = "110110" = -1.25

Examples for division:

signal n1 : ufixed(4 downto -3);


signal n2 : ufixed(2 downto -4);
signal n3 : ufixed(8 downto -6);
declared here.
signal s1 : sfixed(4 downto -3);
signal s2 : sfixed(2 downto -4);
signal s3 : sfixed(9 downto -5);
declared here.

-- see how range of n3 is

-- see how range of s3 is

n1 <= to_ufixed (6.75,n1);


n2 <= to_ufixed (1.5,n2);
n3 <= n1 / n2;
1.5

-- n1 = "00110110" = 6.75
-- n2 = "0011000" = 1.5
-- n3 = "000000100100000" =

s1 <= to_sfixed (-6.75,s1);


s2 <= to_sfixed (1.5,s2);
s3 <= s1 / s2;
-1.5

-- s1 = "11001010" = -6.75
-- s2 = "0011000" = 1.5
-- s3 = "111111101110000" =

These are only a few of the operators available in the package.In the next part of the tutorial, I will
explain the use of some more operators with example.
Read Part 1 and Part 2 of the series here:
Fixed Point Operations in VHDL : Tutorial Series Part 1
Fixed Point Operations in VHDL : Tutorial Series Part 2
Posted by vipin at 2:36 PM

Reactions:
Labels: fixed point package
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:

1.
vipinMay 27, 2010 7:00 PM
This tutorial was inspired from fixed_pkg" documentation by David Bishop.The original document
can
be
downloaded
from
http://www.vhdl.org/fphdl/Fixed_ug.pdf
Reply
2.
balajiDecember 30, 2010 1:52 PM
how to implement qr decomposition matrix method in vhdl
Reply
3.
w3anggoroJune 2, 2011 10:51 PM
This comment has been removed by the author.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

28

).

LoadPages

SUNDAY, MARCH 28, 2010

4 bit Synchronous UP counter(with reset) using JK flip-flops


Here is the code for 4 bit Synchronous UP counter.The module uses positive edge triggered JK flip flops
for the counter.The counter has also a reset input.The JK flipflop code used is from my previous blog.For
simulating this counter code,copy and paste the JK flipflop code available at the above link in a file and
store the file in the same directory with other .vhd files.
The top module code is given below:

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration with port definitions
entity syn_count4 is
port ( clk:
in std_logic;
reset:
in std_logic;
counter : out std_logic_vector(3 downto 0)
);
end syn_count4;

--architecture of entity
architecture Behavioral of syn_count4 is
--signal declaration.
signal J3,J4,Q1,Q2,Q3,Q4,Qbar1,Qbar2,Qbar3,Qbar4 : std_logic :='0';
begin
J3 <= Q1 and Q2;
J4<= J3 and Q3;
--entity instantiations
FF1 : entity work.JK_Flipflop
;
FF2 : entity work.JK_Flipflop
FF3 : entity work.JK_Flipflop
FF4 : entity work.JK_Flipflop
counter <= Q4 & Q3 & Q2 & Q1;

port map (clk,'1','1',Q1,Qbar1,reset)


port map (clk,Q1,Q1,Q2,Qbar2,reset);
port map (clk,J3,J3,Q3,Qbar3,reset);
port map (clk,J4,J4,Q4,Qbar4,reset);

end Behavioral;
The test bench program used for testing the design is given below:

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity testbench is
end testbench;
architecture behavior of testbench is
--Signal declarations
signal clk,reset : std_logic := '0';
signal counter : std_logic_vector(3 downto 0):="0000";
-- Clock period definitions
constant clk_period : time := 1 ns;
begin
-- Instantiate the Unit Under Test (UUT)
UUT : entity work.syn_count4 port map (clk,reset,counter);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process

stim_proc: process
begin
wait for clk_period*20;
reset <='1';
wait for clk_period*2;
reset <='0';
end process;
end;
The simulated waveform is shown below.Note that when reset is '1' the counter value is reset to "0000"
and remains zero till the reset input equals to '0' again.

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.
Posted by vipin at 6:59 PM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

29

).

LoadPages

SUNDAY, MARCH 28, 2010

Fixed Point Operations in VHDL : Tutorial Series Part 2


This article is a continuation of the tutorial series on fixed_pkg library.In this article I will talk about, type
conversions and assignments of signals of the fixed point data type.I assume that you have read Part 1 of
the series.
Let us see how a signal assignment is made.Suppose I have a signal of unsigned fixed point type.I can
assign a value (say 9.75 ) in the following way:

signal n1 : ufixed(4 downto -3);


n1 <= to_ufixed (9.75,4,-3);
-- n1 ="01001110"
Here TO_UFIXED is the conversion function used to convert the value "9.75" to binary number in the
prescribed range.For a signed number you can use the function "TO_SFIXED".

--an example for TO_SFIXED.


signal n2 : sfixed(4 downto -3);
n1 <= to_sfixed (-9.75,4,-3); -- n2 = "10110010"
Assignments can be made in a different way also.This is done by using a signal name as a parameter,
instead of actual range values.

--Both n1 and n3 contains the same value.


signal n1,n2,n3 : ufixed(4 downto -3);
n1 <= to_ufixed (9.75,n1);
-- n1 ="01001110"
n3 <= to_ufixed (9.75,n2);
-- n3 ="01001110"
Another method of type conversion is by using signal_name'high and signal_name'low attributes.See
the below example.

--Type conversion using attributes.


signal n1,n2,n3 : ufixed(4 downto -3);
n1 <= to_ufixed (9.75,n1'high,n1'low);
n3 <= to_ufixed (9.75,n2'high,n2'low);

-- n1 ="01001110"
-- n3 ="01001110"

All the above methods applies equally to TO_SFIXED conversion function also.
Another useful function available in fixed_pkg is resize().This function is used to fix the size of the
output.But while changing the size of the output the signal value may get rounded off or get saturated.

--An example for resize() function.


signal n1 : ufixed(4 downto -3);
signal n2 : ufixed(5 downto -5);
n1 <= to_ufixed (9.75,n2);
-- n1 = "01001110"
n2 <= resize(n1,n2);
-- n2 ="00100111000"
--Resizing functions can be called in the following ways also:
--Method 1
n2 <= resize(n1,n2'high,n2'low);
--Method 2
n2 <= resize(n1,5,-5);
Take the following statements.

n2 <= to_ufixed (31.75,n2);


n1 <= resize(n2,n1);

-- n2 ="01111111000"
-- n1 = "11111110"

In the above code snippet the values are assigned without any rounding off because the value "31.75"
matched with the range of 'n1'.
Now take the next two statements:

n2 <= to_ufixed (32.75,n2);


n1 <= resize(n2,n1);

-- n2 ="10000011000"
-- n1 = "11111111"

Here the range of 'n1' is not sufficient for the value "32.75",so while resizing it we got all 1's in the
output.While writing your code, you should take care of such things.
Note :- Beware of the following type of assignments:

signal n1 : ufixed(4 downto -3);


signal n2 : ufixed(3 downto -4);
n1 <= to_ufixed (5.75,n1);
-- n1 = "00101110" = 5.75
n4 <= n1;
-- n4 = "00101110" =
2.875
Here the compiler will not show any error or warning on 4th line because the size and type of both the
signals are same.But as you can see this is not what we expected.Take care while writing your code using
fixed_pkg.You may get unexpected results even if you are careless about a single line of code.
Posted by vipin at 6:02 PM

Reactions:
Labels: fixed point package
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
vipinMay 27, 2010 7:06 PM
This tutorial was inspired from fixed_pkg" documentation by David Bishop.The original document
can
be
downloaded
from
http://www.vhdl.org/fphdl/Fixed_ug.pdf
Reply
2.
JimApril 12, 2011 6:44 PM
Does the line [n1 <= to_sfixed (-9.75,4,-3); -- n2 = "10110010"] have a typo ? Should it be [n2 <=
to_sfixed
(-9.75,4,-3);
-n2
=
"10110010"]
?
Thanks for the tutorial.
Reply
3.
JimApril 12, 2011 6:49 PM
Does the line [n4<=n1;-- n4 = "00101110" = 2.875] have a typo ? Where is n4 defined ? Should it
be n2 ?
Reply
4.
vipinApril 12, 2011 6:52 PM
@Jim: thanks for noticing the typos.
Reply
Add comment

RELATED SEARCHES:
Page break by AutoPager. Page(

30

).

LoadPages

SUNDAY, MARCH 28, 2010

Positive edge triggered JK Flip Flop with reset input


Here is the code for JK Flip flop which is positive edge triggered.The flip flop also has a reset input
which when set to '1' makes the output Q as '0' and Qbar as '1'.

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration with port definitions
entity JK_Flipflop is
port ( clk:
in std_logic;
J, K:
in std_logic;
Q, Qbar:
out std_logic;
reset:
in std_logic
);
end JK_Flipflop;
--architecture of entity
architecture Behavioral of JK_Flipflop is
--signal declaration.
signal qtemp,qbartemp : std_logic :='0';
begin
Q <= qtemp;
Qbar <= qbartemp;
process(clk,reset)
begin
if(reset = '1') then
qtemp <= '0';
qbartemp <= '1';
elsif( rising_edge(clk) ) then
if(J='0' and K='0') then
NULL;
elsif(J='0' and K='1') then
qtemp <= '0';
qbartemp <= '1';
elsif(J='1' and K='0') then
qtemp <= '1';
qbartemp <= '0';
else
qtemp <= not qtemp;

--Reset the output.

--No change in the output


--Set the output.
--Reset the output.
--Toggle the output.

qbartemp <= not qbartemp;


end if;
end if;
end process;
end Behavioral;
The test bench program used for testing the design is given below:

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity testbench is
end testbench;
architecture behavior of testbench is
--Signal declarations
signal clk,J,K,reset,Q,Qbar : std_logic := '0';
-- Clock period definitions
constant clk_period : time := 1 ns;
begin
-- Instantiate the Unit Under Test (UUT)
UUT : entity work.JK_Flipflop port map (clk,J,K,Q,Qbar,reset);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
J<='1';
K<='0';
wait for clk_period*2;
J<='1';
K<='1';
wait for clk_period*2;
J<='0';

K<='1';
wait for clk_period*2;
J<='0';
K<='0';
wait for clk_period*2;
J<='1';
K<='0';
wait for clk_period*2;
reset <='1';
J<='1';
K<='1';
wait for clk_period*2;
J<='0';
K<='1';
wait for clk_period*2;
reset <='0';
J<='1';
K<='1';
wait;
end process;
end;
The simulated waveform is shown below.Note that when reset is '1' the change in inputs doesn't affect
the output.

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

In the schematic FDPE represents a single D-type flip-flop with data (D), clock enable
(CE), and asynchronous preset (PRE) inputs and data output (Q). Similarly
FDCE represents a single D-type flip-flop with data (D), clock enable (CE), and asynchronous clear
(CLR) inputs and data output (Q).

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.

Posted by vipin at 5:24 PM

Reactions:
Labels: examples, flipflops
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
ashokFebruary 25, 2011 10:55 AM
Q
<=
qtemp;
Qbar <= qbartemp; you placed it above the process statement, is any thing wrong if i placed it
after
end
if
statements?
can u explain the simulation of the above architecture body.(what i want to know is like
compilation steps in 'C')
Reply
2.
vipinFebruary 25, 2011 11:06 AM
@ashok : If you put them inside the process statement then, it gets executed only on clock
edges.
Also
you
may
get
a
synthesis
error.
It is better to place those statements outside the process.Because we are assigning the
temporary variable values to output signals, and we want to update the values immediately.
Reply
3.
blogzworldOctober 12, 2011 9:05 PM
Why doesn't XST infer a single DFF with preset and clear?
Reply
4.
hoangntDecember 20, 2011 9:18 PM
Why did you use qtemp and qbartemp? Can I use Q and Qbar directly in the process? Thanks
^^
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

SUNDAY, MARCH 28, 2010

31

).

LoadPages

3 : 8 Decoder using basic logic gates


Here is the code for 3 : 8 Decoder using basic logic gates such as AND,NOT,OR etc.The module has
one 3-bit input which is decoded as a 8-bit output.

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration with port definitions
entity decoder is
port(
input :
in std_logic_vector(2 downto 0); --3 bit
input
output : out std_logic_vector(7 downto 0) -- 8 bit
ouput
);
end decoder;
--architecture of entity
architecture Behavioral of decoder is
begin
output(0)
output(1)
output(2)
output(3)
output(4)
output(5)
output(6)
output(7)

<=
<=
<=
<=
<=
<=
<=
<=

(not input(2)) and (not input(1)) and (not input(0));


(not input(2)) and (not input(1)) and input(0);
(not input(2)) and input(1) and (not input(0));
(not input(2)) and input(1) and input(0);
input(2) and (not input(1)) and (not input(0));
input(2) and (not input(1)) and input(0);
input(2) and input(1) and (not input(0));
input(2) and input(1) and input(0);

end Behavioral;
The test bench program used for testing the design is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--this is how entity for your test bench code has to be declared.
entity testbench is
end testbench;
architecture behavior of testbench is
--signal declarations.
signal input : std_logic_vector(2 downto 0) :=(others => '0');
signal output : std_logic_vector(7 downto 0) :=(others => '0');
begin
--entity instantiation

UUT : entity work.decoder port map(input,output);


--definition of simulation process
tb : process
begin
input<="000"; --input = 0.
wait for 2 ns;
input<="001";
--input = 1.
wait for 2 ns;
input<="010";
--input = 2.
wait for 2 ns;
input<="011";
--input = 3.
wait for 2 ns;
input<="100";
--input = 4.
wait for 2 ns;
input<="101";
--input = 5.
wait for 2 ns;
input<="110";
--input = 6.
wait for 2 ns;
input<="111";
--input = 7.
wait;
end process tb;
end;
The simulated waveform is shown below:

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.

Posted by vipin at 2:16 PM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
BILAAL WELCOMES YOU ALLDecember 8, 2010 9:46 PM
nice jobs...
Reply
2.
smrutiNovember 29, 2011 9:49 PM
can
u
plz
give
me
a
code
my
email
id
is
the ram must hav 4 output ports each of 8 bit size

for

32
*
32
bit
ram
smrutisoumya.mishra@gmail.com

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

32

).

LoadPages

SUNDAY, MARCH 28, 2010

Fixed Point Operations in VHDL : Tutorial Series Part 1


You must have heard about library named fixed_pkg.In terms of complexity this library can be placed
some where between integer math and floating point maths.I have decided to write a series of tutorials
about the usage of fixed_pkg library.The library helps to handle fractional numbers with ease.
The library can be downloaded from here.
In the first part of this tutorial, I will give an introduction about the library and the new data types available
for use.
How to use this library in your module?
Add the following two lines to your code(the place where you usually add the libraries):

library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
What are the new data types available in the package?
FIXED_PKG defines two new data types.They are UFIXED ( for unsigned fixed point) and SFIXED (for
signed fixed point).
How to declare signals?

Say you want a fixed point unsigned signal with 'a' bits for decimal part and 'b' bits for fractional part,then
you can declare them as follows:

signal example : ufixed( a-1 downto -b);


--an example
signal example : ufixed (3 downto -4);
Here the signal 'example' has 4 bits for decimal part and 4 bits for fractional part.
example = 9.75 = "1001.1100" or simply example ="10011100".
For signed numbers we use "sfixed" while declaring the signals.Signed numbers are stored as 2's
complement format.

--an example for signed fixed point type.


signal example : sfixed(4 downto -4);
Here the signal 'example' has 5 bits of decimal part and 4 bits for fractional part.
example = -9.75 = "101100100".This is got by taking 2's complement of binary value of 9.75.The MSB bit
'1' indicates the number as negative.
If you declare the signal as sfixed and still store a positive value(say 9.75) then it has the same kind of
storage format as ufixed.

--an example
signal example : sfixed(4 downto -4);
--If 'example' contains 9.75 then it is storage as "01001.1100".
Remember that you declare the signals with sufficient width so that values are get stored correctly.If
the width is not enough then the signal may get rounded off.
Posted by vipin at 1:12 PM

Reactions:
Labels: fixed point package
Email ThisBlogThis!Share to TwitterShare to Facebook

7 comments:
1.
ThabangMay 6, 2010 9:01 PM
hi, i tried using the library you have given above but i get the following error in quartus:
Error (10481): VHDL Use
"ieee_proposed"
does

Clause
not

error at TEMP_READER.vhd(9):
contain
primary
unit

why? i copied the vhdl file to the library folders


Reply
2.
vipinMay 7, 2010 9:21 AM

design library
"fixed_pkg"

@Thabang
:
see
this
link
for
the
error
you
have
got:
http://www.alteraforum.com/forum/showthread.php?t=22898
Mostly this will be a problem with Quartus.They may not have updated their software for this
relatively
new
library.
For me it worked fine in Xilinx, but gave some problems during synthesis.
Reply
3.
vipinMay 27, 2010 7:07 PM
This tutorial was inspired from fixed_pkg" documentation by David Bishop.The original document
can
be
downloaded
from
http://www.vhdl.org/fphdl/Fixed_ug.pdf
Reply
4.
Juan Manuel ScheniniFebruary 27, 2011 6:47 PM
Hi, I'm trying to simulate a multiplication of fixed-point numbers in ISIM Xilinx ISE 12.3 and is
giving
me
the
following
error:
HDLCompiler:0
"Unknown"
Line
0:
cannot
open
"/opt/Xilinx/12.3/ISE_DS/ISE/vhdl/hdp/lin64/ieee_proposed/fixed_float_types.vdb" for
this

file

does

not

exist

in

that

folder,

How

can

do

to

file
writing
fix

it?.

Another question is how I can use the multiplier of core generator with fixed-point numbers? I'm
trying to convert a std_logic_vector, but don't know if i can do that (so I need to do the
simulation).
Reply
5.
vipinFebruary 27, 2011 7:41 PM
@Juan
:
Try
1)Download
this
file
and
store
it
in
the
project
http://www.eda-stds.org/vhdl-200x/vhdl-200x-ft/packages_old/fixed_pkg_c.vhdl
2)Now
library
use

replace

the

following

with
library
use
Core generator component can be instantiated in your design.
Reply
6.
SaeedMarch 17, 2011 4:26 AM

this,
directory.

lines
:
ieee_proposed;
ieee_proposed.fixed_pkg.all
thesee:
work;
work.fixed_pkg.all

I am trying to multtiply two real number by using this library simulation is giving perfectio result...
but it gives error during synthesis. like....((constant fixedsynth_or_real : BOOLEAN; -- differed
constant)) has noo value.. what shud i do to make it synthesis able
Reply
7.
darsh kamalMarch 6, 2012 1:50 PM
Please, how to use this package in modelsim (student edition) and in Xlinix ISE 10.1
I mean how to add and compile them as mentioned above in the library named ieee_proposed?
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

33

).

LoadPages

SUNDAY, MARCH 28, 2010

4 bit Ripple Carry Adder using basic logic gates


Here is the code for 4 bit Ripple Carry Adder using basic logic gates such as AND,XOR,OR etc.The
module has two 4-bit inputs which has to be added, and one 4-bit output which is the sum of the given
numbers.Another output bit indicates whether there is a overflow in the addition,that means whether a
carry is generated or not.

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration with port definitions
entity rc_adder is
port(
num1 : in std_logic_vector(3 downto 0); --4 bit input 1
num2 :
in std_logic_vector(3 downto 0); -- 4 bit
input 2
sum : out std_logic_vector(3 downto 0);
-- 4 bit sum
carry : out std_logic
-- carry out.
);
end rc_adder;
--architecture of entity
architecture Behavioral of rc_adder is
--temporary signal declarations(for intermediate carry's).
signal c0,c1,c2,c3 : std_logic := '0';
begin

--first full adder


sum(0) <= num1(0) xor num2(0); --sum calculation
c0 <= num1(0) and num2(0);
--carry calculation
--second full adder
sum(1) <= num1(1) xor num2(1) xor c0;
c1 <= (num1(1) and num2(1)) or (num1(1) and c0) or (num2(1) and c0)
;
--third full adder
sum(2) <= num1(2) xor num2(2) xor c1;
c2 <= (num1(2) and num2(2)) or (num1(2) and c1) or (num2(2) and c1)
;
--fourth(final) full adder
sum(3) <= num1(3) xor num2(3) xor c2;
c3 <= (num1(3) and num2(3)) or (num1(3) and c2) or (num2(3) and c2)
;
--final carry assignment
carry <= c3;
end Behavioral;
The test bench program used for testing the design is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--this is how entity for your test bench code has to be declared.
entity testbench is
end testbench;
architecture behavior of testbench is
--signal declarations.
signal num1,num2,sum : std_logic_vector(3 downto 0) :=(others => '0
');
signal carry : std_logic:='0';
begin
--entity instantiation
UUT : entity work.rc_adder port map(num1,num2,sum,carry);
--definition of simulation process
tb : process
begin
num1<="0010"; --num1 =2
num2<="1001"; --num2 =9
wait for 2 ns;
num1<="1010";
num2<="0011";

--num1 =10
--num2 =3

wait for 2 ns;


num1<="1000"; --num1 =8
num2<="0101"; --num2 =5
wait for 2 ns;
num1<="1010"; --num1 =10
num2<="0110"; --num2 =6
--more input combinations can be given here.
wait;
end process tb;
end;
The simulated waveform is shown below:

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.
Posted by vipin at 12:09 PM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

8 comments:
1.
asmiFebruary 15, 2011 2:05 PM

could

you

please

tell

me

the

types

of

adders

i
carry
carry
carry

...
know

save
ripple
look

adder
adder
adder

ahead

if any adder besides this .....and also which one is best while we code it in vhdl.....and why..??
asmita
Reply

2.
asmiFebruary 15, 2011 2:14 PM
hello could you please provide me with the block diagram you used for this coding of carry ripple
adder...
thanks

in

advance

regards
asmita
Reply
3.
vipinFebruary 15, 2011 4:41 PM
@asmi : Ripple adder gives the worst performance, but it is to implement. So if speed is
important I suggest go for carry save or carry look ahead adder. Carry save adder is relatively
easy
to
implement.
See
this:
http://www.ece.tamu.edu/~sshakkot/courses/ecen248/csa-notes.pdf
Some
1)Kogge-Stone
2)Carry

more
adder(the

adders
fastest

are:
adder)
adder.

bypass

It is difficult to see which adder is the most useful.One way to find out is implementing all of
them.
This is the block diagram I used to code the ripple
http://en.labs.wikimedia.org/wiki/File:4-bit_ripple_carry_adder.svg
Reply
4.
neemMay 21, 2011 1:04 AM
hello can you please give me vhdl codes for kogge stone adder
Reply

carry

adder

here:

5.
premgSeptember 29, 2011 12:55 AM
can any one post carry save adder carry select adder?
Reply
6.
sofiNovember 25, 2011 10:07 AM
can anybody gve me the vhdl code for carry save adder
Reply
7.
sofiNovember 25, 2011 10:10 AM
i have to impement diff adders and multipliers .plse help me
Reply
8.
SumitFebruary 7, 2012 4:41 PM
@vipin : thanxx ....
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

34

).

LoadPages

SUNDAY, MARCH 28, 2010

4 bit comparator with testbench


Here is the code for 4 bit comparator using if .. elsif ... else statements.The module has two 4-bit inputs
which has to be compared, and three 1-bit output lines.One of these output lines goes high depending
upon whether the first number is equal to,less or greater than the second number.

--libraries to be used are specified here


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--entity declaration with port definitions
entity compare is

port(

num1 : in std_logic_vector(3 downto 0); --input 1


num2 :
in std_logic_vector(3 downto 0); --input 2
less :
out std_logic;
-- indicates first
number is small
equal :
out std_logic;
-- both are equal
greater :
out std_logic
-- indicates first number
is bigger
);
end compare;
--architecture of entity
architecture Behavioral of compare is
begin
process(num1,num2)
begin
-- process starts with a 'begin' statement
if (num1 > num2 ) then --checking whether num1 is greater than
num2
less <= '0';
equal <= '0';
greater <= '1';
elsif (num1 < num2) then
--checking whether num1 is less than
num2
less <= '1';
equal <= '0';
greater <= '0';
else
--checking whether num1 is equal to num2
less <= '0';
equal <= '1';
greater <= '0';
end if;
end process;
-- process ends with a 'end process' statement
end Behavioral;
The test bench program used for testing the design is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--this is how entity for your test bench code has to be declared.
entity testbench is
end testbench;
architecture behavior of testbench is
--signal declarations.
signal num1,num2 : std_logic_vector(3 downto 0) :=(others => '0');
signal less,equal,greater : std_logic:='0';

begin
--entity instantiation
UUT : entity work.compare port map(num1,num2,less,equal,greater);
--definition of simulation process
tb : process
begin
num1<="0010"; --num1 =2
num2<="1001"; --num2 =9
wait for 2 ns;
num1<="1001"; --num1 =9
num2<="0010";
--num2 =2
wait for 2 ns;
num1<="1010"; --num1 =10
num2<="1010"; --num2 =10
--more input combinations can be given here.
wait;
end process tb;
end;
The simulated waveform is shown below:

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.
Posted by vipin at 11:46 AM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
UnknownApril 16, 2012 11:56 PM
Hi i need same program for one 24 bit to be compared with hex value FAF320
Reply
2.
jasleenMay 11, 2012 4:46 PM
very clear...i liked it...:)
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

35

).

LoadPages

SATURDAY, MARCH 27, 2010

Simple 1 : 4 Demultiplexer using case statements


Here is the code for 4 :1 DEMUX using case statements.The module has 4 single bit output lines and
one 2 bit select input.The input line is defined as a single bit line.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity demux1_4 is
port (
out0 : out std_logic;
--output bit
out1 : out std_logic;
--output bit
out2 : out std_logic;
--output bit
out3 : out std_logic;
--output bit
sel : in std_logic_vector(1 downto 0);
bitin : in std_logic
--input bit
);
end demux1_4;
architecture Behavioral of demux1_4 is
begin
process(bitin,sel)
begin
case sel is
when "00" => out0 <= bitin; out1 <= '0'; out2 <= '0'; out3 <='0';

when "01" => out1 <= bitin; out0 <= '0'; out2 <= '0'; out3 <='0';
when "10" => out2 <= bitin; out0 <= '0'; out1 <= '0'; out3 <='0';
when others => out3 <= bitin; out0 <= '0'; out1 <= '0'; out2 <='
0';
end case;
end process;
end Behavioral;
The testbench code used for testing the code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY testbench IS
END testbench;
ARCHITECTURE behavior OF testbench IS
SIGNAL out0,out1,out2,out3,bitin : std_logic:='0';
SIGNAL sel : std_logic_vector(1 downto 0):="00";
BEGIN
UUT : entity work.demux1_4 port map(out0,out1,out2,out3,sel,bitin);
tb : PROCESS
BEGIN
bitin <= '1';
sel <="00";
wait for 2 ns;
sel <="01";
wait for 2 ns;
sel <="10";
wait for 2 ns;
sel <="11";
wait for 2 ns;
--more input combinations can be given here.
END PROCESS tb;
END;
The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below:

Posted by vipin at 8:16 PM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

36

).

LoadPages

SATURDAY, MARCH 27, 2010

Simple 4 : 1 multiplexer using case statements


Here is the code for 4 : 1 MUX using case statements.The module contains 4 single bit input lines and
one 2 bit select input.The output is a single bit line.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity multiplexer4_1 is
port (
i0 : in std_logic;
i1 : in std_logic;
i2 : in std_logic;
i3 : in std_logic;
sel : in std_logic_vector(1 downto 0);
bitout : out std_logic
);
end multiplexer4_1;
architecture Behavioral of multiplexer4_1 is
begin

process(i0,i1,i2,i3,sel)
begin
case sel is
when "00" => bitout <= i0;
when "01" => bitout <= i1;
when "10" => bitout <= i2;
when others => bitout <= i3;
end case;
end process;
end Behavioral;
The testbench code used for testing the code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY testbench IS
END testbench;
ARCHITECTURE behavior OF testbench IS
SIGNAL i0,i1,i2,i3,bitout : std_logic:='0';
SIGNAL sel : std_logic_vector(1 downto 0):="00";
BEGIN
UUT : entity work.multiplexer4_1 port map(i0,i1,i2,i3,sel,bitout);
tb : PROCESS
BEGIN
i0<='1';
i1<='0';
i2<='1';
i3<='0';
sel <="00";
wait for 2 ns;
sel <="01";
wait for 2 ns;
sel <="10";
wait for 2 ns;
sel <="11";
wait for 2 ns;
--more input combinations can be given here.
END PROCESS tb;
END;
The simulated testbench waveform is shown below:

The code was synthesized using XILINX ISE XST . The RTL schematic of the design is shown below.

Note :- Use RTL Viewer to get a closer look on how your design is implemented in hardware.
Posted by vipin at 7:35 PM

Reactions:
Labels: examples
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.

AbHiMarch 1, 2011 11:16 PM


can you please explain the dataflow model...
Reply
2.
DarkkobaJanuary 31, 2012 8:00 PM
it's
very
easy
but
how
I
write
code
for
8
bits
multiplexer?
problem
is:
a and b 8 bot input, c is 2 bit input , D is 8bit output if c="00" output A, c="01" output B, c="10"
output
D,
c="11"
output
Z
help me how I write Its code
Reply
Add comment
RELATED SEARCHES:

Page break by AutoPager. Page(

37

).

LoadPages

SATURDAY, MARCH 27, 2010

Migrating from std_logic_vector to UNSIGNED or SIGNED data


types
Some days before I wrote another article about why the library "numeric_std" is preferred over
"std_logic_arith" and others.In that article I have mentioned that use of synopsis IEEE library , such as
STD_LOGIC_ARITH , STD_LOGIC_UNSIGNED and the like should be restricted unless you really need
std_logic_vector in your design.If you want to know more about it click here.
But most of the VHDL tutorial sites have examples based on the synopsis libraries.So as far as a
beginner is concerned it is difficult for him to migrate suddenly from std_logic_arith to numeric_std.This
article is for them.
In the earlier part of this blog I have written a code for BCD to 7- segment converter using the Synopsis
IEEE library such as std_logic_arith and std_logic_unsigned.That article can be read here. I have written
the same code in this article using the library NUMERIC_STD.There are only minor changes applied to
the code,but still I think it will really help beginners.
Given below is the converter code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
----------------------------------use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
--------------------------------use IEEE.NUMERIC_STD.ALL;
entity test is
port (
clk : in std_logic;
------------------------------------------------------------------bcd : in std_logic_vector(3 downto 0);
-segment7 : out std_logic_vector(6 downto 0);
-----------------------------------------------------------------bcd : in UNSIGNED(3 downto 0);
segment7 : out UNSIGNED(6 downto 0)
);
end test;
architecture Behavioral of test is
begin
process (clk,bcd)
BEGIN
if (clk'event and clk='1') then
case bcd is

when "0000"=>
when "0001"=>
when "0010"=>
when "0011"=>
when "0100"=>
when "0101"=>
when "0110"=>
when "0111"=>
when "1000"=>
when "1001"=>
when others=>
end case;
end if;

segment7
segment7
segment7
segment7
segment7
segment7
segment7
segment7
segment7
segment7
segment7

<="0000001";
<="1001111";
<="0010010";
<="0000110";
<="1001100";
<="0100100";
<="0100000";
<="0001111";
<="0000000";
<="0000100";
<="1111111";

end process;
end Behavioral;
The commented part of the code(shown in green colour) is from the original code given here.
The testbench of the above code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
----------------------------------use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
--------------------------------use IEEE.NUMERIC_STD.ALL;
ENTITY test_tb IS
END test_tb;
ARCHITECTURE behavior OF test_tb IS
signal clk : std_logic := '0';
------------------------------------------------------------------signal bcd : std_logic_vector(3 downto 0) := (others => '0');
-signal segment7 : std_logic_vector(6 downto 0);
-----------------------------------------------------------------signal bcd : UNSIGNED(3 downto 0) := (others => '0');
signal segment7 : UNSIGNED(6 downto 0);
constant clk_period : time := 1 ns;
BEGIN
uut: entity work.test PORT MAP (clk,bcd,segment7);
clk_process :process
begin
clk <= '0';
wait for clk_period/2;

end process;

clk <= '1';


wait for clk_period/2;

stim_proc: process
begin
------------------------------------------------------------------for i in 0 to 9 loop
-bcd <= conv_std_logic_vector(i,4);
-wait for 2 ns;
-end loop;
-----------------------------------------------------------------bcd <=bcd + 1;
if(bcd = "1001") then
bcd <="0000";
end if;
wait for 2 ns;
end process;
END;
So I hope, it is not that difficult to migrate to the official IEEE library.You can try changing the counter
code given here, your own and see the results.If you have any difficulties doing so please contact me.
Posted by vipin at 11:42 AM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

38

).

LoadPages

FRIDAY, MARCH 26, 2010

Concatenation Operator in VHDL


Many VHDL programmers doesnt know that there is a operator available in VHDL for doing
concatenation.But there is one. It is written as '&'.
Let us see some usages of this operator.

signal w, x, y, z :std_logic:='0';
signal t : std_logic_vectoR(1 downto 0);

t<= (w and x) & (y and z);


--this is same as
t(1) <= w and x;
t(0) <= y and z;
Remember that the left hand side variables on the RHS belong to the MSB of the left hand side operand.
Integers cannot be concatenated directly,but they can be in the following way.Here is an example to
show how you will concatenate two integers to form and std_logic_vector.

signal t : std_logic_vector(31 downto 0);


constant a: integer := 23;
constant b: integer := 456;
-- conv_std_logic_vector(signal_name, number_of_bits)
t <= conv_std_logic_vector(a, 16) & conv_std_logic_vector(b, 16);
Another example:

signal a: std_logic_vector(0 to 3):="1111";


signal b: std_logic_vector (0 to 7):= (others => '0');
--this statement will make the MSB 4 bits to zero and LSB 4 bits to
one.
b<="0000" & a;
The operator is very useful when comes to checking a group of bits inside a case statement.The following
example illustrates the concept:

process(bit0,bit1,bit2,bit3)
variable bitcat : std_logic_vector(3 downto 0);
begin
bitcat := bit0 & bit1 & bit2 & bit3; --concatenation
case bitcat is
when "0001" => xxx <= 1;
when "0010" => xxx <= 3;
when others => xxx <= 4;
end case;
end process;
These are some of the few situations where '&' operator can be used efficiently.If you know some more
free to post them in the comment section.
Posted by vipin at 7:31 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:
1.

RavindarMarch 27, 2010 11:46 PM


I think in cancatation t<= (x and w) & (y and z). result of y and z is assigned to LSB of t and
result of x and w is assigned to MSM i.e.t(1)
Reply
2.
vipinMarch 28, 2010 11:12 AM
@Ravindar : yeah.. you are right.Sorry for the typing mistake.I have corrected it.Some more
examples
are
here...
signal
signal
a
b
--this
a(1)
a(0)
b(1)
b(0)

a
b

:
:
<=
<=
is

unsigned(1
unsigned(0
'1'
'1'
same
<=
<=
<=
<=

downto
to
&
&

0);
1);
'0';
'0';
as:
'1';
'0';
'0';
'1';

thanks for the comment.


Reply
3.
ChrisJuly 26, 2010 1:52 PM
A useful tip -- watch out for operator order. eg "x & y and z & w" is the same as (x&y) and (z&w).
Its easy to accidently read it as x & (y and z) & w. This usually results in a synthesis error, as its
unlikely the dimensions will match.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

39

).

LoadPages

FRIDAY, MARCH 26, 2010

Random Number Generator in VHDL


In some designs you may need a Random Number Generator for generating random numbers.In C
and other high level languages you have library functions for this kind of functions.In VHDL this is
achieved by designing a pseudo random sequence generator (PRSG) of suitable length. The PRSG I
have coded, will look like this:

The sequence generated by PRSG is not theoretically random,but for most practical applications the
sequence can be considered as random.Because the period of the sequence is (2^n - 1).Where n is
the number of shift registers used in the design.For 32 bit design the period is 4294967295.This is large
enough for most of the practical applications.
The module is written in a generic way.That means the value of 'n' can be specified at the time of
compilation.
Below is the code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity random is
generic ( width : integer := 32 );
port (
clk : in std_logic;
random_num : out std_logic_vector (width-1 downto 0)
output vector
);
end random;

--

architecture Behavioral of random is


begin
process(clk)
variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 =
> '1',others => '0');
variable temp : std_logic := '0';
begin
if(rising_edge(clk)) then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
end if;
random_num <= rand_temp;
end process;
The test bench for the code is given below:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY testbench IS
END testbench;

ARCHITECTURE behavior OF testbench IS


--Input and Output definitions.
signal clk : std_logic := '0';
signal random_num : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.random generic map (width => 4) PORT MAP (
clk => clk,
random_num => random_num
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
END;
The simulated waveform is shown below.

The code is synthesizable.The RTL schematic of the design is given below:

The above test bench program passes the value '4' to the main code in a generic manner so that the
output generated by the code is 4 bit in size.For more information about usage of Generics in VHDL,you
can see this article.You can change the size of the output as you want by editing the following lines:
--change the value shown in RED colours.It should be (width -1).
signal random_num : std_logic_vector(3 downto 0);
--change the value shown in RED colours.It should be equal to 'width' of the output vector.
uut: entity work.random generic map (width => 4) PORT MAP
Posted by vipin at 3:46 PM

Reactions:
Labels: LFSR
Email ThisBlogThis!Share to TwitterShare to Facebook

9 comments:
1.

vikas parasharApril 7, 2010 7:32 AM


thanx for writing such a good post,, this is one of the best material i have found on this subject,
Reply
2.
ThabangMay 6, 2010 6:07 AM
thank you very much much, this helped me a lot.
Reply
3.
ChrisJuly 26, 2010 9:59 AM
This post is unfortunantly wrong. The "taps", or xor'd values are not arbitrary, but rather carefully
selected. If expressed as a polynomial, the tap locations would form a monic, irreducible
polynomial.
this is very obvious if you try to make a 31 element sequence. You will end up with a 21 element
sequence
instead.
why? because the polynomial x^5 + x^4 + 1 is not irreducible. It can be factored as (x^2 + x + 1)
(x^3
+
x
+
1),
where
coefficients
are
in
GF2.
with an FPGA, you can even see that this does NOT work with some of the longer sequence
generators, as the sequence won't be nearly long enough, and will repeat more frequently than
expected.
you should take the tap values from some of the other sites on google. Keep in mind that there
are actually a large number of irreducible polynomials, but not every polynomial is irreducible.
what this means is that an arbitrary selection of taps may result in shorter sequences.
for test purposes, I prefer polynomials that have only a few taps, and where the lowest tap is
relatively high. this allows for a simple to code multi-bit shift.
Reply
4.
vipinJuly 26, 2010 10:27 AM
@Chris:
Thanks
a
lot.I
got
your
point.
I checked the code with 32 bit width, and the seq seems to repeat after 2^21 clock cycles.
After checking with other articles on PRNG I will soon upload a new program which takes care of
the "taps".
Reply
5.
VirDecember 27, 2010 5:19 PM
Have you fixed the random program?
Reply

6.
mlcdJanuary 30, 2012 2:36 PM
thank you very much for the post, but I wonder if you correct the mistake, is this code the new
corrected program?
Reply
7.
chantyMarch 21, 2012 8:05 AM
in this code the 13th line is showing error in modelsim... the line is
variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 => '1',others => '0');
plese rectify it and tell me the right answer...
Reply
8.
Nirav SolankiMarch 31, 2012 11:57 PM
Sorry for writing my question anywhere but can you tell me if I am having 1024 member array of
64 bit length and with each clock I want to excess 4 member out of it
can
you
tell
me
what
i
can
do
for
that?
Someone
said
me
to
use
rom
Can
you
tell
me
how
to
use
it?
And i need to generate real random number also that is varying from 0 to 1 can you tell me how
can i do it?
Reply
9.
FrankJuly 11, 2012 7:06 PM
Just by copy and pasting your generator I get an error: Unexpected EOF. I somehow don't see
what's wrong.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

40

).

LoadPages

THURSDAY, MARCH 25, 2010

Why the library "numeric_std" is preferred over "std_logic_arith"


and others?
This article is based on an email conversion I had with one VHDL expert.If you browse
through some forums about VHDL then you may see some suggestions such as , use

"numeric_std" library instead of "std_logic_arith" and "std_logic_unsigned".I had this doubt


before and here is what he(unfortunately i don't know his name) told me:
std_logic_arith, etc. were packages written by Synopsis and included in their tools'
version of the ieee library, without the approval of the ieee standardization body.
The LRM (Language reference manual) reserves the ieee library for officially balloted and
approved packages for the vhdl language.However, since the whole world started using
synopsys first, and everyone had started writing code dependent upon std_logic_arith being
in ieee, Synopsys refused to take it out of their implementation. And since other tools were
usually forced to work seamlessly with code that worked with Synopsys, they followed suit.
However, different vendors implemented the package slightly differently, with some
problems in compatibility. Since there is no standard governing it, it is subject to change at
any time.
So, the IEEE decided to write and approve a standard package for numerical operations
on SL(std_logic) and BIT based vectors. Those packages are called numeric_std and
numeric_bit. These are ieee standard packages, located in the official version of the ieee
library, and their behavior is governed by the standard, so compatibility is assured.
Numeric_std does not attempt to imply a numerical interpretation on
SLV(std_logic_vector) , but rather defines related types UNSIGNED and SIGNED which have
both numerical and bitwise interpretations (i.e.AND and OR are also defined for them). This
avoids any confusion when needing to use both signed and unsigned arithmetic in the same
body (std_logic_arith simply assumes all arithmetic is unsigned). Numeric_std defines
arithmetic operations between various combinations of signed, unsigned and integer
operands. In all cases(?) the size of the result is the same as the largest signed/unsigned
operand. Over/underflows are truncated (rolled over).
The latest version of the vhdl standard does include a package similar in function to
std_logic_arith, etc., named numeric_std_unsigned, which does define unsigned arithmetic
on std_logic_vector operands. Unfortunately, I know of no tools that support it yet.
Generally, if you can, create your entity interfaces using unsigned or signed (or even
integer) if they are uniformly numerically interpreted. (i.e. a generic memory device
may be able to store any kind of binary data, so SLV may make more sense there, but a
digital filter has a specific definition of its input data in mind, and that can be coded by using
the appropriate type on the port). Using the appropriate types on the ports makes it much
easier to avoid conversions within the body.
For example, if you used an SLV input port, and you need to add one to it and output that on
an SLV output port, you must convert it twice:
output <= std_logic_vector(unsigned(input) + 1);
This converts the SLV input to unsigned (so that + is defined for it), adds (integer) one to it
(the result is unsigned too), then converts the result back to SLV for the output port.It would
have been much easier if input and output had been declared unsigned (or signed) in the
first place:
output <= input + 1;
At the same time you shouldn't get the idea that "don't use SLV at all".Some places SLV is
better than UNSIGNED or SIGNED data type.For example, an ALU (Arithmetic and Logic Unit)
that accepts signed or unsigned data (depending on the operation control) may always have
a numeric interpretation of the data on its ports, but since we do not have a generic numeric
signed and unsigned representation, SLV would still be appropriate for those ports.Other
examples,where SLV is a better option are any collection of bits that does not have a
numeric meaning such as a vector of enable bits, etc...

Note :- In the earlier codes I have heavily dependent on SLV.But in the recent posts I have
started using SIGNED and UNSIGNED data types more frequently.
Posted by vipin at 12:22 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

2 comments:
1.
martinthompsonFebruary 16, 2011 8:42 PM
This

is

the

original

source...

https://groups.google.com/group/comp.lang.vhdl/msg/62ee6c554e38e823?hl=en
Reply
2.
joynancyjoyJune 7, 2011 10:37 PM
easily understandable..........giv me more questions ........... related to verilog sir...............
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

41

).

LoadPages

WEDNESDAY, MARCH 24, 2010

Matrix multiplication in VHDL


Here is a function for doing matrix multiplication in VHDL.
For storing matrix elements I have declared the following data types:

type
type
type
type
type
type

t11 is array (0 to numcols1-1) of unsigned(15 downto 0);


t1 is array (0 to numrows1-1) of t11;
t22 is array (0 to numcols2-1) of unsigned(15 downto 0);
t2 is array (0 to numrows2-1) of t22;
t33 is array (0 to numcols3-1) of unsigned(31 downto 0);
t3 is array (0 to numrows3-1) of t33;

Depending upon the size of your matrix you have to set the values
numcols1,numcols2,numcols3,numrows1,numrows2,numrows3 etc.Here for valid matrix multiplication,
numcols1 = numrows2.
For the resultant matrix, numrows3 = numrows1 and numcols3 = numcols2.

The function is given below:

function matmul ( a : t1; b:t2 ) return t3 is


variable i,j,k : integer:=0;
variable prod : t3:=(others => (others => (others => '0')));
begin
for i in 0 to numrows1-1 loop
for j in 0 to numcols2-1 loop
for k in 0 to numcols1-1 loop
prod(i)(j) := prod(i)(j) + (a(i)(k) * b(k)(j));
end loop;
end loop;
end loop;
return prod;
end matmul;
In the above function replace the names numrows1,numcols1,numcols2 etc with appropriate values.
For example if I want to multiply a 4*3 matrix with 3*5 matrix then :
numcols1=3, numcols2 =5 ,numcols3 = 5,numrows1=4 ,numrows2 =3 and numrows3=4.
So the type declarations will look like this:

type
type
type
type
type
type

t11 is array (0 to 2) of unsigned(15 downto 0);


t1 is array (0 to 3) of t11;
t22 is array (0 to 4) of unsigned(15 downto 0);
t2 is array (0 to 2) of t22;
t33 is array (0 to 4) of unsigned(31 downto 0);
t3 is array (0 to 3) of t33;

Note :- I have declared the elements of the matrix as unsigned 16 bit and for the product matrix as
unsigned 32 bit.If you want to change the size of the operands you can easily do that in the type
declaration.This will not alter the function logic.
Posted by vipin at 10:39 AM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

22 comments:
1.
vipinMarch 28, 2010 3:07 PM
Many people have been asking for a testbench for the above program.Here is the testbench
program.The following codes is for matrix multiplication between 4*3 and 3*5 matrices.The
resulting
matrix
has
size
of
4*5.
First copy paste the below code and store it as mat_ply.vhd.This is the package file.
--package
library
use
use

definition.
IEEE;
IEEE.STD_LOGIC_1164.all;
ieee.numeric_std.all;

package
type
type
type
type
type
type
function

mat_ply
t11
t1
t22
t2
t33
t3
is

is
is
is
is
is

array
array
array
array
array
array
(0

matmul

(0

to
(0

(0
(0
(0
to

unsigned(15
downto
0);
t11;
--4*3
matrix
to
4)
of
unsigned(15
downto
0);
to
2)
of
t22;
--3*5
matrix
to
4)
of
unsigned(31
downto
0);
3)
of
t33;
--4*5
matrix
as
output

2)

is
of

to

3)

t1;

of

b:t2

return

end

mat_ply;

package
function
variable
variable

t3;

body
matmul
prod

a
i,j,k
t3:=(others

mat_ply
:

t1;
=>

b:t2
:
(others

)
=>

is
return
(others

t3
is
integer:=0;
=>
'0')));

begin
for i in 0 to 3 loop --(number of rows in the first matrix
for j in 0 to 4 loop --(number of columns in the second matrix
for k in 0 to 2 loop --(number of rows in the second matrix
prod(i)(j)

:=

prod(i)(j)

(a(i)(k)

1)
1)
1)

b(k)(j));

end
end
end
return
end

loop;
loop;
loop;
prod;
matmul;

end

mat_ply;

copy paste the below code and store it as test_mat.vhd.This is main module which is
used
to
call
the
function.
library
use
use

IEEE;
IEEE.STD_LOGIC_1164.ALL;
IEEE.numeric_std.ALL;

library
use

work;
work.mat_ply.all;

entity
port
a
b
prod
);
end
architecture
begin
process(clk)
begin
if(clk'event
prod<=matmul(a,b);
end
end
end

test_mat
:

(clk

is
std_logic;
t1;
t2;
t3

in

:
:

in
in
out

test_mat;
Behavioral

and
--function

of

test_mat

clk='1')
is

called

is

then
here.
if;
process;
Behavioral;

Now comes the test bench code.Copy paste the below code and store it as mat_tb.vhd.
LIBRARY
USE
USE
library
use

ieee;
ieee.std_logic_1164.ALL;
ieee.numeric_std.ALL;
work;
work.mat_ply.all;

ENTITY
END

mat_tb

IS
mat_tb;

ARCHITECTURE
behavior
OF
mat_tb
IS
--signals
declared
and
initialized
to
zero.
signal
clk
:
std_logic
:=
'0';
signal
a
:
t1:=(others
=>
(others
=>
(others
=>
'0')));
signal
b
:
t2:=(others
=>
(others
=>
(others
=>
'0')));
signal
x:
unsigned(15
downto
0):=(others
=>
'0');
--temporary
variable
signal
prod
:
t3:=(others
=>
(others
=>
(others
=>
'0')));
-Clock
period
definitions
constant
clk_period
:
time
:=
1
ns;
BEGIN
-uut:

Instantiate
entity

the
work.test_mat

-clk_process
begin
clk
wait
clk
wait
end
-stim_proc:
begin
--first
a
b
wait
--second
end

Unit

Under
PORT

Clock

process
<=
for
<=
for
Stimulus

Test
MAP

(UUT)
(clk,a,b,prod);
definitions
:process
'0';
clk_period/2;
'1';
clk_period/2;
process;
process
process

set

<=
<=
set

of

of
inputs..
((x,x+1,x+4),(x+2,x,x+1),(x+1,x+5,x),(x+1,x+1,x));
((x,x+1,x+4,x+2,x+7),(x,x+1,x+3,x+2,x+4),(x,x+2,x+3,x+4,x+5));
for
2
ns;
inputs
can
be
given
here
and
so
on.
process;

END;
Hope this helps..
Reply
2.

swatiApril 19, 2010 12:39 AM


Could
you
please
tell
me
how
to
test
this
code.
I want to multiply 3x3 matrix with a 3x1 matrix to obtain an output of 3x1.

I
tried
to
test
it
but
getting
Its urgent please let me know how to go about the pin assignments.

wrong

answers.

Reply
3.
vipinApril 19, 2010 10:48 AM
@swati : in your case, the function needs a little change.Because you are using a column
matrix.
The
function
will
look
like
this:
function
variable
variable
begin
for
for
prod(i)
end
end
return
end

matmul

The

type

type
type
type

prod

(
:

i
k

The
applied
a
b <= (3,4,5);

t1;

b:t2
:
=>

:=(others

in
in
prod(i)

:=

t11
t1
t2
is

a
i,k
t2

0
0

return
(others

to
to
(a(i)(k)

definitions

will

2
2
*

be

t2
is
integer:=0;
=>
'0'));
loop
loop
b(k));
loop;
loop;
prod;
matmul;

like

this:

is
array
(0
to
2)
of
unsigned(15
downto
0);
is
array
(0
to
2)
of
t11;
--3*3
matrix
array
(0
to
2)
of
unsigned(15
downto
0);
--3*1
matrix
inputs

in

the

testbench

will

look
like
this:
((1,2,3),(4,5,3),(7,2,1));

<=

Reply
4.
carlos julio cantosMay 14, 2010 9:33 PM
Could
you
please
tell
me
how
to
test
this
code.
I want to multiply 3x3 matrix with a 3x3 matrix to obtain an output of 3x3.
I
tried
to
test
it
but
getting
wrong
answers.
Its urgent please let me know how to go about the pin assignments.
how
The
applied
a
b <= (3,4,5);

do
inputs

you
in

the

testbench

obtain:
look
like
this:
((1,2,3),(4,5,3),(7,2,1));

will

<=

Reply
5.
vipinMay 15, 2010 9:24 AM
@carlos
:
Send
me
your
code
http://vhdlguru.blogspot.com/p/contact-me.html

to

me

via

this

form

Reply
6.
Mr.August 31, 2010 6:57 PM
I would like to know the How to take Matrix transpose in Verilog HDL, 4x4 and 8x8,
Please
help
for
this
issue,
or
e-mail
to
me
:
cavalli_italy_@gmail.com
Thank
you
in
advance.
HD.
Reply
7.
vipinAugust 31, 2010 9:07 PM
The transpose is a simple concept.I will give you the VHDL function here.If you know Verilog
basics
then
it
would
be
easy
for
you
to
port
it
into
Verilog.
function
variable
variable
begin
for
for
prod(i)(j)
end
end
return
end

transpose
prod
i
j

i,j
t3:=(others
in
in

t1

return

=>

(others

:
=>

(others

0
0

to
to

numrows-1
numcols-1

:=

t1
is
integer:=0;
=>
'0')));
loop
loop
a(j)(i);
loop;
loop;
prod;
transpose;

Hope that helped.


Reply
8.
J.R.October 20, 2010 11:26 PM
could you please tell me the code to do a fully pipelined 4x5 multiplied by a 5x3 to get a 4x3 with
the
testbench
included.
please
email
it
to
me
jroccurrie15@gmail.com
Thanks
Reply
9.
rourabNovember 26, 2010 11:14 PM
@ vipin : could you write the whole program including inputs and outputports ,pls
Reply
10.

rourabNovember 26, 2010 11:31 PM


@vipin:
here
the

im
the

use
error

is

line

mat_ply.vhd
in

and
line

is

test_mat.vhd
file,
of
test_mat.vhd,

"use

work.mat_ply.all;"

the error is "Declaration all can not be be made visible in this scope since design unit mat_ply is
not
a
package."
it will be better to understand if u write the whole program,
Reply
11.
vipinNovember 27, 2010 12:41 AM
The codes given is already tested.As I am busy with my job I am not able to update this blog
properly. If you want any additional help with the code or tutorial you can pay me to do so.
Thanks.
Reply
12.
jayamFebruary 1, 2011 9:10 PM
can u please tell me how to write a vhdl code for inveting a rectangular matrix
Reply
13.
vipinFebruary 1, 2011 9:14 PM
@jayam : Please contact me for codes, which are not listed in my blog.If I have time, I will post
them here or else I will charge a fee for the same, as I am working as a freelancer for vhdl
coding.
Reply
14.
DON A ALEXANDERMarch 18, 2011 4:20 PM
could u tell how to multiply large matrix dimension eg 200*20 with 20 *10 then 200*10
i
tried
your
code
but
resourse
utilsation
more.
how is the solution?
Reply
15.
vipinMarch 18, 2011 4:32 PM
@DON : you have to pass the elements of the matrix one by one. This code will not work under
such situations. You have to re write the entire logic.
Reply

16.
DON A ALEXANDERMarch 19, 2011 1:36 PM
sir,
could u explain a little explanation about higher dimension. every time i wrote code in different
method iob and dsp48 utilisation more.sir how to pass element of matrix one by one.why looping
can't
work
could u help me?
Reply
17.
vidhiMarch 28, 2011 10:57 AM
sir,
can you plz tell me how to add text io functions to your code as I want to use this code for
multiplying
510*510
and
510*1020
size
matrices.
I

want

to

copy

can

you

the

simulation

output

to

help

file.
me?

vidhi
Reply
18.
vipinMarch 28, 2011 11:21 AM
@vidhi
:
see
this
http://vhdlguru.blogspot.com/2011/02/file-reading-and-writing-in-vhdl-part-2.html

post:

Reply
19.
abcApril 4, 2011 9:43 PM
Can you help me with a matrix multiplication of (1x64) and (64 x 128)
Reply
20.
aishuJuly 5, 2011 11:38 AM
SIR
I WANT TO MULTIPLY 3 MATRICES (XYZ) AT A TIME USING SYSTOLIC ARCHITECTURE,
WHERE X AND Z ARE RECTANGULAR MATRICES AND Y IS A DIAGONAL SQUARE MATRIX
. CAN U PLZ HELP ME . ITS URGENT...
Reply

21.
YoussefDecember 12, 2011 12:35 AM
can

i'm
working
best regard ..

tell
in

me
max

how
||

plus

to
and

get
this

the
library

ieee.numeric_std.all
is

not

available

..

Reply
22.
sampathDecember 19, 2011 8:36 PM
i have to implement a matrix multiplication of 3 matrices of 64x64 to find approximation
coefficient of an image. Is it possible to implement matrix multiplication of these matrices in
FPGA with VHDL coding?
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

42

).

LoadPages

THURSDAY, MARCH 18, 2010

A VHDL Function for finding SQUARE ROOT


I have written a function for finding the square root of a unsigned number in VHDL.The function is
based on "Non-Restoring Square Root algorithm".You can learn more about the algorithm
from this paper.The function takes one unsigned number,which is 32 bit in size and returns the square
root,which is also of unsigned type with 15 bit size.The block diagram of the algorithm is given below:

Here D is the unsigned input number.R is the remainder of the operation for non-perfect squares. Q
contains the square root of 'D'.
The function is given below:

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
-- for UNSIGNED
function
variable
variable
variable
input to
variable

sqrt ( d : UNSIGNED ) return UNSIGNED is


a : unsigned(31 downto 0):=d; --original input.
q : unsigned(15 downto 0):=(others => '0'); --result.
left,right,r : unsigned(17 downto 0):=(others => '0');
adder/sub.r-remainder.
i : integer:=0;

begin
for i in 0 to 15 loop
right(0):='1';
right(1):=r(17);
right(17 downto 2):=q;
left(1 downto 0):=a(31 downto 30);
left(17 downto 2):=r(15 downto 0);
a(31 downto 2):=a(29 downto 0); --shifting by 2 bit.
if ( r(17) = '1') then
r := left + right;
else
r := left - right;
end if;
q(15 downto 1) := q(14 downto 0);
q(0) := not r(17);

--

end loop;
return q;
end sqrt;
The function can be used as follows in your main module:

--An example of how to use the function.


signal a : unsigned(31 downto 0) :="0000000000000000000000000011001
0";
--50
signal b : unsigned(15 downto 0) :=(others => '0');
b <= sqrt ( a ); --function is "called" here.
--b will contain the value "00000111" ( equals to 7) once the
operation is done.
For using the function you have to copy the code snippet between the green lines and put it in a
package.If you don't know about how to include functions in packages then you can learn it here.
Note :- This function is synthesizable.
Posted by vipin at 5:15 PM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
Omar SalimApril 2, 2010 10:25 PM
Hye GURU!!! I'm a beginner in VHDL. i have a coding for square root operation. i key in data for
D and the answer appears in square root. so half of my job i done.. but the prob is, i need to
interface with a keypad (to key in input for D) and display at LCD (output). somethng like a
calculator.. can u help me with the VHDL code.. i'm using a 3x3 keypad and spartan 3 starter kit
LCD. Help me plizz!!! thnks =)
Reply
2.
thomasMay 11, 2010 7:52 PM
I'm

really

for
[...]
q(15
q(0)
end
As
q(15
q(0)

confused

about

in

downto

0
1)

:=

:=
I

know
downto

you
1)
:=

your

...

to

15

q(14
not

downto

0);
r(17);
loop;

16
downto

times
0);
r(17);

would
:=

construct

get
q(14
not

loop

as

it

is

synthesized

as

parallel

copies

...

Don't get, how you can iteratively shift your Q without clock and just with a for loop ...
I

would

be

very

interested

about

helping

me

out

with

this

Best
Thomas

...

regards

Reply
3.
vipinMay 13, 2010 8:08 PM
@thomas
:
Good
Question.
As I am using a function for the square root operation,there is no clock involved.It is a purely a
combinational circuit.When synthesised Xilinx ISE uses LUT's(Look up tables) and some MUX'x
for
implementing
it
in
hardware.
If you try synthesising it yourself you can see that a group of LUT's and MUX'x are connected in
a cascaded fashion.This means that the logic written inside 'for loop' is implemented 15 times to
realize the logic without clock.As you can see that this uses so much resources,but using
functions
is
an
easy
way
to
write
codes.
If you are concerned about the over use of logic gates, use a clock to implement the logic.This
may
reduce
the
logic
gate
usage
by
approximately
15.
(Note :- Shifting is not done in parallel here.)
Reply
4.
nagarajaFebruary 16, 2012 10:03 AM
while execution it is giving error . that is expecting entity or architecture near the function

with
nagaraja.v

regards

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

43

).

LoadPages

THURSDAY, MARCH 18, 2010

Entity Instantiation - An easy way of Port mapping your


components
In the earlier part of this blog I have given some common method of declaring and port mapping your
components in the main module.This article is a continuation of that one.If you are not aware of any port
mapping methods I recommend you to go through the old article here.
The disadvantage with the older port mapping methods was that,you needed to copy your component
declaration in your main modules.This can result in larger code size.With entity instantiation method you

can save some extra length in the code.


Let me show this method using the old fulladder-halfadder module.We are going to implement the
following block diagram in VHDL.

The half adders are implemented as follows:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity halfadder is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
sum : out STD_LOGIC;
carry : out STD_LOGIC
);
end halfadder;
architecture Behavioral of halfadder is
begin
sum <= a xor b;
carry <= a and b;
end Behavioral;
--The top module 'full adder' is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--top module(full adder) entity declaration
entity fulladder is
port (a : in std_logic;
b : in std_logic;
cin : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end fulladder;
--top module architecture declaration.
architecture behavior of fulladder is
signal s1,c1,c2 : std_logic:='0';
begin
--instantiate and do port map for the first half adder.
HA1 : entity work.halfadder port map(a,b,s1,c1);
--instantiate and do port map for the second half adder.

HA2 : entity work.halfadder port map(s1,cin,sum,c2);


carry <= c1 or c2; --final carry calculation
end;
Note the lines starting with 'HA' in the above code.Here is where we port map the component 'half
adder'.Note that 'work' is the default directory where all your project files will be compiled into.'halfadder' is
the component name as defined in the first code. Remember to give the inputs and outputs in the same
order as given in the definition of your component.
If you don't want to give the inputs in any particular order then you can also port map in the following
way:

--first half adder instantiation.


HA1 : entity work.halfadder port map(
a => a,
b => b,
sum => s1,
carry => c1
);
--second half adder instantiation.
HA2 : entity work.halfadder port map(
a => s1,
b => cin,
sum => sum,
carry => c2
);
The RTL schematic generated by the Xilinx XST is given below :

Note :- Use "Entity Instantiation" method as much as possible to port map your components.
Posted by vipin at 12:25 PM

Reactions:
Labels: port mapping, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
Raphael AndreoniAugust 3, 2010 10:25 PM
Your blog is helping me a lot with my studies in vhdl. The tutorials are very well explained and
easy to understand. Thank you very much.
Reply

2.
vipinAugust 4, 2010 8:20 AM
@Raphael : thanks.happy to know that I am able to help people.
Reply
3.
RobertDSeptember 9, 2010 12:04 AM
I have been using VHDL for 3 years now. Thanks very much for your blog as it has helped
explain some of the finer details. This kind of info is hard to come by. Will try to contribute if
possible.
Reply
4.
vipinSeptember 10, 2010 1:58 AM
Thanks, RobertD. I am happy that I am able to help people in some way.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

44

).

LoadPages

WEDNESDAY, MARCH 17, 2010

A VHDL function for division two unsigned numbers


I have written a function for division of variables in VHDL.The function is based on "Restoring
Division algorithm".You can learn more about the algorithm here.The function takes two unsigned
numbers(dividend and divisor) of the same size and returns the quotient,which is also of unsigned type
with the same size.The function is a generalized one and can be used for any size of inputs.

function
variable
variable
variable
variable

divide (a : UNSIGNED; b : UNSIGNED) return UNSIGNED is


a1 : unsigned(a'length-1 downto 0):=a;
b1 : unsigned(b'length-1 downto 0):=b;
p1 : unsigned(b'length downto 0):= (others => '0');
i : integer:=0;

begin
for i in 0 to b'length-1 loop
p1(b'length-1 downto 1) := p1(b'length-2 downto 0);
p1(0) := a1(a'length-1);
a1(a'length-1 downto 1) := a1(a'length-2 downto 0);
p1 := p1-b1;
if(p1(b'length-1) ='1') then

a1(0) :='0';
p1 := p1+b1;
else
a1(0) :='1';
end if;
end loop;
return a1;
end divide;
The function can be used as follows in your main module:

--An example of how to use the function.


signal a : unsigned(7 downto 0) :="10011100";
signal b : unsigned(7 downto 0) :="00001010";
signal c : unsigned(7 downto 0) :=(others => '0');
c <= divide ( a , b ); --function is "called" here.
For using the function you have to copy the code snippet between the green lines and put it in a
package.The libraries I have used are given below:

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

-- for UNSIGNED

If you don't know about how to include functions in packages then you can learn it here.
Note :- This function is synthesizable.The code doesn't work for negative numbers.
Posted by vipin at 8:50 PM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

25 comments:
1.
rourabNovember 23, 2010 12:35 PM
is this function working for std_logic type???
Reply
2.
rourabNovember 23, 2010 12:42 PM
is it possible to do division or modulus operation in xilinx ise without using any function or any
user own logic codes???

Reply
3.
vipinNovember 23, 2010 12:50 PM
@rourab : Why do you want to divide std_logic types. You can then use some other simple code
to
get
the
result.
The division operator available in vhdl has some limitations.But in Xilinx, you can use the
"divider generator" IP core for division if you want.
Reply
4.
rourabSeptember 21, 2011 5:19 PM
I have used divider operator('/') in ISE tool in vhdl code. the test bench is fine, but when im going
to implement it on fpga board its giving error. it is saying the divider must be power of two .
why ?
Reply
5.
vipinSeptember 21, 2011 5:24 PM
@rourab : it happens. Use this function for division.
Reply
6.
rourabSeptember 23, 2011 5:46 PM
thank
you
for
reply.
actually i want modulus(%) operation. I have already implemented your function on
hardware(vertex
5),
i
just
add
a
extra
line
"m1:=a-(a1*b);"
where
m1
hold
the
modulus
value.
but particularly this line (a subtraction and multiplication) take extra resources on FPGA board
for large data width input. So i want to avoid this line. I am not going through in your algorithm.
Using this algorithm is there any way where i can find modulus value directly
Reply
7.
vipinSeptember 23, 2011 5:50 PM
@rourab: there is a "mod" operator in vhdl for doing the modulo operation on integers. You can
use that.
Reply
8.
rourabSeptember 23, 2011 9:36 PM

I have tried all the things, every thing is fine in testbench, but in case of implemantation purpose
these operators like mod, divider are not working. you can try it .. could you modify your
algorithm?
Reply
9.
vipinSeptember 26, 2011 6:38 AM
@rourab :I think it should be working. The above code does what it is supposed to do.
For your purpose I suggest you the "mod" operator available in numeric_std library. All the
source
and
destination
operands
should
be
unsigned.
function

"mod"

(L,

R:

UNSIGNED)

return

UNSIGNED;

Google for "mod" operator and you will find lot of examples.
Reply
10.
rourabSeptember 26, 2011 1:35 PM
library
use
use
use
use

IEEE;
IEEE.STD_LOGIC_1164.ALL;
IEEE.STD_LOGIC_ARITH.ALL;
IEEE.STD_LOGIC_UNSIGNED.ALL;
ieee.numeric_std.all;

---Uncomment
---any
--library
--use
entity
motor
Generic
(
Port
clk
:
input_data
:
decrypted_data
);
end
architecture
signal
signal
begin

base
temp

the
following
library
Xilinx
primitives

instantiating
code.
UNISIM;
UNISIM.VComponents.all;
is
--constrained
in
ucf
file
n
:
positive
:=
4);
(
std_logic;
--spartan
3
e
in
std_logic_vector((n-1)
downto
0);
inout
std_logic_vector((n-1)
downto
0)

in
:

Behavioral

of

((n-1)

unsigned
unsigned

I
have
tried
the
error
"mod can not have such operands in this context"

11.

if
this

motor;

temp<=
unsigned(input_data)
decrypted_data<=std_logic_vector(temp);
end

Reply

declaration
in

motor
((n-1)

is

downto
0):="1010";
downto
0);
mod

base;
Behavioral;

this

code
is

vipinSeptember 26, 2011 1:40 PM


@rourab
:
Use
only
numeric_std.
And
dont
use
std_logic_vector.
And write a simple code to test the use of mod. You are complicating it with so many type
conversions.
Reply
12.
rourabSeptember 26, 2011 5:22 PM
Now
i
have
used
-------------------------------library
IEEE;
use
IEEE.STD_LOGIC_1164.ALL;
use
ieee.numeric_std.all;
---------------------------------and
ports
are
--------------------------Port
(
--clk
:
in
unsigned;
--spartan
3
e
input_data
:
in
unsigned((n-1)
downto
0);
decrypted_data
:
inout
unsigned((n-1)
downto
0)
);
------------------------------------a
signal
--------------------------------signal
base
:
unsigned
((n-1)
downto
0):="1010";
--------------------------------------------and
i
have
written
decrypted_data<=
input_data
mod
base;
--------------------------------------testbench
is
fine
but
when
im
trying
to
implement
it,
its
saying
"Operator
must
have
constant
modulo
operand."
when
i
declare
the
base
signal
as
constant
its
saying
"The
modulo
should
be
a
power
of
2"
what should i do??
Reply
13.
vipinSeptember 26, 2011 5:31 PM
@rourab
:
try
"rem"
instead
which version of ISE are you using?

of

mod

and

see

what

happens.

Reply
14.
rourabSeptember 26, 2011 5:42 PM
Im
using
ise
i
have
tried
its
"Operator must have constant operands or first operand must be power of 2"
Reply

11.1
rem,
saying

15.
vipinSeptember 26, 2011 5:49 PM
I

think

your

tool

doesnt

support

the

mod

operator

fully.

I am not sure about this, but can you use the above code by making the following change:
return
a1;
REPLACE
IT
WITH
return
p1;
If this also doesnt work then contact me through the "contact me" page.
Reply
16.
rourabNovember 28, 2011 12:40 AM
this
Vipin
i
want
i
entity
Generic
Port
clk

works
now
to
habe
motor
(
:

dividend
divisor

use
is
n
in

fine
have
have
function
as
a
separate
written
following
--constrained
in
ucf
:
positive
:=
std_logic;

in
in

remainder
);
end

downto
downto

0);
0);

--spartan

std_logic_vector((n-1)
std_logic_vector((n-1)

out

vipin.
problem.
block.
code.
file
3);
(
e

std_logic_vector((n-1)

downto

0)
motor;

architecture
signal
signal

i
this

Behavioral
a
b

:
:

unsigned((n-1)
unsigned((n-1)

of

motor

downto
downto

0):=
0):=

(others
(others

is
=>
=>

'0');
'0');

--================================================================
signal
p1_out
:
unsigned(divisor'length
downto
0):=
(others
=>
'0');
signal
a1
:
unsigned(dividend'length-1
downto
0):=unsigned(dividend);
signal
b1
:
unsigned(divisor'length-1
downto
0):=unsigned(divisor);
signal
p1
:
unsigned(divisor'length
downto
0):=
(others
=>
'0');
begin
main:

process(clk

variable

)
:

integer:=0;

begin
if(rising_edge(clk))
for
i
p1(divisor'length-1
p1(0)
a1(dividend'length-1
p1
if(p1(divisor'length-1)
a1(0)

then
in
downto
downto

0
1)
<=
1)

to
<=
<=
<=

divisor'length-1
loop
p1(divisor'length-2
downto
0);
a1(dividend'length-1);
a1(dividend'length-2
downto
0);
p1-b1;
='1')
then
<='0';

p1
else
a1(0)
end

<=

p1+b1;
<='1';
if;

end

loop;

end
p1_out<=p1;

if;

end
process
remainder<=std_logic_vector(p1_out((divisor'length-1)

main;
0));

downto

end

Behavioral;

===========================================
i
replace
all
of
the
variable
but
i
didnt
get
the
p1, a1 and b1 did not get the any value. why this is happening??

by
desired

signal.
result

Reply
17.
swamiNovember 28, 2011 8:29 PM
Hi

vipin,

I tried this function in my Design. Unfortunately, it doesn't give the correct value..
I
1.

have
variable

Is
2.
What

p1

the
this

means?

unsigned(b'length
length

if(p1(b'length-1)
The Restoring

questions..

downto

0):=

declaration
algorithm

(others

=>

correct
has

='1')
no

condition

'0');
here?

like

then
this..

Thank you
Reply
18.
rourabNovember 29, 2011 9:17 AM
1.The
varibale
size
pi
2.
If
the
width
of
B
"if(p1(b'length-1) ='1')" it check the (n-1) for logic '1'
Reply
19.
swamiNovember 29, 2011 3:16 PM

is
input

absolutely
is
'n'

fine.
then

@rourab...
Thanks

for

the

reply.

It

works

good

now..

But, the function c <= divide ( a , b ), works only when a and b are fixed values.
I tried generating random no.s of a and b of same width, the function doesn't provide the correct
output...
Reply
20.
rourabNovember 29, 2011 7:15 PM
@swami:but i have implemented this code successfully with random no. in that case i would
prefer
to
check
ur
code,
@vipin: could u help me about my problem?
Reply
21.
vipinDecember 2, 2011 9:29 AM
@rourab : are you having problems with changing variables to signals? this is because variables
gets
updated
immediately
and
signals
after
a
delta
delay.
to make it work with signals you can do one thing. Re-write the code in the form of a state
machine.Each assignment or calculation happens in one clock cycle or in one state of the state
machine.
Reply
22.
rourabDecember 2, 2011 7:43 PM
@vipin
Obviously I will implement the design using state machine. But here i have very basic qusetion
about harware designig. I may be sounded like a fool. If i write this design using state machine it
will take sevaral clocks,design will be slow. Here in a single clock the design will execute less no.
of operations compare to "without state machine designing"(i,e in fuctions). In that case what will
be changed in resouces utilization? could FPGA reuse the slices which were used in previous
clock cycle?
Reply
23.
vipinDecember 2, 2011 7:53 PM
@rourab : state machines will lead to less throughput and but less resources.
Reply
24.
themthitchoDecember 6, 2011 1:56 PM

@all: help to me creat arithmetic paperlined block and this block use division 3 numbers 8 bit.
Thank you very much.
Reply
25.
KumarJuly 24, 2012 7:58 PM
@Vipin: How to get the reminder of the fractional value.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

45

).

LoadPages

WEDNESDAY, MARCH 17, 2010

Simple sine wave generator in VHDL


Here is a sine wave generator in VHDL.This module outputs integer values of the wave from a look up
table.In the module I have declared an array of size 30 byte ,which stores the value of sine component at
different angles.If you want to include more number of values,to increase the accuracy then you can do it
in MATLAB.Type any one of the following comment in MATLAB:
t=0 : pi/10 : 2*pi ; % for 20 values.
t=0 : pi/50 : 2*pi ; % for 100 values etc..
(then type one of the following comment)
int32(sin(t)*10000/128) %128 for 8 bit output.
int32(sin(t)*10000/512) %512 for 6 bit output etc...
Now copy the values generated and paste them in the VHDL code at the appropriate place.
The more number values we use and the more bits we use,higher the accuracy is.But if the memory
resources is limited then you should reduce the number of values.The code can be modified for efficient
use of memory so that,only the first (pi/2) values are stored in the ROM.
If the frequency of your wave is very less then it is better you increase the number of values.Otherwise
there will be lot of high frequency components in your output wave.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; --try to use this library as much as
possible.
entity sinewave is
port (clk :in std_logic;
dataout : out integer range -128 to 127
);
end sinewave;
architecture Behavioral of sinewave is
signal i : integer range 0 to 30:=0;
type memory_type is array (0 to 29) of integer range -128 to 127;
--ROM for storing the sine values generated by MATLAB.

signal sine : memory_type :=(0,16,31,45,58,67,74,77,77,74,67,58,45,


31,16,0,
-16,-31,-45,-58,-67,-74,-77,-77,-74,-67,-58,-45,-31,-16);
begin
process(clk)
begin
--to check the rising edge of the clock signal
if(rising_edge(clk)) then
dataout <= sine(i);
i <= i+ 1;
if(i = 29) then
i <= 0;
end if;
end if;
end process;
end Behavioral;
Let me make some comments about the above code:
1) I have used the library "NUMERIC_STD" instead of "STD_LOGIC_ARITH." and
"STD_LOGIC_UNSIGNED" here.The reason is that the last two libraries are not approved by IEEE.The
standard IEEE library is "numeric_std".So try to use this library as much as possible.Also using
std_logic_vector every where is not a good method of coding.Use integer or signed instead.In the old
codes I have written here, I have used these libraries,but I recommend not to use them.
2)Also, use "rising_edge(clk)" instead of "if(clk'event and clk='1')".
3)In the same way any wave generator can be written.Only thing you have to change is the values stored
in ROM.
4)The code is synthesizable.
Posted by vipin at 12:32 PM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

11 comments:
1.
JocelynJune 22, 2010 3:05 PM
hi!
How

do

you

do

Jocelyn
Reply
2.
vipinJune 22, 2010 3:13 PM

to

change

the

frequency

of

your

sine

wave?

@Jocelyn : The freq of the sine wave is determined by the freq of clk in the above program.Here
we need 30 clk cycles for sending one full cycle of sine values.So the period of sine wave is
(freq
of
clk/30).
Hope I am clear.
Reply
3.
prahladJuly 1, 2010 11:51 AM
heloo

jocelyn!

in the above code i have simulated and runed for 30 sin values but the out put wave does not
looks like sin! is their any settings reqired for getting out put wave in the form of sin as the below!
file://localhost/C:/Documents%20and%20Settings/Administrator/Desktop/enp
%20final/Synthesisable%20Sine%20Wave%20Generator_files/wave.gif
Reply
4.
vipinJuly 1, 2010 12:48 PM
@prahlad : I never told that the wave will look like a sine wave in the simulator.If you want to test
out use a DAC,interface it with FPGA board and connect the output of DAC to an oscilloscope.
Or another thing you can do is take a graph sheet draw the output values Vs time.You will get a
sine signal.If you still not getting contact me.
Reply
Replies

1.
sangameshFebruary 3, 2012 12:56 AM
dude iam using fpga spartan 3e ... i need 2 generate sine wave ,,,,should i use
dac and thn fpga to burn code

2.
citharthFebruary 17, 2012 4:04 PM
hi vipin can you help me in implementing PWM and random PWM in fpga...
Reply

5.
ChrisJuly 26, 2010 10:23 AM
really, people probably should be using the coregen dds compiler. but overall, this shows the
basic
concept.
A DDS will generally exploit the symmetry in the sine wave -- only 1/4th of the sine wave values

are

needed.

this allows a larger table to be used. using a lot of entries allows the user to increment by N, to
generate other frequencies.
Reply
6.
vipinJuly 26, 2010 10:31 AM
@Chris : I do agree. But if you just use core gen IP's for each and everything then how will you
learn.This is a basic code where you can see how it works.I have mentioned in this post itself
that,"The code can be modified for efficient use of memory so that,only the first (pi/2) values are
stored
in
the
ROM".
I just left it as an exercise for readers.
Reply

7.
Laserbeak43August 16, 2010 4:50 AM
Thanks,
I need to learn how to use the DAC so I can play with this!!
Reply
8.
ankurMarch 1, 2011 12:33 PM
how to interface the dac with the fpga ?
Reply
9.
NandithaMay 19, 2011 8:08 PM
The values were generated using matlab??? Is thr a formula for d generation of sine values??
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

46

).

LoadPages

MONDAY, MARCH 15, 2010

Digital clock in VHDL


Here is a program for Digital clock in VHDL.The module has one input 'clk' and 3 outputs.Each output
represents time in seconds,minutes and in hours.The module has two processes.One of them generate
the necessary clock frequency needed to drive the digital clock.The main clock frequency applied to the
module is 100 MHz.But our digital clock has to be driven at only 1 Hz.The first process does the

necessary clock division needed for this.


The second process increment the seconds,minutes and hours etc when the conditions are met.For
example at every clock cycle we increment 'seconds'.Whenever seconds reaches the value '60' we
increment 'minutes' by 1.Similarly whenever minutes reach '60' we increment 'hours' by 1.Once hours
reaches the value '23' we reset the digital clock.The VHDL code for digital clock is given below:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity digi_clk is
port (clk1 : in std_logic;
seconds : out std_logic_vector(5 downto 0);
minutes : out std_logic_vector(5 downto 0);
hours : out std_logic_vector(4 downto 0)
);
end digi_clk;
architecture Behavioral of digi_clk is
signal sec,min,hour : integer range 0 to 60 :=0;
signal count : integer :=1;
signal clk : std_logic :='0';
begin
seconds <= conv_std_logic_vector(sec,6);
minutes <= conv_std_logic_vector(min,6);
hours <= conv_std_logic_vector(hour,5);
--clk generation.For 100 MHz clock this generates 1 Hz clock.
process(clk1)
begin
if(clk1'event and clk1='1') then
count <=count+1;
if(count = 50000000) then
clk <= not clk;
count <=1;
end if;
end if;
end process;
process(clk)
begin

--period of clk is 1 second.

if(clk'event and clk='1') then


sec <= sec+ 1;
if(sec = 59) then
sec<=0;
min <= min + 1;
if(min = 59) then
hour <= hour + 1;

min <= 0;
if(hour = 23) then
hour <= 0;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
This digital clock can be used as a component in your main program.If you want to display the time in
LCD panel or use a speaker to tell the time then you need to write the appropriate VHDL code for
interfacing with such components in your FPGA board.Such programs may vary depending upon the
board and FPGA chip you are using.
Posted by vipin at 3:48 PM

Reactions:
Labels: examples, useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

16 comments:
1.
JimmySeptember 8, 2010 8:30 PM
Nice code... But I only want to ask one ques, say i have to set clock manually. How will that can
be done..
Reply
2.
MotlatsiNovember 12, 2010 9:36 AM
awsome! but how will it look like if i want the results to be displayed on the LCD
Reply
3.
timmyDecember 8, 2010 5:21 PM
i still don't understand how to generate the necessary clock frequency. For 100 MHz clock, why
you wait for 'count' till 50000000 instead of 100000000?
Reply
4.

vipinDecember 8, 2010 5:29 PM


@timmy : look at the code snippet carefully.What we are doing here is that a signal 'clk' is
toggled
whenever
the
count
reaches
50m(50
million).
This
means
that
clk='1'
for
50m
clock
cycles
of
clk1.
then
clk='1'
for
50m
clock
cycles
of
clk1.and
this
toggling
goes
on.
In
effect,
one
clock
cycle
of
clk
=
100m
clock
cycles
of
clk1.
I hope now you understand.
Reply
5.
MuhammadMarch 29, 2011 4:15 PM
can u postt the testbench for it?
Reply
6.
UzairMay 17, 2011 11:49 PM
hey....how can we adjust the time of this clock?? i mean if we press the BTN1 it should
increment or decrement the minutes.....do you have a sample code for this..??
Reply
7.
UzairMay 18, 2011 12:12 AM
Hey...do you ppl have a code which can adjust the time of the clock using its different buttons or
switches??i mean if switch/button is pressed it increment or decrements the time??kindly help
out
Reply
8.
vipinMay 18, 2011 5:42 AM
@Uzar : This is the basic code for the clock. I dont have the code for the time setting part.
Reply
9.
kalyaniAugust 24, 2011 1:03 PM
hi i wnt vhdl code for interfacing gsm and gpsm modem to fpga
Reply
10.
lOgAnSeptember 14, 2011 5:33 PM

can u send me another code for digital clock


Reply
11.
lOgAnSeptember 14, 2011 5:34 PM
hi can u send me another code for digital clock
Reply
12.
eswar chaitanyaNovember 1, 2011 7:20 PM
how to set mode pin in clock using vhdl code?
Reply
13.
prakashMarch 4, 2012 3:51 PM
can anyone help to write a vhdl program for analog to digital converter
Reply
14.
MaiaMarch 13, 2012 7:43 PM
Hi. Sorry for this newbie question. Why do you use integer type for sec,min,hour and then
convert to std_logic_vector? Why arent sec,min,hour declared as std_logic_vector in the
beginning?
Regards,
Maia
Reply
15.
Pritesh DesaiApril 12, 2012 10:23 PM
what value i am supposed to give as/ for "clk1"...?? i mean what is input here precisely if i want
to see simulation wave-forms for tis program?? ...reply ASAP....im in so hurry....plz....
Reply
16.
Pritesh DesaiApril 12, 2012 10:26 PM
hey what as an input i am supposed to put here in "clk1"???...reply ASAP....i want to see
simulation waveforms in xilinx and model sim also...plz reply ASAP........
Reply
Add comment

RELATED SEARCHES:
Page break by AutoPager. Page(

47

).

LoadPages

SATURDAY, MARCH 13, 2010

Some tricky coding methods using VHDL Attributes


Attributes are used to return various types of information about a signal, variable or type.Attributes
consist of a quote mark () followed by the name of the attribute.There are five types of attributes.They are
signal attributes,scalar attributes,array attributes etc are some of them.I will explain here the usage of the
most common attributes used in array access and manipulation.
If you are not familiar with basics of array declaration,initialization,manipulation etc then you can learn
them here.
1)signal_nameevent : This is a signal attribute.It returns the Boolean value True if an event on the signal
occurred, otherwise gives a False.

if(clk'event and clk='1') then


the clk.
output <= '1';
else
output <= input;
end if;

-- to find the positive edge of

For negative edge use " if(clk'event and clk='0') " this.
2)array_name'range : This is an array attribute which returns range of an array.This attribute can be used
to check whether a signal is zero or not.For long signals this attribute is very useful.

--Checking a 64 bit is zero or not.


signal lv,temp :std_logic_vector(63 downto 0):=(others =>'0');
if(lv /= lv'range => '0')) then
temp <= lv;
end if;
--The same method can be used to check individual array elements.
type test is array (0 to 11) of std_logic_vector(63 downto 0);
signal lv,temp : test :=(others => (others =>'0'));
variable i : integer :=0;
for i in 0 to 11 loop
if(lv(i) /= (lv(i)'range => '0')) then
temp(i) := lv(i);
end if;
end loop;
--Checking a two dimensional array is zero or not without 'for'
loop.
if(lv = (lv'range => (lv(0)'range => '0'))) then
temp <= lv;
end if;

--Initializing an array with 1's.


lv <= (lv'range => (lv(0)'range => '1'));
3)array_name'left : returns the left most index of the array.
Similarly array_name'right returns the right most index of the array.
These two attributes are used for accessing a part of the array.

--Initializing a part of the array to zeros or ones.


--64-bit elements with index 1 to 10 of lv are made '1' here.
lv(lv'left+1 to lv'right-1) <= (others => (others => '1'));
--Assigning part of an one dimensional array to another array.
signal temp2,temp3 : std_logic_vector(32 downto 0):=(others => '0')
;
temp2(temp2'left-8 downto temp2'right+8) <= temp3(temp3'left downto
temp3'right+16);
--Assigning part of a two dimensional array two another one
dimensional array.
temp2(temp2(0)'left-8 downto temp2(0)'right+8) <= lv(3)(lv(0)'left
downto lv(0)'right+16);
Note that we are using temp2(0)'left minus 8 and temp2(0)'right plus 8 because the std_logic_vector,
'temp' is declared as little endian format.For big endian formats you have to subtract from temp2(0)'right
and add to temp2(0)'left for accessing a part of the array.
Note :- There many other attributes in VHDL.I have mentioned the important ones only.You can see the
full list of attributes here.
Posted by vipin at 7:03 PM

Reactions:
Labels: useful codes, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
AnonymousMarch 13, 2010 8:20 PM
-

I'm
To

function
variable
begin
if
ret
else
ret
end
return

usually
write

using

general
max(x,

array'high/array'low

functions,
y

array'range

unsigned)

instead
is

also

of
usefull:

>
:=
:=

(silly

example)

returns

unsigned
is
unsigned(x'range);

y)

then
x;

ret:
(x

array'right/array'left

y;
if;
ret;

end;
The point is, the function can be used no matter what the range of x is (as long as x and y are of
equal size)
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

48

).

LoadPages

FRIDAY, MARCH 12, 2010

Xilinx ISE Help : Using RTL and Technology Schematics


This tutorial deals with the Xilinx ISE-synthesis tool.I have assumed that you know, how to start a
project in Xilinx ISE and run a simulation etc...
Once you have completed simulation for your design successfully you want to test it in hardware.The
first step to this is synthesizing your code.The synthesis of your VHDL code is done by XST(Xilinx
Synthesis Technology) tool,which is included in Xilinx ISE software.XST creates Xilinx-specific net-list
files called NGC files.Remember that NGC files are not always same,even for the same VHDL
code.Depending upon the family and device you have chosen you will get different NGC files.Each NGC
file has two parts : logical design data and constraints.
Let us learn how to synthesis a code and infer the reports generated by the software.Copy the
'counter' program from here.This is a 4 bit counter with reset input.Add this code to your Xilinx ISE project
and click on "Synthesis-XST".This will start the Synthesis process.Once the synthesis is done without any
errors, you can get a lot of details from the files generated by synthesis process.
1) To get an overall synthesis report,click on "View Synthesis Report".This will open a file in a new
tab,with extension .syr.From this file you can get the following information:
1) Synthesis Options Summary
2) HDL Compilation
3) Design Hierarchy Analysis
4) HDL Analysis
5) HDL Synthesis
5.1) HDL Synthesis Report
6) Advanced HDL Synthesis
6.1) Advanced HDL Synthesis Report
7) Low Level Synthesis
8) Partition Report
9) Final Report
9.1) Device utilization summary
9.2) Partition Resource Summary
9.3) Timing Summary
Also the synthesis results can be seen by viewing two type of schematics:
2)Click on "View RTL schematic" and you will see the RTL net-list generated by XST. A file will be
opened with the extension .ngr.This file is meant for viewing only.So you can't edit it.This file shows a
schematic representation of the pre-optimized design in terms of generic symbols that are independent of
the targeted Xilinx device, for example, in terms of adders, multipliers, counters, AND gates, and OR
gates etc.The .ngr schematic in this case will look like this:

You can see that there are no hardware elements present in the schematic.For knowing what
hardware elements have been used follow step 3.
3) Click on "View Technology Schematic".You can see the following image opened in a new tab,with an
extension .ngc.This file contains the detailed information of the exact elements used in FPGA chip.See
the figure below:

From the above diagram you can infer that,your design has used one 4 input LUT(Lockup Table),one 3
input LUT,one 2 input LUT and 4 FDC(a D flip-flop with asynchronous clear input).Some other elements
used are input buffer,output buffer,inverters etc.
Now double click on any one of the LUT's(say on LUT2).A new window will open as shown below.This
window provides the following information.
1)The schematic of the gate elements used inside that particular LUT.
2)The Truth Table of the function implemented by that particular LUT.
3)The Karnaugh map of the truth table.

Sometimes these schematics can be used to find out how exactly your code is mapped into
hardware.For students in VLSI or people with an interest in FPGA designs ,this tool is a boon.I was very

much excited when I first saw these schematics.


Note :- In the RTL schematic if you don't see some of the component names then visit this link for more
information.
Posted by vipin at 6:06 PM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
suravi lahiriMay 8, 2012 10:55 AM
it helps me a lot...thank u.......
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

49

).

LoadPages

THURSDAY, MARCH 11, 2010

Synthesis Error : More than 100% of Device resources are used


Consider the below program.This program simply takes two 256 bit vectors and xor them to give a 256
bit output.

entity test is
port ( clk : in std_logic;
in1 : in std_logic_vector(255 downto 0);
in2 : in std_logic_vector(255 downto 0);
out1 : out std_logic_vector(255 downto 0)
);
end test;
architecture Behavioral of test is
begin
process(clk)
begin
if(clk'event and clk='1') then
out1 <= in1 xor in2;
end if;
end process;
end Behavioral;
When you simulate the code,it will work properly.The outputs will come as expected.But when you try
to synthesis the same code the following warning will come:

WARNING:Xst:1336 - (*) More than 100% of Device resources are used.


Now, why this warning has come?The code is hardly 20 lines.But the warning says "More than 100%
of Device resources are used"!!! To know more about the warning open the "Synthesis Report".Just scroll
down the report and you will see some details under the heading "Device utilization summary".This list
shows the resources used by your program in the selected FPGA.Note down this line :
" Number of bonded IOBs:
769 out of 480 160% (*) "
Here IOB means Input or Output blocks. We are using 769 IOB's out of 480 available ones.This was the
reason for the warning.So how do we test the program.If the above program is your top module then there
is no way that you can run it in FPGA.But if this program is just a component of some main module then
you can check whether the code is synthesizable or not.Here is how you do it?Write the following code:

entity test_top is
port ( clk : in std_logic );
end test_top;
architecture behavior of test_top is
component test
--the module which ,I got warning for is
declared as a component here.
port(
clk : in std_logic;
in1 : in std_logic_vector(255 downto 0);
in2 : in std_logic_vector(255 downto 0);
out1 : out std_logic_vector(255 downto 0)
);
end component;
--declare the signals accordingly.
signal in1 : std_logic_vector(255 downto 0) := (others => '0');
signal in2 : std_logic_vector(255 downto 0) := (others => '0');
signal out1 : std_logic_vector(255 downto 0);
begin
uut: test port map (clk,in1,in2,out1);
--port map the
component.
end behavior;
Now when you synthesis the code you will not get any warnings or errors.Thus you have tested the
design which was unable to do,when you tried to synthesis it directly.What I have done here is,I wrote a
new entity with only one input - clk, by which I removed the over usage of IOB's.Then I gave my
code,which has to be tested, as a component of this code.
Note :-The error "More than 100% of Device resources are used" doesn't always means that you have to
change your FPGA.Read the synthesis report carefully to check where the problem is.The above method
is useful only for checking whether your sub-module is synthesizable or not.
Posted by vipin at 7:43 PM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment

RELATED SEARCHES:
Page break by AutoPager. Page(

50

).

LoadPages

THURSDAY, MARCH 11, 2010

Synthesis Error : Signal is connected to multiple drivers


Consider the following code:

entity test is
port ( clk1 : in std_logic;
clk2 : in std_logic;
out1 : out std_logic_vector(7 downto 0)
);
end test;
architecture Behavioral of test is
signal out2: std_logic_vector(7 downto 0);
begin
out1 <= out2;
process(clk1)
begin
if(clk1'event and clk1='1') then
out2 <= out2 + "00000001";
--increment by '1'
end if;
end process;
process(clk2)
begin
if(clk2'event and clk2='1') then
out2 <= out2 + "00000011" ;
-- --increment by '3'
end if;
end process;
end Behavioral;
The above code can be successfully compiled without any errors or warnings.But when you try to
synthesis it you will get the following errors:
ERROR:Xst:528 - Multi-source in Unit on signal <0>>; this signal is connected to multiple drivers.
ERROR:Xst:528 - Multi-source in Unit on signal ; this signal is connected to multiple drivers.
...
ERROR:Xst:528 - Multi-source in Unit on signal ; this signal is connected to multiple drivers.
This was the one of the most common errors I got, when I synthesized my first program.This error
occurs when we try to change a signal in two different processes.As you can see from the above code the
signal 'out2' is driven by two clocks,named clk1 and clk2.A multi-driven signal cannot be realized in
hardware.If the clk1'event and clk2'event occurs at the same time then,the hardware doesn't know which
statement to execute.That is why this kind of code is not synthesizable.And there is no way to solve this
error.Only option is to change your logic in some way that you can get your things done without using a

multi-driven signal.
But one interesting thing is that,even if you don't get any errors during compilation, you will not get any
simulation results with this code.The output signals will be "xx",which means "unknown".You can see the
following warning in the simulation console:
Instance /xxx/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
Note :- Never change a signal in two different processes.This will give you a warning during
simulation and will generate an error during synthesis.
Posted by vipin at 6:27 PM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
kamiqashDecember 6, 2011 3:51 PM
Hey,
The error occurs with changing a signal in two different processes with different clock or two
different
processes
with
same
clock
as
well.
For example I have a top module, one component generates clock from the say master clock,
assigns value to port on the master clock, then the port through top feeded in to the other
component running on the master clock. The port signal is just used to assign value to another
port
there.
Hope
you
get
my
point
of
view
Reader
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

51

).

LoadPages

THURSDAY, MARCH 11, 2010

Synthesis warning : Node of sequential type is unconnected in


block
Consider the following program :

entity test is
port (
clk : in std_logic;
data_in : out std_logic_vector(7 downto 0)
output
);
end test;

-- 8 bit

architecture Behavioral of test is


signal count : integer:=0; --Remember that 'integer' 32 bit
vector.
begin
--conv_std_logic_vector is a conversion function.
data_in <= conv_std_logic_vector(count,8);
--assigning output.
process(clk)
begin
if(clk'event and clk='1') then
count <= count+1;
--incrementing count.
end if;
end process;
end Behavioral;
This module when simulated will work perfectly without any warnings or errors.But when synthesized it
will give the following errors:
WARNING:Xst:2677 - Node of sequential type is unconnected in block .
WARNING:Xst:2677 - Node of sequential type is unconnected in block .
...
...
WARNING:Xst:2677 - Node of sequential type is unconnected in block .
So should you be worried about these warnings.Will the program work as expected on FPGA board?In
this case you don't need to worry about these warnings.Check the code clearly.The signal 'count' is
declared as an integer,whose default size is 32 bit.But your module output is only 8 bit.So in effect you
are not using the bits 8 to 31 of signal 'count'.So during the synthesis the software will optimize the code
so that it has minimum number of connections.That is why the warnings "node is unconnected in block".
Now even though the program will work with such warnings what if you want to remove it?How will you
get rid of such irritating warnings.Make a small change in the above code :
Replace "signal count : integer:=0;" with the following line :
"signal count : integer range 0 to 255:=0;"
What we are doing here is we are restricting the range of integer to values between 0 to 255.That is now
signal 'count' is a 8 bit integer.Warnings will not come now.
Note :- Sometimes you can neglect warnings.Remember that warnings are not errors.They are some of
the possible potential risks.But not always, they create a problem.
Posted by vipin at 10:11 AM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
JoseJune 13, 2012 2:26 PM
It's a good idea if you are working with integer signals, but. What happened if you use
std_logic_vector?
I am adding 2 std_logic_vector signals with 24 bits, and I need to reduce the result to 18 bits.
What can I do to make dissapear this warning? thanks.

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

52

).

LoadPages

THURSDAY, MARCH 11, 2010

Synthesis warning : FF/Latch has a constant value of 0 in block


Consider the following code snippet:

signal count : std_logic_vector(7 downto 0) :="00000000";


process(clk)
begin
if(clk'event and clk='1') then
count <= count+"00001000";
end if;
end process;
The above code will not generate any error or warnings during simulation but will give the following
warnings during synthesis:
WARNING:Xst:1293 - FF/Latch has a constant value of 0 in block . This FF/Latch will be trimmed
during the optimization process.
WARNING : Xst:1896 - Due to other FF/Latch trimming, FF/Latch has a constant value of 0 in block . This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch has a constant value of 0 in block . This
FF/Latch will be trimmed during the optimization process.
So should you be worried about these warnings.Will the program work as expected on FPGA board?
The answer can be YES or NO,depending upon your other parts of the program.For the above program
the answer is "YES". If you look at the code,you can see that binary value "1000" is added to a 8 bit
std_logic_vector which is initialized to zero.So in effect the LSB 3 bits of the signal 'count' will be same i.e.
'0'.So during synthesis these signals are trimmed or removed as a part of optimization process.But still
your code will work as it did during simulation.
But this is not the case always.Sometimes you may not have written your code properly,considering all
the possibilities and the signals which are actually needed may get trimmed.Then the program will fail to
work on board.
Note :- Whenever you get the above warnings,check your program carefully and make sure that the
signals which got trimmed are not needed for your logic to work.
Posted by vipin at 9:41 AM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.

Hong WeiApril 9, 2011 12:19 PM


Hi. I'm new to VHDL and hardware design in general. Could you please explain how you would
resolve the above problem? Thanks.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

53

).

LoadPages

WEDNESDAY, MARCH 10, 2010

Basic model of FIFO Queue in VHDL


Here is a basic model of FIFO(first in first out) queue. I have made some assumptions about the
operation of this FIFO.I have assumed that my writing speed is faster than my reading speed of the
queue.The comments are provided where ever needed.The size of the FIFO is 256 * 8 bit.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity fifo is
port ( clk : in std_logic;
enr : in std_logic;
--enable read,should be '0' when
not in use.
enw : in std_logic;
--enable write,should be '0' when
not in use.
dataout : out std_logic_vector(7 downto 0);
--output
data
datain : in std_logic_vector (7 downto 0);
--input
data
empty : out std_logic;
--set as '1' when the queue is
empty
full : out std_logic
--set as '1' when the queue is
full
);
end fifo;
architecture Behavioral of fifo is
type memory_type is array (0 to 255) of std_logic_vector(7 downto 0
);
signal memory : memory_type :=(others => (others => '0'));
-memory for queue.
signal readptr,writeptr : std_logic_vector(7 downto 0) :="00000000"
; --read and write pointers.
begin
process(clk)

begin
if(clk'event and clk='1' and enr ='1') then
dataout <= memory(conv_integer(readptr));
error <= '0';
readptr <= readptr + '1';
--points to next address.
end if;
if(clk'event and clk='1' and enw ='1') then
memory(conv_integer(writeptr)) <= datain;
writeptr <= writeptr + '1'; --points to next address.
end if;
if(readptr = "11111111") then
--resetting read pointer.
readptr <= "00000000";
end if;
if(writeptr = "11111111") then
--checking whether queue is
full or not
full <='1';
writeptr <= "00000000";
else
full <='0';
end if;
if(writeptr = "00000000") then
--checking whether queue is empty
or not
empty <='1';
else
empty <='0';
end if;
end process;
end Behavioral;
The above program shows an approach towards modeling a FIFO.The actual FIFO used in
communication protocols etc is more complex than the one given here.I recommend you to use CoreGen
software from Xilinx for,generating code for complex FIFO's.
Posted by vipin at 2:29 PM

Reactions:
Labels: FIFO
Email ThisBlogThis!Share to TwitterShare to Facebook

5 comments:
1.
AnonymousMarch 11, 2010 7:07 PM
--these
use
use

are

evil:
IEEE.STD_LOGIC_ARITH.ALL;
IEEE.STD_LOGIC_UNSIGNED.ALL;

--use
use ieee.numeric_std.all;

this

instead:

Reply
2.
vipinMarch 25, 2010 6:49 PM
@anonymous
:
please
see
this
http://vhdlguru.blogspot.com/2010/03/why-library-numericstd-is-preferred.html

post,

Reply
3.
roei cohenSeptember 27, 2011 2:51 PM
library
use
use
use
entity
GENERIC
(
ADDRESS_WIDTH
DATA_WIDTH
);

IEEE;
IEEE.STD_LOGIC_1164.ALL;
IEEE.STD_LOGIC_ARITH.ALL;
IEEE.STD_LOGIC_UNSIGNED.ALL;
fifo

is

:
:

integer:=32

integer:=8;---8
---32

bit
bit

port
(
clk
:
in
std_logic;
reset
:
in
std_logic;
enr
:
in
std_logic;
--enable
read,should
be
'0'
when
not
in
use.
enw
:
in
std_logic;
--enable
write,should
be
'0'
when
not
in
use.
dataout
:
out
std_logic_vector(DATA_WIDTH-1
downto
0);
--output
data
datain
:
in
std_logic_vector
(DATA_WIDTH-1
downto
0);
--input
data
empty
:
out
std_logic;
--set
as
'1'
when
the
queue
is
empty
err
:
out
std_logic;
full
:
out
std_logic
--set
as
'1'
when
the
queue
is
full
);
end
fifo;
architecture

Behavioral

of

fifo

is

type memory_type is array (0 to ((2**ADDRESS_WIDTH)-1)) of std_logic_vector(DATA_WIDTH1


downto
0);
-----distributed------signal memory : memory_type ;-- :=(others => (others => '0')); --memory for queue.----signal readptr,writeptr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); --read and write
pointers.
signal
full0
:
std_logic;
signal
empty0
:
std_logic;
begin
full
empty
fifo0:
begin

<=
<=

full0;
empty0;
process(clk,reset)

if

reset='1'

readptr
writeptr
empty0
full0<='0';
err<='0';

<=
<=

(others
(others

elsif
if
full0<='1';
else
full0<='0';
end

then
=>
=>

'0');
'0');
<='1';

rising_edge(clk)
(writeptr

if
empty0<='1';
else
empty0<='0';
end

'1'

then
=

readptr)

then

if
(readptr

;
writeptr

then

if

if
(empty0='0'
err<='1';
end

and

enr='1')

or

;
(full0='0'

and

enw='1')

if

if
memory
writeptr
end

enw='1'
and
(conv_integer(writeptr))
<=
writeptr

if
dataout
readptr
end

enr='1'

full0='0'
+

and
<=

<=

;
<=

if
memory
readptr
if

then

then
datain
'1'

;
;
;

empty0='0'
then
(conv_integer(readptr));
+
'1'
;
;

end

if;

end
end

process;
Behavioral;

fix fifo doal port ram


Reply
4.
roei cohenSeptember 27, 2011 4:32 PM
it is ram block and not distributed in my comment
Reply
5.
JasinskiApril 6, 2012 6:23 AM

This example is wrong, please correct or remove it; many people have copied it from your
website and are wasting a lot of time wondering why it does not work.
One of the reasons why it is wrong: to generate the "empty" and "full" flags, signals "readptr" and
"writeptr" should be compared with one another, and NOT with absolute values. Cohen's
example
above
is
on
the
right
direction.
To be fair, the presented code is a FIFO in the sense that the first value in is the first value out,
but it requires a reset every 256 elements. This is *not* what people want, in 99.99% of the
cases.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

54

).

LoadPages

WEDNESDAY, MARCH 10, 2010

GENERIC's in VHDL - Construction of parametrized


components
Generics allow a design entity to be described so that,for each use of that component,its structure and
behavior can be changed by generic values.In general they are used to construct parameterized
hardware components.Generics can be of any type.
Let us understand the use of "generic" with an example.

--The top module has two instantiations- a 8 bit PISO(parallel in


serial out) register and a 4 bit PISO.
--Without the use of generics these two components need a
seperate .vhd file.
--But I have used "generic" keyword to solve this problem.
entity piso is
generic ( width : integer := 7 );
--default value
is 7
port ( clk : in std_logic;
load : in std_logic;
in1 : in std_logic_vector(width downto 0);
out1 : out std_logic
);
end piso;
architecture Behavioral of piso is
signal temp: std_logic_vector (width downto 0) := (others => '0');
--initialize to zero
begin
process(clk)
begin
if (load = '0') then -- load the register
temp <= in1;
elsif (clk'event and clk = '1') then
--shift the register elements and output a single bit.

out1 <= temp(width);


temp(width downto 1) <= temp(width-1 downto 0);
end if;
end process;
end Behavioral;
--Now the instantiation of this component in top module is shown
below:
entity test is
...
...
end test;
architecture behavior of test is
component piso
generic ( width : integer := 7 );
port ( clk : in std_logic;
load : in std_logic;
in1 : in std_logic_vector(width downto 0);
out1 : out std_logic
);
end component;
--signal declarations
signal in1 : std_logic_vector(7 downto 0):="10000110";
signal in2 : std_logic_vector(3 downto 0):="1001";
signal load1,load2 : std_logic :='0';
begin
--Note down the next two lines.
--This is how you pass generic parameters to the instantiated
components.
piso1 : piso generic map (width => 7) port map(clk,load1,in1,o1);
piso2 : piso generic map (width => 3) port map(clk,load2,in2,o2);
--change the input signals as you want.
end behavior;
"generic map (width => 7)" is used to pass the generic parameter to the component.Thus,without
writing any extra code you were able to complete your design.
Note1 :- "GENERIC" is a great asset when you use your design at many places with slight change in the
register sizes,input sizes etc.But if the design is very unique then,you need not have generic parameters.
Note2 :- Generic's are synthesizable.
Posted by vipin at 10:35 AM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
ChrisJuly 26, 2010 11:27 AM

This is an example of poor coding style. This would actually make a good interview question. in
fact,
it
generally
is.
There are three things wrong with the code. Remember that synthesizable doesn't mean
"working"
or
"good".
The first mistake is that you don't define "out1" for the async "load" case. This infers extra logic,
as
now
there
is
a
priority
logic
with
load
and
clk.
The second mistake is that your async load sets "temp" to a non-constant value. why is this
bad? well, now the logic needs to set the value on the output, independent of the clock.
FURTHER, if load is deasserted before the next clock edge, this value must be latched.
lastly, the sim won't match the code. in fact, the .syr report will give this as a warning. notice that
if load is asserted, it should be async. but load isn't in the sensitivity list, so it will only get
counted if there is a clk'event. XST will ignore this, but simulators generally won't.
other, less important notes -- in almost all languages constants are ALL_CAPS. generics usually
follow
this
standard
by
most
coders.
its advisable to never instantiate components by port-order. doing such should cause you
physical pain. not only does it make the code unreadable, it leads to all types of errors.
Reply
2.
vipinJuly 26, 2010 11:40 AM
@Chris : Thanks for making a through analysis of most of my posts.It helped me learning a lot.
Anyway I agree my bad coding style, but this post was mainly for learning the usage of
"generics".I think I have succeeded in that.
Reply
3.
ChrisJuly 26, 2010 1:18 PM
Definately, though one large advantage to VHDL over Verilog2001 is with the richness of
generics. for example, you can pass an array of integers, or an array of arrays of vectors, or
records, or strings as a generic. While not commonly used, this flexibility can be helpful.
Reply
4.
FaifooDecember 18, 2010 3:17 PM
Hi
I

read

this

Pls
Let

post

try
me

show

Source: Construction

other

times.

It

to
source

that

is

very

keep
may
interview

be

good

useful.
posting.

for

community.
questions

Best
Jonathan.

regards

Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

55

).

LoadPages

TUESDAY, MARCH 9, 2010

When and how to use "constant"?


Here are some points about the keyword 'constant' in VHDL.
1)Constants are declared and initiliazed as shown below :
constant const_name : std_logic_vector(3 downto 0):="1010";
2)A constant is an object that is assigned a value only once,normally when it is declared.This value
cannot be changed later in the program.constants are used as a part of making more readable codes
because by changing the value at only one point you can make a change throughout the program.
3)When a constant is declared in a package, its name and type must be specified.But the assignment can
be done either as part of its declaration in the package or it can be given in the package body.To know
more about packages click here.
Note :- Use constants whenever you are going to use a particular value at many places in your
program.This will make your code more readable.
Posted by vipin at 5:12 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

56

).

LoadPages

TUESDAY, MARCH 9, 2010

Variables and Shared Variables


Variables :
Variables declared in a function are initialized every time a call is made to the function.Values of variables
do not persist between function calls.Functions use variables only to store intermediate values.A signal's
value is updated only after a small time interval,but in case of variables the data is updated instantly.
These things should be kept in memory when you are opting between signals and variables.The design
may not work as you have expected,if you write your code without keeping these things in mind.
Variables are assigned and changed using the ":=" operator.

--for example:
variable var_name : integer :=0;
Variables are synthesizable.
Shared Variables :
Shared variables are specific type of variables which can be used in two processes at the same
time.But they are not synthesizable.Using shared variables is risky sometimes.You should take care that
when one process is using the shared variable the other process should not use it.Otherwise simulation
will terminate.
Posted by vipin at 4:45 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:
1.
AnonymousMarch 16, 2010 6:47 PM
"Variables

are

reset

each

time

the

function

or

process

is

called."

No they aren't!
Reply
2.
vipinMarch 16, 2010 7:35 PM
For a process - the variable can be used within that process only.And you have to initialize that
variable during declaration.So whenever the process in evoked the variable get initialized to its
old
value.
process(clk)
begin
variable
example
:
integer
:=0;
--other
statements;
end
process;
Now each time clk changes your variable value get initialized to zero.Am I wrong here?
Now for the function,the same rule goes.Function is a combinatorial block.Variable is declared
inside this block.So whenever a function is executed the variable gets initialized back to its old
value.For
example:
function add (a : std_logic_vector(2 downto 0); b: std_logic_vector(2 downto 0)) return
std_logic_vector
is
variable
sum
:
std_logic_vector(2
downto
0):="000";
variable
i
:
integer:=0;
begin
if(i
<
3)
then
sum(i):=a(i)
or
b(i);
i
:=
i+1;
end
if;
Here I am expecting the result "sum <= a or b" but I will get only "sum(0) <=a(0) or
b(0)".Because the value of variable 'i' never goes beyond 1.

Reply
3.
vipinMarch 16, 2010 7:40 PM
But I can agree that,I cant use the term "function is called" here.Because unlike C or any other
programming language VHDL is not sequential.Its concurrent,hardware description
language.Just like in a digital circuit you cant call a block to get executed,its not possible to do it
in VHDL.If you don't want some statements ,to not get executed then you have to give
conditions using 'if statement' etc...
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

57

).

LoadPages

TUESDAY, MARCH 9, 2010

What is the difference between STD_LOGIC and BIT types?


BIT has 2 values: '0' and '1'.
STD_LOGIC is defined in the library std_logic_1164.This is a nine valued logic system.
It has 9 values: 'U', 'X', '0', '1', 'Z', 'W', 'L' ,'H' and '-'.
The meaning of each of these characters are:
U = uninitialized
X = unknown - a multisource line is driven '0' and '1' simultaneously (*)
0 = logic 0
1 = logic 1
Z = high impedance (tri state)
W = weak unknown
L = weak "0"
H = weak "1"
- = dont care
Type std_logic is unresolved type because of 'U','Z' etc.It is illegal to have a multi-source signal in
VHDL.So use 'bit' logic only when the signals in the design doesn't have multi sources.If you are unsure
about this then declare the signals as std_logic or std_logic_vector,because then you will be able to get
errors in the compilation stage itself.
But many of the operators such as shift operators cannot be used on 'std_logic_vector' type.So you may
need to convert them to bit_vector before using shift operations.One example is given below:
--example of how to shift a std_logic signal : right shifting logically by 2 bits.
--count is std_logic_vector.
output <= To_StdLogicVector(to_bitvector(count) srl 2);
--to_bitvector converts Std_Logic_Vector to bit_vector.
--To_StdLogicVector converts bit_vector to Std_Logic_Vector.
Note :- Remember that use "BIT" logic type only when you are sure that the signals are NOT multi
sourced.
BIT_VECTOR is an array of BIT's.Similarly STD_LOGIC_VECTOR is an array of std_logic type.
Posted by vipin at 4:14 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
Jean-NolMay 11, 2010 3:02 PM
Good
explanation
;)
So, when you use std_logic type, it's easier to detect multisourced signal and correct if it needs
to be corrected (it appears red in modelsim wave window by example).
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

58

).

LoadPages

MONDAY, MARCH 8, 2010

Usage of components and Port mapping methods


Suppose your design is a hierarchical model.This means that you have one top module which
contains some sub-modules in it.For instance you can construct a full adder using two half adders.In this
case your full adder is the top module and half adder is the sub module.
As the full adder consists of two sub-modules, they have to be "introduced" first.This is done using a
component declaration in which all module types which will be used, are declared. This declaration has to
occur before the 'begin' keyword of the architecture statement.
Now you have to tell the number of half adder's to be used.This is done by instantiating the declared
component.Each component instance is given a unique name (label) by the designer, together with the
name of the component itself. Component instantiations are done in the definition part of an architecture
(after the keyword 'begin').
Now you have to connect the component ports to the rest of the circuit.A keyword named "port map" is
used for this purpose. It has to list the names of the architecture signals that shall be used in the submodule.
Now let us understand this by an example.VHDL code is written for the following design.

--top module(full adder) entity declaration


entity fulladder is
port (a : in std_logic;
b : in std_logic;

cin : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end fulladder;
--top module architecture declaration.
architecture behavior of fulladder is
--sub-module(half adder) is declared as a component before the
keyword "begin".
component halfadder
port(
a : in std_logic;
b : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end component;
--All the signals are declared here,which are not a part of the top
module.
--These are temporary signals like 'wire' in Verilog.
signal s1,c1,c2 : std_logic:='0';
begin
--instantiate and do port map for the first half adder.
HA1 : halfadder port map (
a => a,
b => b,
sum => s1,
carry => c1
);
--instantiate and do port map for the second half adder.
HA2 : halfadder port map (
a => s1,
b => cin,
sum => sum,
carry => c2
);
carry <= c1 or c2; --final carry calculation
end;
In the above method of port mapping we can map the input in any order.I mean whether "a=>s1" is given
first or "b => c" is given first doesnt change the logic or generate an error.
Now let us see another method of portmapping.In this kind of port mapping replace all the contents
between "begin" and "end" in the above program with the following two lines.

HA1 : halfadder port map (a,b,s1,c1);


HA2 : halfadder port map (s1,cin,sum,c2);
carry <= c1 or c2;
The order in which we write the signal names inside the brackets are important here.This method, if
carefully
written is a great way to reduce unnecassary length of the code.
Note :- Components are valuable part of design when it comes to hierarchical design.It is important to
declare and instantiate them properly for your design to work correctly.
Posted by vipin at 6:13 PM

Reactions:
Labels: port mapping, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

6 comments:
1.
RavindarMarch 27, 2010 11:59 PM
If you have a big module and you are having many components then it is recommended to put
these component definitions in a package file and call that package file in your port mapping
file.This way you will have only instantiation stuff in top file.
Reply
2.
vipinMarch 28, 2010 11:03 AM
@Ravindar : yeah..that's a nice way of handling components.. but I think entity instantiation is
better than that method.If you are using entity instantiation then you need not even have
component
definitions
in
package.
Read
about
entity
instantiation
here
:
http://vhdlguru.blogspot.com/2010/03/entity-instantiation-easy-way-of-port.html
Reply
3.
ChrisJuly 26, 2010 1:42 PM
"The order in which we write the signal names inside the brackets are important here.This
method, if carefully written is a great way to reduce unnecassary length of the code."
I disagree. I strongly believe this style should never be encouraged. Further, if you use a good
text editor you can define code-folding points. this makes any large block of code the same as 1
line.
The other reason to never use this style is because its easier to read and write code with the
ports listed. Unless you are using notepad.
Reply
Replies

1.
GuruMay 16, 2012 8:23 AM
can I have ur mail id chris
Reply

4.
vipinJuly 26, 2010 1:46 PM
@Chris : You can disagree and use the coding style you like.But I am giving that option to
coders.Let them choose the method themselves.
Reply

5.
CuriosMindDecember 15, 2011 1:56 PM
how to do cyclic pumping of 1024 point in FFT implementation on FPGA , genric code of vlsi for
this
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

59

).

LoadPages

MONDAY, MARCH 8, 2010

Is 'case' statement more efficient than 'if..elsif..else' ?


Is 'case' statement more efficient than 'if..elsif..else' statement in VHDL.The answer is "NO".Or you can
say both the statements are equally efficient when it comes to hardware implementation.
Let me show this with the help of an example.

--This program uses if..elsif..else statements for implementing the


logic.
--You need not go through the logic,as it is just given for an
example sake..
process(clk)
begin
if(clk'event and clk='1') then
count <=count+'1';
end if;
if(count ="0000") then
output1 <= "0010";
elsif(count ="0001") then
output1 <= "0011";

elsif(count ="0010") then


output1 <= "0101";
elsif(count ="0011") then
output1 <= "0110";
else
output1<="0111";
end if;
end process;
After implementing the module and synthesizing it,I got the following RTL schematic.Some synthesization
details are also given below.

Minimum period: 1.118ns (Maximum Frequency: 894.374MHz)


Minimum input arrival time before clock: No path found
Maximum output required time after clock: 3.488ns

--Now the above logic is written using the 'case' statement.


--The functionality is same for both the codes.
process(clk)
begin
if(clk'event and clk='1') then
count <=count+'1';
end if;
case count is
when "0000" => output1 <= "0010";
when "0001" => output1 <= "0011";
when "0010" => output1 <= "0101";
when "0011" => output1 <= "0110";
when others => output1 <= "0111";
end case;
end process;
I synthesized this code and got the exact results.Even the RTL schematic was exactly same for both of
the programs.
Note :- This shows that 'case' and 'if...elsif...else' statements are both equally efficient.But if you want to
write a clear code,then you better use 'case'.'case' is very useful when the output depends upon a large
number of conditions.But if the number of conditions are very small(2 or 3) then you can use
'if..elseif..else'.
Posted by vipin at 10:24 AM

Reactions:
Labels: xilinx tips
Email ThisBlogThis!Share to TwitterShare to Facebook

3 comments:
1.
ChrisJuly 26, 2010 10:39 AM
thats not the case of interest. the place the verilog coders care is the one-hot case. eg:
0001, 0010, 0100, 1000. VHDL offers a way of hinting that these cases are mutually exclusive -enumerated
types.
verilog has some synthesis switches to do a similar thing, but due to the ability to to have
overlapping cases, it can end badly.
Reply
2.
blogzworldMay 10, 2012 9:29 PM
Don't
you
use
IF/elseIf
to
target
the
critical
In your example, the path for if count="0000" would be less compared to if count="0011"

path?

Reply
3.
monsieurgutixJuly 18, 2012 10:24 AM
I'd listen that it can depend strongly of the Hardware and their manofacturer... but i don't know if
this is true or not. For example, some manofacture can recomends uses if and other uses the
case...
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

60

).

LoadPages

MONDAY, MARCH 8, 2010

How to do a clocked 'for' loop


Consider the following code.The expected output is 0,1,...,9,1,2....,10,2,3,....,11,3,4,....12 etc and they
change at every positive edge of the clock cycle.The final value will be 18.But if I run the program I will get
a constant value 18 as the output at the first positive edge of clock cycle.

process(clk)
begin
if (clk'event and clk = '1') then

for x in 0 to 9 loop
for y in 0 to 9 loop
output <= x + y;
end loop;
end loop;
end if;
end process;
The above code shows that it is not possible to write a clocked function using 'for' loop.So what do we do
in such cases.We can use two cascaded if statements in such case to get the functionality of a 'for'
loop.The following code illustrates the concept.

--I hope the code is self explanatory.


process(clk)
begin
if(clk'event and clk='1') then
if (x<10) then
if(y<10) then
--write your code here..
output <= x+y;
y<=y+1; --increment the pointer 'j'.
end if;
if(y=10) then
x<=x+1;
--increment the pointer 'i' when j reaches its maximum
value.
y<=0;
--reset j to zero.
end if;
end if;
----End of "if (i<10) then"
end if;
--End of "if(clk'event and clk='1') then"
end process;
Note :- Use this cascaded if's,only if you want a clocked 'for' loop.Otherwise stick to the conventional use
of 'for' loops.They are easy to use and easy to understand.
Posted by vipin at 10:20 AM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

4 comments:
1.
JuicyLipzMarch 11, 2010 1:35 AM
Very informative and helpful! I'm doing FPGA programming and was frustrated about the loop.
Thanks!
Reply

2.
vipinMarch 11, 2010 8:43 AM
@JuicyLipz : thanks...:)
Reply
3.
AnonymousMarch 13, 2010 11:07 PM
Thanks!
Reply
4.
ApurvaMay 16, 2012 8:45 AM
Can u pls tell me how to do it for three nested loops ?
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

61

).

LoadPages

SATURDAY, MARCH 6, 2010

VHDL coding method for Cyclic Reduntancy Check(CRC)


Most of the modern communication protocols use some error detection algorithms. Cyclic Redundancy
Check, or CRC, is the most popular one among these. CRC properties are defined by the generator
polynomial length and coefficients. The protocol specification usually defines CRC in hex or polynomial
notation. For example, CRC-8 used in ATM HEC field is represented as 0x07 in hex notation or as
G(X)=X^8 + X^2 + X^1 +1. in the polynomial notation.The code given below is capable of computing
,CRC-8 for 32 bit input.The module need 32 clock cycles for the computation.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity crc32_8 is
port ( clk : in std_logic;
data_in : in std_logic_vector(31 downto 0);
crcout : out std_logic_vector(7 downto 0)
);
end crc32_8;
architecture Behavioral of crc32_8 is

signal crc_temp : std_logic_vector(7 downto 0) := "00000000";


signal counter1 : std_logic_vector(5 downto 0):="000000";
signal dtemp : std_logic_vector(31 downto 0):=(others => '0');
begin
dtemp <= data_in;
process(data_in,clk)
begin
if(data_in /= "00000000000000000000000000000000") then
if(clk'event and clk='1') then
--CRC calculation. Function used is : X^8 + X^2 + X^1 +1.
--Edit the next 8 lines to compute a different CRC function.
crc_temp(0) <= data_in(31-conv_integer(counter1(4 downto 0))) xor c
rc_temp(7);
crc_temp(1) <= data_in(31-conv_integer(counter1(4 downto 0))) xor c
rc_temp(7) xor crc_temp(0);
crc_temp(2) <= data_in(31-conv_integer(counter1(4 downto 0))) xor c
rc_temp(7) xor crc_temp(1);
crc_temp(3) <= crc_temp(2);
crc_temp(4) <= crc_temp(3);
crc_temp(5) <= crc_temp(4);
crc_temp(6) <= crc_temp(5);
crc_temp(7) <= crc_temp(6);
--CRC calculation is finished here.
--counter increment.
counter1 <= counter1 + '1';
end if;
if(counter1 ="100000") then --counter for doing the CRC operation
for 8 times.
crcout <= crc_temp;
crc_temp <="00000000";
counter1 <= "000000";
else
crcout <= "00000000";
--CRC output is zero during idle time.
end if;
else
--CRC output is zero when input is not given or input is zero
crcout <= "00000000";
crc_temp <="00000000";
counter1 <= "000000";
end if;
end process;
end Behavioral;
When the input is zero or not given the output stays at zero.This module can be edited to calculate
other CRC functions and for different input lengths.If you require program for a different CRC function
leave a comment here.I will try to post the code as soon as possible.

Posted by vipin at 8:21 PM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

7 comments:
1.
[p] January 17, 2011 10:21 PM
why the output is zero even i already put in the input?
Reply
2.
vipinJanuary 17, 2011 10:28 PM
I have tested this code in Xilinx ISE 10.1. It worked successfully. Please check your simulation
and testbench code.
Reply
3.
[p] January 17, 2011 10:48 PM
sorry, i am new in vhdl. i ran this code in quartus 9.0. i set the all the input to HIGH (1). however,
the output is all zero.
Reply
4.
vipinJanuary 17, 2011 11:02 PM
If you use all the inputs as '1' then I think the output is supposed to be '0'.
First calculate the output manually and then check it with the code.
Reply
5.
[p] January 17, 2011 11:08 PM
I will give it a try. Because initially, I set the input randomly but the output is "0". So i thought of
setting all the input to "1"
Reply
6.
Kumar SwamyMarch 1, 2011 6:21 AM

Hey dude, i need to generate CRC-16 using X^16 + X^12 + X^5 +1 as my generator polynomial.
Initial value of FFFFh and residue of F0B8h. This is according to ISO13239 standard.
Thanks
Reply
7.
SafwenOctober 21, 2011 7:56 PM
hi everyone , thanks for the code, but my input is a std_logic_vector(14023 downto 0) how can
adapt this code ?? thanks for answer :)
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

62

).

LoadPages

SATURDAY, MARCH 6, 2010

VHDL code for BCD to 7-segment display converter


Here is a program for BCD to 7-segment display decoder. The module takes 4 bit BCD as input and
outputs 7 bit decoded output for driving the display unit.A seven segment display can be used to display
decimal digits.They have LED or LCD elements which becomes active when the input is zero.The figure
shows how different digits are displayed:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test is
port (
clk : in std_logic;
bcd : in std_logic_vector(3 downto 0);

--BCD input

segment7 : out std_logic_vector(6 downto 0) -- 7 bit


decoded output.
);
end test;
--'a' corresponds to MSB of segment7 and g corresponds to LSB of
segment7.
architecture Behavioral of test is
begin
process (clk,bcd)
BEGIN
if (clk'event and clk='1') then
case bcd is
when "0000"=> segment7 <="0000001"; -- '0'
when "0001"=> segment7 <="1001111"; -- '1'
when "0010"=> segment7 <="0010010"; -- '2'
when "0011"=> segment7 <="0000110"; -- '3'
when "0100"=> segment7 <="1001100"; -- '4'
when "0101"=> segment7 <="0100100"; -- '5'
when "0110"=> segment7 <="0100000"; -- '6'
when "0111"=> segment7 <="0001111"; -- '7'
when "1000"=> segment7 <="0000000"; -- '8'
when "1001"=> segment7 <="0000100"; -- '9'
--nothing is displayed when a number more than 9 is given as
input.
when others=> segment7 <="1111111";
end case;
end if;
end process;
end Behavioral;
If you want a decimal number to be displayed using this code then convert the corresponding code into
BCD and then instantiate this module for each digit of the BCD code.
Here is a sample test bench code for this module:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
ENTITY test_tb IS
END test_tb;
ARCHITECTURE behavior OF test_tb IS
signal clk : std_logic := '0';
signal bcd : std_logic_vector(3 downto 0) := (others => '0');
signal segment7 : std_logic_vector(6 downto 0);
constant clk_period : time := 1 ns;

BEGIN
uut: entity work.test PORT MAP (clk,bcd,segment7);
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
begin
for i in 0 to 9 loop
bcd <= conv_std_logic_vector(i,4);
wait for 2 ns;
end loop;
end process;
END;
Posted by vipin at 7:50 PM

Reactions:
Labels: useful codes
Email ThisBlogThis!Share to TwitterShare to Facebook

10 comments:
1.
AlfredMarch 25, 2010 9:20 AM
hello.. can you pls post a test bench for this code.. tnx...
Reply
2.
vipinMarch 25, 2010 10:25 AM
@Alfred : I have modified the post including the test bench.Hope that helps..
Reply
3.
AlfredMarch 25, 2010 12:57 PM
tnx a lot..
Reply
4.

YanuarMay 30, 2010 7:27 PM


thank
you,
it
is
so
useful
Can you show me, how to control a animation on vga using keyboard in vhdl

for

me.

Reply
5.
Raphael AndreoniOctober 26, 2010 1:25 AM
Hi, I'm trying to implement the sum of two numbers with 5 bits and show in two digits SSD, but
with
no
success,
do
you
have
any
idea
how
to
do
this?
I had success with decimal counter until 99, but how make this work whit the sum, I don't know.
Thanks
Reply
6.
JteslaJuly 21, 2011 2:02 AM
Can some one help me with the code for Four bit BCD decimal COUNTER using VHDL and the
74LS90. I'm using Xilinx 12.1 and I'm really struggling with the logic gate code.
my email is jct0378@gmail.com
Reply

7.
sumdtOctober 19, 2011 10:25 PM
Please
Write
which
display
X
Y

help
a

VHDL
code
to
perform
the
inputs
are
from
Dip
to
7-segment
LED
:
dip
1~4represents
:
dip
5~8represents

the

me!
function
of
Switch
and
with
value
value

multiplier
outputs
BCD.
0~15
0~15

Thanks you so much


Reply
8.
sandeepOctober 21, 2011 6:43 PM
write a VHDL prog to display number on BCD-7 segment display , input given from ps/2
keyboard
Reply
9.
mar&#39;dDecember 21, 2011 7:55 PM

can you help me to get a VHBL program for 64 bit CSA


Reply
10.
blogzworldMay 8, 2012 10:50 PM
Can you post the synthesis report.
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

63

).

LoadPages

FRIDAY, MARCH 5, 2010

Some useful VHDL data types


I have given a list of very commonly used data types in VHDL.Some of these are very interesting and
useful.

type e is (low,high,medium,very_high,very_low);
signal xs : e :=high;
if( xs = high ) then
....

--"downto" used for little endian notation.


--"to" used for big endian notation.
signal x : std_logic_vector (0 to 5):="110001";
x(4)<='1'; -- this will result in x="110011";
x(0)<='0'; -- this will result in x="010011";

type blahblah is
record
a1 : std_logic_vector(3 downto 0);
a2 : std_logic_vector(2 downto 0);
a3 : integer;
end record;
signal x : blahblah :=("1010","110",23);
(OR you can initialize as shown below)
x.a1 <="1010";
x.a2 <="110";
x.a3 <=23;

signal x : std_logic_vector (15 downto 0);


signal y : std_logic_vector (23 downto 0);
--This is correct.But make sure that the size of left and right
hand operands(x and y) are same.
x(8 downto 3) <= y(19 downto 14);

--"Range" is used for specifying the range of data types.


type day is Range 1 to 31;
type volt isRange 12 downto -12;
--declaring the object "in_volts".The range of the signal is a
subset of the full range of "volt" type.
signal in_volts : volt Range 5 downto -5;

--The below type is not synthesizable,but can be used in simulation


level.
--This kind of format can be used for writing easily understandable
code.
type distance is Range 0 to 10000000
units
cm;
m =100 cm;
km =100000 cm;
end units distance;
signal xs : distance;
xs <= 10 km; --xs =1000000.
I will update this list if I come across other data types.Hope you find this useful.
Posted by vipin at 6:45 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment

RELATED SEARCHES:
Page break by AutoPager. Page(

64

).

LoadPages

FRIDAY, MARCH 5, 2010

Can you change a signal at both positive and negative edges of


the clock?
Consider the following code:

signal c : std_logic_vector(3 downto 0):="0000";


process(clk)
begin
c <= c +'1';
end process;
This code is supposed to work as a simple 4 bit counter,counting at both negative and positive edge of
the clock.The design works perfectly in the simulation level.But when you synthesize this code you will get
the following warnings :
WARNING:Xst:647 - Input is never used. This port will be preserved and left unconnected if it belongs to
a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c4.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c6.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c_cy<0>.
Normally warnings can be neglected during synthesis.But in this case "the input clk is never used".So
the basically the design will not work.It is just a combinatorial circuit with feedback.
Now if you write the code in the following way then you will get a synthesis error.
"Signal c cannot be synthesized, bad synchronous description. The description style you are using
to describe a synchronous element (register, memory, etc.) is not supported in the current software
release."

process(clk)
begin
if(clk'event and clk='1') then
c <= c +'1';
end if;
if(clk'event and clk='0') then
c <= c +'1';
end if;
end process;

-- for posedge
--for negedge

These code clearly shows that it is not possible to change a signal at both negative and positive edge of
the clock.Xilinx ISE either synthesizes it badly or it gives an error.
Posted by vipin at 3:34 PM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
ArseniJanuary 8, 2011 9:04 PM
ok

but

bla
BEGIN
if
C
else
C
end
END

:
A

what
PROCESS(A,
=
<=

<=

about:

(others

B)

'1'
=>

then
B;
'Z');
if;
PROCESS;

that synthesizes fine for me


Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

65

).

LoadPages

FRIDAY, MARCH 5, 2010

Xilinx error :- Simulator:702 - Can not find design unit xxx in


library work located at isim/work
How to solve the following error in Xilinx ISE :
"Simulator:702 - Can not find design unit xxx in library work located at isim/work"
You can try two methods to solve this error:
1) Go to main menu -> Project -> Cleanup Project files. Click 'ok'. Now run the simulation again. If the
error is still on then go to step 2.
Note:-Cleaning up project files removes the generated synthesis and implementation files from the
current project directory.This operation is final and you can not undo this procedure after you perform it.If
you want to avoid loss of data, then create a backup copy of the project.For creating a back up for your
project :
Select Project > Take Snapshot.
In the Take a Snapshot of the Project dialog box, enter a name for your snapshot in the Snapshot
Name field.
In the Comment field, add any notes related to this version of your project. Comments are optional.
Click OK.
2)Create a new project and add all the files in your current project to the new project.Now simulate the
design.It should work now.
Posted by vipin at 9:52 AM

Reactions:
Labels: xilinx errors
Email ThisBlogThis!Share to TwitterShare to Facebook

No comments:
Post a Comment
RELATED SEARCHES:
Page break by AutoPager. Page(

66

).

LoadPages

THURSDAY, MARCH 4, 2010

A synthesizable delay generator instead of 'wait for' statement


There are many situations in which you may need to activate a process after a certain delay or at fixed
time intervals.If you want to do simulation alone for your design then you can simply use "wait for"
statement to call a delay routine.But this keyword is not synthesizable.So what will you do in such
situations?
A simple delay routine,which is synthesizable, can be designed using the properties of a "MOD-n
counter".A MOD-n counter can be used to generate a frequency of (f / n) using a frequency 'f'. The code
for generating such a delay is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test is
port (clk : in std_logic;
--delay to be generated.
a : in std_logic_vector(31 downto 0);
--this is a pulse to notify that time interval equal to delay is
over.
flag : out std_logic
);
end test;
architecture Behavioral of test is
signal count :integer:=0;
begin
process(clk)
begin
if(clk'event and clk='1') then
count <= count +1;
--increment counter.
end if;
--see whether counter value is reached,if yes set the flag.
if(count = conv_integer(a)) then
count <= 0;
flag <='1';
else
flag <='0';

end if;
end process;
end Behavioral;
The module has 2 inputs0- clock and a vector which determines the amount of delay to be generated.
Say you want a 100 ns delay.Now say your clk frequency is 1 GHz,that is your clock period is 1 ns.So the
value of 'a' should be equal to (100 / 1) = 100.When the counter counts till 100, it sends a pulse to
notify.Below is an example of how to do it :

---- a program which uses a delay routine of 100 ns.


architecture Behavioral of your_module is
signal flag : std_logic :='0';
signal delay_needed : std_logic_vector(31 downto 0);
delay_needed <= "00000000000000000000000001100100"; --100 in
binary.
inst_delay : test port map(clk,delay_needed,flag);
begin
process(flag)
begin
if(flag'event and flag='1') then
output <= calculated; -- this line is executed only once in 100
ns.
end if;
end process;
end Behavioral;
This small code can be used under many situations,like :
1) To run some parts of your design at a lesser clock frequency than your system clock.
2) To create a delay between some of the processes.
The range of delay values can be increased by increasing the size of 'a'.Also the maximum error in the
delay produced is equal to time period of input clock.
Posted by vipin at 3:57 PM

Reactions:
Labels: vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

6 comments:
1.
KartikAugust 23, 2010 8:43 PM
Thanks
Can I have the same in verilog?

for

the

code,

Reply
2.
vipinAugust 23, 2010 8:45 PM
@kartik : yeah. You can use the basic idea here to write a similar code in verilog.
Reply

3.
nebulaOctober 24, 2010 4:49 PM
but how do i use this in a desgin code? for example if i want to implement a flip flop how do i
encode this mod-n counter in the code for flip flop...can u please give an example? I'm a novice.
Reply
4.
vipinOctober 24, 2010 4:56 PM
@nebula : any MOD-n counter can be designed using flip flops.You just have to reset all the flip
flops when the output reaches the particular count.If it is 3 bit counter , and you want the max
count to be "5" then the reset input of all FF's should be connected to R= count(0) xor (not
count(1)) xor count(2).
Reply
5.
DEEPTHIApril 30, 2011 11:06 PM
Hi,
Is there any other way other than a counter to make the delay synthesizable.
Suppose if dealy to be introduced is 8.114ns, then how to add a delay element for 8.114ns and it
has to be synthesizable.
Reply
6.
fpgap12March 11, 2012 4:14 PM
I get a warning "line 18: One or more signals are missing in the process sensitivity list. To enable
synthesis of FPGA/CPLD hardware, XST will assume that all necessary signals are present in
the sensitivity list. Please note that the result of the synthesis may differ from the initial design
specification.
The
missing
signals
are:
"
and
I
dont
get
output
if
I
add
count
to
the
sensitivity
list....
what shall I do?
Reply
Add comment

RELATED SEARCHES:
Page break by AutoPager. Page(

67

).

LoadPages

WEDNESDAY, MARCH 3, 2010

Usage of Packages and functions


Packages are the only language mechanism to share objects among different design units. Usually, they
are designed to provide standard solutions for specific problems, e.g. data types and corresponding
subprograms like type conversion functions for different data types, procedures and functions for signal
processing purposes, etc.A package is declared in the following format :

package package_name is
-- Declaration of
-- types and subtypes
-- subprograms
-- constants, signals etc.
end package_name;
package body package_name is
-- Definition of previously declared
-- constants
-- subprograms
-- Declaration/definition of additional
-- types and subtypes
-- subprograms
-- constants, signals and shared variables
end package_name;
--An example for a module using package..
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--note this line.The package is compiled to this directory by
default.
--so don't forget to include this directory.
library work;
--this line also is must.This includes the particular package into
your program.
use work.test_pkg.all;
entity test is
port (clk : in std_logic;
a1 : in t1;
b1 : in t1;
c1: out t1

);
end test;
architecture Behavioral of test is
begin
process(clk)
begin
if(clk'event and clk='1') then
c1<=add(a1,b1);
--for doing xor operation at every positive edge
of clock cycle.
end if;
end process;
end Behavioral;

--Package declaration for the above program


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
package test_pkg is
type t1 is --a data type(totally 32 bits contains 3 different
fields)
record
a :std_logic_vector(11 downto 0);
b :std_logic_vector(15 downto 0);
c :std_logic_vector(3 downto 0);
end record;
--function declaration.
function add (a2 : t1; b2: t1) return t1;
end test_pkg;
--end of package.
package body test_pkg is --start of package body
--definition of function
function add (a2 : t1; b2: t1) return t1 is
variable sum : t1;
begin -- Just name the fields in order...
sum.a:=a2.a xoR b2.a;
sum.b:=a2.b xoR b2.b;
sum.c:=a2.c xoR b2.c;
return sum;
end add;
--end function
end test_pkg; --end of the package body
The above program calculates the 'xor' of a 32 bit data type containing 3 fields.If you don't use a
function then it is not possible to directly apply the 'xor' function to different data types like 't1'. If you want
to use this function at many places in your program then it is advisable to use packages(or functions).

Another advantage of packages is that by just editing the data types or functions in the package body
alone you can do some minor modifications in your design.Otherwise you may need to change your code
at lot of places.
Posted by vipin at 5:36 PM

Reactions:
Labels: functions
Email ThisBlogThis!Share to TwitterShare to Facebook

1 comment:
1.
monsieurgutixJuly 14, 2012 1:32 AM
In the package outline you can define constants at the package declaration and also at the body
(or
declaration)
part
of
the
package.
So, What is the difference between define a constant at the declaration of the package and
define
the
same
constant
at
the
body
of
package?
Thanks!
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

68

).

LoadPages

WEDNESDAY, MARCH 3, 2010

How to write a testbench?


Once you finish writing code for your design,you need to test whether it is working or not.One method
of testing your design is by writing a testbench code.Without going much into the details I will give you an
example.
Below is a program for a basic 4 bit counter with reset input :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test
port (clk :
count
reset
);
end test;

is
in std_logic;
: out std_logic_vector(3 downto 0);
:in std_logic

architecture Behavioral of test is


signal c : std_logic_vector(3 downto 0) :=(others => '0');

--

initializing count to zero.


begin
count <= c;
process(clk,reset)
begin
if(clk'event and clk='1') then
-- when count reaches its maximum(that is 15) reset it to 0
if(c = "1111") then
c <="0000";
end if;
c <= c+'1'; --increment count at every positive edge of clk.
end if;
if(reset='1') then --when reset equal to '1' make count equal to
0.
c <=(others => '0'); -- c ="0000"
end if;
end process;
end Behavioral;
Now I will give a sample test bench for the above code:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
-- entity declaration for your testbench.Dont declare any ports
here
ENTITY test_tb IS
END test_tb;
ARCHITECTURE behavior OF test_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT test --'test' is the name of the module needed to be
tested.
--just copy and paste the input and output ports of your module as
such.
PORT(
clk : IN std_logic;
count : OUT std_logic_vector(3 downto 0);
reset : IN std_logic
);
END COMPONENT;
--declare inputs and initialize them
signal clk : std_logic := '0';
signal reset : std_logic := '0';
--declare outputs and initialize them
signal count : std_logic_vector(3 downto 0);
-- Clock period definitions

constant clk_period : time := 1 ns;


BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: test PORT MAP (
clk => clk,
count => count,
reset => reset
);
-- Clock process definitions( clock with 50% duty cycle is
generated here.
clk_process :process
begin
clk <= '0';
wait for clk_period/2; --for 0.5 ns signal is '0'.
clk <= '1';
wait for clk_period/2; --for next 0.5 ns signal is '1'.
end process;
-- Stimulus process
stim_proc: process
begin
wait for 7 ns;
reset <='1';
wait for 3 ns;
reset <='0';
wait for 17 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
END;
I think the code is self explanatory.I have given comments so that you can easily follow it. Now add these
programs to your project and compile them.Once compilation is over click on "simulate Behavioral
Model".You will get the following waveform.

As you can see,whenever my reset=1,count value is zero.Otherwise count increments upto 15 and
then get reset to zero.
Now a little more explanation about the test bench code:
1) wait for 7 ns; means the simulator doesn't do anything for 7 nano second.If you want 7 ms delay
instead of 7 ns then just replace ns with ms.
2)The process named "clock_process" is must in any test bench because it is used to generate clock
for your module.Any main module always work with this clock.The period and duty cycle of the clock can
be changed by editing this process.
3)Your main module has to be given as a component in your test bench program inside "architecture".
4)Your module has to be instantiated after the 'begin' statement.
Posted by vipin at 1:45 PM

Reactions:
Labels: testbench
Email ThisBlogThis!Share to TwitterShare to Facebook

13 comments:
1.
jorisApril 21, 2010 7:37 PM
Inspecting the waveforms works for simple testbenchs, but it's easier to use VHDL asserts;
You can put them at any given point in the test bench, to check whether the received values are
as expected. This way you don't need to inspect waveforms (except when inspecting, when
asserts tell you something is wrong)
Reply
2.
Raphael AndreoniAugust 4, 2010 9:17 PM
There's an insignificant type error in line 30, intead of " count => count; " is " count => count, ".
By

the

way,

what

is

"VHDL

asserts"?

I'm

new

here.

Nice explanation.
Reply
3.
Raphael AndreoniAugust 4, 2010 11:41 PM
In ModelSim, at least for me the "time := 1 ns;" doesn't work, but, with 10 ns is just fine.
Which software did you use?
Reply
4.
vipinAugust 5, 2010 10:17 AM
@Raphael : thanks for pointing out the mistake.I used xilinx ISE version 10.1.
VHDL asserts are used to write intelligent testbenches. For these testbenches you need not see
the waveform for seeing whether the code is working or not.They are used to alert the user of
some condition inside the model. When the expression in the ASSERT statement evaluates to
FALSE, the associated text message is displayed on the simulator console.Assertion statements
can be used for complex designs where inputs and outputs have complex relation.
I will put a post on assertion statements in some time, for now see this link(under the E4
heading):
http://www.vhdl.org/comp.lang.vhdl/html3/gloss_example.html
Reply
5.

DivyaAugust 27, 2010 6:56 AM


hello can i get a link for the modified random number generator in open cores website.
thanks in advance
Reply
6.
vipinAugust 27, 2010 9:19 AM
@Divya
:
The
link
is
available
in
this
http://vhdlguru.blogspot.com/2010/08/random-number-generator-in-vhdlcont.html

post.

Just go to the project page and click on the download option.


Reply
7.
sckoarnMarch 5, 2011 1:55 AM
I
have
been
using
http://opencores.org/project,vhld_tb
For

the

VHDL

package

14+

linked

below:

years

...

Sckoarn
Reply
8.
4x4andmoreMarch 16, 2011 1:57 PM
Hi
I

have

general

question

about

testing

of

VHDL-code...

Can anyone help me out on estimating the effort needed to specify and execute (formal) tests for
VHDL?
I'm quite experienced in (software) testing & estimations but I do not have any metric's or key
figures suitable for VHDL (like the number of I/O's, lines of code, state machines etc.)
A

response

in

email

will

be

appreciated:

4x4andmore

Regards, Patrick
Reply
9.
PlakuApril 1, 2011 8:23 PM
How would you change this to be a 32 bit counter. I'm a beginner. Thanks.
Reply

gmail

dot

com

10.
anubhavJune 24, 2011 11:12 AM
hey can i get the code of a function that converts Boolean into integer .thanks in advance
Reply
11.
vipinJune 24, 2011 11:27 AM
@anubhav : A boolean has only two values TRUE and FALSE.So why do you want to convert it
to a integer. What is your actual purpose?
Reply
12.
simiAugust 25, 2011 12:04 PM
hello can i get a vhdl code for 32 bit array???i am new in this field.
Reply
13.
priyankaDecember 20, 2011 3:44 PM
hi...can i get the vhdl code for frequency multiplier without using unisim library..
Reply
Add comment
RELATED SEARCHES:
Page break by AutoPager. Page(

69

).

LoadPages

THURSDAY, FEBRUARY 25, 2010

Arrays and Records in VHDL


In many situations you may have to use a 2-D array in your design.A 2-D array can be declared in two
ways in VHDL.I will show examples:
1)Using the keyword "array".

--first example
type array_type1 is array (0 to 3) of integer; --first define the
type of array.
signal array_name1 : array_type1; --array_name1 is a 4 element
array of integers.
--second example
--first define the type of array.
type array_type2 is array (0 to 3) of std_logic_vector(11 downto 0)

;
signal array_name2 : array_type2;
array of 12-bit vectors.

--array_name2 is a 4 element

2)Array of different kind of elements.


Using array ,you can easily create an array of similar types.But what will you do if you want an array
of different type of elements,like the structures in C programming.For handling such data types there is
another keyword available in VHDL-"record".

--third example
type record_name is
record
a : std_logic_vector(11 downto 0);
b: std_logic_vector(2 downto 0);
c : std_logic;
end record;
type array_type3 is array (0 to 3) of record_name; --first define
the type of array.
signal actual_name : array_type3;
After going through the above examples you must have got an idea about array and record
declarations.Now we will see how to access them from the program.
If the array name is "var_name" then the individual elements can be accessed by the following notation :
var_name(0),var_name(1) etc....

--an example
signal test1 : std_logic_vector(11 downto 0);
test1 <= array_type2(0);
signal test2 : integer;
test2 <= array_type1(2);
--accessing the record.
a1 : std_logic_vector(11 downto 0);
b1: std_logic_vector(2 downto 0);
c1 : std_logic;
a1 <= actual_name(1).a;
b1 <= actual_name(1).b;
c1 <= actual_name(1).c;
actual_name(2).a <= "100011100011";
actual_name(1) <= (a => "100011100011", b => "101", c => '1');
actual_name(0) <= ("100011100011","101",'1');
Sometimes you may need to initialize a large array to zeros.If the array is very large then it is tedious to
initialize it using the above methods.A keyword called "others" is used in such cases.

--an example illustrating the usage of "others".


signal test4 : std_logic_vector(127downto 0) := (others =>'0');
--test5 ="00000010";
signal test5 : std_logic_vector(7 downto 0) := (1 =>'1', (others =>
'0') );
--initializing a 4 element array of 12 bit elements to zero.
array_name2 <= (others=> (others=>'0'));

--A 2-d array declaration


type array_type2 is array (0 to 3) of std_logic_vector(11 downto 0)
;
type array_type4 is array (0 to 2) of array_type2;
signal array_name4 : array_type4; --array_name4 is a 3*4 two
dimensional array.
--initialization to zeros.
array_name4<=((others=>(others=>'0')),(others=>(others=>'0')),
(others=>(others=>'0')));
Hope this small tutorial really helped you.
Posted by vipin at 6:19 PM

Reactions:
Labels: arrays and records, vhdl tips
Email ThisBlogThis!Share to TwitterShare to Facebook

19 comments:
1.
vipinFebruary 25, 2010 7:16 PM
VHDL keywords are shown in blue colour for easily differentiating.
Reply
2.
AnonymousMarch 9, 2010 11:29 AM
hi how to initialize an integer array to zero.
Reply
3.
vipinMarch 9, 2010 11:46 AM
type
example
signal
(OR)
xx <= (others => 0);

is
xx

array

(0
:

to

2)
example

of

integer;
:=(0,0);

Reply
Replies

1.
monsieurgutixJuly 13, 2012 10:12 PM
@vipin
It's
confusing....
The array has three integers, and you put signal xx : example :=(0,0);
I
ask
to
you....
It
should
be
written
as:

signal
Cause
Thanks!

xx
the

:
array

has

example
three

:=(0,0,0);
integers?

Reply

4.
ambarishApril 25, 2010 1:02 PM
This is great. Thanks man. I appreciate it. arrays in vhdl are so confusing . this really helps!!!!
Reply
5.
ChrisJuly 26, 2010 1:58 PM
you can also use "array (natural range <>) of" to allow the user to specify a size. I suggest
looking at XST's style guide for more examples.
Reply
6.
priyaSeptember 1, 2010 5:23 PM
thank u so much for the explanations with example... really useful!!
Reply
7.
rourabDecember 21, 2010 6:16 PM
i

have

type
array_type2
signal
test1
but
"The

tried
is

very
expression

array_type2,just

array
(0
to
array_name2
<=
can

streang
not
be

3)

of

copy

thes

std_logic_vector(11
:

ise
converted

to

10.1
type

lines

downto
0);
array_type2;
array_type2(0);
saying
array_type2."

how is it possible???????
Reply
8.
vipinDecember 21, 2010 6:36 PM
@rourab : its not strange. You have written "test1 <= array_type2(0)" which should be actually
"test1
<=
array_name2(0)".
Use
the
signal
name
on
the
RHS,
not
the
array
type.
IF the error still comes make sure that test1 is declared as std_logic_vector(11 downto 0).
Reply

9.
surya loyalguyJanuary 21, 2011 4:52 PM
To initialise the whole array of record to zero is there any easy statement like "others"? else
should it be initialized individually?
Reply
10.
azeMay 5, 2011 3:06 PM
why did you use 2 others to initialize a 4 element array of 12 bit elements to zero.
array_name2
<=
(others=>
(others=>'0'));
why not array_name2 <= (others=> '0');
Reply
11.
vipinMay 5, 2011 3:07 PM
@aze: i used two "others" because its a 2 dimensional array.
Reply
12.
osindgyyJune 11, 2011 11:10 AM
Hi,
I

dont

For
type

know

my_2d

how
is

to

array(4

variable
is there
row

find

the

number

downto

0,6

of

downto

eg_2d
a

way

to

find

dynamically
:=

rows

and

colums

of

0)std_logic_vector(7
:

the

number

2d

array.

example:
downto 0);
my_2d;

of

rows

and colums..
eg_2d'ROW..

Plz suggest.
Reply
13.
edggDecember 22, 2011 6:47 PM
Hi,
Could we define a type using some values of the generic? Could we use this type in the ports of
the
same/other
block?
Any
way
around
for
the
second
question?

EXAMPLE
entity
generic(
NBR_STREAM:
NBIT_STREAM
);
port(
stream1
stream2
);

(just

to

show
stream_TEST

integer
:

the

idea):
is

:=
integer

:
:

16;
10

:=
in
out

STREAM;
STREAM

ARCHITECTURE
yy
OF
zz
IS
Type STREAM is array(NBR_STREAM downto 0) of std_logic_vector(NBIT_STREAM downto
0);
BEGING
END ARCHITECTURE;
Reply

14.
harishMarch 15, 2012 11:13 PM
how to declare and initialize an array of 10 elements each of 32bits in size in VHDL...
Reply
15.
UnknownMarch 16, 2012 2:59 PM
@harish
type
type_name
signal

is

array(9
downto
sig_name

0)

of

std_logic_vector(31
:

downto
0);
type_name;

or
type
WORD
is
type
type_name
is
signal sig_name :type_name;

array(31
array(9

downto
downto

0)
0)

of
of

std_logic;
WORD;

Reply

16.
harishMarch 16, 2012 5:46 PM
can we initialize the array with the elements declared in the entity like, in my case i hv declared
elements (arr0,arr1,arr2,arr3,arr4,arr5,arr6,arr7,arr8,arr9) with bit_vector(31 downto 0) in entity..
ex:type
type_name
is
array(9
downto
0)
of
std_logic_vector(31
signal sig_name : type_name:=(arr0,arr1,arr2,arr3,arr4,arr5,arr6,arr7,arr8,arr9);
Reply

downto

0);

17.
DaveMarch 27, 2012 9:14 PM
Why

not

Architecture
signal INPUT

behavior
std_logic_vector

just
(19

of
downto

0)

:=

use:
testbench
is
"00000000000000000000";

?
Reply
18.
monsieurgutixJuly 13, 2012 8:28 PM
Excuse
The
For

me,
arrays
example,

on
I

VHDL
can
can
define
a

has
new

Thanks a lot.
Reply
Add comment
Newer PostOlder PostHome
Subscribe to: Post Comments (Atom)

DOWNLOAD THIS ARTICLE AS PDF

SEARCH THIS BLOG


Search

TRANSLATE THIS PAGE

GET UPDATES
Enter your email address:

Subscribe

dimensions
tipe
with

beyond
5D

2D?
array.

Delivered by FeedBurner

LIKED THIS BLOG ?


LABELS

vhdl tips (28) examples (20) useful


model (4) core

generator (4) state

package (3) flipflops (3) functions(3) port


model (2) LFSR (2) counters (2) interview

codes(14) xilinx errors (9) xilinx tips (9) Behavior level

machine (4) block

RAM(3) file
handling (3) fixed
point
mapping (3) real
variable (3) testbench (3) Gate
level
Q's (2) BCD
converter(1) Buffers (1) C
and
VHDL (1) FFT (1) FIFO (1) FIR

filter (1)Frequency measurement (1) arrays and records (1) coe file (1)comparator (1) distributed RAM (1) frequency multiplier (1) gated
clock (1) generate (1) pipelining (1) power reduction (1) resets (1)sensitivity list (1) sequence detector (1) stack (1) xilinx isim (1)

BLOG ARCHIVE

2012 (6)

2011 (16)

2010 (74)

December 2010 (1)

November 2010 (1)

October 2010 (4)

Sequence detector using state machine in VHDL

How to use coe file for initializing BRAM

Design and simulation of BRAM using Xilinx Core ge...

A 3 bit Magnitude Comparator using logic gates

September 2010 (7)

August 2010 (3)

July 2010 (2)

June 2010 (1)

April 2010 (10)

March 2010 (44)

February 2010 (1)


VISITORS

MY FAVORITES

VHDL Official Website


VHDL Usenet group
Digital Design and
Programming
VHDL-2008 Support
library
The Digital Electronics
Blog

TOTAL PAGEVIEWS

889900
Simple template. Powered by Blogger.

Вам также может понравиться