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.