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-debug.ads | 3 +- src/synth/synth-environment.ads | 107 +++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/synth/synth-environment-debug.ads b/src/synth/synth-environment-debug.ads index 8454f2c97..b45eb80ae 100644 --- a/src/synth/synth-environment-debug.ads +++ b/src/synth/synth-environment-debug.ads @@ -21,6 +21,7 @@ package Synth.Environment.Debug is procedure Dump_Wire_Id (Id : Wire_Id); procedure Dump_Assign (Asgn : Seq_Assign); - procedure Dump_Phi (Id : Phi_Id); procedure Dump_Conc_Assigns (First : Conc_Assign); +private + procedure Dump_Phi (Id : Phi_Id); end Synth.Environment.Debug; 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 '#n160'>160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322