cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
emiliano87
Visitor
Visitor
8,752 Views
Registered: ‎07-14-2011

DDS multifrequency runtime

Jump to solution

Hi, What is the recommended technique to change the frequency of a sine wave at runtime? Do I have to implement a divider by changing the clock counter module for each output frequency? I'm using spartan 3s200 ft256 with DDS 4.0.

 

thanks.

0 Kudos
1 Solution

Accepted Solutions
gszakacs
Professor
Professor
7,124 Views
Registered: ‎08-14-2007

The point is that you should select the bit width of the DDS accumulator and increment port to allow the

frequency resolution you require. 

 

For example for a resolution of 100 Hz at 50 MHz input clock you would need 19 bits.  It

is not uncommon to use enough bits to provide fractional Hz resolution.  If your output needs to go in

geometric steps rather than linear, the best thing is to either calculate the correct increment setting on

the fly or use a look-up table with the phase increment values for each of your required frequencies.

 

Note that the fact that you only have 7 or 8 bits of DAC on the output does not mean that you need

to use no more than 8 bits for the accumulator.  Just attach the most significant bits of the output

to your sine table.

 

-- Gabor

-- Gabor

View solution in original post

12 Replies
gszakacs
Professor
Professor
8,740 Views
Registered: ‎08-14-2007

Normally you just change the "phase increment" to change the frequency.  When you

generate the core, on page two of the customization screens, select "streaming" for

the "Phase Increment Programmability" option.  Then you will have a directly programmable

output frequency.

 

See the DDS data sheet (ds558.pdf) for more detail on how to use the phase increment

streaming mode.

 

-- Gabor

-- Gabor
0 Kudos
emiliano87
Visitor
Visitor
8,737 Views
Registered: ‎07-14-2011

Thank you for support. I'll do it and report the results.

0 Kudos
emiliano87
Visitor
Visitor
8,734 Views
Registered: ‎07-14-2011
I change the 'phase increment' on runtime, but when I increment the register the sine wave distorts. And if I change the clock and phase increment I have normal signal in output. My doubt is, for generate signal in frequency range of 100 hz to 1Mhz I should change the clock everytime that the signal distorts with high value of phase increment with a low clock?
0 Kudos
ywu
Xilinx Employee
Xilinx Employee
8,712 Views
Registered: ‎11-28-2007

Can you provide more details on what you mean by "the sine wave distorts"? Also if you can show how you increment the phase increment, that will help figure out what's going on.

 


@emiliano87 wrote:
I change the 'phase increment' on runtime, but when I increment the register the sine wave distorts. And if I change the clock and phase increment I have normal signal in output. My doubt is, for generate signal in frequency range of 100 hz to 1Mhz I should change the clock everytime that the signal distorts with high value of phase increment with a low clock?



Cheers,
Jim
0 Kudos
emiliano87
Visitor
Visitor
8,694 Views
Registered: ‎07-14-2011

Hi Jim, I'm using the spartan3 from digilent starter kit. Well, the source clock is 50Mhz and I need generate signal from 100hz to 1Mhz.. I read the Xilinx DDS guide and saw that [ Fout = (Fclk*Phase_inc)/2^B ]. Considering this equation, to get low-frequency signals I think that I need to do a clock divider. The phase increment (8bits) I conected with switches of the board for change the value in runtime. The clock divider I did with a push button that change in runtime the value that should be counted. Using this technique, I cannot yet generate signals with specific frequency. If I do not change the clock and just increment the Phase-Increment, when the value of Phase-Increment is a rather large, the sine wave losing samples and showing like steps. I'm using DDS 4.0.

 

With a high value in the register of Phase Increment the system removes some samples to get the signal in the frequency desired. Thus, I set the clock to keep the signal always at least 8 or 7 bits.

In the image, the red is the sine with correct clock and phase increment and blue/green the signal if I change only Phase Increment with the same clock.

sine_wave_distorts.jpg
0 Kudos
joelby
Advisor
Advisor
8,683 Views
Registered: ‎10-05-2010

Are you incrementing the phase increment at every clock cycle, or just setting it to the value of the switches? Can you share your HDL?

 

0 Kudos
emiliano87
Visitor
Visitor
8,674 Views
Registered: ‎07-14-2011

below my HDL code:

Too In annex the source code in pdf.

-----------------------------------------------------------------

ENTITY my_dds IS

PORT(
enable: IN std_logic;
clock: IN std_logic;
sin: OUT std_logic_vector(7 downto 0);
reset: IN std_logic;
led_on: OUT std_logic;
btn_0: IN std_logic;
switch: IN std_logic_vector(7 downto 0)
);

END my_dds;
----------------------------------------------------------------------------------
ARCHITECTURE Behavioral OF my_dds IS

--DDS component
COMPONENT dds_component
PORT (
ce: IN std_logic;
clk: IN std_logic;
pinc_in: IN std_logic_vector(7 downto 0);
sine: OUT std_logic_vector(7 downto 0));
END COMPONENT;

--DCM component
COMPONENT dcm_hardware
PORT(
CLKIN_IN : IN std_logic;
RST_IN : IN std_logic;
CLKFX_OUT : OUT std_logic;
CLKIN_IBUFG_OUT : OUT std_logic;
CLK0_OUT : OUT std_logic;
CLK2X_OUT : OUT std_logic
);
END COMPONENT;


--DDS signals
attribute syn_black_box : boolean;
attribute syn_black_box of dds_component: component is true;
signal wave : std_logic_vector(7 downto 0);
signal wave_inv : std_logic_vector(7 downto 0);
signal phase_inc : std_logic_vector(7 downto 0);

--sinais para geraçao de outro clock
signal clk_new : std_logic;
signal counter:integer;
signal modulo:integer;

signal clk_botao : std_logic;
signal btn_count : integer;
signal step:integer;

signal clk_system:std_logic; --50Mhz board source
signal clk_2x: std_logic; --100Mhz ouput from DCM

BEGIN

gerador: dds_component --DDS 4.0
port map (
ce => enable,
clk => clk_new,
pinc_in => phase_inc,
sine => wave
);

my_dcm: dcm_hardware PORT MAP( --DCM Director Clock Manager
CLKIN_IN => clock,
RST_IN => reset,
CLKFX_OUT => open,
CLKIN_IBUFG_OUT => open,
CLK0_OUT => clk_system,
CLK2X_OUT => clk_2x
);

process(clk_system) --clock button
begin
if(rising_edge(clk_system)) then
if(btn_count = 3000100) then --15kHz button event
clk_botao <= not clk_botao;
btn_count <= 0;
else
btn_count <= btn_count + 1;
end if;
end if;
end process;

process(clk_2x,enable) --clock divisor for DDS
begin
if(clk_2x ='1' and clk_2x'EVENT) then
if(enable = '1') then
if(counter = modulo) then
clk_new <= not clk_new;
counter <= 0;
else counter <= counter + 1;
end if;
else counter <= 0; clk_new <= '0';
end if;
end if;
end process;


process(btn_0,clk_botao)--counter
begin
if(clk_botao = '1' and clk_botao'EVENT) then
if(btn_0 = '1') then
step <= step + 1;
if(step = 11) then
step <= 0;
end if;
end if;
end if;
end process;


process(step,clk_botao)
begin --clock divisor counter
if(rising_edge(clk_botao)) then

case step is
when 1 =>
modulo <= 651;
when 2 =>
modulo <= 195;
when 3 =>
modulo <= 38;
when 4 =>
modulo <= 23;
when 5 =>
modulo <= 18;
when 6 =>
modulo <= 12;
when 7 =>
modulo <= 4;
when 8 =>
modulo <= 3;
when 9 =>
modulo <= 2;
when 10 =>
modulo <= 1;
when others =>
modulo <= 3900;
end case;
end if;
end process;

--phase increment (switch change in runtime by user)
phase_inc <= switch;

--revert bit 7 for compatibility with DAC0800
wave_inv(6 downto 0) <= wave(6 downto 0);
wave_inv(7) <= not wave(7);

--digital signal output (8bit)
sin <= wave_inv;

--indicate that generator is turned on
led_on <= enable;


END Behavioral;

0 Kudos
joelby
Advisor
Advisor
8,665 Views
Registered: ‎10-05-2010

Did you write dds_component as well? The ports look different to those produced by the Xilinx DDS compiler. We can't really comment on why a DDS of your own design (or a wrapper around the Xilinx core) might not be working well without seeing the code for that too, for obvious reasons.

 

I don't really like your use of combinatorial clocks. There are plenty of threads on this forum explaining why they are not optimal, and it's possible that they are causing glitches affecting your design that aren't showing up in simulation. I'm not quite sure why you are using them to drive the DDS clock port. Normally with a DDS you would keep the clock frequency fixed and quite high - considerably higher than the maximum frequency you want to produce - at the very, very least twice as high, but ideally much higher than that.

 

Only the phase increment should be used to set the output frequency. Your phase increment port should be, by design, wide enough on its own to give you the frequency resolution you require (your 8 bit port is pretty small, but perhaps that's sufficient for your application).

 

0 Kudos
emiliano87
Visitor
Visitor
8,656 Views
Registered: ‎07-14-2011

The dds_component (DDS4.0) was generated with IP Core Generator and the ports was generated automatically. The combinatorial clocks I'm researching for a better way to use if they will be necessary and actually with 'enable' signal I was solved glitch.

About the signal generate with dds, if I use high clock (50Mhz), according with equation of DDS user guide from Xilinx: fout = (fclk*Phase_inc)/2^bits; Supose that you want generate signals from 100hz to 1Mhz. If I do not change the clock, with Phase_Inc starting = 1 and 8 bit, the first output frequency will be 195Khz and changing Phase_Inc all output signals will have frequency multiple of this primary.

 

So far I really dont know what is the better to do, but I thank you very much for your help.

0 Kudos
gszakacs
Professor
Professor
7,125 Views
Registered: ‎08-14-2007

The point is that you should select the bit width of the DDS accumulator and increment port to allow the

frequency resolution you require. 

 

For example for a resolution of 100 Hz at 50 MHz input clock you would need 19 bits.  It

is not uncommon to use enough bits to provide fractional Hz resolution.  If your output needs to go in

geometric steps rather than linear, the best thing is to either calculate the correct increment setting on

the fly or use a look-up table with the phase increment values for each of your required frequencies.

 

Note that the fact that you only have 7 or 8 bits of DAC on the output does not mean that you need

to use no more than 8 bits for the accumulator.  Just attach the most significant bits of the output

to your sine table.

 

-- Gabor

-- Gabor

View solution in original post

emiliano87
Visitor
Visitor
3,917 Views
Registered: ‎07-14-2011

Ok Gabor, I will have a look and make new configurations by considering your issues. Soon I'll post the results. Thank you very much.

0 Kudos
emiliano87
Visitor
Visitor
3,894 Views
Registered: ‎07-14-2011
thanks a lot Gabor! Solved my problem.
0 Kudos