The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Design Languages >> Verilog-AMS >> Spectre problems using absdelay()
https://designers-guide.org/forum/YaBB.pl?num=1390848165

Message started by spectrallypure on Jan 27th, 2014, 10:42am

Title: Spectre problems using absdelay()
Post by spectrallypure on Jan 27th, 2014, 10:42am

Hi all! I am having trouble simulating a simple model of a variable delay cell to be used in the delay line (VCDL) of a DLL. My model is as follows:


Code:
`include "discipline.h"
`include "constants.h"

module delaycell (vIN, vCTRL, vOUT);
input      vIN;      electrical      vIN;      // signal input
input      vCTRL;      electrical      vCTRL;      // control input
output      vOUT;      electrical      vOUT;      // signal output

parameter real      K__V_to_delay            = 10n      from [0:inf);      // [s/V]
parameter real      zero_input_delay      = 0      from [0:inf);      // [s]
parameter real      max_delay            = 1u      from [0:inf);      // [s]
real            actual_delay;

analog begin

actual_delay      = K__V_to_delay*V(vCTRL) + zero_input_delay;
V(vOUT)      <+ absdelay(V(vIN), actual_delay, max_delay);

end

endmodule


My problem is that Spectre is not able to resolve the delay properly. For instance, using testbench in Fig. 1 and Spectre in "conservative" mode, I get the output shown in Fig 2., which is wrong.

After a lot of research on the internet (specially, in this forum), I learned about the use of the "$bound_step()" directive. Adding this command with a 10ps argument to my code yields the results in Fig. 3., which are correct.
The problem is that using $bound_step completely bogs down my system level simulations (E.g. locking of the whole DLL, with all ideal blocks in Verilog-A), making them too long, taking away the benefit of fast simulation, which is the main reason I want to model my DLL in Verilog-A in the first place!

Another solution that I tried was to put some circuitry to try to force the simulator to refine its time step. Fig. 4 shows what happens adding a series RC from the output node to ground, with a time constant RC=10ps. It can be seen some improvement, but not yet a correct result. What is worse, trying to use this band-aid solution in more realistic (system-level) simulations did not seem to solve the problem.

So my big question is: how can I instruct Spectre to use an adequate time-step for this circuit, without having to resort to "$bound_step()", whose "constant-sampling" behavior causes the evaluation of thousands of unnecessary points during instants where nothing is really happening?

Thanks in advance for any help!

Cheers,

Jorge.

P.S. Please do not hesitate to ask for more details, if needed! :)

Title: Re: Spectre problems using absdelay() :'(
Post by spectrallypure on Jan 27th, 2014, 10:43am

Fig. 1 - Test circuit

Title: Re: Spectre problems using absdelay() :'(
Post by spectrallypure on Jan 27th, 2014, 10:44am

Fig. 2. - Simulation results without using $bound_step() (Input freq. 50MHz, rise and fall times: 1ns)

Title: Re: Spectre problems using absdelay() :'(
Post by spectrallypure on Jan 27th, 2014, 10:45am

Fig. 3. - Simulation results with $bound_step(10p)

Title: Re: Spectre problems using absdelay() :'(
Post by spectrallypure on Jan 27th, 2014, 10:46am

Fig. 4. - Simulation results without $bound_step(), but with a series RC from the output node to ground (RC=10ns)

Title: Re: Spectre problems using absdelay()
Post by Ken Kundert on Jan 27th, 2014, 4:07pm

Reformulate your delay line into a digital delay line and use the delay argument on a transition function to set the delay.

-Ken

Title: Re: Spectre problems using absdelay()
Post by spectrallypure on Jan 28th, 2014, 11:40am

Hi Ken, thanks so much for your reply!

I tried the approach you suggested and after some tweaking I think I got it, but to be honest I am not really sure why I needed to code my solution the way I did, and not as I first intended; let me explain a bit.

Using the code below I get the waves shown in Fig. 5, which are correct. In particular, it can be seen in this figure that the 2nd rising edge of the input (green curve), happening at 20.5ns, correctly appears at the output (pink curve) after 10ns, i.e., at 30.5ns. This is in agreement with the signal "actual_delay", whose value at this crossing event is 10ns (orange curve).


Code:
`include      "discipline.h"
`include      "constants.h"

module delaycell (vIN, vCTRL, vOUT);
input      vIN;      electrical      vIN;      // signal input
input      vCTRL;      electrical      vCTRL;      // control input
output      vOUT;      electrical      vOUT;      // signal output

parameter real      K__V_to_delay            = 10n      from [0:inf);      // [s/V]
parameter real      zero_input_delay      = 0      from [0:inf);      // [s]
parameter real      Vth_rising            = 1.0;                  // [V]
parameter real      Vth_falling            = 1.0;                  // [V]
parameter real      VHI                  = 2.0;                  // [V]
parameter real      VLOW                  = 0.0;                  // [V]

parameter real      cross__time_tol            = 1f      from [0:inf);      // [s]
parameter real      transition__rise_time      = 1n      from [0:inf);      // [s]
parameter real      transition__fall_time      = 1n      from [0:inf);      // [s]

real            actual_delay;
real            s_vOUT;

analog begin

     // Rising edge delay
     @(cross(V(vIN)-Vth_rising,+1,cross__time_tol)) begin
           actual_delay      = K__V_to_delay*V(vCTRL)+zero_input_delay;
           s_vOUT            = VHI;
     end
     // Falling edge delay
     @(cross(V(vIN)-Vth_falling,-1,cross__time_tol)) begin
           actual_delay      = K__V_to_delay*V(vCTRL)+zero_input_delay;
           s_vOUT            = VLOW;
     end

     V(vOUT)      <+ transition(s_vOUT,actual_delay,transition__rise_time,transition__fall_time);

end
endmodule


Now the problem that I don't understand. At first I tried using the code below (lines not shown are identical as in the previous code), which produced the output in Fig. 6, which is wrong: the 2nd rising edge of the input at 20.5ns incorrectly appears at the output only after 1.5ns, i.e., at 22ns! This is despite the fact that when this crossing event occurs (20.5ns), the instantaneous value of the signal "actual_delay" is 10ns (see orange wave).


Code:
analog begin

     // Actual delay value
     actual_delay                  = K__V_to_delay*V(vCTRL)+zero_input_delay;

     // Rising edge delay
     @(cross(V(vIN)-Vth_rising,+1,cross__time_tol)) begin
           s_vOUT            = VHI;
     end
     // Falling edge delay
     @(cross(V(vIN)-Vth_falling,-1,cross__time_tol)) begin
           s_vOUT            = VLOW;
     end

     V(vOUT)      <+ transition(s_vOUT,actual_delay,transition__rise_time,transition__fall_time);
end


My question is then, why is it necessary to sample the "actual_delay" value at each crossing event? Why can't I just use the 1-line approach to define this signal as in the code above? I would be really grateful if you could please explain me why Spectre behaves as it does here.

Thanks again for your help.

Cheers,

Jorge.

Title: Re: Spectre problems using absdelay()
Post by spectrallypure on Jan 28th, 2014, 11:42am

Fig. 5 - Correct results, obtained sampling the control input (vCTRL) at each crossing event to generate the signal "actual_delay".

Title: Re: Spectre problems using absdelay()
Post by spectrallypure on Jan 28th, 2014, 11:45am

Fig. 6 - Incorrect results, obtained when generating the "actual_delay" signal outside the "@cross" blocks.

Title: Re: Spectre problems using absdelay()
Post by boe on Jan 29th, 2014, 5:20am

Spectrallypure,
did you read the documentation on how the transition filter reacts to changes of the "inputs" while a transition is in progress?
- B O E

Title: Re: Spectre problems using absdelay()
Post by spectrallypure on Jan 29th, 2014, 8:07am

Hi BOE, thanks for your reply! Actually, I checked on this, and from what I read in the documentation about the transition() function, I don't think this is actually the problem.

If you consider Fig. 6, after the simulator processes the rising edge event of the input at 20.5ns, there are no more events to process until t=26.5ns, when a falling edge appears, but the erroneous rise of the output appears at t=22ns, so I don't think this spurious transition is related to a collision between scheduled transitions (since at 22ns the simulator has only one transition scheduled: the rising edge at 20.5ns).
...Or am I maybe missing something?

Cheers,

Jorge.

Title: Re: Spectre problems using absdelay()
Post by boe on Jan 29th, 2014, 9:22am

Spectrallypure,
the transition filter changes the output when the sim time reaches tinput_event+tdelay.
At 22ns, the delay is 0, so the output has to change because of the input event at 20.5ns.
- B O E

Title: Re: Spectre problems using absdelay()
Post by boe on Jan 29th, 2014, 9:31am

Spectrallypure,
the LRM v2.3.1, sec. 4.5.8 states: "td models transport delay".
However, I agree this is not exactly defined in the LRM.
- B O E

Title: Re: Spectre problems using absdelay()
Post by spectrallypure on Jan 29th, 2014, 9:31am

Oh, I see!!! I misunderstood that the value of "delay" that the transition() function uses is the one AT THE INSTANT WHEN THE TRANSITION HAPPENS. Obviously, I was wrong.

Thanks so much for the explanation, BOE!!!

Cheers,

Jorge.

The Designer's Guide Community Forum » Powered by YaBB 2.2.2!
YaBB © 2000-2008. All Rights Reserved.