aboutsummaryrefslogtreecommitdiffstats
path: root/src/grt/grt-signals.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2018-02-27 06:59:30 +0100
committerTristan Gingold <tgingold@free.fr>2018-02-27 06:59:30 +0100
commit48ab280fccb209c223259f8d4df339948c548539 (patch)
treed79515b83e423883ea8421bcd9f37b959b846997 /src/grt/grt-signals.adb
parent8c8b6285bd3532c2f158e33885ea5984dc62270b (diff)
downloadghdl-48ab280fccb209c223259f8d4df339948c548539.tar.gz
ghdl-48ab280fccb209c223259f8d4df339948c548539.tar.bz2
ghdl-48ab280fccb209c223259f8d4df339948c548539.zip
grt-signals: factorize, add comments.
Diffstat (limited to 'src/grt/grt-signals.adb')
-rw-r--r--src/grt/grt-signals.adb89
1 files changed, 51 insertions, 38 deletions
diff --git a/src/grt/grt-signals.adb b/src/grt/grt-signals.adb
index 4cdc8c424..26fe60c8d 100644
--- a/src/grt/grt-signals.adb
+++ b/src/grt/grt-signals.adb
@@ -617,8 +617,19 @@ package body Grt.Signals is
-- List of signals which have projected waveforms in the future (beyond
-- the next delta cycle).
+ -- Currently signals are never removed from this list.
+ -- TODO: maybe remove signals when they have no transaction in the future?
Future_List : aliased Ghdl_Signal_Ptr;
+ -- Insert SIG on the Future_List, if not already inserted.
+ procedure Insert_Future_List (Sig : Ghdl_Signal_Ptr) is
+ begin
+ if Sig.Flink = null then
+ Sig.Flink := Future_List;
+ Future_List := Sig;
+ end if;
+ end Insert_Future_List;
+
procedure Ghdl_Signal_Start_Assign (Sign : Ghdl_Signal_Ptr;
Reject : Std_Time;
Trans : Transaction_Acc;
@@ -646,10 +657,7 @@ package body Grt.Signals is
else
-- AFTER > 0.
-- Put SIGN on the future list.
- if Sign.Flink = null then
- Sign.Flink := Future_List;
- Future_List := Sign;
- end if;
+ Insert_Future_List (Sign);
end if;
Assign_Time := Current_Time + After;
@@ -839,12 +847,6 @@ package body Grt.Signals is
Trans : Transaction_Acc;
begin
- if After > 0 and then Sign.Flink = null then
- -- Put SIGN on the future list.
- Sign.Flink := Future_List;
- Future_List := Sign;
- end if;
-
Trans := new Transaction'(Kind => Trans_Value,
Line => 0,
Time => Current_Time + After,
@@ -853,6 +855,11 @@ package body Grt.Signals is
if Trans.Time <= Driver.Last_Trans.Time then
Error ("transactions not in ascending order");
end if;
+
+ pragma Assert (After > 0);
+
+ Insert_Future_List (Sign);
+
Driver.Last_Trans.Next := Trans;
Driver.Last_Trans := Trans;
end Ghdl_Signal_Next_Assign;
@@ -908,12 +915,6 @@ package body Grt.Signals is
Trans : Transaction_Acc;
begin
- if After > 0 and then Sign.Flink = null then
- -- Put SIGN on the future list.
- Sign.Flink := Future_List;
- Future_List := Sign;
- end if;
-
Trans := new Transaction'(Kind => Trans_Error,
Line => Line,
Time => Current_Time + After,
@@ -922,6 +923,10 @@ package body Grt.Signals is
if Trans.Time <= Driver.Last_Trans.Time then
Error ("transactions not in ascending order");
end if;
+
+ pragma Assert (After > 0);
+ Insert_Future_List (Sign);
+
Driver.Last_Trans.Next := Trans;
Driver.Last_Trans := Trans;
end Ghdl_Signal_Next_Assign_Error;
@@ -1495,8 +1500,8 @@ package body Grt.Signals is
end if;
if Time > 0 then
- Res.Flink := Future_List;
- Future_List := Res;
+ -- This signal will have transaction in the future.
+ Insert_Future_List (Res);
end if;
return Res;
@@ -1558,8 +1563,7 @@ package body Grt.Signals is
(Sig.Mode, Val_Ptr, Mode_Delayed, null, Null_Address);
Res.S.Time := Val;
if Val > 0 then
- Res.Flink := Future_List;
- Future_List := Res;
+ Insert_Future_List (Res);
end if;
Res.S.Attr_Trans := new Transaction'(Kind => Trans_Value,
Line => 0,
@@ -1856,7 +1860,9 @@ package body Grt.Signals is
-- at the time returned (if not current_time).
Next_Signal_Active_Chain : Ghdl_Signal_Ptr;
- -- Remove all (but Signal_End) signals in the active chain.
+ -- Remove all (but Signal_End) signals in the next active chain.
+ -- Called when a transaction/event will occur before the time for this
+ -- chain.
procedure Flush_Active_Chain
is
Sig : Ghdl_Signal_Ptr;
@@ -1890,6 +1896,8 @@ package body Grt.Signals is
Sig.Link := Next_Signal_Active_Chain;
Next_Signal_Active_Chain := Sig;
elsif Trans.Time < Res then
+ -- A transaction is scheduled before all the previous one. Clear
+ -- the active chain, and put simply Sig on it.
Flush_Active_Chain;
-- Put sig on the list.
@@ -2050,8 +2058,7 @@ package body Grt.Signals is
Propagation.Table (Propagation.Last) := P;
end Add_Propagation;
- procedure Add_Forward_Propagation (Sig : Ghdl_Signal_Ptr)
- is
+ procedure Add_Forward_Propagation (Sig : Ghdl_Signal_Ptr) is
begin
for I in 1 .. Sig.Nbr_Ports loop
Add_Propagation
@@ -2221,20 +2228,20 @@ package body Grt.Signals is
Sig.Flags.Propag := Propag_Being_Driving;
Order_Signal_List (Sig, Propag_Done);
Sig.Flags.Propag := Propag_Done;
- if Sig.S.Mode_Sig in Mode_Signal_Forward then
- Add_Forward_Propagation (Sig);
- end if;
case Mode_Signal_Implicit (Sig.S.Mode_Sig) is
when Mode_Guard =>
Add_Propagation ((Kind => Imp_Guard, Sig => Sig));
when Mode_Stable =>
+ Add_Forward_Propagation (Sig);
Add_Propagation ((Kind => Imp_Stable, Sig => Sig));
when Mode_Quiet =>
+ Add_Forward_Propagation (Sig);
Add_Propagation ((Kind => Imp_Quiet, Sig => Sig));
- when Mode_Transaction =>
- Add_Propagation ((Kind => Imp_Transaction, Sig => Sig));
when Mode_Delayed =>
+ Add_Forward_Propagation (Sig);
Add_Propagation ((Kind => Imp_Delayed, Sig => Sig));
+ when Mode_Transaction =>
+ Add_Propagation ((Kind => Imp_Transaction, Sig => Sig));
end case;
return;
when Mode_Conv_In =>
@@ -2801,12 +2808,14 @@ package body Grt.Signals is
end if;
end Add_Active_Chain;
- Clear_List : Ghdl_Signal_Ptr := null;
+ -- List of signals whose 'Active flag must be cleared. A signal is added
+ -- to this list by Mark_Active and removed by Reset_Active_Flag.
+ Active_Clear_List : Ghdl_Signal_Ptr := null;
-- Mark SIG as active (set 'Active and 'Last_Active).
-- This procedure is called while signals are updated.
- -- Put SIG on Clear_List (if not already) so that 'Active will be cleared
- -- at the end of the delta cycle.
+ -- Put SIG on Active_Clear_List (if not already) so that 'Active will be
+ -- cleared at the end of the delta cycle.
procedure Mark_Active (Sig : Ghdl_Signal_Ptr);
pragma Inline (Mark_Active);
@@ -2816,8 +2825,8 @@ package body Grt.Signals is
if not Sig.Active then
Sig.Active := True;
Sig.Last_Active := Current_Time;
- Sig.Alink := Clear_List;
- Clear_List := Sig;
+ Sig.Alink := Active_Clear_List;
+ Active_Clear_List := Sig;
end if;
end Mark_Active;
@@ -3211,6 +3220,8 @@ package body Grt.Signals is
Set_Effective_Value
(Sig, Sig.Driving_Value'Unrestricted_Access);
if Sig.S.Time = 0 then
+ -- Signal is active in the next cycle. If Time > 0, it
+ -- has been put in Future_List during creation.
Add_Active_Chain (Sig);
end if;
else
@@ -3246,8 +3257,7 @@ package body Grt.Signals is
for I in 0 .. Sig.Nbr_Ports - 1 loop
if Sig.Ports (I).Active then
Mark_Active (Sig);
- Set_Effective_Value
- (Sig, Val'Unrestricted_access);
+ Set_Effective_Value (Sig, Val'Unrestricted_access);
exit;
end if;
end loop;
@@ -3277,8 +3287,8 @@ package body Grt.Signals is
Sig : Ghdl_Signal_Ptr;
begin
-- 1) Reset active flag.
- Sig := Clear_List;
- Clear_List := null;
+ Sig := Active_Clear_List;
+ Active_Clear_List := null;
while Sig /= null loop
if Options.Flag_Stats then
if Sig.Active then
@@ -3334,8 +3344,11 @@ package body Grt.Signals is
Set_Effective_Value (Sig, Fv.Val'Access);
if Sig.Net in Signal_Net_Defined then
- -- HACK: mark SIG as active so that propagation will execute
+ -- Mark SIG as active so that propagation will execute
-- just below.
+ -- This is a little HACK as the code just below handles all
+ -- the cases, but we are only interesting in the case for
+ -- defined net (with propagation).
Add_Active_Chain (Sig);
end if;