diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/ghdlsynth_gates.h | 2 | ||||
-rw-r--r-- | src/synth/netlists-builders.adb | 38 | ||||
-rw-r--r-- | src/synth/netlists-builders.ads | 4 | ||||
-rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 17 | ||||
-rw-r--r-- | src/synth/netlists-memories.adb | 64 | ||||
-rw-r--r-- | src/synth/netlists-utils.ads | 4 | ||||
-rw-r--r-- | src/synth/netlists.ads | 2 |
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; |