Step by Step tutorial to design adder in VHDL

| 0 comments |
Suppose you want to design a full adder in VHDL than how will you start creating it? In this tutorial we will start from scratch to illustrate how to design a full adder from truth table to actual implementation using VHDL software.

A full adder has 3 inputs and 2 outputs. The 3 inputs are x, y which are the bits to be added and the carry input cin from previous calculation. The outputs are z which is the result of addition and cout which is the carry output.

The first step would be write down the truth table for the full adder. The truth table for the full adder is shown below.



To find the Boolean Function solution we can use Karnaugh map. There are software available which can minimize the function. One such software is the Karnaugh Map Analyzer.

Using Karnaugh Map Analyzer the solution is for Sum(S):
S =  xyz+xyz+xyz+xyz

And the solution for Carry C is,
C = xz+yz

Now lets implement this circuit in VHDL using VHDL software. The vhdl code of the above Boolean equations is below:

library ieee;
use ieee.std_logic_1164.all;

entity full_adder is
    port(
    x,y,z : in std_logic;
    s,c : out std_logic   
    );
end full_adder;

architecture full_adder_arch of full_adder is
begin
    s <= ((x) and (not y) and (not z)) or ((not x) and (y) and (not z)) or ((not x) and (y) and (z)) or ((x) and (y) and (z));
    c <= (x and (not z)) or (y and z);
   
end full_adder_arch;

Now the simulation waveform for input xyz=110 and xyz=111 is shown below:



The above figure shows that the circuit behaves correctly.

Next if we want to design higher order adder circuit like 4 bit adder then we can just use the above 1 bit full adder to make a 4 bit adder.

The VHDL code is shown below,

library ieee;
use ieee.std_logic_1164.all;

entity adder_ckt is
    port(
    a,b : in std_logic_vector(3 downto 0);
    cin : in std_logic;
    sum: out std_logic_vector(3 downto 0);
    cout : out std_logic
    );
end adder_ckt;

architecture adder_ckt of adder_ckt is

component full_adder is
    port(
    x,y,z : in std_logic;
    s,c : out std_logic   
    );
end component;

signal sig1,sig2,sig3 : std_logic;

begin

    adder1: full_adder port map(x => a(0), y => b(0), z => cin, s => sum(0), c => sig1);
    adder2: full_adder port map(x => a(1), y => b(1), z => sig1, s => sum(1), c => sig2);
    adder3: full_adder port map(x => a(2), y => b(2), z => sig2, s => sum(2), c => sig3);
    adder4: full_adder port map(x => a(3), y => b(3), z => sig3, s => sum(3), c => cout);
       
end adder_ckt;

In the above VHDL code some notes can be taken.

First never write entity name and architecture name beginning with numeric letter(0 to 9). For example 4bit_adder for the entity name  will throw error by the VHDL software like aldec. The error will say-

# Error: COMP96_0018: <name>.vhd : (5, 8): Identifier expected.
# Error: COMP96_0016: <name>.vhd : (5, 9): Design unit declaration expected.

The second thing has to do with instantiation. In the above VHDL code sig1, sig2, sig3 were declared as internal intermediate signals. We could have equally defined those required intermediate signals as:
signal sig : std_logic_vector(2 downto 0) and used sig(0), sig(1) and sig(2) instead of sig1, sig2, sig3.

The third point to hint out here is that, we could have opted not to specify the component section within the architecture. We can just remove it but then we should have rewritten the instantionatoin like the following.

adder1: entity work.full_adder port map(x => a(0), y => b(0), z => cin, s => sum(0), c => sig1);

So the summary of this tutorial is as follows.

To design adder we have to derive the truth table. That truth table must be converted to Boolean function. This Boolean function can then be implemented in VHDL using VHDL software.

Finally, we want to point out that there are many other ways to implement the adder in VHDL. Even Matlab can be used to generate the VHDL code which will be explained in the next blog post.

Meanwhile readers are encouraged to read other ways of writing adder vhdl code to gain better insights into vhdl programming.
  • Full Adder design using Generate statement in VHDL and using Xilinx
  • Adder design using logic gates in vhdl
  • How to create adder in vhdl
  • Adder Subtractor vhdl design
  • Serial adder with accumulator using simulink and aldec vhdl software
Please leave comment, thanks





Read More..

FSK Modulation using 74HC4046 PLL VCO IC

| 0 comments |
FSK digital signalling is one of the methods in which a digital signals can be converted into higher frequency signals and transmitted over a channel which requires higher frequencies. In this post, it is shown how FSK modulation can be achieved using the 74HC4046 PLL/ VCO IC. The simulation is done in Proteus ISIS.

Here only the VCO part of the IC is used for the frequency modulation. Digital stream of data enters the VCO and we get FSK signal at the VCO output.

The frequencies of the VCO is set using three external components- one capacitor C1 and two resistors R1 and R2.

However R2 is optional which is only used to set the frequency offset if it is used.

So here first frequency modulation without frequency offset, that is no R2 and then frequency modulation with the frequency offset using R2 is shown.

First without R2 resistor.

The circuit diagram below shows implementation of FSK modulation using the 74HC4046 PLL/ VCO IC in Proteus.

FSK modulation using 74HC4046 PLL/ VCO IC
FSK modulation using 74HC4046 PLL/ VCO IC


The data enters the port VCOIN which is pin 9. The data is digital one with 1V(or 0V) for logic 0 and 4.5V for logic 1. The data rate of this stream is 500bps and therefore the frequency of the signal is 250Hz.

The value of capacitor C1 and resistor R1 determines the frequencies of the FSK modulation. These frequencies were 800KHz and 12KHz. Accordingly the center frequency is 10KHz. We can then use the following graph to get the values of C1 and R1 which were taken to be 2.5nF and 220Kohm at the supply voltage of 4.5V.
In the digital waveform graph we get the following graph for the output FSK signal,


We can see the two square waves corresponding to the two different frequencies.

Similarly viewing the output FSK signal in the analog graph we get the following signal waveform showing the two different frequencies(zoomed in view).

In the first illustration of the FSK modulation the frequency offset was not used and therefore the resistor R2 was not connected, that is, it was left open.

Now the following shows how R2 can be connected to set an offset frequency and get FSK modulation output.

FSK modulation using 74HC4046 PLL/ VCO IC

The value of C1, R1 and R2 were determined as follows.

First we determine the frequency offset using the equation,

frequency offset = center frequency - 1.6*frequency lock

foff = fo - 1.6*fl

since fo = 10KHz and 2*fl=4KHz and therefore fl = 2KHz

we find that, foff = 6.8KHz

Now we use this value of foff to determine C1 and R2 using the following graph,

 which gives us C1=4nF, R2 = 300KOhm.

Now what remains is to find out the value of R1

We first calculate the frequency lock range which is the difference between the maximum frequency and the minimum frequency which are 12KHz and 8KHz respectively. This gives us the frequency lock range which is (12-8)=4KHz.

Using this frequency lock range we can determine the product R1*C1 using the following graph.


which is approximately R1*C1 = 9.5*10^-2

Now we know that C1 is 4nF so we can determine R1 from the relation above which gives us,

R1 = 23.75MOhm

These values of C1, R1 and R2 were used in the above schematic.

Now the graph obtained from simulation is shown.

Analog Graph result-


Digital Graph result-

The above two graph basically shows two types of waveform corresponding to two frequencies of FSK signal.


Read More..

Difference between synchronous and asynchronous D flip flop

| 0 comments |
Synchronous and Asynchronous D flip flop VHDL code is provided, their difference in code implementation and resulting waveform difference is shown. The difference between synchronous and asynchronous reset in flip flops is that in asynchronous the value stored in flip flop is outputted at the instant of reset signal application but in synchronous the value stored in flip flop is outputted only at the rising or falling edge of the clock depending upon the configuration of update of signal with clock.

The following is a VHDL code of a D type flip flop which has two architecture for synchronous and asynchronous reset.

library ieee;
use ieee.std_logic_1164.all;

entity d_ff is
port(
D : in std_logic;
Q : out std_logic;
rst : in std_logic;
clk : in std_logic
);
end d_ff;

architecture syn_rst_dff_arch of d_ff is
begin
process(clk)
begin
if clkevent and clk = 1 then
if rst = 1 then
Q <= 0;
else
Q <= D;
end if;
end if;

end process;

end syn_rst_dff_arch;

architecture asyn_rst_dff_arch of d_ff is
begin
process(clk, rst)
begin
if rst = 1 then
Q <= 0;
elsif clkevent and clk = 1 then
Q <= D;
end if;

end process;

end asyn_rst_dff_arch;


The entity part is the same, that is the ports inputs and outputs are the same. The difference is that in the asynchronous reset D flip flop, the value D is outputted to Q whenever reset signal rst is applied whereas in the synchronous D flip flop, the value D is outputted as Q in the next rising edge of the clock with reset signal applied.

The following waveform graph shows this-

difference between synchronous and asynchronous D flip flop


In the above figure, at 10 ns, reset signal rst goes high(1), at that instant, Qsyn of synchronous D flip flop stays high but the Qasyn of asynchronous D flip flop goes immediately low. Only at 15 ns when there is rising edge of the clock does Qsyn go low. That is output of D flip flop, Q, is updated immediately in case of asynchronous but is not updated immediately in case of synchronous system.

The testbench for this simulation is below:

library ieee;
use ieee.std_logic_1164.all;

entity dff_tb is
end dff_tb;

architecture dff_tb_arch of dff_tb is

signal D : std_logic;
signal rst : std_logic;
signal clk : std_logic;
signal Qsyn : std_logic;
signal Qasyn : std_logic;

begin

DDF1 : entity work.d_ff(asyn_rst_dff_arch)
port map(D => D, Q => Qsyn, rst => rst, clk => clk);
DDF2 : entity work.d_ff(syn_rst_dff_arch)
port map(D => D, Q => Qasyn, rst => rst , clk => clk);

clk_process : process
begin
clk <= 0;
wait for 5 ns;
clk <= 1;
wait for 5 ns;
end process;

sti_process : process
begin

rst <= 0;

D <= 1;
wait for 10 ns;

rst <= 1;

D <= 1;
wait for 10 ns;

rst <= 0;
wait for 10 ns;

D <= 1;
wait for 10 ns;

wait;

end process;

end dff_tb_arch;
Read More..