From db918fedf1af6da741bb6dd280719cb0f139b583 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 8 Apr 2020 08:21:30 +0200 Subject: synth-environment: add comments. --- src/synth/synth-environment.ads | 107 +++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 41 deletions(-) (limited to 'src/synth/synth-environment.ads') diff --git a/src/synth/synth-environment.ads b/src/synth/synth-environment.ads index 1abb918eb..f2f6c5dc2 100644 --- a/src/synth/synth-environment.ads +++ b/src/synth/synth-environment.ads @@ -27,18 +27,30 @@ with Netlists.Builders; with Synth.Source; package Synth.Environment is - -- A simple signal/variable is either a bit or a std_ulogic - -- signal/variable, or a bus (bit_vector, std_ulogic_vector, signed, - -- unsigned...). + -- This package declares the type Wire_Id and its methods. -- - -- Complex signals/variables (records, arrays) are decomposed to simple - -- signals/variables. + -- A wire_id represents an HDL signal or variable and keeps the current + -- value of it accross control statements. + -- This is not a memory storage, because: + -- * the current value may not be static. + -- e.g.: a <= b + 1; -- If B is a port, the value of A is defined but + -- -- not known + -- * the current value depends on the control statements. + -- e.g.: a := data; -- a0 + -- if cond then + -- a := a + 4; -- Reads a0, but writes to a1 + -- b := a + 1; -- Reads a1, writes b1 + -- else + -- b <= a + 2; -- Reads a0, writes b2 + -- end if; + -- c <= b * 2; -- b = phi(cond, b1, b2) -- - -- Each simple signal/variable is represented by a Wire_Id. Synthesis - -- deals only with these wires or group of them. + -- This is very similar to SSA (static single assignments) + type Wire_Id is private; No_Wire_Id : constant Wire_Id; + -- Wire_Id can be ordered, so that merges can be efficient. function Is_Lt (L, R : Wire_Id) return Boolean; -- A Wire is either a signal, a variable or a port. We need to know the @@ -52,22 +64,20 @@ package Synth.Environment is Wire_Input, Wire_Output, Wire_Inout ); - type Seq_Assign is private; - No_Seq_Assign : constant Seq_Assign; - - type Conc_Assign is private; - No_Conc_Assign : constant Conc_Assign; - -- Create a wire. - function Alloc_Wire (Kind : Wire_Kind; Obj : Source.Syn_Src) - return Wire_Id; + function Alloc_Wire (Kind : Wire_Kind; Obj : Source.Syn_Src) return Wire_Id; -- Mark the wire as free. procedure Free_Wire (Wid : Wire_Id); + -- Read and write the mark flag. + function Get_Wire_Mark (Wid : Wire_Id) return Boolean; + procedure Set_Wire_Mark (Wid : Wire_Id; Mark : Boolean := True); + -- Simple mark & release. This is a very simple mechanism (will free -- all wires allocated after the mark), but efficient and working well -- for the stack based allocation. + -- Not related to the mark flag. procedure Mark (M : out Wire_Id); procedure Release (M : in out Wire_Id); @@ -78,34 +88,33 @@ package Synth.Environment is -- Used for internal wires (exit/quit) when exiting their scope. procedure Phi_Discard_Wires (Wid1 : Wire_Id; Wid2 : Wire_Id); + -- For signals, only the future value can be assigned. But the current + -- value can be read. A gate is needed to represent the current value + -- (as only a gate can provide a net). In most cases, this is a virtual + -- gate whose output is equal to the input and this virtual gate would be + -- later removed during cleanup. + -- -- Set the gate for a wire. - -- The gate represent the current value. It is usually an Id_Signal. procedure Set_Wire_Gate (Wid : Wire_Id; Gate : Net); function Get_Wire_Gate (Wid : Wire_Id) return Net; -- The current value of WID. For variables, this is the last assigned - -- value. For signals, this is the initial value. + -- value. For signals, this is the gate. -- A builder is needed in case of concatenation. function Get_Current_Value (Ctxt : Builders.Context_Acc; Wid : Wire_Id) return Net; + -- Get the currently assigned value of WID at OFF/WD. + -- Used when assigning as a memory. function Get_Current_Assign_Value (Ctxt : Builders.Context_Acc; Wid : Wire_Id; Off : Uns32; Wd : Width) return Net; - -- Read and write the mark flag. - function Get_Wire_Mark (Wid : Wire_Id) return Boolean; - procedure Set_Wire_Mark (Wid : Wire_Id; Mark : Boolean := True); - - type Phi_Id is private; - No_Phi_Id : constant Phi_Id; - - function Get_Wire_Id (W : Seq_Assign) return Wire_Id; - function Get_Assign_Chain (Asgn : Seq_Assign) return Seq_Assign; - - function Get_Assign_Value (Ctxt : Builders.Context_Acc; Asgn : Seq_Assign) - return Net; + -- In the current phi context, assign VAL to DEST. + procedure Phi_Assign + (Ctxt : Builders.Context_Acc; Dest : Wire_Id; Val : Net; Offset : Uns32); + -- A Phi represent a split in the control flow (two or more branches). type Phi_Type is private; -- Create a new phi context. @@ -132,23 +141,25 @@ package Synth.Environment is T, F : Phi_Type; Stmt : Source.Syn_Src); - -- Sort all seq assign of P by wire id. Used to more easily merge them. - function Sort_Phi (P : Phi_Type) return Seq_Assign; - - -- In the current phi context, assign VAL to DEST. - procedure Phi_Assign - (Ctxt : Builders.Context_Acc; Dest : Wire_Id; Val : Net; Offset : Uns32); + -- Lower level part. + -- Currently public to handle case statements. - -- Get current phi context. - function Current_Phi return Phi_Id; - pragma Inline (Current_Phi); + -- Within a Phi, assignments are represented as a linked list of + -- sequential assignments. + type Seq_Assign is private; + No_Seq_Assign : constant Seq_Assign; - procedure Add_Conc_Assign - (Wid : Wire_Id; Val : Net; Off : Uns32; Stmt : Source.Syn_Src); + -- Sort all seq assign of P by wire id. Used to more easily merge them. + function Sort_Phi (P : Phi_Type) return Seq_Assign; - procedure Finalize_Assignments (Ctxt : Builders.Context_Acc); + -- A sequential assignment represent an assignment to a wire. + function Get_Wire_Id (W : Seq_Assign) return Wire_Id; + function Get_Assign_Chain (Asgn : Seq_Assign) return Seq_Assign; + function Get_Assign_Value (Ctxt : Builders.Context_Acc; Asgn : Seq_Assign) + return Net; -- For low-level phi merge. + -- A sequential assignment is a linked list of partial assignment. type Partial_Assign is private; No_Partial_Assign : constant Partial_Assign; @@ -180,6 +191,16 @@ package Synth.Environment is Off : in out Uns32; Wd : out Width); + -- Concurrent assignments. + + type Conc_Assign is private; + No_Conc_Assign : constant Conc_Assign; + + procedure Add_Conc_Assign + (Wid : Wire_Id; Val : Net; Off : Uns32; Stmt : Source.Syn_Src); + + procedure Finalize_Assignments (Ctxt : Builders.Context_Acc); + -- A const wire is a wire_signal which has one whole (same width as the -- wire) assignment and whose assignment value is a const net. -- That's rather restrictive but still efficient. @@ -209,6 +230,10 @@ private type Phi_Id is new Uns32; No_Phi_Id : constant Phi_Id := 0; + -- Get current phi context. + function Current_Phi return Phi_Id; + pragma Inline (Current_Phi); + type Wire_Id_Record is record -- Kind of wire: signal, variable... -- Set at initialization and cannot be changed. -- cgit v1.2.3