--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; --constant zero: std_logic_vector(m-1 downto 0) := (others => '0'); --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_point_multiplication is port ( xP, yP, k: in std_logic_vector(m-1 downto 0); clk, reset, start: in std_logic; xQ, yQ: inout std_logic_vector(m-1 downto 0); Q_infinity: inout std_logic; done: out std_logic ); end EC_point_multiplication; architecture circuit of EC_point_multiplication is constant zero: std_logic_vector(m-1 downto 0) := (others => '0'); component 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 component; signal xxP, yyP, xR, yR, next_xxP, next_yyP, next_xQ, next_yQ, int_k: std_logic_vector(m-1 downto 0); signal ce_P, ce_Q, sel_P, sel_Q, operation, start_operation, operation_done, k_i, reset_counter, count_down, last_step: std_logic; signal step_number: std_logic_vector(logm-1 downto 0); subtype states is natural range 0 to 13; signal current_state: states; begin with sel_P select next_xxP <= xP when '0', xR when others; with sel_P select next_yyP <= yP when '0', yR when others; with sel_Q select next_xQ <= xxP when '0', xR when others; with sel_Q select next_yQ <= yyP when '0', yR when others; --condition_generation: for i in 0 to m-1 generate --xxPxorxQ(i) <= xxP(i) xor xQ(i); --yyPxoryQ(i) <= yyP(i) xor yQ(i); --yyPxoryQxorxxP(i) <= yyPxoryQ(i) xor xxP(i); --with sel_1 select orin1(i) <= xxP(i) when "00", xQ(i) when "01", xxPxorxQ(i) when others; --with sel_1 select orin2(i) <= yyP(i) when "00", yQ(i) when "01", yyPxoryQ(i) when "11", yyPxoryQxorxxP(i) when others; --orout(i) <= orin1(i) or orin2(i); --with sel_2 select norin(i) <= orout(i) when '0', xxP(i) when others; --end generate; --conditions: for i in 0 to m-1 generate --PxorQ(i) <= (xxP(i) xor xQ(i)) or (yyP(i) xor yQ(i)); --PxorMinusQ(i) <= (xxP(i) xor xQ(i)) or (yyP(i) xor yQ(i) xor xQ(i)); --end generate; --long_nor: process(PxorQ, PxorMinusQ, xxP) --begin --if PxorQ = zero then PequalQ <= '1'; else PequalQ <= '0'; end if; --if PxorMinusQ = zero then PequalMinusQ <= '1'; else PequalMinusQ <= '0'; end if; --if xxP = zero then xPequalZero <= '1'; else xPequalZero <= '0'; end if; --end process; register_P: process(clk) begin if clk' event and clk = '1' then if ce_P = '1' then xxP <= next_xxP; yyP <= next_yyP; end if; end if; end process; register_Q: process(clk) begin if clk' event and clk = '1' then if ce_Q = '1' then xQ <= next_xQ; yQ <= next_yQ; end if; end if; end process; main_component: EC_addition_doubling port map(xxP, yyP, xQ, yQ, clk, reset, start_operation, operation, xR, yR, operation_done); counter: process(clk) begin if clk' event and clk = '1' then if reset_counter = '1' then step_number <= conv_std_logic_vector(m, logm); elsif count_down = '1' then step_number <= step_number - 1; end if; end if; end process; with step_number select last_step <= '1' when "00000000", '0' when others; shift_register: process(clk) begin if clk'event and clk = '1' then if reset_counter = '1' then int_k <= k; elsif count_down = '1' then for i in 0 to m-2 loop int_k(i) <= int_k(i+1); end loop; int_k(m-1) <= '0'; end if; end if; end process; k_i <= int_k(0); control_unit: process(clk, reset, current_state) begin case current_state is when 0 to 1 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '1'; when 2 => ce_P <= '1'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '1'; count_down <= '0'; done <= '0'; Q_infinity <= '1'; when 3 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 4 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 5 => ce_P <= '0'; ce_Q <= '1'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; Q_infinity <= '0'; when 6 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '1'; start_operation <= '1'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 7 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '1'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 8 => ce_P <= '0'; ce_Q <= '1'; sel_P <= '0'; sel_Q <= '1'; operation <= '1'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 9 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '1'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 10 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 11 => ce_P <= '1'; ce_Q <= '0'; sel_P <= '1'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '0'; done <= '0'; when 12 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '1'; done <= '0'; when 13 => ce_P <= '0'; ce_Q <= '0'; sel_P <= '0'; sel_Q <= '0'; operation <= '0'; start_operation <= '0'; reset_counter <= '0'; count_down <= '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 k_i = '1' then current_state <= 4; else current_state <= 9; end if; when 4 => if Q_infinity = '1' then current_state <= 5; else current_state <= 6; end if; when 5 => current_state <= 9; when 6 => current_state <= 7; when 7 => if operation_done = '1' then current_state <= 8; end if; when 8 => current_state <= 9; when 9 => current_state <= 10; when 10 => if operation_done = '1' then current_state <= 11; end if; when 11 => current_state <= 12; when 12 => current_state <= 13; when 13 => if last_step = '1' then current_state <= 0; else current_state <= 3; end if; end case; end if; end process; end circuit;