ghdl / ghdl-yosys-plugin

VHDL synthesis (based on ghdl)
GNU General Public License v3.0
308 stars 31 forks source link

Thousend of 'terminate called recursively' messages and 'core' file generated #114

Closed rodrigomelo9 closed 3 years ago

rodrigomelo9 commented 4 years ago

Hi. This problem appears with an example from ISE, where a UNISIM component is used. To simplify the example I provided the primitive definition in the same file.

library ieee;
use ieee.std_logic_1164.all;

entity primitive_2 is
    port(I0,I1 : in std_logic;
         O    : out std_logic);
end primitive_2;

architecture beh of primitive_2 is

    attribute BOX_TYPE : string;

    component LUT2
        generic (
            INIT : bit_vector := X"0"
        );
        port (
            O  : out std_ulogic;
            I0 : in std_ulogic;
            I1 : in std_ulogic
        );
    end component;
    attribute BOX_TYPE of LUT2 : component is "PRIMITIVE";

begin

    inst : LUT2
        generic map (INIT=>"1")
        port map (I0=>I0, I1=>I1, O=>O);

end beh;
$DOCKER_CMD ghdl/synth:beta yosys -Q -m ghdl -p "ghdl primitive_2.vhd -e; synth_xilinx"
...
2.48. Executing OPT_LUT_INS pass (discard unused LUT inputs).
Optimizing LUTs in primitive_2.
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
terminate called recursively
terminate called recursively
terminate called recursively
...
terminate called recursively

Note: a file called core of almost 400mb is also generated.

Xiretza commented 4 years ago

Partly a yosys bug, a LUT2 with an INIT attribute of the wrong length (should be 4, is 1 in the example) causes a crash:

$ yosys -m ghdl -p "ghdl test.vhd -e; write_ilang test.ilang"
$ yosys -p "read_ilang test.ilang; synth_xilinx"
[...]
2.48. Executing OPT_LUT_INS pass (discard unused LUT inputs).
Optimizing LUTs in primitive_2.
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)

The recursive termination is on ghdl though, I think.

rodrigomelo9 commented 4 years ago

Maybe the problem is not to abort when INIT is assigned with "1" instead of "0001". Let me say that it is synthesized by both, ISE and Vivado, without problems (I know, non-standard features are common in such tools).

tgingold commented 4 years ago

Yes, I fear this is an issue in yosys.

Xiretza commented 4 years ago

Definitely not entirely, as yosys just aborts normally when invoked on the equivalent ilang file, yet when the ghdl command has been invoked previously, the recursive termination occurs. Here's a backtrace after two "terminate called recursively", and it involves Ada/gnat code:

#0  0x00007ffff740fce5 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff73f9857 in abort () from /usr/lib/libc.so.6
#2  0x00007ffff7e1e4cd in __gnu_cxx::__verbose_terminate_handler () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/vterminate.cc:50
#3  0x00007ffff7e1c2ca in __cxxabiv1::__terminate (handler=<optimized out>) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#4  0x00007ffff7e1c337 in std::terminate () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#5  0x00007ffff7e1bcd5 in __cxxabiv1::__gxx_personality_v0 (version=<optimized out>, actions=6, exception_class=5138137877735301376, ue_header=0x55555980ce70, context=<optimized out>)
    at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:665
#6  0x00007ffff75ac723 in _Unwind_RaiseException_Phase2 (exc=0x55555980ce70, context=0x7fffffffbd00, frames_p=0x7fffffffbdf0) at /build/gcc/src/gcc/libgcc/unwind.inc:64
#7  0x00007ffff75acc72 in _Unwind_RaiseException (exc=0x55555980ce70) at /build/gcc/src/gcc/libgcc/unwind.inc:136
#8  0x00007ffff68b918a in ada.exceptions.exception_propagation.propagate_gcc_exception () from /usr/lib64/libgnat-9.so
#9  0x00007ffff68b91bb in ada.exceptions.exception_propagation.propagate_exception () from /usr/lib64/libgnat-9.so
#10 0x00007ffff68ba0b5 in ada.exceptions.raise_from_signal_handler () from /usr/lib64/libgnat-9.so
#11 <signal handler called>
#12 0x00007ffff740fce5 in raise () from /usr/lib/libc.so.6
#13 0x00007ffff73f9857 in abort () from /usr/lib/libc.so.6
#14 0x00007ffff7e1e4cd in __gnu_cxx::__verbose_terminate_handler () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/vterminate.cc:50
#15 0x00007ffff7e1c2ca in __cxxabiv1::__terminate (handler=<optimized out>) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#16 0x00007ffff7e1c337 in std::terminate () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#17 0x00007ffff7e1bcd5 in __cxxabiv1::__gxx_personality_v0 (version=<optimized out>, actions=6, exception_class=5138137877735301376, ue_header=0x5555561e0390, context=<optimized out>)
    at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_personality.cc:665
#18 0x00007ffff75ac723 in _Unwind_RaiseException_Phase2 (exc=0x5555561e0390, context=0x7fffffffcc00, frames_p=0x7fffffffccf0) at /build/gcc/src/gcc/libgcc/unwind.inc:64
#19 0x00007ffff75acc72 in _Unwind_RaiseException (exc=0x5555561e0390) at /build/gcc/src/gcc/libgcc/unwind.inc:136
#20 0x00007ffff68b918a in ada.exceptions.exception_propagation.propagate_gcc_exception () from /usr/lib64/libgnat-9.so
#21 0x00007ffff68b91bb in ada.exceptions.exception_propagation.propagate_exception () from /usr/lib64/libgnat-9.so
#22 0x00007ffff68ba0b5 in ada.exceptions.raise_from_signal_handler () from /usr/lib64/libgnat-9.so
#23 <signal handler called>
#24 0x00007ffff740fce5 in raise () from /usr/lib/libc.so.6
#25 0x00007ffff73f9857 in abort () from /usr/lib/libc.so.6
#26 0x00007ffff7e0f81d in __gnu_cxx::__verbose_terminate_handler () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/vterminate.cc:95
#27 0x00007ffff7e1c2ca in __cxxabiv1::__terminate (handler=<optimized out>) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#28 0x00007ffff7e1c337 in std::terminate () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#29 0x00007ffff7e1c59e in __cxxabiv1::__cxa_throw (obj=obj@entry=0x55555697f9e0, tinfo=0x7ffff7f54368 <typeinfo for std::out_of_range>, dest=0x7ffff7e327b0 <std::out_of_range::~out_of_range()>)
    at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:95
#30 0x00007ffff7e12329 in std::__throw_out_of_range_fmt (__fmt=<optimized out>) at /build/gcc/src/gcc/libstdc++-v3/src/c++11/functexcept.cc:82
#31 0x00005555558f94f2 in std::vector<Yosys::RTLIL::State, std::allocator<Yosys::RTLIL::State> >::_M_range_check(unsigned long) const ()
#32 0x0000555555bfb2da in ?? ()
#33 0x000055555597459c in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ()
#34 0x0000555555974af1 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#35 0x0000555555974c3a in Yosys::ScriptPass::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#36 0x0000555555eac42c in ?? ()
#37 0x0000555555ea94d9 in ?? ()
#38 0x000055555597459c in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ()
#39 0x0000555555974af1 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#40 0x00005555559c35e7 in Yosys::run_pass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Yosys::RTLIL::Design*) ()
#41 0x00005555558871a2 in main ()
tgingold commented 4 years ago

Ok, you have a different abort message, but that's still an abort!

The Ada runtime handles the abort signal, which regenerate an abort. I fear there is no easy fix for this crash case.

rodrigomelo9 commented 4 years ago

FYI

I changed generic map (INIT=>"1") with generic map (INIT=>"0001") and it works...

Back to the original version, I changed INIT : std_logic_vector(3 downto 0) := X"0" with INIT : std_logic_vector(3 downto 0) := X"0" and it aborted (it fails at the line of generic map (INIT=>"1")):

primitive_2.vhd:35:28:error: string length does not match that of anonymous integer subtype defined at primitive_2.vhd:22:37 primitive_2.vhd:35:28:error: actual constraints don't match formal ones

alemuller commented 4 years ago
library ieee;
use ieee.std_logic_1164.all;

entity foobar is
    port(P : out std_logic);
end foobar;

architecture beh of foobar is
    component comp
        generic (INIT : bit_vector := X"FFFFFFFFFFFF");
    end component;
begin
    INST : comp generic map (INIT=>1b"1");
    P <= '1';
end beh;
$ ghdl --synth --std=08 issue.vhdl -e foobar

Shouldn't ghdl complain about type length mismatch?

tgingold commented 4 years ago

No, as INIT is declared with an unconstrained type, any value is allowed.