library ieee;
use ieee.std_logic_1164.all;
USE IEEE.numeric_std.ALL;

entity PWM_one_branch is
    generic(
        PHASES : integer;
        HALF_P : integer;
        ACTIVE_H : std_logic;
        ACTIVE_L : std_logic;
        DEAD_TIME_COUNT : unsigned
    );
	port (
	-- Users to add ports here
        run : in std_logic;
        run_neg : in std_logic;
        clk : in std_logic;	
        duty : in unsigned (15 downto 0);
        counter : in unsigned (31 downto 0);
        PWM_H : out std_logic;
        PWM_L : out std_logic
        
	);
end PWM_one_branch;

architecture Behavioral of PWM_one_branch is
	                                          	
    constant half_period : unsigned (31 downto 0) := to_unsigned(HALF_P,32);
	
    signal half_duty_new : unsigned (31 downto 0);
    signal half_duty_actual : unsigned (31 downto 0); 
    signal sw_lvl1 : unsigned (31 downto 0); 
    signal sw_lvl2 : unsigned (31 downto 0); 
    signal sw_lvl3 : unsigned (31 downto 0); 
    signal sw_lvl4 : unsigned (31 downto 0);   

begin
    process (clk,run,run_neg) begin
        if (run = '0' or run_neg = '1') then 
            half_duty_actual <= (others => '0'); 
        elsif (clk'event and clk = '1') then
            half_duty_new <= resize(duty * half_period / 65535,32);
            if (counter = 0) then
                half_duty_actual <= half_duty_new;  
            end if;
        end if; 
    end process;
    
--    process (clk) begin
--        if (clk'event and clk = '1') then
--            if (PHASES=9 and half_duty_actual>half_period/3-10 and half_duty_actual<half_period/3+10) then
--                sw_lvl1 <= half_period - half_duty_actual - dead_time_count + 10;
--                sw_lvl2 <= half_period - half_duty_actual + 10;
--                sw_lvl3 <= half_period + half_duty_actual + 10;
--                sw_lvl4 <= half_period + half_duty_actual + dead_time_count + 10;
--            elsif (PHASES=12 and half_duty_actual>half_period/2-10 and half_duty_actual<half_period/2+10) then  
--                sw_lvl1 <= half_period - half_duty_actual - dead_time_count + 10;
--                sw_lvl2 <= half_period - half_duty_actual + 10;
--                sw_lvl3 <= half_period + half_duty_actual + 10;
--                sw_lvl4 <= half_period + half_duty_actual + dead_time_count + 10;
--            else
--                sw_lvl1 <= half_period - half_duty_actual - dead_time_count;
--                sw_lvl2 <= half_period - half_duty_actual;
--                sw_lvl3 <= half_period + half_duty_actual;
--                sw_lvl4 <= half_period + half_duty_actual + dead_time_count;  
--            end if; 
--        end if;            
--    end process;
    
    process (clk,run,run_neg) begin
        if (run = '0' or run_neg = '1') then 
            PWM_H <= not ACTIVE_H;
            PWM_L <= not ACTIVE_L; 
        elsif (clk'event and clk = '1') then
            if counter = half_period - half_duty_actual - dead_time_count then
                PWM_L <= not ACTIVE_L;
            --end if;    
            elsif counter = half_period - half_duty_actual then
                PWM_H <= ACTIVE_H;      
            --end if;    
            elsif counter = half_period + half_duty_actual then
                PWM_H <= not ACTIVE_H; 
            --end if;     
            elsif counter = half_period + half_duty_actual + dead_time_count then 
                PWM_L <= ACTIVE_L;
            end if;
        end if;           
    end process;    

end Behavioral;