To convert a 6-phase signal into a 90° system, the following logic can be helpful:
VHDL
-- 6-phase Clarke transformation (abcdef -> alpha/beta)
-- Christian Noeding, christian@noeding-online.de
-- https://chrisdevblog.com | https://github.com/xn--nding-jua
--
-- Released under GNU General Public License v3
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity abcdef_to_alpha_beta is
port(
clk : in std_logic;
a : in signed(31 downto 0); --Q15.16
b : in signed(31 downto 0); --Q15.16
c : in signed(31 downto 0); --Q15.16
d : in signed(31 downto 0); --Q15.16
e : in signed(31 downto 0); --Q15.16
f : in signed(31 downto 0); --Q15.16
sync_in : in std_logic;
alpha : out signed(31 downto 0); --Q15.16
beta : out signed(31 downto 0); --Q15.16
sync_out : out std_logic
);
end abcdef_to_alpha_beta;
architecture behavioural of abcdef_to_alpha_beta is
-- internal signals
signal state : natural range 0 to 5 := 0;
signal b_scaled : signed(31 downto 0); -- Q15.16
signal c_scaled : signed(31 downto 0); -- Q15.16
signal e_scaled : signed(31 downto 0); -- Q15.16
signal f_scaled : signed(31 downto 0); -- Q15.16
signal alpha_int : signed(31 downto 0); -- Q15.16
--signals for multiplier
signal mult_in_a : signed(31 downto 0) := (others=>'0');
signal mult_in_b : signed(31 downto 0) := (others=>'0');
signal mult_out : signed(63 downto 0) := (others=>'0');
begin
-- multiplier
process(mult_in_a, mult_in_b)
begin
mult_out <= mult_in_a * mult_in_b;
end process;
process(clk)
begin
if rising_edge(clk) then
if (sync_in = '1' and state = 0) then
-- alpha = (1/3) * (a + b/2 + sqrt(3)*c/2 - e/2 + sqrt(3)*f/2)
-- beta = (1/3) * (sqrt(3)*b/2 + c/2 + d + sqrt(3)*e/2 + f/2)
mult_in_a <= b;
mult_in_b <= to_signed(56756, 32); -- sqrt(3)/2 as Q15.16
state <= 1; -- start state-machine
elsif (state = 1) then
b_scaled <= resize(shift_right(mult_out, 16), 32);
mult_in_a <= c;
state <= state + 1;
elsif (state = 2) then
c_scaled <= resize(shift_right(mult_out, 16), 32);
mult_in_a <= e;
state <= state + 1;
elsif (state = 3) then
e_scaled <= resize(shift_right(mult_out, 16), 32);
mult_in_a <= f;
state <= state + 1;
elsif (state = 4) then
f_scaled <= resize(shift_right(mult_out, 16), 32);
-- alpha = (1/3) * (a + b/2 + sqrt(3)*c/2 - e/2 + sqrt(3)*f/2)
mult_in_a <= a + shift_right(b, 1) + c_scaled - shift_right(e, 1) + f_scaled; -- (a + b/2 + sqrt(3)*c/2 - e/2 + sqrt(3)*f/2)
mult_in_b <= to_signed(21845, 32); -- (1/3)
state <= state + 1;
elsif (state = 5) then
alpha_int <= resize(shift_right(mult_out, 16), 32);
-- beta = (1/3) * (sqrt(3)*b/2 + c/2 + d + sqrt(3)*e/2 + f/2)
mult_in_a <= b_scaled + shift_right(c, 1) + d + e_scaled + shift_right(f, 1); -- (sqrt(3)*b/2 + c/2 + d + sqrt(3)*e/2 + f/2)
mult_in_b <= to_signed(21845, 32); -- (1/3)
state <= state + 1;
elsif (state = 6) then
alpha <= alpha_int;
beta <= resize(shift_right(mult_out, 16), 32);
sync_out <= '1';
state <= state + 1;
elsif (state = 7) then
sync_out <= '0';
state <= 0;
end if;
end if;
end process;
end behavioural;
