• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

FHDLgui/H03-May-2022-998827

cdfggen/H03-May-2022-897759

doc/H03-May-2022-17,55614,975

examples/H03-May-2022-4,6774,114

fire/H03-May-2022-5,5744,674

freehdl/H03-May-2022-18,43112,710

ieee/H03-May-2022-26,85622,918

kernel/H03-May-2022-8,3435,780

std/H03-May-2022-4,4213,187

v2cc/H03-May-2022-31,52922,771

vaul/H03-May-2022-40,72432,339

AUTHORSH A D22-Mar-2007497 1210

COPYINGH A D03-Feb-200017.6 KiB340281

ChangeLogH A D15-Apr-20081.6 KiB6337

HACKINGH A D05-Dec-20051.9 KiB5038

INSTALLH A D03-Feb-20007.3 KiB177137

Makefile.amH A D15-Feb-2008433 178

Makefile.inH A D03-May-202219.9 KiB645567

NEWSH A D27-Apr-20091.9 KiB7256

READMEH A D15-Dec-20012.3 KiB5744

README.AIREH A D03-Feb-200015.4 KiB435294

README.gen-nodesH A D03-Feb-20005.8 KiB169111

README.librariesH A D19-Sep-20008 KiB237169

README.v2ccH A D14-Aug-200510.9 KiB315227

README.vaulH A D03-Feb-20005.7 KiB147111

aclocal.m4H A D25-Sep-2008268.6 KiB7,6346,823

config.guessH A D07-Jul-200843.8 KiB1,5271,315

config.subH A D07-Jul-200832.6 KiB1,6591,514

configureH A D27-Apr-2009783.8 KiB25,33120,513

configure.acH A D25-Sep-20082.2 KiB10186

depcompH A D27-Apr-200914.8 KiB527335

freehdl.pc.inH A D25-Sep-2008318 1916

install-shH A D27-Apr-20099.3 KiB326189

ltmain.shH A D29-Apr-2008195.3 KiB6,9655,506

missingH A D27-Apr-200910.4 KiB361270

v2cc.libsH A D19-Dec-200063 65

README

1This is a early test release of the FreeHDL package.  As such, nothing
2is final yet and everything is bound to be changed.  Please tell us
3everything that you don't like about this package so that we can
4improve it.  You are also allowed to tell us about the things that you
5do like, of course, so that we don't make them worse.
6
7Installation
8------------
9
10This package should behave like a regular GNUish package.  Generic
11installation instructions for such a package can be found in the file
12INSTALL.
13
14Right now, there is only enough documentation to get you to run the
15included example. Further, some additional info about the
16compiler/simulator (e.g. a list of supported VHDL constructs) can be
17found in README.v2cc.
18
19Pick a suitable place to install this package in.  The default is
20/usr/local.  Then run
21
22    % ./configure --prefix <install-prefix>
23    % make
24    % make install
25
26The last step will create some directories below <install-prefix> and
27will put the created programs and some data files there. However, if
28you prefer *not* to install the package (currently the simulator is
29very limited, hence you will not be able to use it for "real" work!)
30check out README.v2cc for some additional info on how to execute the
31compiler/simulator. Further, if your computer should run out of memory
32during compilation run "make CXXFLAGS=-g" instead of just "make".
33
34You must make sure that the installed files can be found by your
35system (otherwise you will only be able to compile an execute models
36copied to the v2cc subdirectory).  That is, the directory
37<install-prefix>/bin should be on your path and your linker should be
38able to find libraries in <install-prefix>/lib.  We are not yet ready
39to isolate you from these technicalities.
40
41Running the example
42-------------------
43
44See file "README.v2cc" for some information on how to compile/run
45the example vhdl models.
46
47
48Where to send bug reports / suggestions / comments
49--------------------------------------------------
50
51If your report addresses a parser related topics then contact Marius
52Vollmer <mvo@zagadka.ping.de>. If it is related to the code generator
53or compiler then send an email to Edwin Naroska
54<edwin@ds.e-technik.uni-dortmund.de>. If your are not sure send it to
55Edwin. He will take care of forwarding your report to the appropriate
56recipient.
57

README.AIRE

1[ If you are working on FIRE, please update this document accordingly.
2  The `I' in the text is mvo@zagadka.ping.de (Marius Vollmer). ]
3
4
5Differences between FIRE and AIRE
6*********************************
7
8The node type definition in fire-chunk.t are an attempt to get as
9close to AIRE as reasonable, but there are both large and small
10differences that are mostly motivated by my laziness.  But many are
11also due to my unhappines with certain AIRE features.
12
13Being fully AIRE compliant is a worthy goal.  But right now, I think
14it does not pay off to put much energy into this as there are more
15useful goals.
16
17Below is a (incomplete) account of the differences between FIRE and
18AIRE, with biased comments.
19
20
21Framework
22---------
23
24With the term `framework', I'm referring to the general constructs
25with which FIRE and AIRE try to support their general goals.  This
26includes things like the operations that are supported for every node
27type, memory management, the precise way how new types are defined,
28extensibility, modularity and more.
29
30The framework of FIRE is more advanced than the one of AIRE and I see
31no point in going with AIRE in this regard.  There has been much
32discussion about this topic on the FreeHDL list, and improvements for
33the framework were the original motivation to start with FIRE.  The
34advantages of FIRE include:
35
36  - Painless high level definitions
37  - Definitions are trivially and confidently machine-readable
38  - Run-time type information via the "is-a" predicate.
39  - Flexible run-time extensibility
40  - Extensibility includes new node types, new visitor functions and
41    new node attributes without recompiling.
42  - Semi-automatic memory management with a simple garbage collector
43  - Inspection facilities that can be used to implement persistence
44
45Please see the libfire sources for ultimate technical details.
46
47
48General Node Stuff
49------------------
50
51The nodes of a abstract syntax `tree' form a graph.  It is useful to
52find a definition what a node can be.  It pays to find a simple but
53general definition because it makes graph algorithms easier to specify
54and implement.  For example, memory management and persitent stores
55are much easier to implement when the nodes have been kept
56conceptually simple.
57
58FIRE views the syntax graph as a passive, mostly un-mutable data
59structure.  It consists of nodes that contain typed pointers to other
60nodes, and additional payload.  This simplistic definition is mapped
61to a similarily simplistic C++ implementation.  Each node type is
62mapped to a C++ struct with the pointers and the payload implemented
63as public data members.
64
65In addition to the type id, there is also a predicate that can test
66whether a given node is derived from a given type.
67
68AIRE uses C++ syntax to describe the node type definitions.  It does
69not seem to have restrictions on what features of C++ one might use in
70such a node type definition.  The AIRE spec randomly uses both public
71data members and accessor functions.
72
73It is possible to add the accessor functions to FIRE to achieve AIRE
74source compatability.  But the underlying simple view of a node as a
75passive data structure should remain.  In fact, using *only* accessor
76functions would be an improvement for FIRE, but they should not
77destroy the fundamental `passiveness' of the graphs, and there should
78not be a random mixture between data members and accessor functions.
79
80AIRE often uses the effectively untyped IIR node type.  This makes the
81specification less precise and less transparent.  FIRE tries to avoid
82the use of IIR and prefers more specialized types instead.  For
83example, a IIR_SignalAssignmentStatement in AIRE denotes the target by
84an IIR, while FIRE uses IIR_Expression.
85
86FIRE generally tries to put the burden on the frontend.  It chooses a
87representation that is convenient for the clients of the frontend.
88For example, it requires that all names have been resolved.
89
90
91Basic Data Types
92----------------
93
94FIRE mostly uses the types defined in AIRE.
95
96IR_Kind: this is not an enumeration member, but a pointer to an opaque
97information structure.  This should be of no consequence, but IR_Kind
98is no longer an integral type that can be used to index arrays, say.
99
100IR_Direction: new type to denote the direction of ranges.
101
102IR_String: new type to hold a constant string and do memory management
103for it.
104
105
106IIR Base Class
107--------------
108
109The get_kind and get_kind_text functions of AIRE are named kind and
110kind_name in FIRE, for no good reasons.
111
112No source location methods are implemented.  Instead, a IIR node
113points to a IIR_PosInfo node.  Predefined IIR_PosInfo types include
114IIR_PosInfo_TextFile and IIR_PosInfo_Sheet.  It is possible to
115trivially implement new kinds of position information.
116
117IIR_Statement is not implemented.
118
119
120IIR_DesignFile & IIR_Comment Derived Classes
121--------------------------------------------
122
123Unimplemented.  Comments are ignored completely and DesignFiles are
124not mapped into the graph.  The largest unit for a graph is a design
125unit.  Design files are handled by the frontend.
126
127
128IIR_Literal Derived Classes
129---------------------------
130
131IIR_TextLiteral has an IR_String attribute called `text' that holds
132the characters of the literal.  IIR_Identifier, IIR_CharacterLiteral,
133and IIR_StringLiteral are derived from TextLiteral without adding any
134new features.  There is no `get' method.
135
136There is no IIR_BitStringLiteral because the lexer converts bit string
137literals immediately into IIR_StringLiterals.  It would be better to
138retain bit string literals unchanged to produce better error messages.
139
140IIR_IntegerLiteral just uses a IR_String for the value, without any
141support routines.  When we want to have arbitrary integers, we should
142be using a bignum package (like GNU mp) and remove
143IIR_IntegerLiteral32, IIR_IntegerLiteral64 completely.  The same
144applies to IIR_FloatingPointLiteral and derived types.
145
146There are additional types IIR_AbstractLiteral,
147IIR_AbstractIntegerLiteral, and IIR_AbstractFloatingPointLiteral to
148further structure the hierachy.
149
150
151IIR_Tuple Derived Classes
152-------------------------
153
154IIR_AssociationElement: Moved actual from AEByExpression to here.
155Added formal_conversion and actual_conversion.  When actual is
156IIR_OpenExpression, then it's an AEOpen, else it's an AEByExpression.
157The types AEByExpression and AEOpen are there and correctly used, too.
158
159IIR_BreakElement: unused/unimplemented.
160
161IIR_CaseStatementAlternative: Moved ChoiceList from CSAByChoices to
162base class.  CSAByExpression, CSAByChoices, CSAByOthers are not used.
163It's all in the ChoiceList.  This could be done AIRE style.
164
165IIR_Choice: added CByExpression, CByRange, CByOthers.  Choice is an
166abstract class.  This could be done AIRE style.
167
168IIR_ConditionalWaveform: unused/unimplemented.  A conditional signal
169assignemnt is expanded into its equivalent process.
170
171IIR_ConfigurationItem: derived from IIR_DeclarativeRegion for historic
172reasons.  Needs to be cleaned up.
173
174IIR_ComponentConfiguration: has no `name' element.
175
176IIR_Designator*: unused/unimplemented.
177
178IIR_Elsif: unused/unimplemented.
179
180IIR_SelectedWaveform: unused/unimplemented.  A selected signal
181assignemnt is expanded into its equivalent process.
182
183IIR_Simultanous*: unused/unimplemented.
184
185IIR_ElementAssociation, IIR_IndexedAssociation: new, used for
186aggregates.
187
188IIR_AttributeValue: new, used for user defined attributes.
189
190
191Lists
192-----
193
194Lists are currently a cheap cop out.  They don't implement any of the
195baroque ADT stuff from AIRE, but are simply singly linked lists with a
196first and rest pointer.  I think the AIRE interface could be provided
197but is not very useful.
198
199Not all lists have been implemented, only those that are actually
200used.  Some new lists are also there.
201
202IIR_GenericList, IIR_PortList: not used because they are not derived
203from IIR_InterfaceList and I want to have `generic' functions that can
204work both on a GenericList and a PortList.  This is no big loss.
205
206
207IIR_TypeDefinition and IIR_NatureDefinition Derived Classes
208-----------------------------------------------------------
209
210Here are many significant deviations from AIRE.  I had especially
211little respect when I did this part of FIRE and it shows.
212
213All IIR_TypeDefinitions have lost their "Definition" suffix.  Thus,
214IIR_TypeDefinition is now IIR_Type.  This is easy to revert of course.
215
216Types have a pointer to their declaration.
217
218Scalar types have no range (it is contained in their primary
219subtype(?)).
220
221Subtypes are arranged differently.  Subtypes form their own hierachy:
222
223 IIR_Type:                Type base
224   IIR_Subtype:           Type immediate_base, FunctionDeclaration res_func
225      IIR_ScalarSubtype:  Range range
226      IIR_ArraySubtype:   TypeList constraint
227
228This avoids gratitous duplication of code for the original multitude
229of similar Subtypes that weren't related hierachically.
230
231The range of a ScalarSubtype is denoted by the IIR_Range hierachy.
232This allows not only for explicit ranges but also for ranges denoted
233by attributes.
234
235There is no IIR_RangeTypeDefinition.
236
237Record and Array types are derived from the new IIR_CompositeType.
238
239ArrayTypes are not restricted to one dimension.  This is important.
240We can either support it directly in the spec or everybody is forced
241to non-portably kluge around it.  See SAVANT.
242
243IIR_Signature: unused/unimplemented.
244
245IIR_NatureDefinition: unused/unimplemented.
246
247
248IIR_Declaration Derived Classes
249-------------------------------
250
251In addition to the declarations, we also maintain the nested
252declarative regions in the graph, so that backends can walk them in a
253generic way.
254
255IIR_Declaration: moved attributes to here and use AttributeValue
256instead of AttributeSpecification.  Has pointer to containing
257IIR_DeclarativeRegion.
258
259IIR_DeclarativeRegion: new.  Chains declarative regions of one scope
260together with a `continued' pointer.  Has list of contained
261IIR_Declarations.  This means that declarations that have their own
262IIR_DeclarationList in AIRE are now derived from IIR_DeclarativeRegion
263and inherit the list.  Makes much more sense.
264
265IIR_LoopDeclarativeRegion: new.
266
267IIR_FunctionDeclaration: pure is just a boolean.
268
269IIR_EnumerationLiteral: has no position info.
270
271IIR_NatureElementDeclaration: unused/unimplemented.
272
273IIR_SubtypeDeclaration: derived from TypeDeclaration.
274
275IIR_NatureDeclaration: unused/unimplemented.
276
277IIR_SubnatureDeclaration: unused/unimplemented.
278
279IIR_ObjectDeclaration: added initial_value.
280
281IIR_ConstantDeclaration, IIR_VariableDeclaration,
282IIR_SharedVariableDeclaration, IIR_SignalDeclaration: no value, use
283initial_value of ObjectDelcaration.  The graph is not intented to be
284used at simulation-time.
285
286IIR_TerminalDeclaration, IIR_QuantityDeclaration: unused/unimplemented.
287
288IIR_InterfaceDeclaration: derived from IIR_ObjectDeclaration.  Added
289`boolean buffer'.  No value, see IIR_ConstantDeclaration, et al.
290
291IIR_TerminalInterfaceDeclaration, IIR_QuantityInterfaceDeclaration:
292unused/unimplemented.
293
294IIR_AliasDeclaration: derived from IIR_ObjectDeclaration.  No name,
295initial_value refers to aliased object (via ObjectReference,
296presumably).
297
298IIR_ComponentDeclaration: derived from IIR_DeclarativeRegion.  This
299probably can be fixed but it doesn't hurt either.
300
301IIR_Group*: unused/unimplemented.  Needs fixing.
302
303IIR_LibraryUnit: added library_name to help identify units.
304
305IIR_EntityDeclaration: has no `architectures' pointer.  The full list
306of architectures can not be determined when parsing the entity
307declaration and the graph should not be mutated later.  Finding all
308architectures of an entity is a useful thing but I do not consider it
309to be the job of the frontend. More often than not, the architectures
310aren't needed anyway.
311
312IIR_PackageDeclaration: like architectures of entities, I consider it
313to be out of the scope of the frontend to find the package body for a
314package.
315
316IIR_PackageBodyDeclaration: rather, a package body points back to its
317package declaration.
318
319IIR_PhysicalUnit: added pointer to defining PhysicalType.
320
321IIR_AttributeSpecification: unused/unimplemented.  Use AttributeValue
322instead, much simpler.
323
324IIR_ConfigurationSpecification: has no component_name, entity_aspect,
325and instantiation_list but simply a `LibraryUnit unit'.
326
327IIR_DisconnectSpecification: used for only one signal, which is
328denoted by `IIR_Expression guarded_signal'.
329
330IIR_LibraryClause: has no logical_name.
331
332IIR_UseClause: has no selected_name, but a direct pointer to the used
333unit.
334
335
336IIR_Name derived Classes
337------------------------
338
339No Name class is used/implemented.  All references are resolved.
340Attributes are implemented as Expressions.
341
342
343IIR_Expression Derived Classes
344------------------------------
345
346No MonadicOperator or DyadicOperator is implemented.  They are
347expressed by function calls that point to the declaration of the
348operator.
349
350We need a number of new node types to refer to objects and literals.
351AIRE seems to allow literals and objects directly in expressions, but
352FIRE doesn't.  This and most of the other changes are done to make the
353life of the backend easier.  By using these additional `indirect'
354classes, we can be more precise and explicit.
355
356IIR_AbstractLiteralExpression: new, used to refer to IIR_AbstractLiterals.
357
358IIR_PhysicalLiteral: derived from AbstractLiteralExpression.
359
360IIR_ArrayLiteralExpression: new, used to refer to IIR_StringLiterals.
361
362IIR_EnumLiteralReference: new, used to refer to
363IIR_EnumerationLiterals.
364
365IIR_NullExpression, IIR_OpenExpression: new, useful.
366
367IIR_Aggregate: split into RecordAggregate and ArrayAggregate with
368their own specialized Element/IndexedAssociations.
369
370IIR_OthersInitialization: unused/unimplemented.
371
372IIR_FunctionCall: `implementation' is called `function', for no good
373reason.
374
375IIR_ObjectReference: new, used to refer to objects.  The hierarchy is
376
377    ObjectReference
378      SimpleReference:        ObjectDeclaration object
379      AccessReference:        Expression access
380      RecordReference:        Expression record, ElementDeclaration element
381      GenericArrayReference:  Expression array
382        ArrayReference:       ExpressionList indices
383        SliceReference:       Range range
384
385Builtin attributes are also derived from Expression.  They are mostly
386copied verbatim from the old VAUL definitions.  There is no similarity
387to the unimplemented AIRE Attribute classes.  The similarity could be
388achieved, but they should remain Expressions.
389
390
391IIR_SequentialStatement Derived Classes
392---------------------------------------
393
394IIR_SequentialStatement: moved label from unimplemented IIR_Statement
395to here.
396
397IIR_ProcedureCallStatement: has no procedure_name, points directly to
398ProcedureDeclaration.
399
400IIR_IfStatement: does not use ElsIf.  Instead, if/elsif chains are
401rewritten into equivalent nested ifs.
402
403IIR_LoopStatement: new, used as common base of ForLoopStatement and
404WhileLoopStatement.  Does not have declaration list, but points to
405LoopDeclarativeRegion.
406
407IIR_LoopControlStatement: new, used as common base of NextStatement,
408ExitStatement.
409
410
411IIR_ConcurrentStatement Derived Classes
412---------------------------------------
413
414IIR_ConcurrentStatement: derived from DeclarativeRegion, for
415historical reasons.  Needs to be fixed, maybe.
416
417IIR_ProcessStatement: added `boolean guarded'.
418
419IIR_ConcurrentProcedureCallStatement, ConcurrentAssertionStatement,
420ConcurrentConditionalSignalAssignment,
421ConcurrentSelectedSignalAssignment: unused/unimplemented.  They are
422rewritten into their equivalent ProcessStatement.
423
424IIR_ComponentInstantiationStatement: added pointer to
425ConfigurationSpecification that configures this thing.
426
427IIR_ConcurrentGenerateStatement: new, used as common base class of
428ConcurrentGenerateForStatement and ConcurrentGenerateIfStatement.
429
430
431IIR_SimultanousStatement Derived Classes
432----------------------------------------
433
434unused/unimplemented.
435

README.gen-nodes

1[This is the README from an early prototype of the gen-nodes tool.  It
2 is quite out of date with regard to the details, but the general
3 ideas still apply.]
4
5This is a demonstration of my ideas about an extensible framework for
6representing an abstract syntax tree (actually a graph).
7
8The goal is to be able to specify a hierachy of node types and define
9`generic' functions on them.  A generic function can have different
10implementations for different types.  These implementations are called
11the methods of a generic function.  The decision which method to
12invoke when a generic functions is called is made at run-time.
13
14We want to be able to define new generic functions without changing
15the definition of the types that they work on.  Therefore, we can not
16use the virtual functions of C++.  A virtual function is part of the
17type it works on and it is therefore necessary to change the type
18itself when adding new virtual functions.  This means frequent and
19inconvenient recompilation.
20
21Furthermore, such changes to the type definitions have to be carefully
22coordinated when more than one party wants to make some.
23
24
25My proposed solution to this dilemma is to design a new, minimal OOP
26model and implement it in C++.  To make it useable, we need a tool
27that generates most of the boilerplate code for us.
28
29The demonstration uses Scheme (a Lisp dialect) for implementing the
30boilerplate generating tool and Scheme syntax for specifying the input
31to it.  I know that this is not the most popular thing to do, but it
32was easiest for me.  Therefore...
33
34*   You need to have Guile installed to play with the tool.  Version  *
35*   1.2 should work fine.  You can find it on your local GNU mirror.  *
36
37
38- How it works
39
40The node features are defined in `chunks'.  Each chunk can contain new
41node type definitions and generic functions with their methods.  You
42can also extend node types with new attributes.
43
44The chunks are independent from one-another.  That is, you can mix and
45match chunks at link time without having to recompile them.
46
47The cornerstone of the system is `gen-nodes'.  This is the tool that
48reads the description of a number of chunks and outputs C++ code for
49their implementation.
50
51- The chunk descriptions.
52
53The files that gen-nodes reads contain the description of the chunks
54in Scheme syntax.
55
56A chunk is started with this statement:
57
58    (chunk NAME OPTS..)
59
60it ends at the end of input or when the next chunk begins.  NAME
61should be a valid C++ identifier and unique among all chunks.
62
63You can define new node types:
64
65    (defnode NAME (BASE)
66       SLOTS...
67       OPTS...)
68
69The NAME is the name of the node type and should be a valid and unique
70C++ identifier.  BASE is the name of a previously defined node type
71that will be used as the base for the new type.  You can omit BASE
72(but not the parentheses around it).
73
74LINKS-AND-ATTRS can specify links to other nodes
75
76    (link NODE LINK-NAME)
77
78where NODE is the type of the node that is pointed to by the link
79named LINK-NAME.  The generated C++ struct will have a member that is
80a pointer to a struct generated for NODE.
81
82You can also specify attributes
83
84    (attr TYPE ATTR-NAME)
85
86where TYPE is string enclosed in double quotes that is a valid C++
87type, such as "char*" or "int".  The generated C++ struct will have a
88member with name ATTR-NAME and type TYPE.
89
90
91Generic functions are specified with
92
93    (defgeneric RET-TYPE GENERIC-NAME EXTRA-ARGS)
94
95This will generate a C++ function named GENERIC-NAME with return type
96RET-TYPE (which should be a string just like a attribute type).  The
97first argument of this function is a pointer to a node struct.  The
98run-time type of this node is used to dispatch to one of the methods
99of this generic function, see below.  The rest of the arguments of the
100function are specified by EXTRA-ARGS.  This should be a list like
101
102    ((TYPE ARG-NAME) (TYPE ARG-NAME) ...)
103
104When the generic function should not be global but be contained in a
105class, you specify the qualified name of it (i.e. including the class
106name) as a list of symbols.  The qualified name
107"outer_class::inner_class::func" would be written as
108
109    (outer_class inner_class func)
110
111Methods are defined with
112
113    (defmethods GENERIC-NAME NODES...)
114
115For each of the node types listed in NODES, an individual method is
116defined.  Methods are translated into ordinary C++ functions whose
117name is formed by concatenating the string "m_" and the GENERIC-NAME.
118Their first parameter is a pointer to the node type they belong to and
119the rest is specified by the EXTRA-ARGS of the generic declaration.
120
121When a generic function is invoked on a node type that has no method
122defined for it, the method for the nearest base type that has a method
123is invoked.  When no such base type exists, the program is aborted.
124
125
126You can extend existing nodes with
127
128    (extnode NODE
129       ATTRS...)
130
131NODE is the name of the node that you want to extend and ATTRS is a
132list of attribute definitions, just like for defnode.  For every
133specified attribute a function will be generated according to this
134template:
135
136    TYPE& NAME (NODE*);
137
138TYPE is the type of the attribute, NAME is the name of the attribute
139and NODE is the struct generated for the extended node.  The function
140will return a reference to the storage reserved for the attribute.
141
142
143You can add arbitary lines to the generated output with
144
145    (header-add LINES...)
146
147and
148
149    (impl-add LINES)
150
151You can split the chunk definitions into several files and use
152
153    (include FILE)
154
155to include them.
156
157
158- Invoking gen-nodes
159
160    gen-nodes CMD CHUNK IN-FILE OUT-FILE
161
162Gen-nodes reads the IN-FILE (which should contain the descriptions in
163the format explained above) and generates output for CHUNK in
164OUT-FILE, according to CMD.
165
166When CMD is `header', gen-nodes writes a header file to OUT-FILE that
167should be included by the users of the CHUNK.  When it is `impl', it
168writes the implementation of CHUNK.
169

README.libraries

1Design libraries and v2cc
2-------------------------
3
4v2cc does not have a opaque notion of design libraries.  VHDL files
5are not pre-analyzed and checked into some library data base.
6Instead, whenever a reference to a design unit needs to be made, v2cc
7parses the VHDL code of that design unit from fresh.  Therefore, it
8needs to be able to find the source file of a design unit given the
9VHDL name of that unit.
10
11Thus, as far as v2cc is concerned, a design library is a mapping from
12VHDL identifiers to file names.  There is also a mapping for getting
13library names from mapping files.
14
15Such a mapping is specified via a "mapping file".  It contains a list
16of pattern rules that each transform a certain class of identifiers
17into file names.
18
19The syntax of a mapping file is:
20
21  Lexical:
22
23     litchar: 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '/' | '-' | '.' escchar
24
25     escchar: '\' char
26
27     whitespace: ' ' | '\n' | '\v' | '\t' | comment
28
29     comment: '#' any_character* '\n'
30
31     opchar: ':' | ',' | '(' | ')'
32
33     specchar: every printable char except litchar, whitespace and opchar
34
35     symchar: litchar | specchar
36
37     symbol: symchar+
38
39  Grammar:
40
41     mapping: version patternrule*
42
43     version: "v2cc_mapfile" "0"
44
45     patternrule: symbol [ ':' symbol ]
46
47Comments are ignored.
48
49A mapping files specifies a sequence of pattern rules.  When
50transforming an indentifier, each rule is tried in turn and the first
51one that matches is choosen.
52
53A rule looks like
54
55  pattern: filename
56
57When the ": filename" part is omitted, it defaults to "patternEXT"
58where "EXT" is determined by the user of the mapping file.
59
60The "pattern" can contain the special character "<" which introduces a
61`wildcard'.  The "<" must be followed by a ">", with arbitrary
62characters inbetween.  These characters form the name of the wildcard.
63A wildcard matches any sequence of characters.  There can be any
64number of wildcards in the pattern, but each must have a unique name.
65
66The "filename" can also contain the character "<", followed by a name,
67followed by ">".  There, it introduces a `wildcard substitution'.  It
68will be replaced with the characters that matched the wildcard with
69the same name in "pattern".  When there is no wildcard in "pattern"
70with the right name, it will be replaced with nothing.  While doing
71this replacement, the characters "#" and "/" are replaced as "##", and
72"#-" respectively.  No other character translations are done, so if
73you have funny characters in your VHDL identifiers, you will have
74funny characters in your filenames.
75
76Before doing the comparison with the patterns, the VHDL identifier is
77brought into a canononical form: when it is not an abstract
78identifier, all its characters are down-cased.
79
80When the resulting filename is relative (does not begin with "/"), it
81is prefixed with the directory of the mapping file.
82
83A non-existent mapping file is equivalent to the single rule
84
85  <>
86
87An empty mapping file is just that: an empty mapping.
88
89The mapping does not need to be reversible.  It is OK when multiple
90identifiers map to a single filename.
91
92No special character besides "<" and ">" is valid in "pattern" or
93"filename".  They are reserved for future extensions.
94
95
96The mapping files for going from design unit names to filenames are
97found by looking into directories specified by the `v2cc library
98path'.  You can use the environment variable V2CC_LIBRARY_PATH and
99command line options to define the path.  When the environment
100variable is not set, it defaults to a value that makes the standard
101libraries available that are distributed and installed with v2cc
102itself.  When it is set, it completely overwrites this default value.
103
104The variable V2CC_LIBRARY_PATH consists of ":" separated filenames.
105The filename "*" is replaced with the default value mentioned above.
106
107In addition to the environment variable, you can use the "-L libdir"
108command line option with v2cc.  The directories specified with "-L"
109are added in front of the ones specified by V2CC_LIBRARY_PATH.  In the
110final library path, they appear in the same order as on the command
111line.
112
113Looking for a design unit named UNIT in a library named LIB is done
114like this:
115
116     for each component of the library path, L
117       if L is a regular file
118         set LMAP to L
119       else if L is a directory
120         set LMAP to L/v2cc.libs
121       else
122         continue with next component
123       translate LIB into FLIB using LMAP with EXT=""
124       if FLIB.vhdl exists
125         terminate with FLIB.vhdl as the result
126       if FLIB.v2cc exists
127         set UMAP to FLIB.v2cc
128       else if FLIB is a directory
129         set UMAP to FLIB/v2cc.units
130       else
131         continue with next component
132       translate UNIT into FUNIT using UMAP with EXT=".vhdl"
133       terminate with FUNIT as the result
134     terminate unsuccessfully
135
136
137This mechanism is used for all design units that are referenced from
138within VHDL code (or via other means).  There is a complication with
139architectures and package bodies, though, because they are not
140uniquely identified by a single identifier.  For them, a artifical
141identifier is constructed.  Architectures get names of the form
142
143    <entity>(<architecture>)
144
145while package bodies become
146
147    <package>(body)
148
149For example, "architecture struct of model" is turned into
150"model(struct)" and "package body misc" is turned into "misc(body)".
151
152When a design file contains multiple design units, they are all
153parsed, checked for correctnes and remembered, but only the needed
154unit will be used for code generation.  That is, when a design file
155contains both a package header and a package body and the package
156header is referenced from another design unit, no code will be
157generated for the package body.  When one of the ignored units will be
158referenced later in the same invocation of v2cc, the design file will
159not be read again because all design units are retained in core.
160
161
162Examples
163--------
164
165The simplest situation is when you have no mapping files at all.  A
166design library is then a directory on your library path.  The name of
167that directory is that of the library in VHDL.  Each file in that
168directory with a ".vhdl" extension is used for a design unit with the
169same name as the file without the extension.
170
171Say you have this directory structure
172
173    somedir/
174      std/
175        standard.vhdl
176        textio.vhdl
177      ieee/
178        numeric_bit.vhdl
179        std_logic_1164.vhdl
180
181When you put "somedir" into your library path, you have access to the
182design units
183
184       STD.STANDARD
185       STD.TEXTIO
186       IEEE.NUMERIC_BIT
187       IEEE.STD_LOGIC_1164
188
189In this situation, you have one file per design unit.  When you have
190one file per design library, it would look like this
191
192    somedir/
193      fmf.vhdl
194
195All references to design units in the FMF design library would be
196routed to "fmf.vhdl".
197
198
199
200
201Considerations
202--------------
203
204- Simplicity
205
206  The mapping is intended to be simple.  If you find yourself doing
207  complicated things or wanting complicated extensions, we should
208  probably rethink the mapping file completely.  Maybe it is better to
209  be able to specify an external program that gets called to do the
210  mapping.
211
212- Extensibility
213
214  Simple things within the pattern rules can be done by defining a
215  meaning for other special characters.
216
217  Broader changes to the grammar of the file should be marked with a
218  different version number, or maybe even a different format name.
219
220- Efficiency
221
222  It might be that the repeated parsing of VHDL source code will be an
223  unduly overhead.  This might not really be the case (Edwin says the
224  C++ compiler takes much longer anyway), but if it turns out to be a
225  problem, the solution would be to cache the results of previous
226  parsing runs on disk.  This should be done transparent to the user
227  (although the user should of course be able to detect and correct
228  problems with the caching like full disks or denied write permission
229  to the caching directoy).
230
231- Automatic generation
232
233  Mapping files are meant to be written by hand.  If you are thinking
234  about some automatic mechanism by which to generate them, it is
235  probably better to extend the capabilities of the mapping files so
236  that your new mechanism can be selected.
237

README.v2cc

10. Table of content
2-------------------
3
4This document is organized as follows:
5
6	1. Running the compiler
7	1.1 Compiling ieee.std_logic_1164 and ieee.numeric_std
8	1.2 Compiler options
9	2. Supported VHDL subset
10	3. Supported simulation commands
11	3.1 Controlling simulation from the command line
12	4. Bug reports
13
14
151. Running the compiler
16-----------------------
17
18Change to subdirectory "v2cc". Here you will find a simple perl script
19"gvhdl" which performs all necessary steps in order to create a
20simulation binary from a VHDL source file. The command
21
22    %./gvhdl y.vhdl
23
24compiles "y.vhdl" into a executable "y". Type
25
26    %./y
27
28to start the simulator. For more info on how to control the simulator
29see section 3.
30
31Note that all VHDL source files must end with ".vhdl".
32
33If you would like to build a simulator for a model consisting of
34several modules (entity + architecture or package + package body) you
35may put all the modules into a single file and compile it as
36described above. The top level module should be placed at the end of
37the file.
38
39Another option is to create a separate file for each module. The files
40should be named after the entity/package it stores. Then, each module
41must be compiled separately:
42
43    %./gvhdl -c <module_1>.vhdl
44    %./gvhdl -c <module_2>.vhdl
45    ...
46    %./gvhdl -c <module_1>.vhdl
47
48Finally, the top level module is compiled and linked via:
49
50    %./gvhdl <top_module>.vhdl <module_1>.o ... <module_n>.o
51
52
531.1 Compiling ieee.std_logic_1164 and ieee.numeric_std
54------------------------------------------------------
55
56If package ieee.std_logic_1164 or ieee.numeric_std are used within a
57design then the corresponding object files must be added when
58compiling the top level design. I.e., when compiling the top level
59module of your design add "../ieee/numeric_std.o
60../ieee/std_logic_1164.o" (order is important!) to the list of modules
61to link (or just "../ieee/std_logic_1164.o" if you do not use
62numeric_std):
63
64    %./gvhdl <top_module>.vhdl <module_1>.o ... <module_n>.o \
65	../ieee/numeric_std.o ../ieee/std_logic_1164.o
66
67Make sure to list numeric_std.o before std_logic_1164.o. Otherwise,
68the link stage may fail!
69
70As an alternative method you may use the "--libieee" option to add
71all ieee libraries (that currently come with the compiler).
72
73Directory "v2cc" contains two example models "top.vhdl" and
74"model4.vhdl" which make use of std_logic_1164 and numeric_std. To
75compile "top.vhdl" execute:
76
77    %./gvhdl -c adder.vhdl
78    %./gvhdl top.vhdl adder.o ../ieee/std_logic_1164.o
79
80or
81
82    %./gvhdl -c adder.vhdl
83    %./gvhdl top.vhdl adder.o --libieee
84
85
86To compile "model4.vhdl" run
87
88    %./gvhdl model4.vhdl ../ieee/std_logic_1164.o ../ieee/numeric_std.o
89
90or simply
91
92    %./gvhdl model4.vhdl --libieee
93
94
951.2 Compiler options
96--------------------
97
98gvhdl now accepts the following options:
99
100    -g : adds debugging info (i.e., the simulator can be debugged
101        using VHDL source file line numbers). This also enables
102        outputting some stack trace info in case of an runtime error.
103    -G : same as -g but no VHDL source file and line number info
104        is added to the executable (this is to support debugging
105	code generated by the compiler).
106    -c : compile only, do not link
107    -l <lib_name> : compile design into library <lib_name>.
108    -L <vhdl_lib> : path to VHDL library root directory. Within this
109	directory the compiler search for a file named v2cc.libs.
110	v2cc.libs translates library unit names to directories.
111	Note that more than one vhdl_lib may be provided
112	(see also section "VHDL libraray mapping").
113    --libieee : add ieee libraries (std:logic_1164, numeric_std, ...)
114	to executable.
115
116All other options not directly recognized by gvhdl are forwarded to
117g++.  Hence, in order to optimize the generated code for speed add
118"-O3" to the list of gvhdl options! E.g.,
119
120    %../v2cc/gvhdl -O3 -c -l ieee std_logic_1164.vhdl
121    %../v2cc/gvhdl -O3 -c -l ieee numeric_std.vhdl
122
123executed within subdir "ieee" will create speed optimized versions of
124std_logic_1164 and numeric_std. However, note that the code of these
125packages is generated form the the ORIGINAL ieee VHDL source. Currently,
126there are no special hand optimized versions of it (this is one of the
127tasks to be done in the future).
128
129
1301.3 VHDL library mapping
131--------------------------------
132
133In order to support mapping from VHDL unit names to directiores, a set
134of v2cc.libs files may be used. The directory where a v2cc.libs file
135is stored is passed over to the compiler using the "-L <vhdl_lib>"
136compiler switch. Note that several vhdl_lib directores may be
137specified.
138
139The content of a v2cc.libs file looks like
140
141v2cc_mapfile 0
142work : vhdl
143dummy : /home/edwin/work/test/dummy
144
145The first line ist just used to check for a vaild vhdl mapping
146file. The next two lines associate
147
148- VHDL libraray "work" with subdirectory "vhdl" and
149- VHDL libraray "dummy" with subdirectory /home/edwin/work/test/dummy.
150
151If the subdir path does not start with "/" then it is relative to the
152directory the corresponding v2cc.libs resides in. Here, VHDL library
153"work" is mapped to "<vhdl_lib>/vhdl". If a model or package named
154"comp" is referenced then the compiler will look into the directores
155of all VHDL libraries that are currently visible and searches for a
156file named "comp.vhdl".
157
158For more details about the v2cc.libs format please read with
159README.libraries.
160
161
1621.3.1 Example VHDL library setup
163--------------------------------
164
165As an example assume that all VHDL libraries are mapped into subdirs
166starting from root directory "/foo". Further, assume that there are
167VHDL libraries named "lib1" and "lib2". They shall be mapped to subdir
168"/foo/lib1_dir" and "/foo/lib2_dir". Hence, the file/directory
169structure is as follows:
170
171/foo  			<-  library root directory
172/foo/v2cc.libs  	<-  mapping control file
173/foo/lib1_dir		<-  library dir for VHDL library lib1
174/foo/lib1_dir/comp1.vhdl <- file that contains VHDL model comp1
175/foo/lib2_dir		<-  library dir for VHDL library lib2
176/foo/lib2_dir/comp2.vhdl <- file that contains VHDL model comp2
177
178Then, file "/foo/v2cc.libs" should contain:
179
180v2cc_mapfile 0
181lib1 : lib1_dir
182lib2 : lib2_dir
183
184In order to compile a design named comp1 (stored in file comp1.vhdl)
185into VHDL library lib1 goto subdir "/foo/lib1_dir" and execute:
186
187    %gvhdl -c -L .. -l lib1 comp1.vhdl
188
189Note that option "-l lib1" forces the compiler to associate the model
190stored in "comp1.vhdl" with VHDL libraray lib1.  Note further, that
191the compiler switch "-L .." specifies the path to the directory where
192"v2cc.libs" is stored. You may also specify an absolute path:
193
194    %gvhdl -c -L /foo -l lib1 comp1.vhdl
195
196Note that comp1 should reside in a file named "comp1.vhdl".
197
198If lib2 contains a design comp2 that makes use of comp1 from lib1 then
199goto "/foo/lib2_dir" and run the following command to create an
200executable for model comp2:
201
202    %gvhdl -L .. -l lib2 comp2.vhdl ../lib1_dir/comp1.o
203
204
2052. Supported VHDL subset
206------------------------
207
208Currently, FreeHDL does not support the entire VHDL'93 standard. The
209following incomplete list gives an overview on what is currently (not)
210supported (note that the compiler is not tested very intensively;
211hence, expect to hit a lot of bugs in the compiler and simulator
212system):
213
214- Individual association of formals of composite type are currently
215not supported.
216
217- VHDL'93 as well as VHDL'87 file support has been added.
218
219- Shared variables are currently not supported.
220
221- Attributes transaction, quiet, stable and delayed are
222currently not supported.
223
224- User defined attributes are currently not supported.
225
226- Groups are currently not supported.
227
228- Guarded signal assignments are currently not supported.
229
230- Currently drivers cannot be switched off.
231
232
233
2343. Supported simulation commands
235--------------------------------
236
237After the simulator has been started a short summary of the available
238commands are printed to the screen:
239
240  c <number> : execute cycles = execute <number> simulation cycles
241  n          : next = execute next simulation cycle
242  q          : quit = quit simulation
243  r <time>   : run = execute simulation for <time>
244  d          : dump = dump signals
245  doff       : dump off = stop dumping signals
246  don        : dump on = continue dumping signals
247  s          : show = show signal values
248  dv         : dump var  = dump a signal from the signal lists
249  ds         : dump show  = shows the list of dumped signals
250  nds        : number  show  = shows the number  of dumped signals
251  dc [-f <filename>] [-t <timescale> <time unit>] [-cfg <translation file>] [-q]
252                : configures dump process
253
254Note that signals are dumped into a file (default file name is
255"wave.dmp") in VCD format. This file format should be accepted by each
256VCD waveform viewer. The file name is set to "wave.dmp" but may be
257changed using "dc -f <new_file_name>". However, make sure to execute
258"dc -f ..." before executing "d".
259
260Here is a small protocol of a simulation run (user input is marked
261with "<--"):
262
263   %./y
264Available commands:
265  c <number> : execute cycles = execute <number> simulation cycles
266  n          : next = execute next simulation cycle
267  q          : quit = quit simulation
268  r <time>   : run = execute simulation for <time>
269  d          : dump = dump signals
270  doff       : dump off = stop dumping signals
271  don        : dump on = continue dumping signals
272  s          : show = show signal values
273  dv         : dump var  = dump a signal from the signal lists
274  ds         : dump show  = shows the list of dumped signals
275  nds        : number  show  = shows the number  of dumped signals
276  dc [-f <filename>] [-t <timescale> <time unit>] [-cfg <translation file>] [-q]
277                : configures dump process
278Simulation time = 0 fs + 0d
279> dc -q                              <-- suppress warnings/verbose messages
280> d                                  <-- dump all signals into wave.dmp
281> run 100 ns                         <-- run for 100 ns
282Run simulation for which time span?
283Simulating model to time 100 ns
284Simulation time = 100 ns + 0d
285
286106 processes were executed.
287138 transaction were created.
288> quit                               <-- quit simulation
289
290
2913.1 Controlling simulation from the command line
292------------------------------------------------
293
294Simulation can be controlled via the command line parameter '-cmd
295"cmd1; cmd2; ..."' where 'cmd1', 'cmd2', ... are simulation commands
296as described in the previous section. Note that each command must be
297separated by ';'. E.g., executing
298
299   %./y -cmd "d;run 1000 ns;q;"
300
301will start simulation program 'y', dump all signals and run simulation
302for 1000 ns. Finally, simulation is terminated. Actually, the last
303command 'q;' is optional as the simulator automatically terminates as
304soon as the last command has been executed.
305
306
3074. Bug reports
308--------------
309
310Please send simulator or code generator related bug reports or
311comments to Edwin Naroska <edwin@ds.e-technik.uni-dortmund.de>. If you
312are not sure to what your problem is related to send your email to
313Edwin as well. He will take care of forwarding your report or comment
314to the appropriate recipient.
315

README.vaul

1This is the source for VAUL.
2
3VAUL is cryptic for Vhdl Analyzer and Utility Library.  Devlopment has
4been initiated in 1994 by the University of Dortmund, Department for
5Electrical Engineering, AG SIV, Heja BVB.  Marius Vollmer
6<mvo@zagadka.ping.de> has written most of it, with guidance from
7Ludwig Schwoerer <ls@nt.e-technik.uni.dortmund.de>.  Part of this work
8is based upon work done by Thomas Dettmer and others.  See the file
9AUTHORS for details.  Many thanks to all who have contributed,
10especially to Professor Schr�der, who has allowed me to distribute my
11work under the terms of the LGPL.
12
13VAUL can be used to parse and analyze arbitrary VHDL code.  The result
14is an abstract syntax graph, which is represented as a collection of
15C++ objects, tightly connected by pointers. All names used in the VHDL
16code have been resolved to their respective declarations (including
17overloaded function names) and types have been checked (excluding
18subtype constraints).
19
20It is now a serious canditate for the VHDL frontend of the FreeHDL
21project, see http://www.linuxeda.com/~freehdl.
22
23* STATUS
24
25Currently, the analyzer understands enough of VHDL to successfully
26parse and type-check the IEEE std_logic_1164 packages (including
27"arith", "signed", "unsigned", "textio", etc.), the VITAL packages
28(timing and primitives), all models of the Free Model Foundation that
29I have tested, and probably much more. It generates quite useful error
30messages, but could do better, of course.
31
32Many minor semantic checks are not done or the details are probably
33incorrect.
34
35The documentation is mostly lacking, unfortunately, but things are
36getting better.  Right now, the most useful source of information
37about the generated syntax graph is probably "v2c.cc", the source code
38of the `VHDL to pseudo-C' translator.
39
40* CONTENTS
41
42libfire/
43    Libfire contains the definition of the abstract syntax nodes, plus
44    support routines.  "Fire" stands for "Feeble Intermediate
45    Representation with Extensibility".  It is of course a pun on
46    "AIRE", the "Advanced Intermediate Representation with
47    Extensibility".  I hope to make libfire AIRE compliant sometimes
48    in the future, but right now, it is only very superficially
49    similar to AIRE.
50
51    Libfire has some unique features for extensibility that I think
52    are superior to the proposed AIRE mechanisms.  So we wont need the
53    extensibility of AIRE for implementing useful applications of the
54    syntax nodes, but it would still be nice to be compatible to
55    existing and upcoming AIRE compliant software.
56
57    Libfire is [will be] documented in the file `doc/libfire.texi'.
58
59libvaul/
60    This is the actual VHDL frontend, packaged as a library.  Included
61    is a sample application, the superficial translator from VHDL to
62    pseudo C, "v2c". There are also a few VHDL files for testing in
63    vlib/.
64
65    PLEASE NOTE: The files in vlib/ are meant for testing ONLY and
66    might therefore contain gratuitous errors and lies.  Please get
67    them afresh from their original sources if you want to use them
68    for real.
69
70    Libvaul uses libfire for its intermediate representation, of
71    course.  It adds some extensions of its own.
72
73    Right now, the relationship between libfire and libvaul is
74    somewhat perverted.  Libfire does not contain anything really
75    useful and the bulk of the syntax nodes is defined as `extensions'
76    in libvaul.  This will change over time, of course.
77
78doc/
79    Here is some documentation.
80
81* COMPILING
82
83Basically, what you do with GNU packages:
84
85    % ./configure
86    % make
87
88More complete (but generic) instructions are in INSTALL.
89
90This version uses automake/libtool as its build environment.  But as
91long as you dont want to change the Makefiles, you don't need to have
92them installed.
93
94The C++ rendition of the abstract syntax node definitions is generated
95by a tool written in Guile Scheme.  The generated files are contained
96in the distribution, so you shouldn't need to run the Scheme program
97unless you modify the definitions in the *.t files.  Guile version 1.2
98from your local GNU mirror should be fine.
99
100You probably need GNU C++ (2.6.3 and up) and maybe some other GNUish
101tools. It should compile at least on GNU/Linux, SunOS 4 and 5, maybe
102with some tweaking.
103
104* RUNNING
105
106There is no real documentation for the library or the example
107programs.  The doc/ directory contains the beginnings of libfire.texi,
108the documentatzion for the general syntax graph support and the
109particular node types used by VAUL, but it is still very incomplete.
110But until then, here are some hints about how to run `v2c' on the
111sample VHDL files.
112
113There are some VHDL files in libvaul/vlib/* that can be used to test
114`libvaul'. Each VHDL design library is contained in a separate
115subdirectory.
116
117    vlib/std/
118	The packages std.standard and std.textio.
119
120    vlib/ieee/
121	The IEEE std_logic_1164 packages and the VITAL timing and
122	primitive packages.
123
124    vlib/fmf/
125	Some packages and models from the Free Model Foundation.
126
127Libvaul does not store its intermediate representation of the VHDL
128source code on disk.  That means that whenever a design unit is needed
129during analysis, the source code for it has to be found and
130reanalyzed.  Only two kinds of design units are ever needed during
131analysis: packages that are mentioned in USE clauses, and entities
132that are mentioned in binding indications. [right?]
133
134Libvaul can not find the needed source code by itself, it needs help
135from the application.  v2c has a very simple rule for finding the
136source code.  For a package or entity named UNIT, that is contained in
137a design library named LIB, it looks for "vlib/LIB/UNIT.vhd" and
138"vlib/LIB/UNIT.vhdl".
139
140    % cd .../libvaul
141
142	v2c knows that the libraries are in vlib/
143
144    % ./v2c -lfmf vlib/fmf/nlb6201.vhd
145
146	`-lfmf' means: use the "fmf" library as the working library.
147