--library IEEE; --use IEEE.std_logic_1164.all; --use IEEE.std_logic_arith.all; --use IEEE.std_logic_unsigned.all; --package my_package is --constant m: natural := 163; --constant logm: natural := 8; --end my_package; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.my_package.all; entity EC_addition_doubling is port( xP, yP, xQ, yQ: in std_logic_vector(m-1 downto 0); clk, reset, start, addition: in std_logic; xR: inout std_logic_vector(m-1 downto 0); yR: out std_logic_vector(m-1 downto 0); done: out std_logic ); end EC_addition_doubling; architecture circuit of EC_addition_doubling is component multiplier_163_7_6_3 is port ( a, b: in std_logic_vector(m-1 downto 0); clk, reset, start: in std_logic; c: inout std_logic_vector(m-1 downto 0); done: out std_logic ); end component; component divider_163_7_6_3 is port( g, h: in std_logic_vector(m-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector(m-1 downto 0); done: out std_logic ); end component; component square_163_7_6_3 is port ( a: in std_logic_vector(162 downto 0); z: out std_logic_vector(162 downto 0) ); end component; signal div_in1, div_in2, div_out, lambda, lambda_square, mult_in1, mult_out, xP_square: std_logic_vector(m-1 downto 0); signal start_div, div_done, start_mult, mult_done: std_logic; subtype states is natural range 0 to 6; signal current_state: states; begin divider_inputs: for i in 0 to m-1 generate div_in1(i) <= yP(i) xor (yQ(i) and addition); div_in2(i) <= xP(i) xor (xQ(i) and addition); end generate; divider: divider_163_7_6_3 port map(div_in1, div_in2, clk, reset, start_div, div_out, div_done); lambda_computation: for i in 0 to m-1 generate lambda(i) <= div_out(i) xor (xP(i) and not(addition)); end generate; lambda_square_computation: square_163_7_6_3 port map(lambda, lambda_square); x_output: for i in 1 to 162 generate xR(i) <= lambda_square(i) xor lambda(i) xor (div_in2(i) and addition); end generate; xR(0) <= not(lambda_square(0) xor lambda(0) xor (div_in2(0) and addition)); multiplier_inputs: for i in 0 to 162 generate mult_in1(i) <= xR(i) xor (xP(i) and addition); end generate; multiplier: multiplier_163_7_6_3 port map(mult_in1, lambda, clk, reset, start_mult, mult_out, mult_done); xP_square_computation: square_163_7_6_3 port map(xP, xP_square); y_output: for i in 0 to 162 generate yR(i) <= mult_out(i) xor xR(i) xor ((addition and yP(i)) or (not(addition) and xP_square(i))); end generate; control_unit: process(clk, reset, current_state) begin case current_state is when 0 to 1 => start_div <= '0'; start_mult <= '0'; done <= '1'; when 2 => start_div <= '1'; start_mult <= '0'; done <= '0'; when 3 => start_div <= '0'; start_mult <= '0'; done <= '0'; when 4 => start_div <= '0'; start_mult <= '1'; done <= '0'; when 5 to 6 => start_div <= '0'; start_mult <= '0'; done <= '0'; end case; if reset = '1' then current_state <= 0; elsif clk'event and clk = '1' then case current_state is when 0 => if start = '0' then current_state <= 1; end if; when 1 => if start = '1' then current_state <= 2; end if; when 2 => current_state <= 3; when 3 => if div_done = '1' then current_state <= 4; end if; when 4 => current_state <= 5; when 5 => if mult_done = '1' then current_state <= 6; end if; when 6 => current_state <= 0; end case; end if; end process; end circuit;