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

Simulation Control Tasks

Formal Definition

Simulation control tasks allow you to stop or quit simulation.

Simplified Syntax

$stop [(n)] ;

$finish [(n)] ;

Description

The $stop system task is used to suspend simulation. When invoked it suspends simulation, prints simulation time and prints location. Optional expressions can determine the type of printed message:

Expression (n)

Message

0

No message

1

Simulation time and location

2

Simulation time, location, memory consumption and CPU time used in simulation

By default the value 1 is used.

The $finish system task ends the simulation, exits the simulator and passes control back to the operating system. It can be invoked with the same arguments as the $stop system task and has the same default value.

Examples

Example 1

$stop ;

Suspend simulation and print message (default argument = 1)

Example 2

#150 $finish(2) ;

Exits simulator after 150 time units from the last executed statement and prints message (argument == 2).

Important Notes

  • Remember that $finish control system task makes the simulator exit, however $stop simply suspends simulation.

Real Constants

Formal Definition

The real constants are used to specify floating-point numbers.

Simplified Syntax

sign unsigned_number.unsigned_number

sign unsigned_number.unsigned_number e sign unsigned_number

sign unsigned_number.unsigned_number E sign unsigned_number

Description

A real constant can be specified using only digits, underscores, decimal points and exponential symbols (e or E). It cannot be specified with size or base format. If a decimal point is provided then the real number should have at least one digit on both sides of a decimal point. Real numbers can be specified in the decimal notation (Example 1) or in the scientific notation (Example 2).

Examples

Example 1

17.5
0.5
1_000_000.0

Example 2

10e5
0.5694_e-5

Important Notes

· The real constants cannot be specified with size or base format.


Register Data Types

Formal Definition

Registers provide means for modeling data storage elements.

Simplified Syntax:

reg range list_of_identifiers;

integer list_of_identifiers;

real list_of_identifiers;

time list_of_identifiers;

realtime list_of_identifiers;

Description

Registers are data types that store assigned values until a new assignment occurs. A new value can be assigned to registers only by using procedural assignments.

The reg register is a 1-bit wide data type. If more than one bit is required then range declaration should be used (see Vectors for more explanations). Negative values assigned to reg data type variables are treated as unsigned values (see Arithmetic expressions with integers and registers for more explanations). Reg data type variables can be declared as memory.

The integer register is a 32-bit wide data type. Integer declarations cannot contain range specification. Integer variables can be declared as memory. Integers store signed values.

The time register is a 64-bit wide data type that is used to store simulation time and to check timing dependence. Time type registers store values as unsigned numbers. Time declaration cannot contain range specification. Time data type variables can be declared as memories.

The real register is a 64-bit wide data type that stores floating-point values. Real registers cannot be used with event control, concatenations ({}), modulus operator (%), case equality (===, !==), bit-wise operators (~, &, |, ^, ^~, ~^), reduction operators (^, ~^, ^~, &, &~, |, |~) and shift operators (<<, >>). Bit-selects and part-selects on real type variables are not allowed.

The realtime registers are treated in the same way as real registers.

Examples

reg scal;
reg [7:0] vect;
reg [7:0] mem [31:0];
integer i;
integer i_mem [7:0];
time t;
time t_mem [3:0];
real r;
realtime rt1, rt2;

'scal' is a 1-bit wide reg type register.

'vect' is an 8-bit wide reg type register.

'mem' is a reg type memory of 32 8-bit words.

'i' is an integer type register.

'i_mem' is an integer type memory.

't' is a time type register.

't_mem' is a time type memory.

'r' is a real type register.

'rt1' and 'rt2' are realtime type registers.

Important Notes

· New values can be assigned to registers only by using procedural statements.

· Some operators, bit-selects, part-selects, range and memory declaration arecannot be used with real and realtime type registers.

· Range can be specified only for reg data type registers.

· Real and realtime registers are initialized to zero value. Reg, integer and time registers are initialized to unknown value (x).


Range Specification

Formal Definition

The range specification can be used to specify an array of gate or module instances.

Simplified Syntax

instance_name[l_index:r_index] (list of terminals);

Description

The range should be specified using two constant expressions separated by a colon and bracketed by square brackets. The expressions constitutes: the left-hand index (l_index) and right-hand index (r_index). The left-hand index can be less than, equal, or greater than the right-hand index (Example 1). If these indexes are equal then only one instance will be generated (Example 2). Identical instance names cannot appear twice with other range specifications (even if ranges do not overlap each other).

Examples

Example 1

reg [3:0] a, b;
wire [3:0] y;
and g[3:0](y,a,b);

This declaration is equivalent to:

and g3 (y[3], a[3], b[3]);
and g2 (y[2], a[2], b[2]);
and g1 (y[1], a[1], b[1]);
and g0 (y[0], a[0], b[0]);

Example 2

reg a, b;
wire y;
or g[0:0](y,a,b);

This declaration is equivalent to:
or g (y, a, b);

Important Notes

· If the range is used in module or gate instantiations, then terminals of all output ports should not be scalars or there may be a bus conflict.


Procedural Continuous Assignments

Formal Definition

Procedural continuous assignments provide a means to continuously drive a value into a register or a net.

Simplified Syntax

assign register_assignment ;
deassign register_left_value ;
force register_assignment | net_assignment ;
release register_left_value | net_left_value ;
register_left_value - left hand-side operand ;
net_left_value - left hand-side operand ;

Description

In the assign statement, the left hand-side operand can be a register or a concatenation of registers in contrast to continuous assignments where the left hand-side operands are nets. However, the memory word, bit-select or part-select cannot be used on the left hand-side. The priority of procedural continuous assignment is higher than that of the procedural assignments. The deassign keyword informs the end of the driving of the corresponding register. After a deassign, register values remain the same until driven by another procedural or procedural continuous assignment. If the assign keyword is used a second time for the same register, the first register will be deassigned and a new procedural continuous assignment statement takes place.

The keywords force and release have the same effect as assign and deassign; however the left hand-side operand should be a net or a bit-select or a part-select of vector net or concatenation of both. It cannot be part-select or bit-select of a vector register or a memory word.

An assign declared as a force overrides all procedural assignments to the register until the release statement is executed. In the same way, if a net is driven by a procedural continuous assignment all previous assignments are overridden until the release statement is executed. In the register case, the value will be maintained to the next procedural continuous assignment.

Examples

Example 1

module example1(clk, d, reset, set, q) ;
input clk, d, reset, set;
output q;
reg q;
  always @(posedge clk) q = d;
  always @(reset or set) begin
  if (reset) assign q = 1'b0;
  else if (set) assign q= 1'b1;
  else deassign q;
  end
endmodule

Important Notes

  • The left-hand operand of the force and release statements can be a net data type variable.
  • Assign and deassign can only be applied to reg type variables.

Procedural Timing Control

Formal Definition

The procedural timing control is used to determine when statements should be executed.

Simplified Syntax

Delay control:

  #delay

  #(min:typ:max delay)

Event type declaration:

  event identifier;

Event trigger:

  -> event_identifier;

Event control:

  @(event_identifier)

  @(posedge identifier)

  @(negedge identifier)

  @(event_expression or event_expression)

Wait statement:

  wait (expression) statement

Description

The Verilog HDL has two types of timing controls: delay control (Example 1) and event control (Example 2).

The delay control specifies the time between encountering and executing the statement. The delay control can be specified as a simple delay and as min:typ:max delay.

The named event (Example 3) is a special data type that does not hold any value. The event can be triggered using special characters -> followed by an event identifier. Any occurrence of an event trigger can be noticed using an event control statement.

An event control specifies the event that is required to resume execution of a statement. Event can be one of the following:

· Named event

· Change of a signal value

· Positive or negative edge occurred on signal (posedge, negedge)

· List of above-mentioned events (separated by or - event or operator)

A posedge is any transition from 0, x, and z to 1, and from 0 to z or x.

A negedge is any transition from 1, x, and z to 0, and from 1 to z or x.

The wait statement (Example 4) will suspend execution of all statements until the expression becomes true.

Examples

Example 1

#10;

The next statement will be executed after 10 time units.

#10 a = 5;

Assignment to a variable will be delayed by 10 time units.

#(1:2:3);

Delay control with min:typ:max delay value.

#(5:3:7) a = 5;

Assignment to a variable delayed by min:typ:max delay value.

Example 2

@ready a = a + 1;

The 'a' variable will be incremented by 1 when a change occurs on the 'ready' variable.

@(posedge clk) q = d;

The 'd' variable will be assigned to 'q' on the positive edge of clk.

@(a or b or c or d)
y = (a | b) & (~c ^ d);

A new value will be assigned to the 'y' variable when a change occurs on any of the variables a, b, c, or d.

Example 3

event e;

Event declaration.

initial begin
  #10;
  -> e;
end

Example of event triggering.

always @e d = 0;

Example of waiting for an event.

Example 4

wait (a);
i = i + 1;
wait (!a);

This sequence of statements will wait until 'a' becomes 1, and then the next statement will be executed. Next, execution will be suspended until 'a' becomes 0.

Important Notes

· The delay controls are useful in specifying patterns for testbenches.


Procedural Assignments

Formal Definition

The procedural assignments enable updating registers.

Simplified Syntax

register_identifier = expression;

register_identifier <= expression;

Description

The procedural assignments can be used only within the structured procedures (always, initial, task, function).

The left-hand side of assignment should be one of the following:

· Register.

· Bit-select of register.

· Part-select of reg, integer, or time data type.

· Memory word.

· Concatenation of any of the above.

The Verilog HDL contains two types of procedural assignments statements: blocking (Example 1) and non-blocking (Example 2) procedural assignments.

If a current statement contains a blocking procedural assignment then the next statement will be executed after the execution of the current statement (in the next step of the simulation).

If a current statement contains a non-blocking procedural assignment then the next statement will be executed at the same time (in the same step of the simulation).

A block of statements with non-blocking procedural assignments has similar functionality as a group of statements within a fork-join block (Example 3).

Examples

Example 1

begin
  a = 1;
  #10 a = 0;
  #5 a = 4;
end

During the simulation, this block will be executed in 15 time units. At time 0 the 'a' variable will be 1, at time 10 the 'a' variable will be 0, and at time 15 (#10 + #5) the 'a' variable will be 4.

Example 2

begin
  a <= 1;
  #10 a <= 0;
  #5 a <= 4;
end

During the simulation this block will be executed in 10 time units. At time 0 the 'a' variable will be 1, at time 5 the 'a' variable will be 4, and at time 10 the 'a' variable will be 0.

Example 3

fork
  a = 1;
  #10 a = 0;
  #5 a = 4;
join

This fork-join block has the same functionality as the block with non-blocking assignments from example 2.

Important Notes

· Statements that contain the non-blocking procedural assignments are executed in the same simulation cycle.