aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jeřábek <martin.jerabek01@gmail.com>2019-03-14 13:50:58 +0100
committertgingold <tgingold@users.noreply.github.com>2021-04-22 18:55:28 +0200
commit2a926485e11b3081b7df9ef4855043b3363027dc (patch)
tree46de251ecf599b76aede5b11fd9fc243fdb1bead /src
parent792f4dbc5b7e692a9862cdfcc4b0243016e5be1c (diff)
downloadghdl-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')
-rw-r--r--src/grt/grt-signals.adb11
-rw-r--r--src/grt/grt-signals.ads9
-rw-r--r--src/grt/grt-types.ads3
-rw-r--r--src/grt/grt-waves.adb37
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;