The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Design Languages >> Verilog-AMS >> VCO in Verilog-A/MS question
https://designers-guide.org/forum/YaBB.pl?num=1115114515

Message started by svensl on May 3rd, 2005, 3:01am

Title: VCO in Verilog-A/MS question
Post by svensl on May 3rd, 2005, 3:01am

Hello,

I am trying to model a VCO with a slightly different behaviour.
Instead of using the "idtmod" function for calculating the phase I would like to use the "idt" function and have the phase reset to a new initial value every half period (when my sampled input changes).
For example, if the input voltage alters between two values with period T, the phase should look like a sawtooth function that is being reset to a certain inital value every period T.

My initial try was to calculate the phase using the idt function and then using one of the @ functions to reset the phase to a certain value every period. When simulating however, I found that phase looks like a ramp that has spikes down to zero at every period T.

I am still new to Verilog and would like some feedback on how to go about solving this problem. Any hints would be appreciated.

Thanks

Title: Re: VCO in Verilog-A/MS question
Post by Andrew Beckett on May 3rd, 2005, 8:25am

I don't really understand why you'd want to use idt rather than idtmod - it's cleaner, and probably more accurate to use idtmod (because you need a timestep with the assertion to reset the phase). Here's an example:


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

module vco(vin, vout);
input vin;
output vout;
electrical vin, vout;
parameter real amp = 1;
parameter real center_freq = 1K;
parameter real vco_gain = 1K;
parameter integer steps_per_period = 32;

  real phase;
  real inst_freq;
  integer resetph;

  analog begin

     inst_freq = center_freq + vco_gain * V(vin);
     $bound_step (1.0 / (steps_per_period*inst_freq));
 
     phase=idt(inst_freq,0,resetph);
     resetph=0;
     @(cross(phase-1.0)) begin
       resetph=1;
       end
     //phase = idtmod(inst_freq,0,1);
     V(vout) <+ amp * sin (2 * `M_PI * phase);
  end
endmodule


Note that the 5 lines of code from the idt onwards could be replaced with the single idtmod line.

So why do you want to make life difficult for yourself?

Andrew.

Title: Re: VCO in Verilog-A/MS question
Post by svensl on May 3rd, 2005, 9:30am

Thanks  Andrew.

You are absolutely right when saying that the idtmod function is more tidy and safes lines of code.
What I was trying to achieve was that the phase resets every period independent of the input magnitude. Instead of using
phase = idtmod(inst_freq,0,1);
I should have just used
phase = idtmod(inst_freq,0,V(vin));. Now if the input
voltage has a higher magnitude, the mod will be higher, thus not resetting the phase to early.

I would like also to have a pulse every time the phase crosses lets say m*PI.
Using

k=0;
@(cross(phase - `M_PI, +1, ttol))
k =1;

will only give me one short spike when the phase crosses  PI. How can I make a pulse out of the short spike and how can I obtain a pulse at multiples of PI?

Again, thanks for your feedback.

Title: Re: VCO in Verilog-A/MS question
Post by Ken Kundert on May 3rd, 2005, 10:25pm

I don't believe that making the modulus a function of the input is what you want to do. Remember that the output is a phase, which is a point on a circle. You already have the argument (inst_freq) being a function of the input, this controls the rate at which the point moves around the circle. Now if you also make the modulus of a function of the input, you are effectively varying the circumference of the circle as well. Meaning that the period of the sawtooth will be constant as a function of the input because, as the input increases the rate, it also increases by the circumference by an equal amount. So the period of the sawtooth is independent of the input, but its amplitude will increase with the input. This is problematic, because with low input levels, the output amplitude will not be large enough to trigger the cross statement.

There are two ways to generate a pulse with a controlled width. The easiest is to put in two thresholds, say at 0.25 and 0.75 (assuming modulus is 1), and have one set the output high and the other reset the output low. This will give you a controlled 50% duty cycle. The other thing to do is to use timer event to produce a fixed width pulse (in the body of the cross event you set the output and then save the time you would like to trigger the timer, and in the body of the timer you reset the output). In this case, you must assure that the pulse width is not longer than the minimum period.

-Ken

Title: Re: VCO in Verilog-A/MS question
Post by Andrew Beckett on May 3rd, 2005, 10:30pm

I agree entirely with Ken (no surprises there!). He said exactly what I would have said.

Andrew.

Title: Re: VCO in Verilog-A/MS question
Post by svensl on May 4th, 2005, 4:33am

You all make excellent points.
I intended to have the phase period independent of the input magnitude.
The only thing changing is the slope of the phase with changing input magnitude. By counting how often the phase crosses m*PI, I can obtain a "quantized" value of the input signal. The quantization error would then be the remainder of the last m*PI crossing till the end of the period before the phase resets. Eventually, I would like the quantization error to be the initial phase for the next period. There might be another way of getting the same result more sophisticated using idtmod, I just don’t know how.

Thanks


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