Altera_Forum
Honored Contributor
12 years agopwm generation
Hi,
I would like to know is there any possibility to use always inside for loop?? please anybody explain the errors associated with my code both logical and coding syntax issues ThankYOUHi,
I would like to know is there any possibility to use always inside for loop?? please anybody explain the errors associated with my code both logical and coding syntax issues ThankYOU
clear all;
n = 1000; %this test length
clk = 100; %MHz system clock
f1 = 1; %MHz required output frequency
%%%%%%%%%%%% accumulator %%%%%%%%%%%%%%%
m = 1024; %(assumed) lut size
tw = floor(m*f1/clk); %tuning word for half cycle
ptr = 0; %pointer to lut
for i = 1:n
ptr = round(mod(ptr + tw, m));
lut_data(i) = (ptr-1)*64; %lut computed per pointer
end
%%%%%%%%%%%%% comparator %%%%%%%%%%%%%
clkout = zeros(1,n);
duty = 1; %1 ~ 100 percent
threshold = 32768*duty*2/100;
for i = 1:n
if lut_data(i) <= threshold, clkout(i) = 32767; end;
end
%%%%%%%%%%%% check results %%%%%%%%%%%
figure;plot(lut_data,'g-'); hold
plot(clkout,'r.-');
grid;
d = diff(clkout);
b = find(d);
c = diff(b);
duty_out = round(100*c(2)/(c(1)+c(2)))
here's a working PWM module
--Author: some guy at digikey
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY pwm IS
GENERIC(
sys_clk : INTEGER := 50_000_000; --system clock frequency in Hz
pwm_freq : INTEGER := 100_000; --PWM switching frequency in Hz
bits_resolution : INTEGER := 8; --bits of resolution setting the duty cycle
phases : INTEGER := 1); --number of output pwms and phases
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --asynchronous reset
ena : IN STD_LOGIC; --latches in new duty cycle
duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); --duty cycle
pwm_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --pwm outputs
pwm_n_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0)); --pwm inverse outputs
END pwm;
ARCHITECTURE logic OF pwm IS
CONSTANT period : INTEGER := sys_clk/pwm_freq; --number of clocks in one pwm period
TYPE counters IS ARRAY (0 TO phases-1) OF INTEGER RANGE 0 TO period - 1; --data type for array of period counters
SIGNAL count : counters := (OTHERS => 0); --array of period counters
SIGNAL half_duty : INTEGER RANGE 0 TO period/2 := 0; --number of clocks in 1/2 duty cycle
BEGIN
PROCESS(clk, reset_n)
BEGIN
IF(reset_n = '0') THEN --asynchronous reset
count <= (OTHERS => 0); --clear counter
pwm_out <= (OTHERS => '0'); --clear pwm outputs
pwm_n_out <= (OTHERS => '0'); --clear pwm inverse outputs
ELSIF(clk'EVENT AND clk = '1') THEN --rising system clock edge
IF(ena = '1') THEN --latch in new duty cycle
half_duty <= conv_integer(duty)*period/(2**bits_resolution)/2; --determine clocks in 1/2 duty cycle
END IF;
FOR i IN 0 to phases-1 LOOP --create a counter for each phase
IF(count(0) = period - 1 - i*period/phases) THEN --end of period reached
count(i) <= 0; --reset counter
ELSE --end of period not reached
count(i) <= count(i) + 1; --increment counter
END IF;
END LOOP;
FOR i IN 0 to phases-1 LOOP --control outputs for each phase
IF(count(i) = half_duty) THEN --phase's falling edge reached
pwm_out(i) <= '0'; --deassert the pwm output
pwm_n_out(i) <= '1'; --assert the pwm inverse output
ELSIF(count(i) = period - half_duty) THEN --phase's rising edge reached
pwm_out(i) <= '1'; --assert the pwm output
pwm_n_out(i) <= '0'; --deassert the pwm inverse output
END IF;
END LOOP;
END IF;
END PROCESS;
END logic;
Hi,
Thankyou inputting a frequency and duty cycle value , using counters concepts pwm generation is successful . as u said, to overcome the limitations of counters I am trying to learn accumulator techniques. But target or problem in my code is that... I need to generate a set of frequencies and their pwm from system clock . Like eg... 50mhz my system clock range of frequency 5mhz-30mhz with stepsize 5mhz.... ie, 5,10,15,20,25,30 like that. so I would like to add a loop to select the current frequency and then rest of program will be same. Thankyou