------------------------------------------------------------------------------- -- file: pwm.vhd -- -- Module: pwm -- -- Revision history: -- 21Apr2009 DF Created from led TV pwm.vhd -- 15May2009 DF PWM is now working. Fixed a few bugs. -- 19Dec2009 DF Copied to esc2 design. -- 20Mar2010 DF Copied to rsca, removed glitch in non-switching side -- -- Description: produces a motor PWM pulse that is width clocks long. -- load is set true for one clock cycle, on which speed contains -- the pulse width (0..127) and dir contains the direction. -- At that time, speed is copied into the width register. -- For each PWM period starting at start, the motor winding will -- be energized for width cycles then shorted for the remainder. -- Outputs hia, hib, loa and lob control the H bridge drivers. -- A dead period of one clock prevents the switches from turning -- on simultaneously, which would short out the power supply. -- -- The 20Mar2010 change removes a 60ns glitch in the non-switching side -- of the motor. The rsca board has longer gate drive lines to -- the high side drivers, so this glitch may have killed Q21. -- The glitch was removed by holding one side low whenever dir says -- to, without the dead-time test. -- --------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity pwm is port ( clk : in std_logic; rst : in std_logic; speed : in std_logic_vector(6 downto 0); dir : in std_logic; load : in std_logic; start : in std_logic; hia : out std_logic; hib : out std_logic; loa : out std_logic; lob : out std_logic; fault : in std_logic ); end pwm; architecture behavioral of pwm is signal width, next_width : std_logic_vector(6 downto 0); signal count, next_count : std_logic_vector(6 downto 0); signal pulse, next_pulse : std_logic; signal last_pulse : std_logic; signal our_dir : std_logic; signal overc, next_overc : std_logic_vector(1 downto 0); begin PWM_SYNC_PROCESS: process (clk, rst) begin if (rst = '1') then -- reset everything width <= (others=>'0'); count <= (others=>'0'); pulse <= '0'; our_dir <= '0'; overc <= "00"; elsif (clk'event and clk = '1') then width <= next_width; -- update registers count <= next_count; -- update registers overc <= next_overc; pulse <= next_pulse; last_pulse <= pulse; if (load = '1') then our_dir <= dir; -- update direction else our_dir <= our_dir; end if; end if; end process PWM_SYNC_PROCESS; PWM_COMB_PROCESS: process (count, load, width, start, speed, our_dir, pulse, last_pulse, fault, overc) begin next_width <= width; if (load = '1') then next_width <= speed; -- load pulse width register end if; next_pulse <= '1'; next_count <= count - '1'; -- count down pulse width if (start = '1') then next_count <= width; -- load downcounter if requested next_pulse <= '0'; elsif (count = "0000000") then next_count <= (others=>'0'); next_pulse <= '0'; -- end of pulse at zero count end if; next_overc <= overc; -- deal with overcurrent reported on fault: 0=bad -- overc means overcurrent: true if 3 clocks of fault=0. if (fault = '0' and overc /= "11") then next_overc <= overc + "01"; -- reset overc when next pwm period starts elsif (start = '1') then next_overc <= "00"; end if; -- drive outputs to H bridge safely hia <= '0'; -- default is no outputs on hib <= '0'; loa <= '0'; lob <= '0'; if (overc /= "11") then -- kill outputs if error if (our_dir = '1') then -- forward current hib <= '0'; -- B side is grounded lob <= '1'; if (last_pulse = '1' and pulse = '1') then hia <= '1'; -- drive B side loa <= '0'; elsif (last_pulse = '0' and pulse = '0') then hia <= '0'; -- short winding loa <= '1'; else hia <= '0'; -- dead time loa <= '0'; end if; else hia <= '0'; -- A side is grounded loa <= '1'; if (last_pulse = '1' and pulse = '1') then hib <= '1'; -- drive A side lob <= '0'; elsif (last_pulse = '0' and pulse = '0') then hib <= '0'; -- short winding lob <= '1'; else hib <= '0'; -- dead time lob <= '0'; end if; end if; end if; end process PWM_COMB_PROCESS; end behavioral;