----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07.05.2024 15:12:04
-- Design Name:
-- Module Name: Point_multx - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Point_mult is
GENERIC (
wid : INTEGER := 256
);
PORT(
Px : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
Py : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
d : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
start : IN STD_LOGIC;
Rx : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
Ry : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
done : OUT STD_LOGIC
);
end Point_mult;
architecture Behavioral of Point_mult is
component Point_double is
GENERIC (
wid : INTEGER := 256
);
PORT(
Px : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
Py : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
start : IN STD_LOGIC;
Rx : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
Ry : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
done : OUT STD_LOGIC
);
end component;
component Point_add is
GENERIC (
wid : INTEGER := 256
);
PORT(
Px : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
Py : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
Qx : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
Qy : IN STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
start : IN STD_LOGIC;
Rx : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
Ry : OUT STD_LOGIC_VECTOR(wid - 1 downto 0);
done : OUT STD_LOGIC
);
end component;
signal tmp_d: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal res_x: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal res_y: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal tmp_x: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal tmp_y: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal dbl_x: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal dbl_y: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal dbl_start : STD_LOGIC;
signal dbl_done : STD_LOGIC;
signal add_x: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal add_y: STD_LOGIC_VECTOR(wid - 1 DOWNTO 0);
signal add_start : STD_LOGIC;
signal add_done : STD_LOGIC;
signal i : integer range 0 to 255;
signal bt : STD_LOGIC;
type state_type is (idle, prep, shift, op_dbl, wait_dbl, get_dbl, op_add, wait_add,
get_add, fin);
signal state_reg, state_next : state_type;
begin
bt <= tmp_d(i);
process(clk, rst)
begin
if (rst='1') then
state_reg <= idle;
elsif (clk'event and clk='1') then
state_reg <= state_next;
end if;
end process;
process(state_reg, start, tmp_d, bt, i, dbl_done, add_done)
begin
case state_reg is
when idle =>
if ( start='1' ) then
state_next <= prep;
else
state_next <= idle;
end if;
when prep =>
if (bt = '1') then
state_next <= op_dbl;
else
state_next <= prep;
end if;
when op_dbl =>
state_next <= wait_dbl;
when wait_dbl =>
if (dbl_done = '1') then
state_next <= get_dbl;
else
state_next <= wait_dbl;
end if;
when get_dbl =>
if ( bt = '1' ) then
state_next <= op_add;
else
state_next <= shift;
end if;
when op_add =>
state_next <= wait_add;
when wait_add =>
if (add_done = '1') then
state_next <= get_add;
else
state_next <= wait_add;
end if;
when get_add =>
state_next <= shift;
when shift =>
if (i = 0) then
state_next <= fin;
else
state_next <= op_dbl;
end if;
when fin =>
state_next <= idle;
end case;
end process;
process(clk, state_reg)
begin
if (rising_edge(clk)) then
if (state_reg = fin) then
done <= '1';
else
done <= '0';
end if;
end if;
end process;
process(clk, rst, state_reg, bt, i)
begin
if (rst='1') then
i <= 255;
elsif (clk'event and clk='1') then
if (state_reg = prep) then
i <= i - 1;
elsif (state_reg = shift and i > 0) then
i <= i - 1;
end if;
end if;
end process;
process(clk, state_reg)
begin
if (rising_edge(clk)) then
if (rst='1') then
Rx <= (others => '0');
Ry <= (others => '0');
elsif (state_reg = fin) then
Rx <= res_x;
Ry <= res_y;
end if;
end if;
end process;
process(state_reg, Px, Py, d)
begin
if (state_reg = idle) then
res_x <= Px;
res_y <= Py;
tmp_x <= Px;
tmp_y <= Py;
tmp_d <= d;
elsif (state_reg = get_add) then
res_x <= add_x;
res_y <= add_y;
elsif (state_reg = get_dbl) then
res_x <= dbl_x;
res_y <= dbl_y;
end if;
end process;
process(state_reg)
begin
if (state_reg = op_add) then
add_start <= '1';
else
add_start <= '0';
end if;
end process;
process(state_reg)
begin
if (state_reg = op_dbl) then
dbl_start <= '1';
else
dbl_start <= '0';
end if;
end process;
Point_double_b: Point_double
GENERIC map(
wid => wid
)
PORT map(
Px => res_x,
Py => res_y,
clk => clk,
rst => rst,
start => dbl_start,
Rx => dbl_x,
Ry => dbl_y,
done => dbl_done
);
Point_add_b: Point_add
GENERIC map(
wid => wid
)
PORT map(
Px => res_x,
Py => res_y,
Qx => tmp_x,
Qy => tmp_y,
clk => clk,
rst => rst,
start => add_start,
Rx => add_x,
Ry => add_y,
done => add_done
);
end Behavioral;