Lec 6
Lec 6
Lecture – 06
Verilog Language Features (Part 1)
So, we now start our discussion where will be talking about some of the features of the
Verilog language. So, the title of this lecture is titled Verilog language features; part one.
Well, talking about Verilog, you have already seen some examples of sample Verilog
programs. So, what we had seen is that the essential component of a Verilog program or
Verilog code is a module, just like in a high level language like C; you have function as
the basic building block. So, the program will consist of one or more functions. So, in a
Verilog program or code implementation, it will consist of one or more modules.
So, the concept of Verilog module is important. So, as I had said the basic building block
or basic unit of hardware in Verilog is called a module, there are some restrictions like a
module cannot contain definitions of other module, well, this is some similarity with a
language like C. Let us say in C, whenever you define a function, you cannot define
another function inside that function. So, the function definitions have to be disjoint. So,
in a similar way, here also the module definitions have to be disjoint, this is one. So, a
module cannot contain definition of other modules. A module can be instantiated within
another module.
So, here we have a mark difference between how a program like C works and how Verilog
works.
So, let me try to just explain, well in a C program, let us say if I talk of a high level language
like C, let us say there is a function f, this is the body of the function, there is a function g,
there is another function h. So, within the body of the function, I can call g with parameters,
I can call h, ok, and so on. So, in a typical program execution, whenever function is called,
what happens; that when this function call is encountered, control will be transferred to
this function. The code of this function will be executed and then control will be returned
back to this statement following this g.
Similarly, when this h is encountered, again control will be transferred to this function h,
it will be finished and then again it will return back. Now, this can happen for nested call
also, suppose there is another function. Let us say k where from inside g you have called
k, right. So, when you call k from inside g, again a similar thing will happen, k will be
called, it will be executed and then it will be returned, ok. So, if you look at the thread of
execution, during execution you encounter g, you go to g, you execute, encounter k, you
go to k, finish it, then come back, then come back.
So, this is like a last in first out, the last function to be called will be the first one to return
right. So, in C program, irrespective of how many times you call the function, your size of
the total program does not increase, just you are simply calling one function from another
function, right. So, your program code is not increasing in that sense, but in Verilog the
concept is slightly different because here we are talking about hardware. So, in Verilog,
we have the concept of modules.
Let us say, I have a module here, let us call this module is M1. So, what I do from inside
this module well I am invoking, let us say just a following the terminology of C, I am
calling a module M2, I am calling it 2 times, I am calling another module M3, let us say.
So, my M2 module is already defined, my M3 module is already defined. Now, what will
happen here whenever these modules are invoked. So, it is not exactly like calling a
function in C, like here for example, you are invoking M2 2 times. So, what will happen
inside this module, 2 copies of M2 will get embedded. Suppose let us say, this is a full
adder. So, if you call it 2 times. So, 2 copies of full adders will be put inside this master
module, let us say M3 is some other module you call it, this M3 will also be embedded.
Now in addition to these, this module M1 can contain other statements also. So, this
process of calling a module and the module getting inserted in the design in the hardware
this is called instantiation.
Because we are talking about hardware, there is no concept of calling hardware and
returning, well if you call it 2 times it means you are saying that I want 2 copies of that
hardware. So, 2 copies are instantiated. So, M3 is called once means I need one copy of
M3 just like that, ok. So, recall the example that we showed you earlier of a 4-bit ripple
carry adder, there we had instantiated a full adder 4 times. So, that 4 copies of those full
adders were included, means in our ripple carry adder design, ok, fine. So, this is what I
just mentioned. So, a module can be instantiated within another module and this
instantiation process, this allows the creation of a hierarchy, let again talking about the
ripple carry adder example you see, ripple carry adder, the highest level as I said will
consist of 4 full adders.
Now every full adder will consist of a sum and carry circuitry and every sum and carry
circuitry if we implement using a structural description it will consist of some gates. So,
this is a hierarchical description. So, the top level, we are seeing a full, just an adder, 4-bit
adder, next level we are seeing 4 full adders, next level we are seeing 4 carry circuitry and
4 sum circuitry and in the lowest level the gates, right. So, a Verilog module in terms of
its syntax contains the key word module to start with and it ends with endmodule. And
after module will come the module name just like, just like in C, you have a function name,
module name and within parenthesis list of parameters, these are actually technically
called ports and at the end there is a semicolon, this has to be given. Now this is ultimately
some hardware we are trying to design, let us say I am building a harder, if this is a full
adder.
(Refer Slide Time: 09:11)
So, you know that for a full adder there are 3 inputs A, B, C, this is a full adder and there
are 2 outputs sum and carry out. So, this A, B, C, S and Cy, these are called ports, these 3
are so-called input ports and these 2 are so-called output ports.
So, in the declaration, first you have to declare all the input output ports then inside your
design you may be requiring some temporary connection like in the gate level netlist. This
sum and the carry, the description that was shown some of them you recall, there some
temporary signal lines wire were used, those are these local nets and after that there will
be some statements, now here we are calling them as parallel statements. Well, why we
will call them parallel? you see in Verilog, there are certain constructs which you will be
learning one by one.
Now, you see ultimately we are describing some hardware, we are describing one piece of
hardware say h1, another hardware h2, those are all part of the module. Now, in terms of
its operation h1 and h2 are both working in parallel because they are actually circuits, they
will always be fed with some inputs and they will be generating some output. So, it is not
that you cannot say each one that well you wait till h2 is complete then only you start. So,
you cannot tell that to hardware like that because ultimately it is a circuit and circuit will
respond whenever some inputs are changing, right. So, these are so called parallel
statements which you shall see later in some more detail.
(Refer Slide Time: 11:17)
Let us take a simplest of simple example just an AND function we have already seen
examples like this earlier using the assign statement. So, we have this module description,
name of the module is simple AND and the port list is f, x and y and you specify x and y
as inputs, input is a keyword, output is another keyword, f is output and assigned f equal
to x this is logical AND. Well, if you just mention x, y and f, it will mean, these are all one
bit variables; that means, they are logic signals. So, when I say ampersand. So, logically
speaking you may see that well I am talking about an AND gate, but well I should say, we
are talking about an AND function not necessarily an AND gate because in this case.
So, you are specifying the behavior, you are saying that the output will be the AND
function of x and y, but when you give this description to the synthesis tool, synthesis tool
will be actually generating the hardware. Now, synthesis tool if it wants it can generate a
single AND gate, but alternately it can generate a NAND gate followed by a NOT; that is
also AND. You see this second one may be more you can say more probable because in
CMOS technology, it is much easier to design and implement NAND, NOR and NOT
gates rather than AND and OR gates. So, this depends on the synthesis tool. So, you really
do not know for sure that what will be your final gate netlist that this synthesizer will be
generating, ok.
(Refer Slide Time: 13:15)
So, let us take another example, this is a 2 level combinational circuit. So, there are 5
parameters, the module name is 2 level. So, A, B, C, D are inputs, output is f, you see here
we have declared some intermediate nets t1 and t2, ok, and there are 3 assign statements,
t1 is doing an AND, t2 is doing a OR and then NOT basically NOR and f1 is doing AND
and NOT basically NAND. So, let us show the natural implementation, t1 equal to a and
b, suppose we implement it using a NAND gate, t2 equal to NOR of C and D, we
implement using basically an NOR gate and finally f we implement using a NAND gate.
So, this is a 2 level design and using assign, we have defined it in some kind of a structure
because we have also mentioned the interconnection. This t1 we have used here, we have
used here on the right hand side, t2 we have assigned, t2 we have used on the right hand
side, ok. So, this intermediate wires t1 and t2, they are serving the purpose of connecting
these 3 gate outputs t1, t2 and finally, this f, ok.
This is again just one possible gate realization because the synthesis tool can generate
some other realization also for the same function. So, just one thing you remember that
whenever you are using assign statement for describing some design, well, just one thing
let me tell you, the assign statement for most practical purposes are used to specify only
combinational circuits, but later on I shall give you an example where assign statement
can also be used to specify a sequential circuit, this we shall see later, right. So, whenever
you are using assign statements one thing you remember that you are actually talking about
a behavioral description, right, ok.
(Refer Slide Time: 15:41)
Now, there are some points to note for the assign statements, first it is that the assign
statement represents something called continuous assignment. So, what you mean by
continuous assignment? where the variable on the left hand side. So, let us say I have an
expression like this assign some variable equal to some expression, let us say in a previous
example, assign t1 equal to a ampersand b, this is the expression. So, the variable on the
left hand side will get updated whenever the expression on the right hand side changes.
So, some constraints are there, well of course, net and register type variables, we shall be
studying later. So, just assume for the time being that there are 2 kinds of variables net and
register and wire which were used, this is an example of a net type variables. So, this
constraint says that this left hand side; this variable must always be a net type variable, but
the right hand side can be either a register type or a net type, left hand side cannot be
register, ok, this is the constraint. Now as the previous example shows. So, a module can
contain any number of assignment statements, this assign statements and as a matter of
convention this assign statements are placed towards the beginning of the code, right after
the declaration of the ports. So, after your port line declarations and the temporary
variables wires, you place this assign statements after that. And this is what I have said
repeatedly that assign models the behavioral design style and is typically used to model
combinational circuits, but you can also model sequential circuits using assign, this we
shall see later.
(Refer Slide Time: 19:47)
Now, we have just now talked about net and register, let us see what these are now. So, in
Verilog, whenever you declare a variable just like in C whenever you declare a variable,
you declared it as either an integer, float, character and so on. So, in the same way
whenever you declare a variable in Verilog, you have to declare them with a particular
given type. So, broadly speaking data types fall under 2 categories, one is net other is
register. Net, just in the example that we took earlier sometime back, net is continuously
driven typically the output of a gate or output of a functional block that is connected to a
net type variable. So, whenever that output of that block changes, the variable that is
connected to it, changes in a continuous way that is why you call it continuous assignment,
ok.
But we cannot use a net to store a value, well whenever it changes, you assign something
again in the next time when you see its value will depend on the input of that gate or that
block. So, it will not hold the value for a long time, ok, just like a flip flop or a latch, you
cannot store a value for a longer duration. Typically, a net is used to model connections
between continuous assignments and instantiations, what do mean by here?
(Refer Slide Time: 21:14)
Let us say, suppose I have done an instantiation in a module, let us say. So, there is a
fulladder I have instantiated. So, there are 3 inputs and 2 outputs, this is Carry and this is
S. So, what I say in my module, I have written somewhere that assign, let us say, Sbar
equal to NOT of S, where I have defined Sbar as wire. So, actually what this will do? this
will take the output from this instantiated full adder and this assign statement will just be
an inverter, it will be driving Sbar and this assignment will be continuously driven,
whenever S changes Sbar will change immediately, right, this is the basic idea.
Similarly, the register type variable, you can assign a value and the register is supposed to
retain or store the value, you can use it again later, ok. Now as the name register implies
well, you may be tempted to think that a register is just like a hardware register that is
constructed using flip-flops, well do not confuse the two. This is a register type variable
in Verilog and when you talk about hardware registers that is actually the implementation
flip-flops, ok. So, here, even if you declare a variable of type register; so, it is often used
to represent storage elements, all right.
(Refer Slide Time: 23:19)
But there can be instances where a register can translate into combinational circuits also,
ok. So, this you have to remember. Now coming to the net data type, we have already
explained in some detail. Net actually represents connection between hardware elements
and suppose this output, a is a net, this is continuously driven from the output of a gate,
they are continuously driven by the output of some device which they are connected to.
So, whenever the input of this gate changes, this gate output will change and the value of
a will also change immediately.
So, when you declare a net using say wire for example, say wire a. So, by default it will
be taken as a 1-bit value, but we shall see that we can also declare vectors where instead
of 1-bit value, we can use a collection of lines like I can declare a variable to be a 4-bit
variable, 8-bit variable, 16-bit and so on. So, I can define something called a vector and
use these vectors in my Verilog description or coding also, ok, this will see. And one thing
when you declare a net, but you have not initialized yet, so, by default the value is
considered to be in the high impedance state z, refers to high impedance or the tri state,
right.
(Refer Slide Time: 24:49)
So, it means in Verilog, there are a large set of net data types that are supported, some of
the important ones I am showing here - wire, this is wired-OR (wor), wired-AND (wand),
tri-state, supply0 and supply1, this wire and tri they are equivalent. So, when the multiple
drivers driving them, the driver outputs are shorted together. I will just show an example
later. This wired-OR and wired-AND, there also outputs are shorted together, but there
will be a OR and AND function at the junction, well, again I have an example, here I shall
show. And sometimes you may need to specify that which is your power supply line VDD
and ground. So, there are 2 special data types supply0 and supply1 that indicate
connections to ground and connection to VDD, net type wire of course, is most commonly
used.
(Refer Slide Time: 25:57)
Let us take some examples, here I have a module, 5 ports are there, A, B, C, D are input,
output is f. Now here I am declaring f as type wire since output it, here I can specify the
type of the output separately and you see I have declared or defined 2 assign statements,
both are assigning value to f; f equal to A AND B, f equal to C OR D.
So, actually this is something one AND gate which is A, B; there is another OR gate, inputs
are C and D, both output are f. So, actually what you are saying that as if the outputs are
shorted together and you are calling this f.
But you see this is not a normal practice and this is something which is prohibited in
design. So, if I apply A1, B1 and C0, B0. So, one gate is trying to make the output 1, other
gate is trying to make the output 0. So, what should be f? It will be indeterminate, right.
So, for certain condition the output f can be indeterminate, this is a wrong design, you
should not use this, but whenever you want to tie the outputs together, you can use this
either wired-AND or wired-OR. You see instead of wire, I use a wired-AND here, what is
wired-AND means, meaning. So, wired-AND means that in this circuit there is an implied
AND gate here at the junction. So, so if you call this 2 lines as t1 and t2.
So, f will actually be t1 AND t2. So, now, the output f is very well defined. So, if you
declare output f as a wired-AND then an implicit AND operation will be realized at the
connection. So, if you declare it as wired-OR then a wire, then here OR operation will be
done. These are all means, operations or operators which have a direct correspondence
with the hardware. So, in hardware we have this concept of wired-AND and wired-OR
connections depending on the logic family, if you tie the output of 2 gates together for
example, for CMOS, it works like a wired-AND, if you connect the outputs of 2 CMOS
gates together the output will be 0, if any one of them is 0, that is how it works.
So, let us take another example where we have also used supply lines, suppliy0 and
supply1. I have defined a variable called VDD which is connected to supply1, a variable
called ground which is connected to supply0 and we have instantiated 3 gates NAND,
XOR, AND. Here for some of the inputs, I have used VDD and ground also. So, this I can
do if I want.
Just an illustration that how you can use the supply wires. So, data value and signal strength
means, Verilog supports this 4 logic values 0, 1, x and z. 0 is logic 0, 1 is logic 1, x is
unknown which is not initialized it can be 0, it can be 1, but z is high impedance state.
Now when you initialize, so, all unconnected nets, the wires they are initialized to z, but if
you declare some variables of type register, registers are initialized to x. Well in addition
to the values, this value levels, there are strength levels also, see strength level actually,
they will talk about something like this if I connect 2 signals together.
So, which of the signal is stronger if my first signal is stronger, then the final output will
be dominated by the stronger signal that is the concept of signal strength. So, in Verilog,
there are 8 signal strengths which are defined, while we should be talking about this later
because this signal strength comes in to the picture particularly when you talk about MOS
transistors.
(Refer Slide Time: 30:25)
So, in circuits is the MOS transistors, there are various points in the circuits where the
signal strengths are different. So, if I connect 2 points together, their signal values are
different, strengths are different, then the highest strength signal will dominate. So, just to
know which one is higher which one is lower? So, this table just shows you that strength
increases in this reaction. So, if two signals of unequal strengths are driven on a single
wire, this stronger signal will prevail, right.
So, with this we come to the end of this lecture. So, we shall be continuing with our
discussion in the next lecture as well.
Thank you.