.. _Specification:Syntax:

File Syntax description
-----------------------

FASM is a line oriented format.

* A single FASM line will do nothing (blank or comments or annotations) or enable a set of features.
* The FASM file format does not support line continuations. Enabling a feature will always be contained within one line.
* Constants and arrays follow verilog syntax

Due to the line orientated format, a FASM file has the following properties:

* Removing a line from a FASM file, produces a FASM file.
* Concatenating two FASM files together, produces a FASM file.
* Sorting a FASM file does not change the resulting bitstream.

If two FASM files are identical, then the resulting bitstream should have identical set of features are enabled. FASM does support various equivalent forms for enabling features, so there is a "canonical" form of a FASM file that removes this variation. If the canonical forms of two FASM files are the same, then they must generate the same bitstream.

Lines
+++++

Examples FASM feature lines
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Canonical enabling of feature
`````````````````````````````

.. code-block:: text

    # Set a single feature bit to 1 (with an implicit 1)
    INT_L_X10Y146.SW6BEG0.WW2END0
    CLBLL_L_X12Y124.SLICEL_X0.BLUT.INIT[17]

Recommended bitarray
````````````````````

.. code-block:: text

    # Setting a bitarray
    CLBLL_R_X13Y132.SLICEL_X0.ALUT.INIT[63:32] = 32'b11110000111100001111000011110000

Permitted advanced variations
`````````````````````````````

.. code-block:: text

    # The bitarray syntax also allows explicit 1 and explicit 0, if verbosity is desired.
    # An explicit 1 is the same as an implicit 1.
    INT_L_X10Y146.SW6BEG0.WW2END0 = 1
    CLBLL_L_X12Y124.SLICEL_X0.BLUT.INIT[17] = 1
    # Explicit bit range to 1
    INT_L_X10Y146.SW6BEG0.WW2END0[0:0] = 1'b1
    CLBLL_L_X12Y124.SLICEL_X0.BLUT.INIT[17:17] = 1'b1

    # An explicit 0 has no effect on the bitstream output.
    INT_L_X10Y146.SW6BEG0.WW2END0 = 0
    CLBLL_L_X12Y124.SLICEL_X0.BLUT.INIT[17] = 0
    # Explicit bit range to 0
    INT_L_X10Y146.SW6BEG0.WW2END0[0:0] = 1'b0
    CLBLL_L_X12Y124.SLICEL_X0.BLUT.INIT[17:17] = 1'b0

Annotations
+++++++++++

To allow tools to output machine usable annotations (e.g. compiler metadata), annotations are supported. Annotations can be on the line with a FASM feature, or on a line by itself. An annotations must not change the output bitstream. If an annotation would have an affect on the output bitstream, it should be a FASM feature.

Annotations that are on the same line as a FASM feature are associated with the feature. Annotations that are on a line with no FASM feature as associated with the FASM file itself.

Example Annotations
~~~~~~~~~~~~~~~~~~~

.. code-block:: text

    # Annotation on a FASM feature
    INT_L_X10Y146.SW6BEG0.WW2END0 { .attr = "" }
    INT_L_X10Y146.SW6BEG0.WW2END0 { .filename = "/a/b/c.txt" }
    INT_L_X10Y146.SW6BEG0.WW2END0 { module = "top", file = "/a/b/d.txt", line_number = "123" }

    # Annotation by itself
    { .top_module = "/a/b/c/d.txt" }

    # Annotation with FASM feature and comment
    INT_L_X10Y146.SW6BEG0.WW2END0 { .top_module = "/a/b/c/d.txt" } # This is a comment

Formal syntax specification of a line of a FASM file
++++++++++++++++++++++++++++++++++++++++++++++++++++

.. code-block:: text

    Identifier ::= [a-zA-Z] [0-9a-zA-Z]*
    Feature ::= Identifier ( '.' Identifier )*
    S ::= #x9 | #x20

    DecimalValue ::= [0-9_]*
    HexidecimalValue ::= [0-9a-fA-F_]+
    OctalValue ::= [0-7_]+
    BinaryValue ::= [01_]+

    VerilogValue ::= (( DecimalValue? S* "'" ( 'h' S* HexidecimalValue | 'b' S* BinaryValue | 'd' S*  DecimalValue | 'o' S* OctalValue ) | DecimalValue )

    FeatureAddress ::= '[' DecimalValue (':' DecimalValue)? ']'

    Any ::= [^#xA#]
    Comment ::= '#' Any*

    AnnotationName ::= [.a-zA-Z] [_0-9a-zA-Z]*
    NonEscapeCharacters ::= [^\"]
    EscapeSequences ::= '\\' | '\"'
    Annotation ::= AnnotationName S* '=' S* '"' (NonEscapeCharacters | EscapeSequences)* '"'
    Annotations ::= '{' S* Annotation ( ',' S* Annotation )* S* '}'

    SetFasmFeature ::= Feature FeatureAddress? S* ('=' S* VerilogValue)?
    FasmLine ::= S* SetFasmFeature? S* Annotations? S* Comment?

Canonicalization
++++++++++++++++

If two FASM files have been canonicalized and are identical, then they enable an identical set of features. The canonical FASM file is also equivalent to the FASM file that would be generated by taking the output bitstream and converting it back into a FASM file.

The canonicalization process is as follows:

#. Flatten any ``FeatureAddress`` with width greater than 1.

   * For ``SetFasmFeature`` lines with a ``FeatureAddress`` width greater than 1 bit, 1 ``SetFasmFeature`` for the width the original ``FeatureAddress``.
   * When flattening, if the flattened address is 0, do not emit the address.
#. Remove all comments and annotations.
#. If the ``FeatureValue`` is 0, remove the FASM line.
#. If the ``FeatureValue`` is 1, only output the ``Feature`` and the ``FeatureAddress`` if the ``Feature`` has addresses other than 0.
#. Remove any lines that do not modify the default bitstream.

   * Example are psuedo-pips in Xilinx parts.
#. Sort the lines in the FASM file.

Example Canonicalization
~~~~~~~~~~~~~~~~~~~~~~~~

``ALUT.INIT[0] = 1``

becomes

``ALUT.INIT``

----

``ALUT.SMALL = 1``

becomes

``ALUT.SMALL``

----

``ALUT.INIT[3:0] = 4'b1101``

becomes

``ALUT.INIT``

``ALUT.INIT[2]``

``ALUT.INIT[3]``
