Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

how to fix varying pwm along with constant frequency of 20kHz in cyclon 2 ep2c5t144c8

Hi! I am using ALTERA cyclon 2 ep2c5t144c8n board for generating varying pulse width modulation (duty cycle from 0 to 100%) along with constant frequency of 20kHz. I have written the code and its working well but the problem is that the varying pwm is running very fast on oscilloscope due to which I cannot see the proper pattern of varying pwm. The other problem is about frequency that I want constant frequencyof 20kHz with varying pwm but its also varying like first it goes down to 10kHz then comes up at 18kHz then at 20kHz and this process repeats again and again....in short we can say that random values of frequency is generating....How can I fix this problem??? Please help me out, your answers will be highly appreciable! Thank you...!

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You need to give us more to work with. It's something wrong with your design - for which you've not given us any detail. How is your design captured? Verilog? VHDL? Schematic? Post your design and we may be able to help.

    Cheers,

    Alex
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thanks for your response alex!

    its VHDL

    I have the written VHDL code with me...

    what do you mean by design?? I am not getting about it!!!

    if I send you the output waveform would it be helpfull for you to understand?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your 'design' is what you want your device to do. Sounds like you've written it in VHDL. Post your VHDL code (your design) to this post and we can probably help.

    Please wrap any code in 'CODE'' (#) tags

    Does it work in simulation?

    Cheers,

    Alex
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Code:

    library IEEE;

    use IEEE.STD_LOGIC_1164.ALL;

    use IEEE.NUMERIC_STD.ALL;

    entity pwm_sti is

    Port ( clk : in STD_LOGIC;

    reset : in STD_LOGIC;

    feed_back : in STD_LOGIC_VECTOR (7 downto 0);

    driv1_out : out STD_LOGIC;

    driv2_out : out STD_LOGIC;

    pwm_out : out STD_LOGIC);

    end pwm_sti;

    architecture Behavioral of pwm_sti is

    signal counter_166, counter_166_delay : unsigned(7 downto 0);

    signal count_2500clk_cycles : unsigned(11 downto 0);

    signal pwm_comp_reg : unsigned(11 downto 0);

    signal count_pwm_comp_reg : unsigned(11 downto 0);

    signal delta_reg : unsigned(7 downto 0);

    signal driv1_out_sig, driv2_out_sig, state_falg : std_logic;

    signal counter_1div60_div4, counter_1div60_div4_delay : unsigned(1 downto 0);

    begin

    driv1_out <= driv1_out_sig;

    driv2_out <= driv2_out_sig;

    -- pwm generation process

    process(clk)

    variable pwm_comp_var : unsigned(12 downto 0);

    begin

    if(clk'event and clk = '1')then

    if(reset = '1') then

    counter_166 <= (others => '0');

    counter_166_delay <= (others => '0');

    count_2500clk_cycles <= (others => '0');

    pwm_comp_reg <= (others => '0');

    count_pwm_comp_reg <= (others => '0');

    delta_reg <= (others => '0');

    driv1_out_sig <= '1';

    driv2_out_sig <= '0';

    counter_1div60_div4 <= (others => '0');

    counter_1div60_div4_delay <= (others => '0');

    state_falg <= '0';

    else

    pwm_out <= '0';

    if(state_falg = '0') then

    delta_reg <= unsigned (feed_back);

    state_falg <= '1';

    else

    if(count_2500clk_cycles = "100111000100") then

    count_2500clk_cycles <= (others => '0');

    counter_166 <= counter_166 + 1;

    -- adding value to pwm comp reg

    if(counter_1div60_div4(0) = '0') then

    pwm_comp_var := resize(pwm_comp_reg, 13) + resize(delta_reg, 13);

    pwm_comp_reg <= pwm_comp_var(11 downto 0);

    elsif(counter_1div60_div4(0) = '1') then

    pwm_comp_var := resize(pwm_comp_reg, 13) - resize(delta_reg, 13);

    pwm_comp_reg <= pwm_comp_var(11 downto 0);

    end if;

    -- after half sine cycle

    if(counter_166 = "10100110") then

    counter_166 <= (others => '0');

    driv1_out_sig <= not (driv1_out_sig);

    driv2_out_sig <= not (driv2_out_sig);

    pwm_comp_reg <= (others => '0');

    end if;

    elsif(count_2500clk_cycles = "100111000011") then

    count_pwm_comp_reg <= (others => '0');

    count_2500clk_cycles <= count_2500clk_cycles + 1;

    else

    count_2500clk_cycles <= count_2500clk_cycles + 1;

    if(count_pwm_comp_reg <= pwm_comp_reg) then

    count_pwm_comp_reg <= count_pwm_comp_reg + 1;

    pwm_out <= '1';

    end if;-- count_pwm_comp

    end if; -- 2500clk

    -- creating a delay

    counter_166_delay <= counter_166;

    if ((counter_166 = "01010011" and counter_166_delay = "01010010") or

    (counter_166 = "10100110" and counter_166_delay = "10100101")) then

    counter_1div60_div4 <= counter_1div60_div4 + 1;

    end if;-- counter_166

    -- creating a delay

    counter_1div60_div4_delay <= counter_1div60_div4;

    if(counter_1div60_div4 = "00" and counter_1div60_div4_delay = "11") then

    delta_reg <= unsigned (feed_back);

    end if; --counter 1 div 60 div 4

    end if; -- state falg

    end if; --reset

    end if; -- clk

    end process

    end Behavioral;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes it works in simulation now I am trying to implement this code on my hardware but I am facing problem which I have discussed above!

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't want to put you off your code but I can't follow it since I have my own simple code below for pwd at any duty cycle, any frequency:

    
        library ieee;
        use ieee.std_logic_1164.all;
        use IEEE.numeric_std.all;
        entity pwm is
        port(
            clk           : in  std_logic;
            freq_word     : in  std_logic_vector(13 downto 0) := "00011001100110";
            duty_scaled   : in  std_logic_vector(13 downto 0) := "10000000000000";
            pwm           : out std_logic
            );
        end entity;
        architecture rtl of pwm is
          
          signal ptr : unsigned(14 downto 0) := (others => '0');
           
          begin
          process(clk)
          begin
            if(rising_edge(clk)) then
               ptr <= ptr + unsigned(freq_word);
               pwm <= '0';
               if ptr(13 downto 0) < unsigned(duty_scaled) then
                   pwm <= '1';
               end if;
            end if;
          end process;
             
        end rtl;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Over complicated though your code is it behaves exactly the same in simulation as it does on my dev board. I can see the same varying PWM pattern on my scope as I see in simulation. The fixed frequency outputs behave as well and don't move around as you suggested in your first post.

    So, I can only assume you're having trouble with your oscilloscope and seeing what you expect.

    Cheers,

    Alex