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 k: integer := 32; constant logk: integer := 5; --constant exp_k: std_logic_vector(k-1 downto 0) := conv_std_logic_vector(17, k); constant exp_k: std_logic_vector(k-1 downto 0) := x"00000183"; --constant exp_2k: std_logic_vector(k-1 downto 0) := conv_std_logic_vector(50, k); constant exp_2k: std_logic_vector(k-1 downto 0) := x"00024909"; --constant p: std_logic_vector(k-1 downto 0) := conv_std_logic_vector(239, k); constant p: std_logic_vector(k-1 downto 0) := x"FFFFFE7D"; --constant p_minus2: std_logic_vector(k-1 downto 0) := conv_std_logic_vector(237, k); constant p_minus2: std_logic_vector(k-1 downto 0) := x"FFFFFE7B"; 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 data_path is port ( x, y: in std_logic_vector(k-1 downto 0); clk, load, shift, ce_product, clear_product: in std_logic; z: out std_logic_vector(k-1 downto 0) ); end data_path; architecture rtl of data_path is signal reg_x: std_logic_vector(k-1 downto 0); signal a, a_plus_p, dif: std_logic_vector(k+1 downto 0); signal product, next_product: std_logic_vector(k downto 0); signal x_i: std_logic; begin with x_i select a <= ('0'&product) + ("00"&y) when '1', ('0'&product) when others; with a(0) select a_plus_p <= a + ("00"&p) when '1', a when others; divide_by_2:for i in 0 to k generate next_product(i) <= a_plus_p(i+1); end generate; shift_register: process(clk) begin if clk'event and clk = '1' then if load = '1' then reg_x <= x; elsif shift = '1' then for i in 0 to k-2 loop reg_x(i) <= reg_x(i+1); end loop; reg_x(k-1) <= '0'; end if; end if; end process shift_register; x_i <= reg_x(0); register_product: process(clk) begin if clk'event and clk = '1' then if clear_product = '1' then product <= (others => '0'); elsif ce_product = '1' then product <= next_product; end if; end if; end process register_product; dif <= ('0'&product) - ("00"&p); with dif(k+1) select z <= product(k-1 downto 0) when '1', dif(k-1 downto 0) when others; end rtl; 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 algorithm4 is port ( x, y: in std_logic_vector(k-1 downto 0); clk, reset, start: in std_logic; done: out std_logic; z: out std_logic_vector(k-1 downto 0) ); end algorithm4; architecture circuit of algorithm4 is component data_path is port ( x, y: in std_logic_vector(k-1 downto 0); clk, load, shift, ce_product, clear_product: in std_logic; z: out std_logic_vector(k-1 downto 0) ); end component; signal load, shift, ce_product, clear_product: std_logic; signal count: std_logic_vector(logk-1 downto 0); subtype states is natural range 0 to 3; signal current_state: states; begin main_component: data_path port map(x, y, clk, load, shift, ce_product, clear_product, z); counter: process(clk) begin if clk'event and clk = '1' then if load = '1' then count <= conv_std_logic_vector(k-1, logk); elsif shift = '1' then count <= count-1; end if; end if; end process counter; control_unit: process(clk, reset, current_state, count) begin case current_state is when 0 to 1 => load <= '0'; shift <= '0'; ce_product <= '0'; clear_product <= '0'; done <= '1'; when 2 => load <= '1'; shift <= '0'; ce_product <= '0'; clear_product <= '1'; done <= '0'; when 3 => load <= '0'; shift <= '1'; ce_product <= '1'; clear_product <= '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 <= current_state + 1; end if; when 1 => if start = '1' then current_state <= current_state + 1; end if; when 2 => current_state <= current_state + 1; when 3 => if count = 0 then current_state <= 0; end if; end case; end if; end process; end circuit; 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 algorithm5 is port ( x, y: in std_logic_vector(k-1 downto 0); clk, reset, start: in std_logic; done: out std_logic; z: out std_logic_vector(k-1 downto 0) ); end algorithm5; architecture circuit of algorithm5 is component algorithm4 is port ( x, y: in std_logic_vector(k-1 downto 0); clk, reset, start: in std_logic; done: out std_logic; z: out std_logic_vector(k-1 downto 0) ); end component; signal first_operand, second_operand, mp, Tx, Ty, e: std_logic_vector(k-1 downto 0); signal sel: std_logic_vector(2 downto 0); signal first_step, ce_Tx, ce_Ty, ce_e, start_mp, done_mp, load, shift: std_logic; signal count: std_logic_vector(logk-1 downto 0); subtype states is natural range 0 to 20; signal current_state: states; begin with sel select first_operand <= y when "000", x when "001", e when others; with sel select second_operand <= exp_2k when "000"|"001", e when "010", Ty when "011", Tx when "100", conv_std_logic_vector(1, k) when others; main_component: algorithm4 port map(first_operand, second_operand, clk, reset, start_mp, done_mp, mp); register_e: process(clk) begin if clk'event and clk = '1' then if first_step = '1' then e <= exp_k; elsif ce_e = '1' then e <= mp; end if; end if; end process register_e; register_Tx: process(clk) begin if clk'event and clk = '1' then if ce_Tx = '1' then Tx <= mp; end if; end if; end process register_Tx; register_Ty: process(clk) begin if clk'event and clk = '1' then if ce_Ty = '1' then Ty <= mp; end if; end if; end process register_Ty; counter: process(clk) begin if clk'event and clk = '1' then if load = '1' then count <= conv_std_logic_vector(k-1, logk); elsif shift = '1' then count <= count-1; end if; end if; end process counter; control_unit: process(clk, reset, current_state, count) begin case current_state is when 0 to 1 => sel <= "000"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '1'; when 2 => sel <= "000"; start_mp <= '1'; first_step <= '1'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 3 => sel <= "000"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 4 => sel <= "000"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '1'; load <= '0'; shift <= '0'; done <= '0'; when 5 => sel <= "001"; start_mp <= '1'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 6 => sel <= "001"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 7 => sel <= "001"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '1'; ce_Ty <= '0'; load <= '1'; shift <= '0'; done <= '0'; when 8 => sel <= "010"; start_mp <= '1'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 9 => sel <= "010"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 10 => sel <= "010"; start_mp <= '0'; first_step <= '0'; ce_e <= '1'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 11 => sel <= "011"; start_mp <= '1'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 12 => sel <= "011"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 13 => sel <= "011"; start_mp <= '0'; first_step <= '0'; ce_e <= '1'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 14 => sel <= "010"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '1'; done <= '0'; when 15 => sel <= "100"; start_mp <= '1'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 16 => sel <= "100"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 17 => sel <= "100"; start_mp <= '0'; first_step <= '0'; ce_e <= '1'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 18 => sel <= "101"; start_mp <= '1'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 19 => sel <= "101"; start_mp <= '0'; first_step <= '0'; ce_e <= '0'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '0'; done <= '0'; when 20 => sel <= "101"; start_mp <= '0'; first_step <= '0'; ce_e <= '1'; ce_Tx <= '0'; ce_Ty <= '0'; load <= '0'; shift <= '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 <= current_state + 1; end if; when 1 => if start = '1' then current_state <= current_state + 1; end if; when 2 => current_state <= current_state + 1; when 3 => if done_mp = '1' then current_state <= current_state + 1; end if; when 4 => current_state <= current_state + 1; when 5 => current_state <= current_state + 1; when 6 => if done_mp = '1' then current_state <= current_state + 1; end if; when 7 => current_state <= current_state + 1; when 8 => current_state <= current_state + 1; when 9 => if done_mp = '1' then current_state <= current_state + 1; end if; when 10 => if p_minus2(conv_integer(count)) = '1' then current_state <= current_state + 1; else current_state <= 14; end if; when 11 => current_state <= current_state + 1; when 12 => if done_mp = '1' then current_state <= current_state + 1; end if; when 13 => current_state <= current_state + 1; when 14 => if count = 0 then current_state <= current_state + 1; else current_state <= 8; end if; when 15 => current_state <= current_state + 1; when 16 => if done_mp = '1' then current_state <= current_state + 1; end if; when 17 => current_state <= current_state + 1; when 18 => current_state <= current_state + 1; when 19 => if done_mp = '1' then current_state <= current_state + 1; end if; when 20 => current_state <= 0; end case; end if; end process; z <= e; end circuit;