8
Detecting and Using Events
During a simulation, the simulator generates analog and digital events that you can use to control the behavior of your modules. The simulator generates some of these events automatically at various stages of the simulation. The simulator generates other events in accordance with criteria that you specify. Your modules can detect either kind of event and use the occurrences to determine whether specified statements run.
This chapter discusses the following kinds of events
The Cadence Verilog®-AMS language also supports events for digital contexts. For more information, see the “Event Control” section in the “Behavioral Modeling” chapter of the Verilog-XL Reference.
Detecting and Using Events
Use the @ operator to run a statement under the control of particular events.
event_control_statement ::=
@ ( event_expr ) statement ;
event_expr ::= simple_event [ or event_expr ]
simple_event ::= initial_step_event | final_step_event | cross_event | timer_event | expression_event | named_event | posedge_event | negedge_event
statement is the statement controlled by event_expr. The statement must not be a contribution statement and must not contain any analog operators. The statement:
simple_event is an event that you want to detect. The behavior depends on the context:
-
In the analog context, when, and only when,
simple_eventoccurs, the simulator runs statement. Otherwise, statement is skipped. The kinds of simple events are described in the following sections. - In the digital context, processing of the block is prevented until the event expression evaluates to true.
If you want to detect more than one kind of event, you can use the event or operator. Any one of the events joined with the event or operator causes the simulator to run statement. The following fragment, for example, sets V(out) to zero or one at the beginning of the analysis and at any time V(sample) crosses the value 2.5.
analog begin @(initial_step or cross(V(sample)-2.5, +1)) begin vout = (V(in) > 2.5) ; end V(out) <+ vout ;
end
| For information on | See |
|---|---|
Initial_step Event
The simulator generates an initial_step event during the solution of the first point in specified analyses, or, if no analyses are specified, during the solution of the first point of every analysis. Use the initial_step event to perform an action that should occur only at the beginning of an analysis.
initial_step_event ::= initial_step [ ( analysis_list ) ]
analysis_list ::= analysis_name { , analysis_name }
analysis_name ::=
"analysis_identifier"
If the string in analysis_identifier matches the analysis being run, the simulator generates an initial_step event during the solution of the first point of that analysis. If you do not specify analysis_list, the simulator generates an initial_step event during the solution of the first point, or initial DC analysis, of every analysis.
In this release of Verilog-AMS, the initial_step event is supported for the ac, noise, tran, and dc sweep analyses.
The initial_step event is predefined, so you cannot redefine it in your model.
You can detect initial_step events only from within the analog block.
Final_step Event
The simulator generates a final_step event during the solution of the last point in specified analyses, or, if no analyses are specified, during the solution of the last point of every analysis. Use the final_step event to perform an action that should occur only at the end of an analysis.
final_step_event ::= final_step [ ( analysis_list ) ]
analysis_list ::= analysis_name { , analysis_name }
analysis_name ::=
"analysis_identifier"
If the string in analysis_identifier matches the analysis being run, the simulator generates a final_step event during the solution of the last point of that analysis. If you do not specify analysis_list, the simulator generates a final_step event during the solution of the last point of every analysis.
In this release of Verilog-AMS, the final_step event is supported for the ac, noise, tran, and dc sweep analyses.
The final_step event is predefined, so you cannot redefine it in your model.
You can detect final_step events only from within the analog block.
You might use the final_step event to print out the results at the end of an analysis. For example, module bit_error_rate measures the bit-error of a signal and prints out the results at the end of the analysis. (This example also uses the timer event, which is discussed in “Timer Event”.)
module bit_error_rate (in, ref) ; input in, ref ; electrical in, ref ; parameter real period=1, thresh=0.5 ; integer bits, errors ; analog begin @(initial_step) begin bits = 0 ; errors = 0 ; // Initialize the variables end @(timer(0, period)) begin if ((V(in) > thresh) != (V(ref) > thresh)) errors = errors + 1; // Check for errors each period bits = bits + 1 ; end @(final_step) $strobe("Bit error rate = %f%%", 100.0 * errors/bits );
end
endmodule
Cross Event
According to criteria you set, the simulator can generate a cross event when an expression crosses zero in a specified direction. Use the cross function to specify which crossings generate a cross event.
cross_function ::=
cross (expr1 [ , direction [ , time_tol [ , expr_tol ] ] ] )
direction ::= +1 | 0 | -1
time_tol ::=
expr2
expr_tol ::=
expr3
expr1 is the real expression whose zero crossing you want to detect.
direction is an integer expression set to indicate which zero crossings the simulator should detect.
| If you want to | Then |
|---|---|
time_tol is a constant expression with a positive value, which is the largest time interval that you consider negligible. The default value is 1.0s, which is large enough that the tolerance is almost always satisfied.
expr_tol is a constant expression with a positive value, which is the largest difference that you consider negligible. If you specify expr_tol, both it and time_tol must be satisfied. If you do not specify expr_tol, the simulator uses the default expr_tol value of
1e-9 + reltol*max_value_of_the_signal
In addition to generating a cross event, the cross function also controls the time steps to accurately resolve each detected crossing.
The cross function is subject to the restrictions listed in “Restrictions on Using Analog Operators”.
The following example illustrates how you might use the cross function and event. The cross function generates a cross event each time the sample voltage increases through the value 2.5. expr_tol is specified as the abstol associated with the potential nature of the net sample.
module samphold (in, out, sample) ;
output out ;
input in, sample ;
electrical in, out, sample ;
real hold ;
analog begin @(cross(V(sample)-2.5, +1, 0.01n, sample.potential.abstol)) hold = V(in) ; V(out) <+ transition(hold, 0, 10n) ;
end
endmodule
Above Event
According to criteria you set, the simulator can generate an above event when an expression becomes greater than or equal to zero. Use the above function to specify when the simulator generates an above event. An above event can be generated and detected during initialization. By contrast, a cross event can be generated and detected only after at least one transient time step is complete.
The above function is a Cadence language extension.
above_function ::=
above (expr1 [ , time_tol [ , expr_tol ] ] )
time_tol ::=
expr2
expr_tol ::=
expr3
expr1 is a real expression whose value is to be compared with zero.
time_tol is a constant real expression with a positive value, which is the largest time interval that you consider negligible.
expr_tol is a constant real expression with a positive value, which is the largest difference that you consider negligible. If you specify expr_tol, both it and time_tol must be satisfied. If you do not specify expr_tol, the simulator uses the value of its own reltol parameter.
During a transient analysis, after t = 0, the above function behaves the same as a cross function with the following specification.
cross(expr1 , 1 , time_tol, expr_tol )
During a transient analysis, the above function controls the time steps to accurately resolve the time when expr1 rises to zero or above.
The above function is subject to the restrictions listed in “Restrictions on Using Analog Operators”.
The following example illustrates how you might use the above function. The function generates an above event each time the analog voltage increases through the value 3.5 or decreases through the value 1.5.
connectmodule elect2logic_2(aVal, dVal); input aVal; output dVal; electrical aVal; logic dVal; parameter real thresholdLo = 1.5; parameter real thresholdHi = 3.5;
integer iVal;
assign dVal = iVal; // direct driver/receiver propagation
always @(above(V(aVal) - thresholdHi))
iVal = 1’b1;
always @(above(thresholdLo - V(aVal)))
iVal = 1’b0;
endmodule
The usefulness of the above function becomes apparent when elect2logic is inserted across the in port of the inv I1 instance in the following module.
module top; electrical src, gnd; logic out; ground gnd;
vsource #(.dc(5)) V1(src,gnd);
inv I1(src,out);
endmodule
module inv(in,out); input in; output out;
assign out = !in;
endmodule
The modules describe a circuit where an analog DC voltage source, V1, generates a constant 5 volt signal that drives a digital inverter. Using the above function in elect2logic sets the values correctly at the end of the initialization. However, if the above function is replaced with the cross function, the value of out is set to 1’b1 at the end of the initialization and retains that value throughout the transient analysis. This incorrect result is caused by the fact that cross events cannot be generated or detected during initialization.
Absdelta Event
According to the criteria you set, the simulator can generate an absdelta event when an analog signal changes more than a specified amount, a capability that is typically used to discretize analog signals. Use the absdelta function to specify when the simulator generates an absdelta event.
You can use the absdelta function only with the AMS Designer simulator using the simulation front end (SFE) parser or the AMS Designer simulator using the UltraSim solver. You must use this function only in an always block.
absdelta_function ::= absdelta (expr,delta[ ,time_tol[ ,expr_tol][,enable_flag]] )
expr is an analog signal expression.
delta is a real expression specifying an amount of change in the value of expr. The simulator generates an event when the expr value changes more than delta plus or minus expr_tol, relative to the expr value at the previous event time.
time_tol is a real expression specifying a time increment after the previous time point. When the current time is within time_tol of the previous event time, no event is generated. If time_tol is not specified, the default value is the time precision of the digital simulation. A specified time_tol that is smaller than the time precision is ignored and the time precision is used instead.
expr_tol is a real expression, which is the largest difference in expr that you consider negligible. If you do not specify expr_tol, the simulator uses the absolute voltage tolerance (vabstol) of the analog solver.
enable_flag is an analog expression. If it is non-zero, absdelta functions as described above, otherwise, the absdelta function is inactive, which means that it does not generate any events.
To disable the absdelta operation, force enable_flag to a zero value. enable_flag is an optional argument of the absdelta function. When enable_flag is not set, the absdelta function is operational (enabled).
The absdelta function generates events for the following times and conditions.
- At time zero.
- At the time when the analog solver finds a stable solution during initialization.
- When the expr value changes more than delta plus or minus expr_tol, relative to the previous absdelta event (but not when the current time is within time_tol of the previous absdelta event).
- When expr changes direction (but not when the amount of the change is less than expr_tol).
The following module describes an event-driven electrical to wreal conversion where the absdelta function is used to determine when the electrical input signal is converted to a wreal output signal.
‘include "disciplines.vams"
‘timescale 1ns / 100ps
module electrical_to_wreal (e_in, r_out);
input e_in;
output r_out;
electrical e_in;
wreal r_out;
parameter real vdelta=0.1 from (0:inf); // voltage delta
parameter real ttol=1n from (0:1m]; // time tolerance
parameter real vtol=0.01 from (0:inf); // voltage tolerance
real sampled;
assign r_out = sampled;
always @(absdelta(V(e_in), vdelta, ttol, vtol)) sampled = V(e_in);
endmodule
Without proper tolerances, the absdelta function might attempt to generate a large number of events when:
- the signal sampled by absdelta changes dramatically at a specific time step.
-
you specify a very small signal delta value as the second argument to the
absdeltafunction.
Generation of a large number of events might significantly slow down the simulation, and in some cases, might even exhaust the system memory and crash the simulation. To handle such situations, the simulator ensures that no two events are generated within the span of the time tolerance time_tol. The default and the minimal time tolerance is the time precision of the digital simulation. A cap is also placed on how many events can be generated in a single time step.
In addition, whenever a large number of events are to be generated, a warning message is issued. This message includes infomation such as the instance name, the Verilog-AMS source file name, and the line number where the problematic absdelta is used. The message also provides suggestions on how to correct or improve the code.
A warning message is also issued whenever you specify the time tolerance to be less than the time precision of the digital simulation. In this case, the specification is ignored and the time precision of the digital simulation is used as the time tolerance.
Timer Event
According to criteria you set, the simulator can generate a timer event at specified times during a simulation. Use the timer function to specify when the simulator generates a timer event.
Do not use the timer function inside conditional statements.
timer_function ::= timer (start_time[ ,period[ ,timetol]] )
start_time is a dynamic expression specifying an initial time. The simulator places a first time step at, or just beyond, the start_time that you specify and generates a timer event.
period is a dynamic expression specifying a time interval. The simulator places time steps and generates events at each multiple of period after start_time.
timetol is a constant expression specifying how close a placed time point must be to the actual time point.
The module squarewave, below, illustrates how you might use the timer function to generate timer events. In squarewave, the output voltage changes from positive to negative or from negative to positive at every time interval of period/2.
module squarewave (out)
output out ;
electrical out ;
parameter period = 1.0 ;
integer x ;
analog begin @(initial_step) x = 1 ; @(timer(0, period/2)) x = -x ; V(out) <+ transition(x, 0.0, period/100.0 ) ;
end
endmodule
Return to top