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
|