Appendix B.

VHDL-1076.1 Formatter

This appendix contains a VHDL formatter, a program to produce readable text files from data structures representing a VHDL-1076.1 design. This version basically fixes bugs in the original formatter program for VHDL-87 written by Peter B. Reintjes and upgrades it to the VHDL/VHDL-AMS standard. It has been tested on the accompanying VHDL-87, VHDL-93, and VHDL-AMS test programs.

The declarative nature of logic programs suggests that a program to produce the textual form of a parse-tree should be identical to a parser for that language. Although this is possible, it is impractical for two reasons:

  1. Whitespace is eliminated deterministically by a separate tokenizer. Otherwise, a complex rule for aritrary amounts of whitespace between every token would consume most of the parser's time. Meanwhile, in the formatter, the result of re-inserting the minimum amount of whitespace during production would not produce a well-formatted text.
  2. A complex language such as VHDL has many optional constructs as well as implied default values. For this reason, the order of rules required to produce the correct output may be different from that to recognize the language unambigously.

Both of these rules result from a very simple principle: there are an exponential number of ways to compose the tokens to produce a legal output file. While the parser has to be ready to accept this diversity, if the parser is used as a generator, this non-determinism is counter productive. In particular, we want the output to be indented and spaced in a specific readable way, independent of how the original source was formatted.

Like the parser, the formatter is largely a collection of grammar rules which describe the IEEE Standard 1076.1-1997 of VHDL language. These grammar rules have been numbered to correspond with the rules in VHDL parser described earlier.

There are essentially three categories of grammar rules in the VHDL formatter. The first includes rules which are no different from the rules in the parser, primarily because they define simple conjunctions of non-terminals. Rule 128 is a good example:


write_vhdl_opt_binding_indication(binding(EA,GAL,PAL)) -->
         write_vhdl_opt_entity_aspect(EA),
        [indent],
         write_vhdl_opt_generic_map_statement(GAL),
        newline,
         write_vhdl_opt_port_map_statement(PAL).
        [undent],

The second category includes rules which only differ from their parser counterparts because of the inclusion of whitespace and formatting directives. Large structures like process and architecture blocks must have this additional information in order to produce readable texts. Rule 108 shows the use of indentation and newline control.


write_vhdl_case_statement_alternatives([vhdl_case(Choices,Ss)|Cases]) -->
       " when ",  write_vhdl_choices(Choices), " => ", newline,
     [indent],
       write_vhdl_sequential_statements(Ss),
     [undent], 
       write_vhdl_case_statement_alternatives(Cases).

Where newline//1 inserts an ASCII newline character into the output list. This can be easily changed to have a newline and a carriage return in non-UNIX systems.


newline --> [10].

Rules in the third category differ from the parser rules in ways that affect the program flow-of-control. The resulting rules still look like grammar rules, but may have the clauses ordered differently and contain extra cuts. A simple example of how the parser and the formatter must differ can be found in the rule for an optional association-list in VHDL (It is not even necessary to understand what an association-list is to follow this example).

In the parser, Rule 24 first tries to recognize an association list (whatever that is). If the first clause fails, the second clause returns the empty list to indicate that the optional association-list is empty.


vhdl_opt_association_list(A)  --> vhdl_association_list(A).
vhdl_opt_association_list([]) --> [].

On the other hand, if we encounter the empty list when preparing to print out the optional association-list, we want to know this first. In this case, we commit to this clause while adding nothing to the output.

The second clause is only taken if the list contains something.


write_vhdl_opt_association_list([]) --> !, [].
write_vhdl_opt_association_list(A)  --> write_vhdl_association_list(A).

As an aside, we should note that the absence of a cut in the parser code is rather subtle. We may not want to commit, even if after a legal association-list has been parsed. For example, imagine the following grammar rule as it encounters a single association-list.


two_lists(A1,A2) -->
      vhdl_opt_association_list(A1), vhdl_association_list(A2).

Although we cannot use exactly the same code for the parser and the formatter, their similarity can be exploited by using the parser as a template for the formatter. Currently, this is a manual task, but it is considerably easier than trying to write a formatter from scratch.

This VHDL formatter has the same number of rules as the parser, and their form is nearly identical. The DCG list arguments are not lists of tokens being consumed but lists of characters being built-up as we insert the appropriate tokens, identifiers, and whitespace. Terminals appear in the formatter as lists of characters (``architecture'', ``if'', ``when'', etc). As we produce this list of characters, we insert the two tokens, indent and undent , which will be used as signals to control the correct tabbing when this list of characters is sent to the output.

Thus, to produce a formatter for a language from a parser, we must do the following:

  1. Change tokens to character strings with appropriate spaces: [begin] -> ``begin '' .
  2. Change the order of rules to handle null cases, empty optional fields, and the empty list base cases first rather than last. This may also involve deleting and/or inserting cuts.
  3. Introduce [indent] and [undent] tokens into the character list at appropriate points.

After this character list has been created by the ``grammar'', the following code writes the list of characters to the output.


write_list([],_).
write_list([undent,0';|Cs],Indent) :-                      
        !, write_list([0';,undent|Cs],Indent).
write_list([C|Cs],Indent) :-
        process(C,Indent,NewIndent),
        write_list(Cs,NewIndent).

The first rule in process/3 ensures that the correct number of spaces (the current indent) follow each newline character. The second, third and fourth clauses recognize the indent, undent and dent tokens and modify the current tab value appropriately. These tokens also generate a newline with the new indent. The last clause simply puts out the current character.


process(10,Indent,Indent)        :- !,
        put(10), putn(Indent,32). 

process(indent,Indent,NewIndent) :- !,
        NewIndent is Indent + 4,
        process(10,NewIndent,_).

process(undent,Indent,NewIndent) :- !,
        NewIndent is Indent - 4,
        process(10,NewIndent,_).

process(dent,Indent,NewIndent) :- !,
        NewIndent is Indent - 4.

process(C,Indent,Indent)         :-    put(C).

Thus, a modified grammar, together with these 13 lines of code produce a cleanly formatted text from a parse tree.

The following program will read a VHDL-1076.1 source file into Prolog terms and then produce a formatted version of that description. By itself, it implements a pretty-printer which will produce source-files with standard indentation and uniform case for keywords, but it is also a template for any program which must process VHDL designs.


main(+File) :-
        vhdl_read(+File,-Design_Units),
        
        % Place any algorithm in here ...
        
        write_vhdl_design_units(+Design_Units,0,-L,[]),
        write_list(-L,0).

write_vhdl_design_units([]) --> [].
write_vhdl_design_units([Design|Designs]) -->
      newline,
      write_vhdl_design_unit(Design),
      write_vhdl_design_units(Designs).

Additionally, this formatter can be used as the back-end of a schematic editor to produce VHDL source-files from the internal data structures built during schematic entry.

Like the parser upon which it is based, the size of this program is near the lower-limit for a program to accomplish this task. Since it describes the language completely, it cannot have less rules than the grammar. The thirteen lines above, together with the [indent] and [undent] tokens inserted into the grammar seem like a minimal price to pay for the function of generating readable VHDL source.


putn(N,_) :- N < 1, !.
putn(N,C) :- put(C), NN is N-1, putn(NN,C).
 
write_vhdl_design_units([],_) --> !, newline, [].
write_vhdl_design_units([Design|Designs],N) -->
      { NN is N+1, name(NN,NNCs) },
      newline,
      "--  VHDL DESIGN UNIT #", [ NNCs ],          
      newline,
      write_vhdl_design_unit(Design),
      write_vhdl_design_units(Designs,NN).

To write fragments of the original source file including documentation, we define the following predicates. (This enhancement was required in the context of the VHDL Design Browser.)


write_file_fragment(File, StartPos, EndPos) :- 
        seeing(Current_File),
	    	see(File),
                StartPos = '$stream_position'(SChPos,_,_),
                EndPos   = '$stream_position'(EChPos,_,_), 
                current_input(Stream),
	        stream_position(Stream,_,StartPos),
                copy_from_to(Stream,SChPos,EChPos),
                seen,
        see(Current_File).

copy_from_to(Stream,SP,EP) :- 
          ( at_end_of_stream(Stream) ; EP is SP + 1) 
                          ->  true;
                               ( get0(Ch), put(Ch), NP is SP + 1, 
                                 copy_from_to(Stream,NP,EP) ).

test_write_file(Name) :- 
                vhdl_read(Name),
                file_path(Name,File),
                assoc_file_design_unit(_,File,StartPos,EndPos), nl,
                nl, write('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'), nl,
                write_file_fragment(File,StartPos,EndPos),fail.  
test_write_file(_).

B.1 The VHDL IEEE 1076.1-1997 Writing Grammar

Rule 1


write_vhdl_designator(op(S),A,B) :- !, name(S,ST),
                                     append([0'"|ST],[0'"|B],A).  
write_vhdl_designator(ID) --> write_vhdl_identifier(ID).

Rule 2


write_vhdl_literal(null)  --> !,  " null ".
write_vhdl_literal(L)     --> write_vhdl_physical_literal(L).
write_vhdl_literal(L)     --> write_vhdl_enumeration_literal(L).
%write_vhdl_literal(L)    --> write_vhdl_abstract_literal(L).
write_vhdl_literal(L,A,B) :- double_the_quotes(L,LL),
                             append([0'"|LL],[0'"|B],A).  
                                               %string or bit-string 

double_the_quotes([],[]).
double_the_quotes([0'"|T],[0'",0'"|TT]) :- !, double_the_quotes(T,TT).
double_the_quotes([H|T],[H|TT]) :- double_the_quotes(T,TT).

Rule 3


write_vhdl_abstract_literal(F) --> write_vhdl_identifier(F).

Rule 4


write_vhdl_enumeration_literal(char(L))  --> !, "'", [L], "'".
write_vhdl_enumeration_literal(ID) --> write_vhdl_identifier(ID).

Rule 5


write_vhdl_physical_literal(pl(AL,ID)) -->
        write_vhdl_abstract_literal(AL), " ",
        write_vhdl_identifier(ID), " ".

Rule 6


write_vhdl_identifier(ID) -->
        { atomic(ID), name(ID,IDC) }, 
        { process_extended_id(IDC,IDCs) }, [  IDCs ].     

process_extended_id([0'\|TB],[0'\|TT]) :- !, double_the_backslash(TB,TT).
process_extended_id(TT,TT).

double_the_backslash([0'\],[0'\]) :- !.
double_the_backslash([0'\|T],[0'\,0'\|TT]) :- !, double_the_backslash(T,TT).
double_the_backslash([H|T],[H|TT]) :- double_the_backslash(T,TT).

write_vhdl_identifier_list([])   --> [].
write_vhdl_identifier_list([ID]) --> !,
        write_vhdl_identifier(ID).
write_vhdl_identifier_list([ID|IDs]) -->
        write_vhdl_identifier(ID), ", ",
        write_vhdl_identifier_list(IDs).

B.2 Design Unit

Rule 7


write_vhdl_design_unit(design_unit(CI,Unit)) -->
        write_vhdl_opt_context_items(CI),
        write_vhdl_library_unit(Unit), ";", newline.

Rule 8


write_vhdl_library_unit(LU) --> write_vhdl_entity_declaration(LU).
write_vhdl_library_unit(LU) --> write_vhdl_configuration_declaration(LU).
write_vhdl_library_unit(LU) --> write_vhdl_package_declaration(LU).
write_vhdl_library_unit(LU) --> write_vhdl_architecture_body(LU).
write_vhdl_library_unit(LU) --> write_vhdl_package_body(LU).

Rule 9


write_vhdl_opt_context_items([]) -->  [].

write_vhdl_opt_context_items([CI|CIs]) -->
        write_vhdl_library_clause(CI), !,
        ";", newline,
        write_vhdl_opt_context_items(CIs).

write_vhdl_opt_context_items([CI|CIs]) --> 
        write_vhdl_use_clause(CI),
        ";", newline,
        write_vhdl_opt_context_items(CIs).

Rule 10


write_vhdl_library_clause(library(IL)) -->
       "library ", write_vhdl_identifier_list(IL).

Rule 11


write_vhdl_opt_use_clauses([ ])      --> !, [ ].
write_vhdl_opt_use_clauses([UC|UCs]) -->
               write_vhdl_use_clause(UC), 
               write_vhdl_opt_use_clauses(UCs).

write_vhdl_use_clause(use([Name|Names])) -->
       " use ", write_vhdl_selected_name(Name),
               write_vhdl_selected_names(Names).

write_vhdl_selected_names([]) --> [].

write_vhdl_selected_names([Name|Names]) -->
         ",",  write_vhdl_selected_name(Name),
               write_vhdl_selected_names(Names).

B.3 Library Units

Rule 12


write_vhdl_entity_declaration(entity(ID,GIL,PIL,DIs,Ss)) -->
       "entity ",  write_vhdl_identifier(ID), " is ",
  [indent],
         write_vhdl_opt_generic_statement(GIL),
         write_vhdl_opt_port_statement(PIL),
         write_vhdl_opt_declarative_items(DIs),
         write_vhdl_opt_entity_body(Ss),
  [undent],
       "end ", write_vhdl_identifier(ID).

write_vhdl_opt_entity_body([]) --> [].
write_vhdl_opt_entity_body(Ss) -->
         "begin ", 
   [indent],
          write_vhdl_concurrent_statements(Ss),
   [undent].

write_vhdl_opt_generic_statement(null) --> !,[].
write_vhdl_opt_generic_statement(IL) -->
        " generic ",
    [indent],
        write_vhdl_interface_list(one_per_line,IL), ";",
    [undent].

write_vhdl_opt_port_statement(null) --> !, [].
write_vhdl_opt_port_statement(IL) -->
        " port ",
   [indent],
        write_vhdl_interface_list(one_per_line,IL), ";",
   [undent].

Rule 13


write_vhdl_architecture_body(arch(ID,Entity,DIs,Ss)) -->
       "architecture ",  write_vhdl_identifier(ID),
            " of ", write_vhdl_mark(Entity), " is ",
       [indent],
            write_vhdl_opt_declarative_items(DIs),
       "begin ",
       [indent],
         write_vhdl_concurrent_statements(Ss),
       [dent, undent],
       "end ", write_vhdl_identifier(ID). 

Rule 14


write_vhdl_configuration_declaration(conf(ID,Entity,DIs,Block)) -->
       "configuration ", write_vhdl_identifier(ID),
           " of ", write_vhdl_mark(Entity), " is ",
    [indent],
         write_vhdl_opt_declarative_items(DIs),
         write_vhdl_block_configuration(Block),
    [undent],
       "end ", write_vhdl_identifier(ID).     

Rule 15


write_vhdl_package_declaration(package(ID,Declarations)) -->
       "package ", write_vhdl_identifier(ID), " is ",
    [indent],
         write_vhdl_opt_declarative_items(Declarations),
    [undent],
       "end ", write_vhdl_identifier(ID).   

Rule 16


write_vhdl_package_body(package_body(ID,DIs)) -->
       "package  body ", write_vhdl_identifier(ID), " is ",
     [indent],
         write_vhdl_opt_declarative_items(DIs),
     [undent],
       "end ", write_vhdl_identifier(ID).

B.4 Declarative Item

Rule 17


write_vhdl_declarative_item(DI) --> write_vhdl_type_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_subtype_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_object_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_file_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_alias_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_subprogram_declaration_or_body(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_component_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_attribute_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_attribute_specification(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_configuration_specification(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_disconnection_specification(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_use_clause(DI).

write_vhdl_declarative_item(DI) --> write_vhdl_group_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_group_template_declaration(DI).

write_vhdl_declarative_item(DI) --> write_vhdl_nature_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_subnature_declaration(DI).

write_vhdl_declarative_item(DI) --> write_vhdl_terminal_declaration(DI).
write_vhdl_declarative_item(DI) --> write_vhdl_quantity_declaration(DI).


write_vhdl_opt_declarative_items([]) --> [].
write_vhdl_opt_declarative_items([I|Is]) -->
        write_vhdl_declarative_item(I), ";", newline,
        write_vhdl_opt_declarative_items(Is).

Rule 17.5


write_vhdl_procedural_declarative_item(DI) --> 
                    (  write_vhdl_subprogram_declaration(DI)
                    ;  write_vhdl_subprogram_body(DI)
                    ;  write_vhdl_type_declaration(DI)
                    ;  write_vhdl_subtype_declaration(DI)
%                    ;  write_vhdl_constant_declaration(DI)
%                    ;  write_vhdl_ordinary_variable_declaration(DI)
%                    ;  write_vhdl_shared_variable_declaration(DI)
                    ;  write_vhdl_object_declaration(DI)
                    ;  write_vhdl_alias_declaration(DI)
                    ;  write_vhdl_attribute_declaration(DI)
                    ;  write_vhdl_attribute_specification(DI)
                    ;  write_vhdl_use_clause(DI)
                    ;  write_vhdl_group_template_declaration(DI)
                    ;  write_vhdl_group_declaration(DI)
                    ).
write_vhdl_procedural_declarative_part([]) --> !, [].
write_vhdl_procedural_declarative_part([DI | DL]) --> 
                    write_vhdl_procedural_declarative_item(DI), ";", newline,
                    write_vhdl_procedural_declarative_part(DL).

write_vhdl_procedural_statement_part([]) --> !, [].
write_vhdl_procedural_statement_part([DI | DL]) --> 
                    write_vhdl_sequential_statement(DI), ";", newline,
                    write_vhdl_procedural_statement_part(DL).

B.5 Groups

VHDL-93 supports the concept of groups and group templates not present in VHDL-87.

Rule 17a


write_vhdl_group_template_declaration(group_template(TID,CL)) --> 
              "group ", write_vhdl_identifier(TID), " is ",
              "(", write_vhdl_entity_class_entry_list(CL), ")".

write_vhdl_entity_class_entry_list([C|CL]) -->
              write_vhdl_entity_class_entry(C), !,
              write_vhdl_entity_class_entry_list_aux(CL).

write_vhdl_entity_class_entry_list_aux([]) --> [ ].

write_vhdl_entity_class_entry_list_aux([C|CL]) -->
              ", ", !, write_vhdl_entity_class_entry(C),
              write_vhdl_entity_class_entry_list_aux(CL).

write_vhdl_entity_class_entry(entity_class(EC,any)) --> 
             !, write_vhdl_entity_class(EC), " <> ".

write_vhdl_entity_class_entry(entity_class(EC,null)) --> 
             write_vhdl_entity_class(EC).

Rule 17b


write_vhdl_group_declaration(group(ID,TID,CL)) --> 
             "group ",  write_vhdl_identifier(ID), " : ",
             write_vhdl_name(TID), 
             "(", write_vhdl_group_constituents(CL), ")".

write_vhdl_group_constituents([L|CL]) --> 
             write_vhdl_constituent(L),
             write_vhdl_group_constituents_aux(CL).

write_vhdl_group_constituents_aux([]) -->  [ ].

write_vhdl_group_constituents_aux([L|CL]) --> 
             ", ", write_vhdl_constituent(L),  
             write_vhdl_group_constituents_aux(CL).

write_vhdl_constituent(L)       --> write_vhdl_name(L).

write_vhdl_constituent(char(L)) --> "'", [ L ], "'".

B.6 Subprograms

Rule 18


write_vhdl_subprogram_declaration(sub_program(SS,null)) -->
        write_vhdl_subprogram_specification(_,SS).

write_vhdl_subprogram_declaration_or_body(sub_program(SS,Body)) -->
        newline,
        write_vhdl_subprogram_specification(Name,SS),
        write_vhdl_opt_subprogram_body(Name,Body).

Rule 19


write_vhdl_subprogram_specification(D,sub_spec(D,IL,null,null)) -->
        !, "procedure ", write_vhdl_designator(D),
        write_vhdl_opt_interface_list(all_in_line,IL).
write_vhdl_subprogram_specification(D,sub_spec(D,IL,TM,P)) -->
        ({ P = impure } -> "impure " ; []),
        "function ",  write_vhdl_designator(D),
        write_vhdl_opt_interface_list(all_in_line,IL),
        " return ", write_vhdl_mark(TM).

Rule 20


write_vhdl_opt_subprogram_body(_,null) --> !, [].

write_vhdl_opt_subprogram_body(Name,program_body(Is,Ss)) -->
        " is ",
        [indent],
           write_vhdl_opt_declarative_items(Is),
        [undent],
        "begin ",
        [indent],
           write_vhdl_sequential_statements(Ss),
        [undent],
        "end ", write_vhdl_designator(Name).

Rule 20.5


write_vhdl_subprogram_body(sub_program(SS,program_body(Is,Sst))) -->
        write_vhdl_subprogram_specification(Kind,Name,SS),
        " is ",
           write_vhdl_opt_declarative_items(subprogram,Is),
        " begin ",
           write_vhdl_sequential_statements(Sst),
        " end ", write_vhdl_opt_designator(Name).

B.7 Interface Lists and Association Lists

Rule 21


write_vhdl_opt_interface_list(_,[]) --> !, [].
write_vhdl_opt_interface_list(Indent_Mode,Is) -->
        write_vhdl_interface_list(Indent_Mode,Is).

write_vhdl_interface_list(Indent_Mode,Is) -->
        "(", write_vhdl_interface_elements(Indent_Mode,Is).

write_vhdl_interface_elements(Indent_Mode,[I|Is]) -->
        write_vhdl_interface_element(I),
        write_vhdl_ie_sub(Indent_Mode,Is).

write_vhdl_ie_sub(all_in_line,[]) --> !, ")".
write_vhdl_ie_sub(all_in_line,Is) --> ";  ",                  
        write_vhdl_interface_elements(all_in_line,Is).

write_vhdl_ie_sub(one_per_line,[]) --> !, ")".
write_vhdl_ie_sub(one_per_line,Is) --> ";", newline,
        write_vhdl_interface_elements(one_per_line,Is).

Rule 22


write_vhdl_interface_element(interface_element(Class,IL,Mode,ST,Bus,Expr)) -->
        write_vhdl_opt_object_class(Class),
        write_vhdl_identifier_list(IL), " :",
        write_vhdl_opt_mode(Mode),
        ({Class == terminal} ->         
                              write_vhdl_subnature_indication(ST)
                           ;  write_vhdl_subtype_indication(ST)),
        write_vhdl_opt_bus(Bus), write_vhdl_opt_assignment(Expr).

Rule 23


write_vhdl_opt_mode(in)      --> " in ".
write_vhdl_opt_mode(out)     --> " out ".
write_vhdl_opt_mode(inout)   --> " inout ".
write_vhdl_opt_mode(buffer)  --> " buffer ".
write_vhdl_opt_mode(linkage) --> " linkage ".
write_vhdl_opt_mode(null)    --> [].

write_vhdl_opt_bus(null) -->  [].
write_vhdl_opt_bus(bus) --> " bus ".

Rule 24


write_vhdl_association_list([A|As]) -->
      "(", write_vhdl_association_element(A),
           write_vhdl_more_association_list(As).

write_vhdl_more_association_list([])     --> !, ")".
write_vhdl_more_association_list([A|As]) -->
        ", ", write_vhdl_association_element(A),
        write_vhdl_more_association_list(As).

write_vhdl_opt_association_list([]) --> !, [].
write_vhdl_opt_association_list(A)  --> write_vhdl_association_list(A).

Rule 25


write_vhdl_association_element(element(Formal,Actual)) -->
      write_vhdl_opt_formal_part(Formal),
      write_vhdl_actual_part(Actual).

Rule 26


write_vhdl_formal_part(Name) --> write_vhdl_name(Name).
write_vhdl_formal_part(formal(FM,Name)) -->
         write_vhdl_mark(FM), "(", write_vhdl_name(Name), ")".

write_vhdl_opt_formal_part(null) --> !, [].
write_vhdl_opt_formal_part(Name) --> write_vhdl_formal_part(Name), " => ".

Rule 27


write_vhdl_actual_part(open) --> !, " open ".
write_vhdl_actual_part(Expr) --> write_vhdl_expression(Expr).

B.8 Names and Expressions

Rule 28


write_vhdl_mark(attr_name([N,A|As])) -->
                 write_vhdl_identifier(N), !, write_vhdl_opt_attrs([A|As]).
write_vhdl_mark(SN) --> write_vhdl_selected_name(SN).
write_vhdl_mark(ID) --> write_vhdl_identifier(ID).

write_vhdl_opt_mark(null) --> !, [].
write_vhdl_opt_mark(M)    --> write_vhdl_mark(M).

Rule 29


write_vhdl_expression(expr(Op,[F|EL])) -->
	 !, write_vhdl_relation(F),
         write_vhdl_relation_list(Op,EL).

write_vhdl_expression(expr(Op,F,E)) -->
	 !, write_vhdl_relation(F),
         write_vhdl_boolop_non_associative(Op),
         write_vhdl_relation(E).

write_vhdl_expression(E) -->  write_vhdl_relation(E).

write_vhdl_relation_list(_,[ ]) --> [ ].

write_vhdl_relation_list(Op,[E|EL]) -->
         write_vhdl_boolop_associative(Op), 
         write_vhdl_relation(E), 
         write_vhdl_relation_list(Op,EL).

write_vhdl_relation(rel(Op,F,E)) --> 
         !, write_vhdl_shift_expression(F),
         write_vhdl_relational_operator(Op),
         write_vhdl_shift_expression(E).

write_vhdl_relation(E) -->  write_vhdl_shift_expression(E).

write_vhdl_shift_expression(shift(Op,F,E)) --> 
          !, "(",
         write_vhdl_simple_expression(F),
         write_vhdl_shift_operator(Op),
         write_vhdl_simple_expression(E),
             ")".
write_vhdl_shift_expression(E) --> 
         write_vhdl_simple_expression(E).

write_vhdl_simple_expression(signed(Uop,F)) -->
         !, write_vhdl_sign(Uop), write_vhdl_term(F).

write_vhdl_simple_expression(term(T,Op,F)) -->
         !, write_vhdl_simple_expression(T),
         write_vhdl_adding_operator(Op), 
         write_vhdl_term(F).

write_vhdl_simple_expression(E) --> 
         write_vhdl_term(E).

write_vhdl_term(factor(T,Op,F)) -->
         !, write_vhdl_term(T), 
         write_vhdl_multiplying_operator(Op), 
         write_vhdl_factor(F).

write_vhdl_term(F) -->
         write_vhdl_factor(F).

write_vhdl_factor(nott(P)) -->
         !, " not ", write_vhdl_primary(P).

write_vhdl_factor(abs(P)) -->
         !, " abs ", write_vhdl_primary(P).

write_vhdl_factor(expt(P1,P2)) -->
         !,  write_vhdl_primary(P1),
         " ** ", write_vhdl_primary(P2).

write_vhdl_factor(F) --> write_vhdl_primary(F).

Rule 30


write_vhdl_primary(P) --> write_vhdl_aggregate(P).
write_vhdl_primary(P) --> write_vhdl_function_call(P).
write_vhdl_primary(P) --> write_vhdl_qualified_expression(P).
write_vhdl_primary(P) --> write_vhdl_name(P).
write_vhdl_primary(P) --> write_vhdl_literal(P).
write_vhdl_primary(P) --> write_vhdl_type_conversion(P).
write_vhdl_primary(P) --> write_vhdl_allocator(P).

% write_vhdl_primary(P) --> "(", write_vhdl_expression(P),")". 
write_vhdl_primary(P) --> 
             ({functor(P,F,_), 
               member(F,[expr,rel,shift,signed,term,factor,nott,abs,expt] )}
             -> "(", write_vhdl_expression(P), ")"
              ; [ ]).

%HACK: to avoid infinite loop thro parenthesized primary 

Rule 31


write_vhdl_name(attr_name([N,A|As])) --> !,
        write_vhdl_designator(N),
        write_vhdl_attr(A),
        write_vhdl_opt_attrs(As).
write_vhdl_name(N) --> write_vhdl_indexed_name(N).
write_vhdl_name(N) --> write_vhdl_selected_name(N).
write_vhdl_name(N) --> write_vhdl_slice_name(N).
write_vhdl_name(N) --> write_vhdl_designator(N).
write_vhdl_name(N) --> write_vhdl_attribute_name(N).

write_vhdl_opt_attrs([]) --> [].

write_vhdl_opt_attrs([A|As]) -->
         write_vhdl_attr(A),
         write_vhdl_opt_attrs(As).

write_vhdl_attr(A) --> "'", write_vhdl_identifier(A).

Rule 32


write_vhdl_selected_name(vhdl_name(P,S)) -->
       write_vhdl_prefix(P), ".", write_vhdl_suffix(S).

Rule 33

This rule is much simpler than its parser counterpart, since it merely has to write out the prefix subunits as it encounters them. The version of

Rule 33 in the parser

had to construct a binary tree by passing the first part of the prefix down as it searched for trailing components of a complex prefix.

write_vhdl_prefix(prefix(Prefix)) --> !,
        write_vhdl_prefix(Prefix).

write_vhdl_prefix(function_call(P1,Args,P2)) --> !,
        write_vhdl_prefix(P1),
        write_vhdl_association_list(Args),
        write_vhdl_prefix(P2).

write_vhdl_prefix(slice(P1,R,P2)) --> !,
        write_vhdl_prefix(P1),
        "(", write_vhdl_discrete_range(R), ")",
        write_vhdl_prefix(P2).

write_vhdl_prefix(select(P1,P2)) --> !,
        write_vhdl_prefix(P1), ".", write_vhdl_prefix(P2).

write_vhdl_prefix(attribute(P1,Attr,E,P2)) --> !,
        write_vhdl_prefix(P1),
        write_vhdl_attr(Attr),
        write_vhdl_opt_paren_expression(E),
        write_vhdl_prefix(P2).

write_vhdl_prefix(P) --> write_vhdl_identifier(P).

write_vhdl_opt_paren_expression(null) --> !, [].
write_vhdl_opt_paren_expression(E) -->
         "(", write_vhdl_expression(E), ")".

Rule 34


write_vhdl_suffix(char(C))   --> !, "'",[C],"' ".
write_vhdl_suffix(all)       --> !, "all ".
write_vhdl_suffix(dot(S,S2)) --> !,
         write_vhdl_designator(S), ".",
         write_vhdl_suffix(S2).
write_vhdl_suffix(S)         --> write_vhdl_designator(S).

Rule 35


write_vhdl_indexed_name(vhdl_name(P,[E|Es])) -->
       write_vhdl_prefix(P), "(",
       write_vhdl_expression(E),
       write_vhdl_expression_list(Es).

write_vhdl_expression_list([]) --> ")".
write_vhdl_expression_list([Expr|Exprs]) -->
        ",", write_vhdl_expression(Expr),
             write_vhdl_expression_list(Exprs).

Rule 36


write_vhdl_slice_name(vhdl_name(P,Range)) -->
       write_vhdl_prefix(P),
       "(", write_vhdl_discrete_range(Range), ")".

Rule 37


write_vhdl_attribute_name(vhdl_name(P,Sign,Attr,Expr)) -->
       write_vhdl_prefix(P),
       write_vhdl_opt_signature(Sign),       
       write_vhdl_attr(Attr),
       write_vhdl_opt_static_expression(Expr).

write_vhdl_opt_static_expression(null) --> !, [].
write_vhdl_opt_static_expression(Expr) -->
        "(", write_vhdl_expression(Expr), ")".

Rule 38


write_vhdl_function_call(vhdl_call(Call,Args)) -->
       write_vhdl_name(Call), write_vhdl_opt_association_list(Args).

Rule 39


write_vhdl_aggregate([A|As]) -->
      "(", write_vhdl_element_association(A), 
           write_vhdl_more_aggregate(A,As).

% FORMATTING HACK : introduce newline if the previous 
% element association is a choice-expr or an aggregate (3/23/98)

write_vhdl_more_aggregate(H,[])     --> ")".
write_vhdl_more_aggregate(H,[A|As]) --> ", ",
%  write_vhdl_element_association(A),  write_vhdl_more_aggregate(As).
%  newline, write_vhdl_element_association(A), write_vhdl_more_aggregate(As).
        ({ H \= element_association(null,_)} -> newline ; 
        ({ H = element_association(null,[_|_])} -> newline ; {true} ) ),
        write_vhdl_element_association(A),
        write_vhdl_more_aggregate(A,As).

Rule 40


write_vhdl_qualified_expression(qual_expr(Type,Expr)) -->
       write_vhdl_mark(Type), "'",
       "(", write_vhdl_expression_or_aggregate(Expr), ")".

write_vhdl_expression_or_aggregate(Expr) -->
       write_vhdl_expression(Expr).
write_vhdl_expression_or_aggregate(aggregate(Ag)) -->
       write_vhdl_aggregate(Ag).

Rule 41


write_vhdl_type_conversion(type_conversion(Type,Expr)) -->
       write_vhdl_mark(Type), "(", write_vhdl_expression(Expr), ")".

Rule 42


write_vhdl_allocator(A) --> " new ", write_vhdl_alloc_subterm(A).
write_vhdl_alloc_subterm(A) -->
       write_vhdl_subtype_indication(A).
write_vhdl_alloc_subterm(A) -->
       write_vhdl_qualified_expression(A).

B.9 Operators

Rule 43


write_vhdl_boolop_associative(and)  --> " and ".
write_vhdl_boolop_associative(or)   --> " or ".
write_vhdl_boolop_associative(xor)  --> " xor ".
write_vhdl_boolop_associative(xnor) --> " xnor ".

write_vhdl_boolop_non_associative(nand) --> " nand  ".
write_vhdl_boolop_non_associative(nor)  --> " nor  ".

write_vhdl_relational_operator('=')    --> " = ".
write_vhdl_relational_operator('/=')   --> " /= ".
write_vhdl_relational_operator('<')    --> " < ".
write_vhdl_relational_operator('>')    --> " > ".
write_vhdl_relational_operator('<=')   --> " <= ".
write_vhdl_relational_operator('>=')   --> " >= ".

write_vhdl_shift_operator(sll)   --> " sll ".
write_vhdl_shift_operator(srl)   --> " srl ".
write_vhdl_shift_operator(sla)   --> " sla ".
write_vhdl_shift_operator(sra)   --> " sra ".
write_vhdl_shift_operator(rol)   --> " rol ".
write_vhdl_shift_operator(ror)   --> " ror ".

write_vhdl_adding_operator('+')   --> " + ".
write_vhdl_adding_operator('-')   --> " - ".
write_vhdl_adding_operator('&')   --> " & ".

write_vhdl_sign('+')   --> " + ".
write_vhdl_sign('-')   --> " - ".

write_vhdl_multiplying_operator('*')   --> " * ".
write_vhdl_multiplying_operator('/')   --> " / ".
write_vhdl_multiplying_operator(mod)   --> " mod ".
write_vhdl_multiplying_operator(rem)   --> " rem ".

Rule 44


B.10 Element Association and Choices

Rule 45

We need an entirely new clause (the first one) to handle the case of an empty set of choices.


write_vhdl_element_association(element_association(null,Expr)) -->
       !,  write_vhdl_expression(Expr).

write_vhdl_element_association(element_association(C,Expr)) -->
       write_vhdl_choices(C), " => ", write_vhdl_expression(Expr).

Rule 46


write_vhdl_choices([C|Cs]) -->
        write_vhdl_choice(C), write_vhdl_more_choices(Cs).

write_vhdl_more_choices([]) --> [].
write_vhdl_more_choices([C|Cs]) -->
        " | ", write_vhdl_choice(C),
                  write_vhdl_more_choices(Cs).

Rule 47


write_vhdl_choice(others) --> !, " others ".
write_vhdl_choice(C)    --> write_vhdl_discrete_range(C).
write_vhdl_choice(C)    --> write_vhdl_expression(C).

B.11 Type Declarations

Rule 48


write_vhdl_type_declaration(vhdl_type(ID,null)) -->
         !, "type ", write_vhdl_identifier(ID).

write_vhdl_type_declaration(vhdl_type(ID,Definition)) -->
         "type ", write_vhdl_identifier(ID), " is ", 
          [indent], write_vhdl_type_definition_2(Definition), [undent], !.

write_vhdl_type_declaration(vhdl_type(ID,Definition)) -->
         "type ", write_vhdl_identifier(ID), " is ", 
          write_vhdl_type_definition_1(Definition).

Rule 49


write_vhdl_type_definition_1(Def) -->
         write_vhdl_enumeration_type_definition(Def).
write_vhdl_type_definition_1(Range) -->
         write_vhdl_range_constraint(Range).
write_vhdl_type_definition_1(Physical) -->
         write_vhdl_physical_type_definition(Physical).

write_vhdl_type_definition_2(Array) -->
         write_vhdl_unconstrained_array_definition(Array).
write_vhdl_type_definition_2(Array) -->
         write_vhdl_constrained_array_definition(Array).
write_vhdl_type_definition_2(RType) -->
         write_vhdl_record_type_definition(RType).
write_vhdl_type_definition_2(Access) -->
         write_vhdl_access_type_definition(Access).
write_vhdl_type_definition_2(FileType) -->
         write_vhdl_file_type_definition(FileType).

Rule 50


write_vhdl_enumeration_type_definition([E|Enums]) -->
        "(", write_vhdl_enumeration_literal(E),
        write_vhdl_enumeration_literal_list(Enums).

write_vhdl_enumeration_literal_list([])     --> !, ")".
write_vhdl_enumeration_literal_list([E|Es]) -->
        ",", write_vhdl_enumeration_literal(E),
        write_vhdl_enumeration_literal_list(Es).

Rule 51


write_vhdl_physical_type_definition(vhdl_type(Range,Base,Secondary)) -->
        write_vhdl_range_constraint(Range),
        "units ", 
          write_vhdl_base_unit_declaration(Base),
          write_vhdl_secondary_unit_declarations(Secondary),
        "end units".

write_vhdl_secondary_unit_declarations([]) --> [].
write_vhdl_secondary_unit_declarations([S|Ss]) -->
        write_vhdl_secondary_unit_declaration(S),
        write_vhdl_secondary_unit_declarations(Ss).

Rule 52


write_vhdl_base_unit_declaration(ID) -->
        write_vhdl_identifier(ID).

Rule 53


write_vhdl_secondary_unit_declaration(vhdl_sec(ID,PL)) -->
        write_vhdl_identifier(ID), "=",
        write_vhdl_physical_literal(PL).

Rule 54


write_vhdl_unconstrained_array_definition(vhdl_array([ISD|ISDs],SI)) -->
        " array (",
             write_vhdl_index_subtype_definition(ISD),
             write_vhdl_index_subtype_definitions(ISDs),
        " of ", write_vhdl_subtype_indication(SI).

write_vhdl_unconstrained_nature_definition(vhdl_nature_array([ISD|ISDs],SI)) -->
        " array (",
             write_vhdl_index_subtype_definition(ISD),
             write_vhdl_index_subtype_definitions(ISDs),
        " of ", write_vhdl_subnature_indication(SI).

write_vhdl_index_subtype_definitions([]) --> ")".
write_vhdl_index_subtype_definitions([I|Is]) -->
        ",", write_vhdl_index_subtype_definition(I),
        write_vhdl_index_subtype_definitions(Is).

Rule 55


write_vhdl_index_subtype_definition(TM) -->
        write_vhdl_mark(TM), " range <>".

Rule 56


write_vhdl_constrained_array_definition(vhdl_array(IC,SI)) -->
        " array ", write_vhdl_index_constraint(IC), 
        " of ", write_vhdl_subtype_indication(SI).

write_vhdl_constrained_nature_definition(vhdl_nature_array(IC,SI)) -->
        " array ", write_vhdl_index_constraint(IC), 
        " of ", write_vhdl_subnature_indication(SI).

Rule 57


write_vhdl_record_type_definition(record(EDs)) -->
       "record ",
        [indent],
          write_vhdl_element_declarations(EDs),
        [undent],
       "end record".

Rule 57.5


write_vhdl_record_nature_definition(record(EDs)) -->
       "record ",
        [indent],
          write_vhdl_nature_element_declarations(EDs),
        [undent],
       "end record".

Rule 58


write_vhdl_element_declaration(vhdl_element(Is,SI)) -->
       write_vhdl_identifier_list(Is), " : ",
       write_vhdl_subtype_indication(SI), ";", newline.

write_vhdl_element_declarations([])     --> [].
write_vhdl_element_declarations([E|Es]) -->
       write_vhdl_element_declaration(E),
       write_vhdl_element_declarations(Es).

Rule 58.5


write_vhdl_nature_element_declaration(vhdl_nature_element(Is,SI)) -->
       write_vhdl_identifier_list(Is), " : ",
       write_vhdl_subnature_indication(SI), ";".

write_vhdl_nature_element_declarations([])     --> [].
write_vhdl_nature_element_declarations([E|Es]) -->
       write_vhdl_nature_element_declaration(E),
       write_vhdl_nature_element_declarations(Es).

Rule 59


write_vhdl_access_type_definition(vhdl_access(TD)) -->
       "access ", write_vhdl_subtype_indication(TD).

Rule 60


write_vhdl_file_type_definition(vhdl_filetype(Type)) -->
       "file of ", write_vhdl_mark(Type).

B.12 Subtypes and Constraints

Rule 61


write_vhdl_subtype_declaration(vhdl_subtype(ID,TD)) -->
       "subtype ", write_vhdl_identifier(ID), " is ", 
       [indent], write_vhdl_subtype_indication(TD), [undent].

Rule 62


write_vhdl_subtype_indication(vhdl_subtype(FM,TM,C,TA))-->
       write_vhdl_opt_mark(FM), " ",
       write_vhdl_mark(TM),
       write_vhdl_opt_constraint(C),
       write_vhdl_opt_tolerance_aspect(TA).

Rule 63


write_vhdl_opt_constraint(null) --> !, [].
write_vhdl_opt_constraint(C)    --> write_vhdl_constraint(C).

write_vhdl_constraint(R) --> write_vhdl_range_constraint(R).
write_vhdl_constraint(I) --> write_vhdl_index_constraint(I).

Rule 64


write_vhdl_range_constraint(S) -->
       " range ", write_vhdl_range_specification(S).

Rule 65


write_vhdl_index_constraint(index([R|Rs])) -->
       "(", write_vhdl_discrete_range(R),
            write_vhdl_more_discrete_ranges(Rs).

write_vhdl_more_discrete_ranges([]) --> ")".
write_vhdl_more_discrete_ranges([R|Rs]) -->
        ",", write_vhdl_discrete_range(R),
             write_vhdl_more_discrete_ranges(Rs).

Rule 66


write_vhdl_discrete_range(R) -->
       write_vhdl_range_specification(R).
write_vhdl_discrete_range(R) -->
       write_vhdl_subtype_indication(R).

Rule 67


write_vhdl_range_specification(vhdl_range(vhdl_name(P,Exprs,range),SE)) -->
       !,  write_vhdl_indexed_name(vhdl_name(P,Exprs,[range])),
       write_vhdl_opt_static_expression(SE).
write_vhdl_range_specification(vhdl_range(E1,D,E2)) -->
       write_vhdl_expression(E1),
       write_vhdl_direction(D), !,
       write_vhdl_expression(E2).
write_vhdl_range_specification(vhdl_range(TM,Sign,SE)) -->
       write_vhdl_mark(TM), 
       write_vhdl_opt_signature(Sign),  "'range ", !,
       write_vhdl_opt_static_expression(SE).
write_vhdl_range_specification(vhdl_range(TM,Sign,SE)) -->
       write_vhdl_function_call(TM),
       write_vhdl_opt_signature(Sign),  "'range ", !,
       write_vhdl_opt_static_expression(SE).

Rule 68


write_vhdl_direction(to)     --> " to ".
write_vhdl_direction(downto) --> " downto ".

B.125 Natures, Subnatures, Terminals, and Quantities

This section deals with rules added to VHDL to obtain the VHDL-AMS extension.

Rule 68-1


write_vhdl_nature_declaration(vhdl_nature(Id,Def)) --> 
       " nature ", write_vhdl_identifier(Id), " is ",
       write_vhdl_nature_definition(Id,Def).

write_vhdl_nature_definition(_,scalar(Across,Through)) --> 
                write_vhdl_mark(Across), " across ",
                write_vhdl_mark(Through), " through ".
write_vhdl_nature_definition(_,Array) -->
                write_vhdl_unconstrained_nature_definition(Array).
write_vhdl_nature_definition(_,Array) -->
                write_vhdl_constrained_nature_definition(Array).
write_vhdl_nature_definition(ID,RType) -->
                write_vhdl_record_nature_definition(ID,RType).

write_vhdl_subnature_declaration(vhdl_subnature(Id,Ind)) --> 
       " subnature ", write_vhdl_identifier(Id), " is ",
       write_vhdl_subnature_indication(Ind).

write_vhdl_subnature_indication(vhdl_subnature_indication(Id,Cons,Tol)) --> 
       write_vhdl_mark(Id), 
       write_vhdl_opt_index_constraint(Cons), 
       write_vhdl_opt_tolerance_across_through(Tol).

write_vhdl_opt_index_constraint(null) --> !, [].

write_vhdl_opt_index_constraint(IC) --> 
       write_vhdl_index_constraint(IC).
 
write_vhdl_opt_tolerance_across_through(null) --> !, [].

write_vhdl_opt_tolerance_across_through(tolerance(A,T)) -->
       " tolerance ",  
       write_vhdl_expression(A), " across ",
       write_vhdl_expression(T), " through ".

Rule 68-3


write_vhdl_terminal_declaration(terminal(Ids,Sn)) -->
                " terminal ",
                write_vhdl_identifier_list(Ids), ":",
                write_vhdl_subnature_indication(Sn).

write_vhdl_quantity_declaration(DI) -->
                " quantity ",
                ( write_vhdl_free_quantity_declaration(DI) ;
                  write_vhdl_branch_quantity_declaration(DI) ;
                  write_vhdl_source_quantity_declaration(DI)
                ).

write_vhdl_free_quantity_declaration(free_quantity(IDs,Type,Expr)) -->
                write_vhdl_identifier_list(IDs), ":",
                write_vhdl_subtype_indication(Type),
                write_vhdl_opt_assignment(Expr).

write_vhdl_branch_quantity_declaration(branch_quantity(AA,THA,TEA)) -->
                write_vhdl_opt_across_aspect(AA),
                write_vhdl_opt_through_aspect(THA),
                write_vhdl_opt_terminal_aspect(TEA).

write_vhdl_source_quantity_declaration(source_quantity(IDs,Type,SA)) -->
                write_vhdl_identifier_list(IDs), ":",
                write_vhdl_subtype_indication(Type),
                write_vhdl_source_aspect(SA).

B.127 Through, Across, Source, Terminal, and Tolerance Aspects

This section deals with rules added to VHDL to obtain the VHDL-AMS extension.

Rule 68-5



write_vhdl_opt_across_aspect(null) --> !, [].

write_vhdl_opt_across_aspect(across_aspect(IDs, TA, Expr)) -->
	        write_vhdl_identifier_list(IDs), 
                write_vhdl_opt_tolerance_aspect(TA),
	        write_vhdl_opt_assignment(Expr),
                " across ".

write_vhdl_opt_through_aspect(null) --> !, [].

write_vhdl_opt_through_aspect(through_aspect(IDs, TA, Expr)) -->
	        write_vhdl_identifier_list(IDs), 
                write_vhdl_opt_tolerance_aspect(TA),
	        write_vhdl_opt_assignment(Expr),
                " through ".


write_vhdl_opt_source_aspect(null) --> !, [].

write_vhdl_opt_source_aspect(spectrum_aspect(Mag, Phase)) -->
	        !, " spectrum ", 
                write_vhdl_simple_expression(Mag), " , ",
	        write_vhdl_simple_expression(Phase).

write_vhdl_opt_source_aspect(noise_aspect(Mag)) -->
	        " noise ", 
	        write_vhdl_simple_expression(Mag).

write_vhdl_opt_terminal_aspect(null) --> !, [].
write_vhdl_opt_terminal_aspect(terminal_aspect(N1,N2)) -->
                write_vhdl_name(N1), 
                ({N2 = null} -> [] ;
                                " to ", write_vhdl_name(N2)).

write_vhdl_opt_tolerance_aspect(null) --> !, [].
write_vhdl_opt_tolerance_aspect(tolerance_aspect(Expr)) -->
                [tolerance],
                write_vhdl_expression(Expr).

B.13 Objects, Aliases, Files, Disconnections

Rule 69


write_vhdl_object_declaration(object_declaration(Class,IDs,Type,Kind,Expr)) -->
       write_vhdl_object_class(Class),
       write_vhdl_identifier_list(IDs), " : ",
       write_vhdl_subtype_indication(Type),
       write_vhdl_opt_signal_kind(Kind),
       write_vhdl_opt_assignment(Expr).

write_vhdl_opt_assignment(null) --> !, [].
write_vhdl_opt_assignment(vhdl_assign(Expr)) -->
       " := ", write_vhdl_expression(Expr).

Rule 70


write_vhdl_object_class(signal)           --> " signal ".
write_vhdl_object_class(constant)         --> " constant ".
write_vhdl_object_class(variable)         --> " variable ".
write_vhdl_object_class(shared_variable)  --> " shared variable ".
write_vhdl_object_class(file)             --> " file ".
write_vhdl_object_class(quantity)         --> " quantity ".
write_vhdl_object_class(terminal)         --> " terminal ".

write_vhdl_opt_object_class(null)  --> !, [].
write_vhdl_opt_object_class(Class) --> write_vhdl_object_class(Class).

Rule 71


write_vhdl_opt_signal_kind(bus)      --> " bus ".
write_vhdl_opt_signal_kind(register) --> " register ".
write_vhdl_opt_signal_kind(null)     --> [].

Rule 72


write_vhdl_alias_declaration(vhdl_alias(ID,null,Name,Sign)) -->
       !, "alias ", write_vhdl_alias_designator(ID), " is ",
       write_vhdl_name(Name), write_vhdl_opt_signature(Sign).

write_vhdl_alias_declaration(vhdl_alias(ID,Type,Name,Sign)) -->
       !, "alias ", write_vhdl_alias_designator(ID), ":", 
       write_vhdl_subtype_indication(Type), " is ",
       write_vhdl_name(Name), write_vhdl_opt_signature(Sign).

write_vhdl_alias_designator(char(L))  --> !, ['''',L,''''].       %**FIX
write_vhdl_alias_designator(ID)       --> write_vhdl_designator(ID).

Rule 73


write_vhdl_file_declaration(vhdl_file(IDs,SI,Mode,null)) -->
       !, "file ", write_vhdl_identifier_list(IDs), " : ", 
                   write_vhdl_subtype_indication(SI), newline,
                   write_vhdl_opt_file_open_kind(Mode).

write_vhdl_file_declaration(vhdl_file(IDs,SI,Mode,Se)) -->
       "file ", write_vhdl_identifier_list(IDs), " : ", 
                write_vhdl_subtype_indication(SI), newline,
              write_vhdl_opt_file_open_kind(Mode), " is ",
              write_vhdl_expression(Se), newline.

write_vhdl_opt_file_open_kind(null) --> !, [ ].
write_vhdl_opt_file_open_kind(Mode) -->
       " open ", write_vhdl_file_mode(Mode).

write_vhdl_file_mode(read_mode)   --> " read_mode ".
write_vhdl_file_mode(write_mode)  --> " write_mode ".
write_vhdl_file_mode(append_mode) --> " append_mode ".

Rule 74


write_vhdl_disconnection_specification(disconnect_spec(SL,Type,Time)) -->
       "disconnect ",
          write_vhdl_signal_list(SL), " : ", write_vhdl_mark(Type),
       " after ", write_vhdl_expression(Time), newline.

Rule 75


write_vhdl_signal_list(others) --> " others ".
write_vhdl_signal_list(all)    --> " all ".
write_vhdl_signal_list([S])    --> !, write_vhdl_name(S).
write_vhdl_signal_list([S|Ss]) -->
        write_vhdl_name(S), ",",
        write_vhdl_signal_list(Ss).

B.14 Signatures

Rule 75.5


write_vhdl_opt_mark_list([]) --> !, [].
write_vhdl_opt_mark_list([ID]) --> !, write_vhdl_mark(ID).
write_vhdl_opt_mark_list([ID|IDs]) -->
        write_vhdl_mark(ID), " , ",  
        write_vhdl_opt_mark_list(IDs).

write_vhdl_opt_signature(null) --> [].
write_vhdl_opt_signature(signature(Ids,null)) --> 
          !, " [ ", write_vhdl_opt_mark_list(Ids), " ] ".
write_vhdl_opt_signature(signature(Ids,Id)) --> 
             " [ ", write_vhdl_opt_mark_list(Ids),
                    " return ", write_vhdl_mark(Id),  " ] ".

B.15 Attribute Declarations and Specifications

Rule 76


write_vhdl_attribute_declaration(attribute_declaration(ID,Type)) -->
       "attribute ",
       write_vhdl_identifier(ID), " : ", write_vhdl_mark(Type).

Rule 77


write_vhdl_attribute_specification(attr_spec(ID,Entity,Expr)) -->
       "attribute ",  write_vhdl_identifier(ID), 
       " of ",  write_vhdl_entity_specification(Entity), " is ",
       write_vhdl_expression(Expr).

Rule 78


write_vhdl_entity_specification(entity_spec(Names,Class)) -->
       write_vhdl_entity_name_list(Names),
       " : ", write_vhdl_entity_class(Class).

Rule 79


write_vhdl_entity_name_list(others) --> " others".
write_vhdl_entity_name_list(all)    --> " all".
write_vhdl_entity_name_list([D])    --> !, write_vhdl_entity_designator(D).
write_vhdl_entity_name_list([D|Ds]) -->
       write_vhdl_entity_designator(D), ",", write_vhdl_entity_name_list(Ds).

write_vhdl_entity_designator(tag_sign(T,S)) -->    
        write_vhdl_entity_tag(T), write_vhdl_opt_signature(S).

write_vhdl_entity_tag(char(L))  -->    !, [ L ].
write_vhdl_entity_tag(T)        -->    write_vhdl_designator(T).

Rule 80


write_vhdl_entity_class(entity)       --> " entity ".
write_vhdl_entity_class(architecture) --> " architecture ".
write_vhdl_entity_class(package)      --> " package ".
write_vhdl_entity_class(configuration)--> " configuration ".
write_vhdl_entity_class(component)    --> " component ".
write_vhdl_entity_class(label)        --> " label ".
write_vhdl_entity_class(type)         --> " type ".
write_vhdl_entity_class(subtype)      --> " subtype ".
write_vhdl_entity_class(procedure)    --> " procedure ".
write_vhdl_entity_class(function)     --> " function ".
write_vhdl_entity_class(signal)       --> " signal ".
write_vhdl_entity_class(variable)     --> " variable ".
write_vhdl_entity_class(constant)     --> " constant ".
write_vhdl_entity_class(literal)      --> " literal ".
write_vhdl_entity_class(units)        --> " units ".
write_vhdl_entity_class(group)        --> " group ".
write_vhdl_entity_class(file)         --> " file ".
write_vhdl_entity_class(nature)       --> " nature ".
write_vhdl_entity_class(subnature)    --> " subnature ".
write_vhdl_entity_class(quantity)     --> " quantity ".
write_vhdl_entity_class(terminal)     --> " terminal ".

B.16 Schemes

Rule 81


write_vhdl_generation_scheme(S) --> write_vhdl_if_scheme(S).
write_vhdl_generation_scheme(S) --> write_vhdl_for_scheme(S).

Rule 82


write_vhdl_iteration_scheme(S) --> write_vhdl_for_scheme(S), !.
write_vhdl_iteration_scheme(S) --> write_vhdl_while_scheme(S).

write_vhdl_opt_iteration_scheme(null) --> !, [].
write_vhdl_opt_iteration_scheme(S)    --> write_vhdl_iteration_scheme(S).

Rule 83


write_vhdl_if_scheme(if(Expr)) -->
        " if ", write_vhdl_expression(Expr).

Rule 84


write_vhdl_for_scheme(for(ID,Range)) -->
        "for ", write_vhdl_identifier(ID),
        " in ", write_vhdl_discrete_range(Range).

Rule 85


write_vhdl_while_scheme(while(Expr)) -->
        " while ", write_vhdl_expression(Expr), newline.

B.17 Concurrent Statements

Rule 86


write_vhdl_concurrent_statements([]) --> [].
write_vhdl_concurrent_statements([S]) --> 
        !, write_vhdl_concurrent_statement(S), ";".
write_vhdl_concurrent_statements([S|Ss]) -->
        write_vhdl_concurrent_statement(S), ";", newline,
        write_vhdl_concurrent_statements(Ss).

Rule 87


write_vhdl_concurrent_statement(S) -->
          write_vhdl_block_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_concurrent_assertion_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_concurrent_procedure_call(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_component_instantiation_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_concurrent_signal_assignment_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_generate_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_process_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_process_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_concurrent_break_statement(S).
write_vhdl_concurrent_statement(S) -->
          write_vhdl_simultaneous_statement(S).
%          write_vhdl_simultaneous_statement_part(S).

Rule 88


write_vhdl_block_statement(block(ID,Expr,GIL,GAL,PIL,PAL,ODI,Ss)) -->
       write_vhdl_identifier(ID), " : ",
       "block ",
        [indent],
          write_vhdl_opt_paren_expression(Expr),
        " is ", 
          write_vhdl_opt_generic_semi(GIL),
          write_vhdl_opt_generic_map_semi(GAL),
          write_vhdl_opt_port_semi(PIL),
          write_vhdl_opt_port_map_semi(PAL),
          write_vhdl_opt_declarative_items(ODI),
       [undent],
       "begin ",
       [indent],
          write_vhdl_concurrent_statements(Ss),
       [undent],
       "end block ", write_vhdl_identifier(ID).

Rule 89


write_vhdl_component_instantiation_statement(comp_instant(ID,IU,AL1,AL2)) -->
        write_vhdl_identifier(ID), " : ",  
        write_vhdl_instantiated_unit(IU),
        write_vhdl_opt_generic_map_statement(AL1),
        write_vhdl_opt_port_map_statement(AL2).

Rule 89a


write_vhdl_instantiated_unit(comp(CM)) --> 
        " component ", write_vhdl_mark(CM).

write_vhdl_instantiated_unit(entity(EID,null)) --> 
        !, " entity ", write_vhdl_mark(EID).

write_vhdl_instantiated_unit(entity(EID,AID)) --> 
        " entity ", write_vhdl_mark(EID), 
        " (",  write_vhdl_identifier(AID), ") ".

write_vhdl_instantiated_unit(config(CID)) --> 
        " configuration ", write_vhdl_mark(CID).

Rule 90


write_vhdl_concurrent_assertion_statement(concurrent_assertion(ID,Post,Stmt)) -->
       write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
       write_vhdl_assertion_statement(Stmt).

write_vhdl_opt_postponed(postponed)   --> " postponed ".
write_vhdl_opt_postponed(null)        --> [ ].

Rule 91


write_vhdl_concurrent_procedure_call(cpc(ID,Post,S)) -->
       write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
       write_vhdl_procedure_call_statement(S).

Rule 92


write_vhdl_concurrent_signal_assignment_statement(csas(ID,Post,CSAS)) -->
        write_vhdl_opt_label(ID), vhdl_opt_postponed(Post),
        write_vhdl_conditional_signal_assignment(CSAS).
write_vhdl_concurrent_signal_assignment_statement(ssas(ID,Post,CSAS)) -->
        write_vhdl_opt_label(ID), write_vhdl_opt_postponed(Post),
        write_vhdl_selected_signal_assignment_statement(CSAS).
write_vhdl_concurrent_signal_assignment_statement(null) --> [ ].

Rule 93


write_vhdl_conditional_signal_assignment(csa(T,G,RT,Tr,W)) -->
       write_vhdl_target(T), " <= ",
       write_vhdl_opt_delay_mechanism(G,RT,Tr), 
       write_vhdl_conditional_waveforms(W).

Rule 94


write_vhdl_conditional_waveforms([wave(W,Cond)|Ws]) -->
        write_vhdl_waveform(W), 
        write_vhdl_opt_conditional_waveforms(Cond,Ws).

write_vhdl_opt_conditional_waveforms(null,[]) --> !, [].

write_vhdl_opt_conditional_waveforms(Expr,[]) -->
       !, " when ", write_vhdl_expression(Expr).

write_vhdl_opt_conditional_waveforms(Expr,Ws) -->
       " when ", write_vhdl_expression(Expr),
       " else ", write_vhdl_conditional_waveforms(Ws).

Rule 95


write_vhdl_waveform(unaffected) --> " unaffected ".

write_vhdl_waveform([WE|WEs]) -->
       write_vhdl_waveform_element(WE), write_vhdl_opt_waveforms(WEs).

write_vhdl_opt_waveforms([]) --> [].
write_vhdl_opt_waveforms([WE|WEs]) --> 
       ",", write_vhdl_waveform_element(WE),
            write_vhdl_opt_waveforms(WEs).

Rule 96


write_vhdl_waveform_element(event(null,Time)) --> !,
       " null ", write_vhdl_opt_delay(Time).
write_vhdl_waveform_element(event(Expr,Time)) -->
       write_vhdl_expression(Expr), write_vhdl_opt_delay(Time).

write_vhdl_opt_delay(null) --> !, [].
write_vhdl_opt_delay(Time) -->
        " after ", write_vhdl_expression(Time).

Rule 97


write_vhdl_target(N) --> write_vhdl_name(N).
write_vhdl_target(A) --> write_vhdl_aggregate(A).

Rule 98


write_vhdl_opt_delay_mechanism(null,null,null)      --> !, [].
write_vhdl_opt_delay_mechanism(null,null,transport) --> !, " transport ".
write_vhdl_opt_delay_mechanism(null,null,inertial)  --> !, " inertial ".
write_vhdl_opt_delay_mechanism(null,RT,inertial)    --> 
                 !, " reject ", write_vhdl_expression(RT), " inertial ".
write_vhdl_opt_delay_mechanism(guarded,RT,TM)   --> 
                 !, " guarded ", write_vhdl_opt_delay_mechanism(null,RT,TM).

Rule 99


write_vhdl_selected_signal_assignment_statement(selected(Expr,Target,G,RT,T,Ws)) -->
        "with ", write_vhdl_expression(Expr), " select ",
    [indent],
        write_vhdl_target(Target),
        " <= ", write_vhdl_opt_delay_mechanism(G,RT,T),
      [indent],
        write_vhdl_selected_waveforms(Ws), 
    [dent, undent].

Rule 100


write_vhdl_selected_waveform(vhdl_waveform(W,Cs)) -->
        write_vhdl_waveform(W), " when ", write_vhdl_choices(Cs).

write_vhdl_selected_waveforms([SW|SWs]) -->
        write_vhdl_selected_waveform(SW),
        write_vhdl_additional_selected_waveforms(SWs).

write_vhdl_additional_selected_waveforms([]) --> !, [].
write_vhdl_additional_selected_waveforms(SWs) -->
         ",", newline, write_vhdl_selected_waveforms(SWs).

Rule 101


write_vhdl_generate_statement(generate(ID,Scheme,null,Ss)) -->
      !, write_vhdl_identifier(ID),  " : ",
           write_vhdl_generation_scheme(Scheme), " generate ",
    [indent],
           write_vhdl_concurrent_statements(Ss),
%           write_vhdl_architecture_statements(Ss),
    [undent],
        "end generate ", write_vhdl_identifier(ID).

write_vhdl_generate_statement(generate(ID,Scheme,DI,Ss)) -->
        write_vhdl_identifier(ID),  " : ",
           write_vhdl_generation_scheme(Scheme), " generate ",
    [indent],
            newline, write_vhdl_opt_declarative_items(DI), newline, 
        "begin ", 
           write_vhdl_concurrent_statements(Ss),
    [undent],
        "end generate ", write_vhdl_identifier(ID).

Rule 102


write_vhdl_process_statement(vhdl_process(LID,ID,Post,SL,DI,Ss)) -->
        write_vhdl_opt_label(LID),    write_vhdl_opt_postponed(Post),
        "process ", write_vhdl_opt_sensitivity_list(SL), " is ",
    [indent],
        write_vhdl_opt_declarative_items(DI),
        "begin ",
      [indent],
          write_vhdl_sequential_statements(Ss),
    [dent, undent],
        "end process ", write_vhdl_opt_label_use(ID).  

write_vhdl_opt_label(null) --> !, [].
write_vhdl_opt_label(ID)   --> write_vhdl_identifier(ID), " : ".

write_vhdl_opt_label_use(null) --> !, [].
write_vhdl_opt_label_use(ID)   --> write_vhdl_identifier(ID).

write_vhdl_opt_sensitivity_list([]) --> [].
write_vhdl_opt_sensitivity_list(SL) --> 
        "(", write_vhdl_sensitivity_list(SL), ")".

Rule 103


write_vhdl_sensitivity_list([S]) --> !, write_vhdl_name(S).
write_vhdl_sensitivity_list([S|Ss]) -->
        write_vhdl_name(S), ",", write_vhdl_sensitivity_list(Ss).

Rule 103.5


write_vhdl_concurrent_break_statement(vhdl_concurrent_break(ID,BL,SC,WC)) -->
         write_vhdl_opt_label(ID), 
         " break ", write_vhdl_opt_break_list(BL),
         write_vhdl_opt_sensitivity_clause(SC),
         write_vhdl_opt_when_condition(WC).

write_vhdl_opt_sensitivity_clause(null) --> !, " ".
write_vhdl_opt_sensitivity_clause(vhdl_sensitivity_clause(SL)) -->
         " on ", write_vhdl_sensitivity_list(SL).

B.18 Sequential Statements

Rule 104


write_vhdl_sequential_statements([]) --> [].
write_vhdl_sequential_statements([S]) --> 
        !, write_vhdl_sequential_statement(S), ";", newline.
write_vhdl_sequential_statements([S|Ss]) --> 
        write_vhdl_sequential_statement(S), ";", newline,
        write_vhdl_sequential_statements(Ss).

Rule 105


write_vhdl_sequential_statement(S) --> write_vhdl_assertion_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_report_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_case_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_exit_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_if_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_loop_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_next_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_null_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_procedure_call_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_return_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_signal_assignment_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_variable_assignment_statement(S).
write_vhdl_sequential_statement(S) --> write_vhdl_wait_statement(S).

Rule 106


write_vhdl_assertion_statement(assert(LID,Assertion,String,Severity)) -->
       write_vhdl_opt_label(LID),
       "assert ",  write_vhdl_expression(Assertion),   " ",
       write_vhdl_opt_report(String),
       write_vhdl_opt_severity(Severity).

write_vhdl_opt_report(null)   --> !, [].
write_vhdl_opt_report(R)      --> "report ",  write_vhdl_expression(R).

write_vhdl_opt_severity(null) --> !, [].
write_vhdl_opt_severity(S)    --> " severity ", write_vhdl_expression(S).

Rule 106a


write_vhdl_report_statement(report(LID,String,Severity)) -->
             write_vhdl_opt_label(LID), 
              "report ", !,
                    write_vhdl_expression(String),
                    write_vhdl_opt_severity(Severity).

Rule 107


write_vhdl_case_statement(case(LID,ID,Cond,Cases)) -->
        write_vhdl_opt_label(LID),
       "case ", write_vhdl_expression(Cond), " is ",
   [indent],
       write_vhdl_case_statement_alternatives(Cases),
   [undent],
       "end case ", write_vhdl_opt_label_use(ID).

Rule 108


write_vhdl_case_statement_alternatives([]) --> [].

write_vhdl_case_statement_alternatives([vhdl_case(Choices,Ss)|Cases]) -->
       " when ",  write_vhdl_choices(Choices), " => ", 
     [indent],
       write_vhdl_sequential_statements(Ss),
     [undent], 
       write_vhdl_case_statement_alternatives(Cases).

Rule 109


write_vhdl_exit_statement(vhdl_exit(LID,ID,null)) -->
     !, write_vhdl_opt_label(LID),
       "exit ", write_vhdl_opt_label_use(ID).

write_vhdl_exit_statement(vhdl_exit(LID,ID,Expr)) -->
        write_vhdl_opt_label(LID),
       "exit ", write_vhdl_opt_label_use(ID), 
       "when ", write_vhdl_expression(Expr).

Rule 110


write_vhdl_if_statement(vhdl_if(LID,ID,Cond,Thens,Elses)) -->
        write_vhdl_opt_label(LID),
       "if ", write_vhdl_expression(Cond), " then ",
    [indent],
                write_vhdl_sequential_statements(Thens),
    [undent],
         write_vhdl_else(Elses),
        "end if ", write_vhdl_opt_label_use(ID).

write_vhdl_else([]) --> !, [].

write_vhdl_else(elsif(ECond,Thens,Else)) --> !,
            "elsif ",
    [indent],
               write_vhdl_expression(ECond),
    [undent],
             "then ",
    [indent],
               write_vhdl_sequential_statements(Thens),
    [undent],
             write_vhdl_else(Else).

write_vhdl_else(Elses) -->
            "else ", 
    [indent],
             write_vhdl_sequential_statements(Elses),
    [undent].

Rule 111


write_vhdl_loop_statement(vhdl_loop(LID,ID,IScheme,Ss)) -->
        write_vhdl_opt_label(LID),
        write_vhdl_opt_iteration_scheme(IScheme),
        " loop ",
        [indent],
          write_vhdl_sequential_statements(Ss),
        [undent],
        "end loop ", write_vhdl_opt_label_use(ID).

Rule 112


write_vhdl_next_statement(vhdl_next(LID,ID,null)) -->
       !, write_vhdl_opt_label(LID),
       "next ", write_vhdl_opt_label_use(ID).
write_vhdl_next_statement(vhdl_next(LID,ID,Expr)) -->
       write_vhdl_opt_label(LID),
       "next ", write_vhdl_opt_label_use(ID),
       " when ", write_vhdl_expression(Expr).

Rule 113


write_vhdl_null_statement(null(LID)) --> 
       write_vhdl_opt_label(LID), "null ".

Rule 114


write_vhdl_procedure_call_statement(vhdl_call(LID,ID,Args)) -->
       write_vhdl_opt_label(LID),
       write_vhdl_name(ID), write_vhdl_opt_association_list(Args).

Rule 115


write_vhdl_return_statement(return(LID,Expr)) -->
       write_vhdl_opt_label(LID),
       "return ", write_vhdl_expression(Expr).

Rule 116


write_vhdl_signal_assignment_statement(signal(LID,T,RT,Mode,W)) -->
       write_vhdl_opt_label(LID),
       write_vhdl_target(T), " <= ",
       write_vhdl_opt_delay_mechanism(null,RT,Mode), 
       write_vhdl_waveform(W).

Rule 117


write_vhdl_variable_assignment_statement(assign(LID,Var,Expr)) -->
       write_vhdl_opt_label(LID),
       write_vhdl_target(Var), " := ", write_vhdl_expression(Expr).

Rule 118


write_vhdl_wait_statement(vhdl_wait(LID,SL,Expr,Time)) -->
       write_vhdl_opt_label(LID),
       "wait ",  write_vhdl_opt_on(SL),
       write_vhdl_opt_until(Expr),
       write_vhdl_opt_for_time(Time).

write_vhdl_opt_on(null)    --> !, [].
write_vhdl_opt_on(SL)      --> " on ", write_vhdl_sensitivity_list(SL).

write_vhdl_opt_until(null) --> !, [].
write_vhdl_opt_until(Expr) -->
       " until ", write_vhdl_expression(Expr).

write_vhdl_opt_for_time(0) --> !, [].
write_vhdl_opt_for_time(Time) -->
       " for ", write_vhdl_expression(Time).

Rule 118.1

These clauses are VHDL-AMS additions.

write_vhdl_break_statement(vhdl_break(LID,BL,Expr)) --> 
        write_vhdl_opt_label(LID), " break ",
        write_vhdl_opt_break_list(BL),
        write_vhdl_opt_when_condition(Expr).

write_vhdl_opt_when_condition(null) --> !, [].
write_vhdl_opt_when_condition(Expr) --> 
        " when ", write_vhdl_expression(Expr).

write_vhdl_opt_break_list([]) --> !, " ".
write_vhdl_opt_break_list([ BE ]) --> !, 
        write_vhdl_break_element(BE).
write_vhdl_opt_break_list([ BE | BL ]) -->
        write_vhdl_break_element(BE), 
        " , " ,  write_vhdl_opt_break_list(BL).

write_vhdl_break_element(vhdl_break_element(SC,N,Expr)) -->
        write_vhdl_opt_break_selector_clause(SC),
        write_vhdl_name(N), " => ", write_vhdl_expression(Expr).

write_vhdl_opt_break_selector_clause(null) --> !, " ".
write_vhdl_opt_break_selector_clause(vhdl_break_selector(N)) -->
        " for ", write_vhdl_name(N), " use ".

B.185 Simultaneous Statements

This section describes VHDL-AMS additions.

Rule 118.2


write_vhdl_simultaneous_statement_part(simultaneous([DI | DL])) --> 
                    write_vhdl_simultaneous_statement(DI),
                    ";", newline, !,
                    write_vhdl_simultaneous_statement_part(DL).
write_vhdl_simultaneous_statement_part([]) --> [].

write_vhdl_simultaneous_statement(SS) --> 
            write_vhdl_simple_simultaneous_statement(SS) 
         ;  write_vhdl_simultaneous_if_statement(SS) 
         ;  write_vhdl_simultaneous_case_statement(SS) 
         ;  write_vhdl_simultaneous_procedural_statement(SS) 
         ;  write_vhdl_simultaneous_null_statement(SS).

Rule 118.3



write_vhdl_simple_simultaneous_statement(vhdl_simple_simultaneous(LID,M,E1,E2,TA))  -->
            write_vhdl_opt_label(LID), 
            ( { M == pure} -> " pure "
                           ; ( { M == impure } -> " impure " ;
                                                 " " ) ), 
            write_vhdl_simple_expression(E1), " == ", 
            write_vhdl_simple_expression(E2), 
            write_vhdl_opt_tolerance_aspect(TA).

Rule 118.4


write_vhdl_simultaneous_case_statement(simultaneous_case(LID,ID,Cond,Cases)) -->
       write_vhdl_opt_label(LID),
       " case ",  write_vhdl_expression(Cond), " use ", !,
          [indent],
                 write_vhdl_simultaneous_alternatives(Cases),
          [undent],
       " end case ", write_vhdl_opt_label_use(ID).

write_vhdl_simultaneous_alternatives([]) --> !, [].

write_vhdl_simultaneous_alternatives([vhdl_case(Choices,Ss)|Cases]) -->
       " when ",  write_vhdl_choices(Choices), " use ", 
          [indent],
           write_vhdl_simultaneous_statement_part(Ss),
          [undent],
         write_vhdl_simultaneous_alternatives(Cases).

Rule 118.5


write_vhdl_simultaneous_if_statement(simultaneous_if(LID,ID,Cond,Thens,Elses)) -->
        write_vhdl_opt_label(LID),
        " if ", write_vhdl_expression(Cond), " use ", 
        [indent],
        write_vhdl_simultaneous_statement_part(Thens),
        [undent], 
        write_vhdl_simultaneous_else(ID,Elses).

write_vhdl_simultaneous_else(ID,elsif(ECond,Thens,Else)) -->
              " elsif ",  write_vhdl_expression(ECond), " use ",
               [indent], 
               write_vhdl_simultaneous_statement_part(Thens),
               [undent], 
               write_vhdl_simultaneous_else(ID,Else).

write_vhdl_simultaneous_else(ID,[]) --> 
               !, write_vhdl_simultaneous_end(ID).

write_vhdl_simultaneous_else(ID,Elses) -->
            " else ",  
               [indent], 
                   write_vhdl_simultaneous_statement_part(Elses),
               [undent],
               write_vhdl_simultaneous_end(ID).

write_vhdl_simultaneous_end(ID) --> " end  use ", write_vhdl_opt_label_use(ID).

Rule 118.6


write_vhdl_simultaneous_procedural_statement(simultaneous_procedural(LID,ID,M,D,S))  -->
            write_vhdl_opt_label(LID),  
            (   {M = pure}   -> " pure "   ; 
                ( {M = impure} -> " impure " ; " ") 
            ), " procedural  is ",
              [indent],
               write_vhdl_procedural_declarative_part(D), 
              [indent],
            " begin ", 
               write_vhdl_procedural_statement_part(S), 
              [dent, undent], 
            " end procedural ", write_vhdl_opt_label_use(ID).

Rule 118.7


write_vhdl_simultaneous_null_statement(LID)       -->
              write_vhdl_opt_label(LID), " null ".

B.19 Components and Configurations

Rule 119


write_vhdl_component_declaration(vhdl_comp(ID,GIL,PIL)) -->
       "component ", write_vhdl_identifier(ID), " is ", 
         write_vhdl_opt_generic_statement(GIL),
         write_vhdl_opt_port_statement(PIL),
       "end component ", write_vhdl_identifier(ID).

Rule 120


write_vhdl_block_configuration(vhdl_conf(Spec,Use,CI)) -->
       "for ", write_vhdl_block_specification(Spec), newline,
          write_vhdl_opt_use_clauses(Use),
          [indent],
          write_vhdl_opt_configuration_items(CI),
          [undent],
       "end for;",
        newline.

Rule 121


write_vhdl_block_specification(vhdl_name(ID,Index)) --> !,
       write_vhdl_mark(ID),
       "(", write_vhdl_index_specification(Index), ")".
write_vhdl_block_specification(vhdl_name(ID,null)) -->
       write_vhdl_mark(ID).

Rule 122


write_vhdl_index_specification(Range) -->
       write_vhdl_discrete_range(Range).
write_vhdl_index_specification(Expr) -->
       write_vhdl_expression(Expr).

Rule 123


write_vhdl_opt_configuration_items([]) -->  [ ].
write_vhdl_opt_configuration_items([CI|CIs]) -->
                write_vhdl_configuration_item(CI),
                write_vhdl_opt_configuration_items(CIs).

write_vhdl_configuration_item(BC) -->
       write_vhdl_block_configuration(BC).
write_vhdl_configuration_item(CC) -->
       write_vhdl_component_configuration(CC).

Rule 124


write_vhdl_component_configuration(vhdl_spec(CSpec,BI,null)) -->
     !,"for ", write_vhdl_component_specification(CSpec),
        [indent],
              write_vhdl_opt_binding_indication(BI),
        [undent],
       "end for;",
        newline.

write_vhdl_component_configuration(vhdl_spec(CSpec,BI,Ss)) -->
       "for ", write_vhdl_component_specification(CSpec),
        [indent],
              write_vhdl_opt_binding_indication(BI),
        [indent],
              write_vhdl_block_configuration(Ss),
        [undent],
        [undent],
       "end for;",
        newline.

Rule 125


write_vhdl_configuration_specification(vhdl_spec(CSpec,BI)) -->
       "for ", write_vhdl_component_specification(CSpec), " ",
        [indent],
        write_vhdl_opt_binding_indication(BI), 
        [undent].                                % newline.

Rule 126


write_vhdl_component_specification(spec(Spec,ID)) -->
       write_vhdl_instantiation_list(Spec), " : ", write_vhdl_mark(ID).

Rule 127


write_vhdl_instantiation_list(all)    --> !, " all ".
write_vhdl_instantiation_list(others) --> !, " others".
write_vhdl_instantiation_list(IL)     --> write_vhdl_identifier_list(IL).

Rule 128


write_vhdl_opt_binding_indication(binding(EA,GAL,PAL)) -->
       write_vhdl_opt_entity_aspect(EA),
       write_vhdl_opt_generic_map_statement(GAL),
       write_vhdl_opt_port_map_statement(PAL).

write_vhdl_opt_generic_map_statement(null) --> !,[].
write_vhdl_opt_generic_map_statement(IL) -->
    [indent],
        " generic map ",
        write_vhdl_association_list(IL),
    [undent].

write_vhdl_opt_port_map_statement(null) --> !, [].
write_vhdl_opt_port_map_statement(IL) -->
   [indent],
        " port map ",
        write_vhdl_association_list(IL),
   [undent].

write_vhdl_opt_generic_map_semi(null) --> !,[].
write_vhdl_opt_generic_map_semi(IL) -->
    [indent],
        " generic map ",
        write_vhdl_association_list(IL), ";",
    [undent].

write_vhdl_opt_port_map_semi(null) --> !, [].
write_vhdl_opt_port_map_semi(IL) -->
   [indent],
        " port map ",
        write_vhdl_association_list(IL), ";",
   [undent].

write_vhdl_opt_generic_semi(null) --> !,[].
write_vhdl_opt_generic_semi(IL) -->
    [indent],
        " generic ",
        write_vhdl_interface_list(one_per_line,IL), ";",
    [undent].

write_vhdl_opt_port_semi(null) --> !, [].
write_vhdl_opt_port_semi(IL) -->
   [indent],
        " port ",
        write_vhdl_interface_list(one_per_line,IL), ";",
   [undent].

Rule 129


write_vhdl_opt_entity_aspect(null) --> !, [ ].

write_vhdl_opt_entity_aspect(EA) -->
       " use ", write_vhdl_entity_aspect(EA).

write_vhdl_entity_aspect(open) --> " open ".

write_vhdl_entity_aspect(entity_aspect(CM,null)) --> !,
       " configuration ", write_vhdl_mark(CM).

write_vhdl_entity_aspect(entity_aspect(Mark,ID)) -->
        " entity ",
        write_vhdl_mark(Mark),
        "(", write_vhdl_identifier(ID), ")".