diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/simul/simul-vhdl_elab.adb | 101 | 
1 files changed, 93 insertions, 8 deletions
| diff --git a/src/simul/simul-vhdl_elab.adb b/src/simul/simul-vhdl_elab.adb index 26092341b..3870f6a11 100644 --- a/src/simul/simul-vhdl_elab.adb +++ b/src/simul/simul-vhdl_elab.adb @@ -59,6 +59,76 @@ package body Simul.Vhdl_Elab is        end case;     end Convert_Type_Width; +   --  For each scalar element, set Vec (off).Total to 1 if the signal is +   --  resolved. +   procedure Mark_Resolved_Signals (Sig_Off : Uns32; +                                    Sig_Type: Iir; +                                    Typ : Type_Acc; +                                    Vec : in out Nbr_Sources_Array; +                                    Already_Resolved : Boolean) +   is +      Sub_Resolved : Boolean; +   begin +      if not Already_Resolved +        and then Get_Kind (Sig_Type) in Iir_Kinds_Subtype_Definition +      then +         Sub_Resolved := Get_Resolution_Indication (Sig_Type) /= Null_Iir; +      else +         Sub_Resolved := Already_Resolved; +      end if; + +      case Typ.Kind is +         when Type_Bit +           | Type_Logic +           | Type_Float +           | Type_Discrete => +            if Sub_Resolved then +               Vec (Sig_Off).Total := 1; +            end if; +         when Type_Vector +           | Type_Array => +            declare +               Len : constant Uns32 := Typ.Abound.Len; +               El_Type : Node; +            begin +               if Typ.Alast then +                  El_Type := Get_Element_Subtype (Sig_Type); +               else +                  El_Type := Sig_Type; +               end if; +               for I in 1 .. Len loop +                  Mark_Resolved_Signals +                    (Sig_Off + (Len - I) * Typ.Arr_El.W, +                     El_Type, Typ.Arr_El, +                     Vec, Already_Resolved); +               end loop; +            end; +         when Type_Record => +            declare +               List : constant Iir_Flist := Get_Elements_Declaration_List +                 (Sig_Type); +               El : Iir_Element_Declaration; +            begin +               for I in Typ.Rec.E'Range loop +                  El := Get_Nth_Element (List, Natural (I - 1)); +                  Mark_Resolved_Signals +                    (Sig_Off + Typ.Rec.E (I).Offs.Net_Off, +                     Get_Type (El), Typ.Rec.E (I).Typ, +                     Vec, Sub_Resolved); +               end loop; +            end; + +         when Type_Slice +           | Type_Access +           | Type_Unbounded_Vector +           | Type_Unbounded_Array +           | Type_Unbounded_Record +           | Type_File +           | Type_Protected => +            raise Internal_Error; +      end case; +   end Mark_Resolved_Signals; +     procedure Gather_Signal (Proto_E : Signal_Entry)     is        Val : constant Valtyp := Get_Value (Proto_E.Inst, Proto_E.Decl); @@ -90,6 +160,9 @@ package body Simul.Vhdl_Elab is                                       Nbr_Conns => 0,                                       Total => 0,                                       Last_Proc => No_Process_Index)); + +         Mark_Resolved_Signals +           (0, Get_Type (E.Decl), E.Typ, E.Nbr_Sources.all, False);        end if;        pragma Assert (E.Kind /= Mode_End); @@ -232,7 +305,8 @@ package body Simul.Vhdl_Elab is     procedure Add_Process_Driver (Proc_Idx : Process_Index_Type;                                   Sig : Signal_Index_Type;                                   Off : Value_Offsets; -                                 Typ : Type_Acc) +                                 Typ : Type_Acc; +                                 Loc : Node)     is        S : Signal_Entry renames Signals_Table.Table (Sig);        Need_It : Boolean; @@ -247,11 +321,22 @@ package body Simul.Vhdl_Elab is        --  Increment the number of driver for each scalar element.        Need_It := False;        for I in Off.Net_Off .. Off.Net_Off + Typ.W - 1 loop -         if S.Nbr_Sources (I).Last_Proc /= Proc_Idx then -            S.Nbr_Sources (I).Nbr_Drivers := S.Nbr_Sources (I).Nbr_Drivers + 1; -            S.Nbr_Sources (I).Last_Proc := Proc_Idx; -            Need_It := True; -         end if; +         declare +            Ns : Nbr_Sources_Type renames S.Nbr_Sources (I); +         begin +            if Ns.Last_Proc /= Proc_Idx then +               --  New driver. +               if not Need_It +                 and then Ns.Nbr_Drivers > 0 +                 and then Ns.Total = 0 +               then +                  Error_Msg_Elab (Loc, "too many drivers for %n", +S.Decl); +               end if; +               Ns.Nbr_Drivers := Ns.Nbr_Drivers + 1; +               Ns.Last_Proc := Proc_Idx; +               Need_It := True; +            end if; +         end;        end loop;        if not Need_It then @@ -295,7 +380,7 @@ package body Simul.Vhdl_Elab is           pragma Assert (Dyn = No_Dyn_Name);           Base := Base_Vt.Val.S; -         Add_Process_Driver (Proc_Idx, Base, Off, Typ); +         Add_Process_Driver (Proc_Idx, Base, Off, Typ, Sig);           Next (It);        end loop; @@ -546,7 +631,7 @@ package body Simul.Vhdl_Elab is                        Sensitivity => No_Sensitivity_Index));                    Add_Process_Driver -                    (Processes_Table.Last, Formal_Sig, Off, Typ); +                    (Processes_Table.Last, Formal_Sig, Off, Typ, Assoc);                    List := Create_Iir_List;                    Vhdl.Canon.Canon_Extract_Sensitivity_Expression | 
