Chip-Level Design Constraints in ALINT-PRO

Introduction

This application note will provide a basic overview of ALINT-PRO's available chip-level design constraints which can be used to describe clocks and resets behavior, timing constraints, and other properties at the overall system level necessary for later design development in synthesis and static timing analysis (STA) tools. ALINT-PRO directly supports reading the industry-standard SDC constraints descriptions, as well as extends it with additional commands to support defining clear intent on resets and clock domain crossings (CDC).

More on Design Constraints

As they are, Synopsys Design Constraints (SDC) provide intent when it comes to a design and provide additional specification on timing, clock tree structure, placement, and other characteristics, all to provide the best possible implementation of a circuit. Actual application of these design constraints can occur throughout the project lifecycle, however, some constraints are required before certain phases, such as providing timing constraints before moving to static timing analysis tools. When verifying if a design can run at a certain clock frequency, it is not enough to just look at the design's layout, as further information must be provided for that clock through additional design constraints, and this includes providing the clock frequency, I/O delays, false paths, multi-cycle paths, and other properties that drive synthesis, optimization, place & route, and other back-end design implementation tools.


SDC commands provide this type of specification, as well as the intent on areas outside of timing. There are, however, additional design considerations necessary when it comes to constraining a project. Like most EDA tool vendors, Aldec's own design constraints (ADC) are a superset of SDC commands, and they provide an expansion on SDC commands to fulfill this same intent on additional areas including resets, clock domain crossings, and more. Not only do these constraints, along with the traditional SDC commands, provide the necessary information for later tools, but they also provide ALINT-PRO with the necessary information that allows for a more comprehensive linting process guided by a clearly expressed designer's intent. As such, the writing of these constraints can start here.

Both SDC command and Aldec Design constraints (ADC) help describe the chip-level characteristics of a design


Chip-Level Design Constraints

Just like the tool's block-level design constraints, ALINT-PRO's design constraints at the chip level are a set of TCL commands providing additional description of various design properties. At the chip-level, these constraints will affect the clock and reset trees for the complete chip hierarchy, providing a more holistic description of clock and reset relations that are not observable from the topology alone. Obviously, some of the specification-driven decisions like external asynchronous interfaces, virtual clocks, or static choices of operational modes cannot be extracted automatically from the netlist itself, and require explicit input from the designer in the form of design specification. This additional specification of intent therefore allows a more comprehensive linting process, which otherwise would create too much noise in reports. As is the case with other design constraints, the commands mentioned in this application note should be specified in one or more Aldec design constraint (.adc) files and should be included in the relevant project as a regular source file.


Chip-level design constraints can be divided into two groups:

  • Chip-level fetchers - these commands are used to retrieve information from the design and include: get_clocks, get_resets, get_paths, get_pins, get_ports, get_nets, get_cells...

  • Chip-level actions - these commands are used to specify characteristics of the design and include: create_clock, create_reset, set_clock_groups, set_input_delay, set_false_path, set_quasi_static...


Additionally, we can characterize these commands into the following relationship between Synopsys Design Constraints and Aldec Design Constraints. Here, the Synopsys Design Constraints provide a subset to our Aldec Design Constraints, as the ADC commands will provide additional intent on those areas outside of SDC, such as resets and CDC/RDC.

Clocks

Perhaps the most basic usage of chip-level constraints is the description of clocks and their properties. Clocks are defined and specified for proper synthesis and analysis in later design tools, and the writing and application of those description can begin here. The first step in providing timing constraints for a given design hierarchy is the creation of clocks, and this action is supported by the create_clock command:


create_clock -period <value> [-name <clock_name>] [<source_objects>] [-f <list_file>]


This command accepts the period of the newly created clock which can be provided in the form of time or frequency by specifying the relevant unit (s, ms, us, ns, or ps in the case of time input, and Hz, KHz, MHz, GHz, or THz in the case of frequency input). When generated, the default assumed clock period is 10ns if not explicitly specified. Source objects can also be specified by providing a list of pins and ports within the design from which the clock originates. In addition to the clock's timing and source specifications, the clock object can be provided a name to be referred to elsewhere in design constraints.

create_clock -name CLK_30MHz -period 33.33 [get_ports TOP/CLK_A]
create_clock -name CLK_50MHZ -period 50mhz [get_ports TOP/CLK_B]


The example above describes two separate constrained clocks: CLK_30MHz, and CLK_50MHz. In the case of CLK_30MHz, no unit is specified within the -period argument and thus ns is assumed for the provided 33.33 value. This clock will reference the CLK_A signal within the design. For CLK_50MHz, the unit of MHz is passed within the -period argument and therefore this clock is specified to run at 50 MHz directly. This clock references the CLK_B signal within the design.

NOTE: When writing clock constraints, the option of passing a frequency in place of a period is nonstandard in common SDC syntax, and is only supported within ALINT-PRO for compatibility with other tools (Intel TimeQuest for example).


Not all clocks constraints have to reference a source, and this is the case when describing virtual clocks. Virtual clocks are used to represent external clocks relative to the chip, and once defined, they can be used to set up proper timing of some I/O delays, which will be expanded on later. For now, it is useful to know that clocks may be described with or without source objects, depending on their application.


Once clocks have been established, a fetcher command (Aldec extension) can be used to verify and analyze existing constraints or those clock signals still in need of constraints. The fetcher command for clocks is get_clocks:


get_clocks [-unconstrained] [-properlyconstrained] [-overconstrained] [-filter <boolean_condition>] [<patterns>] [-f <list_file>]


Unlike the action commands, these commands are not written to Aldec constraint files as they are not setting constraints themselves. Instead, these commands are used within scripts or at command lines to print information on chip-level properties. The fetcher command for clocks allows for filters specified by common TCL syntax. Additionally, options exist for printing unconstrained, properly constrained, and over constrained clocks are available as well. The explanation for these are the following:

  • Unconstrained: prints clock constraints that are automatically detected by the tool but not specified within the project constraint files.

  • Properly Constrained: prints clock constraints that are automatically detected by the tool and are currently specified within the project constraint files.

  • Over Constrained: prints clocks constraints that are not detected by the tool but are currently specified within the project constraint files.


For example, running the get_clocks command in the same project as the previous create_clocks example would provide the following output:

get_clocks
# CLK_30MHz CLK_50MHz


As shown with the fetchers commands for block-level constraints, these commands can also be paired with the report_attributes command to print relevant statistics on the passed clocks.

report_attributes [get_clocks clk_50mhz]
# type:          clock
# name:          clk_50mhz
# phase_shift:   0
# period:        20 ns
# generated:     false
# virtual:       false
# combinational: false
# sources:       TOP/clk_50mhz
# autodetected:  false


If running get_clocks by itself and without any additional switches, this command will operate identically to the all_clocks fetcher command which, when ran, displays all detected clocks within the design to console.

Generated Clocks

Similar to the regular variant, a generated clock describes those originating from a master clock. When a master clock is applied in this way, the resulting clock can undergo modifications, and through the create_generated_clock command, these transformations can be specified through a number of switches:


create_generated_clock -source <master_source> [-master_clock <clock_name>] [-divide_by <divide_by>] [-multiply_by <multiply_by>] [-invert] [-combinational] [-name <name>] <source_objects> [-f <list_file>]


Within this command, the pin source and optional master clock name is specified. Through the -multiply_by and -divide_by switches, the frequency changes can be automatically applied relative to the master clock, either increasing or decreasing the frequency by some factor. Additionally, the clock phase can be completely inverted using the -invert switch. To indicate that a generated clock is propagated from combinatorial logic, the -combinational switch may also be used. By applying these switches, these generated clocks take on the specifications according to their source, and thus when a master clock is modified, its generated clocks will still retain their correct descriptions relative to that master.


When working with a setup like this, it is a good idea to just define the master clocks, as ALINT-PRO can automatically derive generated clocks by looking at the generator's instance in most cases. The tool will automatically extract the correct frequency and phase relations depending on a specific FPGA primitive for example, and those descriptions can be applied during constraint generation (covered later in this document). It is only in the cases of custom clock generation circuits that specific phase and frequency relations for generated clocks may need to be written manually.

Resets

In addition to clocks, resets can also be specified using the create_reset command. Where create_clock is a standard SDC command, the reset equivalent is part of Aldec's own expansion on design constraints. The syntax for this command is as follows:


create_reset -polarity <polarity> [-rise_clock <rise_clock>] [-fall_clock <fall_clock>] [-clock <common_clock>] [-name <name>] [-type <type>] <source_objects> [-f <list_file>]


This command describes a reset signal within the design hierarchy, and can specify both synchronous and asynchronous type signals. When a clock is provided via the -clock switch, the reset will be synchronous to that provided clock signal. In the case that a reset is asynchronous within the design, no -clock switch is necessary. Additionally, asynchronous clocks with de-assertion synchronized may be described as well through the -rise_clock and -fall_clock switches. Both options here will describe the reset with the one relevant edge synchronized. If no clock switches like -clock, -rise_clock, or -fall_clock are specified, that means the reset is fully asynchronous ,which is frequently an independent externally driven master reset signal that requires internal synchronization within the chip before it is used. Finally, just as is the case with the clock creation design constraint, the sources of the reset signal can be specified and a name for future reference can be provided during reset creation.


As was the case with clocks, a fetcher command exists for resets as well in the form of get_resets:


get_resets [-filter <boolean_condition>] [<patterns>] [-f <list_file>]


This command works just like its clock counterpart, allowing for filtering of specific reset signals. Additionally, this command also acts as the input for report_attributes to provide a more detailed report on the signal. Utilizing this fetcher command (along with report_attributes) on the "GEN_RES" reset of the blackjack_vhdl sample design within ALINT-PRO, we would expect the following output:

report_attribures [get_resets GEN_RES]
# type:          reset
# name:          GEN_RES
# polarity:      active-high
# inverted:      false
# combinational: false
# sources:       bjack/GEN_RES
# autodetected:  false


Generated Resets

Just like the case with clocks, reset generators can create signals controlled by master resets. Constraints for generated resets allow setting these signals relative to their master, with these changes being characterized by the command's switches. The create_generated_reset command is used according to the following, and is another command belonging to the Aldec Design Constraints category:


create_generated_reset -source <master_source> [-master_reset <reset_name>] [-invert] [-combinational] [-rise_clock <rise_clock>] [-fall_clock <fall_clock>] [-clock <common_clock>] [-name <name>] <source_objects> [-f <list_file>]


Once again, the generated reset's master is defined within this specification by source pin and optional reset name. The reset may be inverted, as well as marked as generated through combination logic, through the relevant switches. The clock relations for the generated clock can then be set similar to regular resets using those same -clock, -rise_clock, and -fall_clock switches. Similar to the case of clocks, these generated resets will only be explicitly required from the user when custom reset generation circuits are used, as simple generators such as inverters, gates, or 2DFF-based reset deassertion synchronizers can be automatically derived from the tool during constraint generation.

Clock Groups

In the case of clock domain crossing (CDC) within a design, it is important to specify the relationships between clocks in terms of their synchrony between each other. This is necessary in multi-clock designs as the constraints here will explicitly lay out the different domains existing within the design. Any crossings between these domains can cause unexpected issues without proper synchronization down the road and it is therefore important to declare how these clock groups relate to each other through additional Aldec design constraints. These clock groups can be created via the set_clock_groups command:


set_clock_groups {-group <clock_list>} ... [-logically_exclusive] [-physically_exclusive] [-asynchronous] [-f <list_file>]


Clock groups are specified to be asynchronous by providing the -asynchronous switch followed by a list of clock groups. The separate groups are asynchronous to each other while those clocks within a single group are considered to be synchronous, thus forming a list of clock domains.

create_clock -period 100 [get_ports TOP/CLK_A]
create_clock -period 200 [get_ports TOP/CLK_B]
create_clock -period 150 [get_ports TOP/CLK_C]
set_clock_groups -asynchronous -group {TOP/CLK_A TOP/CLK_B}
set_clock_groups -asynchronous -group {TOP/CLK_C}


In the example constraints above, CLK_A and CLK_B will be considered synchronous to each other as they are both grouped within the same clock list. Because CLK_C is grouped within a different list, however, it will be considered asynchronous to the CLK_A/CLK_B clock domain.


Additionally, this command is used to describe whether clocks groups are logically exclusive or physically exclusive to each other, which is specified by including the relevant switches. When clocks are logically exclusive, there are no functional paths existing between them, but may still have coupling interactions with each other as those clocks can still exist within the design at the same time. Alternatively, physically exclusive clocks cannot both exist within a design. Multiple clocks sharing the same source pin would be an example of this as only one clock can be physically active at a time. These switches, along with the -asynchronous switch, are mutually exclusive.

Clock Detection Modes

A noticable difference with typical STA tools is that ALINT-PRO is more pessimistic about clock relations by default. Most STA tools assume all clocks are synchronous, unless the user indicates otherwise. To set these relations, ALINT-PRO has a customizable default clock group assignment policy which can be set according to the following:

  • Optimistic Mode: every generated clock will belong to the same group as its master clock.

  • Default Mode: every generated clocks which is inverted or has had its frequency divided by a power of 2 will belong to the same group as its master clock

  • Pessimistic Mode: any generated clock that has been transformed, except in the case of buffers, is a new clock domain, and will not belong to the same group as its master clock.

  • STA Mode: assume all clocks are synchronous, like in static timing analysis tools.


Optimistic mode is typically chosen by FPGA designers, unless they utilize advanced PLL/MMCM features like non-integer frequency fractions, complex phase, or duty cycle shifts. Alternatively, ASIC designers will typically go with Default or Pessimistic modes, depending on the design requirements. In all cases, confirming the intent with explicit declarations of clock groups is highly recommended to achieve portability between all design and verification tools.

I/O Delays

In static timing analysis and back-end synthesis tools, it is important to specify the data arrival time at the input/output ports relative to a specified clock, as it drives design optimization, placement, and routing. While the exact delay is not important for CDC checking, the other aspect of these constraints, that is setting input and output ports relative to their clocks, will ensure comprehensive analysis and linting when it comes to clock domain crossings as it explicitly declares just which clock domains that ports fall under. Timing constraints for inputs and outputs relative to clocks can be described by the following commands:


set_input_delay -clock <clock_name> [-rise] [-fall] [-clock_fall] [-add_delay] <delay> <objects> [-f <list_file>]
 
set_output_delay -clock <clock_name> [-rise] [-fall] [-clock_fall] [-add_delay] <delay> <objects> [-f <list_file>]


Each command receives the reference clock, timing delay, and input/output ports as its input as well as some optional arguments. To specify whether a delay is applied to just the rise time or just the fall time of the signal, the relevant -rise and -fall arguments should be included within the command. If neither argument is used then the delay will be applied to both transitions. The -clock_fall argument is used to describe when a delay pertains to the falling edge of the clock.


For example, suppose the constraints for a project are the following:

create_clock -period 100 -name CLK_100MHz [get_ports DFF/CLK]
set_input_delay -clock CLK_100M -add_delay 5 [get_ports DFF/D]


Through the set_input_delay command here, the port D of DFF is specified to be within the CLK_100MHz domain and includes a delay of 5 ns. These properties can be verified by reporting the attributes of the port:

report_attributes [get_ports D]
# type:                    port
# name:                    DFF/D
# direction:               in
# clock_domain:            CLK_100MHz
# rising_edge_sampled_by:  CLK_100MHz
# falling_edge_sampled_by: CLK_100MHz


Note that both the rising and falling edge here are sampled by CLK_100MHz due to the exclusion of the those -rise and -fall arguments.


In the case that an input is asynchronous to all chip clocks, it is a good idea to set that clock relative to a virtual clock, which once again is a clock existing outside of the chip. By doing so, proper domain handling of asynchronous ports can be achieved, resulting in a safer CDC analysis of a design.

Another example of IO delays for ports belonging to separate clock domains


Just as inputs and outputs are set relative to clocks, they are also controlled by resets and therefore can be set relative to these signals as well. This type of specification is an extension to standard SDC descriptions for input and output constraints, which could be necessary for designs with complex reset strategies, and is provided by the set_input_reset and set_output_reset commands which are of the Aldec design constraints:


set_input_reset -reset <reset_name> [-add_reset] <objects> [-f <list_file>]

set_output_reset -reset <reset_name> [-add_reset] <objects> [-f <list_file>]


Similar to the clock case, this command receives the reset signal which the passed port depends on. If adding multiple resets, the -add_reset switch can be used to prevent overwriting any current constraints. By providing this specification, ports are tied to their relevant reset dependencies, and this information will be appropriately updated in attribute reports.

Set False Path

In some cases, it is necessary to prevent STA/synthesis tools from analyzing and performing timing optimization across certain paths, thus removing the tool's effort of having to fit that path within the timing budget. Such cases for this include the outputs of quasi-static signals, paths within some clock domain crossings, internal synchronization of asynchronous resets, or perhaps input ports which are read by multiple domains (in which case that port can safely be synchronized with clocks using input delay constraints). Additionally, specifying a set_false_path constraint is necessary for external, fully asynchronous, reset paths. In any case, the resulting linting errors can be avoided through design constraints, and this type of directive is created with the set_false_path command:


set_false_path [-from <from_list>] [-to <to_list>] [-through <through_list>] [-f <list_file>]


Similar Aldec design constraints exist for setting exemptions for crossings across clock and reset domains, as well. When set with the following commands, these paths will be marked false for any CDC or RDC verifications, and thus will not even be treated as crossings across different domains. To enable false CDC or RDC paths, the following set_cdc_false_path and set_rdc_false_path commands are used:


set_cdc_false_path [-from <from_list>] [-to <to_list>] [-through <through_list>] [-f <list_file>]

set_false_path [-from <from_list>] [-to <to_list>] [-f <list_file>]


In any of these cases, a false path is set by providing starting points, ending points, and sometimes through points. A starting point in this context describes any combinational paths originating from the passed pins, ports, cells, or clocks which are passed via the -from switch. Similarly, ending points provide the paths terminating at the passed pins, ports, cells, or clocks and are passed via the -to switch. Note that, when specifying a clock, all points within that domain will be considered as the starting or ending points. In the case of set_rdc_false_path, these -from and -to switches here point to the starting reset point or ending reset point of the desired crossing. The through points work much the same way as the normal -from and -to switches, simply returning any paths passing through that point and is specified by the switch of the same name. By combining these arguments, specific paths can be described when wanting to mark any nets, pins, or cells within those paths as false for CDC or RDC analysis.

An additional fetcher command that is useful here in identifying these types of paths is the get_paths command which shares a similar syntax:


get_paths [-from <from_list>] [-to <to_list>] [-through <through_list>] [-f <list_file>]


As was the case with the action commands, these paths are described via setting starting points, ending points, and through points. Any paths matching those cases will be returned to console, providing a useful debugging mechanism showing what paths the tool currently sees. Running the command itself, with no argument, will display all existing paths.

Set Max Delay

When it comes to static timing analysis, maximum delays along paths are set to inform place and routing tools that certain points are to be positioned close enough to prevent timing errors. For CDC purposes, this is useful for maintaining the timing within synchronizers, as placing these maximum delays at those registers will ensure the integrity of synchronization at clock domain crossings. To describe max delays, the following constraint is used:


set_max_delay [-from <from_list>] [-to <to_list>] [-through <through_list>] <delay_value> [-f <list_file>]


Just like previous path-specific commands, the syntax of this constraint works by providing those same -from, -to, and -through points to describe subsets of timing paths. While a delay value is needed once it comes to synthesis, for linting purposes that argument can safely be ignored.

Set Case Analysis

When dealing with multiplexers and other types of logic for selection between multiple clock signals, or other control modes, complex netlists can be generated which effect clock and reset detection, clock domains and reset domains partitioning, CDC and RDC paths extraction, and more. To simplify analysis via considering just one case at a time, constraints can be used to describe different cases within the logic. These cases define a value for a port or pin within the design and this value gets propagated throughout the implemented logic. Cases can be set with the following command:


set_case_analysis <value> <port_or_pin_list> [-f <list_file>]


All that is needed to be passed to the command here is a value (either 0 or 1) and the relevant port or pins. Once implemented, that value is propagated throughout the design, and any netlist analysis will reflect this propagation. This is especially useful for testing different modes within a design, as the controlling signal for a particular state can be set before netlist analysis. For example consider an example utilizing multiple clocks which are selected via a multiplexer:

Without any case selection, the output of the multiplexer generates a muxed clock domain as it is driven by the A and B clocks. By setting the controlling SEL signal to the value of 0 via case selection, analysis can then be performed within the context of the clock A mode only, as clock B essentially gets cut out of the design in terms of clock/reset detection or clock/reset domain partitioning. By running analysis on individual cases separately, a full verification of all configurations is achieved.

Set Quasi-Static

In cases when a signal is to remain somewhat constant, they can be considered exempt from certain analyses such as clock domain crossing. This is often used in cases of directly enable-controlled signals for example, which are not expected to change often during operational mode. Because these types of signals remain somewhat constant, they are not as susceptible to the issues of clock domain crossings and therefore can be marked false for that type of analysis. These types of signals are described via another one of Aldec's own design constraint commands, the set_quasi_static command:


set_quasi_static <source_objects> -enable <enable_objects> [-polarity <enable_polarity>] [-f <list_file>]


This command works by simply providing the source of the signal one wishes to set as quasi-static by providing ports, pins, or even black box units. The controlling enable signal can then be specified via the -enable switch. From here, the polarity of the quasi-static signal can also be provided via the -polarity switch. Should this optional argument not be provided, the default active-high state will be assumed.

Writing Constraints

While constraints can be written in any editor and then associated with a project by adding that file to the project resources, they may also be applied automatically through console or scripts. Before constraints can be written in this manner, however, a primary constraints file must first be specified via the project properties. To access these properties, either right click on the project within the Project Manager window and select "Properties" or simply press Alt+Enter to access the properties of the current active project. From the project properties window, under the "Constraints" tab, the primary constraints file can be specified at the "Save constraints commands to: " option. Below we can see the "chip-constraints.adc" is set as this project's primary constraints file:

Now whenever constraints are written to console, or when constraints are parsed via scripts, those constraints will automatically be applied to this primary .adc file.

Generating Constraints

What's even easier than writing constraints is having the tool generate them automatically. Through the use of the project.generate.constraints command, constraint descriptions for our clocks, resets, and more can all be automatically detected and written to a nicely formatted file. The command is as follows:


project.generate.constraints [-existing] [-existing_commented] [-derived] [-derived_commented] [-suggested] [-suggested_commented] [-sdc] [-adc] [-clocks] [-clock_groups] [-delays] [-timing_path_exceptions] [-false_paths] [-multicycle_paths] [-min_delay_paths] [-max_delay_paths] [-false_paths_for_async_ports] [-false_paths_for_cdc] [-max_delays_for_async_ports] [-max_delays_for_cdc] [-max_delays_for_synchronizers] [-async_reg_for_synchronizers] [-synchronizer_identification] [-resets] [-reset_io] [-block_level] [-description <description>] [-attention] [-flavor <constraints_flavor>] [-project <project_name>] -file <file_path> [-f <list_file>]


As shown, the command includes numerous switches that allows for generation of many different types of constraints. These different switches can be combined to form generated files covering different areas of your design. To help with this, there are even a few combinational switches which maximizes generation of different constraint areas with simpler syntax. The -adc switch here, for example, will generate constraints for all detected clocks, I/O delays, clock groups, and resets. On the other hand, the -sdc switch will only generate the content that is within the SDC subset and will likely be accepted by other EDA tools. Additionally, constraints support vendor-specific flavors, which attempt to take syntax and hierarchical path differences between the target tools into account.At the execution of this type of command, all relevant automatically detected constraints, according to provided switches, will be applied to the provided .adc file.


Consider the following example:

module TOP(clk_100mhz, clk_50mhz, rst, en_a, en_b, d_in, d_out);
  input  clk_100mhz;
  input  clk_50mhz;
  input  rst;
  input  en_a;
  input  en_b;
  input  [7:0] d_in;
  output [7:0] d_out;

  wire [7:0] d_a;
  wire [7:0] d_b;

  SYNC SYNC_inst
  (
    .clk(clk_100mhz),
    .in(d_a),
    .out(d_b)
  );

  DFF8 DFF8_a
  (
    .clk(clk_50mhz),
    .clr(rst),
    .en(en_a),
    .d(d_in),
    .q(d_a),
  );

  DFF8 DFF8_b
  (
    .clk(clk_100mhz),
    .clr(rst),
    .en(en_b),
    .d(d_b),
    .q(d_out),
  );

endmodule


This project utilizes multiple clocks within its design, thus introducing the problem of possible clock domain crossing (CDC) issues. To ensure ALINT-PRO can fully lint the design to catch issues pertaining to this, we must introduce constraints to provide the information not available from just the topology of the design. Should we run the command get_clocks, we would expect an output similar to something like:

get_clocks
# clk_100mhz clk_50mhz


As you may recall, this prints all the detected clocks within the design, and in this case clk_100mhz and clk_50mhz are returned. Now we know where in our design constraints will be needed as a result of that fetcher command. From here you can either write the constraints manually, or we can have the tool generate them instead. Should we want to save our clocks, we can simply execute the command like so:

project.generate.constraints -clock -file generated_constraints.adc


This will generate a new file, generated_constraints.adc, and it will look something like this:

As expected, the relevant clock constraints were generated for the design. Note that due to the naming convention of the signals within the design, the tool was able to correctly generate the correct periods for each constraint. In cases where the period cannot be guessed based off signal name, however, the tool will default to a period of 100 ns.


Of course we could have generated much more than just the clock constraints. By adding additional switches, the same organized formatting could have been applied to resets, I/O delays, and more. Once any and all commands are generated, however, they may then be edited to fit specific project requirements and then copied over to the project's resource .adc file or the file here may simply be added to the project as well.

An example on generated clock I/O design constraints


In any case, these generated constraints help cut down on the actual writing process of commands, as well as providing the additional benefit of automatically detecting where in a design constraints are required. For additional information on generating constraints, please refer to the command's reference documentation.

More On Constraint Fetchers

While some of the fetcher type constraint commands have already been shown along with some of their accompanying action commands, more still exist which can help debug and provide more information on the design to the user. Having covered get_clocks, get_resets, and get_paths, more fetcher commands are available:

Additional Fetcher Commands

all_clocks

Returns all design clocks.

all_inputs

Returns all input ports of the current top-level instance.

all_outputs

Returns all output ports of the current top-level instance.

all_blackboxes

Returns all black box cells or pins of the current instance.

all_inouts

Returns all inout ports of the current top-level instance.

all_registers

Returns all register cells or pins of the current instance.

all_cells

Returns a list of cells matching the specified pattern. The search is performed relatively to the current instance.

get_nets

Returns a list of nets matching the specified pattern. The search is performed relatively to the current instance.

get_pins

Returns a list of pins matching the specified pattern. The search is performed relatively to the current instance.

get_ports

Returns a list of ports matching the specified pattern. The search is performed for ports of the current top-level instance.

get_clock_domain_crossings

Prints pairs of netlist objects (ports/pins) between which clock domain crossing occurs.

get_clock_domains

Returns a list of clock domains detected in the project. This command may be used to check whether clocks (either automatically detected or explicitly constrained) are properly divided by clock domains.

get_clock_groups

Returns a list of groups of asynchronous clocks (clocks that belong to asynchronous domains) detected in the project.

get_rdc_schemes

Returns a list of detected synchronization schemes used to resolve metastability on RDC paths.

get_wide_rdc_schemes

Returns a list of wide RDC schemes detected in the design that match the specified pattern.

get_reset_domain_crossings

Prints pairs of netlist objects (ports/pins) between which reset domain crossing occurs.

get_reset_domains

Returns a list of reset domains detected in the project. This command may be used to check whether resets (either automatically detected or explicitly constrained) are properly divided into reset domains.

get_synchronizers

Returns a list of synchronizers detected in the design that match the specified pattern.

get_wide_synchronizers

Returns a list of wide synchronizers detected in the design that match the specified pattern.

These commands all return their relevant design elements and, outside the "all"-type commands include some form of filtering for finer control of their output. Similar to the previous fetcher commands, using these to pass specific design elements to the report_attributes command will provide a more detailed report on the relevant element. Through fetchers commands, more information can be obtained from the design and its chip-level characteristics. Among other uses, they provide the information that the tool currently has, thus allowing a designer to not only develop but verify if their design is properly constrained. For a more in-depth look at each individual fetcher command along with their relevant arguments, please refer to the command reference guide of ALINT-PRO, accessible through Help в†’ Command Reference of the ALINT-PRO menu bar.

In fact, all constraints and commands covered in this document can be found here and can be referenced if unsure on a particular command's operation. Along with a description of the command, examples are provided as well.

Summary

Overall, chip-level constraints allow for a more complete linting process by providing the desired specification that are not always immediately available from the design layout itself. Additionally these constraints are useful for later development in the design flow, during synthesis and static timing analysis, and their generation can start here. Through numerous console commands, specifications can be automatically written to provide the foundation for those design constraints.

Ask Us a Question
x
Ask Us a Question
x
Captcha ImageReload Captcha
Incorrect data entered.
Thank you! Your question has been submitted. Please allow 1-3 business days for someone to respond to your question.
Internal error occurred. Your question was not submitted. Please contact us using Feedback form.