Acing Verilog and SystemVerilog Sampled Value Functions
Welcome to our tutorial on sampled value functions in Verilog and SystemVerilog. Sampled value functions play a vital role in analyzing and manipulating values of expressions within your designs. In this tutorial, we will focus on understanding and using these functions to enhance your hardware description skills.
Introduction to Sampled Value Functions in Verilog and SystemVerilog
Sampled value functions help you access current and past sampled values, detect changes in sampled values, and work with various clocking events. Throughout this tutorial, we will explore the following sampled value functions: $sampled
, $rose
, $fell
, $stable
, $changed
, and $past
.
$sampled Function: Accessing the Current Sampled Value
The $sampled
function is used to access the sampled value of an expression at the time a concurrent assertion is evaluated. In certain cases, using $sampled
can be redundant, while in others, it can be quite useful. Let's examine two examples to understand its significance and how it impacts the action block, which refers to the statements executed when a property holds true or false, also known as pass and fail statements.
A good practice when writing action blocks is to ensure the values used are consistent with the context of the assertion. It is generally recommended to use the $sampled
function within the action block if there's a chance that the values of the signals may change in the Reactive region, which could lead to misleading error messages.
Example 1:
a1: assert property (@(posedge clk) $sampled(a));
a2: assert property (@(posedge clk) a);
In this example, using $sampled(a)
in the first assertion is redundant because the value of a
is already sampled at the rising edge of the clock. The second assertion achieves the same purpose without using $sampled
.
Example 2:
logic a, b, clk;
// ...
p1_incorrect: assert property (@(posedge clk) a !== b)
else $error("Equal values: a = %b, b = %b", a, b);
p2_correct: assert property (@(posedge clk) a !== b)
else $error("Equal values: a = %b, b = %b", $sampled(a), $sampled(b));
In this example, the first assertion's action block (the fail statement) can lead to incorrect results because it uses the current values of a
and b
in the Reactive region. If their values change after the rising edge of the clock, the error message might be misleading. The second assertion, on the other hand, uses $sampled(a)
and $sampled(b)
to ensure that the values in the action block are consistent with the assertion context, providing a correct and informative error message.
Value Change Functions: Detecting Changes in Sampled Values
Value change functions help us figure out if something has changed or stayed the same by looking at the current value of a signal and comparing it to its value from just a little while ago. By doing this, we can see if anything has changed between then and now, based on the clocking event we're using. This makes it easier for us to understand what's going on with our signals and how they might be changing over time.
$rose Function: Tracking Rising Edges
The $rose
function detects rising edge transitions in an expression's least significant bit (LSB). It returns true (1'b1
) for a 0
to 1
transition, and false (1'b0
) otherwise. The clocking event is applied to $rose
, influencing its evaluation context.
module RoseExample(
input logic clk,
input logic inputSignal
);
always_ff @(posedge clk) begin
if ($rose(inputSignal)) begin
$display("Detected rising edge at inputSignal");
end
end
endmodule
In this example, $rose
is evaluated in the context of the posedge clk
event.
$fell Function: Tracking Falling Edges
The $fell
function detects falling edges in the sampled value of an expression. It returns true when the least significant bit (LSB) of the expression changes to 0.
module FellExample(
input logic clk,
input logic inputSignal
);
always_ff @(posedge clk) begin
if ($fell(inputSignal)) begin
$display("Detected falling edge at inputSignal");
end
end
endmodule
$stable Function: Identifying Unchanged Values
The $stable
function checks whether the sampled value of an expression remains unchanged. It returns true when the value does not change.
module StableExample(
input logic clk,
input logic inputSignal
);
always_ff @(posedge clk) begin
if ($stable(inputSignal)) begin
$display("InputSignal is stable");
end
end
endmodule
$changed Function: Detecting Changes in Values
The $changed
function detects changes in the sampled value of an expression. It returns true when the value changes.
module ChangedExample(
input logic clk,
input logic inputSignal
);
always_ff @(posedge clk) begin
if ($changed(inputSignal)) begin
$display("InputSignal has changed");
end
end
endmodule
$past Function: Accessing Past Sampled Values
The $past
function allows you to look at the value of a signal at a specific point in the past. Here is the syntax for the $past
function:
$past(expression1, number_of_ticks, expression2, clocking_event)
It accepts several arguments that let you customize its behavior:
expression1
: The signal or expression you want to analyze.number_of_ticks
: Specifies how far back you want to go, measured in clock ticks.expression2
: An optional gating expression that ensures the clocking event occurs only when this expression is true.clocking_event
: An optional argument to define the clocking event for samplingexpression1
.
Here's an example illustrating the use of all the arguments in the $past
function:
module PastExampleAllArgs (
input logic clk,
input logic rst_n,
input logic enable,
input logic [3:0] data,
output logic pastDataValid,
output logic [3:0] delayedData
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
pastDataValid <= 1'b0;
delayedData <= 4'b0;
end
else begin
if ($past(enable, 3, enable, @(posedge clk))) begin
pastDataValid <= 1'b1;
delayedData <= $past(data, 3, enable, @(posedge clk));
end
else begin
pastDataValid <= 1'b0;
end
end
end
endmodule
In this example, when enable
is high and was also high three clock ticks ago, the delayedData
output is assigned the value of data
from three clock ticks in the past. The pastDataValid
signal indicates when the delayedData
contains a valid past value. This demonstrates how the $past
function can be used to access past values of signals with gating conditions and customized clocking events.
Sampled value functions are valuable tools when working with Verilog and SystemVerilog. By understanding and utilizing these functions, you can efficiently analyze, manipulate, and debug signals within your designs. With practice, you'll master the use of $sampled
, $rose
, $fell
, $stable
, $changed
, and $past
functions to create robust and efficient digital designs.