library ieee; use ieee.std_logic_1164.all; package mypackage is constant n: natural := 8; constant m: natural := 239; constant c: natural := 17; constant zero: std_logic_vector(n-1 downto 0) := ('0', others => '0'); end mypackage; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.mypackage.all; entity data_path is port (x: in std_logic_vector(2*n-1 downto 0); clk, sel, enable: in std_logic; z: out std_logic_vector(n-1 downto 0); equal_zero: out std_logic ); end data_path; architecture circuit of data_path is signal next_x1, next_x0, x1, x0, y1, y0: std_logic_vector(n-1 downto 0); signal x1_by_c, long_x0, y: std_logic_vector(2*n-1 downto 0); signal long_y0, minus_m, y0_minus_m: std_logic_vector(n downto 0); begin with sel select next_x1 <= y1 when '0', x(2*n-1 downto n) when others; with sel select next_x0 <= y0 when '0', x(n-1 downto 0) when others; process(clk) begin if clk'event and clk = '1' then if enable = '1' then x1 <= next_x1; x0 <= next_x0; end if; end if; end process; x1_by_c <= x1 * conv_std_logic_vector(c, n); long_x0 <= zero&x0; y <= x1_by_c + long_x0; y1 <= y(2*n-1 downto n); y0 <= y(n-1 downto 0); equal_zero <= '1' when y1 = zero else '0'; long_y0 <= '0'&y0; minus_m <= conv_std_logic_vector(2**n - m, n+1); y0_minus_m <= long_y0 + minus_m; with y0_minus_m(n) select z <= y0_minus_m(n-1 downto 0) when '1', y0 when others; end circuit; library ieee; use ieee.std_logic_1164.all; entity control_unit is port (clk, reset, start, equal_zero: in std_logic; done, sel, enable: out std_logic ); end control_unit; architecture rtl of control_unit is subtype internal_state is natural range 0 to 3; signal state: internal_state; begin process(clk, reset) begin case state is when 0 => sel <= '1'; enable <= '0'; done <= '1'; when 1 => sel <= '1'; enable <= '0'; done <= '1'; when 2 => sel <= '1'; enable <= '1'; done <= '0'; when 3 => sel <= '0'; enable <= '1'; done <= '0'; end case; if reset = '1' then state <= 0 ; elsif clk'event and clk = '1' then case state is when 0 => if start = '0' then state <= state + 1; end if; when 1 => if start = '1' then state <= state + 1; end if; when 2 => state <= state + 1; when 3 => if equal_zero = '1' then state <= 0;end if; end case; end if; end process; end rtl; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.mypackage.all; entity mod_reduction is port (x: in std_logic_vector(2*n-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector(n-1 downto 0); done: out std_logic ); end mod_reduction; architecture circuit of mod_reduction is component data_path port (x: in std_logic_vector(2*n-1 downto 0); clk, sel, enable: in std_logic; z: out std_logic_vector(n-1 downto 0); equal_zero: out std_logic ); end component; component control_unit port (clk, reset, start, equal_zero: in std_logic; done, sel, enable: out std_logic ); end component; signal sel, enable, equal_zero: std_logic; begin component1: data_path port map(x, clk, sel, enable, z, equal_zero); component2: control_unit port map(clk, reset, start, equal_zero, done, sel, enable); end circuit; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.mypackage.all; entity test_mod_reduction is end test_mod_reduction; architecture test of test_mod_reduction is component mod_reduction port (x: in std_logic_vector(2*n-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector(n-1 downto 0); done: out std_logic ); end component; signal a, b: std_logic_vector(n-1 downto 0); signal x: std_logic_vector(2*n-1 downto 0); signal z: std_logic_vector(n-1 downto 0); signal clk, reset, start, done: std_logic := '0'; begin clk <= not(clk) after 10 ns; device_under_test: mod_reduction port map(x, clk, reset, start, z, done); a <= conv_std_logic_vector(227, n), conv_std_logic_vector(14, n) after 100 ns, conv_std_logic_vector(210, n) after 200 ns, conv_std_logic_vector(45, n) after 300 ns, conv_std_logic_vector(0, n) after 400 ns, conv_std_logic_vector(238, n) after 500 ns, conv_std_logic_vector(238, n) after 600 ns; b <= conv_std_logic_vector(198, n), conv_std_logic_vector(211, n) after 100 ns, conv_std_logic_vector(46, n) after 200 ns, conv_std_logic_vector(126, n) after 300 ns, conv_std_logic_vector(0, n) after 400 ns, conv_std_logic_vector(0, n) after 500 ns, conv_std_logic_vector(238, n) after 600 ns; x <= a*b; reset <= '1', '0' after 10 ns; start <= '0', '1' after 20 ns, '0' after 50 ns, '1' after 120 ns, '0' after 150 ns, '1' after 220 ns, '0' after 250 ns, '1' after 320 ns, '0' after 350 ns, '1' after 420 ns, '0' after 450 ns, '1' after 520 ns, '0' after 550 ns, '1' after 620 ns, '0' after 650 ns; end test;