1 Reply Latest reply on Dec 18, 2015 7:01 AM by spektra_th

    ModelSim won't compiles VHDL -> Unexpected signal: 11

    spektra_th

      Hi Mentor,

      some Modelsim versions (10.4b, 10.3c and 10.1e) won't completely compile the following VHDL code.

       

      Code:

       


      library ieee;

      use ieee.std_logic_1164.all;

       

      entity x is

      generic (signal_count         : natural := 1);

      port (clock : in std_logic);

      end entity;

       

      architecture rtl of x is

       

      type t_signal_array is array (signal_count - 1 downto 0) of std_logic_vector (2 downto 0);

      type reg_mclk_t is record

         ddr_chain : t_signal_array;

         output    : std_logic_vector(signal_count - 1 downto 0);

      end record;

       

      signal mclk_r     : reg_mclk_t;

      signal mclk_r_in  : reg_mclk_t;

       

      begin

       

      MCLK_PROC: process (clock, mclk_r_in)

      begin

      if rising_edge (clock) then

         mclk_r.ddr_chain(signal_count - 1 downto 0)(2 downto 1) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(2 downto 1); -- this line results in # ** Fatal: Unexpected signal: 11.

         --mclk_r.ddr_chain(signal_count - 1 downto 0) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0);       -- this works

         --mclk_r.ddr_chain(signal_count - 1 downto 0)(1) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(1); -- this works

         --mclk_r.ddr_chain(signal_count - 1 downto 0)(2) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(2); -- this works

         mclk_r.output <= mclk_r_in.output;

      end if;

      end process;

       

       

      end rtl;

       

      Syntax checking passes all verifications, but when it comes to writing the library data to file system compile process stops with following message.

       

       

        # vcom -work work -2002 -explicit -stats=none C:/work/VHDL-Sims/Test_unexpectedSignal.vhd
      # Model Technology ModelSim ALTERA vcom 10.3c Compiler 2014.09 Sep 20 2014
      # -- Loading package STANDARD
      # -- Loading package TEXTIO
      # -- Loading package std_logic_1164
      # -- Compiling entity x
      # -- Compiling architecture rtl of x
      # ** Fatal: Unexpected signal: 11.
      # ** Error: C:/work/VHDL-Sims/Test_unexpectedSignal.vhd(34): VHDL Compiler exiting 

       

      Library view of ModelSim shows the new entity inside the library. However elaborating this entity and loading it into a simulation fails.

      Even the library files on disk won't be created, thus elaboration can't find them.

       

      Is there a specific reason for this or is it some VHDL issue or somthing else?

        • 1. Re: ModelSim won't compiles VHDL -> Unexpected signal: 11
          spektra_th

          It looks like it is a VHDL issue.

           

          Using explicite indices at all bits gives a expected result.

          And first signal ( i)(0) are alle plain wires, while all following signals are registers of a shift-register array.

          MCLK_PROC: process (clock, mclk_r_in)

          begin

          for i in signal_count -1 downto 0 loop 

            mclk_r.ddr_chain(i)(0) <= mclk_r_in.ddr_chain(i)(0); 

          end loop;

           

          if rising_edge (clock) then

           

            for i in signal_count -1 downto 0 loop

            for j in 2 downto 1 loop

            mclk_r.ddr_chain(i)(j) <= mclk_r_in.ddr_chain(i)(j);

            end loop;

            end loop;

            

            mclk_r.output <= mclk_r_in.output;

            

          end if;

          end process;

           

           

          Doing the same with a ranged index assignment creates a wiereder result.

          Now just signal (0) is assigned to all its signal stages 2 downto 0 at all times thus it directly feeds into output register.

          All other mclk_r.ddr_chain registers with i > 0 are just registers with undefined input.

           

          MCLK_PROC: process (clock, mclk_r_in)

          begin

          mclk_r.ddr_chain(signal_count - 1 downto 0)(0) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(0);

           

          if rising_edge (clock) then

           

             for i in signal_count -1 downto 0 loop

                for j in 2 downto 1 loop

          mclk_r.ddr_chain(i)(j) <= mclk_r_in.ddr_chain(i)(j);

                end loop;

             end loop;

            

             mclk_r.output <= mclk_r_in.output;

            

          end if;

            end process;

           

          Thus the double range assignment somewhat drops the first range index and only uses the second one ... ?

          This bavior is consistent between simulation and synthesis. Thus probably only caused by strange VHDL-rules.

           

          Testcode:

           

          library ieee;

          use ieee.std_logic_1164.all;

           

          entity Test_unexpectedSignal_Syn is

          generic (signal_count         : natural := 5);

          port (clock  : in std_logic;

                pin_in : in std_logic_vector (signal_count - 1 downto 0);

                synced_out: out std_logic_vector (signal_count - 1 downto 0)

                );

          end entity;

           

          architecture rtl of Test_unexpectedSignal_Syn is

           

          type t_signal_array is array (signal_count - 1 downto 0) of std_logic_vector (2 downto 0);

          type reg_mclk_t is record

             ddr_chain : t_signal_array;

             output    : std_logic_vector(signal_count - 1 downto 0);

          end record;

           

          signal mclk_r     : reg_mclk_t;

          signal mclk_r_in  : reg_mclk_t;

           

          begin

           

          synced_out <= mclk_r.output;

           

          COMP_PROC: process (pin_in, mclk_r)

          begin

          for i in signal_count - 1 downto 0 loop

             mclk_r_in.ddr_chain(i)(0) <= pin_in(i); 

            

             mclk_r_in.ddr_chain(i)(2 downto 1) <= mclk_r.ddr_chain(i)(1 downto 0);

             mclk_r_in.output(i) <= mclk_r.ddr_chain(i)(2);

          end loop;

          end process;

           

          MCLK_PROC: process (clock, mclk_r_in)

          begin

          -- just pass through the pin assignment

          mclk_r.ddr_chain(signal_count - 1 downto 0)(0) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(0);

           

          -- for i in signal_count -1 downto 0 loop     

                   -- mclk_r.ddr_chain(i)(0) <= mclk_r_in.ddr_chain(i)(0);    

             -- end loop;

           

          if rising_edge (clock) then

             -- only make part of the record a register set (all except the zerothed signal column)

             mclk_r.ddr_chain(signal_count - 1 downto 0)(2 downto 1) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(2 downto 1); -- this line results in # ** Fatal: Unexpected signal: 11.

             --mclk_r.ddr_chain(signal_count - 1 downto 0)(2 downto 1) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(2 downto 1); -- this line results in # ** Fatal: Unexpected signal: 11.

             --mclk_r.ddr_chain(signal_count - 1 downto 0) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0);       -- this works

             --mclk_r.ddr_chain(signal_count - 1 downto 0)(1) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(1); -- this works, but has a weired synthesis result as if (signal_count - 1 downto 0) is not used

             --mclk_r.ddr_chain(signal_count - 1 downto 0)(2) <= mclk_r_in.ddr_chain(signal_count - 1 downto 0)(2); -- this works

            

            

             -- using such an explicite loop changes the synthesis result too, but simulation compilation works

             -- for i in signal_count -1 downto 0 loop

                -- for j in 2 downto 1 loop

                   -- mclk_r.ddr_chain(i)(j) <= mclk_r_in.ddr_chain(i)(j);

                -- end loop;

             -- end loop;

            

             mclk_r.output <= mclk_r_in.output;

            

             --mclk_r <= mclk_r_in;

          end if;

          end process;

           

           

          end rtl;