Tutorial: Devices

We begin the devices tutorial by defining a few terms. All devices in PHDL require an association with a physical layout definition either shipped with the chosen layout tool software libraries, or created by the layout designer. We use the term "footprint" to refer to this physical layout definition (often referred to as a "decal" in PADS, and a "package" inside EAGLE PCB.) We like the term footprint because it is used consistently in device datasheets to describe the physical dimensions of the device and corresponding recommended PCB layout.

Before starting any design, a collection of devices must be defined. A device may contain two types of elements in any quantity, and in any order. These are: (1) attributes, and (2) pins. Some special attributes are used to reference a particular footprint for the device when a netlist is created. All are tabulated into a Bill of Material for use in parts procurement. Pins form a logical to physical mapping of PHDL pin names to footprint pin names in the layout tool. PHDL allows aggregation of pins in the form of arrays, which some layout tools do not support natively. Throughout a design, these pins are referenced frequently to form the electrical connectivity of the board, just as mouse clicks on a screen would draw the connectivity as lines, terminating a device pins. An example device declaration and its equivalent schematic representation of a surface mount resistor is shown below.

 * A surface mount resistor
device res_0603 {
    // a single line comment
    attr REFPREFIX = "R";
    attr FOOTPRINT = "R0603";
    attr LIBRARY = "rcl-smd";
    pin a = {1};
    pin b = {2};


A quick word on syntax above: keywords are highlighed in bold purple font (the default eclipse color for keywords). Devices start with the keyword device followed by an identifier. This identifier may be any combinations of letters, numbers, and underscores (and a few other characters). The body of the device declaration is wrapped in brackets, and may contain any number of attribute and pin declarations, in any order.

Notice that there are three attributes declared: REFPREFIX, FOOTPRINT, and LIBRARY, and they are all uppercase. The compiler discourages non-uppercase attribute names since all attributes are treated case-insensitive throughout the language. The attribute values can be any string of characters and spaces. These three attributes at a minimum are necessary to produce a valid netlist output. The functionality of each attribute is explained below:

Though only three attributes have been declared in this device, any number of attributes may be declared. They will all appear tabulated in the generated Bill of Material (BOM) for each top-level design unit.

There are also two pins declared: a and b , each mapping to a corresponding footprint pin name 1 and 2 , respectively. The way the pins are declared is somewhat arbitrary. Instead of letters, the pins may take on names that are only numbers, the same way that they are defined in the footprint.

    // these are pin declarations
    pin a = {1};
    pin b = {2};

    // the name is arbitrary but the physical pin names in braces
    // must be the same as the way they are defined in the layout footprint
    // this is also valid
    pin 1 = {1};
    pin 2 = {2};
    // so is this
    pin pin1 = {1};
    pin pin2 = {2};
    // and this
    pin + = {1};
    pin - = {2};

Pin declarations form a logical-to-physical mapping of PHDL pin names to their respective names in the actual layout footprint. The physical pin names are contained in a comma-separated list between brackets, and may contain any sequence of numbers, letters, underscores, and a few other special characters.

If desired, pins may be declared in array notation like this resistor array device declaration:

device res_array {
    attr REFPREFIX = "RA";
    attr FOOTPRINT = "R0612";
    attr LIBRARY = "rcl-smd";
    pin[3:0] a = {1,2,3,4};
    pin[3:0] b = {8,7,6,5};

On the left, array indices in braces separated by a colon form the size of the array (in this case, 4 ), and on the right is a comma-separated list in braces of physical pin-names to which these array values correspond. This means that pin a[3] corresponds to physical pin 1 of the footprint R0612 , a[2] corresponds to 2 , and so on. In other words, the mapping is always taken in left to right order that the array has been declared. If the array for pin a had been declared as

    pin[0:3] a = {1,2,3,4};	// a[0] -> 1, a[1] -> 2, a[2] -> 3, a[3] -> 4

then a[3] would map to physical pin 4 of the footprint. If the size of the array on the left does not equal the size of the list on the right, the compiler will issue an error, since this is obviously not the intent of the declaration.

On all devices (especially high-pin-count devices), there is frequently a need to check that all pins have been declared. Use the PINCOUNT attribute like this:

device res_array {
    attr REFPREFIX = "RA";
    attr FOOTPRINT = "R0612";
    attr LIBRARY = "rcl-smd";
    attr PINCOUNT = "8";     // checks for 8 declared pins (below)
    pin[3:0] a = {1,2,3,4};  // found 4 pins here...
    pin[3:0] b = {8,7,6,5};  // another 4 pins here... we have 8!

This ensures that since we know we are working with an 8-pin device, we have correctly declared 8 pins somewhere in the device body. In this case, we have declared two pin arrays with four pins each, for a total of 8 individual pins. The PINCOUNT attribute requires an integer value, and the compiler will issue an error if it is not an integer, or does not declare the exact number of pins found in the device body.

Declaring Devices in the Eclipse Plugin

The plugin allows devices to be declared quickly and easily. Anywhere a device declaration is legal (either within the global namespace or within a package declaration), the content-assist feature of the plugin may be activated using [CTRL] + [SPACE]. (A good rule of thumb is to always remember that content assist can be activated anywhere to see what options are available to you.) When activated in the context of a device, a dropdown box appears that proposes a device declaration from a template as one of the available options. If it is selected, it inserts a template of a device into the document, with tabbed fields to be able to name things quickly. After the [ENTER] key is pressed, the cursor is moved to the body of the device, after the three required attributes, ready to declare pins. Further use of [CTRL] + [SPACE] will aid in forming pin declarations.

Tips and Tricks

There are a number of shortcuts and tricks that you can use to speed up the declaration of a device - especially if the particular device you are working with has a regular structure that can easily be represented with an array. For example, if you have a connector with 10 pins, you could define the pins like this:

pin[9:0] p = {p9,p8,p7,p6,p5,p4,p3,p2,p1,p0};

However, for large connectors, it can be cumborsome to type in all of the physical pin names. Instead, you could purposely provide an empty phyiscal pin list, and provoke the plugin to propose several quickfix options. For example, you could enter that same declaration as:

pin[9:0] p = {};

The plugin will initially report an error, but also provide you with some valuable quick-fix options. Select the lowest quickfix in the proposal box: Generate new pin list from pin name and vector indices.

Once the quickfix is clicked, the pin declaration should look exactly the same as it did the first time, except we didn't enter any of the physical pin names in by hand this time. Note that this quickfix generates the names according to the way the array has been declared. If the array had been [0:9] , the elements in the physical pin name list would have been reversed, and would look like this:

pin[0:9] p = {p0,p1,p2,p3,p4,p5,p6,p7,p8,p9};

There are also quickfixes to correct attribute names that are not capitalized. You can use [CTRL] + [SPACE] at any time to activate content assist to aid in declaring attributes and pins.


This tutorial has demonstrated the syntax of a PHDL device declaration, the required attributes necessary for generating valid netlist output, as well as introduced some of the automation that the plugin itself provides in analyzing your PHDL code. These features are the tip of the iceburg as far as what the plugin is capable of. Hopefully this tutorial has spiked your interest. If so, read on!

Getting Started With PHDL

The best place to start is to visit our installation instructions which will help you get PHDL up and running on your machine. Then, be sure to visit the tutorial page.