Upload
brian-santos
View
34
Download
1
Embed Size (px)
Citation preview
CHAPTER 2
Verilog HDL for Hardware Modeling
The circuits were described using schematics in past two decades, with advent of Digital and Analog designs it
became difficult to think and design on schematic level. There was strong need for a language which can represent
the hardware. It can model and simulate hardware as good as schematic. This oriented starting point of HDL
(Hardware Descriptive Language) which can describe any circuit using language constructs. There are several HDLs
including Verilog HDL which will be used for purpose of this book. Every statement in Verilog Models Hardware
and like programming language it has constructs including Loops, Logic Structures etc. The hardware
equivalencies of all constructs are specified in bold in this chapter.
2-1 Basic Structure for Programming
2-1-1 Wrapper for Designs
Verilog is based on a basic wrapper which will be used in every program. The wrapper consists of module and
endmodule containing all programming logic . Module in Verilog is the smallest programming entity. They can also
be called like functions in other languages (instantiation in Verilog). The basic structure or wrapper used in every
Verilog program goes like below:
Design Example 2-1: Verilog Wrapper
module DesignName();
//User Logic
endmodule
Common mistake: endmodule is single keyword and must not be written like end module, this will allow
to take module and end separately which are different key words.
As said before that every statement in Verilog HDL models hardware, so the wrapper is just like a chip packaging
with name printed on it and logic inside it. The user logic is most important part of the design it defines a logic
which maps input to output according to specified logic. For example the adder maps two inputs and a carry in to
generate outputs sum and carry out. User Logic will be discuss in detail in preceding section.
2-1-2 Port List
The second basic point in every design is port list. The port list connects the user logic to the external world. It
includes inputs and outputs. In hardware port list is just like pins on the chip boundary, which connect the circuit
inside the chip to the external world. Consider a design which xor two inputs and generate the output. In Example
2-2 a design with two inputs and one output is discussed.
Design Example 2-2: Port list Explained
module my_xor(out,in1,in2);//Port List
//User Logic
endmodule
Verilog Convention: Outputs generally come first in port list than the inputs
Design example 2-2 gives the name of the module name my_xor and two inputs in1 and in2. There may be many
other internal variables inside the design, the port list only contain those variables which are required to be
connected to the external world.
2-1-3 Port Definition
It is required to define that the ports are input or output i.e. direction of the port. Once the port direction is
defined the next question is; what is the width of the port i.e. it is bus or a scalar (one bit). This section of the code
is essential in every design. It must be the starting point of the code. At this point of time we will only focus on the
specifying direction of the ports, and leave their size specification for section 2-4. In order to specify direction of
two keywords input and output are used. Verilog is case sensitive so input and output must be in small letter. The
chips also define port list, and each pin in the chip has the direction, these port directions are specified in the
datasheet.
Design Example 2-3: Port definition explained
module my_xor(out,in1,in2);//Port List
output out;//out is the output
input in1,in2; //in1, in2 are the inputs
//User Logic
endmodule
Common mistake: output and input are not inputs and outputs neither they are Output and
Input. Both key words are case sensitive so does not have s at the end.
2-2 Data Types in Verilog HDL
Verilog HDL has data types like other programming languages. It has two data types net and reg, and of course
they model the hardware behavior. Every variable in Verilog can be positioned under one of these data classes.
First type is register, register models the storage behavior of hardware i.e. value stored in register will retain its
value unit changed by the program itself. In this book we will use data type like reg to store values. The latter
type is net, net models wire behavior of the hardware i.e. value placed on the wire will not retain value
however it can drive value (take value from one place to other). Mostly it is use to interconnect different routes
of circuit. For scope of this book we will use wire which is type of net. The input and output are also net in nature,
however output can be made register in special case which will be discussed latter in section 2-5.
Table 2-1: Description of Data Types in Verilog HDL
Reg reg,output(can be made) Reg models storage behaviour of
the hardware. Any value store in
register will retain its value.
Net wire,input,output(by default) Models wire behavior in
hardware, does not store any
value. Drive value from one
place to other.
2-3 Gate Level Modeling in Verilog HDL
There are many ways in Verilog HDL to write a code inside wrapper discussed in design example 2-3. The schematic
level resembles the Gate level modeling in Verilog. The custom circuits are generally made with process where we
make truth table, minimize the logic (using Boolean reduction or Kmap), write Boolean equations and then make
gate level schematic.
The simplest form of modeling in Verilog is to look at the gate level diagram and write code defining every gate
of the circuit, this type of modeling is called gate level modeling. Verilog has primitive gate which can model any
circuits. The gates are given in table two below:
Table 2-2: Primitives for Gate level Modeling
and and a1(out,in1,in2,); N inputs and gate
nand nand a1(out,in1,in2,); N inputs nand gate
or or a1(out,in1,in2,); N inputs or gate
nor nor a1(out,in1,in2,); N inputs nor gate
xor xor a1(out,in1,in2,); N inputs xor gate
xnor xnor a1(out,in1,in2,); N inputs xnor gate
buf buf a1(out,in); Buffer
not not a1(out,in); Inverter
bufif0,bufif1 Tri state buffer
notif0,notif1 Tri sate Inverter
2-3-1 Xor Gate level modeling
We can model any circuit by looking at table 2-2. For example lets complete the code for wrapper in design
example 2-3. In design example 2-4 the xor gate is instantiated, it will perform the functionality of xor gate.
Design Example 2-4: Gate Level modeling of xor gate.
1
2
3
4
5
module my_xor(out,in1,in2);//Port List
output out;//out is the output
input in1,in2; //in1, in2 are the inputs
xor x1(out,in1,in2);///instant of xor primitive gate
endmodule
Dos of Verilog: Every time the instant of the module is instantiated(called), it must have a
instant name for example in the example above the instant name is x1.
2-3-2 Half Adder
Lets illustrate another example for HDL basics. Assume that we need to design a half adder circuit given in the
Figure 2-1 below.
Figure 2-1: Half Adder Circuit
For the example given in Figure 2-1 the code is given in Design Example 2-5.
Design Example 2-5: Gate Level modeling of Half Adder
1
2
3
4
5
6
module HalfAdder(Sum,Carry,In1,In2);//Port List
output Sum,Carry;
input In1,In2; //in1, in2 are the inputs
xor g1(Sum,In1,In2);
and g2(Carry,In1,In2);
endmodule
2-4 Instantiating Verilog modules
Modules in variable can be called just like C or other programming language. The module call in Verilog is called
instantiation. The instantiation is also like hardware components connected together through wires. The module is
made once, tested and then can be instantiated any number of times. Instantiation of Verilog modules is
fundamental part of divide and conquer design in Verilog. The top down or down top methodologies are basic
element of design in Verilog.
2-4-1 Top down Design Methodology
In top down design practice the top level module is made in the start and then one by one its required modules
are manufactured. For example we start designing 4-Bit Adder to start with, after completing the design we stuck
at point where the module of full adder is required as shown in Figure 2-2. The top node of design becomes 4-Bit
adder than we design full adder module and call it four times in 4-Bit adder. In Full adder we require two half
adders so we design half adder and call them in the Full adder. The Half adder consists of xor and and gates as
shown in design example 2-5. The last entity of top down design is called Leaf.
Figure 2-2: Hierarchical approach of design in Verilog HDL
4-Bit Adder
Full Adder Full Adder Full Adder Full Adder
Half Adder Half Adder
and xor
2-4-2 Bottom up Design Methodology
In bottom up approach start thinking the design from the smallest possible entity i.e. half adder. Two half adder
combines to Full adder and then Full adders combine to 4-Bit adder. This approach will be used in the book and is
more recommended. The reason for using this approach is when the smallest entity is made it is testable and then
when it reaches next level of hierarchy again it is testable and so on. In top down approach the top module is made
on assumption that the module in the next lower hierarchy will be available so the top level module is not testable
until all modules are completed.
2-4-3 Full Adder Example
Now lets spend some time on learning how to instantiate a module. In design example 2-5 half adder was made,
seeing Figure 2-2 lets assume we are using bottom up approach. Next level of design will be Full adder using two
half adders as shown in Figure 2-3.
Figure 2-3: Hierarchical approach of design for Full Adder
Two half adders are instantiated and the interconnections are made using wire e1,e2 and e3. The interconnections
are required act as wire. It is just like making modules in hardware and connecting them using jumper wire. The
interconnects wire are net in nature and does not hold value. The purpose of using wire is to interconnecting two
elements.
Design Example 2-6: Gate Level modeling of Half Adder
module FullAdder(Sum,Carry_Out,In1,In2,Carry_In);
input In1,In2,Carry_In;
output Carry_Out,Sum;
wire e1,e2,e3;
HalfAdder HA1(e1,e2,In1,In2);
HalfAdder HA2(Sum,e3,e1,Carry_In);
or g1(Carry_Out,e3,e2);
endmodule
module HalfAdder(Sum,Carry,In1,In2);//Port List
output Sum,Carry;
input In1,In2; //in1, in2 are the inputs
xor g1(Sum,In1,In2);
and g2(Carry,In1,In2);
endmodule
2-5 Port Connection and Instantiation Rules
In the last section we discussed how we can instantiate the modules in other modules. However there are certain
rules which should be known before any instantiation can be made. The connection rules are very basic part of
HDL design methodology and they must be well understood. In this section we will discuss how to instantiate
modules using Port listing by order and by name. We will also discuss port connection rules of inputs and outputs.
2-5-1 Instantiation using port by Sequence
In example 2-6 we discussed that how two half adders can be instantiated to form a full adder. The signature for
half adder were HalfAdder(Sum,Carry,In1,In2). The two instances of half adder in full adder are using method
called port list by order. In this method the place where instant of a certain modules is made should follow exact
order as were in the original modules. The two instances given below:
HalfAdder HA1(e1,e2,In1,In2);
HalfAdder HA2(Sum,e3,e1,Carry_In);
have the exact order as in HalfAdder(Sum,Carry,In1,In2), it can be notices by seeing Figure 2-3. This method is not
possible for modules with large number of ports.
2-5-2 Instantiation using port by name
For larger designs another method called port by name is used. In port by name the order of ports in original
modules is not important only names of port are used for instantiation. In port by name we are not worried
about exactly if Sum is the first port in Half adder or last, we only write name .Sum(e1) and pass e1 as argument.
The .Sum(e1) means that Sum is name of port in the module which is instantiated and e1 is connected to it from
where it is instantiated. In this case it does not matter whether you write .Sum(e1) in the start or end of port list.
As shown in Design example 2-7 Half adder instant HA1 has .Carry(e2) at the third number while Carry was at
second number in Half Adder module.
Design Example 2-7: Gate Level modeling of Full Adder
module FullAdder(Sum,Carry_Out,In1,In2,Carry_In);
input In1,In2,Carry_In;
output Carry_Out,Sum;
wire e1,e2,e3;
HalfAdder HA1(.Sum(e1),. In1(In1),. Carry(e2),.In2(In2));
HalfAdder HA2(.Sum(Sum), .In1(e1), .In2(Carry_In),.Carry(e3));
or g1(Carry_Out,e3,e2);
endmodule
module HalfAdder(Sum,Carry,In1,In2);//Port List
output Sum,Carry;
input In1,In2; //in1, in2 are the inputs
xor g1(Sum,In1,In2);
and g2(Carry,In1,In2);
endmodule
From now onwards in this book we will follow Port by name instead of port by sequence for instantiating the
module.
2-5-3 Connection Rules
There are some connections rules which must be followed in instantiating one module to other. The input and
output are net in nature as shown in Table 2-3. However output can be made reg if it is required to hold a certain
value. The data is received from the input pins therefore they are intentionally made to prevent any data change
inside the module. However output can be made reg or it is retained as per required. We will discuss making
output reg latter in section 2- in detail.
Table 2-3: Port Connection rules in Verilog
Port Type Inside Module Can be Connected to
input Net net/reg
output net/reg Net
inout Net Net
When the module is connected to other module these connection rules are reversed i.e. input can be connected to
a net or a register and output can only be connected to net. It is quite obvious that input is made net in nature
inside module so prevent any modification after the input is given to the module and output can be connected to
net only to ensure that there is no modification after output is generated.
Input can be externally connected to a register when it is provided with the value generated inside the module
instantiation it and to net when the input is connected to the output of the some other module.
Figure 2-4: Port Connection Rules in Verilog HDL
2-6 Vectors, Array and Number Convention in Verilog HDL
The scalar is considered so far in this chapter which is only single bit. We can define net or regs of more than one
bit which are usually called bus. Four examples we can define an input port which is four bit, of course we can also
Input connect
module
Input connect
output connect
Input(net)
output(net/reg)
assign a four bit number to that bus or its paths. This section will discuss vectors, a way to handle bus in Verilog
and number convention for more than one bit number.
There are two ways to define a vector in Verilog little Endean or Big Endean. End-Dean stands for end with for
example in little Endean the last is number is LSB as it should end with little and in Big Endean the last number is
MSB as it should end with Big Number.
Figure 2-5: Design of 4-Bit Adder
2-6-1 Four Bit Adder Example to Explain Vectors
Consider an example shown in Figure 2-5, its a Full Adder with two inputs a, b which are four bit. Both the inputs
are added and their result is Sum S and Carry_Out are generated. Four Bit adder is modeling by instantiating four
full adder. To model the bus of four bit we will use standard little Endean notation.
Design example 2-8 illustrate the idea, the first line in the RTL input [3:0]A,B; ///two inputs which are two 4 bit
inputs.
Design Example 2-8: Hierarchical modeling of 4-Bit Adder
1
2
module Adder4Bit(A,B,Carry_in,Sum,Carry_Out);
input [3:0]A,B;
a[1]
FA1
b[1]
S[1]
a[0]
FA0
b[0]
S[0]
Carry_in
a[2]
FA2
b[2]
S[2]
a[3]
FA3
b[3]
S[3]
Carry_out
3
4
5
6
7
8
9
10
11
input Carry_in;
output [3:0]Sum;
output Carry_Out;
wire [3:1]C;
FullAdder FA0(.Sum(Sum[0]),.Carry_Out(C[1]),.In1(A[0]),.In2(B[0]),.Carry_In(Carry_in));
FullAdder FA1(.Sum(Sum[1]),.Carry_Out(C[2]),.In1(A[1]),.In2(B[1]),.Carry_In(C[1]));
FullAdder FA2(.Sum(Sum[2]),.Carry_Out(C[3]),.In1(A[2]),.In2(B[2]),.Carry_In(C[2]));
FullAdder FA3(.Sum(Sum[3]),.Carry_Out(Carry_Out),.In1(A[3]),.In2(B[3]),.Carry_In(C[3]);
endmodule
Also [3:0]Sum and interconnecting wire [3:1]C are vectors. Hence we sum up vectors as register or net which are
more than one bit and its syntax is [MSB:LSB].
2-6-2 Difference between Arrays and Vectors
The array in Verilog is same as in C or any other language; its a container which can hold more than one value
which can be scalar or vector. The syntax for array is reg array*3:0+, its are scalar array with four locations in it,
each location is one bit wide as shown in Figure 2-6.
Figure 2-6: Concept of Array, Vector and Vectored array
2-6-3 Vectored Arrays and Memory Example
So we have discussed Vectors which are single location with multiple bits and arrays which are multiple locations
with single bit. We can also combine both to get vectored arrays i.e. multiple locations with more than one bit. The
syntax is quite guessable now, suppose we need to define an array with 4 locations and each location is 8 bit.
reg [7:0]arr[3:0];//Each location is 4 bit and there are 8 locations
reg arr[3:0];//4 bit array reg [3:0]arr;//4 bit
vector
reg [7:0]arr[3:0];//4 bit
vectored array
Vectored arrays find several examples in digital designs for example if we need to define a memory of 256
locations and each location is 8-Bit wide it will require a vectored array. To address 256 locations we require 8
address lines, 8 bit data in and data out(just for a obvious that each location is 8-bit wide) as shown in Figure 2-7.
We will cover this example latter however to elaborate the vectored array, the memory will be a register of 256x8
with an array of 256 location and each location is a 8-Bit vector.
Figure 2-7: Memory with 256 locations, each location is 8-Bit wide
2-6-4 Specifying Numbers in Verilog
This takes us to the second part of this section where we will discuss Number specification in Verilog HDL.
Numbers in Verilog are specified in special format, for example if we want to write 2 in Verilog we must tell that
how much bits two will take what will be the format(decimal, binary etc) for the number. In Verilog we will write
2d2 or 2b10 which means that its a two bit number specified in decimal or binary format respectively. Some
commonly used formats in Verilog are discussed in table 2-4.
Table 2-4: Formats in Verilog HDL
Format Format Name Format Format Name
D or d Decimal O or o Octal
B or b Binary M or m Hierarchical Name
H or h Hexa S or s Strings
Let us take some examples given in table 2-5 to properly understand the number format specification in Verilog
HDL.
Table 2-5: Examples of Format Specification
Example Description
4d5 4 Bit decimal 5
Memory 256x8
Mem_Address(8)
)8
Mem_DataIn(8) Mem_DataOut(8)
Write
3b111 Binary 7 Number
5h1A 5 Bit number 26 in Hexa
2-7 Level of Signals in HDL
It has been discussed that we can define the numbers in Verilog HDL and they can more than one bit. They are of
course meant to assign to a bus, a scalar must be assigned with one bit. All values are treated as binary internally
not matter how they are specified, this means a number specified in Hexa or Decimal is also binary internally. Any
value in Verilog has four possible states High, Low, High Impedance and unknown. This is how the hard ware see
the signals, consider a CMOS logic Inverter below.
Figure 2-8: Transistor level of Signaling
Table 2-6: Level of Signal in Verilog HDL
Example Description
1b1 High
1b0 Low
1bx Unknown
1bz High Impedance
2-8 Different level of Modeling in Verilog HDL
In section 2-3 we discussed gate level modeling, as discussed earlier that Digital Designs can be modeled in Gate
Level, Data Flow and Behavioural Level modeling. Gate level modeling and data flow modeling are used for small
designs where no of gates or Boolean logic is finite and countable.
Table 2-7: Modeling Types in Verilog HDL
Modeling Level Modeling Behaviour Description
Gate Level Modeling Use predefined Gates constructs
and wires to connect them
Just like Making circuits using
Gates, used for small design
where no of gates are countable
Data Flow Use data operators to model a
certain logic
Models Boolean expressions,
used where the logic is small and
there are few Boolean
expressions.
Behavioural Level Modeling Use C like constructs like Loops,
Case Statement, if else etc.
Digital design does not have
parallel modeling for Behavioural
level. It is pure programming and
logic approach used by larger
designs. Where a design cannot
be modeled using gates or
Boolean expressions.
As discussed in first chapter no matter what the level of modeling the design will have to ultimately translate into
gate level modeling which is called gate net list. Writing a code in gate flow level has advantage with less complex
synthesis. Dataflow offer complexity of a bit higher level than gate flow. Behaviour level modeling offer very
complex gate net list as compared to Gate level and Data flow level modeling.
However for larger designs we cannot think things at gate level. We must write code in Behavioural level. We can
used mixed modeling in any design i.e. a module may have combination of behaviour level and Data flow
modeling. Smaller modules in large design may also be modeled in gate level.
Figure 2-9: Level of Complexity Increased with modeling level becoming Higher
Behavioural Level Modeling
Data Flow Modeling
Gate Level Modeling
2-9 Data Flow Modeling
Data flow modeling is very popular style in coding in Verilog HDL. In larger designs chunks are written in Data Flow
for a two reasons.
1- Where there is no delay and immediate assignments are made. Outputs are not forced by any inputs
conditions. For example think of Flip Flop, there are two outputs q and qbar, qbar is always inverted of q.
There is no condition involve, we always assign qbar equals invert of q.
2- Where we have very simple combinations circuit elements and we do not want to model them in
behaviour level. Usually this is required is resolving synthesis constraints, and we model few part from
behaviour to dataflow to bypass constraint problems.
Data Flow modeling use mathematical operators to model a certain Boolean Expression. A digital design mostly
starts with some logic given in truth tables, which is minimized by K Maps or Boolean reduction. This results into
Boolean expressions which are ultimately to be translated into Gates. Gate level modeling think designs on Gate
level while dataflow think designs in Boolean Expressions. So what difference does it makes in thinking both ways.
1- When you think designs in Gate level you have to do routing yourself. However in data flow no routing is
required, its simply writing Boolean expression in Verilogs way.
2- I gate level we have limitation of thinking design in only one way i.e. gates. But in data flow we can think
design in sense of Boolean expression or Bolean Logic. For example we can think 2x1 multiplexer as two
and gates, one nor gate and one or gate in Boolean expression or we can think it in if else structure. This
is explained in Example 2-9.
2-9-1 Operators and Basic Rules in Data Flow
The armor of data flow is operators, below are operators used in data flow.
Table 2-8: Unary Operators for Data Flow modeling
Operator Name Operator Symbol Operational Mode
Logical Inverter ! Only for Scalars
Bit wise negation ~ For Scalar and Vectors
For Vectors-yields a single bit
output
AND &
NAND ~&
OR |
NOR ~|
XOR ^
XNOR ~^
Table 2-9: Arithmetic Operator and their Symbols
Operator Name Operator Symbol
Multiplication *
Division ~/ The result is x if denominator is
zero
Modulus %
Addition +
Subtraction -
Table 2-9: Arithmetic Operator and their Symbols
Operator Name Operator Symbol Usage
Shift Left A2 Shift A two times right
Concatenation Operator {A,B} Combine A and B into single
vector
Replication Operator {{A,2}} Replicate A two times in the
vector
If Else Operator ?:
Data flow is very simple if few things are kept in mind.
1- You can only use primitive operators in data flow. Precedence of all operators must be kept in mind to get
the correct result.
2- The LVAL (the left side where value is assigned) must be net in nature. Every data flow statement must
start with key word assign. Assignment is done as soon as the data on right is changed.
3- The number of assign statements is equal to number of outputs. Every output is function of inputs; data
flow level defines combination of input in Boolean way to express a certain output.
2-9-2 Multiplexer Modeling in Data Flow
Below is example 2-9 of the code. In the first part 2-8-1 the design is implemented in the Gate level you can see
the need for routing and nets between the gates.
Design Example 2-9: Multiplexer Example using Data Flow
MUX_SEL(1)
2-9-1 Thinking design in Gate level
module Mux2x1(MUX_OUT,MUX_SEL,MUX_IN);
input [1:0]MUX_IN;
input MUX_SEL;
output MUX_OUT;
wire e1,e2,e3;
and g1(e2,MUX_IN[0],e1);
and g2(e3,MUX_IN[1],MUX_SEL);
not g3(MUX_OUT,e3,e2);
or g4(e1,MUX_SEL);
endmodule
2-9-2 Thinking design in Boolean Way
module Mux2x1(MUX_OUT,MUX_SEL,MUX_IN);
input [1:0]MUX_IN;
input MUX_SEL;
output MUX_OUT;
assign MUX_OUT=(MUX_IN[0]&~MUX_SEL)| (MUX_IN[1]&MUX_SEL);
endmodule
2-9-3 Thinking design in Logical way
module Mux2x1(MUX_OUT,MUX_SEL,MUX_IN);
input [1:0]MUX_IN;
input MUX_SEL;
output MUX_OUT;
assign MUX_OUT=MUX_SEL? MUX_IN[1]: MUX_IN[0];
MUX 2x1 MUX_IN(2)
MUX_OUT(1)
endmodule
In 2-9-2 and 2-9-3 Data flow modeling is shown above. Boolean expressions are implemented in 2-8-2 and similar
gate level logic is represented. LVAL MUX_OUT is Net is nature and any change in right hand side will validate the
assignment.
2-9-3 Four Bit Adder in Data Flow
Example 2-10 shows implementation of Four Bit adder in data flow level. The example is repeated from Example 2-
8 which show the Gate Level implementation of Four bit adder.
Design Example 2-10: Dataflow modeling of 4-Bit Adder
2-10-1 Thinking design in Logical way
module Adder4Bit(A,B,Carry_in,Sum,Carry_Out);
input [3:0]A,B;
input Carry_in;
output [3:0]Sum;
output Carry_Out;
assign { Carry_Out , Sum }=A+B+ Carry_in;
endmodule
2-10-2 Thinking design in Gate Level
module Adder4Bit(A,B,Carry_in,Sum,Carry_Out);
input [3:0]A,B;
input Carry_in;
output [3:0]Sum;
output Carry_Out;
wire [3:1]C;
FullAdder FA0(.Sum(Sum[0]),.Carry_Out(C[1]),.In1(A[0]),.In2(B[0]),.Carry_In(Carry_in));
FullAdder FA1(.Sum(Sum[1]),.Carry_Out(C[2]),.In1(A[1]),.In2(B[1]),.Carry_In(C[1]));
FullAdder FA2(.Sum(Sum[2]),.Carry_Out(C[3]),.In1(A[2]),.In2(B[2]),.Carry_In(C[2]));
FullAdder FA3(.Sum(Sum[3]),.Carry_Out(Carry_Out),.In1(A[3]),.In2(B[3]),.Carry_In(C[3]);
endmodule
Earlier we made a rule that generally no. of statements in dataflow statements equals number of outputs.
However in some cases this may not be true for example the statement in Example 2-10-1:
assign { Carry_Out , Sum }=A+B+ Carry_in;
The above statement combines two outputs into single statement using concatenation operator. The four bit A
and B and 1 bit carry will generate five bit output, the left most bit of this five bit sum will be Carry_out and next
four bits are Sum.
2-9-4 Four Bit comparator in Data Flow
Four bit comparator is good example of show multiple flow statements for each output.
Design Example 2-11: Dataflow modeling of Four Bit Comparator
module Comp4Bit(AEB,ALB,AGB,CmpA,CmpB);
input [3:0]CmpA,CmpB;
output AEB,ALB,AGB;
assign ALB=(CmpACmpB) ?1b1: 1b0;
endmodule
Both inputs are compared for less then, equal to and greater to logic and corresponding outputs are assigned. The
gate level modeling of the design and its comparison with the data flow counterpart is left to the reader and is
given in the end problems.
Figure 2-10: Summary of Rules in data flow Modeling
2-10 Behavioural Level Modeling(Combinational Circuits)
4- Bit
Comparator
CmpA
CmpB
AEB
ALB
AGB
Rules for Data Flow Modeling
1- Each statement in data flow modeling start with key word assign.
2- The LVAL of data flow statement should always be a net.
3- The LVAL is assigned new value every time there is change in any value of RVAL.
General Practices for Data Flow Modeling
1- LVAL is output, the number of assign statements is equal to number of outputs.
2- RVAL are inputs and LVAL are outputs.
This section addresses most important modeling in Verilog HDL for Larger designs. Behavioural level modeling is
thinking codes at algorithmic level. This is highest level of abstraction, most of constructs inspired from C. As
discussed earlier that after synthesis all form of codes are translated into gate level called gate net list. Hence the
synthesis of behavioural level modeling is producing much larger logic then data flow and gate level modeling.
2-10-1 Rules for Behavioural coding
Behavioural level modeling is governed by following set of rules.
1- All coding in behavioural level modeling must be done inside behavioural blocks always and initial. This
type of modeling provides two types of blocks generally called procedural/behavioural blocks. This is
unlike Data flow and gate level modeling where you can write the code directly between module,
endmodule wrapper. However in case of behavioural level modeling first always or initial block is written
inside the wrapper and then coding can be done
2- The LVAL must be register however the RVAL can be anything including net and register.
3- More than one lines under initial/always statements must include begin and end key words. It is just like {
and } brackets use in C++.
4- Nesting of Behavioural blocks is not allowed i.e. Initial inside initial, always inside always, initial inside
always and always inside initial.
5- No matter how many Procedural blocks are written, all blocks are executed at once at time t=0.
2-10-2 always and initial block
The always and initial blocks are back bone of Behavioural level modeling. Initial block is just like booting
process in any IC, it start at time t=0 and execute all the logic under it. Once it executes it is never executed
again during life cycle of the code. Usually initial blocks are used to initialize different variables in the design.
always@(inputs)
Always block are also executed at time t=0, once
executed at goes at the top again and check the
initial
Initial block is just like booting process in any IC, it start
at time t=0 and execute all the logic under it.
sensitively list(the list after @ symbol in the top of
the block and then execute the block again.
Figure 2-11: Procedural Blocks in Verilog HDL
Always block are also executed at time t=0, once executed at goes at the top again and check the sensitively
list(the list after @ symbol in the top of the block and then execute the block again. Always block has a list
with its statement, if this list is not mentioned then always block is executed repeatedly without any condition.
All the elements in sensitivity list are generally inputs, and always block is executed if any of the input is
changed. Once a block is executed it goes back on the top and waits for the input to be changed, block is
executed every time even if one of the input change.
2-10-3 Combinational Design in Behavioural Level modeling
Multiplexer code is given in example 2-9 where data flow and gate level implementation is given. This section
implements the design in Behavioural level as given in example 2-12.
Design Example 2-12: Multiplexer Example using Data Flow
MUX_SEL(1)
2-12-1 Using case statement
module Mux2x1(MUX_OUT,MUX_SEL,MUX_IN);
input [1:0]MUX_IN;
input MUX_SEL;
output MUX_OUT;
reg MUX_OUT;
always@( MUX_IN or MUX_SEL)
case(MUX_SEL)
1b0: MUX_OUT= MUX_IN[0];
2-12-2 Using if else blocks
module Mux2x1(MUX_OUT,MUX_SEL,MUX_IN);
input [1:0]MUX_IN;
input MUX_SEL;
output MUX_OUT;
reg MUX_OUT;
always@( MUX_IN or MUX_SEL)
if(MUX_SEL==1b0)
MUX_OUT= MUX_IN[0];
MUX 2x1 MUX_IN(2)
MUX_OUT(1)
1b1: MUX_OUT= MUX_IN*1+;
endcase
endmodule
else if(MUX_SEL==1b1)
MUX_OUT= MUX_IN[1];
endmodule
1- Observe in the code that MUX_OUT is register in the code. The LVAL in always block is register.
2- All codes are written inside always block, and no code is directly written inside the wrapper.
3- The logic of C is directly used in Behavioural level modeling. For example 2-12-1 given the case based
implementation and 2-12-2 givens if else based implementation of the design.
4- The inputs are present in the sensitively list, and will be executed when MUX_IN or MUX_SEL is changed.
Another example of usage of case statement is 3x8 decoder. The default value is also used in the case; it will be
approached if none of the statement in the case is true. The designs of Demultiplex and Encoder are left for
userand is given in the exercise. Example 2-14 presents code of comparator in behavioural level, the example is
repeated from example 2-11(data flow modeling of comparator).
Design Example 2-13: Multiplexer Example using Data Flow
module Decoder(Data_out, Data_in);
input [2:0]Data_in;
output [7:0]Data_out;
always@(Data_in)
case(Data_in)
3b000: Data_out=8b00000_001;
3b001: Data_out=8b00000_010;
3b010: Data_out=8b00000_100;
3b011: Data_out=8b00001_000;
3b100: Data_out=8b00010_000;
Decoder
3x8
Data_in[0]
Data_in[1]
Data_in[2]
Data_out(8)
3b101: Data_out=8b00100_000;
3b110: Data_out=8b01000_000;
3b111: Data_out=8b10000_001;
default: Data_out=8b10000_000;
endcase
endmodule
Design Example 2-14: Comparator design in Behavioural level modeling
module Comparator(ALB,AGB,AEB,InA,InB);
input [3:0]InA,InB;
output ALB,AEB,AGB; reg ALB,AEB,AGB;
always@( InA or InB)
if(InAInB) ALB=1b0;AEB=1b0;AGB =1b1;
else if(InA==InB) ALB=1b0;AEB=1b1;AGB =1b0;
endmodule
2-10-4 Memory Design in Behavioural Level modeling
Example of memory is presented in 2-15, the Mem is 16x8 structure which is vectored array. If Write is one
Mem_Address of Mem array is assigned to Mem_DataOut. And if write is zero MemData_in is stored at
Mem_Address of Mem.
Design Example 2-15: Memory design
module Memory(Mem_DataIn,Write,Mem_DataOut,Mem_Address);
input [7:0] Mem_DataIn;
input Write;
input [3:0] Mem_Address;
output [7:0] Mem_DataOut;
Memory 16x8
Mem_Address(8)
)8
Mem_DataIn(8) Mem_DataOut(8)
Write
reg [7:0]Mem[15:0];
always@( Mem_DataIn or Write or Mem_Address)
if(Write ==0)//read
Mem_DataOut = Mem[Mem_Address];
else if(Write ==1)
Mem[Mem_Address]= Mem_DataIn;
endmodule
2-11 Behavioural Level Modeling (Sequential Logic Circuits)
Sequential circuits can only be modeled using behavioural level modeling there is no way of modeling data flow
and gate level. Most sequential circuits are synchronized and controlled by signal synchronous control. Most of
time Counter, Shift register, Flip Flops and other sequential logic are triggered on Positive or negative of the clock.
Verilog HDL defines two key words POSEDGE and NEGEDGE to model edge sensitive behaviour of circuits.
2-11-1 Clock Edge control Signals
Verilog HDL has two edge control signals for each positive and negative edge of clocks. The design is only
triggered on the edge driven synchronizing signal.
12(a)Positive Edge of Clock
always@(posedge Sig)
12(b)Negative Edge of Clock
always@(negedge Sig)
Figure 2-12:Positive and Negative Edge of the Clocks
Flip Flops are of several type, D Flip Flop is very popular type. Example 2-16 shows the implementation of Flip Flip.
Notice that Value of Q is not affected by change in Data, if Posedge of Clock arrives that signal check the control. If
control is 0 the Q becomes Data otherwise it retains its value.
Design Example 2-16: D Flip Flop Example
module DFF(Qbar,Q,CLK,C,Din);
input CLK,C,Din;
output Q,Qbar; reg Q;
assign Qbar=~Q;
always@(posedge CLK)
if(C==0)
Q=D;
else
Q=Q;
endmodule
2-11-2 Blocking and Non-Blocking Statement
The purpose of such statements is assignment of RVAL on LVAL. Normally RVALs are combination of nets and
regs which are combined together by operators and yield a result which is assigned to LVAL.
In blocking Statements all lines inside procedural blocks are executed, RVALs are calculated. But assignments
on LVALs are not made. After procedural block ends all assignments are made together. It is represented by
(
a=3; b=2;
end
always
if(enable==1)
begin
a
reg [7:0]RF[3:0];
always@(Reg_in or Reg_Add or RW)
if(RW==0)
Reg_out
Note that there is no if condition to check if Count has reached it maximum value. This is because Count is 4 Bit
and will go to zero itself when maximum storage of the variable arrives however if Counter of other then 0-15 was
required using 4 bit for example 0-12 counter then a check was to be palced to set it back to zero if maximum
arrives
Example 2-19 shows shift register implementation, the register can shift both left and right shift once. There is
interesting end problem to implement a more generic universal Shift register. The Universal Shift register is
left for reader as an exercise, I can do all type of shifting including arithmetic, logical and circular.
All type of Shifting is simple in Verilog HDL, it can be done using matrix manipulation or shifting operator. In
Figure 2-13 Circular and Logical Shifting is explained and arithmetic shifting is left for the reader in the
exercise. The trick of shifting is simply figuring how bits will be manipulated after and before shifting.
Using Shifting
Operator
12-13(a) Logical Shift
r=r1//right
12-13(b) Circular Shift
temp=r[7]//save the last bit
r=r
module ShiftReg(DOut,LData,RData,Data_in,USR_Ctr,CLK); input [3:0]Data_in; input [1:0]USR_Ctr; input CLK; output LData,RData; output [3:0]DOut; reg LData,RData; reg [3:0]DOut; reg [3:0] Sreg; always@( posedge CLK) case(USR_Ctr)
2b00: SReg
1- There are no ports in the test bench.
2- All inputs are made register and outputs are made nets.
3- As inputs are made register therefore input values must be applied in Behavioural block.
4- The design is instantiated inside the test bench.
Figure 2-14:Test Bench design
2-12-2 Test Bench examples
Lets start writing test bench for Adder and Counter given example in earlier sections. In example 2-20 original
example with test bench is below.
1- Line 2,3 has registers to apply two inputs, these two registers will be connected to the inputs of design.
Initial block line 7,15 apply these inputs. This is just like signal generator.
Design Example 2-20: 4-Bit Adder with Test Bench
module Adder4Bit(A,B,Carry_in,Sum,Carry_Out);
input [3:0]A,B; input Carry_in;
output [3:0]Sum; output Carry_Out;
wire [3:1]C;
FullAdder FA0(.Sum(Sum[0]),.Carry_Out(C[1]),.In1(A[0]),.In2(B[0]),.Carry_In(Carry_in));
FullAdder FA1(.Sum(Sum[1]),.Carry_Out(C[2]),.In1(A[1]),.In2(B[1]),.Carry_In(C[1]));
FullAdder FA2(.Sum(Sum[2]),.Carry_Out(C[3]),.In1(A[2]),.In2(B[2]),.Carry_In(C[2]));
FullAdder FA3(.Sum(Sum[3]),.Carry_Out(Carry_Out),.In1(A[3]),.In2(B[3]),.Carry_In(C[3]);
endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
module TB_Adder4Bit();
reg [3:0]in1,in2; reg Cin;
wire [3:0]S; wire COut;
Adder4Bit A1(.A(in1),.B(in2),.Carry_in(Cin),Sum(S),.Carry_Out(COut));
initial begin
in1=4d2; in2=4d3; Cin=1b0;//testing normal case no.
#5 Cin=1b1;
#5 in1=-4d2; in2=-4d3; Cin=1b0;//both no. are negative
#5 in1=4d2; in2=-4d3; Cin=1b0;///one no. Is negative
#5 in1=-4d2; in2=4d3; Cin=1b0;//one no. is negative
#5 in1=4d10; in2=4d11; Cin=1b0; //When sum can exceed 4 bits
end
endmodule
2- Outputs are made net; simulators automatically connect these nets to oscilloscope of the tool. If the tool
does not provide this facility, we can always use Verilog system tasks; refer to figure 2-15.
3- Line 6 instantiate the design under test, it is mandatory to call the design under test.
2-12-3 System Tasks
System tasks are control which modify the inputs/output in specific way so that the outputs can be observed.
System task use dollar sign ($), modern simulators like Model Sim does not require such system tasks. The tasks
are not synthesizable and they are ignored by the synthesis tools as they are only meant to observe the output and
no role in the design itself.
Figure 2-15 does not cover all system tasks, but some tasks required in this section. More system tasks will be
covered in the latter sections as they will be required.
2-12-4 Designs with Clocking signals
Any design with synchronous signal which can is flipping itself after some time is called clock. It can be generated
using forever or always.
Design Example 2-21: Counter 4-Bit
$display, $monitor $ monitor, $display are used to display the outputs or any variables in the textual form on the
screen. $ Monitor is written once in the code and display values whenever the value of
variable is change, however $display shows the outputs only once where they are written.
The work like printf in C as shown below:
$display(value of the variable is=%h,a)
Where a is any variable to be displayed. %h is formatting control and display output in
hexadecimal.
$time Display the current time.
$stop, $finish,
$reset
All simulations are endless and once started they are not self-stopped. $finish is used to
finish the simulation after the time it is applied while $stop halts the simulation and returns
the control to model sim to enter commands. $reset starts the simulation from time t=0.
Formatting Controls Escape Sequence
%d or %D Decimal \n New line
%b or %B Binary \t Tabulation
%h or %H Hexa Decimal \\ Print \
%o or %O Octal \ Print
%m or %M Hierarchical name %% Print %
%t or %T Time Format
Figure 2-15: System Tasks in Verilog
Counter
4-Bit
RST
Clk
Count
module Counter4Bit(Count,Clk,RST);
output [3:0]Count;
input RST, Clk;
reg [3:0]Count;
always@(posedge Clk)
if(RST==1)
Count
module LFSR(Clk);
input Clk;
reg [3:0]SR; reg[2:0]TReg;
parameter DATA=4b1011, TAPS=3b110;
reg fb; integer i;
initial
begin
SR
Design Example 2-23: Arithmetic Logic Unit
OP Code Operations
2b00 ADD
2b01 Subtract
2b10 Logical AND
2b11 Logical OR
module ALU(ALU_out,ALU_inA, ALU_inB,OPCode);
input [1:0]OPCode;
input [3:0]ALU_inA, ALU_inB;
output [3:0]ALU_out;
reg [3:0]ALU_out;
always@(ALU_in or OPCode)
case(OPCode)
2b00: ALU_out
Design Example 2-24: Stack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module Stack(Stack_Empty,Stack_Full,Data_Out,PushPop,Data_in);
input PushPop; input [7:0]Data_In;
output [7:0]Data_Out; output Stack_Empty,Stack_Full;
reg [7:0]Data_Out; reg [3:0]ST[7:0]; reg [1:0]TOP;
assign Stack_Empty=(TOP==2d0)?1b1:1b0;
assign Stack_Full=(TOP==2d3)?1b1:1b0;
initial
TOP=2d0;
always@(Data_In or PushPOP)
case(PushPop)
1b0:
if(TOP>2d0)
begin
Data_Out
Example 2-25 shown RAM with 256 locations each location is 8-bit. Mem_DataOut and Mem_DataIn are 8-bit as
each location is 8-bit. The Mem_Address is also 8-Bit as there are 256 locations and to address 256 locations 8-Bit
are required.
Design Example 2-25: Random Access Memory
1
2
3
4
5
6
7
8
9
10
11
12
module Memory(Mem_DataOut,Mem_Address,Mem_Data_In,Write);
input [7:0]Mem_Address, Mem_Data_In;
input Write;
output [7:0]Mem_DataOut;
reg [7:0]Mem_DataOut;
reg [7:0]Mem[255:0];
always@( Mem_Address or Mem_Data_In or Write)
if(Write==0)
Mem_DataOut
$dumpfile dumpfile(filename.dmp)
$dumpvar Dump all variables in the design
$dumpvar(n,top) Putting any number n will dump all the variable in top
module and all n levels below.
$dumpon,$dumpoff Initialize and Stop dumping respectively
$readmemb Read the text file data load it into vectored array of
specified size $readmemb(filename.txt,R,x,y)
R is the name of vectored array while x and y are the size
of the vectored array.
Figure 2-16:Dumping Tasks and in Verilog
2-14-3 ROM Design
ROM is read only memory the data is once loaded into ROM and then it can only be read. No writes in ROM are
allowed. Line-7 contains system task to initialize the ROM contents.
Initial Statement is another choice for storing data in the ROM however best way to store data in ROM is
using System Tasks.
Design Example 2-25: Read Only memory using system Task
1
2
3
4
5
6
7
8
Module ROM(ROM_DataOut,ROM_DataIN);
input [2:0]ROM_Add;
output [3:0]ROM_DataOut;
reg[3:0]R[7:0];
assign ROM_DataOut=R[ROM_Add];
initial
$readmemb(romdata.txt,R,0,7);
endmodule
ROM 8x4 ROM_Add(3) ROM_DataOut(4)
Design Example 2-26: Read only Memory using Initial Statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Module ROM(ROM_DataOut,ROM_DataIN);
input [2:0]ROM_Add;
output [3:0]ROM_DataOut;
reg[3:0]R[7:0];
assign ROM_DataOut=R[ROM_Add];
initial
begin
R*0+
Selected Exercise Problems
2-1a: Write Verilog code for the even parity generator circuit given in Figure p2-1a. Write code at gate level and
data flow level. Also write test bench for the design.
Figure p2-1a: Even parity Generator Circuit
2-1b: Think of Circuit which is odd parity generator. Repeat 2-1a for odd parity generator.
2-2a: Design a counter which can count both up and down. A control called up down controls whether the
counter counts up or down. Whenever this control is 1 it should count up otherwise it counts down.
Figure p2-2a: Even parity Generator Circuit
2-2b: Design a 4-Bit Counter which count from 0-9. Repeat the problem with up and down counter, also write
their test benches.
2-3: Design cascaded counters, the counter are so arranged that first counter can count from 0-3, when first
counter counts from 0-3 the second counter will count one. When the second counter will count from 0-3 the
third counter will count one. This means it requires second counter to counter 4 times from 0-3 until the third
counter counts 0-3 once. Give the design, Verilog code and test bench for the design.
2-4a: There might be a possible over flow in the 4-Bit adder circuit, think of a mechanism through which the
overflow can be determine. More over give a code of module which can indicate possible overflow in the
addition. The circuit for full adder is given in Figure p2-4a.
rst
updown Up Down
Counter
CLK
Count
Figure p2-4a: Even parity Generator Circuit
2-4b: The circuit of adder subractor is given in the Figure p2-4b, instantiate the Adder4bit from example 2-10
and use data flow level to make 4-Bit adder subtractor circuit. Write test bench of the design to test the circuit.
Figure p2-4b: Even parity Generator Circuit
2-5a: Design a Register File which can store 16 Values each value is 8 bit wide. The Register File can store and
read two Values at a time. This means it got two addresses and one read/write control either the RF can write
or Read two values.
2-5b: Add special type of register Called accumulator register. The value stored inside the accumulator register
is added with already existing value in the Accumulator. The reset signal can reset the value of accumulator to
a[1]
FA1
b[1]
S[1]
a[0]
FA0
b[0]
S[0]
Carry_in
a[2]
FA2
b[2]
S[2]
a[3]
FA3
b[3]
S[3]
Carry_out
zero. Write a test bench of the design.
2-6a: Design a BCD to seven segment decoder. The purpose of the decoder is to translate a 4-Bit Binary number
to seven bit code which can be displayed on the seven segments.
Figure p2-6a: BCD to Seven Segment
2-6b: Write a verilog code of 4-Bit counter which can count from 0-9, then instantiate 4-bit counter and BCD to
seven segment Decoder coded in p 2-6a in one Main File. This will be a design of 4-bit counter with Seven
Segment Display.
Figure p2-6b: Counter to BCD to Seven Segment
Data_in0
Data_in1
Data_in
2
Data_in3
SEG_A
SEG_B
SEG_C
SEG_D
SEG_E
SEG_F
SEG_G
BCD to
Seven
segment
2-17: Design a Stop watch, the watch has three inputs. Start input start the clock and it start counting up until a
stop button is press. If stop is pressed once the counting with pause for a while but if Start is press again It will
restart from the same point. If Reset is pressed at this point the stop watch will go to zero again. The Stop
watch is synchronized by the clock signal, the output of the Stop Watch has two outputs Minutes and Seconds.
Second goes form 0-59 and then to zero making minutes to goes one up
Minutes goes from 0-59 and then to zero making Hours to goes one up
Figure p2-17: Stop Watch Diagram
2-31: The serial adder is shown in Figure p2-31. Suppose that Register A has 1101 and Register B has 1011.
Write verilog code for Serial register, JK Flip Flop and instantiate in the main module. Also use logic gates to
implement the Serial Adder.
CLK
Start
Stop
Reset
Minutes1 (3)
Seconds1 (3)
Seconds2 (3)
Minutes2(3)
Stop
Watch
Figure p2-31: Serial Adder
Shift Register A
Shift Register B
J
K
S1 S0
S1 S0
Clear
S
x
y
C Serial input
Serial Control
CLK