--======================================================================================= -- TITLE : Deadtime manager -- DESCRIPTION : Timer for deadtime generation -- FILE : deadtime_generator.vhd -- COMPANY : Micro-Cameras & Space Exploration SA --======================================================================================= -- CREATION -- DATE AUTHOR PROJECT REVISION -- 02/03/2011 JGi FTM 110302a --======================================================================================= -- MODIFICATION HISTORY -- DATE AUTHOR PROJECT REVISION COMMENTS -- 02/03/2011 JGi FTM 110302a Description -- 13/04/2011 JGi FTM 110413a Remove unused signal --======================================================================================= -- Library Definition library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- Entity Definition entity deadtime_generator is port( --clock clk_250MHz : in std_logic; --control deadtime : in std_logic_vector(15 downto 0); --I/O start : in std_logic; waiting : out std_logic); end deadtime_generator; -- Architecture Definition architecture RTL of deadtime_generator is type t_reg is record -- Internal register declaration deadtime : std_logic_vector(15 downto 0); deadtime_counter : std_logic_vector(15 downto 0); deadtime_value_reached : std_logic_vector(3 downto 0); deadtime_0_done : std_logic_vector(2 downto 0); deadtime_1_done : std_logic_vector(1 downto 0); deadtime_2_done : std_logic; -- Ouput register declaration busy : std_logic_vector(2 downto 0); end record; signal i_next_reg : t_reg := (deadtime => (others => '0'), deadtime_counter => (others => '0'), deadtime_value_reached => (others => '0'), deadtime_0_done => (others => '0'), deadtime_1_done => (others => '0'), deadtime_2_done => '0', busy => (others => '0')); signal i_reg : t_reg := (deadtime => (others => '0'), deadtime_counter => (others => '0'), deadtime_value_reached => (others => '0'), deadtime_0_done => (others => '0'), deadtime_1_done => (others => '0'), deadtime_2_done => '0', busy => (others => '0')); begin -- Combinatorial logic process(start, deadtime, i_reg) variable v_reg : t_reg := (deadtime => (others => '0'), deadtime_counter => (others => '0'), deadtime_value_reached => (others => '0'), deadtime_0_done => (others => '0'), deadtime_1_done => (others => '0'), deadtime_2_done => '0', busy => (others => '0')); begin v_reg := i_reg; --=================================================================================== --=================================================================================== -- Counter management --=================================================================================== -- Register deadtime to reduce delay v_reg.deadtime := deadtime; -- If deadtime enabled, count if i_reg.busy(0) = '1' then v_reg.deadtime_counter(3 downto 0) := std_logic_vector(unsigned(i_reg.deadtime_counter(3 downto 0))+1); if i_reg.deadtime_0_done(2) = '1' then v_reg.deadtime_counter(7 downto 4) := std_logic_vector(unsigned(i_reg.deadtime_counter(7 downto 4))+1); end if; if i_reg.deadtime_1_done(1) = '1' then v_reg.deadtime_counter(11 downto 8) := std_logic_vector(unsigned(i_reg.deadtime_counter(11 downto 8))+1); end if; if i_reg.deadtime_2_done = '1' then v_reg.deadtime_counter(15 downto 12) := std_logic_vector(unsigned(i_reg.deadtime_counter(15 downto 12))+1); end if; else v_reg.deadtime_counter := (others => '0'); end if; -- If counter reached the deadtime value if i_reg.deadtime_value_reached = "1111" then v_reg.busy := (others => '0'); end if; -- Start when input goes high if start = '1' then v_reg.busy := (others => '1'); end if; -- Generate partial comparison to the programmed deadtime value if i_reg.deadtime_counter(3 downto 0) = i_reg.deadtime(3 downto 0) then v_reg.deadtime_value_reached(0) := i_reg.busy(1); else v_reg.deadtime_value_reached(0) := '0'; end if; if i_reg.deadtime_counter(7 downto 4) = i_reg.deadtime(7 downto 4) then v_reg.deadtime_value_reached(1) := i_reg.busy(1); else v_reg.deadtime_value_reached(1) := '0'; end if; if i_reg.deadtime_counter(11 downto 8) = i_reg.deadtime(11 downto 8) then v_reg.deadtime_value_reached(2) := i_reg.busy(1); else v_reg.deadtime_value_reached(2) := '0'; end if; if i_reg.deadtime_counter(15 downto 12) = i_reg.deadtime(15 downto 12) then v_reg.deadtime_value_reached(3) := i_reg.busy(1); else v_reg.deadtime_value_reached(3) := '0'; end if; -- Manage partial counters enable if i_reg.deadtime_counter(3 downto 0) = "1100" then v_reg.deadtime_0_done(0) := '1'; else v_reg.deadtime_0_done(0) := '0'; end if; v_reg.deadtime_0_done(1) := i_reg.deadtime_0_done(0); v_reg.deadtime_0_done(2) := i_reg.deadtime_0_done(1); if i_reg.deadtime_counter(7 downto 4) = "1111" then v_reg.deadtime_1_done(0) := i_reg.deadtime_0_done(0); else v_reg.deadtime_1_done(0) := '0'; end if; v_reg.deadtime_1_done(1) := i_reg.deadtime_1_done(0); if i_reg.deadtime_counter(11 downto 8) = "1111" then v_reg.deadtime_2_done := i_reg.deadtime_0_done(1) and i_reg.deadtime_1_done(0); else v_reg.deadtime_2_done := '0'; end if; --=================================================================================== --=================================================================================== -- Drive register input i_next_reg <= v_reg; --=================================================================================== -- Output assignation waiting <= i_reg.busy(2); --=================================================================================== end process; -- Sequential logic process(clk_250MHz) begin if rising_edge(clk_250MHz) then i_reg <= i_next_reg; end if; end process; end RTL;