Featured post

Top 5 books to refer for a VHDL beginner

VHDL (VHSIC-HDL, Very High-Speed Integrated Circuit Hardware Description Language) is a hardware description language used in electronic des...

Sunday, 9 September 2012

Identifiers

Formal Definition

The identifier is a unique name, which identifies an object.

Simplified Syntax

identifier

\escaped_identifier

Description

An identifier is used as an object reference. An identifier can contain a sequence of letters, digits, underscores (_) and dollar signs ($). The first character of an identifier can only be a letter or an underscore (Example 1). Identifiers are case sensitive.

Escaped identifiers (Example 2) start with backslash character (\) and end with white space (i.e. space, tab, new line). Escaped identifiers can contain any printable characters. Leading backslash character and white space at the end are not considered as part of an identifier, thus identifiers \enable and enable are identical.

Examples

Example 1

reg enable;
wire _ready;
integer group_a;
reg and5;
tri clk$1;

Legal identifiers.

Example 2

wire \+^_^+*+*<-> ;
reg \!clk ;

White spaces between an escaped identifier and the semicolon that follows it are required, because otherwise, the semicolon will be taken as a part of an identifier.
reg \clk ;

defines \clk identifier, but
reg \clk;

defines \clk; identifier (and there will be also an error message because a variable declaration should be ended by semicolon).

Important Notes

  • Identifiers are case sensitive

  • \clk and clk are the same identifiers

  • Escaped identifiers should be followed by at least a white space character

Functions

Formal Definition

Functions provide a means of splitting code into small parts that are frequently used in a model.

Simplified Syntax

function type_or_range identifier;

  parameter_declaration;

  input_declaration;

  register_declaration;

  event_declaration;

  statement;

endfunction

Description

Functions can only be declared inside a module declaration.

Function definition begins with the function keyword and ends with the endfunction keyword. The returned type or range declaration followed by a function identifier and semicolon should appear after the function keyword. Function can contain declarations of range, returned type, parameters, input arguments, registers and events (these declarations are similar to module items declaration). Net declarations are illegal. Declaration of parameters, registers, events and returned type or range are not required. A function without a range or return type declaration, returns a one-bit value. Functions should have at least one input declaration and a statement that assigns a value to the register with the same name as the function.

Any expression can be used as a function call argument. Functions cannot contain any time-controlled statements, and they cannot enable tasks. Functions can return only one value.

Examples

Example 1

function [15:0] negation;
input [15:0] a;
negation = ~a;
endfunction

A function returning 16-bit value.

Example 2

function real multiply;
input a, b;
real a, b;
multiply = ((1.2 * a) * (b * 0.17)) * 5.1;
endfunction

A function returning real value.

Example 3

real a;
wire [15:0] b;
wire c, d, e, f;
assign b = negation ({4{c, d, e, f}}); // (#1)
initial begin
a = multiply(1.5, a); // (#2)
$display(" b=%b ~b=%b”, b, negation(b)); // (#3)
end

Examples of function calls declared in example 1 and 2 (#1 - continuous assignment, #2 and #3 - procedural statements).

Important Notes

· Functions cannot contain time-control statements.

· A function returns value when invoked by its name.

· Functions should have at least one input argument.

· Functions cannot have output or inout arguments.

· Functions can only be declared inside a module declaration.

· Can use 'include to insert function code

File I/O Functions

Formal Definition

File I/O functions perform operations on files.

Simplified Syntax

$fopen (file_name) ;

$fclose (file_name) ;

$fdisplay (arguments) ;

$fwrite (arguments) ;

$fstrobe (arguments) ;

$fmonitor (arguments) ;

$readmemb ("file", memory_identifier [,begin_address[,end_address]]) ;

$readmemh ("file", memory_identifier [,begin_address[,end_address]]) ;

Description

The $fopen function opens a file and returns a multi-channel descriptor in the format of an unsized integer. This is unique for each file. All communications between the simulator and the file take place through the file descriptor. Users can specify only the name of a file as an argument, this will create a file in the default folder or a folder given in the full path description.

To close an opened file use the $fclose function. This function is called without any arguments, it simply closes all opened files. If an argument is specified it will close only a file in which the descriptor is given. By default, before the simulator terminates, all open files are closed. This means that the user does not have to close any files, and closing is done automatically by the simulator.

All file output tasks work in the same way as their corresponding display tasks. (see the Display Tasks chapter for further information) The only difference is a file descriptor that appears as the first argument in the function argument list. These functions only can append data to a file and cannot read data from files.

To read data from a file and store it in memory, use the functions: $readmemb and $readmemh. The $readmemb task reads binary data and $readmemh reads hexadecimal data. Data has to exist in a text file. White space is allowed to improve readability, as well as comments in both single line and block. The numbers have to be stored as binary or hexadecimal values. The basic form of a memory file contains numbers separated by new line characters that will be loaded into the memory.

When a function is invoked without starting and finishing addresses, it loads data into memory starting from the first cell. To load data only into a specific part of memory, start and finish addresses have to be used. The address can be explicit, given in the file with the @ (at) character and is followed by a hexadecimal address with data separated by a space. It is very important to remember the range (start and finish addresses) given in the file, the argument in function calls have to match each other, otherwise an error message will be displayed and the loading process will be terminated.

Examples

Example 1

integer file ;
reg a, b, c;
initial begin
  file = $fopen("results.dat") ;
  a = b & c ;
  $fdisplay(file, "Result is: %b", a) ;
  $fclose(file) ;
end

Result of operation a = b & c will be put into the file result.dat.

Example 2

reg [3:0] memory [15:0] ;
initial begin
  $readmemb("data.bin", memory) ;
end

Loading data in binary format from file data.bin into memory.

Example 3

reg [3:0] memory [15:0] ;
initial $readmemh("data.hex", memory, 4, 2) ;

Loading data in hexadecimal format from file data.hex into memory starting at address 4 and down to 2.

Important Notes

· If the file that is being opened in one block and accessed in another parallel block, then an error can occur if accessing takes place before the file is opened.

· Care must be taken when accessing files in independent procedural blocks.

Expression Bit Length

Formal Definition

This chapter explains values for evaluation of size of expressions.

Description

Every expression has a result with a specified bit length. Therefore operand lengths should be checked before the expression is calculated to prevent the loss of important bits. This problem occurs when the result of an expression is assigned to a variable that cannot store all the result bits.

Expression

Bit length

Unsized constant number

Same as integer

Sized constant number

As given

i op j,

op: + - / % & | ^ ^~ ~^

Max(length of i, length of j)

i * j

Length of i + length of j

op i,

op: + - ~

Length of i

i op j,

op: == != === !== && || > >= < <=

1 bit

op i,

op: & ~& | ~| ^ ~^ ^~

1 bit

i op j,

op: >> <<

Length of i

i ? j : k

Max(length of j, length of k)

{i,j}

Length of i + length of j

{i{j,k}}

i * (length of j + length of k)

Table 2 Expression bit length rules

Examples

Example 1

reg [3:0] a;
reg [7:0] b;
reg [15:0] c;
a + b -> 8 bits
a * b -> 12 bits
a || b -> 1 bit
a >> 2 -> 4 bits
(c) ? a : b -> 8 bits
{i,j} -> 12 bits
{2(a,b}} -> 24 bits

Important Notes

  • The expression result bit-length should be known before the assignment to prevent unintended data loss.

Edge Sensitive Path

Formal Definition

The edge sensitive path is a module path described with an edge transition at the source.

Simplified Syntax

Paralel_path:

  ([edge_identifier] input_terminal =>

  output_terminal [polarity]:data_source) = delays;

Full_path :

  ([edge_identifier] input_terminal *>

  output_terminal [polarity]:data_source) = delays;

Edge identifier:

  posedge

  negedge

Polarity:

  + -

Description

The edge sensitive path is the same as simple module path. The difference is that in the edge sensitive path, the source edge transition is used. The edge identifier can be either aposedge or a negedge. If an input is declared as a vector port then the least significant bit is used to detect the edge transition. If no transition is specified, then the edge sensitive path works as a simple module path (i.e. at any transition that occurs on an input terminal).

The polarity operator describes if data passing from the source to the output is inverted (-) or not inverted (+).

The keywords posedge and negedge can be used both in parallel and in full paths.

Examples

Example 1

(posedge clk => (q +: d)) = (3,1);

At a positive edge on a 'clk' signal the value of 'q' will change, using the rising delay of 3 and the falling delay of 1 time unit. The data path travels from 'd' to 'q' and data is not inverted.

Important Notes

· The polarity operator is used by timing analysis tools and is ignored by the simulator.

Display Tasks

Formal Definition

System tasks display specific information from the simulator.

Simplified Syntax

$display | $displayb | $displayh | $displayo (arguments) ;

$write | $writeb | $writeh | $writeo (arguments) ;

$strobe | $strobeb | $strobeh | $strobeo (arguments) ;

$monitor | $monitorb | $monitorh | $monitoro (arguments) ;

$monitoron ;

$monitoroff ;

Description

Generally, display system tasks are grouped into three categories. The first one includes the display and write tasks such as the $display and the $write tasks. The second category is strobe monitoring, which consists of the $strobe group of tasks and the continuous monitoring tasks such as the $monitor task.

The first group of displaying tasks is very similar to print the function in the ANSI C language (the syntax is almost the same). The $write and the $display tasks work in the same way and the only difference is that the $display task adds a new line character at the end of the output, while the $write task does not.

When one of these tasks is invoked, it simply prints its arguments. The order of printed arguments is the same as the order that the x appear in the argument list. If no argument is specified, it can be declared a null argument (two adjacent commas) and when the display task is invoked, it simply prints a single space character (Example 1). An argument can be an expression that returns a value and a quoted string (see Example 2).

When an argument is given as a quoted string, there are several rules concerning format, the string argument is described in more detail in the String chapter. However there are some differences and extensions to format strings in display system tasks.

The display tasks have a special character (%) to indicate that the information about signal value is needed. When using a string, the compiler recognizes the % character and knows that the next character is a format specification. For a full description of all format specifications see the following table. If the format specification sign is used it should always be followed by a corresponding argument (exception is the %m argument).

If we need to display the % character we should use double %%.

%d or %D

Decimal format

%b or %B

Binary format

%h or %H

Hexadecimal format

%o or %O

Octal format

%c or %C

ASCII character format

%v or %V

Net signal strength

%m or %M

Hierarchical name

%s or %S

As a string

%t or %T

Current time format

Table 1 The format specification for display system tasks.

When the $display or $write system task is executed it displays the string, and all format specifications are replaced with corresponding expression values (see Example 3 and 4).

These system tasks can be invoked with "o", "h" and "b" extensions. For example $writeb, $writeo, and $displayh. When invoked, they inform the simulator that there are some arguments without corresponding format specifications and the default display format should be changed. By default, $display and $write system tasks use the decimal format to change display formats (see Example 5).

For information on how the %t format specification works see the Timescale chapter. This format specification is similar to $timeformat system task.

The size of the displayed data is very important. Generally it depends on the format specification. If you are using a hexadecimal format, the data will be displayed as four characters, each of them representing four bits of value (a single hexadecimal value can be represented as four bits). Similarly, octal values will be displayed as group of characters representing three bits. See Examples 4 and 5 for further information. The result of an expression is automatically sized, however you can change default settings by adding 0 (zero) after the % character. Example 6 shows how it is applied and displays the results. In the decimal format, values with leading zeros will be replaced by a space character. The number of spaces added corresponds to the number of truncated zeros.

Another very useful display tasks feature is rules applying to the result of an expression that has an unknown or high impedance value.

If you are using decimal format (%d) the following rules apply:

  • Single lowercase "x" character will be displayed when all bits are of an unknown value
  • Single uppercase "X" character will be displayed when some bits are of an unknown value
  • Single lowercase "z" character will be displayed when all bits are of a high impedance value
  • Single uppercase "Z" character will be displayed when some bits are of a high impedance

If you are using hexadecimal (%h) and octal (%o) formats the following rules apply:

  • Single lowercase "x" will be displayed when all bits in group are of an unknown value
  • Single uppercase "X" will be displayed when some bits in group are of an unknown value
  • Single lowercase "z" will be displayed when all bits in group are of a high impedance value
  • Single uppercase "Z" will be displayed when some bits in group are of a high impedance

NOTE: In the octal format, a group represents a group of three bits that can be represented as one digit within the range is 0 to 7. In the hexadecimal format, a group of four bits can be represented as one character within the range 0 to 9 and characters in range a to f. (See Examples 7 and 8)

The strength information may be needed when dealing with nets. For this purpose there is a special %v format specification in Verilog HDL to retrieve such information. It reports strength of a net but only in a scalar type. Three characters represent the strength, which is displayed in the console. The first two characters inform us about strength and the third character is the actual value of the net. In Verilog there are only four values: 0, 1, x, z, but the value returned by %v can also be L or H. See the table below for a full description of the strength identifier:

The first two characters:

Mnemonic

Strength name

Strength level

Su

Supply drive

7

St

Strong drive

6

Pu

Pull drive

5

La

Large capacitor

4

We

Weak drive

3

Me

Medium capacitor

2

Sm

Small capacitor

1

Hi

High impedance

0

The third character:

0

Logic 0 value

1

Logic 1 value

X

An unknown value

Z

A high impedance value

L

Logic 0 or high impedance value

H

Logic 1 or high impedance value

For further rules on displaying strengths, refer to the chapter regarding Strength.

The second category of display tasks is the strobe monitoring tasks. The $strobe task also has extensions such as o, b and h. They work in the same way as the $display task, however when the $display or $write task is encountered, it is executed immediately. The $strobe task is suspended until all events that occur in a particular time are processed. This means that this task returns values that are used in the next time unit. See example 10.

The last category of display tasks consists of continuous monitoring tasks. This category includes $monitor, $monitoron and $monitoroff. The difference between this group of tasks and other tasks is that these tasks provide a means of displaying a value when an event occurs. The $strobe returns value when all events in the time unit occurs, while $monitor is sensitive to an event on a variable in its argument list.

Examples

Example 1

$display(, ,) ;
$write(, ,) ;

These tasks produce single space characters; however $display adds a new line character at the end of a line.

Example 2

reg a,b ;
$display("Simple string");
$write(a*b) ;

$display produces a Simple string text and $write evaluates a value of an expression and prints the result in the console window.

Example 3

// reg a, b ;
// a = 0 ;
// b = 1 ;
$display("The value of a is: %b", a) ;
$write ("The value of b is: %b", b) ;

The console window displays the following:

The value of a is: 0

The value of b is: 1.

Notice that the $write task prints the results below the $display tasks. ($display adds a new line character). If you change the order of these tasks to make the $write task first, then the console window will display the following:

The value of b is: 1 The value of a is: 0

This is because the $write task does not add a new line character at the end of the line.

Example 4

reg [8:0] a ; // a = 492 ;
reg [7:0] b ; // b = 205 ;
$display("The decimal value of a is: %d", a) ;
$display("The octal value of a is: %o", a) ;
$display("The binary value of a is: %b", a) ;
$display("The hexadecimal value of a is: %h", a) ;
$display("The decimal value of b is: %d", b) ;
$display("The hexadecimal value of b is: %h", b) ;
$display("The binary value of b is: %b", b) ;
$display("The octal value of b is: %o", b) ;

The results are:

The decimal value of a is: 492

The octal value of a is: 754

The binary value of a is: 111101100

The hexadecimal value of a is: 1ec

The decimal value of b is: 205

The hexadecimal value of b is: cd

The binary value of b is: 11001101

The octal value of b is: 315

In the hexadecimal format, a single character represents a group of four bits and in the octal format , a single character represents a group of three bits.

Example 5

reg [8:0] a ; // a = 492 ;
$display(a, ";") ;
$displayb(a, ";") ;
$displayo(a, ";") ;
$displayh(a, ";") ;

The results are:

492;

111101100;

754;

1ec;

Example 6

reg [31:0] a ; // a = 40 ;
$display("Decimal value a is: '%d'", a) ;
$display("Decimal value a is: '%0d'", a) ;
$display("Octal value a is: '%o'", a) ;
$display("Octal value a is: '%0o'", a) ;

The results are:

Value a is: ' 40'

Value a is: '40'

Octal value a is: '00000000050'

Octal value a is: '50'

Notice that in the first case, the value is preceded by eight space characters. The register can store a maximum value of 4294967295. To print this number, 10 characters are needed. If only 2 characters are displayed (40), the remaining eight characters are replaced by space characters. By using the %0d format specification, you cause the value to be printed without any space characters and automatically resized. Space characters only in the case of decimal format replace the leading zeros. In other cases, zeros are always displayed.

Example 7

reg [4:0] a ;
$display("Value a: %d", a) ; // a = 5'bxxxxx ;
$display("Value a: %d", a) ; // a = 5'b1x1x0 ;
$display("Value a: %d", a) ; // a = 5'bzzzzz ;
$display("Value a: %d", a) ; // a = 5'b10zz1 ;
$display("Value a: %d", a) ; // a = 5'b1x0zz ;

This example shows how the rules apply to %d format specification.

Results are:

Value a: x

Value a: X

Value a: z

Value a: Z

Value a: X

Notice that in the last case, the unknown bit and high impedance bits result in a single uppercase X. This is because an unknown value has higher priority than a high impedance value.

Example 8

reg [4:0] a ;
$display("Value a: %o", a) ; // a = 5'bxxxxx ;
$display("Value a: %o", a) ; // a = 5'b1x1x0 ;
$display("Value a: %o", a) ; // a = 5'bzzzzz ;
$display("Value a: %o", a) ; // a = 5'b10zz1 ;
$display("Value a: %o", a) ; // a = 5'b1x0zz ;

For the %o format specification the results are:

Value a: xx

Value a: XX

Value a: zz

Value a: 2Z

Value a: XZ

See the expression bit length chapter for more details on zz and xx .

Example 9

reg [4:0] a ;
$display("Value a: %h", a) ; // a = 5'bxxxxx ;
$display("Value a: %h", a) ; // a = 5'b1x1x0 ;
$display("Value a: %h", a) ; // a = 5'bzzzzz ;
$display("Value a: %h", a) ; // a = 5'b10zz1 ;
$display("Value a: %h", a) ; // a = 5'b1x0zz ;

The results are:

Value a: xx

Value a: 1X

Value a: zz

Value a: 1Z

Value a: 1X

Example 10

reg [4:0] a ;
$strobe("Value a: %h", a) ;

Important Notes

  • To display the % character use double %%.

Disable Statement

Formal Definition

The disable statement provides means of terminating active procedures.

Simplified Syntax

disable task_identifier;

disable block_identifier;

Description

The disable statement can be used to terminate tasks (Example 1), named blocks (Example 2) and loop statements (Example 3) or for skipping statements in loop iteration statements (Example 4). Using the disable keyword followed by a task or block identifier will only disable tasks and named blocks. It cannot disable functions. If the task that is being disabled enables other tasks, all enabled tasks will be terminated.

If a task is enabled more than once, then disabling that task terminates all its instances.

Examples

Example 1

task t;
output o;
integer o;
#100 o = 15;
endtask
disable t; // Disabling task t.

Example 2

begin : named_block
a = 1; // #1
disable named_block;
a = 2; // #2
end

Statement #2 will never be executed, therefore after execution of this block, variable 'a' will have 1 as its value.

Example 3

begin : break_block
i = 0;
forever begin
  if (i==a)
  disable break_block;
  #1 i = i + 1;
  end
end

The forever statement will be executed until 'i' is not equal to 'a'.

Example 4

begin
i = 0;
forever begin : continue_block
  if (i==a)
  disable continue_block;
  #1 i = i + 1;
  end
end

If 'i' is equal to 'a' then statement (#1 i = i + 1) that appears after the disable statement will not be executed.

Important Notes

· The disable statement cannot be used to disable functions.

· If a task or a named block contains other tasks or named blocks then disabling that task or a named block terminates all tasks and blocks within.

· The disable statement can appear only within the procedural blocks.