The Designer's Guide Community
Forum
Welcome, Guest. Please Login or Register. Please follow the Forum guidelines.
Apr 19th, 2024, 6:40pm
Pages: 1
Send Topic Print
hidden state in dff verilogA (Read 61 times)
Betai
Guest




hidden state in dff verilogA
Oct 03rd, 2002, 4:17pm
 
How can I get rid of hidden state problem in the following dff code ?

module d_ff(vin_d, vclk, vout_q, vout_qbar);
input vclk, vin_d;
output vout_q, vout_qbar;
electrical vout_q, vout_qbar, vclk, vin_d;
parameter real vlogic_high = 5;
parameter real vlogic_low = 0;
parameter real vtrans_clk = 2.5;
parameter real vtrans = 2.5;
parameter real tdel = 3u from [0:inf);
parameter real trise = 1u from (0:inf);
parameter real tfall = 1u from (0:inf);

integer x;
 
  analog begin
      @ (cross( V(vclk) - vtrans_clk, +1 ))
            x = (V(vin_d) > vtrans);
      V(vout_q) <+ transition( vlogic_high*x +  vlogic_low*!x, tdel, trise, tfall );
      V(vout_qbar) <+ transition( vlogic_high*!x + vlogic_low*x, tdel, trise, tfall );

   end

endmodule

Back to top
 
 
  IP Logged
Ken Kundert
Global Moderator
*****
Offline



Posts: 2384
Silicon Valley
Re: hidden state in dff verilogA
Reply #1 - Oct 5th, 2002, 2:05pm
 
Here is a simple replacement for your D flip-flop model. My parameters are not the same as yours, so you might need to do a little touch up to make this one a drop-in replacement for yours. When using it be careful to keep the transition delay (td) and transition time (tt) short to reduce the chance that a transition could occur at a shooting interval boundary, which would cause convergence problems (see the hidden state paper on the website).

Code:
// D Flip Flop
//
// Works with SpectreRF (has no hidden state)

`include "discipline.h"

module dff (clk, d, q);

voltage clk, d, q;
input clk, d; output q;
parameter real v0=0;
parameter real v1=1 from (v0:inf);
parameter integer dir=1 from [-1:1] exclude 0;
parameter real td=0 from [0:inf);
parameter real tt=0 from [0:inf);
integer now;
real thresh;

analog begin
    thresh = (v0+v1)/2;
    now = 0;
    @(initial_step or cross(V(clk) - thresh, dir)) now = 1;
    V(q) <+ transition(idt(0, V(d) > thresh, now) ? v1 : v0, td, tt);
end
endmodule
 


Unfortunately when I run this model with the currently available version of Spectre it fails due to a bug in the idt code. The bug has been fixed and the fix will be released in the next roll up, but I'm afraid this model does not solve your problem today.

Is there anyone that has a model that works with existing versions of Spectre?
Back to top
 
« Last Edit: Oct 11th, 2002, 12:15am by Ken Kundert »  
View Profile WWW   IP Logged
ronv
New Member
*
Offline



Posts: 1
Melbourne FL
Re: hidden state in dff verilogA
Reply #2 - Oct 10th, 2002, 2:31pm
 
The only clean way to incorporate an internal state into a Verilog-A model
that will be used in SpectreRF is to hold the value as a capacitor
voltage.  The implementation can be equivalent to a real sample-and-hold
type structure:  Place a capacitor from the node that's used to hold the
value to ground, and connect it to the signal that it needs to follow
through an effective switch (small or big resistor, depending whether
you're sampling or not).  When it's not being driven, it can be slowly
discharged through a big RC time constant.

If there's only a limited number of states possible (such as logic levels,
or a moderate number of integer states), it can be maintained through
regenerative feedback:  drive the output toward the nearest state rather
than letting it float when it isn't being externally driven.



/////Example:  simple D latch (output follows input when clock is high):
module d_latch_rf (clk, d, q);
input clk,d; output q;
electrical clk,d,q;
parameter real v0=0, v1=5;         // low & high output levels
parameter real vth=(v1+v0)/2 from (v0:v1); // threshold level (input & output)
parameter real TauOut=0.2u;        // time constant for following input
integer Lout;                      // desired output logic level
real VoutNom;                      // nominal output voltage
analog begin
   if (V(clk)>vth)  Lout = (V(d)>vth); // clk high: state defined by D input
   else             Lout = (V(q)>vth); // clk low:  state follows output
   VoutNom = Lout? v1:v0;          // get nominal output voltage
   I(q) <+ ddt((TauOut/1.0)*V(q)); // hold capacitor
   I(q) <+ (V(q)-VoutNom)/1.0;     // 1ohm resistor drives Vout from VoutNom
end
endmodule


If you needed to fully control the output waveshape with a transition
statement in the above example, you could just let the "q" node be an
internal node, and drive the actual output node using a transition
statement based on the "VoutNom" value:
  V(qout) <+ transition(VoutNom,Td,Tr,Tf);

But, to make an edge-triggered sample-and-hold, you can't really change
the capacitor voltage on a single timestep to do a real edge trigger.
Instead, the circuit-equivalent implementation would be to use a dual
track-and-hold arrangement:
 - First stage tracks when the clock is low, holds when it's high;
 - Second stage tracks when the clock is high, holds when it's low.
Thus, on the leading clock edge, the input value which was being tracked
is transferred to output, resulting in proper leading-edge-triggered result.


/////Example:  DFF implemented via dual track-and-hold format.
module d_ff_rf (vin_d, vclk, vout_q, vout_qbar);
input vclk, vin_d;
output vout_q, vout_qbar;
electrical vout_q, vout_qbar, vclk, vin_d;
electrical X1,X2;           // node for first and second stage states
parameter real vlogic_high=5,vlogic_low=0;
parameter real vtrans=(vlogic_high+vlogic_low)/2;
parameter real tdel=3u, trise=1u, tfall=1u;
parameter real tau=trise/10;
integer Lclk,Lvin,Lx1,Lx2;  // current state for each node
integer Kx1,Kx2;            // desired state for track-and-holds
analog begin
// Convert all signals to logic 1/0 format:
   Lclk = (V(vclk)>vtrans);
   Lvin = (V(vin_d)>vtrans);
   Lx1  = (V(X1)>0.5);
   Lx2  = (V(X2)>0.5);
// force last point before transition to accurately measure input at crossing:
   @(cross( V(vclk)-vtrans,+1 )) Lclk=0;
// compute new logic states desired:
   Kx1 = Lclk? Lx1:Lvin;
   Kx2 = Lclk? Lx1:Lx2;
// capacitors for each state, and drive each through 1 ohm resistance:
   I(X1) <+ ddt(tau*V(X1));
   I(X2) <+ ddt(tau*V(X2));
   I(X1) <+ (V(X1)-Kx1)/1.0;
   I(X2) <+ (V(X2)-Kx2)/1.0;
// output using transition statement as ideal voltage, and inversion:
   V(vout_q) <+ transition(Kx2? vlogic_high:vlogic_low ,tdel,trise,tfall);
   V(vout_qbar) <+ vlogic_high+vlogic_low - V(vout_q);
end
endmodule

.........................................................Ron
Back to top
 
 
View Profile   IP Logged
Pages: 1
Send Topic Print
Copyright 2002-2024 Designer’s Guide Consulting, Inc. Designer’s Guide® is a registered trademark of Designer’s Guide Consulting, Inc. All rights reserved. Send comments or questions to editor@designers-guide.org. Consider submitting a paper or model.