From: Martin Prudek Date: Thu, 9 Apr 2015 17:57:20 +0000 (+0200) Subject: PWM entity file added. X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/rpi-motor-control.git/commitdiff_plain/ded99c7db106505deace0863b870c0572a991f5d PWM entity file added. --- diff --git a/pmsm-control/mcpwm.vhdl b/pmsm-control/mcpwm.vhdl new file mode 100644 index 0000000..53604e7 --- /dev/null +++ b/pmsm-control/mcpwm.vhdl @@ -0,0 +1,92 @@ +-- +-- * motion-control PWM * +-- PWM controller with failsafe input +-- +-- part of LXPWR motion control board (c) PiKRON Ltd +-- idea by Pavel Pisa PiKRON Ltd +-- code by Marek Peca +-- 01/2013 +-- +-- license: GNU GPLv3 +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity mcpwm is + generic ( + pwm_width: natural := 12 + ); + port ( + -- reset: in std_logic; + clock: in std_logic; + sync: in std_logic; --flag that counter "restarts-overflows" + data_valid:in std_logic; --indicates data is consistent + failsafe: in std_logic; --failmode turn of both transistors + en_p, en_n: in std_logic; --enable positive & enable inverse + match: in std_logic_vector (pwm_width-1 downto 0); --posion of counter when we swap output logic + count: in std_logic_vector (pwm_width-1 downto 0); --do we use external counter? + + out_p, out_n: out std_logic --pwm outputs + ); +end mcpwm; + +architecture behavioral of mcpwm is + signal match_reg, next_match_reg: std_logic_vector (match'range); + signal en_p_reg, en_n_reg : std_logic; --enable positive + inverse output + signal next_en_p_reg, next_en_n_reg: std_logic; --enable - next value + signal q, next_q: std_logic; --logic value(level) of output +begin + + -- setting the output (q holds the logic value) + out_p <= q and en_p_reg and not failsafe; + -- out_n <= not q and en_n_reg and not failsafe; --Use this line when using "not inteligent" half-H bridge + out_n <= en_n_reg or failsafe; --switch off both transistors. Use this line when "inteligent" half-H bridge is at use + + --set next values - use old or new values + reg: process (data_valid, failsafe, match, match_reg, + en_p, en_n, en_p_reg, en_n_reg) + begin + --when theres no new data & failsafe is unset - use old values + next_match_reg <= match_reg; + next_en_p_reg <= en_p_reg; + next_en_n_reg <= en_n_reg; + + --when failsafe is set disable both directions + if failsafe = '1' then -- + -- + -- little paranoia, costs nothing + -- + next_en_p_reg <= '0'; + next_en_n_reg <= '0'; + --if theres no failsafe flag & data is valid, we can set next values + elsif data_valid = '1' then + next_match_reg <= match; + next_en_p_reg <= en_p; + next_en_n_reg <= en_n; + end if; + end process; + + --swaping output logic when counter counts to match + rs: process (sync, count, match_reg, q) --if theres event on sync(the counter "restarts") or count + begin + if count = match_reg then --when the counter counts to match, we swap the signals (~middle of duty cycle) + next_q <= '0'; + elsif sync = '1' then --syncing signal (start of duty cycle) + next_q <= '1'; + else + next_q <= q; + end if; + end process; + + seq: process + begin + --set actual -> shift next registers + wait until clock'event and clock = '1'; + match_reg <= next_match_reg; + en_p_reg <= next_en_p_reg; + en_n_reg <= next_en_n_reg; + q <= next_q; + end process; +end behavioral;