diff options
| author | Tristan Gingold <tgingold@free.fr> | 2019-11-22 07:39:06 +0100 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2019-11-22 07:40:11 +0100 | 
| commit | 326da7937c313109c8877ed02c1c862170abb2ed (patch) | |
| tree | 28950b6252fd17235d3c17426eb9106c39ebdf4a /src | |
| parent | e506f77e8f6ddeb3e114a3b7e3ce5f114192d801 (diff) | |
| download | ghdl-326da7937c313109c8877ed02c1c862170abb2ed.tar.gz ghdl-326da7937c313109c8877ed02c1c862170abb2ed.tar.bz2 ghdl-326da7937c313109c8877ed02c1c862170abb2ed.zip  | |
synth: support discrete static case statement.
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth/synth-stmts.adb | 86 | 
1 files changed, 81 insertions, 5 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 59b3a5136..c1c90388a 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -878,7 +878,8 @@ package body Synth.Stmts is     procedure Free_Partial_Assign_Array is new Ada.Unchecked_Deallocation       (Partial_Assign_Array, Partial_Assign_Array_Acc); -   procedure Synth_Case_Statement (C : in out Seq_Context; Stmt : Node) +   procedure Synth_Case_Statement_Dynamic +     (C : in out Seq_Context; Stmt : Node; Sel : Value_Acc)     is        use Vhdl.Sem_Expr; @@ -905,7 +906,6 @@ package body Synth.Stmts is        Nbr_Wires : Natural;        Wires : Wire_Id_Array_Acc; -      Sel : Value_Acc;        Sel_Net : Net;     begin        --  Strategies to synthesize a case statement.  Assume the selector is @@ -924,9 +924,6 @@ package body Synth.Stmts is        --       to 2**W (eg: a partially filled memory)        --    - divide and conquier -      --  Create a net for the expression. -      Sel := Synth_Expression_With_Basetype (C.Inst, Expr); -        --  Count choices and alternatives.        Count_Choices (Case_Info, Choices);        Fill_Choices_Array (Case_Info, Choices); @@ -1091,6 +1088,85 @@ package body Synth.Stmts is        Free_Alternative_Data_Array (Alts);        Free_Partial_Assign_Array (Pasgns);        Free_Net_Array (Nets); +   end Synth_Case_Statement_Dynamic; + +   procedure Synth_Case_Statement_Static_Scalar +     (C : in out Seq_Context; Stmt : Node; Sel : Int64) +   is +      use Vhdl.Sem_Expr; + +      Choices : constant Node := Get_Case_Statement_Alternative_Chain (Stmt); +      Choice : Node; +      Stmts : Node; +      Sel_Expr : Node; +   begin +      --  Synth statements, extract choice value. +      Stmts := Null_Node; +      Choice := Choices; +      loop +         pragma Assert (Is_Valid (Choice)); +         if not Get_Same_Alternative_Flag (Choice) then +            Stmts := Get_Associated_Chain (Choice); +         end if; + +         case Get_Kind (Choice) is +            when Iir_Kind_Choice_By_Expression => +               Sel_Expr := Get_Choice_Expression (Choice); +               if Vhdl.Evaluation.Eval_Pos (Sel_Expr) = Sel then +                  Synth_Sequential_Statements (C, Stmts); +                  exit; +               end if; +            when Iir_Kind_Choice_By_Others => +               Synth_Sequential_Statements (C, Stmts); +               exit; +            when Iir_Kind_Choice_By_Range => +               declare +                  Bnd : Discrete_Range_Type; +                  W : Width; +                  pragma Unreferenced (W); +                  Is_In : Boolean; +               begin +                  Synth_Discrete_Range +                    (C.Inst, Get_Choice_Range (Choice), Bnd, W); +                  case Bnd.Dir is +                     when Iir_To => +                        Is_In := Sel >= Bnd.Left and Sel <= Bnd.Right; +                     when Iir_Downto => +                        Is_In := Sel <= Bnd.Left and Sel >= Bnd.Right; +                  end case; +                  if Is_In then +                     Synth_Sequential_Statements (C, Stmts); +                     exit; +                  end if; +               end; +            when others => +               raise Internal_Error; +         end case; +         Choice := Get_Chain (Choice); +      end loop; +   end Synth_Case_Statement_Static_Scalar; + +   procedure Synth_Case_Statement (C : in out Seq_Context; Stmt : Node) +   is +      use Vhdl.Sem_Expr; + +      Expr : constant Node := Get_Expression (Stmt); +      Sel : Value_Acc; +   begin +      Sel := Synth_Expression_With_Basetype (C.Inst, Expr); +      if Is_Static (Sel) then +         case Sel.Typ.Kind is +            when Type_Bit +              | Type_Logic +              | Type_Discrete => +               Synth_Case_Statement_Static_Scalar (C, Stmt, Sel.Scal); +            when others => +               --  TODO: support vector/array/slice +               raise Internal_Error; +         end case; +      else +         Synth_Case_Statement_Dynamic (C, Stmt, Sel); +      end if;     end Synth_Case_Statement;     procedure Synth_Selected_Signal_Assignment  | 
