Предложу пример модуля работы с плавающей точкой.
Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity matem is
Port ( clk40 : in STD_LOGIC;
clk160 : in STD_LOGIC;
iowr : in STD_LOGIC;
st : in STD_LOGIC;
addr : in STD_LOGIC_VECTOR (31 downto 0);
data : in STD_LOGIC_VECTOR (31 downto 0);
dq : out STD_LOGIC_VECTOR (31 downto 0)
);
end matem;
architecture Behavioral of matem is
signal ma, mb, madd, mmult, mdiv, f_to_s, s_to_f, msqrt : std_logic_VECTOR(31 downto 0);
signal mampl, matan: std_logic_vector(31 downto 0);
signal mcmp_int: std_logic_VECTOR(0 downto 0);
signal mcmp: std_logic_vector(31 downto 0);
signal op: std_logic_vector(5 downto 0);
component f_add
port (
a: IN std_logic_VECTOR(31 downto 0);
b: IN std_logic_VECTOR(31 downto 0);
operation: in std_logic_vector(5 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(31 downto 0));
end component;
component f_cmp
port (
a: IN std_logic_VECTOR(31 downto 0);
b: IN std_logic_VECTOR(31 downto 0);
operation: in std_logic_vector(5 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(0 downto 0));
end component;
component f_mult
port (
a: IN std_logic_VECTOR(31 downto 0);
b: IN std_logic_VECTOR(31 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(31 downto 0));
end component;
component s_f
port (
a: IN std_logic_VECTOR(31 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(31 downto 0));
end component;
component f_s
port (
a: IN std_logic_VECTOR(31 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(31 downto 0));
end component;
component f_div
port (
a: IN std_logic_VECTOR(31 downto 0);
b: IN std_logic_VECTOR(31 downto 0);
clk: IN std_logic;
result: OUT std_logic_VECTOR(31 downto 0));
end component;
begin
fadd : f_add
port map (
a => ma,
b => mb,
operation => op,
clk => clk160,
result => madd);
fcmp : f_cmp
port map (
a => ma,
b => mb,
operation => op,
clk => clk160,
result => mcmp_int);
fmult : f_mult
port map (
a => ma,
b => mb,
clk => clk160,
result => mmult);
sf : s_f
port map (
a => ma,
clk => clk160,
result => s_to_f);
fsa : f_s
port map (
a => ma,
clk => clk160,
result => f_to_s);
fdiv : f_div
port map (
a => ma,
b => mb,
clk => clk160,
result => mdiv);
process(clk40)
begin
if rising_edge(clk40) then
if iowr = '1' and conv_integer(addr) = 1505 then ma <= data; end if;
if iowr = '1' and conv_integer(addr) = 1506 then mb <= data; end if;
if iowr = '1' and conv_integer(addr) = 1507 then op <= data(5 downto 0); end if;
end if;
end process;
mcmp <= x"FFFFFFFF" when mcmp_int = "1" else x"00000000";
with conv_integer(addr) select
dq <= madd when 1500,
mmult when 1501,
mdiv when 1502,
f_to_s when 1503,
s_to_f when 1504,
mcmp when 1505,
(others => 'Z') when others;
end Behavioral;
Использовался модуль как математический сопроцессор (хотя управляться он может как угодно) рядом с самописным процессором.
Плавающая точка реализована набором IP-ядер, формат выбран Single (одинарная точность).
f_to_s - преобразование из плавающего в целое. s_to_f - наоборот.
Управляется модуль системной шиной, которая реализована в виде 4 линий. Адреса (addr), Данных (data), ВыходныхДанных (dq), СигналаЗаписи (iowr).
Для записи операндов в модуль выставляем нужный адресс (if iowr = '1' and conv_integer(addr) = 1505 then ma <= data; end if;), например 1505 для операнда A и поднимаем в 1 сигнал iowr.
Для чтения просто выставляем адресс и читаем линию dq.
Посмотрите даташиты на эти модули, чтобы лучше понять, как они работают (например, разобраться что делает линия operation тут). При генерации любого IP-ядра, где то рядом есть кнопочка "datasheet" или что-то подобное.