0

So, i've created a hierarchical desing of components in VHDL. The top level entity for now is the following.

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;

And i am testing it using this testbench

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;

But for what i am able to see, the inner components (comparer and multiplexers) are not being "executed" and the result ports are never changed.

All components have all their IN ports as triggers for their processes.

I've been reading a little bit about this and found that components can't be executed inside processes so maybe, when i do: exp_1 <= exp_1_in; exp_2 <= exp_2_in; i am not actually triggering the components.

However, i saw an example that is quite similar with what i am attempting here. https://www.altera.com/support/support-resources/design-examples/design-software/vhdl/v_hier.html

I don't know where my problem is. I've tested every component individually and they all work.

EDIT:

I am analyzing every file with ghdl -a Then building an executable from the testbench with ghdl -e exp_equalizer_tb And lastly, i am running the executables ./exp_equalizer

I made a script that does the same for every component in my project and i have testbenches for all of them with assertions and reports and they all work fine. Is in this component where i am not getting the expected results.

user3013172
  • 1,637
  • 3
  • 15
  • 26
  • Executed by what? What steps are you taking with what program(s)? – JHBonarius Sep 21 '17 at 06:45
  • Your example is not complete. We cannot reproduce your issue without all code. – JHBonarius Sep 21 '17 at 06:47
  • Besides not having a [Minimal, Complete and Verifiable example](https://stackoverflow.com/help/mcve) and not being able to reproduce your somewhat vague problem you could note the process has exp_1 and exp_2 in the sensitivity list but doesn't evaluate them, while exp_1_in and exp_2_in are evaluated but aren't in the sensitivity list. You need to go over that sensitivity list pretty closely. –  Sep 21 '17 at 07:41
  • Yo are right! i don't know why i only added the signals to that list. – user3013172 Sep 21 '17 at 11:07
  • 1
    It might be useful should you modify your question making it an MCVe and provide an answer yourself. Without the ability to 'see' the problem it's of little utility to those using Stackoverflow as a search resource. –  Sep 22 '17 at 03:20

1 Answers1

0

Without at least some source code for your other entities there is no way of reproducing your specific problem.

I do not use GHDL, but i'm going to throw a guess out here that the problem could be these lines:

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;

I've seen many issues with configurations in the past, especially with synthesizers. Not usually a problem in simulators, but who knows.

Plus, it would seem that in your case they have no purpose anyway, so you should IMO leave them out as a matter of course.

DLnd
  • 378
  • 3
  • 11
  • Those lines can be commented out with little effect as long as compatible entity declarations and architectures are found in library work for binary_multiplexer and comparer. See IEEE Std 1076-2008 7.3.3 Default binding indication. Commenting them out can help searching for analysis errors without them here: 7.3.2.2 Entity aspect *At the time of the analysis of an entity aspect of the first form, the library unit corresponding to the entity declaration denoted by the entity name is required to exist; ...* An error which ghdl correctly detects. –  Sep 22 '17 at 02:56