diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-05-09 18:32:07 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-05-09 18:32:07 +0200 |
commit | 894bbd7c174bafd59fbea3b3bd990ffdfbb685d2 (patch) | |
tree | 26f0529cd8afe0333ff2c9cdb69b829294e991fe /src | |
parent | 0d9ed3a18e33337e3b6343067295dd5b3ad0a871 (diff) | |
download | ghdl-894bbd7c174bafd59fbea3b3bd990ffdfbb685d2.tar.gz ghdl-894bbd7c174bafd59fbea3b3bd990ffdfbb685d2.tar.bz2 ghdl-894bbd7c174bafd59fbea3b3bd990ffdfbb685d2.zip |
synth_stmts: handle ranges in case. Fix ghdl/ghdl-yosys-plugin#104
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-stmts.adb | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index e93eab85e..68f4f7313 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -802,22 +802,66 @@ package body Synth.Stmts is Choice : in out Node) is Ctxt : constant Context_Acc := Get_Build (Syn_Inst); - Expr_Val : Valtyp; Cond : Net; begin loop case Iir_Kinds_Case_Choice (Get_Kind (Choice)) is when Iir_Kind_Choice_By_Expression => - Expr_Val := Synth_Expression_With_Basetype - (Syn_Inst, Get_Choice_Expression (Choice)); - Expr_Val := Synth_Subtype_Conversion - (Ctxt, Expr_Val, Choice_Typ, False, Choice); - Cond := Build_Compare - (Ctxt, Id_Eq, Sel, Get_Net (Ctxt, Expr_Val)); - Set_Location (Cond, Choice); + declare + V : Valtyp; + begin + V := Synth_Expression_With_Basetype + (Syn_Inst, Get_Choice_Expression (Choice)); + V := Synth_Subtype_Conversion + (Ctxt, V, Choice_Typ, False, Choice); + Cond := Build_Compare (Ctxt, Id_Eq, Sel, Get_Net (Ctxt, V)); + Set_Location (Cond, Choice); + end; when Iir_Kind_Choice_By_Range => - raise Internal_Error; + declare + Rng : Discrete_Range_Type; + Cmp_L, Cmp_R : Module_Id; + L, R : Net; + begin + Synth_Discrete_Range + (Syn_Inst, Get_Choice_Range (Choice), Rng); + + if Rng.Is_Signed then + case Rng.Dir is + when Dir_To => + Cmp_L := Id_Sge; + Cmp_R := Id_Sle; + when Dir_Downto => + Cmp_L := Id_Sle; + Cmp_R := Id_Sge; + end case; + L := Build2_Const_Int (Ctxt, Rng.Left, Choice_Typ.W); + R := Build2_Const_Int (Ctxt, Rng.Right, Choice_Typ.W); + else + case Rng.Dir is + when Dir_To => + Cmp_L := Id_Uge; + Cmp_R := Id_Ule; + when Dir_Downto => + Cmp_L := Id_Ule; + Cmp_R := Id_Uge; + end case; + L := Build2_Const_Uns + (Ctxt, Uns64 (Rng.Left), Choice_Typ.W); + R := Build2_Const_Uns + (Ctxt, Uns64 (Rng.Right), Choice_Typ.W); + end if; + + L := Build_Compare (Ctxt, Cmp_L, Sel, L); + Set_Location (L, Choice); + + R := Build_Compare (Ctxt, Cmp_R, Sel, R); + Set_Location (R, Choice); + + Cond := Build_Dyadic (Ctxt, Id_And, L, R); + Set_Location (Cond, Choice); + end; when Iir_Kind_Choice_By_Others => -- Last one. |