SFL BNF (Backus-Naur Form)

Here is a short overview of the BNF formalism:

 

x1::= x2

x1 to be substituted with x2

 

x1 | x2

x1 or x2

 

{x}

zero or n times repetition of x

 

[x]

x may be omitted

 

'x

the terminal symbol x itself

Symbols

symbol ::= name|number|constant|keyword|reserved

name ::= char{char|digit}

number ::= digit{digit}

constant ::= 0{x16Number|o8Number|b2Number|X16Number|O8Number|B2Number}

16Number ::= {16Digit}

8Number ::= {8Digit}

2Number ::= {2Digit}

keyword ::= module|circuit|declare
                |input|output|bidirect
                |instrin|instrout|instrself
                |sel|bus|sel_v|bus_v
                |reg|reg_ws|reg_wr|mem
                |instr_arg|stage_name|task
                |instruct|stage
                |state_name|segment_name|first_state
                |state|segment
                |par|alt|any|if|else
                |goto|call|return|generate|relay|finish
                |'{|'}|;|,|(|)|.|:|'[|']
                |:=|=|==|'||@|&|'|'||+|'>|'<
                |'>'>|'<'<|^|/'||/@|/&|/|\|#

reserved ::= p_reset|m_clock|s_clock|b_clock|VDD|VSS
                |scan_in|scan_out|scan_enb|scan_clock|t_adrs_number

char ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
        |a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|_

2Digit ::= 0|1

8Digit ::= 0|1|2|3|4|5|6|7

digit ::= 0|1|2|3|4|5|6|7|8|9

16Digit ::= 0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|A|B|C|D|E|F

code ::= !|"|#|$|%|&|'|(|)|*|+|,|-|.|/|:|;
           |'<|=|'>|?|@|'[|\|']|^|`|'{|'||'}|~

blank ::= space|tab|newline

Remarks: There must be a blank character between symbols. Names can not start with an underscore character (i.e. _input is not allowed). Reserved words are later inserted by the PARTHENON synthesizer (SFLEXP, OPT_MAP, etc.) thus they should not be used by the SFL programmer.

SFL Description

SFLdescription ::=
        {moduleDeclaration|moduleDefinition|circuitDefinition}

moduleDeclaration ::=
        declare moduleName '{
                {ioTerminalDefinition}
                {specialArgumentDefinition}
        '}

ioTerminalDefinition ::=
          input dataInputTerm['<width '>]{,dataInputTerm['<width'>]};
        | output dataOutputTerm['<width '>]{,dataOutputTerm['<width '>]};
        | bidirect dataBidirectTerm['<['<width '>]{,dataBidirectTerm['<['<width '>]};
        | instrin ctrlInputTerm{,ctrlInputTerm};
        | instrout ctrlOutputTerm{,ctrlOutputTerm};

specialArgumentDefinition ::=
        instr_arg ctrlInputTerm([mappingInputTerm{,mappingInputTerm}]);

moduleDefinition ::=
        module moduleName '{
                {moduleDeclaration}
                {ioTerminalDefinition|facilityDefinition}
                {normalArgumentDefinition}
                {stageDefinition}
                [coreBehavior]
                {ctrlBehavior}
                {stageBehavior}
        '}

circuitDefinition ::=
        circuit circuitName '{
                {moduleDeclaration}
                {ioTerminalDefinition|facilityDefinition}
                {normalArgumentDefinition}
                {stageDefinition}
                [coreBehavior]
                {ctrlBehavior}
                {stageBehavior}
        '}

Remarks: If there are no arguments the "specialArgumentDefinition" part can be omitted.

Facilities

facilityDefinition ::=
          instrself ctrlInternalTerm{,ctrlInternalTerm};
        | bus dataInternalTerm['<['<width '>]{,dataInternalTerm['<['<width '>]};
        | sel dataInternalTerm['<['<width '>]{,dataInternalTerm['<['<width '>]};
        | bus_v dataInternalTerm['<['<width '>]{,dataInternalTerm['<['<width '>]};
        | sel_v dataInternalTerm['<['<width '>]{,dataInternalTerm['<['<width '>]};
        | reg regName['<['<width '>]{,regName['<['<width '>]};
        | reg_ws regName['<['<width '>]{,regName['<['<width '>]};
        | reg_wr regName['<['<width '>]{,regName['<['<width '>]};
        | mem memoryName '[wordNum ']['<['<width '>]{,memoryName '[wordNum ']['<['<width '>]};
        | moduleName submoduleName{,submoduleName};

Arguments

normalArgumentDefinition ::=
          instr_arg ctrlOutputTerm([mappingOutputTerm{,mappingOutputTerm}]);
        | instr_arg submoduleName.ctrlInputTerm([mappingInputTerm{,mappingInputTerm}]);
        | instr_arg ctrlInternalTerm([dataInternalTerm{,dataInternalTerm}]);

mappingInputTerm ::=
          dataInputTerm
        | dataBidirectTerm

mappingOutputTerm ::=
          dataOutputTerm
        | dataBidirectTerm

stageDefinition ::=
        stage_name stageName '{
                {task taskName([regName{,regName}]);}
        '}

Remarks: If there are no arguments the "normalArgumentDefinition" part can be omitted.

Behavior

coreBehavior ::= action

ctrlBehavior ::=
          instruct ctrlInputTerm action
        | instruct ctrlInternalTerm action
        | instruct submoduleName.ctrlOutputTerm action

stageBehavior ::=
        stage stageName '{
                {stageDefinition}
                {segmentDefinition}
                [firstStateDefinition]
                [coreBehavior]
                {stateBehavior}
                {segmentBehavior}
        '}

segmentBehavior ::=
        segment segmentName '{
                {stageDefinition}
                firstStateDefinition
                [coreBehavior]
                {stateBehavior}
        '}

stageDefinition ::= state_name stateName{,stateName};

segmentDefinition ::= segment_name segmentName{,segmentName};

firstStateDefinition ::= first_state stateName;

stateBehavior ::= state stateName action

Actions

action ::=
          parBlock
        | altBlock
        | anyBlock
        | ifBlock
        | elementAction

parBlock ::= par'{{action}'}

altBlock ::= alt'{condAction{condAction}[elseAction]'}

anyBlock ::= any'{condAction{condAction}[elseAction]'}

ifBlock ::= if(condition)action

condAction ::= condition:action

elseAction ::= else:action

condition ::= expr

Elementar actions

elementAction ::=
          writeDataTerm
        | writeReg
        | writeMemory
        | stateTransition
        | segmentCall
        | specialSegmentCall
        | segmentReturn
        | taskGenerate
        | taskRelay
        | taskFinish
        | ctrlAction
        | nopAction

writeDataTerm ::=
          dataInternalTerm=expr;
        | dataOutputTerm=expr;
        | dataBidirectTerm=expr;
        | submoduleName.dataInputTerm=expr;
        | submoduleName.dataBidirectTerm=expr;

writeReg ::= regName:=expr;

writeMemory ::= memoryName '[expr ']:=expr;

stateTransition ::= goto stateName;

segmentCall ::= call segmentName(returnStateName);

specialSegmentCall ::= call segmentName();

segmentReturn ::= return;

taskGenerate ::= generate stageName.taskName([arg{,arg}]);

taskRelay ::= relay stageName.taskName([arg{,arg}]);

taskFinish ::= finish;

ctrlAction ::=
          ctrlOutputTerm([arg{,arg}]);
        | submoduleName.ctrlInputTerm([arg{,arg}]);
        | ctrlInternalTerm([arg{,arg}]);

nopAction ::= ;

returnStateName ::= stateName

arg ::= expr

Expressions and operations

expr ::=
          unaryExpr '|expr     /* or */
        | unaryExpr @expr      /* eor */
        | unaryExpr &expr      /* and */
        | unaryExpr '|'|expr   /* concatination */
        | unaryExpr +expr      /* addition */
        | unaryExpr '>'>expr   /* right bit shift */
        | unaryExpr '<'<expr   /* left bit shift */
        | unaryExpr ==expr     /* equal test */
        | unaryExpr

unaryExpr ::=
          ^unaryExpr          /* negation */
        | /'|unaryExpr        /* all bit or */
        | /@unaryExpr         /* all bit eor */
        | /&unaryExpr         /* all bit and */
        | /unaryExpr          /* decode */
        | \unaryExpr          /* encode */
        | extensionNumber #unaryExpr           /* bit extension */
        | ident '<upperNumber[:lowerNumber]'>  /* bit extraction */
        | ident

Identifier

ident ::=
          (expr)
        | constant
        | regName
        | memoryName '[address ']
        | stageName.taskName
        | dataInternalTerm
        | ctrlInternalTerm
        | dataInputTerm
        | dataOutputTerm
        | dataBidirectTerm
        | ctrlInputTerm
        | ctrlOutputTerm
        | submoduleName.dataInputTerm
        | submoduleName.dataOutputTerm
        | submoduleName.dataBidirectTerm
        | submoduleName.ctrlInputTerm
        | submoduleName.ctrlOutputTerm
        | submoduleName.ctrlInputTerm([arg{,arg}]).dataOutputTerm
        | submoduleName.ctrlInputTerm([arg{,arg}]).dataBidirectTerm
        | ctrlInternalTerm([arg{,arg}]).dataInternalTerm
        | ctrlOutputTerm([arg{,arg}]).dataInputTerm
        | ctrlOutputTerm([arg{,arg}]).dataBidirectTerm

address ::= expr

Names and numbers

moduleName ::= name

circuitName ::= name

dataInputTerm ::= name

dataOutputTerm ::= name

dataBidirectTerm ::= name

dataInternalTerm ::= name

ctrlInputTerm ::= name

ctrlOutputTerm ::= name

ctrlInternalTerm ::= name

submoduleName ::= name

regName ::= name

memoryName ::= name

stageName ::= name

taskName ::= name

segmentName ::= name

stateName ::= name

width ::= number

wordNum ::= number

extensionNumber ::= number

upperNumber ::= number

lowerNumber ::= number

Remarks: For keeping consistency, "moduleName" and "circuitName" must be unique within a design. All other identifiers (facilities, data- and control terminals, stage names, etc.) can be reused in another module. It is also possible to reuse "taskName", "segmentName" and "stateName" in different stages.