aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-09-05 09:10:12 +0200
committerTristan Gingold <tgingold@free.fr>2019-09-05 09:10:12 +0200
commitf6d49eb62dac359c96aefc79d3d0ae8f907dc8d9 (patch)
tree09aa6cd0c040f31fba6b1275467059288ee90e52 /src
parent0c71b4ee8844742426f96f0dc0b7c09a197c57dd (diff)
downloadghdl-f6d49eb62dac359c96aefc79d3d0ae8f907dc8d9.tar.gz
ghdl-f6d49eb62dac359c96aefc79d3d0ae8f907dc8d9.tar.bz2
ghdl-f6d49eb62dac359c96aefc79d3d0ae8f907dc8d9.zip
synth: add netlists.concats
Diffstat (limited to 'src')
-rw-r--r--src/synth/netlists-concats.adb87
-rw-r--r--src/synth/netlists-concats.ads46
-rw-r--r--src/synth/synth-environment.adb38
3 files changed, 140 insertions, 31 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;
diff --git a/src/synth/netlists-concats.ads b/src/synth/netlists-concats.ads
new file mode 100644
index 000000000..3b1e9cb93
--- /dev/null
+++ b/src/synth/netlists-concats.ads
@@ -0,0 +1,46 @@
+-- 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.
+
+with Dyn_Tables;
+with Netlists.Builders; use Netlists.Builders;
+
+package Netlists.Concats is
+ type Concat_Type is limited private;
+
+ -- Append net N to C.
+ procedure Append (C : in out Concat_Type; N : Net);
+
+ -- Get the concatenation of all nets in C. Reset C.
+ procedure Build (Ctxt : Context_Acc; C : in out Concat_Type; N : out Net);
+private
+ Static_Last : constant Int32 := 16;
+
+ package Net_Tables is new Dyn_Tables
+ (Table_Component_Type => Net,
+ Table_Index_Type => Int32,
+ Table_Low_Bound => 1,
+ Table_Initial => Integer (Static_Last * 2));
+
+ type Concat_Type is limited record
+ Len : Int32 := 0;
+ Sarr : Net_Tables.Table_Type (1 .. Static_Last);
+ Darr : Net_Tables.Instance;
+ end record;
+end Netlists.Concats;
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index 4c8850a6a..3e5a65b6d 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -20,6 +20,7 @@
with Netlists.Builders; use Netlists.Builders;
with Netlists.Utils; use Netlists.Utils;
+with Netlists.Concats;
with Errorout; use Errorout;
with Synth.Inference;
with Synth.Errors; use Synth.Errors;
@@ -620,17 +621,15 @@ package body Synth.Environment is
-- Build a vector
declare
- Vec : Net_Tables.Instance;
+ use Netlists.Concats;
+ Vec : Concat_Type;
Seq : Seq_Assign;
P : Partial_Assign;
Cur_Off : Uns32;
Cur_Wd : Width;
- Last : Int32;
- Inst : Instance;
Res : Net;
begin
- Net_Tables.Init (Vec);
Cur_Off := Off;
Cur_Wd := Wd;
pragma Assert (Wd > 0);
@@ -651,11 +650,11 @@ package body Synth.Environment is
-- Found.
if Pr.Offset = Cur_Off and then Pw = Cur_Wd then
-- No need to extract.
- Net_Tables.Append (Vec, Pr.Value);
+ Append (Vec, Pr.Value);
else
Cur_Wd := Width'Min
(Cur_Wd, Pw - (Cur_Off - Pr.Offset));
- Net_Tables.Append
+ Append
(Vec, Build_Extract (Ctxt, Pr.Value,
Cur_Off - Pr.Offset, Cur_Wd));
end if;
@@ -678,7 +677,7 @@ package body Synth.Environment is
Seq := Get_Assign_Prev (Seq);
if Seq = No_Seq_Assign then
-- Extract from gate.
- Net_Tables.Append
+ Append
(Vec, Build_Extract (Ctxt, Wire.Gate,
Cur_Off, Cur_Wd));
exit;
@@ -694,30 +693,7 @@ package body Synth.Environment is
end loop;
-- Concat
- Last := Net_Tables.Last (Vec);
- case Last is
- when Int32'First .. 0 =>
- raise Internal_Error;
- when 1 =>
- Res := Vec.Table (1);
- when 2 =>
- Res := Build_Concat2 (Ctxt, Vec.Table (2), Vec.Table (1));
- when 3 =>
- Res := Build_Concat3
- (Ctxt, Vec.Table (3), Vec.Table (2), Vec.Table (1));
- when 4 =>
- Res := Build_Concat4
- (Ctxt,
- Vec.Table (4), Vec.Table (3), Vec.Table (2), Vec.Table (1));
- when 5 .. Int32'Last =>
- Res := Build_Concatn (Ctxt, Wd, Uns32 (Last));
- Inst := Get_Parent (Res);
- for I in Net_Tables.First .. Last loop
- Connect (Get_Input (Inst, Port_Idx (I - 1)), Vec.Table (I));
- end loop;
- end case;
- -- Free the vector and return it.
- Net_Tables.Free (Vec);
+ Build (Ctxt, Vec, Res);
return Res;
end;
end Get_Current_Assign_Value;