diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/simul/simul-vhdl_elab.adb | 86 | ||||
| -rw-r--r-- | src/simul/simul-vhdl_elab.ads | 11 | ||||
| -rw-r--r-- | src/simul/simul-vhdl_simul.adb | 69 | 
3 files changed, 152 insertions, 14 deletions
diff --git a/src/simul/simul-vhdl_elab.adb b/src/simul/simul-vhdl_elab.adb index 33501a536..61737af24 100644 --- a/src/simul/simul-vhdl_elab.adb +++ b/src/simul/simul-vhdl_elab.adb @@ -66,10 +66,16 @@ package body Simul.Vhdl_Elab is     begin        E := Proto_E;        E.Typ := Val.Typ; + +      --  Be sure the width is correct for a signal.        Convert_Type_Width (E.Typ); + +      --  Allocate the value in global pool.        Current_Pool := Global_Pool'Access;        E.Val := Alloc_Memory (E.Typ);        Current_Pool := Expr_Pool'Access; + +      --  Set it to the default value.        if Val.Val.Init /= null then           Copy_Memory (E.Val, Val.Val.Init.Mem, E.Typ.Sz);        else @@ -77,6 +83,14 @@ package body Simul.Vhdl_Elab is        end if;        E.Sig := null; +      if E.Typ.W > 0 then +         E.Nbr_Sources := +           new Nbr_Sources_Array'(0 .. E.Typ.W - 1 => +                                    (Nbr_Drivers => 0, +                                     Nbr_Conns => 0, +                                     Last_Proc => No_Process_Index)); +      end if; +        pragma Assert (E.Kind /= Mode_End);        pragma Assert (Signals_Table.Table (Val.Val.S).Kind = Mode_End);        Signals_Table.Table (Val.Val.S) := E; @@ -118,28 +132,28 @@ package body Simul.Vhdl_Elab is                 when Iir_Linkage_Mode =>                    Gather_Signal ((Mode_Linkage, Decl, Inst, null, null, null,                                    No_Sensitivity_Index, No_Signal_Index, -                                  No_Driver_Index, No_Connect_Index)); +                                  No_Driver_Index, No_Connect_Index, null));                 when Iir_Buffer_Mode =>                    Gather_Signal ((Mode_Buffer, Decl, Inst, null, null, null,                                    No_Sensitivity_Index, No_Signal_Index, -                                  No_Driver_Index, No_Connect_Index)); +                                  No_Driver_Index, No_Connect_Index, null));                 when Iir_Out_Mode =>                    Gather_Signal ((Mode_Out, Decl, Inst, null, null, null,                                    No_Sensitivity_Index, No_Signal_Index, -                                  No_Driver_Index, No_Connect_Index)); +                                  No_Driver_Index, No_Connect_Index, null));                 when Iir_Inout_Mode =>                    Gather_Signal ((Mode_Inout, Decl, Inst, null, null, null,                                    No_Sensitivity_Index, No_Signal_Index, -                                  No_Driver_Index, No_Connect_Index)); +                                  No_Driver_Index, No_Connect_Index, null));                 when Iir_In_Mode =>                    Gather_Signal ((Mode_In, Decl, Inst, null, null, null,                                    No_Sensitivity_Index, No_Signal_Index, -                                  No_Driver_Index, No_Connect_Index)); +                                  No_Driver_Index, No_Connect_Index, null));              end case;           when Iir_Kind_Signal_Declaration =>              Gather_Signal ((Mode_Signal, Decl, Inst, null, null, null,                              No_Sensitivity_Index, No_Signal_Index, -                            No_Driver_Index, No_Connect_Index)); +                            No_Driver_Index, No_Connect_Index, null));           when Iir_Kind_Configuration_Specification =>              null;           when Iir_Kind_Free_Quantity_Declaration @@ -172,9 +186,16 @@ package body Simul.Vhdl_Elab is           when Iir_Kind_Above_Attribute =>              Gather_Signal ((Mode_Above, Decl, Inst, null, null, null,                              No_Sensitivity_Index, No_Signal_Index)); +         when Iir_Kind_Object_Alias_Declaration => +            --  In case it aliases a signal. +            declare +               V : Valtyp; +            begin +               V := Get_Value (Inst, Decl); +               Convert_Type_Width (V.Typ); +            end;           when Iir_Kind_Constant_Declaration             | Iir_Kind_Variable_Declaration -           | Iir_Kind_Object_Alias_Declaration             | Iir_Kind_Non_Object_Alias_Declaration             | Iir_Kind_Attribute_Declaration             | Iir_Kind_Attribute_Specification @@ -205,24 +226,51 @@ package body Simul.Vhdl_Elab is        end loop;     end Gather_Processes_Decls; +   --  Add a driver for process PROC_IDX on signal SIG at OFF/TYP.     procedure Add_Process_Driver (Proc_Idx : Process_Index_Type;                                   Sig : Signal_Index_Type;                                   Off : Value_Offsets; -                                 Typ : Type_Acc) is +                                 Typ : Type_Acc) +   is +      S : Signal_Entry renames Signals_Table.Table (Sig); +      Need_It : Boolean;     begin +      pragma Assert (Typ.Wkind = Wkind_Sim); + +      if Typ.W = 0 then +         --  Be safe: no signal, then no driver. +         return; +      end if; + +      --  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; +      end loop; + +      if not Need_It then +         --  The driver has already been added. +         return; +      end if; +        Drivers_Table.Append          ((Sig => Sig,            Off => Off,            Typ => Typ, -          Prev_Sig => Signals_Table.Table (Sig).Drivers, +          Prev_Sig => S.Drivers,            Proc => Proc_Idx,            Prev_Proc => Processes_Table.Table (Proc_Idx).Drivers)); -      Signals_Table.Table (Sig).Drivers := Drivers_Table.Last; +      S.Drivers := Drivers_Table.Last;        Processes_Table.Table (Proc_Idx).Drivers := Drivers_Table.Last;     end Add_Process_Driver; +   --  Add drivers for process PROC.     procedure Gather_Process_Drivers       (Inst : Synth_Instance_Acc; Proc : Node; Proc_Idx : Process_Index_Type)     is @@ -349,6 +397,22 @@ package body Simul.Vhdl_Elab is        Destroy_Iir_List (List);     end Gather_Process_Sensitivity; +   --  Increment the number of sources for EP. +   procedure Increment_Nbr_Sources (Ep : Connect_Endpoint) is +   begin +      if Ep.Typ.W = 0 then +         return; +      end if; +      for I in Ep.Offs.Net_Off .. Ep.Offs.Net_Off + Ep.Typ.W - 1 loop +         declare +            N : Uns32 renames +              Signals_Table.Table (Ep.Base).Nbr_Sources (I).Nbr_Conns; +         begin +            N := N + 1; +         end; +      end loop; +   end Increment_Nbr_Sources; +     procedure Gather_Connections (Port_Inst : Synth_Instance_Acc;                                   Ports : Node;                                   Assoc_Inst : Synth_Instance_Acc; @@ -414,10 +478,12 @@ package body Simul.Vhdl_Elab is                      | Iir_Buffer_Mode =>                       Conn.Drive_Formal := False;                       Conn.Drive_Actual := True; +                     Increment_Nbr_Sources (Actual_Ep);                    when Iir_Inout_Mode                      | Iir_Linkage_Mode =>                       Conn.Drive_Formal := True;                       Conn.Drive_Actual := True; +                     Increment_Nbr_Sources (Actual_Ep);                    when Iir_Unknown_Mode =>                       raise Internal_Error;                 end case; diff --git a/src/simul/simul-vhdl_elab.ads b/src/simul/simul-vhdl_elab.ads index c17555920..0fb790475 100644 --- a/src/simul/simul-vhdl_elab.ads +++ b/src/simul/simul-vhdl_elab.ads @@ -122,6 +122,16 @@ package Simul.Vhdl_Elab is     --  Signals. +   --  Number of drivers and out connections for each scalar element. +   type Nbr_Sources_Type is record +      Nbr_Drivers : Uns32; +      Nbr_Conns : Uns32; +      Last_Proc : Process_Index_Type; +   end record; + +   type Nbr_Sources_Array is array (Uns32 range <>) of Nbr_Sources_Type; +   type Nbr_Sources_Arr_Acc is access Nbr_Sources_Array; +     type Signal_Entry (Kind : Mode_Signal_Type := Mode_Signal) is record        Decl : Iir;        Inst : Synth_Instance_Acc; @@ -139,6 +149,7 @@ package Simul.Vhdl_Elab is           when Mode_Signal_User =>              Drivers : Driver_Index_Type;              Connect : Connect_Index_Type; +            Nbr_Sources : Nbr_Sources_Arr_Acc;           when Mode_Quiet | Mode_Stable | Mode_Delayed             | Mode_Transaction =>              Time : Std_Time; diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb index fb0efee72..58efc7101 100644 --- a/src/simul/simul-vhdl_simul.adb +++ b/src/simul/simul-vhdl_simul.adb @@ -1995,7 +1995,6 @@ package body Simul.Vhdl_Simul is        procedure Create_Signal (Val : Memory_Ptr;                                 Sig_Off : Uns32; ---                               Sig : Memory_Ptr;                                 Sig_Type: Iir;                                 Typ : Type_Acc;                                 Vec : Nbr_Sources_Vector; @@ -2181,8 +2180,7 @@ package body Simul.Vhdl_Simul is              pragma Assert (E.Sig = null);              if E.Collapsed_By /= No_Signal_Index then                 E.Sig := Signals_Table.Table (E.Collapsed_By).Sig; -               --  TODO: keep val ? -               E.Val := Signals_Table.Table (E.Collapsed_By).Val; +               --  E.Val will be assigned in Collapse_Signals.              else                 Create_Signal (I);              end if; @@ -2190,6 +2188,69 @@ package body Simul.Vhdl_Simul is        end loop;     end Create_Signals; +   procedure Add_Extra_Driver_To_Signal (Sig : Memory_Ptr; +                                         Typ : Type_Acc; +                                         Init : Memory_Ptr; +                                         Off : Uns32; +                                         Vec : Nbr_Sources_Array) is +   begin +      case Typ.Kind is +         when Type_Logic +           | Type_Bit +           | Type_Discrete +           | Type_Float => +            if Vec (Off).Nbr_Drivers = 0 +              and then Vec (Off).Nbr_Conns = 0 +            then +               Grt.Signals.Ghdl_Signal_Add_Extra_Driver +                 (Read_Sig (Sig), To_Ghdl_Value ((Typ, Init))); +            end if; +         when Type_Vector +           | Type_Array => +            declare +               Len : constant Uns32 := Typ.Abound.Len; +               El : constant Type_Acc := Typ.Arr_El; +            begin +               for I in 1 .. Len loop +                  Add_Extra_Driver_To_Signal +                    (Sig_Index (Sig, (Len - I) * El.W), El, +                     Init + Size_Type (I - 1) * El.Sz, Off + (Len - I), Vec); +               end loop; +            end; +         when Type_Record => +            for I in Typ.Rec.E'Range loop +               declare +                  E : Rec_El_Type renames Typ.Rec.E (I); +               begin +                  Add_Extra_Driver_To_Signal +                    (Sig_Index (Sig, E.Offs.Net_Off), E.Typ, +                     Init + E.Offs.Mem_Off, Off + E.Offs.Net_Off, Vec); +               end; +            end loop; +         when others => +            raise Internal_Error; +      end case; +   end Add_Extra_Driver_To_Signal; + +   procedure Collapse_Signals is +   begin +      for I in Signals_Table.First .. Signals_Table.Last loop +         declare +            E : Signal_Entry renames Signals_Table.Table (I); +         begin +            if E.Collapsed_By /= No_Signal_Index then +               if Get_Mode (E.Decl) in Iir_Out_Modes then +                  Add_Extra_Driver_To_Signal +                    (E.Sig, E.Typ, E.Val, 0, E.Nbr_Sources.all); +               end if; +               --  The signal value is the value of the collapsed signal. +               --  TODO: keep the default value ? +               E.Val := Signals_Table.Table (E.Collapsed_By).Val; +            end if; +         end; +      end loop; +   end Collapse_Signals; +     type Connect_Mode is (Connect_Source, Connect_Effective);     -- Add a driving value PORT to signal SIG, ie: PORT is a source for SIG. @@ -2635,9 +2696,9 @@ package body Simul.Vhdl_Simul is        Create_Connects;        -- Create_Disconnections;        Create_Processes; -      -- Create_PSL;        Create_Terminals;        Create_Quantities; +      Collapse_Signals;        --  Allow Synth_Expression to handle signals.        Synth.Vhdl_Expr.Hook_Signal_Expr := Hook_Signal_Expr'Access;  | 
