LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY gating_signal IS GENERIC( sys_clk : INTEGER := 50_000_000; --system clock frequency in Hz switch_freq : INTEGER := 50_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 deadgap : INTEGER := 2); --deadgap 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 G1_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0); --G1 outputs G2_out : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0)); --G2 outputs END gating_signal; ARCHITECTURE logic OF gating_signal 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 SIGNAL delay : INTEGER :=0; 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 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 G1_out(i) <= '0'; --G1 output ELSIF(count(i) = half_duty +10 ) then G2_out(i) <= '1'; --G2 dead gap delay output ELSIF (count(i) = period - half_duty -10) THEN G2_out(i) <= '0'; --G2 dead gap delay output ELSIF(count(i) = period - half_duty) THEN --phase's rising edge reached G1_out(i) <= '1'; --G1 output END IF; END LOOP; END IF; END PROCESS; END logic;