-- Instantiation synthesis.
-- Copyright (C) 2019 Tristan Gingold
--
-- This file is part of GHDL.
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <gnu.org/licenses>.
with GNAT.SHA1;
with Types_Utils; use Types_Utils;
with Name_Table;
with Std_Names;
with Hash; use Hash;
with Dyn_Tables;
with Interning;
with Synthesis; use Synthesis;
with Grt.Algos;
with Netlists; use Netlists;
with Netlists.Builders; use Netlists.Builders;
with Netlists.Concats;
with Netlists.Folds;
with Elab.Vhdl_Objtypes; use Elab.Vhdl_Objtypes;
with Elab.Vhdl_Values; use Elab.Vhdl_Values;
with Vhdl.Utils; use Vhdl.Utils;
with Vhdl.Errors;
with Vhdl.Evaluation;
with Vhdl.Ieee.Math_Real;
with Vhdl.Std_Package;
with Elab.Memtype; use Elab.Memtype;
with Elab.Vhdl_Files;
with Elab.Debugger;
with Elab.Vhdl_Errors;
with Elab.Vhdl_Expr; use Elab.Vhdl_Expr;
with Synth.Vhdl_Environment; use Synth.Vhdl_Environment.Env;
with Synth.Vhdl_Stmts; use Synth.Vhdl_Stmts;
with Synth.Vhdl_Decls; use Synth.Vhdl_Decls;
with Synth.Vhdl_Expr; use Synth.Vhdl_Expr;
with Synth.Source; use Synth.Source;
with Synth.Errors;
with Synth.Vhdl_Context; use Synth.Vhdl_Context;
package body Synth.Vhdl_Insts is
Global_Base_Instance : Base_Instance_Acc;
function Mode_To_Port_Kind (Mode : Iir_Mode) return Port_Kind is
begin
case Mode is
when Iir_In_Mode =>
return Port_In;
when Iir_Buffer_Mode
| Iir_Out_Mode =>
return Port_Out;
when Iir_Inout_Mode =>
return Port_Inout;
when Iir_Linkage_Mode
| Iir_Unknown_Mode =>
raise Synth_Error;
end case;
end Mode_To_Port_Kind;
-- Parameters that define an instance.
type Inst_Params is record
-- Declaration: either the entity or the component.
Decl : Node;
-- Implementation: the architecture or Null_Node for black boxes.
Arch : Node;
-- Configuration (Null_Node for black boxes).
Config : Node;
-- Values of generics.
Syn_Inst : Synth_Instance_Acc;
-- Encoding if the instance name.
Encoding : Name_Encoding;
end record;
type Inst_Object is record
Decl : Node;
Arch : Node;
Config : Node;
Syn_Inst : Synth_Instance_Acc;
M : Module;
-- Encoding if the instance name.
Encoding : Name_Encoding;
end record;
function Hash (Params : Inst_Params) return Hash_Value_Type
is
Res : Hash_Value_Type;
begin
Res := Hash_Value_Type (Params.Decl);
Res := Res xor Hash_Value_Type (Params.Arch);
Res := Res xor Hash_Value_Type (Params.Config);
-- TODO: hash generics
return Res;
end Hash;
function Equal (Obj : Inst_Object; Params : Inst_Params) return Boolean
is
Inter : Node;
begin
if Obj.Decl /= Params.Decl
or else Obj.Arch /= Params.Arch
or else Obj.Config /= Params.Config
then
return False;
end if;
Inter := Get_Generic_Chain (Params.Decl);
while Inter /= Null_Node loop
pragma Assert (Get_Kind (Inter)
= Iir_Kind_Interface_Constant_Declaration);
if not Is_Equal (Get_Value (Obj.Syn_Inst, Inter),
Get_Value (Params.Syn_Inst, Inter))
then
return False;
end if;
Inter := Get_Chain (Inter);
end loop;
Inter := Get_Port_Chain (Params.Decl);
while Inter /= Null_Node loop
pragma Assert (Get_Kind (Inter)
= Iir_Kind_Interface_Signal_Declaration);
if not Is_Fully_Constrained_Type (Get_Type (Inter)) then
if not Are_Types_Equal (Get_Value (Obj.Syn_Inst, Inter).Typ,
Get_Value (Params.Syn_Inst, Inter).Typ)
then
return False;
end if;
end if;
Inter := Get_Chain (Inter);
end loop;
return True;
end Equal;
procedure Hash_Uns64 (C : in out GNAT.SHA1.Context; Val : Uns64)
is
V : Uns64;
S : String (1 .. 8);
begin
-- Store to S using little endianness.
V := Val;
for I in S'Range loop
S (I) := Character'Val (V and 16#ff#);
V := Shift_Right (V, 8);
end loop;
GNAT.SHA1.Update (C, S);
end Hash_Uns64;
procedure Hash_Memory (C : in out GNAT.SHA1.Context;
M : Memory_Ptr;
Typ : Type_Acc)