From 683fbcde25efed81aac4d659d89bc4a8421a7b26 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sun, 3 May 2020 17:25:39 +0200 Subject: synth: minor refactoring for clean-up. --- src/synth/synth-environment.adb | 69 +++++++++++++++++++++++++++-------------- src/synth/synth-environment.ads | 47 ++++++++++++++++------------ src/synth/synth-stmts.adb | 49 ++--------------------------- 3 files changed, 75 insertions(+), 90 deletions(-) (limited to 'src/synth') diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb index 5270c3c0e..d6bb29883 100644 --- a/src/synth/synth-environment.adb +++ b/src/synth/synth-environment.adb @@ -1239,6 +1239,51 @@ package body Synth.Environment is end loop; end Extract_Merge_Partial_Assigns; + function Is_Assign_Value_Array_Static + (Wid : Wire_Id; Arr : Seq_Assign_Value_Array) return Memtyp + is + Res : Memtyp; + Prev_Val : Memtyp; + begin + Prev_Val := Null_Memtyp; + for I in Arr'Range loop + case Arr (I).Is_Static is + when False => + -- A value is not static. + return Null_Memtyp; + when Unknown => + if Prev_Val = Null_Memtyp then + -- First use of previous value. + if not Is_Static_Wire (Wid) then + -- The previous value is not static. + return Null_Memtyp; + end if; + Prev_Val := Get_Static_Wire (Wid); + if Res /= Null_Memtyp then + -- There is already a result. + if not Is_Equal (Res, Prev_Val) then + -- The previous value is different from the result. + return Null_Memtyp; + else + Res := Prev_Val; + end if; + end if; + end if; + when True => + if Res = Null_Memtyp then + -- First value. Keep it. + Res := Arr (I).Val; + else + if not Is_Equal (Res, Arr (I).Val) then + -- Value is different. + return Null_Memtyp; + end if; + end if; + end case; + end loop; + return Res; + end Is_Assign_Value_Array_Static; + procedure Partial_Assign_Init (List : out Partial_Assign_List) is begin List := (First | Last => No_Partial_Assign); @@ -1365,30 +1410,6 @@ package body Synth.Environment is Merge_Partial_Assigns (Ctxt, W, List); end Merge_Assigns; - -- Force the value of a Seq_Assign to be a net if needed, return it. - function Get_Assign_Value_Force (Val : Seq_Assign_Value) - return Partial_Assign - is - N : Net; - begin - case Val.Is_Static is - when Unknown => - return No_Partial_Assign; - when True => - N := Synth.Context.Get_Memtyp_Net (Val.Val); - return New_Partial_Assign (N, 0); - when False => - return Val.Asgns; - end case; - end Get_Assign_Value_Force; - - -- Force the value of a Seq_Assign to be a net if needed, return it. - function Get_Assign_Partial_Force (Asgn : Seq_Assign) - return Partial_Assign is - begin - return Get_Assign_Value_Force (Get_Seq_Assign_Value (Asgn)); - end Get_Assign_Partial_Force; - function Merge_Static_Assigns (Wid : Wire_Id; Tv, Fv : Seq_Assign_Value) return Boolean is diff --git a/src/synth/synth-environment.ads b/src/synth/synth-environment.ads index 74d0c3350..5d066bf43 100644 --- a/src/synth/synth-environment.ads +++ b/src/synth/synth-environment.ads @@ -167,30 +167,12 @@ package Synth.Environment is type Partial_Assign is private; No_Partial_Assign : constant Partial_Assign; - type Seq_Assign_Value (Is_Static : Tri_State_Type := True) is record - case Is_Static is - when Unknown => - -- Used only for no value (in that case, it will use the previous - -- value). - -- This is used only for temporary handling, and is never stored - -- in Seq_Assign. - null; - when True => - Val : Memtyp; - when False => - -- Values assigned. - Asgns : Partial_Assign; - end case; - end record; - + type Seq_Assign_Value is private; No_Seq_Assign_Value : constant Seq_Assign_Value; function Get_Assign_Partial (Asgn : Seq_Assign) return Partial_Assign; function Get_Seq_Assign_Value (Asgn : Seq_Assign) return Seq_Assign_Value; - -- Force the value of a Seq_Assign to be a net if needed, return it. - function Get_Assign_Partial_Force (Asgn : Seq_Assign) return Partial_Assign; - function New_Partial_Assign (Val : Net; Offset : Uns32) return Partial_Assign; @@ -198,6 +180,17 @@ package Synth.Environment is type Seq_Assign_Value_Array is array (Int32 range <>) of Seq_Assign_Value; + -- Return the unique value from array of Seq_Assign_Value if it exists, + -- otherwise return Null_Memtyp. + -- To be more precise, a value is returned iff: + -- 1) All present values in Arr are static + -- 2) There is no missing values *or* the previous value is static. + -- 3) All the values are equal. + -- then assign directly. + -- WID is used in case of unknown value. + function Is_Assign_Value_Array_Static + (Wid : Wire_Id; Arr : Seq_Assign_Value_Array) return Memtyp; + type Partial_Assign_List is limited private; procedure Partial_Assign_Init (List : out Partial_Assign_List); @@ -294,6 +287,22 @@ private Nbr_Final_Assign : Natural; end record; + type Seq_Assign_Value (Is_Static : Tri_State_Type := True) is record + case Is_Static is + when Unknown => + -- Used only for no value (in that case, it will use the previous + -- value). + -- This is used only for temporary handling, and is never stored + -- in Seq_Assign. + null; + when True => + Val : Memtyp; + when False => + -- Values assigned. + Asgns : Partial_Assign; + end case; + end record; + No_Seq_Assign_Value : constant Seq_Assign_Value := (Is_Static => Unknown); type Seq_Assign_Record is record diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 88fa1df4c..0ebdf073f 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -1066,54 +1066,9 @@ package body Synth.Stmts is -- 3) The default value is unused *or* it is static -- 4) All the values are equal. -- then assign directly. - Sval := Null_Memtyp; - declare - Prev_Val : Memtyp; - begin - Prev_Val := Null_Memtyp; - for I in Pasgns'Range loop - case Pasgns (I).Is_Static is - when False => - Sval := Null_Memtyp; - -- It's over. - exit; - when Unknown => - if Prev_Val = Null_Memtyp then - if not Is_Static_Wire (Wi) then - Sval := Null_Memtyp; - -- It's over. - exit; - end if; - Prev_Val := Get_Static_Wire (Wi); - end if; - if Sval /= Null_Memtyp - and then not Is_Equal (Sval, Prev_Val) - then - Sval := Null_Memtyp; - -- It's over. - exit; - end if; - when True => - if Sval = Null_Memtyp then - Sval := Pasgns (I).Val; - if Prev_Val /= Null_Memtyp - and then not Is_Equal (Sval, Prev_Val) - then - Sval := Null_Memtyp; - -- It's over. - exit; - end if; - else - if not Is_Equal (Sval, Pasgns (I).Val) then - Sval := Null_Memtyp; - -- It's over. - exit; - end if; - end if; - end case; - end loop; - end; + Sval := Is_Assign_Value_Array_Static (Wi, Pasgns.all); if Sval /= Null_Memtyp then + -- Use static assignment. Phi_Assign_Static (Wi, Sval); else -- Compute the final value for each partial part of the wire. -- cgit v1.2.3