aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth/ghdlsynth_gates.h2
-rw-r--r--src/synth/netlists-builders.adb38
-rw-r--r--src/synth/netlists-builders.ads4
-rw-r--r--src/synth/netlists-disp_vhdl.adb17
-rw-r--r--src/synth/netlists-memories.adb64
-rw-r--r--src/synth/netlists-utils.ads4
-rw-r--r--src/synth/netlists.ads2
7 files changed, 85 insertions, 46 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h
index b215f9793..e7594295b 100644
--- a/src/synth/ghdlsynth_gates.h
+++ b/src/synth/ghdlsynth_gates.h
@@ -55,6 +55,8 @@ enum Module_Id {
Id_Adff = 51,
Id_Idff = 52,
Id_Iadff = 53,
+ Id_Mdff = 54,
+ Id_Midff = 55,
Id_Utrunc = 64,
Id_Strunc = 65,
Id_Uextend = 66,
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index b07786fa5..385a73d8b 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -320,28 +320,30 @@ package body Netlists.Builders is
Res := New_User_Module
(Ctxt.Design,
New_Sname_Artificial (Get_Identifier ("memory"), No_Sname),
- Id_Memory, 0, 1, 0);
+ Id_Memory, 1, 1, 0);
Ctxt.M_Memory := Res;
- Outputs (0 .. 0) := (0 => Create_Output ("ports"));
- Set_Ports_Desc (Res, Port_Desc_Array'(1 .. 0 => <>), Outputs (0 .. 0));
+ Outputs (0 .. 0) := (0 => Create_Output ("oport"));
+ Inputs (0 .. 0) := (0 => Create_Input ("iport"));
+ Set_Ports_Desc (Res, Inputs (0 .. 0), Outputs (0 .. 0));
Res := New_User_Module
(Ctxt.Design,
New_Sname_Artificial (Get_Identifier ("memory_init"), No_Sname),
- Id_Memory_Init, 1, 1, 0);
+ Id_Memory_Init, 2, 1, 0);
Ctxt.M_Memory_Init := Res;
- Outputs (0 .. 0) := (0 => Create_Output ("ports"));
- Inputs (0 .. 0) := (0 => Create_Input ("init"));
- Set_Ports_Desc (Res, Inputs (0 .. 0), Outputs (0 .. 0));
+ Outputs (0 .. 0) := (0 => Create_Output ("oport"));
+ Inputs (0 .. 1) := (0 => Create_Input ("iport"),
+ 1 => Create_Input ("init"));
+ Set_Ports_Desc (Res, Inputs (0 .. 1), Outputs (0 .. 0));
Res := New_User_Module
(Ctxt.Design,
New_Sname_Artificial (Get_Identifier ("mem_rd"), No_Sname),
Id_Mem_Rd, 2, 2, 0);
Ctxt.M_Mem_Rd := Res;
- Inputs (0 .. 1) := (0 => Create_Input ("pport"),
+ Inputs (0 .. 1) := (0 => Create_Input ("iport"),
1 => Create_Input ("addr"));
- Outputs (0 .. 1) := (0 => Create_Output ("nport"),
+ Outputs (0 .. 1) := (0 => Create_Output ("oport"),
1 => Create_Output ("data"));
Set_Ports_Desc (Res, Inputs (0 .. 1), Outputs (0 .. 1));
@@ -350,11 +352,11 @@ package body Netlists.Builders is
New_Sname_Artificial (Get_Identifier ("mem_rd_sync"), No_Sname),
Id_Mem_Rd_Sync, 4, 2, 0);
Ctxt.M_Mem_Rd_Sync := Res;
- Inputs (0 .. 3) := (0 => Create_Input ("pport"),
+ Inputs (0 .. 3) := (0 => Create_Input ("iport"),
1 => Create_Input ("addr"),
2 => Create_Input ("clk"),
3 => Create_Input ("en"));
- Outputs (0 .. 1) := (0 => Create_Output ("nport"),
+ Outputs (0 .. 1) := (0 => Create_Output ("oport"),
1 => Create_Output ("data"));
Set_Ports_Desc (Res, Inputs (0 .. 3), Outputs (0 .. 1));
@@ -363,12 +365,12 @@ package body Netlists.Builders is
New_Sname_Artificial (Get_Identifier ("mem_wr_sync"), No_Sname),
Id_Mem_Wr_Sync, 5, 1, 0);
Ctxt.M_Mem_Wr_Sync := Res;
- Inputs := (0 => Create_Input ("pport"),
+ Inputs := (0 => Create_Input ("iport"),
1 => Create_Input ("addr"),
2 => Create_Input ("clk"),
3 => Create_Input ("en"),
4 => Create_Input ("data"));
- Outputs (0 .. 0) := (0 => Create_Output ("nport"));
+ Outputs (0 .. 0) := (0 => Create_Output ("oport"));
Set_Ports_Desc (Res, Inputs (0 .. 4), Outputs (0 .. 0));
end Create_Memory_Modules;
@@ -1117,7 +1119,7 @@ package body Netlists.Builders is
return O;
end Build_Addidx;
- function Build_Memory (Ctxt : Context_Acc; W : Width) return Net
+ function Build_Memory (Ctxt : Context_Acc; W : Width) return Instance
is
pragma Assert (W > 0);
Inst : Instance;
@@ -1126,11 +1128,11 @@ package body Netlists.Builders is
Inst := New_Internal_Instance (Ctxt, Ctxt.M_Memory);
O := Get_Output (Inst, 0);
Set_Width (O, W);
- return O;
+ return Inst;
end Build_Memory;
function Build_Memory_Init (Ctxt : Context_Acc; W : Width; Init : Net)
- return Net
+ return Instance
is
pragma Assert (W > 0);
pragma Assert (Get_Width (Init) = W);
@@ -1140,8 +1142,8 @@ package body Netlists.Builders is
Inst := New_Internal_Instance (Ctxt, Ctxt.M_Memory_Init);
O := Get_Output (Inst, 0);
Set_Width (O, W);
- Connect (Get_Input (Inst, 0), Init);
- return O;
+ Connect (Get_Input (Inst, 1), Init);
+ return Inst;
end Build_Memory_Init;
function Build_Mem_Rd
diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads
index 02f616a8f..d28c8c332 100644
--- a/src/synth/netlists-builders.ads
+++ b/src/synth/netlists-builders.ads
@@ -131,9 +131,9 @@ package Netlists.Builders is
I : Net; Step : Uns32; Max : Uns32; W : Width) return Net;
function Build_Addidx (Ctxt : Context_Acc; L, R : Net) return Net;
- function Build_Memory (Ctxt : Context_Acc; W : Width) return Net;
+ function Build_Memory (Ctxt : Context_Acc; W : Width) return Instance;
function Build_Memory_Init (Ctxt : Context_Acc; W : Width; Init : Net)
- return Net;
+ return Instance;
function Build_Mem_Rd
(Ctxt : Context_Acc; Pport : Net; Addr : Net; Data_W : Width)
return Instance;
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index eae711c57..ac077f4a7 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -645,16 +645,17 @@ package body Netlists.Disp_Vhdl is
-- Clock
S := Get_Input_Net (Port_Inst, 2);
Data_W := Get_Width (Get_Output (Port_Inst, 1));
+ when Id_Memory
+ | Id_Memory_Init =>
+ exit;
when others =>
raise Internal_Error;
end case;
- Disp_Net_Name (S);
- Port := Get_Output (Port_Inst, 0);
- if Is_Connected (Port) then
+ if Port /= Ports then
Put (", ");
- else
- exit;
end if;
+ Disp_Net_Name (S);
+ Port := Get_Output (Port_Inst, 0);
end loop;
Put_Line (") is");
@@ -675,7 +676,7 @@ package body Netlists.Disp_Vhdl is
Val : Net;
Val_Inst : Instance;
begin
- Val := Get_Input_Net (Mem, 0);
+ Val := Get_Input_Net (Mem, 1);
Val_Inst := Get_Net_Parent (Val);
if Get_Id (Val_Inst) = Id_Isignal then
Val := Get_Input_Net (Val_Inst, 1);
@@ -711,11 +712,13 @@ package body Netlists.Disp_Vhdl is
Disp_Template ("\o0", Mem);
Disp_Template ("(to_integer (\ui1));" & NL, Port_Inst);
Put_Line (" end if;");
+ when Id_Memory
+ | Id_Memory_Init =>
+ exit;
when others =>
raise Internal_Error;
end case;
Port := Get_Output (Port_Inst, 0);
- exit when not Is_Connected (Port);
end loop;
Put_Line (" end process;");
end Disp_Memory;
diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb
index f9f566e5c..f490d54e3 100644
--- a/src/synth/netlists-memories.adb
+++ b/src/synth/netlists-memories.adb
@@ -553,9 +553,9 @@ package body Netlists.Memories is
return Res;
end Create_Read_Port;
- -- MEM_LINK is the link from the last port (or from the memory).
+ -- MEM_INST is the memory instance.
procedure Replace_Read_Ports
- (Ctxt : Context_Acc; Orig : Instance; Mem_Link : Net)
+ (Ctxt : Context_Acc; Orig : Instance; Mem_Inst : Instance)
is
Orig_Net : constant Net := Get_Output (Orig, 0);
Last : Net;
@@ -568,7 +568,7 @@ package body Netlists.Memories is
Val_W : Width;
Port_Inst : Instance;
begin
- Last := Mem_Link;
+ Last := Get_Output (Mem_Inst, 0);
-- Convert readers.
Inp := Get_First_Sink (Orig_Net);
@@ -605,17 +605,20 @@ package body Netlists.Memories is
end case;
Inp := Next_Inp;
end loop;
+
+ -- Close the loop.
+ Connect (Get_Input (Mem_Inst, 0), Last);
end Replace_Read_Ports;
-- ORIG (the memory) must be Const.
procedure Replace_ROM_Memory (Ctxt : Context_Acc; Orig : Instance)
is
Orig_Net : constant Net := Get_Output (Orig, 0);
- Last : Net;
+ Inst : Instance;
begin
- Last := Build_Memory_Init (Ctxt, Get_Width (Orig_Net), Orig_Net);
+ Inst := Build_Memory_Init (Ctxt, Get_Width (Orig_Net), Orig_Net);
- Replace_Read_Ports (Ctxt, Orig, Last);
+ Replace_Read_Ports (Ctxt, Orig, Inst);
end Replace_ROM_Memory;
-- Try to reach Id_Signal/Id_Isignal (TODO: Id_Output) from dyn_insert
@@ -966,7 +969,7 @@ package body Netlists.Memories is
Offs : Off_Array_Acc;
Nbr_Offs : Int32;
- Heads : Net_Array_Acc;
+ Heads : Instance_Array_Acc;
Tails : Net_Array_Acc;
Outs : Net_Array_Acc;
begin
@@ -1133,7 +1136,7 @@ package body Netlists.Memories is
end if;
-- 3. Create array of instances
- Heads := new Net_Array (1 .. Nbr_Offs - 1);
+ Heads := new Instance_Array (1 .. Nbr_Offs - 1);
Tails := new Net_Array (1 .. Nbr_Offs - 1);
Outs := new Net_Array (1 .. Nbr_Offs - 1);
@@ -1155,7 +1158,7 @@ package body Netlists.Memories is
when others =>
raise Internal_Error;
end case;
- Tails (I) := Heads (I);
+ Tails (I) := Get_Output (Heads (I), 0);
end;
end loop;
@@ -1168,6 +1171,7 @@ package body Netlists.Memories is
Dff_Clk : Net;
begin
-- Try to extract clock from dff.
+ -- FIXME: this is wrong as it assumes there is only one dff.
Dff_Clk := No_Net;
Inst := Get_Input_Instance (Sig, 0);
case Get_Id (Inst) is
@@ -1182,7 +1186,8 @@ package body Netlists.Memories is
Inst := Sig;
loop
-- Check gates connected to the output.
- -- First the dyn_extract
+ -- First the read ports (dyn_extract), and also find the next
+ -- gate in the loop.
N_Inst := No_Instance;
Inp := Get_First_Sink (Get_Output (Inst, 0));
while Inp /= No_Input loop
@@ -1265,14 +1270,15 @@ package body Netlists.Memories is
Inp := N_Inp;
end loop;
- -- Handle INST.
- case Get_Id (Inst) is
+ -- Handle N_Inst. If the output is connected to a write port,
+ -- add it (after the read ports).
+ case Get_Id (N_Inst) is
when Id_Dyn_Insert_En
| Id_Dyn_Insert =>
declare
- Off : constant Uns32 := Get_Param_Uns32 (Inst, 0);
+ Off : constant Uns32 := Get_Param_Uns32 (N_Inst, 0);
Wd : constant Width :=
- Get_Width (Get_Input_Net (Inst, 1));
+ Get_Width (Get_Input_Net (N_Inst, 1));
Idx : Int32;
Len : Int32;
Addr : Net;
@@ -1283,12 +1289,12 @@ package body Netlists.Memories is
Clk : Net;
begin
Off_Array_To_Idx (Offs.all, Off, Wd, Idx, Len);
- Inp2 := Get_Input (Inst, 2);
+ Inp2 := Get_Input (N_Inst, 2);
Addr := Get_Driver (Inp2);
Disconnect (Inp2);
Convert_Memidx (Ctxt, Mem_Sz, Addr, Mem_W);
- if Get_Id (Inst) = Id_Dyn_Insert_En then
- Inp2 := Get_Input (Inst, 3);
+ if Get_Id (N_Inst) = Id_Dyn_Insert_En then
+ Inp2 := Get_Input (N_Inst, 3);
En := Get_Driver (Inp2);
Disconnect (Inp2);
Clk := Dff_Clk;
@@ -1300,7 +1306,7 @@ package body Netlists.Memories is
if En = No_Net then
En := Build_Const_UB32 (Ctxt, 1, 1);
end if;
- Inp2 := Get_Input (Inst, 1);
+ Inp2 := Get_Input (N_Inst, 1);
Dat := Get_Driver (Inp2);
for I in Idx .. Idx + Len - 1 loop
Wr_Inst := Build_Mem_Wr_Sync
@@ -1311,9 +1317,24 @@ package body Netlists.Memories is
end loop;
Disconnect (Inp2);
end;
+ when Id_Dff
+ | Id_Idff =>
+ null;
+ when Id_Signal
+ | Id_Isignal =>
+ null;
+ when others =>
+ raise Internal_Error;
+ end case;
+
+ -- Remove INST.
+ case Get_Id (Inst) is
+ when Id_Dyn_Insert_En
+ | Id_Dyn_Insert =>
Remove_Instance (Inst);
when Id_Dff
| Id_Idff =>
+ -- Disconnect clock and init value.
Disconnect (Get_Input (Inst, 0));
if Get_Id (Inst) = Id_Idff then
Disconnect (Get_Input (Inst, 2));
@@ -1338,13 +1359,18 @@ package body Netlists.Memories is
end case;
end loop;
+ -- Close loops.
+ for I in Heads'Range loop
+ Connect (Get_Input (Heads (I), 0), Tails (I));
+ end loop;
+
-- Finish to remove the signal/isignal.
Remove_Instance (Inst);
end;
-- 6. Cleanup.
Free_Off_Array (Offs);
- Free_Net_Array (Heads);
+ Free_Instance_Array (Heads);
Free_Net_Array (Tails);
Free_Net_Array (Outs);
end Convert_To_Memory;
diff --git a/src/synth/netlists-utils.ads b/src/synth/netlists-utils.ads
index be6f58e9e..f7edc80c7 100644
--- a/src/synth/netlists-utils.ads
+++ b/src/synth/netlists-utils.ads
@@ -27,6 +27,10 @@ package Netlists.Utils is
procedure Free_Net_Array is new Ada.Unchecked_Deallocation
(Net_Array, Net_Array_Acc);
+ type Instance_Array_Acc is access Instance_Array;
+ procedure Free_Instance_Array is new Ada.Unchecked_Deallocation
+ (Instance_Array, Instance_Array_Acc);
+
function Get_Nbr_Inputs (Inst : Instance) return Port_Nbr;
function Get_Nbr_Outputs (Inst : Instance) return Port_Nbr;
function Get_Nbr_Params (Inst : Instance) return Param_Nbr;
diff --git a/src/synth/netlists.ads b/src/synth/netlists.ads
index f4462fbb6..8683d6943 100644
--- a/src/synth/netlists.ads
+++ b/src/synth/netlists.ads
@@ -102,6 +102,8 @@ package Netlists is
type Instance is private;
No_Instance : constant Instance;
+ type Instance_Array is array (Int32 range <>) of Instance;
+
-- Hash INST (simply return its index).
function Hash (Inst : Instance) return Hash_Value_Type;