PWM entity file added.
authorMartin Prudek <prudemar@fel.cvut.cz>
Thu, 9 Apr 2015 17:57:20 +0000 (19:57 +0200)
committerMartin Prudek <prudemar@fel.cvut.cz>
Thu, 9 Apr 2015 17:57:20 +0000 (19:57 +0200)
pmsm-control/mcpwm.vhdl [new file with mode: 0644]

diff --git a/pmsm-control/mcpwm.vhdl b/pmsm-control/mcpwm.vhdl
new file mode 100644 (file)
index 0000000..53604e7
--- /dev/null
@@ -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 <pisa@cmp.felk.cvut.cz>
+-- code by Marek Peca <mp@duch.cz>
+-- 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;