Forum Discussion

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

PWM generator

i want a PWM generator which i insert D.C in percents, so i did : (tmp_1 is my requierd D.C)

i defined signals like that :

signal count_1 : std_logic_vector(15 downto 0);

signal tmp_1 : std_logic_vector(6 downto 0) ;

if PWM_creator_CLK'event and PWM_creator_CLK='1' then

count_1 <= count_1 + 1;

if count_1 = 49999 then

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

elsif count_1 < tmp_1*500 then ---------------------------------------------------------------------> got an Error at this line

motor_1_PWM_OUT <= '1';

else

motor_1_PWM_OUT <= '0';

end if;

end if;

end process motor_1_PWM ;

how can i do this condition by another way ?

thank you for help...

2 Replies

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

    VHDL is a strong "typed" language. tmp_1 is a std_logic_vector and 500 is an integer.

    There are a few ways around this. Although it may be bad practice, you could try:

    elsif (count_1 < (tmp_1*conv_std_logic_vector(500,7))) then
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I suggest that you consider the use of ieee.numeric_std and VHDL 2008, at least the construts in VHDL 2008 as supported by Quartus at this time. (Altera, we are still waiting for full support of VHDL 2008!)

    I put together a quick snippet of code for what I think that you want to do. Note that I use a record type to clarify the PWM signals. There are effectively three states: one during the duty cycle on time, one during the duty cycle off time, and one to reset the counter (which really isn't a state, just a resetting of the pwm counter.) Best, James

    architecture RLT of PWMgenerator is
    type pwmType is record
        drive : std_logic;
        dutyCycle : integer range 0 to 2**24;
        Period    : integer range 0 to 2**24;
    end record;
    signal pwm : pwmType;
    begin
    pwm.Period    <= someValue;  -- (Would come from port I/O)
    pwm.dutyCycle <= someIncomingValue; -- (Would come form port I/O)
    process(all)
    variable counter : integer;
    begin
    if HRST then
        pwm.drive <= '0';
    elsif rising_edge(MCLK) then
        if counter < pwm.dutyCycle then
            counter := counter + 1;
            pwm.drive <= '1';
        elsif counter < pwm.Period then
            counter := counter + 1;
            pwm.drive <= '0';
        else
            counter := 0;
            pwm.drive <= '0';
        end if;
    end if;
    end process;