Chapter 3: Verilog Syntax Details

 

Chapter 3: Verilog Syntax Details

Our goal up to this point has been to teach you how to model some simple circuits before swamping you with all the details about Verilog types, ports, and numbers. But as we do more Behavioral design it becomes easier to make mistakes in this area. Before you begin a big design you might want to get a copy of "Verilog HDL" by Samir Plantikar and memorize Chapters 3, 4, and 7. What follows is just enough information in order to understand the subsequent behavioral code examples.

3.1 Structural Data Types: wire and reg

Verilog supports structural data types called nets which model hardware connections between circuit components. The two most common structural data types are wire and reg. The wire nets act like real wires in circuits. The reg type hold their values until another value is put on them, just like a register hardware component. The declarations for wire and reg signals are inside a module but outside any initial or always block. The initial state of a reg is x unknown, and the initial state of a wire is z.

Ports:Modules communicate with each other through ports, the signals listed in the parameter list at the top of the module. Ports can be of type in, out, and inout.

Here are 3 simplistic rules for matching the structural data type to the type of port:

  1. Use reg as the outputs of Behavioral blocks. If you us a wire then the value will never be seen by other blocks.
  2. Use wire for all inputs, inouts, and most outputs of Structural elements.
  3. If you need a special strength type operation use special net keyword wand, wor, tir, triand, trior, trireg.

3.2 Behavioral Data Types: integer, real, and time

The types in integer and real are convenient data types to use for counting in behavioral code blocks. These data types act like their counter parts in other programming languages. If you eventually plan to synthesize your behavioral code then you would probably want to avoid using these data types because they often synthesize large circuits.

The data type time can hold a special simulator value called simulation time which is extracted from the system function $time. The time information can be used to help you debug your simulations.

..... //code fragment from inside a module

integer i, y;
real a;
real b = 3.5;
real c = 4;
time simulationTime;
initial
  begin
  y = 4;
  i = 5 + y;
  c = c + 3.5;
  a = 5.3e4;
  simulationTime = $time; 
  $display("integer y = %d, i = %f \n", y, i);
  $display("reals   c = %f, a = %e, b= %g \n", c, a, b);
  $display("time    simulationTime = %t \n", simulationTime);
  end

3.3 Number Syntax

Numbers in verilog are in the following format

'

The size is always specified as a decimal number. If no is specified then the default size is at least 32bits and may be larger depending on the machine. Valid base formats are 'b , 'B , 'h , 'H 'd , 'D , 'o , 'O for binary, hexadecimal, decimal, and octal. Numbers consist of strings of digits (0-9, A-F, a-f, x, X, z, Z). The X's mean unknown, and the Z's mean high impedance If no base format is specified the number is assumed to be a decimal number. Some examples of valid numbers are:

  2'b10 // 2 bit binary number
   'b10 // at least a 32-bit binary number
      3 // at least a 32-bit decimal number
  8'hAf // 8-bit hexadecimal
-16'd47 // negative decimal number 

3.4 Behavioral Design with blocking and non-blocking statements

There are 2 kinds of assignment statements: blocking using the = operator, and non-blocking using the <= operator. Blocking assignments act like sequential code statements and execute when they are called. Non-blocking schedule events to happen at some time in the future. This can be confusing because lines that appear after a non-blocking statement execute at the same time as the non-blocking statement. Here are some examples:

#5 x = 1'b0;   // blocks for 5 time units, applies value to x, then next line goes
y = 1'b1;      // blocks, sets y to 1 now, then next statement goes  
y <=  #3 1'b0; // evaluates now, schedules apply y=0 in 3 time units, and next line goes
#5 x <= y;     // waits for 5 time units, evaluates, 
                 //  schedules apply at end of current time, and next line goes

The following two code blocks are not equivalent:

// Section 1: Blocking statements execute sequentially
#5 a = b;  // waits 5 time units, evaluates and applies value to a
   c = d;  // evaluates and applies value to c

// Section 2: Non-Blocking statements execute concurrently
#5 a <= b; // waits 5 time units, evaluates, schedules apply for end of current time
   c <= d; // evaluate, schedules apply for end of current time
           // At end of current time both a and c receive their values

3.6 Arrays, Vectors, and Memories

Verilog supports three similar data structures called Arrays, Vectors, and Memories. Arrays are used to hold several objects of the same type. Vectors are used to represent multi-bit busses. And Memories are arrays of vectors which are accessed similar to hardware memories. Read the following examples to determine how to reference and use the different data structures.

//*** Arrays for integer, time, reg, and vectors of reg ***************
integer i[3:0];  //integer array with a length of 4
time    x[20:1]; //time array with length of 19
reg     r[7:0];  //scalar reg array with length of 8

c = r[3]; //the 3rd reg value in array r is assigned to c

//*** Vectors are multi-bit words of type reg or net (wire)************
reg  [7:0] MultiBitWord1;    // 8-bit reg vector with MSB=7 LSB=0
wire [0:7] MultiBitWord2;    // 8-bit wire vector with MSB=0 LSB=7
reg [3:0] bitslice;
reg a;                      // single bit vector often referred to as a scalar  
....    //referencing vectors 
a = MultiBitWord1[3]; //applies the 3rd bit of MultiBitWord1 to a
bitslice = MultiBitWord1[3:0]; //applies the 3-0 bits of MultiBitWord1 to bitslice


//*** Memories are arrays of vector reg ********************************
reg [7:0] ram[0:4095];      // 4096 memory cells that are 8 bits wide

               //code excerpt from Chapter 2 SRAM model
input [11:0] ABUS;     // 12-bit address bus to access all 4096 memory cells
inout [7:0] DATABUS;   // 8-bit data bus to wite into and out of a memory cell
reg  [7:0] DATABUS_driver;
wire [7:0] DATABUS = DATABUS_driver; //inout must be driven by a wire
....
for (i=0; i < 4095; i = i + 1)  // Setting individual memory cells to 0
  ram[i] = 0;
end
....
ram[ABUS] = DATABUS;  //writing to a memory cell
....
DATABUS_driver =  ram[ABUS]; //reading from a memory cell

3.7 Operators

Here is a small selection of the Verilog Operators which look similar but have different effects. Logical Operators evaluate to TRUE or FALSE. Bitwise operators act on each bit of the operands to produce a multi-bit result. Unary Reduction operators perform the operation on all bits of the operand to produce a single bit result.

Operator Name Examples
! logical negation
~ bitwise negation
&& logical and
& bitwise and abus = bbus&cbus;
& reduction and abit = &bbus;
~& reduction nand
|| logical or
| bitwise or
| reduction or
~| reduction nor
^ bitwise xor
^ reduction xor
~^ ^~ bitwise xnor
~^ ^~ reduction xnor
== logical equality, result may be unknown if x or z in the input if (a == b)
=== logical equality including x and z
!= logical inequality, result may be unknown if x or z in the input
!== logical inequality including x and z
> relational greater than
>> shift right by a number of positions a = shiftvalue >> 2;
>= relational greater than or equal
< relational less than
<< shift left by a number of positions
<= relational less than or equal if (a <= b)
<= non blocking assignment statement, schedules assignment for future and allows next statement to execute #5 b <= b + 2;
= blocking assignment statement, waits until assignment time before allowing next statement to execute #5 a = a + 2;

Verilog also supports arithmetic, replication, and concatenation operators

 

Links

SynaptiCAD provides a free 6 month license for Verilog Simulator