diff options
| -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; | 
