aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-05-03 17:25:39 +0200
committerTristan Gingold <tgingold@free.fr>2020-05-04 19:04:09 +0200
commit683fbcde25efed81aac4d659d89bc4a8421a7b26 (patch)
treeb5720b6e9ae24f0d90e4d85474bcce4811022b84 /src/synth
parentd3670fb86dc7ccd39d2e6738d90d268da3308713 (diff)
downloadghdl-683fbcde25efed81aac4d659d89bc4a8421a7b26.tar.gz
ghdl-683fbcde25efed81aac4d659d89bc4a8421a7b26.tar.bz2
ghdl-683fbcde25efed81aac4d659d89bc4a8421a7b26.zip
synth: minor refactoring for clean-up.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/synth-environment.adb69
-rw-r--r--src/synth/synth-environment.ads47
-rw-r--r--src/synth/synth-stmts.adb49
3 files changed, 75 insertions, 90 deletions
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.