0

因此,我在 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

我制作了一个脚本,它对我项目中的每个组件都执行相同的操作,并且我为所有这些组件提供了带有断言和报告的测试台,它们都工作正常。在这个组件中我没有得到预期的结果。

4

1 回答 1

0

如果没有其他实体的至少一些源代码,就无法重现您的特定问题。

我不使用 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;

过去我看到过很多配置问题,尤其是合成器。在模拟器中通常不是问题,但谁知道呢。

另外,在你的情况下,它们似乎没有任何目的,所以你应该理所当然地将它们排除在外。

于 2017-09-21T14:36:40.173 回答