aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/netlists-concats.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/netlists-concats.adb')
-rw-r--r--src/synth/netlists-concats.adb87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/synth/netlists-concats.adb b/src/synth/netlists-concats.adb
new file mode 100644
index 000000000..b01308514
--- /dev/null
+++ b/src/synth/netlists-concats.adb
@@ -0,0 +1,87 @@
+-- Provide a simple way to concat an unknown number of nets.
+-- 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, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+package body Netlists.Concats is
+ procedure Append (C : in out Concat_Type; N : Net) is
+ begin
+ if C.Len < C.Sarr'Last then
+ C.Len := C.Len + 1;
+ C.Sarr (C.Len) := N;
+ elsif C.Len > C.Sarr'Last then
+ C.Len := C.Len + 1;
+ Net_Tables.Append (C.Darr, N);
+ else
+ -- Switch to the dynamic array.
+ C.Len := C.Len + 1;
+ Net_Tables.Init (C.Darr);
+ Net_Tables.Set_Last (C.Darr, C.Len);
+ C.Darr.Table (C.Sarr'Range) := C.Sarr;
+ C.Darr.Table (C.Len) := N;
+ end if;
+ end Append;
+
+ -- Get the concatenation of all nets in C. Reset C.
+ procedure Build (Ctxt : Context_Acc; C : in out Concat_Type; N : out Net)
+ is
+ Inst : Instance;
+ Wd : Width;
+ begin
+ case C.Len is
+ when Int32'First .. 0 =>
+ raise Internal_Error;
+ when 1 =>
+ N := C.Sarr (1);
+ when 2 =>
+ N := Build_Concat2 (Ctxt, C.Sarr (2), C.Sarr (1));
+ when 3 =>
+ N := Build_Concat3 (Ctxt, C.Sarr (3), C.Sarr (2), C.Sarr (1));
+ when 4 =>
+ N := Build_Concat4
+ (Ctxt, C.Sarr (4), C.Sarr (3), C.Sarr (2), C.Sarr (1));
+ when 5 .. Static_Last =>
+ Wd := 0;
+ for I in 1 .. C.Len loop
+ Wd := Wd + Get_Width (C.Sarr (I));
+ end loop;
+
+ N := Build_Concatn (Ctxt, Wd, Uns32 (C.Len));
+ Inst := Get_Parent (N);
+ for I in 1 .. C.Len loop
+ Connect (Get_Input (Inst, Port_Idx (I - 1)), C.Sarr (I));
+ end loop;
+ when Static_Last + 1 .. Int32'Last =>
+ pragma Assert (C.Len = Net_Tables.Last (C.Darr));
+ Wd := 0;
+ for I in 1 .. C.Len loop
+ Wd := Wd + Get_Width (C.Darr.Table (I));
+ end loop;
+
+ N := Build_Concatn (Ctxt, Wd, Uns32 (C.Len));
+ Inst := Get_Parent (N);
+ for I in Net_Tables.First .. C.Len loop
+ Connect (Get_Input (Inst, Port_Idx (I - 1)), C.Darr.Table (I));
+ end loop;
+ -- Free the vector.
+ Net_Tables.Free (C.Darr);
+ end case;
+
+ C.Len := 0;
+ end Build;
+end Netlists.Concats;