diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-07-04 18:21:59 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-07-04 18:21:59 +0200 |
commit | bbbd9f1a3b59251990b34348db49f0decc3ff995 (patch) | |
tree | 81397f50f0297597601da0feb25a993f64ce236f /src | |
parent | bc88630cb8984977873f6acb7f03a1dd73e92305 (diff) | |
download | ghdl-bbbd9f1a3b59251990b34348db49f0decc3ff995.tar.gz ghdl-bbbd9f1a3b59251990b34348db49f0decc3ff995.tar.bz2 ghdl-bbbd9f1a3b59251990b34348db49f0decc3ff995.zip |
synth: handle PSL restrict directive (WIP).
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-expr.adb | 3 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 109 |
2 files changed, 111 insertions, 1 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index bd48683a7..23d97a129 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1540,7 +1540,8 @@ package body Synth.Expr is raise Internal_Error; end if; end; - when Iir_Kind_Simple_Name => + when Iir_Kind_Simple_Name + | Iir_Kind_Interface_Signal_Declaration => -- For PSL... return Synth_Name (Syn_Inst, Expr); when Iir_Kind_Indexed_Name => return Synth_Indexed_Name (Syn_Inst, Expr); diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 85d6b664f..9ed350e4d 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -25,11 +25,17 @@ with Grt.Algos; with Areapools; with Vhdl.Errors; use Vhdl.Errors; +with Vhdl.Types; with Vhdl.Sem_Expr; with Vhdl.Utils; use Vhdl.Utils; with Vhdl.Ieee.Std_Logic_1164; with Vhdl.Evaluation; +with PSL.Types; +with PSL.Nodes; +with PSL.NFAs; +with PSL.Errors; + with Synth.Types; use Synth.Types; with Synth.Errors; use Synth.Errors; with Synth.Decls; use Synth.Decls; @@ -41,6 +47,7 @@ with Vhdl.Annotations; use Vhdl.Annotations; with Netlists; use Netlists; with Netlists.Builders; use Netlists.Builders; +with Netlists.Gates; package body Synth.Stmts is function Synth_Waveform (Syn_Inst : Synth_Instance_Acc; @@ -1068,6 +1075,106 @@ package body Synth.Stmts is Build_Assert (Build_Context, Get_Net (Val, Get_Type (Cond))); end Synth_Concurrent_Assertion_Statement; + function Synth_PSL_Expression + (Syn_Inst : Synth_Instance_Acc; Expr : PSL.Types.PSL_Node) return Net + is + use PSL.Nodes; + begin + case Get_Kind (Expr) is + when N_HDL_Expr => + declare + E : constant Vhdl.Types.Vhdl_Node := Get_HDL_Node (Expr); + begin + return Get_Net (Synth_Expression (Syn_Inst, E), Get_Type (E)); + end; + when N_Not_Bool => + return Build_Monadic + (Build_Context, Netlists.Gates.Id_Not, + Synth_PSL_Expression (Syn_Inst, Get_Boolean (Expr))); + when others => + PSL.Errors.Error_Kind ("translate_psl_expr", Expr); + end case; + end Synth_PSL_Expression; + + function Synth_Psl_NFA (Syn_Inst : Synth_Instance_Acc; + NFA : PSL.Types.PSL_NFA; + Nbr_States : Int32; + States : Net) return Net + is + use PSL.NFAs; + S : NFA_State; + S_Num : Int32; + D_Num : Int32; + I : Net; + Cond : Net; + E : NFA_Edge; + D_Arr : Net_Array_Acc; + Res : Net; + begin + D_Arr := new Net_Array'(0 .. Nbr_States - 1 => No_Net); + S := Get_First_State (NFA); + while S /= No_State loop + S_Num := Get_State_Label (S); + I := Build_Extract_Bit (Build_Context, States, Uns32 (S_Num)); + + E := Get_First_Src_Edge (S); + while E /= No_Edge loop + Cond := Build_Dyadic + (Build_Context, Netlists.Gates.Id_And, + I, Synth_PSL_Expression (Syn_Inst, Get_Edge_Expr (E))); + + D_Num := Nbr_States - 1 - Get_State_Label (Get_Edge_Dest (E)); + if D_Arr (D_Num) = No_Net then + D_Arr (D_Num) := Cond; + else + D_Arr (D_Num) := Build_Dyadic + (Build_Context, Netlists.Gates.Id_Or, D_Arr (D_Num), Cond); + end if; + + E := Get_Next_Src_Edge (E); + end loop; + + S := Get_Next_State (S); + end loop; + + if D_Arr (Nbr_States - 1) = No_Net then + D_Arr (Nbr_States - 1) := Build_Const_UB32 (Build_Context, 0, 1); + end if; + + Res := Concat_Array (D_Arr); + Free_Net_Array (D_Arr); + + return Res; + end Synth_Psl_NFA; + + procedure Synth_Psl_Restrict_Directive + (Syn_Inst : Synth_Instance_Acc; Stmt : Node) + is + Nbr_States : constant Int32 := Get_PSL_Nbr_States (Stmt); + Init : Net; + Clk : Net; + States : Net; + Res : Net; + begin + -- create init net, clock net + pragma Assert (Nbr_States <= 32); + Init := Build_Const_UB32 (Build_Context, 1, Uns32 (Nbr_States)); + Clk := Synth_PSL_Expression (Syn_Inst, Get_PSL_Clock (Stmt)); + + -- build idff + States := Build_Idff (Build_Context, Clk, No_Net, Init); + + -- create update nets + -- For each state: if set, evaluate all outgoing edges. + Res := Synth_Psl_NFA (Syn_Inst, Get_PSL_NFA (Stmt), Nbr_States, States); + Connect (Get_Input (Get_Parent (States), 1), Res); + + -- build assume gate + Build_Assume (Build_Context, + Build_Reduce (Build_Context, + Netlists.Gates.Id_Red_Or, States)); + end Synth_Psl_Restrict_Directive; + procedure Synth_Concurrent_Statements (Syn_Inst : Synth_Instance_Acc; Stmts : Node) is @@ -1109,6 +1216,8 @@ package body Synth.Stmts is null; when Iir_Kind_Psl_Default_Clock => null; + when Iir_Kind_Psl_Restrict_Directive => + Synth_Psl_Restrict_Directive (Syn_Inst, Stmt); when others => Error_Kind ("synth_statements", Stmt); end case; |