LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY demo IS GENERIC( sys_clk : INTEGER := 50_000_000; --system clock frequency in Hz switch_freq : INTEGER := 100_000; --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 : IN STD_LOGIC; -- reset ena : IN STD_LOGIC; --latches in new duty cycle duty : IN STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); --duty cycle phaseshift: IN INTEGER ; --phaseshift G1_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --G1 outputs G2_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --G2 outputs G3_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --G3 outputs G4_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0)); --G4 outputs END demo; ARCHITECTURE logic OF demo IS CONSTANT period : INTEGER := sys_clk/switch_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) BEGIN IF(reset = '1') THEN --asynchronous reset count <= (OTHERS => 0); --clear counter G1_out <= (OTHERS => '0'); --clear G1 outputs G2_out <= (OTHERS => '0'); --clear G2 inverse outputs G3_out <= (OTHERS => '0'); --clear G3 G4_out <= (OTHERS => '0'); --clear G4 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 + 3) THEN --phase's falling edge reached --G1_out(i) <= '0'; --G1 output G2_out(i) <= '1'; --G2 output ELSIF(count(i) = half_duty - 3) THEN --phase's falling edge reached G1_out(i) <= '0'; --G1 output ELSIF(count(i) = (period - phaseshift + 3 )) THEN -- 250-100=150 G3_out(i) <= '1'; ELSIF(count(i) = (period - phaseshift - 3 )) THEN -- 250-100=150 G4_out(i) <= '0'; ELSIF(count(i) = period - half_duty + 3) THEN --phase's rising edge reached G1_out(i) <= '1'; --G1 output ELSIF(count(i) = period - half_duty - 3) THEN --phase's falling edge reached G2_out(i) <= '0'; --G2 output ELSIF(count(i) = (half_duty + (125-phaseshift) - 3 )) THEN G3_out(i) <= '0'; ELSIF(count(i) = (half_duty + (125-phaseshift) + 3 )) THEN G4_out(i) <= '1'; END IF; END LOOP; END IF; END PROCESS; END logic;