---------------------------------------------------------------------------- -- Point multiplication in K233 (K233_point_multiplication.vhd) -- -- Uses the entities K233_addition and two classic squarer -- ---------------------------------------------------------------------------- ------------------------------------------------------------ -- K233_package ------------------------------------------------------------ library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; package K233_package is constant m: natural := 233; constant zero: std_logic_vector(m-1 downto 0) := (others => '0'); end K233_package; ------------------------------------------------------------ -- K233_point_multiplication ------------------------------------------------------------ library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.K233_package.all; entity K233_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); done: out std_logic ); end K233_point_multiplication; architecture circuit of K233_point_multiplication is component K233_addition is port( x1, y1, x2, y2: in std_logic_vector(m-1 downto 0); clk, reset, start: in std_logic; x3: inout std_logic_vector(m-1 downto 0); y3: out std_logic_vector(m-1 downto 0); done: out std_logic ); end component; component classic_squarer is port ( a: in std_logic_vector(M-1 downto 0); c: out std_logic_vector(M-1 downto 0) ); end component; signal a, next_a, a_div_2: std_logic_vector(m downto 0); signal b, next_b: std_logic_vector(m-1 downto 0); signal xxP, yyP, next_xQ, next_yQ, xxPxoryyP, square_xxP, square_yyP, y1, x3, y3: std_logic_vector(m-1 downto 0); signal ce_P, ce_Q, ce_ab, load, sel_1, start_addition, addition_done, carry, Q_infinity, aEqual0, bEqual0, a1xorb0: std_logic; signal sel_2: std_logic_vector(1 downto 0); subtype states is natural range 0 to 12; signal current_state: states; begin xor_gates: for i in 0 to m-1 generate xxPxoryyP(i) <=xxP(i) xor yyP(i); end generate; with sel_1 select y1 <= yyP when '0', xxPxoryyP when others; with sel_2 select next_yQ <= y3 when "00", yyP when "01", xxPxoryyP when others; with sel_2 select next_xQ <= x3 when "00", xxP when others; first_component: K233_addition port map( x1 => xxP, y1 => y1, x2 => xQ, y2 => yQ, clk => clk, reset => reset, start => start_addition, x3 => x3, y3 => y3, done => addition_done); second_component: classic_squarer port map( a => xxP, c => square_xxP); third_component: classic_squarer port map( a => yyP, c => square_yyP); register_P: process(clk) begin if clk' event and clk = '1' then if load = '1' then xxP <= xP; yyP <= yP; elsif ce_P = '1' then xxP <= square_xxP; yyP <= square_yyP; end if; end if; end process; register_Q: process(clk) begin if clk' event and clk = '1' then if load = '1' then Q_infinity <= '1'; elsif ce_Q = '1' then xQ <= next_xQ; yQ <= next_yQ; Q_infinity <= '0'; end if; end if; end process; divide_by_2: for i in 0 to m-1 generate a_div_2(i) <= a(i+1);end generate; a_div_2(m) <= a(m); next_a <= (b(m-1)&b) - (a_div_2 + carry); next_b <= zero - (a_div_2(m-1 downto 0) + carry); register_ab: process(clk) begin if clk' event and clk = '1' then if load = '1' then a <= ('0'&k); b <= zero; elsif ce_ab = '1' then a <= next_a; b <= next_b; end if; end if; end process; aEqual0 <= '1' when a = 0 else '0'; bEqual0 <= '1' when b = 0 else '0'; a1xorb0 <= a(1) xor b(0); control_unit: process(clk, reset, current_state, addition_done, aEqual0, bEqual0, a(0), a1xorb0, Q_infinity) begin case current_state is when 0 to 1 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '0'; done <= '1'; when 2 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '1'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '0'; done <= '0'; when 3 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '0'; done <= '0'; when 4 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '1'; ce_Q <= '0'; ce_ab <= '1'; start_addition <= '0'; done <= '0'; when 5 => sel_1 <= '0'; sel_2 <= "01"; carry <= '0'; load <= '0'; ce_P <= '1'; ce_Q <= '1'; ce_ab <= '1'; start_addition <= '0'; done <= '0'; when 6 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '1'; done <= '0'; when 7 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '0'; done <= '0'; when 8 => sel_1 <= '0'; sel_2 <= "00"; carry <= '0'; load <= '0'; ce_P <= '1'; ce_Q <= '1'; ce_ab <= '1'; start_addition <= '0'; done <= '0'; when 9 => sel_1 <= '1'; sel_2 <= "10"; carry <= '1'; load <= '0'; ce_P <= '1'; ce_Q <= '1'; ce_ab <= '1'; start_addition <= '0'; done <= '0'; when 10 => sel_1 <= '1'; sel_2 <= "00"; carry <= '1'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '1'; done <= '0'; when 11 => sel_1 <= '1'; sel_2 <= "00"; carry <= '1'; load <= '0'; ce_P <= '0'; ce_Q <= '0'; ce_ab <= '0'; start_addition <= '0'; done <= '0'; when 12 => sel_1 <= '1'; sel_2 <= "00"; carry <= '1'; load <= '0'; ce_P <= '1'; ce_Q <= '1'; ce_ab <= '1'; start_addition <= '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 (aEqual0 = '1') and (bEqual0 = '1') then current_state <= 0; elsif a(0) = '0' then current_state <= 4; elsif (a1xorb0 = '0') and (Q_infinity = '1') then current_state <= 5; elsif (a1xorb0 = '0') and (Q_infinity = '0') then current_state <= 6; elsif (a1xorb0 = '1') and (Q_infinity = '1') then current_state <= 9; else current_state <= 10; end if; when 4 => current_state <= 3; when 5 => current_state <= 3; when 6 => current_state <= 7; when 7 => if addition_done = '1' then current_state <= 8; end if; when 8 => current_state <= 3; when 9 => current_state <= 3; when 10 => current_state <= 11; when 11 => if addition_done = '1' then current_state <= 12; end if; when 12 => current_state <= 3; end case; end if; end process; end circuit;