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 |
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.
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.
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};
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.
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
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
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
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
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
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.