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.
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:
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.