From df259b99050928cd72874377d7797c0de797935b Mon Sep 17 00:00:00 2001 From: Jonas Baggett Date: Fri, 5 Aug 2016 14:28:25 +0200 Subject: 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 --- doc/Simulation_and_runtime.rst | 26 +++++- src/grt/grt-errors.adb | 6 ++ src/grt/grt-errors.ads | 1 + src/grt/grt-fst.adb | 45 +++++------ src/grt/grt-vcd.adb | 34 ++++---- src/grt/grt-wave_opt-design.adb | 152 +++++++++++++++++++++++++++--------- src/grt/grt-wave_opt-design.ads | 15 +++- src/grt/grt-wave_opt-file-debug.adb | 2 +- src/grt/grt-wave_opt-file.adb | 83 ++++++++++++-------- src/grt/grt-wave_opt-file.ads | 8 +- src/grt/grt-wave_opt.adb | 4 +- src/grt/grt-wave_opt.ads | 14 +--- src/grt/grt-waves.adb | 37 ++++----- 13 files changed, 276 insertions(+), 151 deletions(-) diff --git a/doc/Simulation_and_runtime.rst b/doc/Simulation_and_runtime.rst index 518c8a290..25a779fb2 100644 --- a/doc/Simulation_and_runtime.rst +++ b/doc/Simulation_and_runtime.rst @@ -123,16 +123,34 @@ all options available, including the debugging one. Filter signals to be dumped to the wave file according to the wave option file provided. - Here is a description of the wave option file format : + Here is a description of the wave option file format currently supported : - $ version = 1.0 # Optional + $ version = 1.1 # Optional - # Signals in packages : + # Path format for signals in packages : my_pkg.global_signal_a - # Signals in entities : + # Path format for signals in entities : /top/sub/clk + # Dumps every signals named reset in first level sub entities of top + /top/*/reset + + # Dumps every signals named reset in recursive sub entities of top + /top/**/reset + + # Dump every signals of sub2 which could be anywhere in design except on + # top level + /**/sub2/* + + # Dump every signals of sub3 which must be a first level sub entity of the + # top level + /*/sub3/* + + # Dump every signals of the first level sub entities of sub3 (but not + # those of sub3) + /**/sub3/*/* + .. option:: --write-opt-file= 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; -- cgit v1.2.3