---------------------------------------------------------------------------- -- Carry Save adder Modular Multiplier (csa_mod_multiplier.vhd) -- -- Multiply and Reduce modular multiplier using CSA -- -- Three entities are declared: -- - modified_csa_multiplier -- - modified_srt_reducer -- - csa_mod_multiplier ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; package csa_mod_multiplier_parameters is constant K: natural := 8; constant N: natural := 2*K; constant logK: natural := 3; constant ZERO1: std_logic_vector(logK-1 downto 0) := (others => '0'); constant counter_size: natural := 4; constant ZERO2: std_logic_vector(counter_size-1 downto 0) := (others => '0'); end csa_mod_multiplier_parameters; ---------------------------------------------------------------------------- -- modified_csa_multiplier ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.csa_mod_multiplier_parameters.all; entity modified_csa_multiplier is port ( x, y: in std_logic_vector (K-1 downto 0); clk, reset, start: in std_logic; ps, pc, p: inout std_logic_vector (K-1 downto 0); done: out std_logic ); end modified_csa_multiplier; architecture rtl of modified_csa_multiplier is signal next_s, y_by_xi: std_logic_vector(k-1 downto 0); signal next_c: std_logic_vector(K downto 1); signal load, update, equal_zero: std_logic; signal count: std_logic_vector(logk-1 downto 0); type states is range 0 to 3; signal current_state: states; begin csa: for i in 0 to k-1 generate next_s(i) <= ps(i) xor pc(i) xor y_by_xi(i); next_c(i+1) <= (ps(i) and pc(i)) or (ps(i) and y_by_xi(i)) or (pc(i) and y_by_xi(i)) ; end generate; and_gates: for i in 0 to k-1 generate y_by_xi(i) <= y(i) and p(0); end generate; --sum <= ps + pc; --z <= sum&p; registers: process(clk) begin if clk'event and clk = '1' then if load = '1' then ps <= (others => '0'); pc <= (others => '0'); p <= x; elsif update = '1' then ps <= '0' & next_s(K-1 downto 1); pc <= next_c(k)& next_c(K-1 downto 1); p <=next_s(0) & p(K-1 downto 1); end if; end if; end process; counter: process(clk) begin if clk'event and clk = '1' then if load = '1' then count <= conv_std_logic_vector(K-1, logK); elsif update = '1' then count <= count-1; end if; end if; end process counter; with count select equal_zero <= '1' when ZERO1, '0' when others; control_unit: process(clk, reset, current_state, equal_zero) begin case current_state is when 0 to 1 => load <= '0'; update <= '0'; done <= '1'; when 2 => load <= '1'; update <= '0'; done <= '0'; when 3 => load <= '0'; update <= '1'; 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 equal_zero = '1' then current_state <= 0; end if; end case; end if; end process; end rtl; ---------------------------------------------------------------------------- -- modified_srt_reducer ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.csa_mod_multiplier_parameters.all; entity modified_srt_reducer is port ( ps, pc, p: in std_logic_vector (K-1 downto 0); m: in std_logic_vector(K-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector (K-1 downto 0); done: out std_logic ); end modified_srt_reducer; architecture rtl of modified_srt_reducer is signal ss: std_logic_vector(N+1 downto 0); signal sc: std_logic_vector(N+1 downto N-K); signal rs: std_logic_vector(N downto 0); signal rc: std_logic_vector(N downto N-K+1); signal r, minus_m, w: std_logic_vector(K downto 0); signal not_m: std_logic_vector(K-1 downto 0); signal load, update, equal_zero: std_logic; signal t: std_logic_vector(2 downto 0); signal quotient: std_logic_vector(1 downto 0); signal count: std_logic_vector(counter_size -1 downto 0); type states is range 0 to 3; signal current_state: states; begin csa: for i in n-k to n-1 generate rs(i) <= ss(i) xor sc(i) xor w(i-n+k); rc(i+1) <= (ss(i) and sc(i)) or (ss(i) and w(i-n+k)) or (sc(i) and w(i-n+k)) ; end generate; rs(n) <= ss(n) xor sc(n) xor w(k); rs(n-k-1 downto 0) <= ss(n-k-1 downto 0); r(0) <= rs(n-k); r(k downto 1) <= rs(n downto n-k+1) + rc(n downto n-k+1); with r(k) select z <= r(k-1 downto 0) when '0', r(k-1 downto 0) + m when others; registers: process(clk) begin if clk'event and clk = '1' then --if load = '1' then ss <= x(n)&x; sc <= (others => '0'); if load = '1' then ss <= ("00" & ps) & p; sc <= "00" & pc; elsif update = '1' then ss(0) <= '0'; for i in 1 to n+1 loop ss(i) <= rs(i-1); end loop; sc(n-k) <= '0'; sc(n-k+1) <= '0'; for i in n-k+2 to n+1 loop sc(i) <= rc(i-1); end loop; end if; end if; end process registers; counter: process(clk) begin if clk'event and clk = '1' then if load = '1' then count <= conv_std_logic_vector(N-K-1, counter_size); elsif update = '1' then count <= count-1; end if; end if; end process counter; with count select equal_zero <= '1' when ZERO2, '0' when others; t <= ss(n+1 downto n-1) + sc(n+1 downto n-1); quotient(1) <= t(2) xor (t(1) and t(0)); quotient(0) <= not(t(2) and t(1) and t(0)); not_gates: for i in 0 to k-1 generate not_m(i) <= not(m(i)); end generate; minus_m <= ('1' & not_m) +1; with quotient select w <= minus_m when "01", ('0'& m) when "11", (others => '0') when others; control_unit: process(clk, reset, current_state, equal_zero) begin case current_state is when 0 to 1 => load <= '0'; update <= '0'; done <= '1'; when 2 => load <= '1'; update <= '0'; done <= '0'; when 3 => load <= '0'; update <= '1'; 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 equal_zero = '1' then current_state <= 0; end if; end case; end if; end process; end rtl; ---------------------------------------------------------------------------- -- csa_mod_multiplier ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.csa_mod_multiplier_parameters.all; entity csa_mod_multiplier is port ( x, y, m: in std_logic_vector(K-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector(K-1 downto 0); done: inout std_logic ); end csa_mod_multiplier; architecture circuit of csa_mod_multiplier is component modified_csa_multiplier is port ( x, y: in std_logic_vector (K-1 downto 0); clk, reset, start: in std_logic; ps, pc, p: inout std_logic_vector (K-1 downto 0); done: out std_logic ); end component; component modified_srt_reducer is port ( ps, pc, p: in std_logic_vector (K-1 downto 0); m: in std_logic_vector(K-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector (K-1 downto 0); done: out std_logic ); end component; signal ps, pc, p: std_logic_vector (K-1 downto 0); signal done1, start1, done2, start2: std_logic; type states is range 0 to 4; signal current_state: states; begin first_step: modified_csa_multiplier port map(x => x, y => y, clk=> clk, reset => reset, start => start1, ps => ps, pc => pc, p => p, done => done1); second_step: modified_srt_reducer port map(ps => ps, pc => pc, p => p, m => m, clk => clk, reset => reset, start => start2, z => z, done => done2); control_unit: process(clk, reset) begin case current_state is when 0 to 1 => done <= '1'; start2 <= '0'; when 2 => done <= '0'; start2 <= '0'; when 3 => done <= '0'; start2 <= '1'; when 4 => done <= '0'; start2 <= '0'; end case; start1 <= start; 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 => if done1 = '1' then current_state <= 3; end if; when 3 => current_state <= 4; when 4 => if done2 = '1' then current_state <= 0; end if; end case; end if; end process; end circuit;