I created what I believe to be a simple ADC that samples the value of a signal on the rising edge of a reference clock. The reference clock begins in the high state (1V), holds high for a half cycle, and then transitions with a 50% duty cycle (low state = 0V). I also added a delay parameter to the sample time such that the signal will be sampled at the rising clock edge time + the parameter value.
First I declare the module and initialize relevant variables:
Code:`include “discipline.h”
`include “constants.h”
module ADC(clk, test);
input clk;
electrical clk;
input test;
electrical test;
parameter real sample_offset = 18e-12;
parameter real threshold = 0.5;
parameter real expr_tol = 1e-15;
parameter real time_tol = 1e-15;
real rising_edge_time;
real rising_clock_voltage;
real test_sample;
integer test_bin_value;
integer fh;
integer rising_edge_count = 0;
integer rising_edge_detected = 0;
Now I initialize file output and verify that no rising edge has yet been detected:
Code: analog begin
@(initial_step) begin
fh = $fopen(“test_output”);
$fdisplay(fh, “initially, rising_edge_detected = %d”, rising_edge_detected);
end
I have one loop that triggers on a rising clock edge and saves the time at which it occurred:
Code:@cross(V(clk)-threshold, +1, time_tol, expr_tol)) begin
rising_edge_time = $abstime();
rising_edge_voltage = V(clk);
rising_edge_count = rising_edge_count + 1;
rising_edge_detected = 1;
$fdisplay(“rising edge detected at t = %f ps”, rising_edge_time/1p);
end
And a second loop that triggers whenever the abstime exceeds the last saved rising clock edge time + the sample offset:
Code:@(cross($abstime()-(rising_edge_time+sample_offset), +1, time_tol, expr_tol)) begin
If (rising_edge_detected == 1) begin
test_sample = V(test);
if (test_sample > threshold) begin
test_bin_value = 1;
end
else begin
test_bin_value = 0;
end
end
$fdisplay(“clk rise %d at time %f ps, test_bin_value = %d”, rising_edge_count, rising_edge_time/1p, test_bin_value);
rising_edge_detected = 0;
end
This loop samples the analog voltage of the test signal and converts it to digital.
The problem I am seeing is that the first loop is immediately triggering when the simulation starts and apparently counting the initial high value of clk as a low-to-high transition. This in turn triggers the second loop and creates a sample I didn’t intend on capturing.
My output is as follows:
Code:initially, rising_edge_detected = 0
rising edge detected at t = 0.100000 ps
clk rise 1 at time 0.100000 ps, test_bin_value = 0
Does an initial high value always trigger a @cross(V(<signal>)-threshold, +1, time_tol, expr_tol)) statement, or is there something wrong with my logic? The actual clk signal starts at 1V and doesn’t transition to 0 V until hundreds of ps later. All other transitions are captured correctly; I ‘m just getting an extra one at the very beginning of the simulation that doesn’t actually occur. The rising_edge_detected variable is correctly initialized to 0 at the start of the simulation.