The Designer's Guide Community
Forum
Welcome, Guest. Please Login or Register. Please follow the Forum guidelines.
Jul 17th, 2024, 12:47pm
Pages: 1
Send Topic Print
need help modifying the reset to an oscillator module (Read 3200 times)
altaj
Junior Member
**
Offline



Posts: 11

need help modifying the reset to an oscillator module
Mar 11th, 2011, 2:31pm
 
I have a module for an oscillator that works as follows:  When the ENB (enable_bar, so active low) is set low, the output goes to zero.  Great.  When ENB is set high, the output resumes.  Also great.   However, the timebase of the oscillator is as it was before the reset.  That is to say, it behaves like a continuouslly running oscillator with an outout enable.

I want to modify the module so that when ENB is set low, the oscillator will always start from the same state, regardless of the abstime.  I've tried messing with the n and next variables, making them hold position while ENB is high, but am getting nowhere.

If anyone has a suggestion, I would like to hear it.  I'm a novice, so, as always, if you see something silly or wrong in the module, I'm always open to learning a better way!

Here is the module:
module osc (enb, out);

input enb;
output out;
voltage enb,out;

parameter real      freq=1 from (0:inf),            // output frequency
                                               vl=-1,                        // high output voltage
                                               vh=1,                        // low output voltage
                                               vth=(vh-vl)/2,
                                               tt=0.01/freq from (0:inf);      // transition time of output

integer n, enable;
real next;

analog begin

           @(cross(V(enb) - vth, -1 )) enable = 1;
           @(cross(V(enb) - vth, +1 )) enable = 0;
   
               @(initial_step)
                             next = (0.5/freq + $abstime);
                     
               @(timer(next)) begin
                             n = !n;
                             next = next + 0.5/freq;
                    end
                       
                       V(out) <+ transition(n ? enable*vh : vl, 0, tt);

     end
endmodule


Thanks!
John
Back to top
 
 
View Profile   IP Logged
Ken Kundert
Global Moderator
*****
Offline



Posts: 2386
Silicon Valley
Re: need help modifying the reset to an oscillator module
Reply #1 - Mar 12th, 2011, 8:32am
 
You should compute next in the cross statement that detects the falling edge on enb.

Also, your approach to detecting whether the block is enabled is problematic because it needs an edge to determine the state of enable. A better approach would be
Code:
enable = V(enb) < vth;
@(cross(Venb)-vth))
    ; 


In this way the conditional is run at every time point and so the resulting value of enable is always correct, and the cross is added so that you accurately resolve the time at which the threshold is crossed. To add your phase reset functionality, you could do this:
Code:
enable = V(enb) < vth;
@(cross(Venb)-vth)) begin
    if (V(enb) > vth)
	  next = 1000;
    else
	  next = $abstime + freq/2;
end 


And, shouldn't the output transition statement look more like this?
Code:
V(out) <+ transition(n&&enable ? vh : vl, 0, tt); 


-Ken
Back to top
 
 
View Profile WWW   IP Logged
Marq Kole
Senior Member
****
Offline

Hmmm. That's
weird...

Posts: 122
Eindhoven, The Netherlands
Re: need help modifying the reset to an oscillator module
Reply #2 - Mar 14th, 2011, 3:06am
 
Replacing the cross() event function calls in your code by above() event function calls will achieve the same as the conditional outside the event.

Code:
@(above(V(enb) - vth)) enable = 0;
@(above(vth - V(enb))) begin enable = 1; next = $abstime; end 



I'm puzzled that you do not use the period argument of the timer() event function and just update the reference on every falling edge of enb.

Code:
@(timer(next, 0.5/freq)) n = !n; 



If you want the oscillator to have 0 output voltage when disabled and a voltage that toggles between vh and vl you will need still a different output statement:

Code:
V(out) <+ transition(enable ? (n ? vh : vl) : 0, 0, tt); 



Cheers,
Marq
Back to top
 
 
View Profile   IP Logged
altaj
Junior Member
**
Offline



Posts: 11

Re: need help modifying the reset to an oscillator module
Reply #3 - Mar 14th, 2011, 11:13am
 
Thanks.  I got a lot of useful knowledge from both of these  replies.   I used the "@(above" function, which I had not yet encountered.  

I had to modify the "phase reset" block Ken provided slightly, to also reset n.  Otherwise the new start state of the osc was not always the same, as it depends on n :
Code:
@(cross(V(enb)-vth)) begin
		if (V(enb) > vth) begin
			next = 1000; n=0; end
		else
			next = $abstime + 0.5/freq;
	end 



Question:  Why 1000?   Arbitrary choice?

Thanks again!
John
Back to top
 
 
View Profile   IP Logged
Ken Kundert
Global Moderator
*****
Offline



Posts: 2386
Silicon Valley
Re: need help modifying the reset to an oscillator module
Reply #4 - Mar 14th, 2011, 10:15pm
 
Yes, 1000 was arbitrary. It just has to be larger than any possible stop time.

-Ken
Back to top
 
 
View Profile WWW   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.