ASIC Design using VHDL: A tutorial
This tutorial is written for those who have knowledge of paper/pencil digital design
and are looking to use VHDL to put their ideas efficiently into design.
Nevertheless if you dont know digital design, and still want to use VHDL for design,
most welcome, many of us are using VHDL with no knowledge of design anyway,
and I guess, after going through this tutorial, you will be far better off.

Well I reckon, all the books are written frontsideback(analogous to upside down).
They will tell you many things which you will wonder why? For example, a book
will say vhdl is this vhdl is that vhdl has this vhdl has that, there are the 'data types'
these are 'operators' these are 'functions' these are 'configurations' etc..etc.. blah blah.
and to really frighten you more intimedating things like 'operator overloading' or even 'linked
lists' in vhdl?
So when I first read a book on vhdl I thought, as you may also do : what should I do with
those alien looking terms, pickle them?
Its like when you look for a unix book, you will be taught all the commands, and you will
keep on thinking, ok, but what do i do with them? again pickle them?
There is No book which says, that dude,
this is your problem and to solve it we have to do this this and this, and here is your
solution. So i am going to take this approach.

So what is our problem here:
Our problem is that we have to design ICs using VHDL. Right? Well if you dont agree
then what are you doing here, go to YouTube and entertain yourself.

Well, we will start with very small ICs, and then go to a bit moderate size, of course
I am not going to design a pentium here.

A smallest IC I can think of is may be adder, a one bit adder. Let us design a 1 bit adder using VHDL.
so how do you think an IC(I will call it a block or small design rather than IC, or ICs will be insulted, as
now a days ICs have millions of gates)
OK, the first thing you must know is what are the inputs to and outputs from a block you
want to design? Well a one bit adder will have 3 inputs, and 2 outputs
inputs: a, b, c_in
outputs: sum, c_out
where, 'a' and 'b' are two 1 bit numbers to be added togather with 'c_in' which is carry in
and will produce result as 1 bit 'sum' and 1 bit carry which is called 'c_out'.

So what info we have till now?
We need to design a block with inputs a,b,c_in and outputs sum, c_out.
In VHDL a block or a design is called an 'entity' and input/outputs are called 'port' and
of course each 'port' will have a direction associated with it i.e 'input' or 'output'. I must
say the direction can also be 'inout' but we will leave it for now(1).

Now what is the kind of inputs/outputs of this design. Its kind is digital, it can take only
two values i.e '0' and '1'. VHDL gives us the name of this 'kind' as 'std_logic' which is
also called 'data type'. So, a port will have at least: a name, direction, and kind.
std_logic can take the values '0' or '1' and also some more like 'X' which we will leave for now(2).

So here is how you write the information which you have collected so far in VHDL

entity myadder is --this line describes an 'entity' named 'myadder'
     -- input ports
     a : in std_logic; -- this line describes a 'port' named 'a' with its direction as 'input' and is of type 'std_logic'
     b : in std_logic;
     c_in : in std_logic;

     -- output ports
     sum : out std_logic;
     c_out : out std_logic
end entity;

Well just a empty box with inputs outputs doesn't serve our purpose does it?
We need to define its functionality, to be able to make any use of it.
VHDL says the functionality of the design will be called 'architecture', but architecture
of what? 'architecture' of 'entity' which is analogous to functionality of design.
So what is the functionality of a 1 bit adder. Well most of the combinational logic is
described using a truth table. So let us do the same:

c_in a
sum c_out
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

Now that we know how the adder is going to 'behave' let us try to put it in VHDL language:

architecture func_description of myadder is -- this line describes the name of architecture i.e 'func_description' of a entity called 'myadder'
  add_desc_comb_p : process(c_in,a,b) -- this line describes a 'process' which has 'c_in,a,b' in its 'sensitivity list' and which has been labeled as 'add_desc_comb_p'
    sum <= 'X';
    c_out <= 'X';
    If (c_in = '0' and a = '0' and b = '0' ) then
        sum <= '0';
        c_out <= '0';
    end if;
    If(c_in = '0' and a = '0' and b = '1') then
sum <= '1' ;
c_out <= '0';
    end if;
    If(c_in = '0' and a = '1' and b = '0' ) then
sum <= '1' ;
c_out <= '0';
    end if;
    If(c_in = '0' and a = '1' and b = '1' ) then
sum <= '0';
c_out <= '1';
    end if;
    If(c_in = '1' and a = '0' and b = '0' ) then
sum <= '1' ;
c_out <= '0';
    end if;
    If(c_in = '1' and a = '0' and b = '1' ) then
sum <= '0';
c_out <= '1';
    end if;
    If(c_in = '1' and a = '1' and b = '0' ) then
sum <= '0';
c_out <= '1';
    end if;
    If(c_in = '1' and a = '1' and b = '1' ) then
sum <= '1' ;
c_out <= '1';
    end if;
  end process add_desc_comb_p;
end func_description;
Download this vhdl design here

We learnt that to write a code in VHDL the bare minimum you would need to do is:
1. Describe an 'entity' which will contain the 'ports' of the design/block
2. Describe an 'architecture' corresponding to the 'entity' which will describe the 'functionality' of the design

So, we have done our first 'design' in VHDL, but the question is : Is the 'functionality' correct? Of course
we will have to 'verify' that the design's functionality is as expected. So how would you verify it? Well in
the same way as you would if you had a adder IC in lab. You will apply inputs and observe corresponding
outputs, if all the outputs corresponding to each of the input(s) are as expected, we will say the 'design' is

How to apply inputs in VHDL, and also how to observe outputs.
For this purpose we will write another VHDL model, commonly called 'testbench' which will
1. Call an instance of our design, i.e instantiate it(dont worry you will understand what intantiation means) in itself
2. Generate input(s) for the design to be test, also called design under test or DUT
3. You may optionally add a mechanism to 'monitor' the outputs form DUT, and check them against the expected once to
automate the process of verification.

Some rules:
1. A tesbench will normally not have any inputs or outputs, because it will only generage signals also called 'stimulus'
for the DUT, and itself wont interact with any other thing.
2. Graphically a testbench can be represented something like this:

Note: This tutorial is designed to help those who help themselves, as prior knowledge of
ASIC design is expected.

0. VHDL is a parallel language. All 'constructs' in vhdl are executed parallelly.
So just think you will be using a computer a PC or a workstation, which executes
commands sequentially, to 'simulate' a design written in VHDL in parallel.

1. Combinational Design:

First thing one should know is combinational design, and how to use VHDL for it.

VHDL has following constructs to code combinational logic:

consider the folloging signals:

signal result_sig : std_logic_vector(wi downto 0);
signal choice0_sig : std_logic_vector(wi downto 0);
signal choice1_sig : std_logic_vector(wi downto 0);
signal sel : std_logic;

result_sig is the function of choice0_sig, choice1_sig and sel.

now result_sig can be given a value in following 3 ways:

result_sig <= choice0_sig when sel = '0' else choice1_sig;

result_sig <= mux_vec(choice0_sig,choice1_sig,sel);

where mux_vec can be a vhdl function

assign_result_sig_comp_b: process(choice0_sig,choice1_sig,sel)
  result_sig <= choice0_sig;
  if(sel = '1') then
    result_sig <= choice1_sig;
  end if;

end process assign_result_sig_comp_b;

First 2 are simple, the 3rd method uses what are called 'process'
A process in vhdl is a construct, inside which the code is executed in sequential manner.
Well OK vhdl is a parallel language, but that means all constructs are execued in parallel.
a 'process' is a construct, so all 'processes' will execute in parallel. But statements inside
a process construct will execute sequentially