Prelim Module4 - B
Prelim Module4 - B
Prelim Module4 - B
COURSE INTENDED On the completion of the course, student is expected to be able to do the
LEARNING OUTCOMES: following:
II. OBJECTIVES: By the end of this module you should be able to:
III. INTRODUCTION:
The purpose of this module is to introduce different datatypes used in
VERILOG. This means that, by using an HDL, one can describe any
(digital) hardware at any level. VHDL is an HDL. And so is Verilog..
IV. CONTENTS:
Lesson Coverage:
- Data Types
DATA TYPES
Keywords are like a comfortable language element that you use to communicate with the compiler, and the
compiler winks at you and mouths. Always write keywords using lowercase letters. Why? Unlike VHDL, Verilog
is a case sensitive language. For example:
We can see some commonly used keywords in Verilog from the table below:
Identifiers
An identifier is a unique name, which identifies an object. They are case-sensitive made up of alphanumeric
characters, underscore, or a dollar sign.
We can start identifiers using alphanumeric or underscore. It’s not possible to name identifiers beginning with a
dollar sign since it is reserved for naming system tasks. Also starting with numbers is not advisable. Let’s see
how we can use identifiers in Verilog:
Another type of identifier that exists is the escape identifier. Escaped identifiers start with a backslash and end
with white space (i.e., space, tab, newline). Escaped identifiers can contain any printable characters. The
backslash and white space are not part of the identifier. For example:
/a+b
/**my_name**
Number Specifications
We can use two types of number specification in Verilog:
Sized numbers
<size>’base format><number>
The size specifies the number of bits in the number. It is written in decimal only. The base format is used for
representing which base we use to represent our number. Legal base formats are binary (‘B or ‘b), decimal (‘d or
‘D), octal (‘O or ‘o) or hexadecimal (‘h or ‘H).
The number is specified as consecutive digits from 0,1,2,3,4,5,6,7,8,9, a,b,c,d,e,f. Only a subset of these digits is
legal for each base. Let’s see the legal digits for each base.
Unsized number
Numbers without <size> have a default size of 32 bits. The default size differs depending on the machine and
simulator. When no base is specified, it is decimal by default. For example:
It is recommended to use sized numbers. As a designer, we always thrive to use our memory allocation efficiently
to build efficient hardware.
The unsized format will take up 32-bit of memory, which is a total waste in this case. Hence, we prefer sized
number specifications.
X or Z values
For representing ‘unknown’ and ‘high impedance,’ Verilog uses x and z. These are important for modeling real
circuits. An x or z sets four bits in the hexadecimal base, three bits in the octal base, and one bit in the binary
base. For example:
Comments
For describing or documenting a model, we use comments. This part of the code will be skipped during execution.
For example:
We can write comments in two ways. When we want to skip one full line during execution, we specify the
comment using //. Verilog jumps from that point to the end of the line.
To write multiline comments, we start with /* and end it with */.
/* this is a
multi-line comment */
That’s all about some basic conventions and elementary syntax in Verilog. Now, let’s see what the different data
types available in Verilog are.
Data types
Data types in Verilog inform the compiler whether to act as a transmission line (like a wire) or store data (like a
flip flop). This depends on what group of data type is declared. There are two groups: NET and REGISTER. Let’s
discuss them.
Net
Recall that the entire purpose of an HDL like Verilog is to describe circuits. So physical circuit elements that you
see need to be describable by the HDL.
A Net represents connections between hardware elements. Nets don’t store values. They have the values of the
drivers.
For instance, in the figure, the net out connected to the output is driven by the driving output value A&B.
Types of Nets
Wire
The keyword wire is the most commonly used net in modeling circuits. When used in the code, it exhibits the
same property as an electrical wire used for making connections. Let’s see how we can declare wire by describing
a simple AND gate in Verilog:
module and_gate;
input wire A,B;
output wire C;
assign C = A & B;
endmodule
Tri
This is another type of net that has identical syntax and function as wire. Then, what’s the difference?
A wire net can be used for nets that are driven by a single gate or continuous assignment. Whereas, the tri net can
be used where multiple drivers drive a net. Let’s see an example where tri is declared:
https://chipdesignworld.com/2020/02/06/verilog-hdl-syntax-and-basic-concepts/
The above diagram shows a 2:1 mux constructed using tri-state buffers. Let’s see how we can write the Verilog
code for the above circuit.
Have you noticed something? We have declared out as tri because it is driven by multiple drivers as per the logic
circuit. We have instantiated tri-state buffers bufif1 and bufif0 to implement the functionality of the MUX.
It is a gate which functions exactly opposite to the NOT gate. That is, it transfers the signal to the output from the
input exactly as it is. These buffers are used to implement delays in circuits. The logic symbol of a buffer gate is
given below:
buffer gate
buf(out,in)
When we add a control signal to a buffer, we get tri-state buffers. These gates will propagate only if their control
signal is asserted. If the control signal is de-asserted, they propagate z(high impedance, tri-state). These gates are
used when a signal is to be driven only when the control signal is asserted. Such a situation is applicable when
multiple drivers drive the signal.
tristate buffer with an active-low control signal(bufif0): It will propagate the input to the output only if the control
signal is asserted as 0. Else it propagates z.
tristate buffer with an active-high control signal(bufif1): It will propagate the input to the output only if the control
signal is asserted as 1. Else it propagates z. The logic symbols of bufif0 and bufif1 are shown below :
bufif1 bufif0
For declaring tri-state buffers, Verilog gate primitives are available as shown:
In every circuit we build, there are two crucial elements – power supply and ground. Hence, we use supply0 and
supply1 nets to represent these two. The supply1 is used to model power supply. Whereas, the supply0 is for
modeling ground. These nets have constant logic values and strength level supply, which is the strongest of all
strength levels.
supply1 Vcc; // all nets connected to Vcc are connected to power supply
supply0 GND; // all nets connected to GND are connected to ground
Variable Datatypes
The variable datatypes are responsible for the storage of values in the design. It is used for the variables, whose
values are assigned inside the always block. Also, the input port can not be defined as a variable group. reg and
integer are examples of the variable datatypes. For designing purposes, we commonly use reg.
Registers
Isn’t that hardware registers made from flip flops? No. In Verilog, the term register means a variable that can hold
value. It can retain value until another value is placed. Unlike a net, a register does not need a driver. It doesn’t
need a clock as hardware registers do.
Register datatype is commonly declared using the keyword reg. Let’s see how we can declare reg in Verilog:
reg reset // declare a variable reset that can hold it's value
initial
begin
reset = 1'b1; //initialize the reset variable to 1 to reset the digital circuit
#10 reset = 1'b0; //After 10 time units, reset is deasserted.
end
Integer
An integer is a general-purpose register data type used for manipulating quantities. The integer register is a 32-
bit wide data type. So what makes it different from reg? The reg store values as unsigned quantities, whereas
integer stores signed values. To declare an integer in Verilog, we use the keyword integer. For example:
Real
The real register is a 64-bit wide data type. In order to store decimal notation(eg 3.14) or scientific notation(eg:
3e6 which is 3 X 106 ), we use the keyword real. Real numbers cannot have a range declaration, and their default
value is 0. Let’s see how we can declare them Verilog:
initial
begin
delta = 4e10; //assigned scientific notation
delta = 2.13 //assigned a decimal value of 2.13
end
If a real value is assigned to an integer, it gets rounded off to the nearest integer. For example:
integer i;
initial
begin
i = delta // i gets the value 2 (rounded value of 2.13);
end
Time registers
Since timing is an essential factor in designing digital circuits, we need something to keep track of it. Hence, the
keyword time helps us to record the simulation time. The default size of time-register is implementation-specific
but should be at least 64 bit. To get the current simulation time, the $time system function is invoked.
The realtime register is also a time register which will record current simulation time. For example
1-bit is declared as a scalar datatype. It has only one bit. When we declare a wire or reg as a scalar, we write them
as:
wire n;
reg d1;
Vector data types are multi-bit. We either use [<MSB bit number> : <LSB bit number>] or [<LSB bit number> :
<MSB bit position>] to represent them. For example, we can declare a 4-bit wire or reg as:
wire [0:3] a;
reg [3:0] d0;
Module declaration
The module forms the building block of a Verilog design. A module definition always starts with the keyword
module and ends with endmodule. There are five components within a module.
All these components except the module, module_name, and endmodule can be mixed and matched as per design
needs. To get a better understanding, we can see the Verilog code of 2:1 Multiplexer:
//port declarations
input s,a,b;
output out;
//endmodule statement
endmodule
Have you noticed something? There are no variable declarations, instantiation of lower gates, or behavioral
blocks mentioned in the above module. Let’s see the test bench treating the above DUT.
//module name
//mux_21_tb module
module mux_21_tb;
//endmodule statement
endmodule
The test bench module above contains the variable declaration, behavioral block, and instantiation of lower
blocks. But there is no port declaration and dataflow statements in this module. What can we understand from
that?
It’s not compulsory that all the five components should be incorporated in the module. The components except
for the module, module_name, and endmodule are mixed and matched according to what our design demands.
IO Port Declaration
module mux_21(s,a,b,out);
input s,a,b;
output out;
The above code has specified that there are ports in our mux_21 module. Wait? What are the ports?
Ports are what declares the interface of the module. The ports model the pins of the hardware components. For
example, our mux_21 has four ports communicating with its internal circuitry. Depending on their direction, ports
can be input, output, or inout. As per our mux_21 module, s, a, and b are input ports, while out is the output port.
What about the ports in the mux_21_tb (testbench) module? It is a stimulus module. Hence we use reg and wire
declarations. Declaring ports is not applicable in this case.
D flip flop
input clk,d,rest;
output reg q, qbar;
We can also declare ports using ANSI C style. In this style, the complete information of the port is specified along
with the module and port declarations. Such an example is given below:
endmodule
V. REFERENCES: Roth, C.H. Jr. And John, L. K. (2018). Digital Systems Design Using VHDL (3rd
ed.). Texas, USA: Cengage Unlimited