diff options
author | Jonas Baggett <jonasb@tranquille.ch> | 2016-08-05 14:28:25 +0200 |
---|---|---|
committer | Jonas Baggett <jonasb@tranquille.ch> | 2016-11-02 13:25:04 +0100 |
commit | df259b99050928cd72874377d7797c0de797935b (patch) | |
tree | e28835c3357a82ba1896130445d16f4999a480d7 /src/grt | |
parent | b869a4acb52358fe8ca5decaac826af056bfdfca (diff) | |
download | ghdl-df259b99050928cd72874377d7797c0de797935b.tar.gz ghdl-df259b99050928cd72874377d7797c0de797935b.tar.bz2 ghdl-df259b99050928cd72874377d7797c0de797935b.zip |
Support added for * and **. Please note that wildcards inside names like /top/sub*/... are not supported yet, only synthax like /top/*/... works for now. Support for wildcards inside names will be added on version 1.2, at the same time as simple regexp support.
Current version set to 1.1
Diffstat (limited to 'src/grt')
-rw-r--r-- | src/grt/grt-errors.adb | 6 | ||||
-rw-r--r-- | src/grt/grt-errors.ads | 1 | ||||
-rw-r--r-- | src/grt/grt-fst.adb | 45 | ||||
-rw-r--r-- | src/grt/grt-vcd.adb | 34 | ||||
-rw-r--r-- | src/grt/grt-wave_opt-design.adb | 152 | ||||
-rw-r--r-- | src/grt/grt-wave_opt-design.ads | 15 | ||||
-rw-r--r-- | src/grt/grt-wave_opt-file-debug.adb | 2 | ||||
-rw-r--r-- | src/grt/grt-wave_opt-file.adb | 83 | ||||
-rw-r--r-- | src/grt/grt-wave_opt-file.ads | 8 | ||||
-rw-r--r-- | src/grt/grt-wave_opt.adb | 4 | ||||
-rw-r--r-- | src/grt/grt-wave_opt.ads | 14 | ||||
-rw-r--r-- | src/grt/grt-waves.adb | 37 |
12 files changed, 254 insertions, 147 deletions
diff --git a/src/grt/grt-errors.adb b/src/grt/grt-errors.adb index 56d1e6f81..9a48de48e 100644 --- a/src/grt/grt-errors.adb +++ b/src/grt/grt-errors.adb @@ -142,6 +142,12 @@ package body Grt.Errors is Newline_Err; end Report_E; + procedure Report_E (N : Integer) is + begin + Put_Err (N); + Newline_Err; + end Report_E; + procedure Report_E (Str : Std_String_Ptr) is subtype Ada_Str is String (1 .. Natural (Str.Bounds.Dim_1.Length)); diff --git a/src/grt/grt-errors.ads b/src/grt/grt-errors.ads index 25900da69..974ef3820 100644 --- a/src/grt/grt-errors.ads +++ b/src/grt/grt-errors.ads @@ -46,6 +46,7 @@ package Grt.Errors is procedure Report_Now_C; procedure Report_E (Str : String); procedure Report_E (Str : Std_String_Ptr); + procedure Report_E (N : Integer); -- Complete error message. procedure Error (Str : String); diff --git a/src/grt/grt-fst.adb b/src/grt/grt-fst.adb index 20455b3aa..8358967e0 100644 --- a/src/grt/grt-fst.adb +++ b/src/grt/grt-fst.adb @@ -31,7 +31,7 @@ -- visible on the tree view (SST) of gtkwave, but both of them are visible -- when no item is selected in the tree view and are mixed together. -- (Same issue with VCD waves.) --- + After calling FST_Put_Hierarchy (Pack, Wave_Elem), Avhpi_Error is +-- + After calling FST_Put_Hierarchy (Pack, Match_List), Avhpi_Error is -- raised several times when no signal paths are provided in a wave option -- file. It has no consequences other than a printed message. -- (Same issue with VCD waves.) @@ -413,10 +413,10 @@ package body Grt.Fst is end Fst_Add_Signal; procedure Fst_Put_Hierarchy - (Inst : VhpiHandleT; Wave_Elem : Wave_Opt.Elem_Acc); + (Inst : VhpiHandleT; Match_List : Design.Match_List); procedure Fst_Put_Scope - (Scope : fstScopeType; Decl : VhpiHandleT; Wave_Elem : Wave_Opt.Elem_Acc) + (Scope : fstScopeType; Decl : VhpiHandleT; Match_List : Design.Match_List) is Name : String (1 .. 128); Name_Len : Integer; @@ -467,17 +467,17 @@ package body Grt.Fst is fstWriterSetScope (Context, Scope, To_Ghdl_C_String (Name'Address), null); - Fst_Put_Hierarchy (Decl, Wave_Elem); + Fst_Put_Hierarchy (Decl, Match_List); fstWriterSetUpscope (Context); end Fst_Put_Scope; procedure Fst_Put_Hierarchy - (Inst : VhpiHandleT; Wave_Elem : Wave_Opt.Elem_Acc) + (Inst : VhpiHandleT; Match_List : Design.Match_List) is Decl_It : VhpiHandleT; Decl : VhpiHandleT; Error : AvhpiErrorT; - Wave_Elem_Child : Wave_Opt.Elem_Acc; + Match_List_Child : Design.Match_List; begin Vhpi_Iterator (VhpiDecls, Inst, Decl_It, Error); if Error /= AvhpiErrorOk then @@ -497,9 +497,9 @@ package body Grt.Fst is case Vhpi_Get_Kind (Decl) is when VhpiPortDeclK | VhpiSigDeclK => - Wave_Elem_Child := Get_Cursor - (Wave_Elem, Avhpi_Get_Base_Name (Decl), Is_Signal => True); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl), Is_Signal => True); + if Is_Displayed (Match_List_Child) then Fst_Add_Signal (Decl); end if; when others => @@ -527,20 +527,21 @@ package body Grt.Fst is return; end if; - Wave_Elem_Child := Get_Cursor (Wave_Elem, Avhpi_Get_Base_Name (Decl)); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl)); + if Is_Displayed (Match_List_Child) then case Vhpi_Get_Kind (Decl) is when VhpiIfGenerateK => Fst_Put_Scope - (FST_ST_VHDL_IF_GENERATE, Decl, Wave_Elem_Child); + (FST_ST_VHDL_IF_GENERATE, Decl, Match_List_Child); when VhpiForGenerateK => Fst_Put_Scope - (FST_ST_VHDL_FOR_GENERATE, Decl, Wave_Elem_Child); + (FST_ST_VHDL_FOR_GENERATE, Decl, Match_List_Child); when VhpiBlockStmtK => - Fst_Put_Scope (FST_ST_VHDL_BLOCK, Decl, Wave_Elem_Child); + Fst_Put_Scope (FST_ST_VHDL_BLOCK, Decl, Match_List_Child); when VhpiCompInstStmtK => Fst_Put_Scope - (FST_ST_VHDL_ARCHITECTURE, Decl, Wave_Elem_Child); + (FST_ST_VHDL_ARCHITECTURE, Decl, Match_List_Child); when others => null; end case; @@ -624,7 +625,7 @@ package body Grt.Fst is Pack : VhpiHandleT; Error : AvhpiErrorT; Root : VhpiHandleT; - Wave_Elem : Wave_Opt.Elem_Acc; + Match_List : Design.Match_List; begin -- Do nothing if there is no VCD file to generate. if Context = Null_fstContext then @@ -650,17 +651,17 @@ package body Grt.Fst is Avhpi_Error (Error); return; end if; - Wave_Elem := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); - if Is_Displayed (Wave_Elem) then - Fst_Put_Hierarchy (Pack, Wave_Elem); + Match_List := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); + if Is_Displayed (Match_List) then + Fst_Put_Hierarchy (Pack, Match_List); end if; end loop; -- Then top entity. Get_Root_Inst (Root); - Wave_Elem := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); - if Is_Displayed (Wave_Elem) then - Fst_Put_Hierarchy (Root, Wave_Elem); + Match_List := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); + if Is_Displayed (Match_List) then + Fst_Put_Hierarchy (Root, Match_List); end if; Wave_Opt.Design.Last_Checks; diff --git a/src/grt/grt-vcd.adb b/src/grt/grt-vcd.adb index b44090ed5..eab5fa89a 100644 --- a/src/grt/grt-vcd.adb +++ b/src/grt/grt-vcd.adb @@ -31,7 +31,7 @@ -- visible on the tree view (SST) of gtkwave, but both of them are visible -- when no item is selected in the tree view and are mixed together. -- (Same issue with FST waves.) --- + After calling Vcd_Put_Hierarchy (Pack, Wave_Elem), Avhpi_Error is +-- + After calling Vcd_Put_Hierarchy (Pack, Match_List), Avhpi_Error is -- raised several times when no signal paths are provided in a wave option -- file. It has no consequences other than a printed message. -- (Same issue with FST waves.) @@ -532,12 +532,12 @@ package body Grt.Vcd is end Add_Signal; procedure Vcd_Put_Hierarchy - (Inst : VhpiHandleT; Wave_Elem : Wave_Opt.Elem_Acc) + (Inst : VhpiHandleT; Match_List : Design.Match_List) is Decl_It : VhpiHandleT; Decl : VhpiHandleT; Error : AvhpiErrorT; - Wave_Elem_Child : Wave_Opt.Elem_Acc; + Match_List_Child : Design.Match_List; begin Vhpi_Iterator (VhpiDecls, Inst, Decl_It, Error); if Error /= AvhpiErrorOk then @@ -557,9 +557,9 @@ package body Grt.Vcd is case Vhpi_Get_Kind (Decl) is when VhpiPortDeclK | VhpiSigDeclK => - Wave_Elem_Child := Get_Cursor - (Wave_Elem, Avhpi_Get_Base_Name (Decl), Is_Signal => True); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl), Is_Signal => True); + if Is_Displayed (Match_List_Child) then Add_Signal (Decl); end if; when others => @@ -590,14 +590,14 @@ package body Grt.Vcd is | VhpiForGenerateK | VhpiBlockStmtK | VhpiCompInstStmtK => - Wave_Elem_Child := Get_Cursor - (Wave_Elem, Avhpi_Get_Base_Name (Decl)); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl)); + if Is_Displayed (Match_List_Child) then Vcd_Put ("$scope module "); Vcd_Put_Name (Decl); Vcd_Putc (' '); Vcd_Put_End; - Vcd_Put_Hierarchy (Decl, Wave_Elem_Child); + Vcd_Put_Hierarchy (Decl, Match_List_Child); Vcd_Put ("$upscope "); Vcd_Put_End; end if; @@ -873,7 +873,7 @@ package body Grt.Vcd is Pack : VhpiHandleT; Error : AvhpiErrorT; Root : VhpiHandleT; - Wave_Elem : Wave_Opt.Elem_Acc; + Match_List : Design.Match_List; begin -- Do nothing if there is no VCD file to generate. if Vcd_Close = null then @@ -894,17 +894,17 @@ package body Grt.Vcd is Avhpi_Error (Error); return; end if; - Wave_Elem := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); - if Is_Displayed (Wave_Elem) then - Vcd_Put_Hierarchy (Pack, Wave_Elem); + Match_List := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); + if Is_Displayed (Match_List) then + Vcd_Put_Hierarchy (Pack, Match_List); end if; end loop; -- Then top entity. Get_Root_Inst (Root); - Wave_Elem := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); - if Is_Displayed (Wave_Elem) then - Vcd_Put_Hierarchy (Root, Wave_Elem); + Match_List := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); + if Is_Displayed (Match_List) then + Vcd_Put_Hierarchy (Root, Match_List); end if; Wave_Opt.Design.Last_Checks; diff --git a/src/grt/grt-wave_opt-design.adb b/src/grt/grt-wave_opt-design.adb index 2002cca0d..989969ecd 100644 --- a/src/grt/grt-wave_opt-design.adb +++ b/src/grt/grt-wave_opt-design.adb @@ -33,72 +33,150 @@ package body Grt.Wave_Opt.Design is -- Find the element that matches the name given. Starts with the element -- given, then go thru all its siblings function Find_Cursor (Name : String; - First_Sibling : Elem_Acc; + Parent : Match_List; Is_Signal : Boolean := False) - return Elem_Acc; + return Match_List; + + -- If the name of the current design object matches with the child tree + -- element given in parameter (Elem_Acc), this procedure is called to add + -- the latter to the list of all the child tree elements that match a design + -- object. + -- A list needs to be done, because if /top/sub/a, /top/sub/b and /top/sub/c + -- exist in the design and if we have /top/sub/a, /top/*/b and /top/**/c in + -- the tree, then a list of the child tree elements of /top will be done + -- with sub, * and ** so that /top/sub/a, /top/sub/b and /top/sub/c can be + -- matched with respectively /top/sub/a, /top/*/b and /top/**/c + procedure Match_List_Append + (List : in out Match_List; Tree_Elem : Elem_Acc); + -- TODO : Deallocate the list somewhere, but the memory gain shouldn't be + -- significative function Get_Top_Cursor (Tree_Index : Tree_Index_Type; Name : Ghdl_C_String) - return Elem_Acc + return Match_List is - Root : Elem_Acc; + Root : Match_List; begin - Root := Trees (Tree_Index); - if State = Write_File and then Root.Next_Child = null then + if State = Write_File and then Trees (Tree_Index).Next_Child = null then Write_Tree_Comment (Tree_Index); end if; + Root := new Match_Elem_Type'(Trees (Tree_Index), null); return Get_Cursor (Root, Name); end Get_Top_Cursor; - function Get_Cursor (Parent : Elem_Acc; + function Get_Cursor (Parent : Match_List; Name : Ghdl_C_String; - Is_Signal : Boolean := False) return Elem_Acc + Is_Signal : Boolean := False) return Match_List is - Cursor : Elem_Acc; - Dummy_Bool : Boolean; + Tree_Elem_Cursor : Elem_Acc; + Last_Updated : Boolean; Str_Name : constant String := Name (1 .. strlen (Name)); begin case State is when Write_File => - Cursor := Parent; - Update_Tree (Cursor => Cursor, - Updated => Dummy_Bool, - Elem_Name => Str_Name, - Level => Parent.Level + 1); + Tree_Elem_Cursor := Parent.Tree_Elem; + Last_Updated := True; + Update_Tree (Cursor => Tree_Elem_Cursor, + Last_Updated => Last_Updated, + Elem_Expr => Str_Name, + Level => Tree_Elem_Cursor.Level + 1); if Is_Signal then - Write_Signal_Path (Cursor); + Write_Signal_Path (Tree_Elem_Cursor); end if; - return Cursor; + return new Match_Elem_Type'(Tree_Elem_Cursor, null); when Display_Tree => - return Find_Cursor (Str_Name, Parent.Next_Child, Is_Signal); + return Find_Cursor (Str_Name, Parent, Is_Signal); when Display_All => return null; end case; end Get_Cursor; function Find_Cursor (Name : String; - First_Sibling : Elem_Acc; + Parent : Match_List; Is_Signal : Boolean := False) - return Elem_Acc + return Match_List is - Cursor : Elem_Acc; + Tree_Elem_Cursor : Elem_Acc; + Parent_Cursor, List : Match_List; + -- + function Match_Expr return Boolean is + begin + if Tree_Elem_Cursor.Expr.all = Name then + return True; + elsif Tree_Elem_Cursor.Expr.all = "*" then + -- Returns true in the following cases : + -- Design object : /top/a | Tree element : /top/* + -- Design object : /top/sub/... | Tree element : /top/*/... + if Is_Signal xor Tree_Elem_Cursor.Next_Child /= null then + return True; + end if; + elsif Tree_Elem_Cursor.Expr.all = "**" then + -- Returns true in the following cases : + -- Design object : /top/sub/... | Tree element : /top/** + -- Design object : /top/a | Tree element : /top/** + -- But will return false in the following case : + -- Design object : /top/a | Tree element : /top/**/x + if not Is_Signal or else Tree_Elem_Cursor.Next_Child = null then + return True; + end if; + end if; + return False; + end Match_Expr; + + function Get_Cursor_Kind return Elem_Kind_Type is + begin + if Tree_Elem_Cursor.Expr.all = "**" then + return Recursion; + elsif Is_Signal then + return Signal; + else + return Pkg_Entity; + end if; + end Get_Cursor_Kind; begin - Cursor := First_Sibling; + Parent_Cursor := Parent; loop - if Cursor = null then - return null; - elsif Cursor.Name.all = Name then - if Is_Signal then - Cursor.Kind := Signal; - else - Cursor.Kind := Pkg_Entity; + exit when Parent_Cursor = null; + Tree_Elem_Cursor := Parent_Cursor.Tree_Elem.Next_Child; + if Parent_Cursor.Tree_Elem.Expr.all = "**" then + -- Add the current tree element to the list in the following cases: + -- Design object : /top/y/x | Tree element : /top/**/x + -- Design object : /top/y/x/... | Tree element : /top/**/x/... + -- where x matchs the Name parameter, ** is the parent expression + if Tree_Elem_Cursor /= null + and then Tree_Elem_Cursor.Expr.all = Name + then + Match_List_Append (List, Tree_Elem_Cursor); + -- Add the parent tree element (**) to the list in the following + -- cases: + -- Design object : /top/y/x/... | Tree element : /top/** + -- Design object : /top/y/x | Tree element : /top/** + -- But it won't do it in the following case: + -- Design object : /top/y/x | Tree element : /top/**/z + -- as x != z + elsif not Is_Signal or else Tree_Elem_Cursor = null then + Match_List_Append (List, Parent_Cursor.Tree_Elem); end if; - return Cursor; end if; - Cursor := Cursor.Next_Sibling; + loop + exit when Tree_Elem_Cursor = null; + if Match_Expr then + Tree_Elem_Cursor.Kind := Get_Cursor_Kind; + Match_List_Append (List, Tree_Elem_Cursor); + end if; + Tree_Elem_Cursor := Tree_Elem_Cursor.Next_Sibling; + end loop; + Parent_Cursor := Parent_Cursor.Next; end loop; + return List; end Find_Cursor; - function Is_Displayed (Cursor : Elem_Acc) return Boolean is + procedure Match_List_Append (List : in out Match_List; Tree_Elem : Elem_Acc) + is + begin + List := new Match_Elem_Type'(Tree_Elem => Tree_Elem, Next => List); + end Match_List_Append; + + function Is_Displayed (Cursor : Match_List) return Boolean is begin if State /= Display_Tree or else Cursor /= null then return True; @@ -129,14 +207,12 @@ package body Grt.Wave_Opt.Design is while Cursor /= null loop if Cursor.Kind = Not_Found then Print_Context (Cursor, Warning); - Report_C (Cursor.Name.all); + Report_C (Cursor.Expr.all); Report_C (" : first element of the path not found in design."); - Report_E (" more references may follow"); - elsif Cursor.Level = Cursor.Path_Context.Max_Level - and then Cursor.Kind = Pkg_Entity - then + Report_E (" More references may follow"); + elsif Cursor.Next_Child = null and then Cursor.Kind = Pkg_Entity then Print_Context (Cursor, Warning); - Report_C (Cursor.Name.all); + Report_C (Cursor.Expr.all); Report_E (" is not a signal"); else Check_Sub_Tree_If_All_Found (Cursor.Next_Child); diff --git a/src/grt/grt-wave_opt-design.ads b/src/grt/grt-wave_opt-design.ads index 54a96acfa..febb9f91b 100644 --- a/src/grt/grt-wave_opt-design.ads +++ b/src/grt/grt-wave_opt-design.ads @@ -38,20 +38,27 @@ with Grt.Types; use Grt.Types; package Grt.Wave_Opt.Design is pragma Preelaborate; + type Match_Elem_Type; + type Match_List is access Match_Elem_Type; + type Match_Elem_Type is record + Tree_Elem : Elem_Acc; + Next : Match_List; + end record; + -- Returns the top element of the tree corresponding to the index given, but -- only if the name given matches with it. Otherwise returns null function Get_Top_Cursor (Tree_Index : Tree_Index_Type; Name : Ghdl_C_String) - return Elem_Acc; + return Match_List; -- If there is an element in the parent element given that matches the name -- given, returns it, otherwise returns null function Get_Cursor - (Parent : Elem_Acc; Name : Ghdl_C_String; Is_Signal : Boolean := False) - return Elem_Acc; + (Parent : Match_List; Name : Ghdl_C_String; Is_Signal : Boolean := False) + return Match_List; -- Returns true if the element given is not null, which means it exists in -- the tree of the VHDL elements to be displayed - function Is_Displayed (Cursor : Elem_Acc) return Boolean; + function Is_Displayed (Cursor : Match_List) return Boolean; -- If relevent, read the whole tree and check if every element was found in -- design diff --git a/src/grt/grt-wave_opt-file-debug.adb b/src/grt/grt-wave_opt-file-debug.adb index 44878077a..0ecc1e840 100644 --- a/src/grt/grt-wave_opt-file-debug.adb +++ b/src/grt/grt-wave_opt-file-debug.adb @@ -56,7 +56,7 @@ package body Grt.Wave_Opt.File.Debug is while Sibling_Cursor /= null loop Put ((3 .. 2 * Sibling_Cursor.Level => ' ')); Put ('/'); - Put_Line (Sibling_Cursor.Name.all); + Put_Line (Sibling_Cursor.Expr.all); Dump_Sub_Tree (Sibling_Cursor.Next_Child); Sibling_Cursor := Sibling_Cursor.Next_Sibling; end loop; diff --git a/src/grt/grt-wave_opt-file.adb b/src/grt/grt-wave_opt-file.adb index bad572f15..bf961f8ae 100644 --- a/src/grt/grt-wave_opt-file.adb +++ b/src/grt/grt-wave_opt-file.adb @@ -39,7 +39,7 @@ -- the right tree while looking for signals to be displayed in the design. -- 2) Create only 1 case sensitive tree then latter when we have more -- informations, look for VHDL paths in the tree and merge elements who --- have the same name after lowering their characters. +-- have the same expression after lowering their characters. with System; use System; with Grt.Types; use Grt.Types; @@ -218,7 +218,7 @@ package body Grt.Wave_Opt.File is begin for I in Tree_Index_Type'Range loop Trees (I) := new Elem_Type; - Trees (I).Name := new String'(1 => Seps (I)); + Trees (I).Expr := new String'(1 => Seps (I)); Trees (I).Level := 0; end loop; end Initialize_Tree; @@ -233,13 +233,11 @@ package body Grt.Wave_Opt.File is is -- Can equal to 0 in case of error (like '.' as a full path) First, Last : Natural; - Path_Context : Path_Context_Acc; + Level : Positive; Tree_Index : Tree_Index_Type; Tree_Cursor : Elem_Acc; Tree_Updated : Boolean; begin - Path_Context := new Path_Context_Type'(Lineno => Lineno, - Max_Level => 0); To_Lower (Line); Last := Line'First; if Line (Line'First) = '/' then @@ -248,7 +246,7 @@ package body Grt.Wave_Opt.File is -- Catch '/' as a full path if Last > Line'Length then Error_Context - ("invalid signal path", Path_Context.Lineno, Line'First); + ("invalid signal path", Lineno, Line'First); end if; else -- '/' not allowed for package signal paths in a. Catch also the @@ -256,11 +254,13 @@ package body Grt.Wave_Opt.File is -- code to believe it's inside a package if Find (Line, '/') > 0 then Error_Context - ("invalid signal path", Path_Context.Lineno, Line'First); + ("invalid signal path", Lineno, Line'First); end if; Tree_Index := Pkg; end if; Tree_Cursor := Trees (Tree_Index); + Tree_Updated := False; + Level := 1; loop First := Last; @@ -276,29 +276,37 @@ package body Grt.Wave_Opt.File is Last := Last + 1; end loop; - Path_Context.Max_Level := Path_Context.Max_Level + 1; Update_Tree (Cursor => Tree_Cursor, - Updated => Tree_Updated, - Elem_Name => Line (First .. Last), - Level => Path_Context.Max_Level, - Path_Context => Path_Context); + Last_Updated => Tree_Updated, + Elem_Expr => Line (First .. Last), + Level => Level, + Lineno => Lineno); if Last = Line'Last then - if not Tree_Updated then - Error_Context ("ignored already known signal path", - Path_Context.Lineno, - Line'First, - Warning); + -- If there is the following content in the wave option file : + -- /top/a/b + -- /top/a + -- Then there is a conflict between those lines as according to the + -- 2nd line, a is a signal but it isn't according to the 1st line. + -- Then /top/a will supercede /top/a/b. + if not Tree_Updated and Tree_Cursor.Next_Child /= null then + Print_Context (Lineno, Line'First, Warning); + Report_C ("supercedes line "); + Report_C (Tree_Cursor.Lineno); + Report_E (" and possibly more lines in between"); + -- TODO : destroy Tree_Cursor.Next_Child + Tree_Cursor.Lineno := Lineno; + Tree_Cursor.Next_Child := null; end if; return; end if; + Level := Level + 1; -- Skip the separator Last := Last + 2; -- Catch signal paths ending with / or . if Last > Line'Last then - Error_Context - ("invalid signal path", Path_Context.Lineno, Line'First); + Error_Context ("invalid signal path", Lineno, Line'First); end if; end loop; @@ -306,10 +314,10 @@ package body Grt.Wave_Opt.File is end Parse_Path; procedure Update_Tree (Cursor : in out Elem_Acc; - Updated : out Boolean; - Elem_Name : String; + Last_Updated : in out Boolean; + Elem_Expr : String; Level : Natural; - Path_Context : Path_Context_Acc := null) + Lineno : Natural := 0) is Sibling_Cursor, Previous_Sibling_Cursor : Elem_Acc; Created_Elem : Elem_Acc; @@ -321,24 +329,37 @@ package body Grt.Wave_Opt.File is -- to no existing element ? Then we will create an element if Sibling_Cursor = null then Created_Elem := new Elem_Type; - Created_Elem.Name := new String'(Elem_Name); - Created_Elem.Path_Context := Path_Context; - Created_Elem.Column := Elem_Name'First; + Created_Elem.Expr := new String'(Elem_Expr); + Created_Elem.Lineno := Lineno; + Created_Elem.Column := Elem_Expr'First; Created_Elem.Level := Level; Created_Elem.Parent := Cursor; -- First element of level ? if Previous_Sibling_Cursor = null then + -- If there is the following content in the wave option file : + -- /top/a + -- /top/a/b + -- Then there is a conflict between those lines as according to + -- the 1st line, a is a signal but it isn't according to the 2nd + -- line. Then /top/a will supercede /top/a/b. + if Level > 1 and not Last_Updated then + Print_Context (Lineno, Elem_Expr'First, Warning); + Report_C ("superceded by line "); + Report_E (Cursor.Lineno); + return; + -- TODO : destroy Created_Elem + end if; Cursor.Next_Child := Created_Elem; else Previous_Sibling_Cursor.Next_Sibling := Created_Elem; end if; Cursor := Created_Elem; - Updated := True; + Last_Updated := True; return; -- Identifier was found in the tree ? Then move to its first child - elsif Elem_Name = Sibling_Cursor.Name.all then + elsif Elem_Expr = Sibling_Cursor.Expr.all then Cursor := Sibling_Cursor; - Updated := False; + Last_Updated := False; return; end if; Previous_Sibling_Cursor := Sibling_Cursor; @@ -414,17 +435,17 @@ package body Grt.Wave_Opt.File is Signal_Path (I) := Cursor; Cursor := Cursor.Parent; end loop; - if Signal_Path (1).Parent.Name.all = "/" then + if Signal_Path (1).Parent.Expr.all = "/" then Sep := '/'; Put (Write_Stream, Sep); else Sep := '.'; end if; for I in Signal_Path'Range loop - Put (Write_Stream, Signal_Path (I).Name.all); + Put (Write_Stream, Signal_Path (I).Expr.all); Put (Write_Stream, Sep); end loop; - Put_Line (Write_Stream, Signal.Name.all); + Put_Line (Write_Stream, Signal.Expr.all); end Write_Signal_Path; procedure Finalize is diff --git a/src/grt/grt-wave_opt-file.ads b/src/grt/grt-wave_opt-file.ads index fafc8eb0e..7cdb8217a 100644 --- a/src/grt/grt-wave_opt-file.ads +++ b/src/grt/grt-wave_opt-file.ads @@ -51,10 +51,10 @@ package Grt.Wave_Opt.File is -- Called when the option file is read or when the option file is created -- while reading the design hierarchy. procedure Update_Tree (Cursor : in out Elem_Acc; - Updated : out Boolean; - Elem_Name : String; + Last_Updated : in out Boolean; + Elem_Expr : String; Level : Natural; - Path_Context : Path_Context_Acc := null); + Lineno : Natural := 0); -- Destructor procedure Finalize; @@ -70,7 +70,7 @@ private Minor : Integer; end record; Version : Version_Type := (others => -1); - Current_Version : constant Version_Type := (Major => 1, Minor => 0); + Current_Version : constant Version_Type := (Major => 1, Minor => 1); type Sep_Array is array (Tree_Index_Type) of Character; diff --git a/src/grt/grt-wave_opt.adb b/src/grt/grt-wave_opt.adb index 0a6059adc..65391e05d 100644 --- a/src/grt/grt-wave_opt.adb +++ b/src/grt/grt-wave_opt.adb @@ -49,7 +49,7 @@ package body Grt.Wave_Opt is procedure Print_Context (Element : Elem_Acc; Severity : Severity_Type) is begin Print_Context - (Element.Path_Context.Lineno, Element.Column, Severity); + (Element.Lineno, Element.Column, Severity); end Print_Context; procedure Error_Context (Msg : String; @@ -69,7 +69,7 @@ package body Grt.Wave_Opt is (Msg : String; Element : Elem_Acc; Severity : Severity_Type := Error) is begin Error_Context - (Msg, Element.Path_Context.Lineno, Element.Column, Severity); + (Msg, Element.Lineno, Element.Column, Severity); end Error_Context; end Grt.Wave_Opt; diff --git a/src/grt/grt-wave_opt.ads b/src/grt/grt-wave_opt.ads index f14ed7ac5..5d7ed2ee1 100644 --- a/src/grt/grt-wave_opt.ads +++ b/src/grt/grt-wave_opt.ads @@ -45,19 +45,13 @@ package Grt.Wave_Opt is File_Path : String_Cst; - type Path_Context_Type is record - Lineno : Natural; - Max_Level : Natural; - end record; - type Path_Context_Acc is access Path_Context_Type; - - type Elem_Kind_Type is (Not_Found, Pkg_Entity, Signal); + type Elem_Kind_Type is (Not_Found, Pkg_Entity, Signal, Recursion); type Elem_Type; type Elem_Acc is access Elem_Type; type Elem_Type is record - Name : String_Cst; - Path_Context : Path_Context_Acc := null; - Column : Natural := 0; + Expr : String_Cst; + Lineno : Natural; + Column : Natural; Level : Natural; Kind : Elem_Kind_Type := Not_Found; Parent : Elem_Acc := null; diff --git a/src/grt/grt-waves.adb b/src/grt/grt-waves.adb index a94eae23f..33edffdf2 100644 --- a/src/grt/grt-waves.adb +++ b/src/grt/grt-waves.adb @@ -916,15 +916,15 @@ package body Grt.Waves is -- Create a hierarchy block. procedure Wave_Put_Hierarchy_Block (Inst : VhpiHandleT; Step : Step_Type; - Wave_Elem : Wave_Opt.Elem_Acc); + Match_List : Design.Match_List); procedure Wave_Put_Hierarchy_1 - (Inst : VhpiHandleT; Step : Step_Type; Wave_Elem : Wave_Opt.Elem_Acc) + (Inst : VhpiHandleT; Step : Step_Type; Match_List : Design.Match_List) is Decl_It : VhpiHandleT; Decl : VhpiHandleT; Error : AvhpiErrorT; - Wave_Elem_Child : Wave_Opt.Elem_Acc; + Match_List_Child : Design.Match_List; begin Vhpi_Iterator (VhpiDecls, Inst, Decl_It, Error); if Error /= AvhpiErrorOk then @@ -944,9 +944,9 @@ package body Grt.Waves is case Vhpi_Get_Kind (Decl) is when VhpiPortDeclK | VhpiSigDeclK => - Wave_Elem_Child := Get_Cursor - (Wave_Elem, Avhpi_Get_Base_Name (Decl), Is_Signal => True); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl), Is_Signal => True); + if Is_Displayed (Match_List_Child) then case Step is when Step_Name => Create_String_Id (Avhpi_Get_Base_Name (Decl)); @@ -985,14 +985,15 @@ package body Grt.Waves is Nbr_Scopes := Nbr_Scopes + 1; - Wave_Elem_Child := Get_Cursor (Wave_Elem, Avhpi_Get_Base_Name (Decl)); - if Is_Displayed (Wave_Elem_Child) then + Match_List_Child := Get_Cursor + (Match_List, Avhpi_Get_Base_Name (Decl)); + if Is_Displayed (Match_List_Child) then case Vhpi_Get_Kind (Decl) is when VhpiIfGenerateK | VhpiForGenerateK | VhpiBlockStmtK | VhpiCompInstStmtK => - Wave_Put_Hierarchy_Block (Decl, Step, Wave_Elem_Child); + Wave_Put_Hierarchy_Block (Decl, Step, Match_List_Child); when VhpiProcessStmtK => case Step is when Step_Name => @@ -1012,7 +1013,7 @@ package body Grt.Waves is procedure Wave_Put_Hierarchy_Block (Inst : VhpiHandleT; Step : Step_Type; - Wave_Elem : Wave_Opt.Elem_Acc) is + Match_List : Design.Match_List) is begin case Step is when Step_Name => @@ -1024,7 +1025,7 @@ package body Grt.Waves is Write_Hierarchy_El (Inst); end case; - Wave_Put_Hierarchy_1 (Inst, Step, Wave_Elem); + Wave_Put_Hierarchy_1 (Inst, Step, Match_List); if Step = Step_Hierarchy then Wave_Put_Byte (Ghw_Hie_Eos); @@ -1036,7 +1037,7 @@ package body Grt.Waves is Pack_It : VhpiHandleT; Pack : VhpiHandleT; Error : AvhpiErrorT; - Wave_Elem : Wave_Opt.Elem_Acc; + Match_List : Design.Match_List; begin -- First packages. Get_Package_Inst (Pack_It); @@ -1047,16 +1048,16 @@ package body Grt.Waves is Avhpi_Error (Error); return; end if; - Wave_Elem := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); - if Is_Displayed (Wave_Elem) then - Wave_Put_Hierarchy_Block (Pack, Step, Wave_Elem); + Match_List := Get_Top_Cursor (Pkg, Avhpi_Get_Base_Name (Pack)); + if Is_Displayed (Match_List) then + Wave_Put_Hierarchy_Block (Pack, Step, Match_List); end if; end loop; -- Then top entity. - Wave_Elem := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); - if Is_Displayed (Wave_Elem) then - Wave_Put_Hierarchy_Block (Root, Step, Wave_Elem); + Match_List := Get_Top_Cursor (Entity, Avhpi_Get_Base_Name (Root)); + if Is_Displayed (Match_List) then + Wave_Put_Hierarchy_Block (Root, Step, Match_List); end if; end Wave_Put_Hierarchy; |