| 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 modelthat 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
 |