Chapter 7. Board Hardware Definition

If you are on a video output hardware design team and are defining a new board with all its rules, this is the place. If you are not on such a team, there is no need to continue reading this chapter.

Two general sections make up the board definition:

Given a properly-defined chip definition file, the video format compiler synthesizes the program needed to drive the chip to produce the signals you specify.

General Notes About Writing Definition Files

Variables

Don't miss the touching description of “User-Defined Variables”. These variables can be defined in the same way and scope as can variables in the C language.


Tip: Pay attention to exported variables, as described in “Storage Classes”. All exported variables are written to the output file and can be used by loading software. Exported variables are handy for storing the results of calculations made when producing the video format. These variables are typically calculated in the rules section, but they are also often derived in the post-processing statements, described in “Pre-Processing and Post-Processing Statements”.


Statements

To help you deal with complicated situations, you may use “Control Statements” as you would in the C language. Also, you can use “Diagnostic Statements” to warn the user of errors during processing.

Control Statements

You may use the following statements, as you would in the C language:

if (expression) statement

if (expression) statement else statement

for (expression; expression; expression) statement

Diagnostic Statements

These statements allow you to pass information along to the user. The compiler prints any string you specify as it would any other internally generated messages.

info string-expression

warning string-expression

error string-expression

The info and warning statements allows compilation to proceed; the error statement causes the compiler to terminate before producing an output file and generates an error status code on exit.


Tip: You can build string expressions by using the + operator. Any numeric value expressions are converted to string expressions automatically, and expressions of quoted strings to be concatenated are perfectly legal.


Board Description

This section describes how to describe the board in the board definition file.

  • The first part of this section of the board description file shows the different parameters you can use to describe the board; this is described in “Parameter Definition”.

  • The second part of this section of the board description file defines signal names; read about this in “Board Signal Assignment”.

  • The next part of the board description file associates signals with special attributes; this is covered in “Special Signal Definition”.

Before writing the rules, you should carefully describe your board. A thorough description will make the compiler work harder for you.

Parameter Definition

These variables describe the way in which video is generated on your board. Some are used for programming, others for bounds checking. The variables are in Table 7-1.

Table 7-1. Board Hardware Definition Variables

Variable Name

Description

Required

VideoClockRatioNumerator

Part of the description of the pixel-to-video clock ratio. This value describes the number of pixels in the ratio.

Yes

VideoClockRatioDenominator

Part of the description of the pixel-to-video clock ratio. This value describes the number of video clocks in the ratio.

Yes

SystemVideoClockRateMaximum

The highest rate at which the video clock operates. This compiler reports an error if the user's format exceeds this rate.

Yes

SystemVideoClockRateMinimum

The lowest rate at which the video clock operates. This compiler reports an error if the user's format is less than this rate.

Yes

DACRateMaximum

The highest rate at which the output DAC operates. The compiler reports an error if the user's format exceeds this rate.

Yes

DACRateMinimum

The highest rate at which the output DAC operates. The compiler reports an error if the user's format is less than this rate.

Yes


Board Signal Assignment

The chip definition (not described in this book) supplies the chip's names for each signal it can generate. Typically, these are the names of the pin-out of the chip (or may just be names the chip uses internally). Because a single kind of format generation chip can be used on more than one board, these names often do not have particular meaning (or can sometimes have meaning other than their true use).

The signal name definition statement associates a chip's signal name with a name meaningful on the board. It is that board signal name that you can use within the rules when you assign transitions.

You must have a board signal assignment statement for each signal you intend to use. Although you need not use every signal on a chip, you must make the assignment for those you do intend to use (even if the name of the chip and the board are identical).

The syntax of the statement is as follows:

signal board-signal-name uses chip hardware signal chip-signal-name;

  • board-signal-name

    The board-signal-name is any string (usually in double quotes) you choose. The name should be meaningful to application on the board; you will use this name in the rules section (see “Rules Definition”).

  • chip-signal-name

    The chip-signal-name is the name assigned by the writer of the chip definition file. You must specify it exactly as presented there.

Special Signal Definition

The compiler requires some additional information about how your output signals are used when running. These signals drive the frame analysis process which is in turn used to provide information for the -a ascii option (for more information, see vfc(1) ); frame analysis is also used to drive the rules section of the compiler (see “Rules Definition”).

Each special signal definition specifies the signal to fill each role. The general form is

signal-type is board-signal-name active direction ;

The signal-type is one of those detailed below. The board-signal-name is the same name you specified in the board signal assignment (see “Board Signal Assignment”). The direction specifies the polarity of the signal when active (either high or low).

The following are board signal assignments:

  • Composite Sync Signal

composite sync signal is board-signal-name active direction ;

The composite sync signal is very important for frame analysis. The signal you designate is used for determining the positions of all frame portions.

  • Active Signal

active signal is board-signal-name active direction ;

The active signal is used for frame analysis to determine on which lines active pixels lie (those containing picture content — see “Architecture of a Video Frame” for details if you need them). The active lines are used to determine the horizontal blanking interval values as well as to determine the number of fields in the format (by counting the clusters of active lines).

  • Trilevel Sync Signal

trilevel sync signal is board-signal active direction ;

The trilevel sync specifies which, if any, of the output signals is used for tri-level sync. If you define this signal, the compile defines the user tri-level signal for you.

  • Pixel Requesting Signal

pixel requesting signal is board-signal active direction ;

If your board has a signal that corresponds to the transfer of video pixels, you should specify it in this statement. The signal need not correspond to the time at which the format would have the pixels transfer, but the duration in clocks must be correct as measured by VideoClockRatioNumerator and VideoClockRatioDenominator (see Table 7-1).

If you set this signal, the compiler can verify that no rounding errors have changed the correct duration of the pixel requesting signal.

Rules Definition

This section of the definition file is where you can define the signal transitions necessary to operate a video board. The master timing reference is the user's video format: all signals reference the user's format for their temporal positions.

The Edge Database

All signal transitions that in the format are placed in the edge database. This includes the transitions the user specifies in the format (see “The User Signals for Reference”) augmented by the transitions on signals that are defined in the rules (see “The set signal Statement for Transitions”). The within statement (see “The within Statement for Location”) uses the edge database for reference with some signals.

The edge database is resident in the compiler until the compiler terminates. Because the edge database is always ready for your use, you can reference it within pre-processing and post-processing statements (see “Pre-Processing and Post-Processing Statements”).

The edge database stores transitions in time units at the maximum internal resolution of the edge database. Transitions are not quantized to the clock period until they are extracted from the database. Delay of quantization attempts to minimize successive quantization error when dealing with absolute time units.

Initial State

The initial state of the signal is the state of the signal at the beginning of the frame. You have wo choices: high or low. Syntax for the statement is as follows:

signal board-signal-name initial state direction ;

Some chip hardware has signals for which the initial state is programmable; the compiler can set the initial state properly if you use this signal. Other hardware may have fixed initial state requirements; the compiler can check to be certain your initial state setting is compatible with hardware.

The set signal Statement for Transitions

Use the set signal statement to describe signal transitions on any signal you generate with the video format compiler. This enters the transition in the edge database (for more information on this part of the video format compiler, see “The Edge Database”).

Syntax for this statement is as follows:

set signal board-signal-name transition-direction at time-expression [ error-handling ];

The following are components of this statement:

  • signal-name

    The signal-name you use is any of the signals you have defined in the board signal assignment (see “Board Signal Assignment”).

  • transition-direction

    The transition direction can be either high or low, similar to the manner in which sync signals are defined in “Level of Sync”.

    You may use a variable instead of these predefined keywords; define an integer variable with the value  you choose and use the variable for the direction. If you are copying the polarity of the innermost range of the scope, you can use CorrespondingPolarity.

  • time-expression

    You can use any of the time expression specified in “Time Expressions”. Because you will probably be using within statements most of the time, make ample use of the BeginTime and EndTime variables the compiler defines for you (see “How You Can Use Range Information”).

    If the time you specify is at a point before the beginning of the frame or after the end of the frame, the compiler issues a warning message, but wraps the time to the proper point in the current frame.

  • error-handling

    Error handling is an optional clause of the set signal statement. You need set it only under circumstances that require it.

    Only one error handling clause is defined at present:

    • ignoring wrap error—This clause instructs the compiler not to issue a warning if the time-expression is at a point before the beginning of the frame or after the end of the frame.

The within Statement for Location

The within statement gives you reference points to the architecture of a frame. You specify a time range in which you are interested, and the compiler supplies the variables, giving you the time position in the frame of that range. Given those variables, you can use set signal to set transitions.

The compiler has two forms of the within statement:

  • within ( range-expression first-expression, last-expression [ ; warn–expression ] ) board-rules-statement

  • within each ( range-expression [ ; warn-expression ] ) board–rules–statement

Both statements use a range-expression to specify which portion of the frame should be iteratively selected. The range expressions, explained in detail in the following sections, permit you to specify logical portions of the frame (for example, Vertical Front Porch, Horizontal Sync, and so on); transitions of previously-defined signals; and absolute periods of time.

You should understand these concepts—Vertical Front Porch, Horizontal Sync, and so on—before you begin. If you need a brief overview or if you want to know the compiler's definition of many of these terms, see Chapter 3, “Building Blocks of a Video Format.”

The within statement has clauses that permit you to specify which of the range expressions you wish to choose by specifying the first and last instances of that range, inclusive. Instances are one-based: the first instance is 1, the second instance is 2, the last instance is “number of lines.” For example, the following would iteratively select lines two, three, and four:

within (line 2,4) ...

The within each statement is a special case of the within statement. The within each iteratively chooses every instance of the specified range. For example, the following statement iteratively selects every horizontal front porch defined in the format:

within each (Horizontal Front Porch) ...

Nesting Statements

Statements may be nested, with each statement successively narrowing the scope. For example, the statement within Example 7-1 has narrowed its scope to the second line of Vertical Back Porch of the first field.

Example 7-1. Nested Board Rules Statements

within (field 1,1)
    within each (Vertical Back Porch)
        within (line 2,2)
             ...

In Example 7-1, the following are successively selected:

  1. In within (field 1,1), the within statement selects the first field by specifying the range beginning with field 1 and ending with field 1. Remember, instances are one-based.

  2. In within each (Vertical Back Porch), this statement selects the time span embodied with the Vertical Back Porch of field 1 (the field being narrowed in the previous statement).


    Note: Although “within each” would normally iterate through all instances of this item within the parenting scope, only one Vertical Back Porch exists for any field (so the additional restriction is not necessary).


  3. In within (line 2,2), the statement limits the scope to line 2 (both beginning and ending with 2) of the previous scope (which had been narrowed to Vertical Back Porch of field 1).

By successively narrowing the scope, the above figure has selected a time span that starts with the beginning of line 2 of Vertical Back Porch of field 1 and ends with the end of line 2 of Vertical Back Porch of field 1.

A nested scope can never exceed the bounds of a parenting scope. If a nested range expression specifies a range greater than the range of the parenting scope, the scope is simply limited to the parenting scope.

It is possible to narrow a range such that no time remains in the innermost scope. For example, see Example 7-2.

Example 7-2. Narrowing Scope So No Time Remains

within each (Vertical Back Porch)
    within each (Vertical Front Porch)
        ...

Because Vertical Front Porch and Vertical Back Porch define mutually exclusive time spans within the frame, the innermost range specifies no time span at all and is not a valid scope.

How You Can Use Range Information

When in the bounds of a board rules selection, three variables become active. Their values depend on the format as specified by the user and by previous signal definitions.

  • BeginTime—returns the starting time of the innermost range. This variable is of type time.

  • EndTime—returns the end time of the innermost range. This variable is of type time.

  • CorrespondingPolarity—returns the polarity of the innermost range. This variable is an int.

  • FramePortionIndex—returns the index of the within item iteration (that is., 0 for the first execution of the within block, 1 for the second execution, and so on). This variable is an int.

Each range expression as described below sets values uniquely, according to its rules and bounding scope.

Table 7-2. Range Expressions

Expression Syntax

Description

Start Time

End Time

Polarity

frame

The entire frame. This is provided as a convenience and is not strictly necessary because it is the default range. (See “Default Range”.)

Zero seconds

Duration of the frame.

Positive

field

The field of the frame.

The user defines the number of frames in the field via the variable FieldsPerFrame. (See “The General Parameters Section”).

The beginning of Vertical Sync for this field.

The end of Vertical Front Porch for this field.

Positive

line

The whole line boundary. Line durations are defined by the user's format via this formula:

 

 

FPS is set by the user via FramesPerSecond and TLPF is set by the user via TotalLinesPerFrame. (These variables are described in “The General Parameters Section”.)

The beginning of the whole line (as calculated in Description).

The end of the whole line (as calculated in Description).

Positive

pixel

The whole pixel boundary. Pixel durations are defined by the user's format via this formula:

 

 

FPS is set by the user via FramesPerSecond, TLPF is set by the user via TotalLinesPerFrame, and TPPL is set by the user via TotalPixelsPerLine. (These variables are described in “The General Parameters Section”.)

The start point of pixel is calculated from the beginning of the frame, not the beginning of the period; therefore, it is possible to have a nested pixel time range quantized to a point not coincident with its parent time range.

The user directly defines the total number of pixels in the frame via this equation (using the previously defined variables):

 

The beginning of the whole pixel (as calculated in Description).

The beginning of the whole pixel (as calculated in Description).

Positive

Vertical Front Porch

The first of three portions of the vertical blanking interval. One vertical blanking interval exists for each field in the frame.

The Vertical Front Porch for the first field may be defined following the active portion of the last field, yet still be associated with the first field.

For formats that employ military sync (see definition in Vertical Sync), Vertical Front Porch has a duration equal to zero.

There is one Vertical Front Porch in each field.

These choices are possible:

1) If the format, such as NTSC and PAL, has an intra-line pulse (that is, a pulse that does not fall at the beginning of a whole line from the beginning of the frame), time begins at the start of that pulse.

2) If the format has no intra-line pulse, the time at the beginning of the first line following the last active line of the frame.

The time at the leading edge of the vertical sync pulse. If this format contains more than one vertical sync pulse, the end of the Vertical Front Porch is the leading edge of the first pulse

Positive

Vertical Sync

The second of three portions of the vertical blanking interval. This is often considered the true beginning of the frame.

A vertical sync pulse is defined to be a pulse that is longer than a horizontal blanking pulse (found on active lines).

Three types of vertical sync patterns are possible:

1) Commercial sync (typical for broadcast) that contains some number of equalizing pulses preceding sync pulses (in Vertical Front Porch); Vertical Sync, with serration pulses; equalizing pulses following sync pulses (in Vertical Back Porch).

2) Block sync (such as the Silicon Graphics standard high-resolution format) with a single long pulse that may span several lines. See Chapter 2 for a discussion of block sync

3) Military sync, which has no vertical synchronization pulses and simply has a period of time without active lines.

Each field contains exactly one Vertical Sync.

These choices are possible:

1) For commercial and block sync, the time of the leading edge of the first vertical sync pulse.

2) For military sync, the time of the first full line without active picture.

These choices are possible:

1) For commercial sync, the time of the beginning of the first whole line containing no vertical sync pulses (that is, long pulses).

2) For block sync, the beginning of the first line where the long sync pulse ends.

3) For military sync, the beginning of the first line containing active picture.

Negative

Vertical Back Porch

The third of three portions of the vertical blanking interval.

For formats that employ military sync (see definition in Vertical Sync), Vertical Back Porch has duration equal zero.

The end of Vertical Sync (see Vertical Sync).

These choices are possible:

1) If the format contains intra-line pulses (see Vertical Front Porch), the time of the first active video.

2) If the format does not contain intra-line pulses, the beginning of the first line containing active picture.

Positive

Field Active

The active portion of this field. It is the time in the field exclusive of the vertical blanking interval.

Each field contains exactly one Field Active portion.

The end of Vertical Back Porch (see Vertical Back Porch).

The beginning of Vertical Front Porch (see Vertical Front Porch).

Positive

Horizontal Front Porch

The first of three portions of the horizontal blanking interval containing the dead time preceding horizontal sync.

Each line contains exactly one Horizontal Front Porch.

The end of active video in the previous line.

The beginning of the horizontal sync pulse.

Positive

Horizontal Sync

The second of three portions of the horizontal blanking interval defined as the duration of time while the horizontal sync pulse is low. The time marks the point of the 50% crossing of the pulse.

Each line contains exactly one Horizontal Sync period.

The falling edge of the sync pulse (50% crossing).

The rising edge of the sync pulse (50% crossing).

Negative

Horizontal Back Porch

The last of three portions of the horizontal blanking interval, containing the dead time following horizontal sync. In composite formats, this is used for color burst.

Each line contains exactly one Horizontal Back Porch period.

The end of the horizontal sync pulse.

The beginning of active video.

Positive

Line Active

The active pixels in the line.

The time of the first active element.

The time of the last active element.

Positive

edge-transition-direction edge of board-signal-name

The time of the specified edge. This directive allows you to specify a transition that has a direction of 1) rising (low to high); 2) falling (high to low); or any (matches both rising and falling).

The transition refers to a change in the sense of a board signal. The transition must be defined prior to the execution of the range expression in which it is referenced; transitions are defined in: 1) the “set signal” statement (see

“The set signal Statement for Transitions”); or 2) in one of the special user signals, defined when the user employs the compiled language (see “The User Signals for Reference”).

The polarity corresponds to the sense of the transition. If the transition is a falling edge, the polarity is low; if the transition is rising, the polarity is high.

The time of the transition.

Same as start time.

Can be either. See Description

pulse-transition-direction pulse of board-signal-name

The time of the specified pulse. This directive allows you to specify a transition that has a direction of 1) positive (signal in high state); 2) negative (signal in low state).

For a discussion of how transitions are defined, see edge-transition-direction edge of board-signal-name.

The polarity corresponds to the sense of the pulse. If the pulse is positive-going, the polarity is positive; if the pulse is negative-going, the polarity is negative.

The time of the transition.

Same as start time

Can be either. See Description

time-expression

The specified duration. This allows you to specify an absolute duration as measured from the beginning of the frame.

If you specify an iterative time value that does not comprise exact whole-number units of the frame, the last time expression will be truncated to the time at the end of the frame. Put more simply, you will never get an end time past the end of the frame, even if the whole unit of time would properly set it past the end of the frame.

Consider i to be the number of iterations of the time expressions of duration d. The start time is

Can be either. See Description


Default Range

The default range is the name given to the range before any range selections are applied and is set to the entire frame. This is equivalent to setting the following range:

within each (frame) ...

Although not harmful, it is not necessary to use this construct.

Ranges That Do Not Fall on Whole-Unit Boundaries

Nested ranges always find the beginning and end of the whole unit for which they are defined. Examine this example, where Vertical Front Porch contains 10.5 lines and starts in the middle of a defined line of video. Watch what happens when the following statements are used:

within each (Vertical Front Porch)
    within each (line)
        ...

In the above example, the statement within each (Vertical Front Porch) would be repeated exactly 10 times, corresponding to the number of whole units (in this case, lines) contained within Vertical Front Porch. Because Vertical Front Porch begins on a half-line boundary, the first whole unit (line) begins half a line past the beginning of Vertical Front Porch.

In other words, nested ranges always round forward in time to the next whole unit.

The User Signals for Reference

The edge database contains the set of all transitions of signals from which the specific chip hardware is loaded. In addition to the signals defined in the board and chip definitions, the compiler defines several standard signals internally. These signals are defined either automatically when the user employs the high-level language, or manually if the user cites them using the line-based language

These signals can be referenced from within the hardware rules and should be used in preference to the signals that they alias; these signals do not automatically generate any other signal. For example (and most notably), you must produce the actual sync output from the board; the actual sync signal must be copied from the “User Sync” signal (this can be done trivially).

These signals represent a timing ideal that may differ from the actual representation on the hardware. For example, the user active signal is the time at which the active signal makes transitions during a line of video; however, the hardware may need to advance or delay the actual active signal output from the chip. By specifying the ideal time at which the transition should be made in the user signal, the rules may derive the chip time from the ideal.

User Sync Signal

The user sync signal is high when the signal is at blanking level, low when at sync level. Within the rules or the line-based language, you may refer to user sync.

User Blank Signal

The user blank signal is high when the signal is enabled (that is, the signal is high when blanking is enabled, low when blanking is disabled and pixels are displayed). Within the rules or the line-based language, you may refer to user blank.

The user blank signal aligns itself on whole lines, presuming a normal frame layout. This works correctly with the half lines of commercial sync and with the whole lines of block sync and military sync. If the source video format does not have its active area aligned with whole lines, you should not use the user blank signal; instead, reference the user sync signal directly (see “User Sync Signal”).

User Active Signal

The user active signal is high when the signal is enabled (that is, high when pixels are displayed). The distinction between user blank and user active is on those lines when active takes only one-half the line (for example, first lines of one field of NTSC and PAL): on those half lines, the duration of user active is the full line, while the duration of user blank is half-line. With this difference between the signals, those hardware platforms that must always fetch an entire line when requesting pixels may use both signals to create the distinction; those that can request partial lines may do so by referencing only the blank signal. Within the rules or the line-based language, you may refer to user active.

System-Defined Variables

The compiler defines several variables for your use. They take several forms:

Field Attribute Variables

These variables get their values from the attributes the user specifies for each field. The attributes and their definitions are in Table 5-3.

Each variable is an array with each element corresponding to a field. The array is zero-based, so the first field is in array element [0], the second in element [1], and so on. How many fields in the format? You can use the variable FieldsPerFrame (see Table 5-2) to find out.

Table 7-3. Field Attribute Variables

Name[a]

Data Type

Description

FieldLineCount

int

The number of lines in the field.

FieldLineOffset

int

The offset specified by the user.

FieldLineSkip

int

The skip specified by the user.

FieldSwap

boolean

Is true if swap enabled this field, false if not.

FieldColor

mask

Is 1 for red, 2 for green, 4 for blue (multiple values can be specified with inclusive-OR).

FieldEye

mask

Is 1 for left, 2 for right (multiple values can be specified with inclusive-OR).

[a] These names are shown without the array index. All have FieldsPerFrame elements.


Format Information Variables

These are useful only after frame analysis takes place, so you can use them in either rules definitions or post-processing operations.

Table 7-4. Format Information Variable

Name

Data Type

Description

SwapsPerFrame

int

The number of swaps per frame.


Built-In Functions

A limited number of functions are available to aid with writing rules.

Table 7-5. Functions

Function Name

Returned Data Type

Description

TransitionsDefinedOnSignal( board-signal-name )

Boolean

Returns true if the specified signal has any transitions already defined on it, false if no transitions were yet defined. Transitions may already be defined on the signal if the signals were user-defined signals (see “The User Signals for Reference”); or were defined with line-based language (see Chapter 8, “Line-Based Format Definition Language”). For a discussion of the use of this function, see “Anticipating Line-Based Definitions in the Rules”.

sec( time-expression )

float

Returns a floating-point value equal to the number of seconds in time-expression.


Examples of Writing Rules

Copying User Sync

It is often necessary to create a signal with the same shape as the sync signal provided by the user. Because the compiler provides the user sync signal as a predefined set of transitions in the database, you can easily copy the signal. You can read about the user sync signal in “User Sync Signal”.

Example 7-3. Copying the User Sync Signal


within each (edge of user sync) {
    set signal "CSYNC" CorrespondingPolarity at BeginTime;
}

To copy user sync to a signal named CSYNC, this example uses the each edge range expression; for information, see edge-transition-direction edge of board-signal-name in Table 7-2. For each edge of the user sync signal in the database, the range expression causes within to execute the set signal statement. The CorrespondingPolarity value copies the polarity of the user sync signal, while BeginTime sets the transition to the same time as the user sync signal (see “How You Can Use Range Information” for information on these variables).

Copying Another Signal With Changes

It is unusual to use another true signal with no changes at all (why would a hardware designer require two identical signals?). More often, some changes are needed to make a signal operate properly.

Example 7-4. Copying Another Signal With Changes


within each (rising edge of "IMPREG_LD") {
    set signal "XMAPREG_LD" high at BeginTime;
}
within each (falling edge of "IMPREG_LD") {
    set signal "XMAPREG_LD" low at BeginTime - 0.1 usec;
}
within each (positive pulse of "IMPREG_LD") {
    time pulseDuration;

    pulseDuration = (EndTime - BeginTime);

    if (pulseDuration < 1.0 usec)
        error "Insufficient IMPREG_LD pulse == " + pulseDuration;
}

The each rising edge range expression is similar to the copy operation shown in “Copying User Sync”, yet this expression discriminates by copying only half the edges (only the rising edges); for information, see edge-transition-direction edge of board-signal-name in Table 7-2. The time and polarity of XMAPREG_LD transitions match those of IMPREG_LD.

However, note the each falling edge range expression's set signal statement. The low transition of XMAPREG_LD is advanced by 0.1 usec; the new transition precedes the time of IMPREG_LD by that amount of time.

The last range expression, each positive pulse, performs error checking and has no set signal statement associated with it; see pulse-transition-direction pulse of board-signal-name in Table 7-2. This example shows checking the duration of a pulse (delimited by BeginTime and EndTime). If the pulse is too short, the compiler will issue an error message generated by the error statement; see “Diagnostic Statements”.

Calculating Scalar Variables

The example in “Copying Another Signal With Changes” showed calculation of a variable for detecting an error state. It is possible to calculate exported variables for later use as well (see “Variables”).

Example 7-5. Calculating Scalar Variables


{
    exported double HBackPorchClampStart;
    exported double HBackPorchClampLength;

    within (field active 1,1) {
        within (line 2,2) {
            time LineStartTime;

            LineStartTime = BeginTime;

            within each (Horizontal Back Porch) {
                time tBackPorchStart;
                time tBackPorchLength;

                tBackPorchStart = BeginTime - LineStartTime + 2 clocks;

                HBackPorchClampLength = sec(HorizontalBackPorch)/2;
                HBackPorchClampStart = 
                    sec(tBackPorchStart) + (HBackPorchClampLength/2);
            }
        }
    }
}

The code in Example 7-5 shows the definition and calculation of two variables: HBackPorchClampStart and HBackPorchClampLength. You can see the declaration of the variables is the first item within a compound statement delimited by curly brackets ({ }). Syntax requires you to declare items only at the beginning of a block.

Example 7-5 shows use of nested within statements. The innermost loop is defined as the horizontal back porch area of second line of the first field's active region of this format.

The exported length variable is calculated by determining the duration (in seconds) of the back porch using the sec function. The exported start variable also uses the tBackPorchStart variable, the calculated time position of the relative start location of horizontal back porch within a line.

Control Statements

You can use if, for and while statements to alter control flow to execute different sections of code. You can see their use in Example 7-6.

Example 7-6. Using Control Statements in Rules


{
    int nEdgeCnt = 0;

    /* check for serrations */
    within (Vertical Sync 1, 1) {
        within each (edge of user sync) {
            nEdgeCnt++;
        }
    }

    if (nEdgeCnt > 2) {
        /* we have serrations, so don't create transitions */
        signal "PLL_PHASE" initial state = high;
    } else {
        /* mask out vertical from the PLL's phase detector */
        signal "PLL_PHASE" initial state = low;
        within each (Vertical Sync) {
            set signal "PLL_PHASE" low  at BeginTime - 2.5H 
                ignoring wrap error;
            set signal "PLL_PHASE" high at EndTime + 2.5H
                ignoring wrap error;
        }
    }
}

The code in Example 7-6 performs different operations based on whether the user's sync signal contained serration pulses (see “The Vertical Interval”).

To determine whether the format has serrations, this code fragment counts the number of transitions (using the each edge range expression) in the first vertical sync region. Note that the variable nEdgeCnt is defined at the beginning of a compound statement because syntax requires variables be declared there; if this variable were not needed, the extra curly brackets ({ }) at the beginning and end of the example would probably not be needed.

If the format does have serrations, no signal transitions are defined—only the initial state is set. However, if the sync signal does have serration pulses, the two set signal statements are executed every vertical sync. The difference of 2.5 lines (2.5H) from the beginning and end of the vertical sync region puts the transitions beyond the beginning and end of the frame; therefore, the ignoring wrap error statement is needed to keep the compiler from issuing a warning for this circumstance (see “The set signal Statement for Transitions”).

Pre-Processing and Post-Processing Statements

These statements allow you to execute private functions needed to complete your format. You can define pre- and post-processing statements in any file. These statements are executed before and after the rules processing is performed, respectively.

The syntax of the statement is

preprocess { statement... }
postprocess { statement ... }

You may perform any processing you need within these statements. Moreover, you can have as many pre- or post-processing statements as needed; they are executed in the order the compiler encounters them.