diff options
Diffstat (limited to 'src/synth/netlists-utils.adb')
-rw-r--r-- | src/synth/netlists-utils.adb | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/synth/netlists-utils.adb b/src/synth/netlists-utils.adb new file mode 100644 index 000000000..3dece320b --- /dev/null +++ b/src/synth/netlists-utils.adb @@ -0,0 +1,126 @@ +-- Netlist utilities (composed of a few calls). +-- Copyright (C) 2017 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, write to the Free Software +-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +-- MA 02110-1301, USA. + +package body Netlists.Utils is + function Get_Nbr_Inputs (Inst : Instance) return Port_Nbr + is + M : constant Module := Get_Module (Inst); + begin + if Is_Self_Instance (Inst) then + return Get_Nbr_Outputs (M); + else + return Get_Nbr_Inputs (M); + end if; + end Get_Nbr_Inputs; + + function Get_Nbr_Outputs (Inst : Instance) return Port_Nbr + is + M : constant Module := Get_Module (Inst); + begin + if Is_Self_Instance (Inst) then + return Get_Nbr_Inputs (M); + else + return Get_Nbr_Outputs (M); + end if; + end Get_Nbr_Outputs; + + function Get_Nbr_Params (Inst : Instance) return Param_Nbr + is + M : constant Module := Get_Module (Inst); + begin + return Get_Nbr_Params (M); + end Get_Nbr_Params; + + function Get_Param_Desc + (Inst : Instance; Param : Param_Idx) return Param_Desc is + begin + return Get_Param_Desc (Get_Module (Inst), Param); + end Get_Param_Desc; + + function Get_Id (Inst : Instance) return Module_Id is + begin + return Get_Id (Get_Module (Inst)); + end Get_Id; + + function Get_Input_Name (M : Module; I : Port_Idx) return Sname is + begin + return Get_Input_Desc (M, I).Name; + end Get_Input_Name; + + function Get_Output_Name (M : Module; I : Port_Idx) return Sname is + begin + return Get_Output_Desc (M, I).Name; + end Get_Output_Name; + + function Is_Connected (O : Net) return Boolean is + begin + return Get_First_Sink (O) /= No_Input; + end Is_Connected; + + function Has_One_Connection (O : Net) return Boolean + is + Inp : Input; + begin + Inp := Get_First_Sink (O); + if Inp = No_Input then + -- No connection. + return False; + end if; + Inp := Get_Next_Sink (Inp); + return Inp = No_Input; + end Has_One_Connection; + + procedure Disconnect_And_Free (I : Input) + is + I_Net : constant Net := Get_Driver (I); + Inst : constant Instance := Get_Net_Parent (I_Net); + Nbr_Inputs : Port_Nbr; + Nbr_Outputs : Port_Nbr; + begin + -- First disconnect. + Disconnect (I); + + -- Quick check: is output (of I) still used ? + if Is_Connected (I_Net) then + return; + end if; + + -- Check that all outputs are unused. + Nbr_Outputs := Get_Nbr_Outputs (Inst); + if Nbr_Outputs > 1 then + for K in 0 .. Nbr_Outputs - 1 loop + if Is_Connected (Get_Output (Inst, K)) then + return; + end if; + end loop; + end if; + + -- First disconnect inputs. + Nbr_Inputs := Get_Nbr_Inputs (Inst); + if Nbr_Inputs > 0 then + for K in 0 .. Nbr_Inputs - 1 loop + Disconnect_And_Free (Get_Input (Inst, K)); + end loop; + end if; + + -- Free Inst + Free_Instance (Inst); + end Disconnect_And_Free; +end Netlists.Utils; |