📄 grt-avhpi.adb
字号:
-- GHDL Run Time (GRT) - VHPI implementation for Ada.-- Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold---- GHDL is free software; you can redistribute it and/or modify it under-- the terms of the GNU General Public License as published by the Free-- Software Foundation; either version 2, or (at your option) any later-- version.---- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY-- WARRANTY; without even the implied warranty of MERCHANTABILITY or-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License-- for more details.---- You should have received a copy of the GNU General Public License-- along with GCC; see the file COPYING. If not, write to the Free-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA-- 02111-1307, USA.with Grt.Errors; use Grt.Errors;with Grt.Vstrings; use Grt.Vstrings;with Grt.Rtis_Utils; use Grt.Rtis_Utils;package body Grt.Avhpi is procedure Get_Root_Inst (Res : out VhpiHandleT) is begin Res := (Kind => VhpiRootInstK, Ctxt => Get_Top_Context); end Get_Root_Inst; procedure Get_Package_Inst (Res : out VhpiHandleT) is begin Res := (Kind => VhpiIteratorK, Ctxt => (Base => Null_Address, Block => To_Ghdl_Rti_Access (Ghdl_Rti_Top_Ptr)), Rel => VhpiPackInsts, It_Cur => 0, It2 => 0, Max2 => 0); end Get_Package_Inst; -- Number of elements in an array. function Ranges_To_Length (Rngs : Ghdl_Range_Array; Indexes : Ghdl_Rti_Arr_Acc) return Ghdl_Index_Type is Res : Ghdl_Index_Type; begin Res := 1; for I in Rngs'Range loop Res := Res * Range_To_Length (Rngs (I), Get_Base_Type (Indexes (I - Rngs'First))); end loop; return Res; end Ranges_To_Length; procedure Vhpi_Iterator (Rel : VhpiOneToManyT; Ref : VhpiHandleT; Res : out VhpiHandleT; Error : out AvhpiErrorT) is begin -- Default value in case of success. Res := (Kind => VhpiIteratorK, Ctxt => Ref.Ctxt, Rel => Rel, It_Cur => 0, It2 => 0, Max2 => 0); Error := AvhpiErrorOk; case Rel is when VhpiInternalRegions => case Ref.Kind is when VhpiRootInstK | VhpiArchBodyK | VhpiBlockStmtK | VhpiIfGenerateK => return; when VhpiForGenerateK => Res.It2 := 1; return; when VhpiCompInstStmtK => Get_Instance_Context (Ref.Inst, Ref.Ctxt, Res.Ctxt); return; when others => null; end case; when VhpiDecls => case Ref.Kind is when VhpiArchBodyK | VhpiBlockStmtK | VhpiIfGenerateK | VhpiForGenerateK => return; when VhpiRootInstK | VhpiPackInstK => Res.It2 := 1; return; when VhpiCompInstStmtK => Get_Instance_Context (Ref.Inst, Ref.Ctxt, Res.Ctxt); Res.It2 := 1; return; when others => null; end case; when VhpiIndexedNames => case Ref.Kind is when VhpiGenericDeclK => Res := (Kind => AvhpiNameIteratorK, Ctxt => Ref.Ctxt, N_Addr => Loc_To_Addr (Ref.Obj.Common.Depth, Ref.Obj.Loc, Ref.Ctxt), N_Type => Ref.Obj.Obj_Type, N_Idx => 0, N_Obj => Ref.Obj); when others => Error := AvhpiErrorNotImplemented; return; end case; case Res.N_Type.Kind is when Ghdl_Rtik_Subtype_Array => declare St : Ghdl_Rtin_Subtype_Array_Acc := To_Ghdl_Rtin_Subtype_Array_Acc (Res.N_Type); Bt : Ghdl_Rtin_Type_Array_Acc := St.Basetype; Rngs : Ghdl_Range_Array (0 .. Bt.Nbr_Dim - 1); begin Bound_To_Range (Loc_To_Addr (St.Common.Depth, St.Bounds, Res.Ctxt), Bt, Rngs); Res.N_Idx := Ranges_To_Length (Rngs, Bt.Indexes); end; when others => Error := AvhpiErrorBadRel; end case; return; when others => null; end case; -- Failure. Res := Null_Handle; Error := AvhpiErrorNotImplemented; end Vhpi_Iterator; procedure Vhpi_Scan_Indexed_Name (Iterator : in out VhpiHandleT; Res : out VhpiHandleT; Error : out AvhpiErrorT) is procedure Update (S : Ghdl_Index_Type) is begin Iterator.N_Addr := Iterator.N_Addr + (S / Storage_Unit); end Update; Is_Sig : Boolean; El_Type : Ghdl_Rti_Access; begin if Iterator.N_Idx = 0 then Error := AvhpiErrorIteratorEnd; return; end if; El_Type := To_Ghdl_Rtin_Type_Array_Acc (Get_Base_Type (Iterator.N_Type)).Element; Res := (Kind => VhpiIndexedNameK, Ctxt => Iterator.Ctxt, N_Addr => Iterator.N_Addr, N_Type => El_Type, N_Idx => 0, N_Obj => Iterator.N_Obj); -- Increment Address. case Iterator.N_Obj.Common.Kind is when Ghdl_Rtik_Generic => Is_Sig := False; when others => Internal_Error ("vhpi_scan_indexed_name(1)"); end case; case Get_Base_Type (El_Type).Kind is when Ghdl_Rtik_Type_P64 => if Is_Sig then Update (Address'Size); else Update (Ghdl_I64'Size); end if; when others => Internal_Error ("vhpi_scan_indexed_name"); end case; Iterator.N_Idx := Iterator.N_Idx - 1; Error := AvhpiErrorOk; end Vhpi_Scan_Indexed_Name; procedure Vhpi_Scan_Internal_Regions (Iterator : in out VhpiHandleT; Res : out VhpiHandleT; Error : out AvhpiErrorT) is Blk : Ghdl_Rtin_Block_Acc; Ch : Ghdl_Rti_Access; Nblk : Ghdl_Rtin_Block_Acc; begin Blk := To_Ghdl_Rtin_Block_Acc (Iterator.Ctxt.Block); if Blk = null then Error := AvhpiErrorIteratorEnd; return; end if; loop << Again >> null; if Iterator.It_Cur >= Blk.Nbr_Child then Error := AvhpiErrorIteratorEnd; return; end if; Ch := Blk.Children (Iterator.It_Cur); Nblk := To_Ghdl_Rtin_Block_Acc (Ch); if Iterator.Max2 /= 0 then -- A for generate. Iterator.It2 := Iterator.It2 + 1; if Iterator.It2 >= Iterator.Max2 then -- End of loop. Iterator.Max2 := 0; Iterator.It_Cur := Iterator.It_Cur + 1; goto Again; else declare Base : Address; begin Base := To_Addr_Acc (Iterator.Ctxt.Base + Nblk.Loc.Off).all; Base := Base + Iterator.It2 * Nblk.Size; Res := (Kind => VhpiForGenerateK, Ctxt => (Base => Base, Block => Ch)); Error := AvhpiErrorOk; return; end; end if; end if; Iterator.It_Cur := Iterator.It_Cur + 1; case Ch.Kind is when Ghdl_Rtik_Process => Res := (Kind => VhpiProcessStmtK, Ctxt => (Base => Iterator.Ctxt.Base + Nblk.Loc.Off, Block => Ch)); Error := AvhpiErrorOk; return; when Ghdl_Rtik_Block => Res := (Kind => VhpiBlockStmtK, Ctxt => (Base => Iterator.Ctxt.Base + Nblk.Loc.Off, Block => Ch)); Error := AvhpiErrorOk; return; when Ghdl_Rtik_If_Generate => Res := (Kind => VhpiIfGenerateK, Ctxt => (Base => To_Addr_Acc (Iterator.Ctxt.Base + Nblk.Loc.Off).all, Block => Ch)); -- Return only if the condition is true. if Res.Ctxt.Base /= Null_Address then Error := AvhpiErrorOk; return; end if; when Ghdl_Rtik_For_Generate => Res := (Kind => VhpiForGenerateK, Ctxt => (Base => To_Addr_Acc (Iterator.Ctxt.Base + Nblk.Loc.Off).all, Block => Ch)); Iterator.Max2 := Get_For_Generate_Length (Nblk, Iterator.Ctxt); Iterator.It2 := 0; if Iterator.Max2 > 0 then Iterator.It_Cur := Iterator.It_Cur - 1; Error := AvhpiErrorOk; return; end if; -- If the iterator range is nul, then continue to scan. when Ghdl_Rtik_Instance => Res := (Kind => VhpiCompInstStmtK, Ctxt => Iterator.Ctxt, Inst => To_Ghdl_Rtin_Instance_Acc (Ch)); Error := AvhpiErrorOk; return; when others => -- Next one. null; end case; end loop; end Vhpi_Scan_Internal_Regions; procedure Rti_To_Handle (Rti : Ghdl_Rti_Access; Ctxt : Rti_Context; Res : out VhpiHandleT) is begin case Rti.Kind is when Ghdl_Rtik_Signal => Res := (Kind => VhpiSigDeclK, Ctxt => Ctxt, Obj => To_Ghdl_Rtin_Object_Acc (Rti)); when Ghdl_Rtik_Port => Res := (Kind => VhpiPortDeclK, Ctxt => Ctxt, Obj => To_Ghdl_Rtin_Object_Acc (Rti)); when Ghdl_Rtik_Generic => Res := (Kind => VhpiGenericDeclK, Ctxt => Ctxt, Obj => To_Ghdl_Rtin_Object_Acc (Rti)); when Ghdl_Rtik_Subtype_Array | Ghdl_Rtik_Subtype_Array_Ptr => declare Atype : Ghdl_Rtin_Subtype_Array_Acc; Bt : Ghdl_Rtin_Type_Array_Acc; begin Atype := To_Ghdl_Rtin_Subtype_Array_Acc (Rti); Bt := Atype.Basetype; if Atype.Name = Bt.Name then Res := (Kind => VhpiArrayTypeDeclK, Ctxt => Ctxt, Atype => Rti); else Res := (Kind => VhpiSubtypeDeclK, Ctxt => Ctxt, Atype => Rti); end if; end; when Ghdl_Rtik_Type_B2 | Ghdl_Rtik_Type_E8 => Res := (Kind => VhpiEnumTypeDeclK, Ctxt => Ctxt, Atype => Rti); when others => Res := (Kind => VhpiUndefined, Ctxt => Ctxt); end case; end Rti_To_Handle; procedure Vhpi_Scan_Decls (Iterator : in out VhpiHandleT; Res : out VhpiHandleT; Error : out AvhpiErrorT) is Blk : Ghdl_Rtin_Block_Acc; Ch : Ghdl_Rti_Access; Obj : Ghdl_Rtin_Object_Acc; begin Blk := To_Ghdl_Rtin_Block_Acc (Iterator.Ctxt.Block); -- If there is no context, returns now. -- This may happen for a unbound compinststmt. if Blk = null then Error := AvhpiErrorIteratorEnd; return; end if; if Iterator.It2 = 1 then case Blk.Common.Kind is when Ghdl_Rtik_Architecture => -- Iterate on the entity. Blk := To_Ghdl_Rtin_Block_Acc (Blk.Parent); when Ghdl_Rtik_Package_Body => -- Iterate on the package. Blk := To_Ghdl_Rtin_Block_Acc (Blk.Parent); when Ghdl_Rtik_Package => -- Only for std.standard. Iterator.It2 := 0; when others => Internal_Error ("vhpi_scan_decls"); end case; end if; loop loop exit when Iterator.It_Cur >= Blk.Nbr_Child; Ch := Blk.Children (Iterator.It_Cur); Obj := To_Ghdl_Rtin_Object_Acc (Ch); Iterator.It_Cur := Iterator.It_Cur + 1; case Ch.Kind is when Ghdl_Rtik_Port | Ghdl_Rtik_Generic | Ghdl_Rtik_Signal | Ghdl_Rtik_Subtype_Array | Ghdl_Rtik_Subtype_Array_Ptr | Ghdl_Rtik_Type_E8 | Ghdl_Rtik_Type_B2 => Rti_To_Handle (Ch, Iterator.Ctxt, Res); if Res.Kind /= VhpiUndefined then Error := AvhpiErrorOk; return; else Internal_Error ("vhpi_handle"); end if; when others => null; end case; end loop; case Iterator.It2 is when 1 => -- Iterate on the architecture/package decl. Iterator.It2 := 0; Blk := To_Ghdl_Rtin_Block_Acc (Iterator.Ctxt.Block); Iterator.It_Cur := 0; when others => exit; end case; end loop; Error := AvhpiErrorIteratorEnd; end Vhpi_Scan_Decls; procedure Vhpi_Scan (Iterator : in out VhpiHandleT; Res : out VhpiHandleT; Error : out AvhpiErrorT) is begin if Iterator.Kind = AvhpiNameIteratorK then case Iterator.N_Type.Kind is when Ghdl_Rtik_Subtype_Array => Vhpi_Scan_Indexed_Name (Iterator, Res, Error); when others => Error := AvhpiErrorHandle; Res := Null_Handle; end case; return; elsif Iterator.Kind /= VhpiIteratorK then Error := AvhpiErrorHandle; Res := Null_Handle; return; end if; case Iterator.Rel is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -