![]() |
|
|
Table of Contents
Introduction
Mini XML Tutorial
Using XMAC
Essentially the XMAC "language" consists of a bunch of xml tags that define the java code to be created. The XMAC system is also flexible enough to be extended to parse user defined tags if the need should arise.
XMAC also uses a very powerful feature of XML parsers, that is the ability to validate xml against a rigid set of rules. These rules are contained in a schema file called xmac.xsd.
Another program associated with the XMAC package is boolgen. Boolgen will be mentioned briefly later on because it exists, but it's not something that most people need ever worry about.
This document is intended as an introduction to XMAC and how it applies to the JHDL primitives. A prior knowledge of basic xml is helpful, though not completely necessary. Those familiar with html will find xml very intuitive (though xml is much better!).
<tag1>
<tag2>
</tag2>
</tag1>
Is legal XML code, while
<tag1>
<tag2>
</tag1>
</tag2>
is not. XML Must be nested or the XML parser will generate an error. An XML document is said to be well formed if each opening tag has a closing tag and if all the tags are nested properly. XML is valid if it conforms to specific requirements based on the application.
Some tags will have attributes associated with them and are of the form: <tag1 attribute="something">
Another nice feature of XML is the ability to create self closing tags. If for example a tag has no data associated with it, but must be in place, you can use either one of two forms: <tag1 attribute="something"></tag1> or <tag1 attribute="something"/> Either is valid, the last one is of course easier to use.
Each and every single XML document must have a line at the top that declares what type of document this is and the encoding. There are many variations but the most simple is:
<?xml version="1.0"?>
Don't forget the include that as the first line in every single XML document.
Another thing to keep in mind is that the input xmac file will be completely parsed by the XML parser. This means that any special characters will be interpreted by the parser. Some of these characters are: &, <, >, and depending on context the " char. These characters are used by the parser and so special care must be taken to ensure you get the desired results. For example, the < char opens a new tag. If you wrote some java code that did a comparison such as if (a < b).... The xml parser would die because it couldn't figure out what you were doing. To get around this rewrite it as if (a < b).... The xml parser will turn the < into a < symbol for you. Here are the most common codes (note the trailing semicolon is important):
At the core of XMAC is the Xerces XML parsing engine. Xerces is
distributed by the Apache Software Foundation
and can be obtained from their web site. PLEASE NOTE XMAC uses a Schema to
validate the input files. As of this writing the only version of Xerces to support schema's
is 1.4.3. You must use Xerces 1.4.3 for XMAC to work. After downloading Xerces
place it in your classpath and XMAC will find what it needs.
java xmac basedir [options]
Where the basedir is the base directory to store the resulting java files in. The final directory the files are placed in is a function of the package tag, which will be discussed later. If you are creating files for the jhdl tree then this needs to be the base (or head if you prefer) of the tree.
Options
-s directoryname The directory to start scanning for .xmac files. The default is the current directory.
-q
Quiet mode. This suppresses all output messages.
<?xml version="1.0"?>
<xmac>
<package>byucc.jhdl.Xilinx.XC4000</package>
<package>byucc.jhdl.Xilinx.Virtex</package>
<package>byucc.jhdl.Xilinx.Virtex2</package>
<javadoc>
This class implements a basic buffer.
</javadoc>
<class name="buf" extends="XilinxCL" implements="UnmappableCell,
Buf">
<interface>
<in name="i" width="1"/>
<out name="o" width="1"/>
</interface>
<sharecell/>
<propagate>
<put refid="o"><get refid="i"/></put>
</propagate>
<constructor/>
<schematic>BUF</schematic>
<test>
0, 0
0, 0
1, 1
1, 1
</test>
</class>
</xmac>
Each of the tags will be discussed in detail below, but briefly here's what is going on. The first thing to note is the line <?xml version="1.0"?>. This is required in every xml document and MUST be the very first thing in the document. If there is even so much as a space before this line the xml parser will complain and die.
The next requirement is that the document root tag must be <xmac> or an error will be generated.
Under the <xmac> tag is where everything else belongs. Note there are three
<package> tags. These instruct XMAC to create three files, place them in the
correct package directory, and give each one an appropriate header - usually a bunch
of import statements. The header is configured in the config.xml document. The format
is pretty straight forward and is well documented in that file. For example the
Virtex header is:
package byucc.jhdl.Xilinx.Virtex;
import byucc.jhdl.base.*;
import byucc.jhdl.Xilinx.*;
import byucc.jhdl.Logic.Logic;
import byucc.jhdl.Logic.LogicGates;
import byucc.jhdl.Logic.LibrarySelfTester;
import byucc.jhdl.Logic.TestException;
import byucc.jhdl.Logic.WideBooleanFunction;
import byucc.jhdl.Xilinx.Virtex.*;
import byucc.jhdl.apps.Viewers.Schematic.PreDefinedSchematic;
The <javadoc> tag will neatly format its contents and place it in the output file as javadoc style comments.
The <class> tag is one of the most important tags in the whole xmac document. If this is not present then XMAC will die. The output file gets its name from this tag. Also, it's easy to see where the class declaration comes from by looking at the attributes in the tag.
The rest of the tags define the ports this cell will have, and the behavior
of the cell. This simple example will take the input and pass it to the output -
thus this models a buffer.
TAG | Required | Scope | Description |
<xmac> | Yes | Root Tag | XML requires that there be one and only one root tag. This seemed like a logical choice. :) |
<package> | No | <xmac> | This defines the package that the resulting java file will be created for. Example: <package>byucc.jhdl.Xilinx.Virtex</package> Note that more than one package tag may be present in any given xmac file. |
<javadoc> | No | <xmac> | Text blocks within this tag will be formatted and output to the file in javadoc format. |
<class> | Yes | <xmac> | This tag sets several things: First it outlines the body of the class, second it sets a class name with a name attribute, third it sets other important parameters with other attributes. |
<interface> | No* | <class> | Defines the wires and port info needed by this cell. This is primarily useful for JHDL, but may prove useful for other applications. |
<sharecell> | No | <class> | Results in cellInterfaceDeterminesUniqueNetlistStructure() method. |
<clock> | No | <class> | Model synchronous behavior. |
<propagate> | No | <class> | The asynchronous behavior model. |
<reset> | No | <class> | The behavior at reset time. |
<constructor> | No | <class> | Build the default constructor set. |
<wire> | No | any | Create a new wire object. |
<schematic> | No | <class> | Defines which schematic symbol to use. |
<test> | No | <class> | Defines a series of test vectors for the cell. |
<code> | No | any | Allows java code to be inserted directly into the xmac file. |
<put> | No | any | Put a value on a wire or port. |
<get> | No | any | Retrieve a value from a wire or port. |
<not> | No | any | Usually used in conjunction with a get, this inverts the signal. |
Description
The package this file will be created for. Note, more than one
package tag may exist. If more than one exists then a copy of the
file will be created for each package and tossed to the appropriate directory.
If no package tag is present then the file will be placed in the current
directory.
Example
<package>byucc.jhdl.Xilinx.Virtex</package>
When XMAC is invoked it requires a head directory to place the output files.
In the example the output file would be placed in the directory byucc/jhdl/Xilinx/Virtex
relative to this head directory.
Description
The text under this tag will be neatly formatted and output to the
resulting java file in javadoc format.
Example
<javadoc>
The buf cell performs simple buffering.
</javadoc>
Will result in:
/**
* The buf cell performs simple buffering.
*/
Which is neatly formatted for javadoc.
Description
The contents between the opening and closing class tags constitute
the bulk of the xmac file. This is where most other tags live and
the real work is done.
Example
<class name="buf" extends="Logic" implements="UnmappableCell"
returncellname="buffer">
...
</class>
Most of the info will be obvious to Java programmers, the one attribute above that is
worth mentioning is the returncellname attribute. Normally this cell would
return the name "buf" to the netlister. However, this attribute will
override that default and return "buffer" instead. If its not desireable
to have a name returned at all, then the attribute suppresscellname can
be set to true.
Description
This tag describes the interface block for the cell. There are several
subtags associated with this tag: in, out, inout, clk, sout, saout, sin,
sain, ain, aout, implicit, and generic. All tags except generic have
the same attributes: name and width. The generic tag has: name and
value. Note that for the width either a number or the word GENERIC
is acceptable.
Example 1
<interface>
<in name="i" width="1"/>
<out name="o" width="1"/>
</interface>
Example 2
<interface>
<implicit name="clk" width="1"/>
<ain name="i" width="GENERIC"/>
<out name="o" width="GENERIC"/>
<generic name="INIT" value="1234"/>
</interface>
Description
This tag results in the code cellInterfaceDeterminesUniqueNetlistStructure().
There
is no other data associated with this tag.
Example
<sharecell/>
Attributes
Description
The body of this tag defines the synchronous behavior of the cell.
Attributes
Description
The body of this tag defines the asynchronous behavior of the cell.
Example
A simple buffer can be defined as:
<put refid="o"><get refid="i"/></put>
Description
The body of this method defines the reset behavior.
Example
<put refid="o">0</put> - Set the port "o" to zero on
reset.
Description
This tag does two things: first it creates a default set of constructors,
and second it makes each of those constructors run any code that you place
within the constructor tags.
The default constructors include wires only, wires with an instance name, wire pairs, etc. The can all be defined in the configuration document. Also, multiple constructor sets can be defined, if the need should arise. See the documentation on the configuration for more information.
Any code placed between the tags will in turn be placed in the init() method of the output.
Example
<constructor/> - Produces the default set of constructors.
<constructor>
(code)
</constructor>
Will creates the default constructor set and dumps the code into the init method which is called by each constructor.
<constructor name="set2"/> - Create the constructor set
called set2 as defined in the configuration.
Description
Create a new wire object in the cell. There is one main advantage of
using the tag, rather than just straight java code - the XML parser will
know about this tag while it would not otherwise. This is useful
info for many of the tags, particularly the get and put tags. They
use this to figure out how wide a wire is and adjust themselves accordingly.
Example
<wire name="w" width="4"/>
Description
Define the schematic symbol to use in the simulator. For a list
of currently supported schematic types see the documentation on byucc.jhdl.apps.Viewers.Schematic.PreDefinedSchematic.
Example
<schematic>BUF</schematic>
Description
Define a set of test vectors. Note that any implicit ports are
not included in this list.
Example
Suppose the cell in question is a generic width buffer with one input
and one output. The test vectors could be:
<test width="1">
0, 0
0, 0
1, 1
1, 1
</test>
<test width="16">
0x0000, 0x0000
0x0000, 0x0000
0xabcd, 0xabcd
0xabcd, 0xabcd
0x1234, 0x1234
0x1234, 0x1234
</test>
<test width="64">
0x0123456789abcdefL, 0x0123456789abcdefL
...
</test>
<test width="128">
0.0.0.0, 0.0.0.0
0.0.0.0, 0.0.0.0
0xdeadbeef.0xdeadbeef.0x12345678.0xabcdef00, 0xdeadbeef.0xdeadbeef.0x12345678.0xabcdef00
...
</test>
Notice how the 128-bit wide vector is broken up. Also, note that
64-bit wide vectors have the trailing "l" to make them longs.
Description
No "floating text" is allowed in the document. What this means
is that everything must be enclosed in tags. If tags alone are not
sufficient to meet the needs of the cell, then java code may be placed
directly in the xmac file. The code must be placed between the <code>...</code>
tags. Also note that any tags present within this tag will still
be parsed, and example will follow.
Example
<code>
if (<get refid="i"/> == 0) {
<put refid="o">1</put>
}
else {
<put refid="o"><get refid="i"/></put>
}
</code>
Description
This tag will put a value on a wire or port. In JHDL there are
three main put methods: put, putL, and putA. Which one to use depends
on the width of the wire. If the put tag knows about a wire either
through the port interface or a wire tag then it will automagically configure
the resulting put in the java output to the right method. If the
wire is a generic width then put will also build an if...else... clause
and let the cell figure out how wide it is.
Example
<put refid="o">0</put>
Description
This tag will get a value from a wire or port. Often this is
used in conjunction with a put tag, but may be used alone.
Example
<put refid="o"><get refid="i"/></put>
See the code tag documentation for another example.
Description
This will invert a wire. This is usually used to surround a get
tag.
Example
<put refid="o"><not><get refid="i"/></not></put>
For the most part the XMAC classes are separated by functionality. The naming convention is TagnameParser. For example, the <test> tag is parsed by TestParser, the <class> tag is parsed by ClassParser, etc. The most important classes are: XMAC, XMACParser, ClassParser, and DocInfo. Becuase all of the classes need certain information the class DocInfo contains all the important information about the current job. This object is passed back and forth between the parser classes so they know what they are doing. The top level class is XMAC. XMAC is normally called by the wrapper class xmac which is in the byucc/jhdl/helpers directory. This class contains the outer loop and takes care of creating the DOM document and the DocInfo object. From there control is passed to XMACParser which will process the tags under the <xmac> tag. Control is passed in turn to the classes that parse each of the tags.
Each of the Parser classes extend the TagParser class, which provides some common functionality between all the parsers.
It's probably best to illustrate with an example....
Most of the tag parsers conform to this and will work just fine. Some parsers however need to call a tag by name. Where this happens they usually also handle tags that it doesn't explicitly know the name. A good example is in order here. Let's say we want to add a <foobar> tag. This is the code that would add that tag:
package byucc.jhdl.util.xmac;
// Exception handling
import java.io.IOException;
// DOM Interface
import org.w3c.dom.Node;
import org.w3c.dom.Element;
/**
* Process the foobar tag
*/
public class FoobarParser extends TagParser {
private Node docRoot; // The "root" of this part
of the DOM tree
private Element docElm; // The Element version of the same
root
private WireInfo wireInfo;
/**
* The default constructor for this class.
* @param docInfo The <code>DocInfo</code>
object that contains the
* current settings and parameters.
*/
public FoobarParser(DocInfo docInfo) throws Exception {
super (docInfo);
wireInfo = new WireInfo(docInfo.getDOMDoc().getElementsByTagName("xmac").item(0));
}
/**
* This is the actual method that does the parsing
of the tag.
* @param docRoot The <code>Node</code>
of the foobar tag.
*/
public void parse(Node docRoot) throws Exception {
this.docRoot = docRoot;
docElm = (Element) docRoot;
// Did they for some reason pass us a node with
the wrong name?
if (!docElm.getTagName().equals("foobar"))
throw new Exception("FoobarParser
was passed a wrong node!\n");
// Check out parent and make sure we have the
right heritage.
if (!checkParent(docRoot, "xmac"))
throw new Exception("<foobar>
must be a child of <xmac>!");
StringBuffer str = new StringBuffer();
str.append(indentLine("for (int i = 0; i < 10; i++) {\n"));
increaseIndent();
str.append(indentLine("System.out.println(\"Hello World!\");\n"));
decreaseIndent();
str.append(indentLine("}\n"));
// Dump this to the output file
writeOutput(str.toString());
}
}
That would create an output file with the following contents:
for (int i = 0; i < 10; i++) {
System.out.println("Hello World!");
}
A few methods to make note of: writeOutput(), indentLine(), increaseIndent(),
decreaseIndent(), and checkParent(). These are some of the methods inherited from the
TagParser class. See the API documentation for the complete list of methods. Briefly though
the methods are as follows:
writeOutput() takes a String and dumps it to the output file stream.
indentLine() takes a String, and then returns a String which has spaces at the
beginning of the line, thus indenting the line. The number of spaces on the front is
dependent on two variables. One is set in the config file, which is how many spaces per
indent level, and the other is the current indent level.
increaseIndent() increases the current indent level. See the code above for a good
example on where to use this method.
decreaseIndent() decreases the current indent level. See above code for example.
Note: always remember to match an increaseIndent() and decreaseIndent() or subsequent
.xmac files will be really messed up!!!!!!
To be continued...Obviously there is a ton more to cover, which I will add as time permits...
First, what is a schema? Essentially it is a set of gramatical rules that the xml parser uses while it is parsing. In the XMAC schema each tag is declared and its data structure is set. Anything not conforming to this defined structure will generate an exception. It might be argued that this takes some of the flexibility out of XMAC because now a strict set of rules must be adhered to. To a degree this is true, however, try contrasting BASIC and Java code. One is a mess and has no structure, the other is very structured and easy to read. XMAC with a schema is much the same way - it must conform to certain rules or it dies.
Let's illustrate with an example. Below is the code in the schema which defines
the class tag.
<xsd:element name="class">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="code" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="interface" minOccurs="0" maxOccurs="1"/>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element ref="constructor" maxOccurs="1"/>
<xsd:element ref="code" maxOccurs="unbounded"/>
<xsd:element ref="clock" maxOccurs="1"/>
<xsd:element ref="propagate" maxOccurs="1"/>
<xsd:element ref="reset" maxOccurs="1"/>
<xsd:element ref="schematic" maxOccurs="1"/>
<xsd:element ref="test" maxOccurs="unbounded"/>
<xsd:element ref="sharecell" maxOccurs="1"/>
</xsd:choice>
</xsd:sequence>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="extends" use="optional" type="xsd:string"/>
<xsd:attribute name="implements" use="optional" type="xsd:string"/>
<xsd:attribute name="returncellname" use="optional" type="xsd:string"/>
<xsd:attribute name="suppresscellname" use="optional" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
In the example on extending XMAC we added a foobar tag. Suppose we want to
use this tag under the class tag now. In the class tag declaration we'd add:
<xsd:element ref="foobar" maxOccurs="1"/>
Note that the above is only a reference to the tag foobar. Now we need to
define the actual declaration. In this case it's simple:
<xsd:element name="foobar" type="xsd:string"/>
That should be good enough to get you started. The schema file xmac.xsd
is documented well and should be easy to follow.
| JHDL Home Page | Configurable Computing Lab | Prev (Behavioral Models) | Next (General Issues) | |
JHDL 0.3.45
Copyright (c) 1998-2003 Brigham Young University. All rights reserved.
Last updated on September 11, 2003