⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grt-signals.adb

📁 vhdl集成电路设计软件.需要用gcc-4.0.2版本编译.
💻 ADB
📖 第 1 页 / 共 5 页
字号:
   procedure Mark_Active (Sig : Ghdl_Signal_Ptr);   pragma Inline (Mark_Active);   procedure Mark_Active (Sig : Ghdl_Signal_Ptr)   is   begin      if Sig.Active then         Internal_Error ("mark_active");      end if;      Sig.Active := True;      Sig.Last_Active := Current_Time;      Sig.Alink := Clear_List;      Clear_List := Sig;   end Mark_Active;   type Resolver_Acc is access procedure     (Instance : System.Address;      Val : System.Address;      Bool_Vec : System.Address;      Vec_Len : Ghdl_Index_Type;      Nbr_Drv : Ghdl_Index_Type;      Nbr_Ports : Ghdl_Index_Type);   function To_Resolver_Acc is new Ada.Unchecked_Conversion     (Source => System.Address, Target => Resolver_Acc);   procedure Compute_Resolved_Signal (Resolv : Resolved_Signal_Acc)   is      Sig : Ghdl_Signal_Ptr := Sig_Table.Table (Resolv.Sig_Range.First);      Length : Ghdl_Index_Type;      type Bool_Array_Type is array (1 .. Sig.S.Nbr_Drivers) of Boolean;      Vec : Bool_Array_Type;   begin      --  Compute number of non-null drivers.      Length := 0;      for I in 1 .. Sig.S.Nbr_Drivers loop         case Sig.S.Drivers (I - 1).First_Trans.Kind is            when Trans_Value =>               Length := Length + 1;               Vec (I) := True;            when Trans_Null =>               Vec (I) := False;            when Trans_Error =>               Error ("range check error");         end case;      end loop;      --  Check driving condition on all signals.      for J in Resolv.Sig_Range.First + 1.. Resolv.Sig_Range.Last loop         for I in 1 .. Sig.S.Nbr_Drivers loop            if (Sig_Table.Table (J).S.Drivers (I - 1).First_Trans.Kind                /= Trans_Null)              xor Vec (I)            then               Error ("null-transaction required");            end if;         end loop;      end loop;      --  if no driving sources and register, exit.      if Length = 0 and then Sig.Nbr_Ports = 0        and then ((Sig.Rti.Common.Mode and Ghdl_Rti_Signal_Kind_Mask)                  = Ghdl_Rti_Signal_Kind_Register)      then         return;      end if;      --  Call the procedure.      To_Resolver_Acc (Resolv.Resolv_Proc).all        (Resolv.Resolv_Inst,         Resolv.Resolv_Ptr,         Vec'Address,         Length,         Sig.S.Nbr_Drivers,         Sig.Nbr_Ports);   end Compute_Resolved_Signal;   type Conversion_Func_Acc is access procedure (Instance : System.Address);   function To_Conversion_Func_Acc is new Ada.Unchecked_Conversion     (Source => System.Address, Target => Conversion_Func_Acc);   procedure Call_Conversion_Function (Conv : Sig_Conversion_Acc)   is      F : Conversion_Func_Acc;   begin      F := To_Conversion_Func_Acc (Conv.Func);      F.all (Conv.Instance);   end Call_Conversion_Function;   procedure Resume_Process_If_Event     (Sig : Ghdl_Signal_Ptr; Proc : Process_Id)   is      El : Action_List_Acc;   begin      El := new Action_List'(Kind => Action_Process,                             Proc => Proc,                             Next => Sig.Event_List);      Sig.Event_List := El;   end Resume_Process_If_Event;   --  Order of signals:   --  To be computed: driving value or/and effective value   --  To be considered: ports, signals, implicit signals, resolution,   --                    conversion   --   procedure Add_Propagation (P : Propagation_Type) is   begin      Propagation.Increment_Last;      Propagation.Table (Propagation.Last) := P;   end Add_Propagation;   --  Put SIG in PROPAGATION table until ORDER level.   procedure Order_Signal (Sig : Ghdl_Signal_Ptr; Order : Propag_Order_Flag);   --  Return TRUE is the effective value of SIG is the driving value of SIG.   function Is_Eff_Drv (Sig : Ghdl_Signal_Ptr) return Boolean   is   begin      case Sig.S.Mode_Sig is         when Mode_Signal           | Mode_Buffer =>            return True;         when Mode_Linkage           | Mode_Out =>            --  No effective value.            return False;         when Mode_Inout           | Mode_In =>            if Sig.S.Effective = null then               if Sig.S.Nbr_Drivers > 0 or Sig.Nbr_Ports > 0 then                  --  Only for inout.                  return True;               else                  return False;               end if;            else               return False;            end if;         when Mode_Conv_In           | Mode_Conv_Out =>            return False;         when Mode_Stable           | Mode_Guard           | Mode_Quiet           | Mode_Transaction           | Mode_Delayed =>            return True;         when Mode_End =>            return False;      end case;   end Is_Eff_Drv;   procedure Order_Signal_List (Sig : Ghdl_Signal_Ptr;                                Order : Propag_Order_Flag)   is   begin      for I in 1 .. Sig.Nbr_Ports loop         Order_Signal (Sig.Ports (I - 1), Order);      end loop;   end Order_Signal_List;   --  Put SIG in PROPAGATION table until ORDER level.   procedure Order_Signal (Sig : Ghdl_Signal_Ptr; Order : Propag_Order_Flag)   is   begin      if Sig = null then         return;      end if;      --  Catch infinite loops, which must never happen.      --  Also exit if the signal is already fully ordered.      case Sig.Flags.Propag is         when Propag_None =>            null;         when Propag_Being_Driving =>            Internal_Error ("order_signal: being driving");         when Propag_Being_Effective =>            Internal_Error ("order_signal: being effective");         when Propag_Driving =>            null;         when Propag_Done =>            --  If sig was already handled, nothing to do!            return;      end case;      --  First, the driving value.      if Sig.Flags.Propag = Propag_None then         case Sig.S.Mode_Sig is            when Mode_Signal_User =>               if Sig.S.Nbr_Drivers = 0 and Sig.Nbr_Ports = 0 then                  --  No source.                  Sig.Flags.Propag := Propag_Driving;               elsif Sig.S.Resolv = null then                  --  Not resolved (so at most one source).                  if Sig.S.Nbr_Drivers = 1 then                     --  Not resolved, 1 source : a driver.                     if Is_Eff_Drv (Sig) then                        Add_Propagation ((Kind => Eff_One_Driver, Sig => Sig));                        Sig.Flags.Propag := Propag_Done;                     else                        Add_Propagation ((Kind => Drv_One_Driver, Sig => Sig));                        Sig.Flags.Propag := Propag_Driving;                     end if;                  else                     Sig.Flags.Propag := Propag_Being_Driving;                     --  not resolved, 1 source : Source is a port.                     Order_Signal (Sig.Ports (0), Propag_Driving);                     if Is_Eff_Drv (Sig) then                        Add_Propagation ((Kind => Eff_One_Port, Sig => Sig));                        Sig.Flags.Propag := Propag_Done;                     else                        Add_Propagation ((Kind => Drv_One_Port, Sig => Sig));                        Sig.Flags.Propag := Propag_Driving;                     end if;                  end if;               else                  --  Resolved signal.                  declare                     Resolv : Resolved_Signal_Acc;                     S : Ghdl_Signal_Ptr;                  begin                     --  Compute driving value of brothers.                     Resolv := Sig.S.Resolv;                     for I in Resolv.Sig_Range.First .. Resolv.Sig_Range.Last                     loop                        S := Sig_Table.Table (I);                        if S.Flags.Propag /= Propag_None then                           Internal_Error ("order_signal(1)");                        end if;                        S.Flags.Propag := Propag_Being_Driving;                     end loop;                     for I in Resolv.Sig_Range.First .. Resolv.Sig_Range.Last                     loop                        S := Sig_Table.Table (I);                        --  Compute driving value of the sources.                        for J in 1 .. S.Nbr_Ports loop                           Order_Signal (S.Ports (J - 1), Propag_Driving);                        end loop;                     end loop;                     for I in Resolv.Sig_Range.First .. Resolv.Sig_Range.Last                     loop                        S := Sig_Table.Table (I);                        S.Flags.Propag := Propag_Driving;                     end loop;                     if Is_Eff_Drv (Sig) then                        if Resolv.Sig_Range.First = Resolv.Sig_Range.Last then                           Add_Propagation ((Kind => Eff_One_Resolved,                                             Sig => Sig));                        else                           Add_Propagation ((Kind => Eff_Multiple,                                             Resolv => Resolv));                        end if;                     else                        if Resolv.Sig_Range.First = Resolv.Sig_Range.Last then                           Add_Propagation ((Kind => Drv_One_Resolved,                                             Sig => Sig));                        else                           Add_Propagation ((Kind => Drv_Multiple,                                             Resolv => Resolv));                        end if;                     end if;                  end;               end if;            when Mode_Signal_Implicit =>               Sig.Flags.Propag := Propag_Being_Driving;               Order_Signal_List (Sig, Propag_Done);               Sig.Flags.Propag := Propag_Done;               case Mode_Signal_Implicit (Sig.S.Mode_Sig) is                  when Mode_Guard =>                     Add_Propagation ((Kind => Imp_Guard, Sig => Sig));                  when Mode_Stable =>                     Add_Propagation ((Kind => Imp_Stable, Sig => Sig));                  when Mode_Quiet =>                     Add_Propagation ((Kind => Imp_Quiet, Sig => Sig));                  when Mode_Transaction =>                     Add_Propagation ((Kind => Imp_Transaction, Sig => Sig));                  when Mode_Delayed =>                     Add_Propagation ((Kind => Imp_Delayed, Sig => Sig));               end case;               return;            when Mode_Conv_In =>               --  In conversion signals have no driving value               null;            when Mode_Conv_Out =>               declare                  Conv : Sig_Conversion_Acc;               begin                  Conv := Sig.S.Conv;                  for I in Conv.Dest.First .. Conv.Dest.Last loop                     Sig_Table.Table (I).Flags.Propag := Propag_Being_Driving;                  end loop;                  for I in Conv.Src.First .. Conv.Src.Last loop                     Order_Signal (Sig_Table.Table (I), Propag_Driving);                  end loop;                  Add_Propagation ((Kind => Out_Conversion, Conv => Conv));                  for I in Conv.Dest.First .. Conv.Dest.Last loop                     Sig_Table.Table (I).Flags.Propag := Propag_Done;                  end loop;               end;            when Mode_End =>               Internal_Error ("order_signal: mode_end");         end case;      end if;      -- Effective value.      if Order = Propag_Driving then         --  Will be done later.         return;      end if;      case Sig.S.Mode_Sig is         when Mode_Signal           | Mode_Buffer =>            --  Effective value is driving value.            Sig.Flags.Propag := Propag_Done;         when Mode_Linkage           | Mode_Out =>            --  No effective value.            Sig.Flags.Propag := Propag_Done;         when Mode_Inout           | Mode_In =>            if Sig.S.Effective = null then               --  Effective value is driving value or initial value.               null;            else               Sig.Flags.Propag := Propag_Being_Effective;               Order_Signal (Sig.S.Effective, Propag_Done);               Add_Propagation ((Kind => Eff_Actual, Sig => Sig));               Sig.Flags.Propag := Propag_Done;            end if;         when Mode_Stable           | Mode_Guard           | Mode_Quiet           | Mode_Transaction           | Mode_Delayed =>            --  Sig.Propag is already set to PROPAG_DONE.            null;         when Mode_Conv_In =>            declare               Conv : Sig_Conversion_Acc;            begin               Conv := Sig.S.Conv;               for I in Conv.Dest.First .. Conv.Dest.Last loop                  Sig_Table.Table (I).Flags.Propag := Propag_Being_Effective;               end loop;               for I in Conv.Src.First .. Conv.Src.Last loop                  Order_Signal (Sig_Table.Table (I), Propag_Done);               end loop;               Add_Propagation ((Kind => In_Conversion, Conv => Conv));               for I in Conv.Dest.First .. Conv.Dest.Last loop                  Sig_Table.Table (I).Flags.Propag := Propag_Done;               end loop;            end;         when Mode_Conv_Out =>            --  No effective value.            null;         when Mode_End =>            Internal_Error ("order_signal: mode_end");      end case;   end Order_Signal;   procedure Set_Net (Sig : Ghdl_Signal_Ptr;                      Net : Signal_Net_Type;                      Link : Ghdl_Signal_Ptr)   is      use Astdio;      use Stdio;   begin      if Sig = null then         return;      end if;      if Boolean'(False) then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -