diff options
author | Martin Jeřábek <martin.jerabek01@gmail.com> | 2019-03-14 13:50:58 +0100 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2021-04-22 18:55:28 +0200 |
commit | 2a926485e11b3081b7df9ef4855043b3363027dc (patch) | |
tree | 46de251ecf599b76aede5b11fd9fc243fdb1bead /src/grt | |
parent | 792f4dbc5b7e692a9862cdfcc4b0243016e5be1c (diff) | |
download | ghdl-2a926485e11b3081b7df9ef4855043b3363027dc.tar.gz ghdl-2a926485e11b3081b7df9ef4855043b3363027dc.tar.bz2 ghdl-2a926485e11b3081b7df9ef4855043b3363027dc.zip |
grt: optimize wave dump
Instead of walking through all the signals every cycle,
keep an array of changed signals (without duplicates).
Before dumping, sort the array. Afterwards clear it.
This massively improves performance on big designs.
Diffstat (limited to 'src/grt')
-rw-r--r-- | src/grt/grt-signals.adb | 11 | ||||
-rw-r--r-- | src/grt/grt-signals.ads | 9 | ||||
-rw-r--r-- | src/grt/grt-types.ads | 3 | ||||
-rw-r--r-- | src/grt/grt-waves.adb | 37 |
4 files changed, 49 insertions, 11 deletions
diff --git a/src/grt/grt-signals.adb b/src/grt/grt-signals.adb index ea714ae20..9b669ee2f 100644 --- a/src/grt/grt-signals.adb +++ b/src/grt/grt-signals.adb @@ -252,6 +252,8 @@ package body Grt.Signals is Nbr_Ports => 0, Ports => null, + Dump_Table_Idx => 0, + S => S); if Resolv /= null and then Resolv.Resolv_Ptr = System.Null_Address then @@ -622,6 +624,8 @@ package body Grt.Signals is Nbr_Ports => 0, Ports => null, + Dump_Table_Idx => 0, + S => (Mode_Sig => Mode_End)); @@ -3123,7 +3127,12 @@ package body Grt.Signals is Sig.Event := True; Sig.Last_Event := Current_Time; - Sig.Flags.RO_Event := True; + if not Sig.Flags.RO_Event then + Sig.Flags.RO_Event := True; + if Sig.Dump_Table_Idx /= 0 then + Changed_Sig_Table.Append(Sig); + end if; + end if; El := Sig.Event_List; while El /= null loop diff --git a/src/grt/grt-signals.ads b/src/grt/grt-signals.ads index 25af3e8b9..14d20dfb8 100644 --- a/src/grt/grt-signals.ads +++ b/src/grt/grt-signals.ads @@ -355,6 +355,8 @@ package Grt.Signals is Nbr_Ports : Ghdl_Index_Type; Ports : Signal_Arr_Ptr; + Dump_Table_Idx : Dump_Table_Index; + -- Mode of the signal (in, out ...) --Mode_Signal : Mode_Signal_Type; S : Ghdl_Signal_Data; @@ -367,6 +369,13 @@ package Grt.Signals is Table_Low_Bound => 0, Table_Initial => 128); + -- Signals with RO_Event set. Cleared in Grt.Wave.Wave_Cycle. + package Changed_Sig_Table is new Grt.Table + (Table_Component_Type => Ghdl_Signal_Ptr, + Table_Index_Type => Natural, + Table_Low_Bound => 1, + Table_Initial => 128); + -- Read the value pointed by VALUE_PTR. It cannot be simply deferred as -- pointer alignment may not be correct. function Read_Value (Value_Ptr : Ghdl_Value_Ptr; Mode : Mode_Type) diff --git a/src/grt/grt-types.ads b/src/grt/grt-types.ads index b4f4555e8..35b8f8e1e 100644 --- a/src/grt/grt-types.ads +++ b/src/grt/grt-types.ads @@ -180,6 +180,9 @@ package Grt.Types is First, Last : Sig_Table_Index; end record; + -- Signal index in Waves.Dump_Table. + type Dump_Table_Index is new Natural; + -- Simple values, used for signals. type Mode_Type is (Mode_B1, Mode_E8, Mode_E32, Mode_I32, Mode_I64, Mode_F64); diff --git a/src/grt/grt-waves.adb b/src/grt/grt-waves.adb index a69aa119a..b3d575c3a 100644 --- a/src/grt/grt-waves.adb +++ b/src/grt/grt-waves.adb @@ -45,6 +45,7 @@ with Grt.Ghw; use Grt.Ghw; with Grt.Wave_Opt; use Grt.Wave_Opt; with Grt.Wave_Opt.File; use Grt.Wave_Opt.File; with Grt.Wave_Opt.Design; use Grt.Wave_Opt.Design; +with Ada.Containers.Generic_Array_Sort; pragma Elaborate_All (Grt.Rtis_Utils); pragma Elaborate_All (Grt.Table); @@ -853,6 +854,7 @@ package body Grt.Waves is -- If the signal number is 0, then assign a valid signal number. if Num = 0 then Nbr_Dumped_Signals := Nbr_Dumped_Signals + 1; + Sig.Dump_Table_Idx := Dump_Table_Index(Nbr_Dumped_Signals); Sig.Alink := To_Ghdl_Signal_Ptr (Integer_Address (Nbr_Dumped_Signals)); Num := Nbr_Dumped_Signals; @@ -1780,9 +1782,19 @@ package body Grt.Waves is procedure Wave_Cycle is + type Arr_Type is array (Dump_Table_Index range <>) of Ghdl_Signal_Ptr; + + function Cmp (Left, Right : Ghdl_Signal_Ptr) return Boolean is + begin + return Left.Dump_Table_Idx < Right.Dump_Table_Idx; + end Cmp; + + procedure Sort is new Ada.Containers.Generic_Array_Sort + (Dump_Table_Index, Ghdl_Signal_Ptr, Arr_Type, "<" => Cmp); + Diff : Std_Time; Sig : Ghdl_Signal_Ptr; - Last : Natural; + Last : Dump_Table_Index; begin if not In_Cyc then Wave_Section ("CYC" & NUL); @@ -1796,15 +1808,20 @@ package body Grt.Waves is -- Dump signals. Last := 0; - for I in Dump_Table.First .. Dump_Table.Last loop - Sig := Dump_Table.Table (I); - if Sig.Flags.RO_Event then - Wave_Put_ULEB128 (Ghdl_U32 (I - Last)); - Last := I; - Write_Signal_Value (Sig); - Sig.Flags.RO_Event := False; - end if; - end loop; + if Changed_Sig_Table.First <= Changed_Sig_Table.Last then + Sort (Arr_Type (Changed_Sig_Table.Table + (Changed_Sig_Table.First .. Changed_Sig_Table.Last))); + for I in Changed_Sig_Table.First .. Changed_Sig_Table.Last loop + Sig := Changed_Sig_Table.Table(I); + if Sig.Flags.RO_Event then + Wave_Put_ULEB128 (Ghdl_U32 (Sig.Dump_Table_Idx - Last)); + Last := Sig.Dump_Table_Idx; + Write_Signal_Value (Sig); + Sig.Flags.RO_Event := False; + end if; + end loop; + Changed_Sig_Table.Set_Last (0); + end if; Wave_Put_Byte (0); end Wave_Cycle; |