diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-08-13 23:09:04 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-08-13 23:09:04 +0200 |
commit | 3f3974481acdbaa36a607b9178f2ae751748020e (patch) | |
tree | 38a69c207ee47deaf51cf971e7296ce5f4097bdf /src | |
parent | de92555dc278dbb5799aaa386e1bd9b980ce0cbc (diff) | |
download | ghdl-3f3974481acdbaa36a607b9178f2ae751748020e.tar.gz ghdl-3f3974481acdbaa36a607b9178f2ae751748020e.tar.bz2 ghdl-3f3974481acdbaa36a607b9178f2ae751748020e.zip |
synth: also extract edge in PSL expressions.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-expr.adb | 24 | ||||
-rw-r--r-- | src/synth/synth-expr.ads | 6 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 24 |
3 files changed, 36 insertions, 18 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index dab693362..592f25297 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1728,29 +1728,24 @@ package body Synth.Expr is -- Try to match: clk'event and clk = X -- or: clk = X and clk'event -- where X is '0' or '1'. - function Synth_Clock_Edge (Syn_Inst : Synth_Instance_Acc; Expr : Node) - return Value_Acc + function Synth_Clock_Edge + (Syn_Inst : Synth_Instance_Acc; Left, Right : Node) return Net is - pragma Assert (Get_Kind (Expr) = Iir_Kind_And_Operator); - Left : constant Node := Get_Left (Expr); - Right : constant Node := Get_Right (Expr); Prefix : Node; begin -- Try with left. Prefix := Extract_Event_Expr_Prefix (Left); if Is_Valid (Prefix) then - return Create_Value_Net - (Extract_Clock_Level (Syn_Inst, Right, Prefix), Boolean_Type); + return Extract_Clock_Level (Syn_Inst, Right, Prefix); end if; -- Try with right. Prefix := Extract_Event_Expr_Prefix (Right); if Is_Valid (Prefix) then - return Create_Value_Net - (Extract_Clock_Level (Syn_Inst, Left, Prefix), Boolean_Type); + return Extract_Clock_Level (Syn_Inst, Left, Prefix); end if; - return null; + return No_Net; end Synth_Clock_Edge; function Synth_Type_Conversion (Syn_Inst : Synth_Instance_Acc; Conv : Node) @@ -2038,13 +2033,14 @@ package body Synth.Expr is Imp : constant Node := Get_Implementation (Expr); Def : constant Iir_Predefined_Functions := Get_Implicit_Definition (Imp); - Edge : Value_Acc; + Edge : Net; begin -- Match clock-edge if Def = Iir_Predefined_Boolean_And then - Edge := Synth_Clock_Edge (Syn_Inst, Expr); - if Edge /= null then - return Edge; + Edge := Synth_Clock_Edge (Syn_Inst, + Get_Left (Expr), Get_Right (Expr)); + if Edge /= No_Net then + return Create_Value_Net (Edge, Boolean_Type); end if; end if; diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads index be6daba0d..06b824fe2 100644 --- a/src/synth/synth-expr.ads +++ b/src/synth/synth-expr.ads @@ -42,6 +42,12 @@ package Synth.Expr is procedure To_Logic (Enum : Int64; Etype : Type_Acc; Val : out Uns32; Zx : out Uns32); + -- Try to match: clk'event and clk = X + -- or: clk = X and clk'event + -- where X is '0' or '1'. + function Synth_Clock_Edge + (Syn_Inst : Synth_Instance_Acc; Left, Right : Node) return Net; + function Bit_Extract (Val : Value_Acc; Off : Uns32; Loc : Node) return Value_Acc; diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 7c0039a8c..af833d634 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -1242,6 +1242,7 @@ package body Synth.Stmts is function Synth_PSL_Expression (Syn_Inst : Synth_Instance_Acc; Expr : PSL.Types.PSL_Node) return Net is + use PSL.Types; use PSL.Nodes; begin case Get_Kind (Expr) is @@ -1256,10 +1257,25 @@ package body Synth.Stmts is (Build_Context, Netlists.Gates.Id_Not, Synth_PSL_Expression (Syn_Inst, Get_Boolean (Expr))); when N_And_Bool => - return Build_Dyadic - (Build_Context, Netlists.Gates.Id_And, - Synth_PSL_Expression (Syn_Inst, Get_Left (Expr)), - Synth_PSL_Expression (Syn_Inst, Get_Right (Expr))); + declare + L : constant PSL_Node := Get_Left (Expr); + R : constant PSL_Node := Get_Right (Expr); + Edge : Net; + begin + -- Handle edge (as it can be in default clock). + if Get_Kind (L) = N_HDL_Expr and then Get_Kind (R) = N_HDL_Expr + then + Edge := Synth_Clock_Edge + (Syn_Inst, Get_HDL_Node (L), Get_HDL_Node (R)); + if Edge /= No_Net then + return Edge; + end if; + end if; + return Build_Dyadic + (Build_Context, Netlists.Gates.Id_And, + Synth_PSL_Expression (Syn_Inst, L), + Synth_PSL_Expression (Syn_Inst, R)); + end; when N_Or_Bool => return Build_Dyadic (Build_Context, Netlists.Gates.Id_Or, |