Почему внутренние компоненты не выполняются

Итак, я создал иерархический дизайн компонентов в VHDL. Объект верхнего уровня на данный момент является следующим.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

--This component takes 2 numbers written in scientific notation and returns the same numbers with the same exponent

entity exp_equalizer is

    generic(
        TOTAL_BITS : natural := 23;
        EXP_BITS   : natural := 6
    );

    port(
        man_1_in   : in  std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0);
        exp_1_in   : in  std_logic_vector(EXP_BITS - 1 downto 0);
        man_2_in   : in  std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0);
        exp_2_in   : in  std_logic_vector(EXP_BITS - 1 downto 0);
        man_1_out  : out std_logic_vector((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto 0); --extended precision
        man_2_out  : out std_logic_vector((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto 0);
        exp_out    : out std_logic_vector(EXP_BITS - 1 downto 0);
        difference : out unsigned(EXP_BITS - 1 downto 0)
    );
end exp_equalizer;

architecture exp_equalizer_arq of exp_equalizer is

    signal exp_1            : std_logic_vector(EXP_BITS - 1 downto 0)              := (others => '0');
    signal exp_2            : std_logic_vector(EXP_BITS - 1 downto 0)              := (others => '0');
    signal man_1            : std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0) := (others => '0');
    signal man_2            : std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0) := (others => '0');
    signal comparer_greater : std_logic                                            := '0';
    signal comparer_smaller : std_logic                                            := '1';
    signal smaller_exp      : std_logic_vector(EXP_BITS - 1 downto 0)              := (others => '0');
    signal greater_exp      : std_logic_vector(EXP_BITS - 1 downto 0)              := (others => '0');
    signal smaller_man      : std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0) := (others => '1');
    signal greater_man      : std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0) := (others => '1');

    component comparer is
        generic(
            BITS : natural := 16
        );

        port(
            number1_in     : in  std_logic_vector(BITS - 1 downto 0);
            number2_in     : in  std_logic_vector(BITS - 1 downto 0);
            first_greater  : out std_logic;
            second_greater : out std_logic;
            equals         : out std_logic
        );

    end component;

    component binary_multiplexer is
        generic(
            BITS : natural := 16
        );
        port(
            number1_in : in  std_logic_vector(BITS - 1 downto 0);
            number2_in : in  std_logic_vector(BITS - 1 downto 0);
            chooser    : in  std_logic;
            mux_output : out std_logic_vector(BITS - 1 downto 0)
        );
    end component;

    for greater_exp_mux : binary_multiplexer use entity work.binary_multiplexer;
    for smaller_exp_mux : binary_multiplexer use entity work.binary_multiplexer;
    for greater_man_mux : binary_multiplexer use entity work.binary_multiplexer;
    for smaller_man_mux : binary_multiplexer use entity work.binary_multiplexer;
    for comparer_0 : comparer use entity work.comparer;

begin

    comparer_0 : comparer
        generic map(BITS => EXP_BITS)
        port map(
            first_greater  => comparer_smaller,
            second_greater => comparer_greater,
            number1_in     => exp_1,
            number2_in     => exp_2,
            equals => open
        );

    greater_exp_mux : binary_multiplexer
        generic map(BITS => EXP_BITS)
        port map(
            chooser    => comparer_greater,
            number1_in => exp_1,
            number2_in => exp_2,
            mux_output => greater_exp
        );

    smaller_exp_mux : binary_multiplexer
        generic map(BITS => EXP_BITS)
        port map(
            chooser    => comparer_smaller,
            number1_in => exp_1,
            number2_in => exp_2,
            mux_output => smaller_exp
        );

    greater_man_mux : binary_multiplexer
        generic map(BITS => TOTAL_BITS - EXP_BITS - 1)
        port map(
            chooser    => comparer_greater,
            number1_in => man_1,
            number2_in => man_2,
            mux_output => greater_man
        );

    smaller_man_mux : binary_multiplexer
        generic map(BITS => TOTAL_BITS - EXP_BITS - 1)
        port map(
            chooser    => comparer_smaller,
            number1_in => man_1,
            number2_in => man_2,
            mux_output => smaller_man
        );

    process(exp_1, exp_2, man_1, man_2, comparer_greater, comparer_smaller, smaller_exp, greater_exp, smaller_man, greater_man) is
        variable shifting_difference  : unsigned(EXP_BITS - 1 downto 0)                                := (others => '0');
        variable extended_man_greater : std_logic_vector((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto 0) := (others => '0');
        variable extended_man_smaller : std_logic_vector((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto 0) := (others => '0');
    begin
        exp_1 <= exp_1_in;
        exp_2 <= exp_2_in;
        extended_man_greater((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto (TOTAL_BITS - EXP_BITS - 1)) := greater_man;
        extended_man_smaller((TOTAL_BITS - EXP_BITS - 1) * 2 - 1 downto (TOTAL_BITS - EXP_BITS - 1)) := smaller_man;
        shifting_difference := unsigned(greater_exp) - unsigned(smaller_exp);
        man_1_out <= std_logic_vector(shift_right(unsigned(extended_man_smaller), to_integer(shifting_difference)));
        man_2_out <= extended_man_greater;
        exp_out <= greater_exp;
    end process;

end architecture;

И я тестирую его с помощью этого тестового стенда

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity exp_equalizer_tb is
end entity;

architecture exp_equalizer_tb_arq of exp_equalizer_tb is

    signal man_1_in   : std_logic_vector(15 downto 0) := (others => '0');
    signal exp_1_in   : std_logic_vector(5 downto 0)  := (others => '0');
    signal man_2_in   : std_logic_vector(15 downto 0) := (others => '0');
    signal exp_2_in   : std_logic_vector(5 downto 0)  := (others => '0');
    signal man_1_out  : std_logic_vector(31 downto 0) := (others => '0');
    signal man_2_out  : std_logic_vector(31 downto 0) := (others => '0');
    signal exp_out    : std_logic_vector(5 downto 0)  := (others => '0');
    signal difference : unsigned(5 downto 0) := "000000";

    component exp_equalizer is
        generic(
            TOTAL_BITS : natural := 23;
            EXP_BITS   : natural := 6
        );

        port(
            man_1_in   : in  std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0);
            exp_1_in   : in  std_logic_vector(EXP_BITS - 1 downto 0);
            man_2_in   : in  std_logic_vector(TOTAL_BITS - EXP_BITS - 2 downto 0);
            exp_2_in   : in  std_logic_vector(EXP_BITS - 1 downto 0);
            man_1_out  : out std_logic_vector((TOTAL_BITS - EXP_BITS - 2) * 2 + 1 downto 0); --extended precision
            man_2_out  : out std_logic_vector((TOTAL_BITS - EXP_BITS - 2) * 2 + 1 downto 0);
            exp_out    : out std_logic_vector(EXP_BITS - 1 downto 0);
            difference : out unsigned(EXP_BITS - 1 downto 0)
        );
    end component;
    for exp_equalizer_0 : exp_equalizer use entity work.exp_equalizer;

begin

    exp_equalizer_0 : exp_equalizer
        generic map(TOTAL_BITS => 23, EXP_BITS => 6)
        port map(
            exp_1_in   => exp_1_in,
            exp_2_in   => exp_2_in,
            man_1_in   => man_1_in,
            man_2_in   => man_2_in,
            exp_out    => exp_out,
            man_1_out  => man_1_out,
            man_2_out  => man_2_out,
            difference => difference
        );

    process
        type pattern_type is record
            m1  : std_logic_vector(15 downto 0);
            e1  : std_logic_vector(5 downto 0);
            m2  : std_logic_vector(15 downto 0);
            e2  : std_logic_vector(5 downto 0);
            mo1 : std_logic_vector(31 downto 0);
            mo2 : std_logic_vector(31 downto 0);
            eo  : std_logic_vector(5 downto 0);
        end record;
        --  The patterns to apply.
        type pattern_array is array (natural range <>) of pattern_type;
        constant patterns : pattern_array := (
            ("0000000000000001", "000000", "0000000000000001", "000000", "00000000000000010000000000000000", "00000000000000010000000000000000", "000000"),
            ("0000000000000001", "111110", "0000000000000000", "111111", "00000000000000010000000000000000", "00000000000000000000000000000000", "111111")
        );

    begin
        for i in patterns'range loop
            --  Set the inputs.
            exp_1_in <= patterns(i).e1;
            exp_2_in <= patterns(i).e2;
            man_1_in <= patterns(i).m1;
            man_2_in <= patterns(i).m2;

            wait for 100 ms;

            assert patterns(i).mo1 = man_1_out report "BAD MANTISSA 1, GOT: " & integer'image(to_integer(signed(man_1_out)));
            assert patterns(i).mo2 = man_2_out report "BAD MANTISSA 2, GOT: " & integer'image(to_integer(signed(man_2_out)));
            assert patterns(i).eo = exp_out report "BAD EXP, GOT: " & integer'image(to_integer(signed(exp_out)));
            --  Check the outputs.
        end loop;
        assert false report "end of test" severity note;
        wait;
    end process;
end;

Но, как я могу видеть, внутренние компоненты (компаратор и мультиплексоры) не "выполняются", и порты результата никогда не меняются.

Все компоненты имеют все свои порты IN в качестве триггеров для своих процессов.

Я немного читал об этом и обнаружил, что компоненты не могут быть выполнены внутри процессов, поэтому, возможно, когда я это сделаю: exp_1 <= exp_1_in; exp_2 <= exp_2_in; я на самом деле не запускаю компоненты.

Тем не менее, я видел пример, который очень похож на то, что я пытаюсь здесь. https://www.altera.com/support/support-resources/design-examples/design-software/vhdl/v_hier.html

Я не знаю, где моя проблема. Я протестировал каждый компонент в отдельности, и все они работают.

РЕДАКТИРОВАТЬ:

Я анализирую каждый файл с помощью ghdl -a. Затем создаю исполняемый файл из тестового стенда с помощью ghdl -e exp_equalizer_tb. И, наконец, я запускаю исполняемые файлы ./exp_equalizer

Я сделал скрипт, который делает то же самое для каждого компонента в моем проекте, и у меня есть тестовые наборы для всех из них с утверждениями и отчетами, и все они работают нормально. Находится в этом компоненте, где я не получаю ожидаемых результатов.

1 ответ

Без хотя бы некоторого исходного кода для других ваших сущностей нет способа воспроизвести вашу конкретную проблему.

Я не использую GHDL, но я собираюсь высказать предположение, что проблема может заключаться в следующих строках:

for greater_exp_mux : binary_multiplexer use entity work.binary_multiplexer;
for smaller_exp_mux : binary_multiplexer use entity work.binary_multiplexer;
for greater_man_mux : binary_multiplexer use entity work.binary_multiplexer;
for smaller_man_mux : binary_multiplexer use entity work.binary_multiplexer;
for comparer_0 : comparer use entity work.comparer;

В прошлом я видел много проблем с конфигурациями, особенно с синтезаторами. Обычно не проблема в симуляторах, но кто знает.

Кроме того, может показаться, что в вашем случае они не имеют никакой цели, так что вы должны IMO оставить их как само собой разумеющееся.

Другие вопросы по тегам