WHKEg QWR Yg Ok Ycnv
WHKEg QWR Yg Ok Ycnv
WHKEg QWR Yg Ok Ycnv
www.aldec.com
This page is intentionally left blank.
Table of Contents
Chapter 1 Basic Design Constraints.......................................................................................................8
1.1.1 Basic naming conventions...................................................................................................8
STARC_VLOG 1.1.1.1 ...........................................................................................................8
STARC_VLOG 1.1.1.2 .........................................................................................................10
STARC_VLOG 1.1.1.3 .........................................................................................................12
STARC_VLOG 1.1.1.4 .........................................................................................................13
STARC_VLOG 1.1.1.5 .........................................................................................................14
STARC_VLOG 1.1.1.6 .........................................................................................................15
STARC_VLOG 1.1.1.7 .........................................................................................................16
STARC_VLOG 1.1.1.8 .........................................................................................................18
STARC_VLOG 1.1.1.9 .........................................................................................................20
STARC_VLOG 1.1.1.10 .......................................................................................................22
1.1.2 Naming conventions of circuit and port names should be considered by the hierarchy.....23
STARC_VLOG 1.1.2.1 .........................................................................................................23
STARC_VLOG 1.1.2.2 .........................................................................................................25
1.1.3 Give meaningful names for signals....................................................................................26
STARC_VLOG 1.1.3.1 .........................................................................................................26
1.1.4 Naming conventions of include file, parameter and `define (different from VHDL)............27
STARC_VLOG 1.1.4.1 .........................................................................................................27
STARC_VLOG 1.1.4.2 .........................................................................................................31
STARC_VLOG 1.1.4.3 .........................................................................................................33
STARC_VLOG 1.1.4.4 .........................................................................................................34
STARC_VLOG 1.1.4.5 .........................................................................................................36
1.1.5 Naming should consider clock systems.............................................................................38
STARC_VLOG 1.1.5.1 .........................................................................................................38
1.2.1 Clock synchronous design.................................................................................................40
STARC_VLOG 1.2.1.1 .........................................................................................................40
STARC_VLOG 1.2.1.2 .........................................................................................................42
STARC_VLOG 1.2.1.3 .........................................................................................................44
1.3.1 Use asynchronous reset for initial reset.............................................................................47
STARC_VLOG 1.3.1.2 .........................................................................................................47
STARC_VLOG 1.3.1.3 .........................................................................................................49
STARC_VLOG 1.3.1.5 .........................................................................................................51
STARC_VLOG 1.3.1.6 .........................................................................................................52
1.3.2 Reset line hazards.............................................................................................................54
STARC_VLOG 1.3.2.1 .........................................................................................................54
STARC_VLOG 1.3.2.2 .........................................................................................................56
1.4.3 Gated clocks should be used with special care.................................................................58
STARC_VLOG 1.4.3.2 .........................................................................................................58
STARC_VLOG 1.4.3.4 .........................................................................................................60
STARC_VLOG 1.4.3.5 .........................................................................................................64
STARC_VLOG 1.4.3.6 .........................................................................................................67
1.5.1 Consider metastable issues in signals between asynchronous clocks..............................69
STARC_VLOG 1.5.1.1 .........................................................................................................69
STARC_VLOG 1.5.1.2 .........................................................................................................75
STARC_VLOG 1.5.1.3 .........................................................................................................78
1.7.1 Considerations for using both ASICs and FPGAs.............................................................80
STARC_VLOG 1.7.1.1 .........................................................................................................80
Chapter 2 RTL Description Techniques................................................................................................82
2.1.1 Use always constructs and function statements correctly..................................................82
STARC_VLOG 2.1.1.2 .........................................................................................................82
2.1.2 Define combinational circuits using the function statement...............................................84
STARC_VLOG 2.1.2.1 .........................................................................................................84
STARC_VLOG 1.1.1.1
RULE NAME File names should be as follows: ”<module name>.v”.
Single file should contain single topmost-level module with the same name.
DETAIL-1 Name “{TopName}” of the topmost-level module differs from the file
“{FileName}” name.
DETAIL-2 Name of the topmost-level module “{TopName}” matches to file name, but this
module is described along with another topmost-level modules. Multiple
MESSAGE
modules can be included in a file only in case when they have a tree
hierarchical structure.
DETAIL-3 Topmost-level module “{TopName}” is detected.
DETAIL-4 Topmost-level module “{TopName}” is detected. Multiple modules can be
included in a file only in case when they have a tree hierarchical structure.
Names that make debugging more efficient should be carefully chosen. They help to understand
project structure because if different naming conventions are used by different designers, circuits
that were divided into sections by multiple designers will be difficult to understand when they are
integrated.
PROBLEM
A single file should contain a single module, but this is unfit for a large design with many files
DESCRIPTION since it becomes difficult to handle. In this case, multiple modules can be included in a file, but
modules which have no relation to one another should not be included in the same file. A single
file should include modules which have a tree hierarchical structure. The top module name and
file name should be the same.
LEVEL RECOMMENDATION 2
Checker detects all topmost-level modules between described in the translation unit hierarchy:
– if there is a single topmost-level module in the translation unit and its name differs from
the name of the file => violation (detail-2);
– if primary module is described along with another topmost-level module(s) in the
translation unit:
– if one of topmost-level modules has the same name as translation unit => violation
CHECKER
(detail-2 + detail-3);
BEHAVIOR
– if there is no topmost-level module with the name that is equal to the translation unit
name => violation (detail-4).
Note-1: translation unit is a source file specified for compilation session (for example: alog ram.v)
and it can include another files (content of such files is considered as part of current translation
unit).
Note-2: name comparison is case sensitive.
//file top1.v
Single file should contain single -level module w ith the same name.
`include “top2.v”
module top1;
Name of the topmost-level module “top1” matches to file name, but this
... module is described along w ith another topmost-level modules.
Multiple modules can be included in a file only in case w hen they have
endmodule a tree hierarchical structure.
//file top2.v
end
//file top.v
...
endmodule
module ff ( clk, d, q );
...
end
MESSAGE-2
{ObjectClass} name “{ObjectName}” is an escaped identifier. Try not to use
escaped identifiers in pure Verilog designs.
MESSAGE-3 {ObjectClass} name “{ObjectName}” matches forbidden pattern “{RegExp}”.
MESSAGE-4 {ObjectClass} name “{ObjectName}” does not match legal pattern “{RegExp}”.
Object identifiers must facilitate understanding the function of the underlying HDL description
especially if multiple designers work on a project. Therefore, it is recommended to use consistent
naming conventions.
PROBLEM
In case of Verilog-HDL, any characters or keywords can be used if an escaped identifier is used.
DESCRIPTION However, it is impossible in VHDL(87) and problems may occur later in the design flow. That is
why it is not recommended to use symbols other than alphanumeric characters and the
’_’(underscore) or to use escaped identifiers.
LEVEL RULE
CHECKER Checker verifies names of each object and provides built-in checks which activated via
BEHAVIOR DEFAULT_CHECKS parameter:
– if DEFAULT_CHECKS == “1” built-in checks are activated:
– if the name does not satisfy requirements that only alphanumeric characters and
the underscore '_' should be used, and the first character is a letter and it is not an
escaped identifier => violation (message-1);
– if the name is an escaped identifier => violation (message-2);
– if DEFAULT_CHECKS == “0” built-in checks are not performed.
Checker provides also mechanism for regular expression-based checking:
– if REGEXP_MATCH == “deny” and object name matches forbidden pattern => violation
(message-3);
– if REGEXP_MATCH == “allow” and object name does not match legal pattern =>
violation (message-4).
Note-1: if an escaped identifier is a simple identifier and is not a Verilog keyword => no violation.
Note-2: following parameters are supported by the checker:
– parameter DEFAULT_CHECKS defines whether to perform standard checks: “1” means
yes (default), “0” means no;
– parameter REGEXP_MATCH controls custom regular expressions checking:
– “deny” - warnings are issued on matched identifiers;
– “allow” - warnings are on unmatched identifiers;
– empty string (“”) - do not perform regular expression matching (default);
– REGEXP defines the regular expression for matching against identifiers;
– REGEXP_CASE_SENSITIVE controls the mode of regular expression matching:
– “1” - case sensitivity (default);
– “0” - case insensitivity.
Note-3: {ObjectClass} is defined by the following table:
Verilog construction {ObjectClass}
module module
parameter parameter
task task
function function
concatenation concatenation
EXAMPLE-1: [1] module name does not satisfy described condition => violation (message-1)
module 1top$; Module name "_top$" violates basic naming convention. Only alphanumeric
... characters and the underscore '_' should be used, and the first character
endmodule should be a letter of the alphabet.
EXAMPLE-3: [1] parameter name is an escaped identifier that does not contain prohibited symbols but is
Verilog-HDL keyword => violation (message-2)
reg \reg ;
Parameter name “\reg” is an escaped identifier. Try not to use
escaped identifiers in pure Verilog designs.
EXAMPLE-4: [1] parameter name is an escaped identifier but it is a simple identifier => no violation
wire [1:0] \non_esc_name ;
MESSAGE-2
{ObjectClass} name "{ObjectName}" violates basic naming convention. Lower-
case version of the name corresponds to Verilog-HDL keyword "{Keyword}".
Object identifiers must facilitate understanding the function of the underlying HDL description.
Verilog is a case sensitive language. Consequently, the designer is allowed to use reserved
language identifiers for object names that differ only by letter case: e.g., INPUT, Reg. However,
this is not recommended because it could lead to confusion.
PROBLEM
DESCRIPTION Moreover, in addition to Verilog-keywords, VHDL and software keywords should not be used
(problems may occur later in the design flow). There are no particular problems with EDIF, SDF
and Windows keywords, but for safety they should also be avoided in descriptions.
LEVEL RULE
Checker verifies that name of each object does not belong to one of the restricted sets of
keywords:
– if name belongs to Verilog set (built-in) => violation (message-2)
– if name belongs to VHDL/EDIF/SDF/Windows set => violation (message-1)
Note-1: sets of keywords are defined in the configuration file:
CHECKER – additional sets can be defined, for example:
BEHAVIOR – KEYWORD_CATEGORIES = [ "EDIF", "SDF", "Windows", "PSL",
"SYSTEM_VERILOG" ]
– each set (except built-in Verilog) can be extended with any keywords necessary for the
target design (using configuration file), for example:
– KEYWORD_LIST_WINDOWS = [ "CON", "AUX", "COM1", "COM2", ... ]
Note-2: see rule 1.1.1.2 for {ObjectClass} substitution table
EXAMPLE-1: [1] module name belongs to Verilog-keywords category => violation (message-2)
module Task; Module name "Task" violates basic naming convention. Low er-case
...
version of the name corresponds to Verilog-HDL keyw ord "task".
endmodule
EXAMPLE-2: [1] wire name belongs to Windows-keywords category => violation (message-1)
wire [8:0] COM1; Signal name "COM1" violates basic naming convention. Name belongs
to keyw ords category "Window s".
EXAMPLE-1: [1] register name is equal to the restricted fragment "GND" => violation
EXAMPLE-2: [1] wire name includes restricted fragment "VCC" => violation
EXAMPLE-3: [1] port name includes two restricted fragments: "VREF" and "VSS" => violation
[2] note: "VREF" is specified twice, but displayed once in the violation message
LEVEL RULE
EXAMPLE-1: [1] module name differs only by letter case from task declared in this module i.e. in sub-scope =>
violation (message-1);
[2] the same module name is equal to the name of signal declared in one of lower level of scope
hierarchy => violation (message-2);
[3] name of the first module is equal to the name of signal declared in another module (top2), i.e.
in parallel scope => no violation.
module top1; Module name “top1” has duplicates w hich differ only by letter case. Such
naming style should be avoided.
...
task Res; Module name “top1” has duplicates. Avoid naming different objects w ith the
...
same identifier.
begin : block1
reg top1;
... Duplicate identifier: Signal name “top1”.
end
endtask
Task name “Top1” differs only by letter case.
task Top1;
...
endtask
...
endmodule
...
reg top1;
...
endmodule
endmodule
Module name “top_” ends w ith underscore('_') or contains consecutive
underscores.
EXAMPLE-2: [1] module name contain only one underscore character => no violation;
[2] identifier contain two underscores consecutively, but parameter is not included in list of
checking object => no violation;
[3] Input of task violates current restrictions for identifiers, but it is not primary port => no violation.
module to_p;
...
...
task task1;
input in__1;
...
endtask
...
endmodule
module ff (clk,rst,set_n,d,q); Active high control signal “set_n” violates basic naming convention.
Identifying symbol (”_X” or ”_N”) should be added only at the end of
input clk the negative logic signal name to identify its polarity clearly.
input rst;
input set_n; Active low control signal “rst” violates basic naming convention. Add
input d; an identifying symbol (”_X” or ”_N”) at the end of the name so the
output reg q; polarity of negative logic signals is clearly identified.
module ff (clk,d1,d2,q1,q2);
Declaration of control signal “clk” intends it to be used as positive logic
input clk; signal, but both polarities are used.
input d1,d2;
output reg q1,q2;
Signal is used as positive logic.
always @( posedge clk )
q1 <= d1;
always @( * )
if ( !clk ) Signal is used as negative logic.
q2 = d2;
endmodule
module top;
Instance names should be based on the module name or <module_quantity>
... if multiple instances exist.
...
Instance name “latch_inst” does not correspond to module name “latch”.
endmodule
module top; Instance names should be based on the module name or <module_quantity>
... if multiple instances exist.
ff ff_inst1 ( ... );
ff ff_inst2 ( ... ); Module “ff” is instantiated multiple times but instantiation names do not
correspond to <module_quantity> template.
...
endmodule
begin: gen_ff Instance names w ithin 'generate' statement should be based on the module
name or <module_quantity> if multiple instances exist.
ff ff_inst ( ... );
end
Instance name “ff” does not correspond to module name “latch”.
Checker verifies each module specified as top-level for elaboration. Object names are checked in
the following order:
– module name:
– if length is greater than 16 => violation (message-1)
– else if non-alphabetical letters or underscores are used => violation (message-2)
– else if letter cases are mixed => violation (message-3)
CHECKER
BEHAVIOR – each port name:
– if length is greater than 16 => violation (message-1)
– else if non-alphabetical letters, numbers or underscores are used => violation
(message-4)
– else if underscores specified at the beginning/end or used consecutively =>
violation (message-5)
– else if letter cases are mixed => violation (message-3)
EXAMPLE-2: [1] module name contains letters having different cases => violation (message-3);
[2] port name has more than 16 characters in length => violation (message-1);
[3] note: port name also contains underscore at the beginning, but no violation is displayed for it
(checker consecutively verifies constraints and if the previous one is broken, the next one is not
checked);
Module name "TopLevel" violates basic naming convention. Top level
module and port names should use only upper case or low er case to
support systems that are not case sensitive.
module TopLevel( _serial_argument_input );
...
endmodule Port name "_serial_argument_input" has 22 characters. Length of top
level module and port names should be 16 or few er characters to use
design as the IP core.
MESSAGE-2
{ObjectClass} name "{ObjectName}" violates basic naming convention. Name
corresponds to attached library "{LibraryName}".
Naming conventions are specified by the used semiconductor technology flow. These limitations
can be quite different depending on the vendor, but there are two common requirements: names
PROBLEM of instances and cells should not correspond to the name of ASIC library being used. Also, it is
DESCRIPTION required to avoid names that are the same as libraries used by the simulator.
LEVEL RULE
EXAMPLE-1: [1] the name of the instance corresponds to the ASIC library "GTECH" => violation (message-1)
Instance name "Gtech" violates basic naming convention. Name
corresponds to library name "GTECH".
FPU_UNIT Gtech( .SEL( SEL ), ... );
EXAMPLE-2: [1] name of the cell corresponds to the attached library "STD" ("-l STD" is specified for compilation)
=> violation (message-2)
`celldefine Cell name "std" violates basic naming convention. Name corresponds
to library name "STD".
module std( ... );
...
endmodule
`endcelldefine
STARC_VLOG 1.1.2.1
RULE NAME
Module names and instance names should be between 2 and 32
characters in length
{ObjectClass} name “{ObjectName}” has {NameLength} characters. Module
MESSAGE-1 names and instance names should be between {MIN_LENGTH} and
{MAX_LENGTH} characters in length.
Logic synthesis tools may change module or instance names if they exceed 32 characters. Also
there are ASIC vendors limitations which states allowable length between 2 and 32 characters for
PROBLEM such identifiers. According to the constraints, module and instance names should be between 2
DESCRIPTION and 32 characters in length.
LEVEL RULE
MESSAGE-2
{ObjectClass} name “{ObjectName}” has {NameLength} characters. A length of
{MAX_LENGTH_RECOMMEND} or fewer characters is recommended.
Long instance names decrease readability when objects (signals, functions etc.) from lower
PROBLEM levels of hierarchy are used. Instance names of 16 or fewer characters is recommended.
DESCRIPTION
LEVEL RECOMMENDED 2
MESSAGE-3
{ObjectClass} name “{ObjectName}” has {NameLength} characters. Instance
names with hierarchy should be less than {MAX_LENGTH_HIER} characters.
A hierarchy may be flattened by some tool which is used at later stages. It leads to difficulties if
instance names are long and hierarchy is deep. Therefore, it is recommended that an instance
PROBLEM
names including module hierarchy should be 128 or fewer characters.
DESCRIPTION
LEVEL RECOMMENDED 3
EXAMPLE-1: [1] module name is only one character in length (shorter than MIN_LENGTH) => violation
(message-1);
[2] instance name longer then recommended length => violation (message-2)
Module name “t” has 1 characters. Module names and instance names should
module t;
... be betw een 2 and 32 characters in length.
submod too_long_instance_name(...);
submod very_long_and_unreadable_instance_name(...);
EXAMPLE-1: [1] module mod1 instantiation statement contains net name which differs from port name (ordered
port connection is used, one port is unconnected but it is allowed) => violation;
[2] module mod2 instantiation statement contains net name which differs from port name (named
and implicit port connection is used) => violation;
[3] module mod3 instantiation statement contains net name which differs from port name, but the
module is instantiated more then once => no violation;
module mod2 ( a, b ,c );
...
endmodule There is name inconsistency betw een port(s) and connected net(s) in
the module instantiation statement. Net name of the upper level to
module mod3 ( x, y );
... w hich a port name is connected should be the same.
endmodule
Net name "in" differs from the port name "in1".
module top;
...
mod1 inst1 ( in, in2, out1, ); There is name inconsistency betw een port(s) and connected net(s) in
mod2 inst2 ( .a(out1), .* ); the module instantiation statement. Net name of the upper level to
mod3 inst3 ( .x(xxx), .y(y) ); w hich a port name is connected should be the same.
mod3 inst4 ( .* );
endmodule Net name "in" differs from the port name "in1".
STARC_VLOG 1.1.3.1
RULE NAME
Signal names, port names, parameter names, `define names and
function names should be between 2 and 40 characters in length
{ObjectClass} name “{ObjectName}” has {NameLength} characters. It should be
MESSAGE-1
between {MIN_LENGTH} and {MAX_LENGTH} characters in length.
The number of characters in signal names, port names, parameter names and function names is
PROBLEM recommended to be between 2 and 40 to make project code easy to read and understand.
DESCRIPTION
LEVEL MANDATORY
EXAMPLE-1: [1] parameter name is shorter than MIN_LENGTH => violation (message-1).
parameter p; Parameter name “p” has 1 characters. It should be betw een 2 and 40
characters in length.
EXAMPLE-2: [1] port name is longer than recommended => violation (message-2);
[2] signal name is longer than MAX_LENGTH => violation (message 1).
STARC_VLOG 1.1.4.1
RULE NAME Do not use parameters with the same name for different modules
Module “{ModuleName}” has “{ParamName}” parameter, which name is equal to
parameter(s) declared in module(s) from other hierarchy(ies). Current description
may lead to confusion with duplicated parameters, because it is recommended to
put data to be used as parameters into `include files to make it easy to change
MESSAGE parameter values.
DETAIL-1 Module “{ModuleName}” has parameter with the same name
“{ParamName}”.
DETAIL-2 Instance “{InstanceName}” of module “{ModuleName}”.
Whenever possible, data to be used as parameters should be put into include files, thus making it
easy to change parameter values. But care should be taken with parameter names to avoid
confusing when including file with parameters declarations. Distinguish parameters used for the
PROBLEM
overall design from parameters used only under particular hierarchies, and place each one into a
DESCRIPTION
separate include file.
LEVEL RECOMMENDATION 3
CHECKER Checker verifies modules from the library:
BEHAVIOR
– if there are modules in the design that contain parameter declarations with equal names:
– for each hierarchy level (hierarchy begins from top-level – in other words, multiple
hierarchies are possible in case of multiple top-levels in the design) and parameter
name:
– if parameter with the same name exists in any instance ( of another module )
that is neither a child, nor a parent of the analyzed instance => violation
example #1: parameters with same name in modules from different levels of
parallel hierarchies, bur upper level module also has parameter with the name
=> no violation
hierarchy
levels
1 P1
parallel
2 hierarchy
P1
3
P1
parallel
hierarchy
– example #2: parameters with same name in modules from 2nd levels in one of
parallel hierarchies and from both levels of other, there are no common upper
level module which also has parameter with the name => violation
parallel
2 hierarchy
3
P1 P1
parallel
hierarchy
hierarchy
levels
1 top
//sub-modules declaration
module mod1(...);
Ins tance “top”. Module “mod1” has “p1” parameter, w hich name is
parameter p1 = 32; equal to parameter(s) declared in module(s) from other hierarchy(ies).
Current description may lead to confusion w ith duplicated parameters,
... because it is recommended to put data to be used as parameters into
`include files to make it easy to change parameter values.
endmodule
module mod2(...);
Module “mod2” has parameter w ith the same name “p1”.
parameter p1 = 8;
...
endmodule
hierarchy
levels
1 top1
2 mod1 mod2
parameter p1 = 2;
...
endmodule
//sub-modules declaration
module mod1(...);
parameter p1 = 32;
...
endmodule
module mod2(...);
parameter p1 = 8;
...
endmodule
hierarchy
levels
1 top1 top2
2 mod1 mod2
...
endmodule
...
endmodule
//sub-modules declaration
module mod1(...);
parameter p1 = 32;
...
endmodule
module mod2(...);
parameter p1 = 8;
...
endmodule
EXAMPLE-1: [1] module accesses macro "LENGTH" is not defined in the current module => violation
`define LENGTH 8 Macro "LENGTH" is used in module "tb" 1 time(s). Use `define
definitions declared only in the current module to enable separate
module tb; generation of each module by the logic synthesis tool.
wire[ `LENGTH - 1: 0 ]
...
endmodule Global macro used
EXAMPLE-2: [1] module accesses macro "COMB" defined outside the module => violation (message-2,
because it is defined in the included file "defines.h")
`include "defines.h" Macro "COMB" is used in module "dev8" 2 time(s). Use `define
definitions declared only in the current module to enable separate
module dev8( ... ); generation of each module by the logic synthesis tool.
`ifdef COMB
...
`ifdef COMB Global macro used
`endif
...
endmodule
EXAMPLE-3: [1] module accesses macro "COMB" defined in the included file "defines.h" => no violation
("defines.h" is included locally)
EXAMPLE-4: [1] module accesses macro "COMB" that is not defined in current file (neither globally nor
included) => no violation
1) Checker scans output/inout port drivers (continuous and procedural assignment statements) in
synthesizable context:
CHECKER – if constant/parameter is assigned => violation (message-1)
BEHAVIOR
2) Checker verifies list of port connections in the module instantiation statements:
– if constant/parameter is connected to the input port => violation (message-2)
EXAMPLE-1: [1] 'assign' statement connects constant to output port => violation (message-1);
[2] note: constant is member of concatenation;
EXAMPLE-2: [1] parameter is connected to the input port of the component => violation (message-2);
module circ( input [1:0] SAMPLE, output AL );
...
endmodule
...
module top;
parameter [1:0] STOP_B; Constant is assigned to 1 port(s) of low er layer module "circ". Some
... redundant logic may remain after applying synthesis optimization.
MESSAGE-3
Parameter is initialized with value "{ParamValue}" without base specifier.
Describe 'b, 'h, 'd or 'o clearly when initializing a parameter.
Parameter is initialized with expression which contains {IllegalConstCount}
constant(s) without base specifier. Describe 'b, 'h, 'd or 'o clearly when using
MESSAGE-4 constants for parameter initialization.
DETAIL-1 Base is not specified for constant "{ConstValue}"
It is strongly recommended to describe the base specification clearly for parameter numeric
values greater than 8 ('b, 'h', 'o, 'd). If base is not specified, there is a possibility to introduce a
PROBLEM mistake (for example, 11 is not 'h11). Moreover, descriptions without base specifiers are harder
DESCRIPTION to maintain.
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] numeric value (greater than 8) without base specifier initialize parameter => violation
(message-1, because there is no expression, and parameter name is known)
EXAMPLE-2: [1] instantiated component "generic_divider" is not compiled to the working library yet => port
names are unknown;
[2] parameter is overridden at instance "CLK_DIV_10" with a single constant "10" without base
specifier => violation (message-3, due to unknown parameter name);
EXAMPLE-1: [1] bit width is 44 and is not specified in parameter declaration statement => violation
(message-1);
parameter BW = 'h50077766677;
Parameter "BW" is initialized w ith value "'h50077766677" w ithout w idth
specifier. Specify bit w idth directly w hen declaring parameters greater
than 32 bits.
EXAMPLE-2: [1] bit width of decimal parameter is 32, but value of rule parameter
CHECK_BIT_WIDTH_GREATER_THAN is changed by configuration file to 30 => violation
(message-1);
parameter BW = 'd4278255360;
Parameter "BW" is initialized w ith value "4278255360" w ithout w idth
specifier. Specify bit w idth directly w hen declaring parameters greater
than 30 bits.
STARC_VLOG 1.1.5.1
Basically, use “CLK” or “CK” for clock signal names, “RST_X” or
RULE NAME “RESET_X” for reset signal names and “EN” for enable signal
names. Add identifiers to the end of these basic names.
{SignalType} signal “{SignalName}” violates basic naming convention. Use
“CLK” or “CK” for clock signal names, “RST” or “RESET” for reset signal names
MESSAGE-1 and “EN” for enable signal names. Add up to {IDENT_CHAR_NUMBER}
identifying characters to the end of these basic names if multiple
{SignalTypeLower} signals exist.
MESSAGE-2 {SignalType} signal “{SignalName}” matches forbidden pattern “{RegExp}”.
MESSAGE-3 {SignalType} signal “{SignalName}” does not match legal pattern “{RegExp}”.
In order to improve the readability of a description, a signal name based on the clock system can
be used. First, decide the basic signal name for the clock signal, reset signal and enable signal.
Then add an identifier to the end of the basic signal name when more than one signals of the
same kind exist.
It is recommended to use basic signal names of “CLK” or “CK” for a clock signal, “RST_X” or
“RESET_X” for a reset signal and “EN” for an enable signal. For example, if multiple clocks exist,
add one to three characters to the end of “CLK” or “CK” like “CLK2”, “CLKD” or “CLK_CPU”, etc.
PROBLEM
DESCRIPTION Names which suggest a clock system can be given by adding the name of the clock signal
source, to the end of the signal name (ex.”_CLKM").
It would be overly verbose to add clock identification to signals for the entire design. However,
knowing which clock each signal is dependent upon is important in systems that employ two-
phase or three-phase latch based designs or use asynchronous transfer. A clock name should be
added when designing such circuits.
LEVEL RECOMMENDATION 3
EXAMPLE-1: [1] reset signal does not match the pattern (basic name is inappropriate) => violation (message-1);
[2] enable signal does not match the pattern (number of identifying characters specified after basic
name exceeds allowed number ) => violation (message-1).
Note: parameter IDENT_CHAR_NUMBER value is default ( IDENT_CHAR_NUMBER = 3 ).
if ( rs_clk123 ) Reset signal “rs_x_123” violates basic naming convention. Use “CLK”
q <= 1'b0; or “CK” for clock signal names, “RST” or “RESET” for reset signal
names and “EN” for enable signal names. Add up to 3 identifying
characters to the end of these basic names if multiple reset signals
exist.
STARC_VLOG 1.2.1.1
RULE NAME Designs should use a single clock/single edge as much as possible
Module "{ModuleName}" uses {CLKCount} different clock lines. Designs should
use a single clock as much as possible.
MESSAGE-1
Process infers FF(s) with clock signal “{CLKName}” from {FFCount}
DETAIL-1
signal(s)
Module "{ModuleName}" uses {CLKCount} different clock lines. Currently
allowed clock domains = {CLOCK_DOMAINS_ALLOWED}.
MESSAGE-2
Process infers FF(s) with clock signal “{CLKName}” from {FFCount}
DETAIL-1
signal(s)
When dealing with really large designs, the circuit operation speed is analyzed using static timing
analysis tools instead of logic simulation. If the clock system is complex, such analysis becomes
very difficult: system is represented as a few smaller systems operating with a single clock and a
PROBLEM single edge.
DESCRIPTION So it is recommended not to use multiple clock lines. In cases, when multiple clocks are
necessary, their count should be reduced as much as possible.
LEVEL RECOMMENDATION 1
Checker collects clock signals (by extracting them from a flip-flops inferred in the current
module):
– if not all flip-flops are using the same clock signal => violation:
CHECKER – message-1, if parameter CLOCK_DOMAINS_ALLOWED is equal to 1 (default)
BEHAVIOR – message-2, if parameter CLOCK_DOMAINS_ALLOWED is greater than 1
Note: parameter CLOCK_DOMAINS_ALLOWED can be set up for designs where multiple clocks
are required
Note: clock edges are checked in rule 1.4.3.6
EXAMPLE-1: [1] two 'always' processes infer flip-flops having different clock signals => violation (message-1)
module trn( ... );
... Module "trn" uses 2 different clock lines. Designs should use a single
always @( posedge CLK_1 ) begin clock as much as possible.
REG_A <= OP_STATE;
end
... Process infers FF(s) w ith clock signal “CLK_1” from 1 signal(s)
always @( posedge CLK_2 ) begin
if( RESET )
REG_B <= 1'b0;
Process infers FF(s) w ith clock signal “CLK_2” from 1 signal(s)
else
REG_B <= TS_STATE;
end
...
endmodule
module trn( ... ); Module "trn" uses 3 different clock lines. Currently allow ed clock
...
always @( posedge CLK_1 ) begin domains = 2
REG_A <= OP_STATE;
end
... Process infers FF(s) w ith clock signal “CLK_1” from 1 signal(s)
always @( posedge CLK_2 ) begin
if( RESET )
REG_B <= 1'b0; Process infers FF(s) w ith clock signal “CLK_2” from 1 signal(s)
else
REG_B <= TS_STATE; Process infers FF(s) w ith clock signal “CLK_3” from 2 signal(s)
end
...
always @( negedge CLK_3 ) begin
REG_C <= PS_STATE_0;
REG_D <= PS_STATE_1;
end
endmodule
LEVEL RULE
Checker scans net list for the presence one of the following feedback types
(described at the picture):
CHECKER – if connection and feedback between two gates (either direct or inverter)
BEHAVIOR is present => violation
Note: parameter DETAILED_PROPAGATION_CHAIN configures displaying
message (see 1.2.1.3 for information about messages displaying).
EXAMPLE-1: [1] D-latch is described using primitives (see picture in “PROBLEM DESCRIPTION” section);
[2] feedback of mentioned type is detected => violation
Note: parameter DETAILED_PROPAGATION_CHAIN is set to 0.
input c;
input d;
output out;
endmodule
input clk;
input d;
Detected combinational description of the circuit that is similar to RS
output Q;
latch. Avoid describing latches w ith standard primitive cells because
wire nQ; timing analysis tools can treat it as feedbacks in combinational circuits.
d cd qcd rqcd
Q
clk
ccd
nQ
snqccd
DETAIL-4
Asynchronous loop propagates through submodule instance
“{InstanceName}” from port “{InputPortName}” to “{OutputPortName}”
Static timing analysis tools are used to analyze the circuit operation
speed for large designs. Combinational circuit feedbacks carry into
the effect of a feedback loop during timing analysis and should be COMB_LOGIC
PROBLEM avoided.
DESCRIPTION
LEVEL RULE
Checker scans the design hierarchy to detect feedbacks that are propagated through
combinational paths:
– each signal is propagated through subsequent combinational paths in order to detect
the feedback
– a combinational path is a path that allows asynchronous propagation of signal (see
Note-1 for feedback signal propagation rules)
– if there is such a path in the design hierarchy (through which propagated signal will
asynchronously return to its source) => combinational feedback loop is detected and
violation message is displayed (see Note-2 for message displaying rules)
Note-1: following rules are imposed on propagation of signal through the design hierarchy:
– propagation stops on following objects (picture at Propagation
New
stops
the right side shows stop of propagation for the propagation
“SIG” signal): SIG
LD
L.SIG
SIG «L»
– synchronous inputs of flip-flops / latches SIG
CHECKER – black boxes
BEHAVIOR
– propagation resumes from outputs of objects that stopped the propagation before
(picture below shows that propagation is resumed for signal “SIG” after it has been
stopped with data input of the latch “L”)
Note-2: violation message is displayed regarding the line for which feedback is detected
– feedback is an intermediate line (it is not explicitly specified in the description, but it is
implied to be generated by the logic synthesis tool – see the example below) =>
violation message #2 is displayed (*)
– feedback is not an intermediate line (see the example below) => violation message #1 is
displayed (*)
Feedback on
line «Q»
is detected
A
B
Q
C
(*)
– two modes are provided to display details for violation message (depending on state
of the parameter):
– parameter DETAILED_PROPAGATION_CHAIN is equal to “0” (default)
– violation is reported in short form: no details displayed (see the example #1)
– parameter DETAILED_PROPAGATION_CHAIN is equal to “1”
– violation is reported in full form: details describe the path through which
combinational feedback is propagated (see the example #2)
– when combinational feedback is propagated through an intermediate line,
detail #1 is displayed
– when combinational feedback is propagated through a line that is not
intermediate, detail #2 is displayed
– when combinational feedback is propagated through flip-flops or latches,
detail #3 is displayed followed by a list of possible objects ({ObjectType})
and ports corresponding to them ({PortType}):
{ObjectType} {PortType}
FF asynchronous reset
latch asynchronous set
EXAMPLE: [1] violation is reported in the detailed form: feedback propagation path is described
(DETAILED_PROPAGATION_CHAIN = 1)
[2] consider the design hierarchy at the picture below
[3] note, that all possible paths of feedback propagation are demonstrated:
– through the submodule instance
– through the flip-flop and latch
– through the combinational logic line
– through the intermediate combinational logic line
Propagation fm754
through intermediate Propagation
line through instance
f7k
A
X2
FF X1 f_and
B
«Q1» Y1 LD
f_or
f7k_o «FK» FK
CLK y1 G
L_e
C
input A, B, C, CLK;
output FK;
reg FK; Ins tance "fm 754". "STARC 1.2.1.3" Combinational feedback is
detected. Do not use feedbacks in combinational circuits to avoid the
wire f7k_o, RST, L_e; effect of a feedback loop during the timing analysis.
reg Q1;
always @( A or L_e ) Asynchronous loop propagates through latch "FK" enable input
if( L_e )
FK = A;
endmodule
STARC_VLOG 1.3.1.2
It is safer to use asynchronous reset for initial reset to a register.
RULE NAME
- Reset tree synthesis at layout is easy.
- Values may not be fixed in a gate-level simulation with
synchronous reset.
Global reset “{GlResetSignalName}” is connected to FF “{FFName}”
MESSAGE-1 synchronous {ControlType} input. Initial reset should be connected to
asynchronous control input to avoid problems with simulation.
MESSAGE-2 None of the specified reset signals was found, auto-detect mode is used. Detected
[INFO] reset signals: {GlResetSignalNameList}.
MESSAGE-3 None of the specified reset signals was found, auto-detect mode is used. No global
[INFO] resets detected.
MESSAGE-4 Specified global reset signal “{SignalName}” could not be found in the design.
[INFO]
MESSAGE-5 Info: No reset signals specified, auto-detect mode is used. Detected reset signals:
[INFO] {GlResetSignalNameList}.
MESSAGE-6 No reset signals specified, auto-detect mode is used. No global resets detected.
[INFO]
In some kinds of circuits (for example, state machine which depends on the previous state) using
synchronous reset may cause simulation problems. In the beginning of simulation reset is used to
clear all registers, but in case of synchronous reset previous state is unknown and may block
PROBLEM
propagation of the reset to synchronous input, registers are not cleared and simulation result is
DESCRIPTION
not valid. So it is recommended to use asynchronous reset for initial reset of a register.
LEVEL RECOMMENDATION 3
Checker detects signals that are used as synchronous set/reset for FF(s).:
CHECKER
– if signal has 'global_reset' attribute => violation (message-1).
BEHAVIOR
Note: see 1.4.3.4 for details about info messages 2-6.
input clk;
input data;
input greset;
output out1;
output out2;
endmodule
if ( RESET )
Q <= 1'b0;
else
Q <= D;
endmodule
input D;
input CLK;
input SET;
output reg Q;
if ( !RESET )
Q <= 1'b0;
else
Q <= D;
endmodule
MESSAGE-4 None of the specified reset signals was found, auto-detect mode is used. No global
[INFO] resets detected.
MESSAGE-5 None of the specified reset signals was found, auto-detect mode is used. Detected
[INFO] reset signals: {GlResetSignalNameList}.
MESSAGE-6 No reset signals specified, auto-detect mode is used. No global resets detected.
[INFO]
MESSAGE-7 No reset signals specified, auto-detect mode is used. Detected reset signals:
[INFO] {GlResetSignalNameList}.
When combinational circuit generates an asynchronous reset signal, there are
situations possible in which hazards will occur as result of optimization by logic
PROBLEM synthesis tool. Therefore, signals other than initial resets are forbidden for
DESCRIPTION asynchronous control pins of flip-flops.
LEVEL RECOMMENDATION 1
Checker propagates reset signal(s) through the design hierarchy and restricts its connection to
pins other than FF/latch asynchronous control pins:
– see the rule 1.4.3.4 (behavior of this checker is almost the same(*))
(*)
– the main difference between these checkers is:
– 1.3.1.4 restricts connection of global clock signal(s) (specified with -alint_gclk
switch) to pins other than FF clock pins
– 1.2.3.3 restricts connection of global reset signal(s) (specified with -alint_grst
switch) to pins other than FF asynchronous control pins
Note-1: violation message is displayed per each object with improperly mapped reset (see the
table from Note-2 for list of possible objects and their pins)
Note-2: following table defines set of strings that are possible for the {ObjectType} token (different
CHECKER from 1.4.3.4):
BEHAVIOR
{ObjectType} {PortType}
clock
FF data
enable
data
latch
enable
multiplexer select
tri-state buffer Enable
input RESET;
input D_IN;
output D_OUT;
endmodule
endmodule
EXAMPLE-2: [1] global resets are auto-detected from signals 'RESET' and 'SET' that are mapped to
asynchronous control pins of flip-flop “DATA_OUT” (note, that special message #7 is displayed to
indicate the list of reset signals that are auto-detected);
[2] global reset signal 'RESET' is also connected to combinational logic that is mapped to flip-flop
'DATA_OUT' clock pin => violation (message #1 is displayed).
else
Q <= DATA;
DETAIL-1
Connection to asynchronous control pin of flipflop “{FFName}” is
MESSAGE detected.
DETAIL-2 Connection to synchronous control pin of flipflop “{FFName}” is detected.
DETAIL-3
Signal "{SigName}" is also used both for synchronous and asynchronous
reset line(s) in the same connections.
If one reset line has both synchronous reset and asynchronous reset, synthesis may not be
performed properly. The asynchronous reset line sometimes forms a tree-structure during the
layout process. To avoid accidentally inserting a buffer or logical operand during logic synthesis
with Design Compiler, set_ideal_net directive may be put on this reset line. This directive means
that the specified net is excluded from the limitation of the logic synthesis, the timing analysis,
and the design rule. Then, if this reset line is also
PROBLEM input to a FF's synchronous input, that part will DATA FF FF
DESCRIPTION not be synthesized and synthesis will fail as a
result. In addition to this, having both RST_N
asynchronous reset and synchronous reset may
cause other problems during logic synthesis and
layout, so they should not be mixed.
LEVEL RULE
Checker detects signals that are used simultaneously as both asynchronous set/reset and
synchronous set/reset in the design:
– if such signals detected => violation
CHECKER – connection to asynchronous reset pin => detail-1
BEHAVIOR – connection to synchronous reset pin => detail-2
– if several signals drive simultaneously both asynchronous set/reset and synchronous
set/reset pins => only one main message is displayed for all of them (selected by
name), and detail-3 per each other driver-signal.
EXAMPLE-1: [1] signal is used simultaneously as asynchronous reset and synchronous reset => violation
(message-1 + detail-1/detail-2).
if ( !RST )
Q1 <= 1'b0;
else Connection to synchronous control pin of flipflop “Q1” is detected.
Q1 <= DATA[0];
end
if ( !RST )
endmodule
EXAMPLE-1: [1] two signals drive simultaneously asynchronous reset and synchronous reset pins => violation
(message-1 + detail-1/detail-2 + detail-3).
end
if ( !TMP )
Connection to asynchronous control pin of flipflop “Q2” is detected.
Q2 <= 1'b0;
else
Q2 <= DATA[1];
end
endmodule
DATA
FF FF
RST_N_2
RST_N_1
STARC_VLOG 1.3.2.1
Do not insert logical operands in a reset line at the local module. In
addition, circuits that supply reset lines should be separated into
RULE NAME an individual module.
- Logic order may be replaced by synthesis.
- Hazards cannot be prevented in the RTL description.
Combinational logic is connected to asynchronous {ControlType} of flip-flop
“{FFName}”. Do not insert logical operands in a reset line at the local module to
MESSAGE avoid problems with optimization of this logic by synthesis tools. It is
recommended to separate into individual modules such circuits that supply reset
lines.
An asynchronous reset signal may be supplied as synchronized and additional logic may be
inserted in reset line to prevent unstable operation. Also, logic circuits may be inserted so that a
system reset can be selected. When logic is needed on a reset line, combine that reset line logic
together in the top level (see picture below) as much as possible and directly input the same
signal input to all FFs. By creating modules for reset generation, it will also become easier to
apply synthesis constraints.
RST_GEN
FF FF
PROBLEM
DESCRIPTION COUNT
Logic
CTRL
RST_N
top
LEVEL RECOMMENDATION 1
if( !rcnt_n )
q <= 1'b0; Combinational logic is connected to asynchronous reset of flip-flop
else “q”. Do not insert logical operands in a reset line at the local module to
q <= d; avoid problems w ith optimization of this logic by synthesis tools. It is
recommended to separate into individual modules such circuits that
endmodule
supply reset lines.
d
FF
q
clk
ctrl
4
cnt
MESSAGE-3 None of the specified reset signals was found, auto-detect mode is used. No global
[INFO] resets detected.
MESSAGE-4 None of the specified reset signals was found, auto-detect mode is used. Detected
[INFO] reset signals: {GlResetSignalNameList}.
MESSAGE-5 No reset signals specified, auto-detect mode is used. No global resets detected.
[INFO]
MESSAGE-6 No reset signals specified, auto-detect mode is used. Detected reset signals:
[INFO] {GlResetSignalNameList}.
Signals other than initial reset should not be input for asynchronous reset pins, because
it is difficult to analyze the paths which the asynchronous reset and set pass through
during the timing analysis (such timing paths are cut off without taking into account –
see the picture below for example).
FF FF FF
COMB_LOGIC COMB_LOGIC
PROBLEM RESET
DESCRIPTION
Timing
FF Analysis
COMB_LOGIC cut off
Therefore, avoid such descriptions when using logic synthesis tools or static timing
analysis tools to perform timing analysis.
LEVEL RECOMMENDATION 1
Checker restricts signal that is connected to asynchronous control pin of flip-flop to be global
reset signal:
– global reset signal(s) (specified with -alint_grst switch or auto-detected) is propagated
through the design hierarchy
– asynchronous control pin(s) of each flip-flop should be connected to global reset (it
means that propagation reached this pin)
– if propagation does not reach asynchronous control pin => violation message #1 is
CHECKER displayed (per FF signal assignment) with detail message (per appropriate
BEHAVIOR asynchronous control branch)
– see 1.4.3.4 for details:
– rules for auto-detection (during the auto-detection, each signal that is connected to
asynchronous control pin of flip-flop is considered as reset signal)
– rules for global reset propagation (global reset propagates through buffers /
inverters / combinational logic / multiplexers data / tri-state inputs)
– rules for displaying info-messages (indicate the list of auto-detected clock or report
about reset signals that are specified with -alint_gclk but could not be found)
0
Black box
1
FF out2
data2
clk2
grst
“grst” is considered as
global reset signal
wire muxout;
wire bboxout1;
wire bboxout2;
dff DFF_INSTANCE1 ( .D( data1 ), .CLK( clk1 ), .RESET( grst ), .Q( out1 ) );
dff DFF_INSTANCE2 ( .D( data2 ), .CLK( clk2 ), .RESET( muxout ), .Q( out2 ) );
endmodule
input D;
input CLK;
input RESET;
output Q;
reg Q;
STARC_VLOG 1.4.3.2
RULE NAME Do not input a FF output pin to other FF clock pins
The clock pin of flip-flop "{DrivenFFName}" is driven by the output of another
flip-flop. CTS tool will not be able to take the clock line balancing into
MESSAGE consideration.
DETAIL Clock pin is driven with the output of flip-flop "{DriverFFHierName}"
Clock Tree Synthesis (CTS) tools are used to synthesize and Violation
route clock lines after the placement of each FF in the layout. FF FF
When output pin of some flip-flop is supplied to clock pin of
PROBLEM other flip-flop, the CTS tool will not be able to take the clock line
DESCRIPTION balancing into consideration.
LEVEL RULE
Checker scans the design hierarchy for flip-flops that have output of another flip-flop supplied to
their clock pins:
– back-propagation is performed from clock pin of each flip-flop to define its driver (See
Note-1 for backward propagation rules)
– clock pin driver is a signal on which backward propagation stops
– if the driver is the output of another flip-flop (as shown on image in the “Problem
description” section) => violation is reported (main message points at the process that
infers the driven flip-flop, whereas detail message points at the assignment of signal that
CHECKER infers the driving flip-flop)
BEHAVIOR Note-1: the following rules are imposed on backward propagation from the signal through the
design hierarchy:
– backward propagation starts from driven signal, passes through instances and stops on
any except of following objects:
– inverters
– buffers
– direct connections (wires)
– driver is a signal at which propagation stops
EXAMPLE-1: [1] two modules infer flip-flops (the first flip-flop has an asynchronous reset, the second one does
not have one);
[2] rule violation at the third (top-level) module: output of first flip-flop is mapped to the clock pin of
the second one;
module chain( I_A, I_B, I_C, I_D, I_RST, I_CLK, O_A, O_B );
input I_A, I_B, I_C, I_D, I_RST, I_CLK;
output O_A, O_B;
M_FF1 U0 ( .I_A( I_A ), .I_CLK ( I_CLK ), .I_RST( I_RST ), .O_A( O_A ) );
M_FF2 U1 ( .I_A( I_A ), .I_CLK ( O_A ), .O_A( O_B ) );
endmodule
module M_FF2 ( I_A, I_CLK, O_A ); Instance "chain.U1". The clock pin of flip-flop "test_1_4_3_2.U1.O_A"
input I_A, I_CLK; is driven by the output of another flip-flop. CTS tool w ill not be able to
output reg O_A;
take the clock line balancing into consideration.
MESSAGE-1 DETAIL-1
Global clock signal(s) “{GlClkSignalNameList}” is connected to the
{ObjectType} “{ObjectName}” {PortType} input
Global clock signal(s) “{GlClkSignalNameList}” is connected to the
DETAIL-2
multiplexer select input
MESSAGE-2 Specified global clock signal “{SignalName}” could not be found in the design.
[INFO]
MESSAGE-3 None of the specified clock signals was found, auto-detect mode is used. No global
[INFO] clocks detected.
MESSAGE-4 None of the specified clock signals was found, auto-detect mode is used. Detected
[INFO] clock signals: {GlCLKSignalNameList}.
MESSAGE-5 No clock signals specified, auto-detect mode is used. No global clocks detected.
[INFO]
MESSAGE-6 No clock signals specified, auto-detect mode is used. Detected clock signals:
[INFO] {GlCLKSignalNameList}.
Clock signals should not be connected to LD FF 0
input pins other than clock pins of flip-flops.
1
Paths having clock lines connected to
CLK
latches, enabling logic of multiplexers and
tri-states, non-clocking pins of flip-flops are
PROBLEM
extremely dangerous (consider the picture COMB COMB COMB
DESCRIPTION
at the right side): it is impossible to analyze
timing correctly for them.
Additionally, logic synthesis tools will not perform any optimizations for such paths.
LEVEL RULE
CHECKER Checker propagates clock signal(s) through the design hierarchy and restricts its connection to
BEHAVIOR pins other than FF clock input pins:
– correct case is shown on the picture at the right side of the page CLK
FF
– propagation of each clock signal through the design hierarchy
(see Note-1 for clock signals determination and Note-2 for clock
signals propagation) restricts clock signal connection to:
– flip-flop: it is not allowed to supply clock signal to pins other than clock pin;
– latch: it is not allowed to supply clock signal to any pin;
– multiplexer: it is not allowed to supply clock signal to select pin(s);
– tri-state: it is not allowed to supply clock signal to enable pin;
– violation message is displayed for each case where any of upper options is not true
– see Note-3 for list of possible objects ({ObjectType}) and ports corresponding to
them ({PortType}).
Note-1: there are two routines provided to detect clock signal(s):
– clock signal(s) is specified with -alint_gclk command line switch
(example: alint -alint_gclk top.clk1 -asim top);
– clock signal(s) is determined automatically (when there is no clock(s) specified with
-alint_gclk switch):
(*)
– each signal connected to clock pin of any flip-flop in the design hierarchy is
SOME_SIG SOME_SIG
(*)
– following requirements are imposed on such signal:
– it should be the input port of the top-level module
– it should not be connected through the combinational logic (except buffers
and inverters)
– information message-2 is displayed if automatic mode is enabled
Note-2: following rules are used to propagate clock signal(s) through the design hierarchy:
– clock signal is propagated through:
– combinational logic (logic gates);
– multiplexer data inputs;
– clock signal is not propagated through:
– flip-flops;
– latches;
– tri-states.
Note-3: following cases are possible {ObjectType} and {PortType} that are displayed in the
violation message:
{ObjectType} {PortType}
data
enable
asynchronous set
FF
asynchronous reset
synchronous set
synchronous reset
data
enable
latch
asynchronous set
asynchronous reset
multiplexer select
EXAMPLE-1: [1] consider design hierarchy that is represented on the picture below: common violation cases are
considered (clock propagation routine is marked with orange color);
[2] clock is specified with “-alint_gclk” switch (alint -alint_gclk top.CLK -asim top).
REV FF
always @( posedge CLK ) Do not connect clock signal to the pin other than to the FF clock input
pin, it may lead to the incorrect timing analysis
res_q2 <= buf_to_dff;
Global clock signal(s) "top.CLK" is connected to the FF "top.res_q2"
ld_n_and i2 ( .L_I( buf_to_dff ), data input
.L_E( en ),
.rev( rev ),
.L_O( ld_to_tri ),
.g_to_en( g_to_en ) );
always @( g_to_en, ld_to_tri ) Global clock signal(s) "top.CLK" is connected to the tristate buffer
if ( g_to_en ) "top.res_q1" enable input
res_q1 <= 1'bz;
else Do not connect clock signal to the pin other than to the FF clock input
res_q1 <= ld_to_tri; pin, it may lead to the incorrect timing analysis
reg mux_out;
endmodule
reg L_O;
reg L_OS;
endmodule
EXAMPLE 1: [1] consider design hierarchy that is represented on the picture below (clock propagation routine is
marked with orange color)
[2] clock “top.CLK_1” is specified with -alint_gclk switch (alint -alint_gclk top.CLK_1 -asim top)
top
DATA FF
OUT1
CLK_1
COMB Global clock signal
0 “CLK_1” is
connected to
RESET 1 asynchronous control
COMB line of FF “Q” .
TEST
output OUT1;
wire mux_to_res;
dff DFF_INSTANCE ( .D( DATA ), .CLK( CLK_1 ), .RESET( mux_to_res ), .Q( OUT1 ) );
endmodule
output reg Q;
endmodule
EXAMPLE 2: [1] consider design hierarchy that is represented on the picture below
[2] clock “top.CLK_1” is specified with -alint_gclk switch (alint -alint_gclk top.CLK_1 -asim top)
top
modwithinout
DATA_1 FF
OUT1
CLK_1
DATA_2 FF
CLK_2
endmodule
output OUT1;
Q1 <= DATA_1;
Q2 <= DATA_2;
endmodule
LEVEL RECOMMENDATION 1
Checker collects clock signals (by extracting them from a flip-flops inferred in the current
module):
– if parameter CHECK_CLOCK_DOMAINS is disabled (OFF) => all clock signals should
use the same edge:
CHECKER – if edges are inverted for any of clock signals => violation (message-1)
BEHAVIOR – if parameter CHECK_CLOCK_DOMAINS is enabled (ON) => each clock signal must
use the same edge:
– if some of clock signals uses inverted edges => violation (message-2)
Note: field {InvertedEdge} in the warning message is defined by the less used clock edge (if
number of positive and negative edges is equal, negedge is treated as inverted)
EXAMPLE-1: [1] multiple (2) clocks are used in the module, these clocks have different edges and parameter
CHECK_CLOCK_DOMAINS is disabled => violation (message-1);
[2] note: 'posedge' is inverted edge here (it is less used)
module sl_dec( ... ) Module "sl_dec" uses clock signal w ith posedge for 1 FF signal(s)
always @( negedge CLK_2 ) and negedge for 2 FF signals(s). Inverted edge is: posedge. Do not
read_state <= read_finish; use FFs w ith inverted edges.
EXAMPLE-2: [1] multiple (2) clocks are used in the module, these clocks have different edges and parameter
CHECK_CLOCK_DOMAINS is enabled => violation (message-2, only per clock with different
edges);
[2] note: 'negedge' is inverted edge here (number of positive and negative edges is equal);
module sl_dec( ... ) Module "sl_dec" uses clock signal "CLK_2" w ith posedge in 1 FF(s)
always @( posedge CLK_1 )
and negedge in 1 FF(s). Inverted edge is: negedge. Do not use FFs
if( RESET )
return_slot <= P_INITIAL; w ith inverted edges.
STARC_VLOG 1.5.1.1
RULE NAME
To avoid metastable conditions, do not locate combinational logic
between asynchronous clock domains
FF “{FFName}” obtains data from another clock domain through combinational
logic. Combinational logic should not be located between asynchronous clock
domains, because it significantly increases the risk to propagate incorrect value
to downstream logic and cause functional errors.
DETAIL-1 “{ClockName}” is the origin clock of the source domain.
MESSAGE
DETAIL-2 “{ClockName}” is the origin clock of the target domain.
DETAIL-3 Signal “{SignalName}” derived from global clock(s) with circuit “{Circuit}”
is the origin clock of the source domain.
DETAIL-4 Signal “{SignalName}” derived from global clock(s) with circuit “{Circuit}”
is the origin clock of the target domain.
PROBLEM Metastability problem should be considered carefully during data transmission between different
DESCRIPTION clock domains.
The picture below illustrates that input signal value could be changed during a flip-flop setup/hold
time – metastable value (glitch) could be sampled and propagated from a flip-flop to the logic
circuits.
FF
CLK_1 CLK_1
DATA_1
CLK_2 samples
DATA_1 while it
is changing DATA_1
CLK_2
FF
CLK_2
DATA_2 DATA_2
Clocked signal
DATA_2 is initially … and might still be metastable
metastable at the next rising edge of CLK _2
It is quite difficult to detect such kind of problems before circuit is fabricated. Therefore, it is highly
important to prevent metastability-related issues by enforcing effectiveness-proven
methodologies during the RTL design.
To understand the rule 1.5.1.1, consider simple synchronizer. A simple synchronizer comprises
two flip-flops in series without any combinational circuitry between them. This approach ensures
that the first flip-flop exits its metastable state and its output settles before the second flip-flop
samples it. For proper work of such synchronization, the signal crossing a clock domain should
pass from flip-flop in the original clock domain to the first flip-flop of the synchronizer without
passing through any combinational logic.
First flip-flop of a synchronizer is sensitive to glitches that combinational logic produces (glitch
that occurs at the correct time could meet the setup-and-hold requirements of the first flip-flop in
DATA FF FF FF
COMB_LOGIC
DOMAIN_1 DOMAIN_2
[X MHz] [Y MHz]
LEVEL RULE
Checker scans design hierarchy against combinational logic between different asynchronous
clock domains (*):
– those flip-flops that have data input driven by combinational logic are validated:
– violation is issued if another clock domain drives this combinational logic
– (*) Clock domains are auto-detected – the following algorithm defines clock domains
extracting principles:
– global clocks are detected (external port(s) that is/are directly connected to FF clock
input – see 1.4.3.4 for details)
– each global clock creates separate clock domain:
– global clock is propagated through design hierarchy by common principles (through
combinational logic and multiplexers – see 1.4.3.4 for details about clock
propagation)
– note: feedbacks on clock signal path are not considered (no backward
propagation is performed);
CHECKER
BEHAVIOR – note: latches on clock signal propagation path are transparent
– each FF which has global clock signal connected to the clock pin is added to the
corresponding clock domain;
– note: if the FF clock input is driven by the output of a FF/latch/tristate that
belongs to a clock domain "A", this FF is correspondingly added to a clock
domain "A";
FF_1 FF_2
CLK_1
BELON GS TO BELON GS TO
D O MA IN_ 1 D OMAIN _1
BEC AU SE OF BEC AU SE OF
C L K_ 1 F F_1
– if two or more clock signals are propagated through the same combinational logic or
multiplexer (clock domains crossing) then output of this logic / mux derives new clock
signal – resulting in new clock domain for subsequent connections;
DOMAIN_3
(DERIVED) FF
BELON GS TO
DOMAIN_2 D O MA IN_ 3
FF
BELON GS TO
COMB_LOGIC D O MA IN_ 2
– if clock signal is connected to the select pin of multiplexer then its output derives new
clock signal – resulting in new clock domain for subsequent connections;
DOMAIN_2
(DERIVED)
FF
0 BELON GS TO
D O MA IN _2
DOMAIN_1 FF
BELON GS TO
D O MA IN _1
DOMAIN_2 DOMAIN_4
[CLK2] (DERIVED)
DOMAIN_3
[CLK3]
{Circuit} = xor( and( CLK2, CLK3 ), CLK1 )
1 1
DOMAIN_1 DOMAIN_1
[CL K1] [CLK1]
{Circuit} = multiplexer ( CLK1, CLK2 ) {Circuit} = multiplexer ( CLK1 )
3. clock signals are crossed in arithmetic circuit (length of such "chain" should
not exceed 2, otherwise it will be considered as complex logic – see example-4
below):
DOMAIN_1
[CL K1 ]
+ DOMAIN_4
(DERIVED)
DOMAIN_3
[CLK 3] SHL
DOMAIN_1 1
[CL K 1]
DOMAIN_2 DOMAIN_4
[CL K2] ( DERIVED)
DOMAIN_3
[CLK3 ]
EXAMPLE-1: [1] consider sample circuit at the picture below – there are two clock domains (driven by global
clocks 'CLK_1' and 'CLK_2';
[2] combinational logic (multiplexer) is located between these domains => violation;
subtractor
CLK_1 Combinational logic
between clock domains
DOMAIN_1
0 div2
1
adder DOMAIN_2
DOMAIN_1
CL:K_2
adder adder(
.CLK( CLK_1 ),
.A ( ARG_A ),
.B ( ARG_B ),
.RES( res_add )
);
subtractor subtractor(
.CLK( CLK_1 ),
.A ( ARG_A ),
.B ( ARG_B ),
.RES( res_sub )
);
endmodule
input CLK;
input [`BIT_LENGTH-1:0] A, B;
output [`BIT_LENGTH-1:0] RES;
reg [`BIT_LENGTH-1:0] RES;
endmodule
input CLK;
input [`BIT_LENGTH-1:0] A, B;
output [`BIT_LENGTH-1:0] RES;
reg [`BIT_LENGTH-1:0] RES;
endmodule
input CLK;
input [`BIT_LENGTH-1:0] ARG;
output [`BIT_LENGTH-1:0] RES;
reg [`BIT_LENGTH-1:0] RES;
simple_sync simple_sync(
.CLK ( CLK ),
.DATA_IN ( ARG ),
.DATA_OUT( stable_arg )
);
endmodule
input CLK;
input [`BIT_LENGTH-1:0] DATA_IN;
output [`BIT_LENGTH-1:0] DATA_OUT;
reg [`BIT_LENGTH-1:0] DATA_OUT;
TARGET DOMAIN
TARGET DOMAIN
CLOCK
Thus, it is not recommended to locate combinational logic between the adjacent flip-flops of basic
synchronizer.
LEVEL RECOMMENDATION 1
Checker scans design hierarchy against combinational logic between adjacent flip-flops of each
basic synchronizer:
– each target clock domain (*) is considered:
– the first two flip-flops are treated as basic synchronizer;
CHECKER – the violation is issued if there is a circuitry between them (see figure above);
BEHAVIOR – note: violation message:
– the main violation message points to the second flip-flop;
– special detail messages are also displayed in order to indicate origin
clocks of source and target domains (see 1.5.1.1 for details);
– (*) see 1.5.1.1 for details about clock domains detection;
EXAMPLE-1: [1] consider sample circuit at the picture below – there are two clock domains (source domain is
driven by derived clock 'multiplexer(CLK_1, CLK_2)', target domain is driven by global clock
'CLK_3');
[2] combinational logic is located between the adjacent flip-flops of simple synchronizer in the
target domain => violation;
subtractor div2
DOMAIN_1 C O M B _ L O G IC DOMAIN_2
LOGIC 1st FF 2nd FF LOGIC
OF B A S IC OF B A S IC
S Y N C H R ON IZE R
CLK_1 S Y N C H R ON IZE R
CLK_2
subtracter subtracter( Signal “sub.cur_clk” derived from global clock(s) w ith circuit
.CLK( cur_clk ), “multiplexer(sub.CLK_1, sub.CLK_2)” is the origin clock of the source
.A ( ARG_A ),
.B ( ARG_B ), domain.
.RES( res_sub )
);
div2 div2(
.CLK( CLK_3 ),
.ARG( res_sub ),
.RES( RES )
);
endmodule
//Subtracter
module subtracter( CLK, A, B, RES );
input CLK;
input [`BIT_LENGTH-1:0] A, B;
output [`BIT_LENGTH-1:0] RES;
reg [`BIT_LENGTH-1:0] RES;
endmodule
//Divider
module div2( CLK, ARG, RES );
input CLK;
input [`BIT_LENGTH-1:0] ARG;
output [`BIT_LENGTH-1:0] RES;
reg [`BIT_LENGTH-1:0] RES;
endmodule
//Synchronizer
module simple_sync( CLK, DATA_IN, DATA_OUT );
input CLK;
input [`BIT_LENGTH-1:0] DATA_IN;
output [`BIT_LENGTH-1:0] DATA_OUT;
reg [`BIT_LENGTH-1:0] DATA_OUT;
always @( posedge CLK ) Ins tance "sub.div2.s im ple_s ync". Combinational logic is detected
second_stage_ff = custom_gate;
betw een the adjacent flip-flops of basic synchronizer
endmodule "sub.div2.simple_sync.first_stage_ff"-"sub.div2.simple_sync.second_
stage_ff". Glitches produced by combinational logic increase the risk
to propagate incorrect value to dow nstream logic. For proper
synchronization, the basic synchronizer cell should contain tw o pure
flip-flops.
TARGET DOMAIN
st nd
SIG N AL FR O M TH E
SO U R C ED O MAIN
1 FF 2 FF TARGET DOMAIN
OF BASIC OF BASIC
SYNCHRONIZER LOGIC
SYNCHRONIZER
S IG N AL FR O M TH E
TA R GE T D O MAI N
PROBLEM TA R G ET D O MAIN
C LOC K
DESCRIPTION
Checker scans design hierarchy against a feedback loop at the first-stage of each basic
synchronizer:
– each target clock domain (*) is considered:
– the first two flip-flops are treated as basic synchronizer;
– the violation is issued if there is a feedback at the first of them (see figure above);
– note: violation message:
CHECKER
BEHAVIOR – the main message points to the line at which the feedback is detected;
– special detail messages are also displayed in order to indicate origin
clocks of source and target domains (see 1.5.1.1 for details);
– additional detail messages could be also displayed in order to indicate the
feedback propagation path (depends on value of parameter
DETAILED_PROPAGATION_CHAIN – see 1.2.1.3 for details);
– (*) see 1.5.1.1 for details about clock domains detection;
EXAMPLE-1: [1] consider sample circuit at the picture below – there are two clock domains (source domain is
driven by clock 'CLK_1', target domain is driven by clock 'CLK_2';
[2] there is a feedback loop at the first flip-flop of basic synchronizer – right after the transfer
between asynchronous clocks => violation;
DFF
1 st FF 2nd FF bb3
DFF OF BASIC
SYNCHRONIZER
OF BASIC
SYNCHRONIZER
[BLACK BOX]
bb2
DFF [BLACK BOX]
CLK_1 CLK_2
input CLK_1, CLK_2, RST; "top.CLK_2" is the origin clock of the target domain.
input DI1, DI2;
output DO;
always @( posedge CLK_2 ) Ins tance "top". Feedback loop is detected in the first-stage of basic
sync_1st = data_src; synchronizer "top.sync_1st"-"top.sync_2nd". The metastable state on
always @( posedge CLK_2 ) the synchronizer input might affect the latched value and result in
sync_2nd = sync_1st; circuit malfunction. Even if the placement of logic betw een the
adjacent flip-flops of synchronizer can not be avoided, feedback
always @( posedge CLK_1 ) should not be used.
if( RST )
clk_div2 = 0;
else
clk_div2 = ~clk_div2;
endmodule
STARC_VLOG 1.7.1.1
RULE NAME Don't use gated clocks in an FPGA
Global clock “{GClkName}” passes through the gate logic. Gated clocks should
MESSAGE not be used in FPGAs wherever possible, because it becomes difficult to fine-
tune clock delays and skew.
Using gated clocks is a popular way to decrease circuit power consumption by reducing the clock
network power dissipation. This mechanisms is often used for ASIC design, but there are some
problems of implementing gated clocks for FPGA design.
FPGAs have pre-synthesized clock trees for providing synchronized clock to the finite number of
flip-flops and memories across the chip. When additional logic is applied to the clock signal in the
RTL, the logic translates into physical gates outside the pre-synthesized balanced clock tree,
through which the clock signal passes, thus causing large clock skews between registers of
theFPGA.
Gated clocks should not be used in FPGAs wherever possible. If you still want to use gated
clocks, clock gating logic should be put in a separate FPGA and separate FPGAs should be used
for each clock domain (see the picture below).
PROBLEM
DESCRIPTION Clock generating FPGA
CLK FPGA 1
CTRL1
FPGA 2
CTRL2
FPGA 3
CTRL2
LEVEL RECOMMENDATION 1
Checker collects signals that are detected as global clocks (auto-detected or specified with
-alint_gclk switch):
CHECKER – if the signal from the set is connected directly (*) to some gate
BEHAVIOUR – if the output of the gate is connected directly (*) to FF clock pin => violation
(*)
– for this rule, signal that is directly connected may be connected directly or
through buffers/inverters
input CLK;
Ins tance ''top''. Global clock “CLK” passes through the gate logic. Gated
input CTRL, D1, D2;
clocks should not be used in FPGAs w herever possible, because it becomes
output OUT1, OUT2; difficult to fine-tune clock delays and skew .
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
top
FF
OUT1
D1
CTRL
CLK
FF
CLK OUT2
D2
STARC_VLOG 2.1.1.2
RULE NAME Describe every case statement expressions in a function statement
Function “{FuncName}” is not defined in all cases. The results of RTL and post-
synthesis simulation will not match.
MESSAGE-1 DETAIL-1 “{Variable}” is not defined in all cases.
Function result is assigned with “{Variable}” which is not defined in all
DETAIL-2
cases.
“{FuncBit}” bit of function result is not defined in all cases. The results of RTL
and post-synthesis simulation will not match.
MESSAGE-2 DETAIL-1 “{Variable}” is not defined in all cases.
DETAIL-2
Function result is assigned with “{Variable}” which is not defined in all
cases.
{BitCount} bits of function “{FuncName}” are not defined in all cases. The results
of RTL and post-synthesis simulation will not match.
MESSAGE-3 DETAIL-1 “{Variable}” is not defined in all cases.
Function result depends on a value of “{Variable}”, which is not defined in
DETAIL-2
all cases.
The function statement is a sub-program that can return only one value. In hardware it is
implemented as a combinational circuit. In function statements, latches are not generated even if
the conditions are not completely defined. In such situation, function returns an undefined value
during simulation, but synthesis tool will assign the value of 0 or 1.
PROBLEM
DESCRIPTION Therefore, it is required to describe full 'case'/'if' statements (value of each signal is defined in
each branch) in functions. Otherwise, there is a danger of mismatches between the RTL and
post-synthesis simulation results.
LEVEL RULE
CHECKER Checker scans function statements:
BEHAVIOR
– if function output is not defined (return value is not assigned ) in any possible case =>
violation
– if function result is a scalar or the whole vector violates the rule =>
message-1
– if function result is a vector and only one bit violates the rule => message-2
– if function result is a vector and only some bits (>1, but not all) violate the rule =>
message-3
function [1:0] res; Function “res” is not defined in all cases. The results of RTL and post-
input [2:0] sel; synthesis simulation w ill not match.
begin
case ( sel )
3'b011: res = 2'b00; “res” is not defined in all cases.
3'b100: res = 2'b01;
3'b101: res = 2'b10;
endcase
end
endfunction
function [1:0] res; “res[1]” bit of function result is not defined in all cases. The results of
input [2:0] sel; RTL and post-synthesis simulation w ill not match.
input [2:0] data;
reg c;
reg d;
begin
if (sel) c = data[0]
else d = data[1];
res = c; Function result depends on a value of “c”, w hich is not defined in all
end
cases.
endfunction
STARC_VLOG 2.1.2.1
RULE NAME
The function statement shouldn't be used for asynchronous reset
line logic in an always construct for FF inference
The function statement should not be used for asynchronous reset line logic in
MESSAGE
an 'always' construct for FF inference.
Some synthesis tools cannot recognize the type of reset signal (posedge or negedge) if function
PROBLEM call is used instead of simple expression in the asynchronous control condition branch.
DESCRIPTION
LEVEL RULE
EXAMPLE-1: [1] function is called in the asynchronous control line => violation;
[2] function is called in the clock enable line => no violation
input PRESET_DATA;
...
function invert;
input arg;
begin
invert = ~arg;
end
endfunction
...
always @( posedge CLK or negedge RESET ) begin
if( invert( RESET ) )
Q <= PRESET_DATA; The function statement should not be used for asynchronous reset
else if( invert( EN ) ) line logic in an 'alw ays' construct for FF inference.
Q <= DATA;
end
EXAMPLE-2: [1] function is called in the synchronous control line => no violation
input PRESET_DATA;
...
function invert;
input arg;
begin
invert = ~arg;
end
endfunction
...
always @( posedge CLK ) begin
if( invert( RESET ) )
Q <= 1'b0;
else if( invert( EN ) )
Q <= DATA;
end
Checker detects the signals that have ever been read in the following expressions (inside the
function):
– right-hand-side of an assignments
CHECKER – conditional expressions ('if', 'for', ternary conditional operator)
BEHAVIOR
– another function calls
If the signal is read but it is defined neither as function input nor as local variable => violation
Note: if signal is not local, but it is 'for' loop variable =>no violation
EXAMPLE-1 [1] signal is read in the conditional expression of an 'if' statement and it is not defined as function
: input or local variable => violation
function ADD_SUB; Function "ADD_SUB" uses 1 signal(s) not declared as function inputs
input [7:0] ARG_1; or local variables. The results of RTL and post-synthesis simulation
input [7:0] ARG_2; may not match.
reg RES;
begin
Signal "OP_SEL" is not declared as function input or local variable
if( OP_SEL == 1'b1 )
RES <= ARG_1 + ARG_2;
else
RES <= ARG_1 - ARG_2;
ADD_SUB = RES;
end
endfunction
EXAMPLE-1 [1] if signal is not local, but it is 'for' loop variable => no violation
:
integer i;
function BW_ADD;
input [7:0] ARG_1;
input [7:0] ARG_2;
begin
for ( i = 0; i <=7; i = i + 1 )
BW_ADD <= ARG_1[i] + ARG_2[i];
end
endfunction
CHECKER Checker detects task enable statements and if any are detected it issues one violation per
BEHAVIOR module.
EXAMPLE-1: [1] module "d32_ang" contains 2 task enable statements => violation
module d32_ang( ... );
task swap; Module "d32_ang" contains 2 'task' enable statement(s). Usage of
... 'task' statements in RTL description is not recommended.
endtask
EXAMPLE-1: [1] task "light" contains an event control statement => violation
task light; Task "light" contains 1 event control statement(s). Event control
output COLOR; statements should not be used in 'task' statements.
input [31:0] TICS;
begin
repeat( TICS ) @( posedge CLOCK );
COLOR = OFF;
end Event control statement detected
endtask
STARC_VLOG 2.1.3.1
RULE NAME
Match the argument bit width with the bit width of the function
statement input declaration (Verilog only)
Argument bit width does not match to bit width of the function port declaration.
Match bit widths exactly to avoid loss or misalign of input signal bit values.
MESSAGE-1
Argument width is "{ArgBitWidth}" while port "{InputName}" width is
DETAIL-1
"{InputBitWidth}"
Argument bit width does not match to bit width of the task port declaration.
Match bit widths exactly to avoid loss or misalign of input/output signal bit
MESSAGE-2 values.
Argument width is "{ArgBitWidth}" while port "{InputName}" width is
DETAIL-1
"{InputBitWidth}"
When function statement is described, bit width of the input/output arguments must be
considered with special care: the bit width of the function input declaration should match to bit
PROBLEM width of the input argument. If bit widths doesn't match, value of input signal can be misaligned or
DESCRIPTION lost.
LEVEL RULE
wire ST_SSM;
wire ST_SSK;
... Argument bit w idth does not match to bit w idth of the function port
function INV; declaration. Match bit w idths exactly to avoid loss or misalign of input
input arg; signal bit values.
begin
INV = ~arg;
end Argument w idth is "2" w hile port "arg" w idth is "1"
endfunction
...
assign rev_slot = INV( { ST_SSM, ST_SSK } );
...
task copy8to16;
input [ 7:0] src_arg;
output [15:0] dest_arg;
begin
dest_arg = { 8'b00000000, src_arg };
end
endtask Argument bit w idth does not match to bit w idth of the task port
... declaration. Match bit w idths exactly to avoid loss or misalign of
always @( * ) begin input/output signal bit values.
...
copy8to16( sample_k_bus, transn_k_bus );
...
end
Argument w idth is "32" w hile port "dest_arg" w idth is "16"
Checker verifies each assignment (=, <=, assign) where right-hand-side is pure function call:
– bit width of function return value should be the same as bit width of assignment
destination
– message-1 is displayed when target of assignment has greater bit width than bit width of
function return value
CHECKER – message-2 is displayed when target of assignment has less bit width than bit width of
BEHAVIOR function return value
Note-1: this rule can be dependent on parameters or hierarchical references => elaboration-time
checking is required for such cases
Note-2: this checker verifies only cases where right-hand-side is pure function call. This is made
intentionally, since checker 2.10.3.3 verifies cases where right-hand-side is not simple function
call (for example, an expression with function call as one of its members)
EXAMPLE-1: [1] function "SHL" is called in "true" branch of ternary conditional operator (it is pure call);
[2] bit width of function return value is greater than bit width of assignment destination => violation
(message-2)
EXAMPLE-2: [1] function "SHL" is called in a right-hand 'always' statement (it is pure call);
[2] bit width of function return value is less than bit width of assignment destination => violation
(message-1);
EXAMPLE-3: [1] bit width of function return value is greater than bit width of assignment destination, but right-
hand-side is not pure function call (function is member of an expression) => no violation (this is
case for 2.10.3.3)
Checker scans every execution path in a function statement to verify that each execution path is
finished by return value assignment (RVA):
– lower scopes are not checked if RVA is found in the current scope
CHECKER
BEHAVIOR – if RVA is present at least in one branch of 'case' statement – checkers treats it as if all
'case' branches have RVA (completeness of 'case' in a function is checked by rule
2.1.1.2)
– execution path is good if last statement of this execution path has/is RVA
EXAMPLE-1: [1] function doesn't have RVA in one of execution paths => violation (DETAIL-1);
[2] redundant statements after RVA in another one execution path => violation (DETAIL-2);
function FUNC;
input a; Function does not end w ith a return value assignment in every
input b; execution path. Return value assignment should be the last statement
reg t; for any function execution path.
begin
if( a ) begin
FUNC = a | b; Redundant statements after the return value assignment
t = a;
end
else begin Return value assignment is not performed in this execution path
b = ~b;
a = ~a;
end
end
endfunction;
EXAMPLE-2: [1] lower level execution path is not full, but there is no violation due to RVA in the upper level
execution path;
[2] case statement is treated as if all branches has RVA, because RVA is present in at least one of
the branches => no violation;
[3] RVA is not present in the last execution path => violation (DETAIL-1);
function FUNC;
input a;
input b; Function does not end w ith a return value assignment in every
reg t; execution path. Return value assignment should be the last statement
begin for any function execution path.
if( a ) begin
if( b ) begin
t = a;
This execution path “if( b )” is not full, b ut upper level execution path
end
“if( a )” contains RVA => no violation
FUNC = a | b;
EXAMPLE-3: [1] function includes execution path that is not full, but the last statement in global execution path is
full => no violation
function FUNC;
input a;
input b;
reg t;
begin
if( a ) begin
t = a;
FUNC = a | b; This execution path “else” does not have RVA, b ut the last statement
end “if( t )” in the upper level execution path “begin ... end” has RVA =>
else
no violation
t = b;
if( t )
FUNC = t;
else
FUNC = ~t;
end
endfunction
...
reg glbl;
Function “func1” assigns values to outer signals. In a function
function func1;
statement, global signal assignment should not be performed.
input a;
input b;
begin
if ( a )
Signal “glbl” is assigned in a function.
func1 = b;
else
glbl = a;
...
end
endfunction
...
endmodule
EXAMPLE-2: [1] global signal is assigned in the function statement but it is for loop variable => no violation
module top;
...
integer glbl;
input [3:0] a;
input [3:0] b;
...
end
endfunction
...
endmodule
STARC_VLOG 2.1.4.5
RULE NAME Logical operator should not be used for vector (Verilog only)
MESSAGE
Logical operator has vector argument(s). Use bit-wise operators for multi-bit
arguments and logical operators only for 1-bit arguments.
Logical operators (!, &&, ||) treat argument as FALSE if it is 0 or as TRUE in other case and return
1-bit result. Bit-wise operators process arguments bit by bit. Results of calculations are the same
for logical and bit-wise operators only if arguments are of 1-bit width. For other arguments results
PROBLEM
are different. So it is recommended to use logical operators only with 1-bit arguments to avoid
DESCRIPTION
mistakes.
LEVEL RECOMMENDED 1
EXAMPLE-1: [1] one argument of logical operator is 2-bit width => violation.
reg one_bit_reg;
parameter [1:0] two_bits_param = 2'b01;
Logical operator has vector argument(s). Use bit-w ise operators for multi-bit
arguments and logical operators only for 1-bit arguments.
LEVEL RECOMMENDATION 3
EXAMPLE-1: [1] argument 'a' of the reduction operator is one bit width => violation (message-1)
[2] bit width of argument 'b' of the reduction operator is greater then recommended => violation
(message-2)
reg a; Argument bit w idth of reduction operator “&” is equal to one bit. Such
reg [15:0] b; description is not recommended since no operation w ill be performed.
assign c = &a + |b;
Argument bit w idth “16” of reduction operator “|” is too large. It is
recommended to use arguments less than or equal to “8” bits to avoid
performing functions w ith many operational steps.
STARC_VLOG 2.1.5.1
RULE NAME Use nesting of a conditional operator (?) only once (Verilog only)
Ternary conditional operator contains {NestedCount} nested conditional
MESSAGE-1 operators. It is recommended to use this operator only once to improve
readability of the description and decrease possibility of nesting mistakes.
The conditional operator can be nested, but since readability of the description decreases and
nesting mistakes are more likely, it is recommended that a conditional operation be used only
once. When two or more ? exist the nesting relationship is difficult to verify, whether it is an if-if
PROBLEM
nest or an else-if nest. Therefore, using an if statement within an always construct is
DESCRIPTION
recommended.
LEVEL RECOMMENDATION 3
EXAMPLE-1: [1] conditional operator contains nested conditional operator => violation (message- 1)
LEVEL RECOMMENDATION 2
CHECKER Checker verifies conditional expression of the if statements and the ternary operator ( ? ):
BEHAVIOR – if expression bit width is greater then 1 => violation
EXAMPLE-1: [1] result of selection expression has width greater then 1 => violation
input [7:0] sel;
...
if( sel )
EXAMPLE-2: [1] selection expression contains equality operator so result bit width is 1 => no violation
input [7:0] sel;
input [7:0] in_a,in_b;
reg [15:0] res;
...
...
end
STARC_VLOG 2.1.6.1
RULE NAME
Specification of an array should be [MSB:LSB], if it is one-
dimensional
Module “{ModuleName}” contains {IllegalDeclCount} vector range declaration(s)
that does not correspond to [MSB:LSB] style. Such style is recommended to
avoid problems with arithmetic operations which are based on [MSB:LSB]
MESSAGE assumption.
DETAIL Vector “{VecName}” range declaration does not correspond to [MSB:LSB]
specification.
Arithmetic operations are based on the assumption of [MSB:LSB] and if a reverse vector is used,
it is necessary to convert it for arithmetic operations otherwise operation result is incorrect. It is
PROBLEM
recommended to specify [MSB:LSB], even if the array does not perform arithmetic operations.
DESCRIPTION
LEVEL RECOMMENDATION 2
Checker scans vector declarations (function return value range, function / task ports are also
considered) and checks range declaration [MSB:LSB]:
CHECKER – if ( MSB < LSB ) => violation
BEHAVIOR
Note-1: array of vectors declaration are skipped
Note-2: array range may be parameter-dependent => elaboration time checks required
EXAMPLE-1: [1] within vector declaration MSB > LSB => violation
module top; Module “top” contains 1 vector range declaration(s) that does not
correspond to [MSB:LSB] style. Such style is recommended to avoid
reg [0:31] tmp; problems w ith arithmetic operations w hich are based on [MSB:LSB]
assumption.
...
EXAMPLE-2: [1] within array of vectors declaration MSB > LSB => no violation
module top;
...
endmodule
Checker scans vector declarations (function return value range, function / task ports are also
considered) and detect LSB in range declaration expression:
– if ( LSB != RECOMMENDED_LSB ) => violation
CHECKER Note-1: array of vectors declaration are skipped
BEHAVIOR
Note-2: array range may be parameter-dependent => elaboration time checks required
Note-3: parameter RECOMMENDED_LSB value is described in configuration file and may be
used to tune vector declarations style (by default RECOMMENDED_LSB == 0).
...
endmodule
module top;
...
endmodule
Checker scans array references within 'always' and 'assign' synthesizable statements:
– if any of indexes (constant or variable) used in references does not fit to declared range:
– if array index is constant and index > MSB or index < LSB => violation
(message-1);
– if array index is variable and maximum possible value is greater than MSB or/and
CHECKER minimum possible value is less then LSB => violation (message-2).
BEHAVIOR
Note-1: initial assignments are not checked.
Note-2: array can be referenced by loop constant index. Loop constant index is an expression of
statically countable loops (see 2.9.1.2), that contain only constants, loop variables, unary, binary
and ternary operation (in this case index range is counted by values). If expression has non-loop
variables, concatenation, it is simple expression (in this case index range is counted by bit-width
of operands).
CHECKER Checker verifies bit-selection or part-selection index expression which evaluates to a constant:
BEHAVIOR – if value of index contain unknown bits ('x' or 'z') => violation
EXAMPLE-1: [1] bit selection expression contains unknown ('z') value => violation
assign out1 = { in1[1'bz], in2[30:0] };
Unknown value in the index: 1'bz. Incorrect
synthesis results may be generated.
EXAMPLE-2: [1] reference to memory contains unknown 'x' value => violation
always @(mem) begin
out1 = mem[ 3'b1x1 ]
end Unknown value in the index: 3'b1x1. Incorrect synthesis results may be generated.
STARC_VLOG 2.2.1.1
RULE NAME
Latches are generated unless all conditions have been described.
Care should be taken not to create latches
Possible latch inference for {LatchSigCount} signal(s)
MESSAGE
DETAIL Signal "{SignalName}" is not assigned in all cases
When describing a process for a combinational circuit, each signal should be defined in all
execution paths of the process. It usually means that assignment to the signal should be
performed in each branch of any conditional statement ('if', 'case') inside the process. Otherwise,
PROBLEM
logic synthesis tools will recognize that output signal must be retained for certain condition. As a
DESCRIPTION
result, latch will be generated to maintain output value.
LEVEL RULE
Checker scans 'always' statements in order to detect the latches. Following requirements are
imposed on each signal assigned in an 'always' construct:
– if signal is assigned in some branch of 'if'/'case' statement, it must be also assigned in
all other branches of this statement (i.e. signal assignment should be complete)
– if there is no 'else' branch in 'if' statement => all conditions must be covered by existing
branches (i.e. 'if' statement should be complete)
– if there is no 'default' clause in 'case' statement => all conditions must be covered by
existing clauses (i.e. 'case' statement should be complete)
CHECKER Consecutively, latch is inferred if one of the above restrictions is broken.
BEHAVIOR
So, violation message is displayed when 'always' block describes latches only and one from the
two following cases is true:
– 'if'/'case' statement is complete, but signal is not assigned in all branches
– the signal is assigned in all branches, but 'if'/'case' statement is incomplete
Note-1: when completeness of 'case'/'if' statement depends on parameter => elaboration-time
checking is required (warning message will include instance name)
Note-2: detail-message for vector can be either single (if latches are inferred by all elements of
the vector) or multiple (if latches are inferred only by some bits)
EXAMPLE-1: [1] 'if' is complete ('else' branch is present) but one of two signals is not assigned in all branches
always @( S, A, B ) begin
if( S == 2'b00 ) begin Possible latch inference for 1 signal(s)
F1 <= A | B;
F2 <= 1'b0;
end
else if( S == 2'b01 ) begin Signal "F2" is not assigned in all cases
F1 <= 1'b0;
F2 <= 1'b1;
end
else if( S == 2'b10 ) begin
F1 <= 1'b0;
end
else begin
F1 <= 1'b0;
F2 <= A & B;
end
end
always @( S, A, B ) begin
case( S ) Possible latch inference for 2 signal(s)
2'b00: begin
F1 <= A | B;
F2 <= 1'b0; Signal "F1" is not assigned in all cases
end
2'b01: begin Signal "F2" is not assigned in all cases
F1 <= 1'b0;
F2 <= 1'b1;
end
2'b10: begin
F2 <= A & B;
end
endcase
end
EXAMPLE-3: [1] casex is incomplete (completeness of depends on parameter => elaboration-time checking
required);
[2] assigned signal "F" is 2-bit vector (single warning issued for it – due to incomplete 'case' – all
bits will infer latches)
STARC_VLOG 2.2.2.1
All signals at the right of the conditional expression and the
RULE NAME assignment statement in the always construct of the combinational
circuit must be defined in the sensitivity list
The sensitivity list of always statement is incomplete. Differences between RTL
MESSAGE and post-synthesis simulation results are possible.
DETAIL Signal “{ObjectName}” is read, but is not included in the sensitivity list.
Logic synthesis tools ignore sensitivity lists in combinational circuits assuming that always
construct executes if any of reading signal changes. When any signal read in the process is not
PROBLEM
included in sensitivity list – differences between RTL and gate level simulation may occur.
DESCRIPTION
LEVEL RULE
Checker verifies all signals which are read in combinational always block:
– signals on the right side of procedural assignment
– condition expression of the if-statement
– selection expression of the case-statement
– input arguments of function/task calls
If any of detected signals is not included in sensitivity list of current always block => violation.
Checker skips following objects:
– initial constructs
CHECKER – internally declared signals
BEHAVIOR
– delay expressions
– event control statements
– always constructs if there is an edge description in sensitivity list
– blocks without sensitivity list
– incremental statement of loop variable is not checked.
– loop variables as index
– intermediate variables (variables that are assigned and read in this process).
Note: elaboration-time checks are possible when needed.
EXAMPLE-1: [1] signal is used on the right side of procedural assignment and is not included in sensitivity list =>
violation
end Signal “in3” is read, but is not included in the sensitivity list.
always @( in1, in2 ) begin The sensitivity list of alw ays statement is incomplete. Differences
betw een RTL and post-synthesis simulation results are possible.
for( i = 0; i < 10; i = i + 1 ) begin
out1 = in1[i] && in2[in3];
end
... Signal “in3” is read, but is not included in the sensitivity list.
end
DETAIL-5
Signal "{ObjectName}" is unnecessary because it is used only as an
intermediate variable.
Logic synthesis tools ignore sensitivity lists in combinational circuits assuming that always
construct executes if any of reading signal changes. Unnecessary signals described in sensitivity
list may cause extra cycles of 'always' block execution and differences between RTL and gate
PROBLEM
level simulation may occur as a result. So do not define constants and unnecessary signals in the
DESCRIPTION
sensitivity list
LEVEL RECOMMENDATION 2
EXAMPLE-1: [1] signal is used on the right side of procedural assignment and is not included in sensitivity list =>
violation
end Signal “in3” is read, but is not included in the sensitivity list.
EXAMPLE-2: [1] signal is used for bit selection and is not included in the sensitivity list => violation
[2] loop variable is used for bit selection => no violation
The sensitivity list of alw ays statement is incomplete. Differences
always @( in1, in2 ) begin
betw een RTL and post-synthesis simulation results are possible.
for( i = 0; i < 10; i = i + 1 ) begin
out1 = in1[i] && in2[in3];
end
... Signal “in3” is read, but is not included in the sensitivity list.
end
EXAMPLE-1: [1] 'always' block contains multiple event expressions => violation (message-1);
always @( CLK ) begin 'alw ays' block contains 2 event control statements. Such description
style is rarely synthesizable. One event control statement is required.
if( RESET = '1' )
@( posedge CLK ) Event control statement detected
F <= 1'b0;
else Event control statement detected
F <= Y1 ^ Y2;
end
EXAMPLE-2: [1] 'always' block doesn't contains event control expressions => violation (message-2)
always begin 'alw ays' block does not contain any event control statement. Infinite
if( RESET = '1' ) loop is possible during simulation. One event control statement is
F <= 1'b0;
else required.
F <= Y1 ^ Y2;
end
EXAMPLE-3: [1] 'always' block contains multiple event control expressions => violation (message-1)
always @( posedge CLK ) begin 'alw ays' block contains 2 event control statements. Such description
Y <= A & B; style is rarely synthesizable. One event control statement is required.
@( negedge CLK )
Y <= A | B;
Event control statement detected
end
STARC_VLOG 2.2.3.1
RULE NAME
Do not mix blocking assignments (=) and non-blocking
assignments (<=) in combinational always construct
Always construct for combinational circuit contains a mixture of blocking (=) and
MESSAGE non-blocking (<=) assignments. It is safer to use only one type of assignments in
the same 'always' block.
Assignment of a value to the signal with non-blocking assignment takes place after the evaluation
of all assignment statements in the always block. When the blocking assignment is performed,
the assignment is already completed at the time this line is evaluated, so the assigned values on
PROBLEM the lines after that are certainly valid. Mixture of assignment types may easily lead to mistakes.
DESCRIPTION Moreover simulation results may differ depending on Verilog-HDL simulators. It is safer to use
only one type of assignments in the same always block.
LEVEL RULE
...
end
Checker scans combinational 'always' statements in order to find signals that are assigned with
non-blocking assignments:
– if signal(*) is assigned multiple times under the same execution path(es) =>
CHECKER violation
BEHAVIOR
(*) if separate bits of the same signal are assigned – compacting is performed
Note: 'always' for combinational circuit for this checker is such 'always' statement, where all
signals are described without edges in the sensitivity list
EXAMPLE-1: [1] multiple non-blocking assignments over the same signal "Y1" (in the same execution path) =>
violation;
[2] multiple non-blocking assignments over the same signal "Y2" (execution path is not the same)
=> no violation;
always @( CLK. SEL, A, B ) begin Multiple non-blocking assignments over the same signal "Y1" are
Y1 <= 1'b0;
detected on the same execution path in the 'alw ays' construct for a
if( SEL ) begin
Y1 <= A | B; combinational circuit. Final signal value is undetermined.
Y2 <= A & B;
end
else begin
Y1 <= A & B;
Y2 <= A | B;
end
end
EXAMPLE-2: [1] 2-bit vector is assigned with full assignment and with partial assignment => violation for bit that
is assigned multiple times
always @( CLK, SEL, A, B ) begin Multiple non-blocking assignments over the same signal "Q[0]" are
Q <= 2'b00; detected on the same execution path in the
case( SEL ) 'alw ays' construct for a combinational circuit. Final signal value is
1'b0: Q[0] <= A | B;
1'b1: Q[0] <= A & B; undetermined.
endcase
end
EXAMPLE-3: [1] multiple non-blocking assignment over the same signal "Q" in sequential circuit => no violation
(this is case for 2.2.3.3)
Checker scans body of the 'always' statement for sequential circuit and finds assigned signals
(with blocking or nonblocking assignments either):
– if signal(*) (for which FF or latch is inferred) is assigned more than once in single
CHECKER execution path(es) => violation
BEHAVIOR
(*) if separate bits of the same signal are assigned – compacting is performed
Note: 'always' for sequential circuit for this checker is such 'always' statement, where all signals
are described with edges in the sensitivity list
EXAMPLE-1: [1] multiple assignments (blocking and non-blocking) over the same signal "outx[0]" in sequential
circuit (in the same execution path) => violation;
else begin
end
STARC_VLOG 2.3.1.1
RULE NAME Use non-blocking assignment in FF inferences
'always' construct infers {FFCount} flip-flop(s) assigned with blocking
assignment(s) (=). Use non-blocking assignments (<=) in FF inferences.
MESSAGE DETAIL-1 FF inference for signal "{ObjectName}", {BACount} blocking
assignment(s):
DETAIL-2 Blocking assignment to FF signal "{ObjectName}".
With standard blocking assignments (=), evaluation timing of the right-hand side and assignment
timing of the left-hand side are done at the same time, but in the case of non-blocking
assignments, assignment to the left-hand side is performed after evaluation of the right-hand side
PROBLEM
is completely finished. For that reason, it is possible to avoid race conditions using non-blocking
DESCRIPTION
assignment.
LEVEL RULE
CHECKER Checker detects always constructs which infer FFs and all signals for which FFs are inferred :
BEHAVIOR – if signal is assigned with blocking (=) assignment => violation
EXAMPLE-1: [1] always construct infer FF for one signal but it is assigned with non blocking assignment (in two
branches) => violation
EXAMPLE-2: [1] blocking assignment is used but process does not infer FF => no violation
always @(CLK or D)
if (CLK) Q = D;
Checker detects 'always' which infers FFs and signals for witch FF is inferred:
CHECKER – if delay for FF signal assignment is not specified (Q <= D) => violation
BEHAVIOR
Note: FF signal assignments made under asynchronous control are not checked
EXAMPLE-1: [1] delay is not specified for FF signal assignment under asynchronous control (reset) => no
violation;
[2] delay is not specified for FF signal assignment under synchronous control (set) => violation;
[3] delay is not specified for FF signal assignment expression => violation;
end
EXAMPLE-2: [1] delay is not specified for signal assignment, but no FF is inferred by the description => no
violation
Q <= DATA;
end
Q <= #1 DATA;
end
#1 Q <= DATA; It is recommended not to use delay values otherw ise than for a flip-
flop signal assignments. RTL and post-synthesis simulation results
end may not match. How ever, if delay is necessary here, use
parameters to enable modification depending on differences in target
technologies.
parameter DELAY = 1;
PROBLEM
DATA
DESCRIPTION REG_B REG_A
GATED_CLK
CLK
EN
Malfunction can occur either during gate simulation or RTL simulation. Upper drawing displays
circuit diagram that is generated from the description above. Think about events order at CLK
rise: it is unclear what signal will change first – GATED_CLK or REG_B (if GATED_CLK is first
=> REG_A will be assigned with old value from REG_B, otherwise – with updated one).
So, such problem doesn't necessarily occur – it depends on simulator. But, it is strongly
recommended to insert delay values into assignment expressions for signals: such style helps to
avoid a lot of problems with simulation dependency on some particular tool). As a result, solution
to the racing problem will depend on particular device only.
LEVEL RULE
Checker scans 'always' statements that infer flip-flops and for each detected intra-assignment
delay (Q <= #DELAY D) – verifies following:
– delay should be specified with integral number (integral numbers are:
constants/parameters of integer/reg/time type), if number is not integral => violation with
message-1
CHECKER
– delay should be positive (in case of parametrized delay – elaboration-time checking is
BEHAVIOR
required)
Note-1: if delay is not integral, it will not be checked that it is positive (in other words, only one
message will be displayed for non-integral negative delay)
Note-2: delay can be specified with integral expression (integral expression is such that consists
of integral constants/parameters only)
EXAMPLE-3: [1] delay is specified with non-integral constant => violation (message-1)
always @( posedge CLK ) begin
if( RESET )
Q <= #(7) 1'b0; Specify delay values w ith integral numbers in flip-flop inferences.
else (note, if specify delay value "-7.7" here => warning message will b e
Q <= #(7.7) DATA; single and same)
end
EXAMPLE-4: [1] delay is not specified (such case is for rule 2.3.1.3 – "set delay values for FF inferences") => no
violation
EXAMPLE-5: [1] delay value is negative in first intra-assignment and non-integral in the second one (but they are
specified not in the flip-flop inference) => no violation
LEVEL RULE
CHECKER Checker scans 'always' statements that infer flip-flops and verifies asynchronous reset controls:
BEHAVIOR
– for each asynchronous reset control signal: edge described in the sensitivity list should
correspond to polarity in the 'if' branch when it is possible to define polarity
– polarity can be detected if following constructs are used in conditions of 'if' branch:
– logical / bitwise 'or' (||, |), concatenations({}), logical / bitwise negation (!, ~)
Note-1: negation of ORed signals is not allowed (it is not the same that
ORing of negated signals)
Note-2: vector in an asynchronous condition is the same as ORing of all its bits
Note-3: ternary operators are allowed and restrictions for “()?” condition are
similar to restrictions for 'if' conditions
– comparisons of following format: <signal / concatenation COMP constant>,
EXAMPLE-1: [1] polarity of asynchronous reset control differs from specified in the sensitivity list => violation
always @( posedge CLK or negedge RESET ) Polarity of asynchronous control signal "RESET" does not match the
edge described in the sensitivity list. In FF inference w ith
begin asynchronous control, pay attention to the negedge or posedge of the
if( RESET )
control signal.
Q <= 1'b0;
else
Q <= DATA;
end Polarity violation in the condition for asynchronous control.
EXAMPLE-2: [1] polarity of asynchronous reset control is parameter-dependent and it differs from specified in
the sensitivity list => violation;
[2] elaboration time checking is required => message will include instance name.
parameter RESET_POLARITY = 0;
always @( posedge CLK or posedge RESET ) Polarity of asynchronous control signal "RESET" does not match the
edge described in the sensitivity list. In FF inference w ith
begin asynchronous control, pay attention to the negedge or posedge of the
if( RESET == RESET_POLARITY ) control signal.
Q <= 1'b0;
else
Q <= DATA;
end Polarity violation in the condition for asynchronous control.
begin
if( RESET1 + RESET2 )
Q1 <= 1'b0; Polarity of asynchronous control signal(s) cannot be detected
else if( (RESET1 - 1) % 2 ) because operator “+” is used in asynchronous control expression.
Q1 <= 1'b0; Define asynchronous control clearly - w ith signal or its
else negation - to avoid problems w ith most of logic synthesis tools.
Q1 <= DATA;
end
Checker scans 'always' statements that infer flip-flops and verifies number of asynchronous
control signals:
CHECKER – it is allowed to use only one asynchronous control signal
BEHAVIOR Note-1: see 2.3.1.6: asynchronous control signal description.
Note-2: if any other signal (asynchronous input) is used as control signal for FF output
assignment, it is treated as presence of 2 asynchronous controls: both set and reset.
EXAMPLE-1: [1] flip-flop with asynchronous reset and synchronous set is described => no violation
(asynchronous control is single)
STARC_VLOG 2.3.2.2
RULE NAME
Do not mix blocking and non-blocking assignments in FF inference
always construct
Detected a mixture of non-blocking (<=) and blocking (=) assignments in the
MESSAGE 'always' construct for sequential circuit. Such description style may not
synthesize.
Coexistence of blocking assignment statements (=) and non-blocking assignment statements
(<=) within a single 'always' construct doesn't cause syntax error and it is allowed by the
PROBLEM language specification. But, such description style must be avoided since it risks to cause errors
DESCRIPTION when using logic synthesis tools.
LEVEL RULE
EXAMPLE-1: [1] sequential 'always' block is described (all signals in the sensitivity list are specified with edges);
[2] blocking and non-blocking assignments are mixed within the 'always' body => violation
EXAMPLE-2: [1] combinational 'always' block is described (signals in the sensitivity list are specified without
edges);
[2] blocking and non-blocking assignments are mixed within the 'always' body => no violation.
STARC_VLOG 2.3.3.1
RULE NAME
Do not use two or more different clock edges within a single always
construct
Different edges are used in {EventControlCount} event control statement(s) for
signal "{SignalName}" in an 'always' construct for a sequential circuit. Such
MESSAGE-1 description style is not synthesizable and should be avoided.
DETAIL {EdgeType} {SignalName}
MESSAGE-2
Edges are mixed with levels in one event control statement. Do not use such
descriptions because they are not synthesizable and should be avoided.
Different edges are used for noncontrol signals within single event control
MESSAGE-3
statement. Such description style is not synthesizable and should be avoided.
From the syntax point of view, it is not restricted to have both rising and falling clock edges
together in a single 'always' construct. But it is prohibited in the real hardware description, since it
PROBLEM is non-synthesizable (it is difficult to implement such description in actual hardware: flip-flops that
DESCRIPTION allow data reading for both clock edges do not exist independently).
LEVEL RULE
Checker detects 'always' statements which contain event control statements with edge specifiers
(negedge, posedge):
– if not the same edges are used for all non-control signals within single event control
expression => violation (message-3)
CHECKER Note: 'control' for 'always' process is a signal which is used in the conditional expression
BEHAVIOR inside a process
– if edge-sensitive signals are mixed with level-sensitive within single event control
expression => violation (message-2)
– if same signals are used with different edges in different event control statements =>
violation (message-1)
EXAMPLE-1: [1] same signals are used with different edges in different event control statements => violation
(message-1)
Different edges are used in 2 event control statements for signal
"CLK" in an 'alw ays' construct for a sequential circuit. Such
always @( posedge CLK ) begin description style is not synthesizable and should be avoided.
Y <= A ^ B;
@( negedge CLK ) posedge CLK
Y <= A & B;
end negedge CLK
EXAMPLE-2: [1] same signals are used with different edges in different event control statements => violation
(message-1)
Different edges are used in 2 event control statements for signal
"CLK" in an 'alw ays' construct for a sequential circuit. Such
description style is not synthesizable and should be avoided.
1) Checker detects 'always' statements which contain event control statements with edge
specifiers (negedge, posedge):
CHECKER
– if not same edge is used in all event controls => violation (message-1)
BEHAVIOR
2) Checker detects 'always' statements where is no event control statement at the top of the
construct (message-2)
EXAMPLE-1: [1] two event controls are used (sets are the same, two edges are different) => no violation; [2] no
event control statement described at the top of 'always' construct => violation (message-2)
always begin Event control statement described in 'alw ays' construct after 'begin'
@( posedge CLK ) keyw ord. Logic synthesis may be impossible for some tools. Specify
Y <= A ^ B; event control statement at the top of an 'alw ays' construct.
@( negedge CLK )
Y <= A & B;
end
EXAMPLE-2: [1] two event controls are used (sets are same, edges are the same) => violation
Identical edges are used in 2 event control statements for signal
"CLK" in an 'alw ays' construct for a sequential circuit. Such
always @( posedge CLK ) begin description style may be not synthesizable and should be avoided.
Y <= A ^ B;
@( posedge CLK ) posedge CLK
Y <= A & B;
end posedge CLK
EXAMPLE-3: [1] three event controls are used (sets are the same, edges are not same for all signals) =>
violation (for signals with same edges)
Identical edges are used in 3 event control statements for signal
"CLK" in an 'alw ays' construct for a sequential circuit. Such
description style may be not synthesizable and should be avoided.
Y <= A | B;
posedge CLK
end
STARC_VLOG 2.3.4.1
RULE NAME Do not specify FF initial values explicitly in initial constructs
Signal “{SignalName}”, for which FF is inferred, is assigned {AssignmentsCount}
time(s) in {InitialCount} 'initial' construct(s). 'initial' construct is ignored by
MESSAGE synthesis tools, use reset signal to initialize FF.
DETAIL-1 FF output is assigned in the 'initial' construct.
It is common case to assign FF initial value in an 'initial' construct. This value will function as
initial value during the RTL simulation. But logic synthesis ignores 'initial' construct and such
PROBLEM
"reset" will not be defined.
DESCRIPTION
LEVEL RULE
Checker collects FF signals from 'always' statements and verifies that these signals are not
CHECKER assigned in an 'initial' constructs
BEHAVIOR
Note: FF signal is such signal for which flip-flop is inferred
EXAMPLE-1: [1] flip-flop is inferred for signal "Q"; [2] signal "Q" is assigned in an 'initial' construct => violation
initial Signal "Q", for w hich FF is inferred, is assigned 1 time(s) in 1 'initial'
Q <= 1'b0; construct(s). 'initial' construct is ignored by synthesis tools, use reset
signal to initialize FF.
always @( posedge CLK ) begin
Q <= DATA; FF output is assigned in the 'initial' construct
end
EXAMPLE-2: [1] latch is inferred for signal "Q"; [2] signal "Q" is assigned in an 'initial' construct => no violation
initial
Q <= 1'b0;
endmodule
STARC_VLOG 2.3.5.1
RULE NAME
Do not use descriptions which to generate FFs having fixed input
values
Inferred FF “{ObjectName}” will have constant input. Do not use descriptions
MESSAGE
which infer FFs with fixed input values.
Fixed input values in FF become untestable and fault detection rate drops extremely
PROBLEM
DESCRIPTION
LEVEL RULE
Checker scans 'always' statements that infer flip-flops and displays violation if FF signal is
CHECKER assigned with constant/parameter within all execution paths of the process
BEHAVIOR
Note: violation is displayed for the first assignment
parameter RESET_LEVEL = 1'b0; Inferred FF "Q" w ill have a constant input. Do not use descriptions
always @( posedge CLK ) begin w hich infer FFs w ith fixed input values.
if( RESET )
Q <= RESET_LEVEL;
else
Q <= 1'b1;
end
STARC_VLOG 2.3.6.1
RULE NAME
Do not mix FF inference with and without asynchronous resets in
the same always construct
Do not mix FF inferences with and without or different asynchronous set/reset
signals in the same 'always' construct.
MESSAGE DETAIL-1 "{SignalName}" is a FF without asynchronous control.
DETAIL-2 "{SignalName}" is a FF with {AsyncControlsCount} asynchronous
control(s).
Descriptions that combine FF inference with and without asynchronous reset are misleading and
understanding the behavior becomes difficult during debug. Consider following example:
always @( posedge CLK or negedge RESET ) begin
if( !RESET )
Q <= 4'b0000;
else begin
Q <= DATA;
K <= DATA;
end
end
In the example FF inference which has an asynchronous reset (for signal Q) and a FF inference
without an asynchronous reset (signal K) are described in the same always construct.
PROBLEM Since some synthesis tools may not perform synthesis correctly, the description should be
DESCRIPTION
written in such a way that the always construct is divided as in following description:
always @( posedge CLK or negedge RESET ) begin
if( !RESET )
Q <= 4'b0000;
else
Q <= DATA;
end
Checker detects always statements which infer FFs and contain an asynchronous reset signal:
CHECKER
BEHAVIOR – if some FF signal is not assigned in an if/case branch for asynchronous reset signal =>
violation
EXAMPLE-1: [1] each of 2 bits of same signal are inferred to be FF, but only one of them has asynchronous
reset => violation
reg [1:0] Q; Do not mix FF inferences w ith and w ithout or different asynchronous
set/reset signals in the same 'alw ays' construct.
always @( negedge CLK or negedge RESET ) begin
if( !RESET ) begin
Q[0] <= 1'b0;
end
"Q[0]" is a FF w ith1 asynchronous control(s).
else begin
Q[0] <= DATA1;
Q[1] <= DATA2;
end
end "Q[1]" is a FF w ithout asynchronous control.
EXAMPLE-3: [1] two FFs are inferred by the description, only one signal is reset, but synchronous reset control
is used => no violation
Checker scan 'always' statements which infer flip-flops with asynchronous controls and verify
conditional branch inclusive at least one asynchronous control:
– if asynchronous control is active high (sensitivity list is checking) => violation (detail-1);
– if asynchronous control is used in an expression with another synchronous signals =>
CHECKER violation (detail-2);
BEHAVIOR – if asynchronous control is used in an expression with another asynchronous signals =>
violation (detail-3);
– if multiple-bit signal is tested as asynchronous control => violation (detail-4).
Note: this checker does not trigger in cases with polarity violation (see 2.3.1.6 for polarity
violations)
always @( posedge CLK or posedge RESET ) Hazardous description of asynchronous reset is detected.
Asynchronous control signal(s) should be one bit only and specified
begin by 'negedge' to avoid problems w ith logic synthesis.
if( RESET )
begin
STARC_VLOG 2.4.1.1
RULE NAME
Clearly distinguish a latch inference from the logic in other
combinational circuits
Possible latch inference for {LatchSigCount} signal(s). Clearly distinguish a latch
MESSAGE inference from the other combinational logic.
DETAIL Signal "{SignalName}" is not assigned in all cases
In general, latches are very similar to the typical combinational circuits in a description. It is not
easy to distinguish latches from combinational circuit => it is recommended to describe latches
PROBLEM
separately from other descriptions.
DESCRIPTION
LEVEL RECOMMENDATION 1
EXAMPLE-2: [1] 'always' construct infers latches for all signals being assigned => no violation
always @( DATA, START, G ) begin
if( G )
Q <= DATA;
else
Y1 <= DATA | START;
end
Checker scans modules which infer at least one latch in any process ('always' or 'assign'):
– if there are inferences of combinational logic (within same or other processes) =>
violation:
CHECKER – if process infers latches mixed with another logic => detail-1;
BEHAVIOR
– if process infers pure latches => detail-2.
Note: latches within instantiated modules are treated as those which do not belong to currently
scanned module.
if ( G )
c = a;
else
c = b;
endmodule
...
always @( D1 or G )
if ( G )
if ( G )
Q2 <= D1;
endmodule
Checker scans 'always' statements that infer latches. Violation is issued if asynchronous reset/set
signal is present. Following conditions are true for such a signal:
– it is used in the condition (ternary condition in the 'assign' construct or 'if'/'case'
condition)
– constant/parameter is assigned to latch signal under this condition:
CHECKER – violation (detail-1): {'x', 'z', '?'} is assigned
BEHAVIOR
– violation (detail-2): '0' is assigned
– violation (detail-3): '1' is assigned
Note-1: see chapter 2.2.1.1: latches inference principles
Note-2: when reset/set detection depends on parameter => elaboration-time checking is required
(message will contain instance name)
EXAMPLE-1: [1] 'always' block describes latch with both asynchronous reset and set => violation;
[2] SET signal is specially omitted in the sensitivity list (synthesis tools ignore sensitivity lists and
latch with asynchronous reset/set will be synthesized either with specified SET or omitted);
always @( RESET, G, SET ) begin 2 asynchronous control signal(s) for latch "Q" is detected. Do not use
if( RESET )
latches w ith asynchronous control
Q <= 1'b0;
else if( SET )
Q <= 1'b1; Asynchronous reset control
else if ( G )
Q <= DATA; Asynchronous set control
end
EXAMPLE-2: [1] 'assign' describes latch with an asynchronous reset => violation
1 asynchronous control signal(s) for latch "Q" is detected. Do not use
latches w ith asynchronous control
assign Q = ( RESET )? 1'b0 : ( G )? DATA;
end
DETAIL-4
Asynchronous loop propagates through submodule instance
“{InstanceName}” from port “{InputPortName}” to “{OutputPortName}”
During the period when gate signal is not active, latch
becomes transparent and data from the D input goes LD
through a latch towards to the output. So, if combinational COMB_LOGIC
feedback loop contains a latch, it means that asynchronous
loop exists.
PROBLEM Static timing analysis tools are used to analyze the circuit
DESCRIPTION operation speed for large designs. Combinational circuit feedbacks carry into the effect of
asynchronous feedback loop and create problems with timing analysis.
Therefore, circuits like this should be avoided regardless they could be acceptable in terms of
their behavior.
LEVEL RULE
Checker scans the design hierarchy to detect feedbacks that are propagated through
combinational paths and/or latch(es):
– see the rule 1.2.1.3 (behavior of this checker is almost the same(*))
CHECKER
(*)
BEHAVIOR – the difference between these checkers is:
– 2.4.1.4 triggers only on asynchronous loop that has latches in the propagation path
– 1.2.1.3 triggers on any asynchronous loop
EXAMPLE: [1] violation is reported in the detailed form: feedback propagation path is described
(DETAILED_PROPAGATION_CHAIN = 1);
[2] consider the design hierarchy at the picture below;
[3] note, that all possible paths (see 1.2.1.3) of feedback propagation are demonstrated:
– through the submodule instance
– through the flip-flop and latch
– through the combinational logic line
– through the intermediate combinational logic line
f7k
A
X2
FF X1 f_and
B LD
«Q1» Y1
f_or
f7k_o «FK» FK
CLK y1 G
L_e
C
input A, B, C, CLK;
output FK;
reg FK; Ins tance "fm 754". "STARC 2.4.1.4" Asynchronous feedback
containing latch(es) is detected. Do not use feedback loops to avoid
wire f7k_o, RST, L_e; problems w ith timing analysis tools.
reg Q1;
always @( A or L_e ) Asynchronous loop propagates through latch "FK" enable input
if( L_e )
FK = A;
endmodule
LEVEL RECOMMENDATION 1
Checker scans design hierarchy for latches and verifies lines that are mapped to the gate pin:
– if there are two latches that are connected (Q -> D) in series(*)
CHECKER
BEHAVIOUR
(*) combinational logic placed between latches is not considered and latches are treated
as sequentially placed (series of latches)
– if latch enable signals are the same and have equal polarity => violation.
EXAMPLE-1: [1] if there are two latches that are connected in series;
[2] latch enable signals are the same and have equal polarity (~CLK) => violation.
output [7:0] Q;
endmodule
//D flop-flop
module dff( CLK, D, Q );
endmodule
//D-latch
module latch( G, D, Q );
input G, D;
output reg Q;
Ins tance "top.LD1". Sequence of latches that have the same clock phase
always @(G, D) w ith latch "Q" is detected. Connect latches so that none of the successive
if ( G ) ones have clock signals of the same phase to avoid errors in data transfers.
Q <= D;
endmodule
Latch "top.LD2.Q" has the same clock phase.
// BB1 interface definition
module bb1 ( CLK, D, Q);
input CLK;
input [7:0] D;
output Q;
endmodule
endmodule
8 FF LD LD FF
8 Q
D BB1 BB2
CLK1
CLK2
STARC_VLOG 2.5.1.1
RULE NAME Create modules for tri-state buffers
Module “{ModuleName}” contains tristate inference mixed with other logic.
Create a simple hierarchical module without any other logic to separate the tri-
MESSAGE-1 state descriptions from other code to avoid inconsistencies with timing analysis
tools.
DETAIL Tri-state buffer is inferred.
MESSAGE-2
Module “{ModuleName}” contains inferences of tri-state buffers from different
signals. Describe different tristates in separate hierarchical modules.
When tri-state buffers are used in the description, there are cases where paths, which do not
require timing analysis, are analyzed. To avoid this problem, the tri-state buffer should be made
in a hierarchical module and delays for it should be specified. A tri-state buffer module should be
created and then instantiated as shown in the picture below.
1) Create hierarchical
module for tri-state
enb buffer
enb1
data tri_mod tri_out
Logic A 2) Instantiate module
with description of
tri-state buffer
enb1
PROBLEM tri-mod1 Logic A
DESCRIPTION
Logic B
top
enb2
The following order is recommended for synthesis of design containing tri-state buffers:
1. compile the tri-state buffer block by itself first;
2. before synthesis of the design, specify input and output delays of the tri-state that has
become a gate;
3. synthesize the design.
LEVEL RECOMMENDATION 3
module top ( din, enb, clk, dout ); Module “top” contains tristate inference mixed w ith other logic. Create
a simple hierarchical module w ithout any other logic to separate the
input din, enb, clk; tri-state descriptions from other code to avoid inconsistencies w ith
output dout;
timing analysis tools.
reg tmp;
wire wtmp;
endmodule
EXAMPLE-2: [1] module contains tristate inference for different signals => violation (message-2).
module top (in1, in2, in3, in4, enb,dout1,dout2);
input in1,in2,in3,in4,enb; Module “top” contains inferences of tri-state buffers from different
output [1:0] dout1; signals. Describe different tristates in separate hierarchical modules.
output [1:0] dout2;
endmodule
EXAMPLE-3: [1] module contains tristate inference along with another logic;
[2] combinational logic is connected to the inputs of the tristate => no violation.
input din1,din2,enb1,rnb2;
output dout;
endmodule
Checker scans conditional statements of if / case / ternary constructs that infer tri-state buffers:
– if conditional expression contains any logic
– expression contains arithmetic / logical operators or it is a vector => violation
(message-1)
– expression contains simple signal, but it is driven by another logic => violation
CHECKER (message-2)
BEHAVIOR Checker scans built-in primitives (bufif0, bufif1, notif0, notif1):
– if parameter which corresponds to control signal contains any logic => violation (same
requirements for displaying message-1 or message-2)
Note-1: buffers and inverters are not considered as logic
Note-2: when two types of violation (with same tri-state) occurs in single case => only one
violation (message-1)
always @ (enb1 or enb2 or in1) Logic is detected at the control input of tri-state “out1”. It is
recommended to describe only simple scalar signals in conditional
if ( enb1 & enb2 ) expressions for tri-state inferences to avoid malfunctions during the
out1<=1'bz; logic synthesis.
else
out1<=in1;
...
...
endmodule
LEVEL RECOMMENDATION 2
module top ( data1, data2, data3, data4, data5, data6, enb1, enb2, enb3, enb4, enb5, dout );
input data1,data2,enb1,enb2;
output tri_out;
Tri-state
driver
2 tri-state
inst_A drivers inst_B
PROBLEM
DESCRIPTION Logic
LEVEL RULE
module top ( in1, in2, in3, in4, in5, enb1, enb2, glbl_out );
input in1,in2;
output mul_out;
Module output port “mul_out” is driven by 2 non-tri-state drivers. Tw o
assign mul_out = in1; or more output drivers other than tri-state ones should not be used in
assign mul_out = in2; the RTL description.
glbl_out
Non-tri-state
driver
Non-tri-state Non-tri-state
driver driver
Non-tri-state driver
mul_connect mul_connect_tri
top
MESSAGE-2
Inout port “{ObjectName}” should not be directly connected to output port
“{PortName}”.
Do not connect a port declared as inout to ports with direct input or output declarations. Paths
that do not exist in the RTL description are generated after logic synthesis is performed, and
PROBLEM
inconsistencies will occur in simulation results in RTL and at the gate level.
DESCRIPTION
LEVEL RULE
MESSAGE--4
Submodule output port “{OutputPortName}” is driven by constant. Avoid
meaningless port connections.
Submodule output port “{OutputPortName}” is driven by expression. Avoid
MESSAGE--5
meaningless port connections.
Connections of an input port, a constant or an expression is meaningless, but could be made by
a mistake. Such connections lead to unexpected design behavior and should be avoided.
PROBLEM
DESCRIPTION Note: this extension is added by Aldec, Inc.
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] input is assigned to the inout throw the temporary signals => violation (message-1)
module top (in, io, out);
input in;
inout io;
output out;
assign io = w;
assign w = in; Inout port “io” should not be directly connected to input port “in”.
assign out = in;
...
endmodule
EXAMPLE-2: [1] inout is directly assigned to output port => violation (message-2)
module top (clk, din, dout);
input clk;
inout din;
output reg dout;
always @(posedge clk) Inout port “din” should not be directly connected to output port “dout”.
dout = din;
endmodule
EXAMPLE-3: [1] if input port drives output port => violation (message-3) ;
[2] expression is connected to output port => violation (message-5).
sub instance_1 (
.I1( 0 ),
.I2( I2 ), Submodule output port “O1” is driven by input port “I1”. Avoid
.O1( I1 ), meaningless port connections.
.O2( O1 )
);
sub instance_2 (
.I1( 0 ),
.I2( I2 ), Submodule output port “O1” is driven by expression. Avoid
.O1( I1 & I2 ), meaningless port connections.
.O2( O2 )
);
endmodule
// Submodule declaration
module sub( I1, I2, O1, O2 );
...
endmodule
always @ (out1)
Signal “out1” is driven by the output of tri-state. It is not recommended
if (out1) to use tri-state signals for conditional expression of 'if' statements.
out2<=1'b0;
else
out2<=1'b1;
LEVEL RECOMMENDATION 2
Checker detects all tri-states in the module and scans description for 'case' statements:
– if any signal is assigned under control of tri-state output from 'case' branch
CHECKER
BEHAVIOR
– if there is no 'default' clause => violation (message-1)
– if 'default' clause is specified, but not all signals are assigned 'x'-es within
the clause => violation (message-2)
EXAMPLE-1: [1] signal is assigned under control of tri-state output from 'case' branch;
[2] there is no 'default' clause at the 'case' statement => violation (message-1)
EXAMPLE-2: [1] signal is assigned under control of tri-state output from the 'case' branch;
[2] 'default' clause is specified, but one bit of the signal is assigned with 'x'-es within the clause =>
violation (message-2)
out1 <= enb ? in1 : 1'bz; Signal “out1” is driven by the output of tri-state w hereas not all
signals are assigned 'x'-es in the 'default' clause. If it is necessary to
always @ (out1) use tristate output in 'case' selection expression, assign 'x'-es in the
'default' clause to enable 'z'-value propagation.
case(out1)
0: out2 <= tmp1;
1: out2 <= tmp2;
Signal “out2[1]” is not assigned 'x'(-es) in 'default' clause.
default: out2[0] <= 1'bx;
endcase
case ( enb )
0: out2<=in1;
1: out2<=1'bz; Selection expression of 'casex(z)' statement contains signal “out2”
default:out2<=1'bx; that is driven by the output of a tri-state. Such description is
endcase recognized as don't care and should not be used to avoid difficulties
casez( out1 ) w ith 'x'-value propagation.
3'b000: out2<=in1;
3'b011: out2<=1'b1;
default: out2<=1'bx;
endcase
STARC_VLOG 2.5.2.1
RULE NAME
Create a block for a tri-state buffer and a block for an input cell
connected directly from a bidirectional bus
Inout port "{PortName}" is directly connected to control line(s). Create a block for
an input cell that is connected directly from a bidirectional bus to prevent 'x'
propagation.
MESSAGE
DETAIL-1 Inout port is directly connected to {PortType} input of {ObjectType}
“{ObjectName}”.
DETAIL-2 Inout port is directly connected to select input of multiplexer.
Bidirectional buses with tri-state buffers may become 'z' momentarily. In that case, RTL code is
optimized to block the propagation of 'z' by additional logic. Consequently, the RTL simulation
result and the synthesized gate level simulation result may differ. For example (see the picture
below), a circuit description using an AND gate to control propagation is added to prevent ‘z’
propagation in the RTL. As a result of synthesis however, the logic circuit containing the AND
gate is optimized, the logic for preventing 'z' propagation is changed to OR, and propagation of
unknown value 'x' may occur, without 'z' propagation being prevented. Since the logic connected
to the control signal may be changed as a result of optimization, some problems may occur.
Therefore, it is necessary to separate the description of this logic from the tri-state bus
PROBLEM description, as well as from the description of the tri-state bus readers, by encapsulating this logic
DESCRIPTION into its own separate module. This should prevent risky synthesis optimization.
LEVEL RECOMMENDATION 2
– (*) to be on the same hierarchy level means to be described in the same module
where 'inout' port is declared:
– logic on the same hierarchy level:
top
FF
enable
asynchronous reset
FF
asynchronous set
clock
enable
asynchronous set
module top (clk1, clk2, sel, d, q); Ins tance "top". Inout port "sel" is directly connected to control
line(s). Create a block for an input cell that is connected directly from
input clk1, clk2, d; a bidirectional bus to prevent 'x' propagation.
inout sel;
output reg q;
wire sel_clk;
endmodule
d
FF
q
0
clk1
1
clk2
top
STARC_VLOG 2.6.1.2
RULE NAME
Use intermediate variables when the same logic is used in more
than two places
The same selection condition ({SelCondition}) is detected {ExpressionsCount}
times in different conditional statements. Use intermediate variables to share the
MESSAGE same logic between different constructs to avoid generation of the same logic
several times with logic synthesis tools.
DETAIL Exactly the same selection condition is detected.
To decrease the number of output signals in one always construct, selection conditions with
exactly the same contents are described in two or more always constructs. This logic should be
shared using an intermediate variable, except for simple logic. Especially, when using an
arithmetic operator with 5 or more bits or a relational operator for conditional expressions – a
PROBLEM
logic synthesis tool may not share it. By describing it twice in two always constructs, the area will
DESCRIPTION
be doubled in size. Therefore, equal logic should be used with caution. It is recommended to
assign the shared logic output to an intermediate variable, and then use it in both processes.
LEVEL RECOMMENDATION 2
Checker verifies conditional expressions from 'if' and ternary conditional statements within current
module:
– if there are two and more equal conditional expressions within different statements =>
CHECKER violation
BEHAVIOR Note-1: context for the rule is following: 'always' statements, continuous assignments and module
instantiations.
Note-2: commutative operators are considered properly: &&, ||, +, *, ==, !=, ===, !==, &, |, ^ (for
example: expressions 'a && b' and 'b && a' are equal).
EXAMPLE-1: [1] there are two equal conditional expressions within different statements => violation.
Note: operator “|” is commutative.
assign tmp = ( ctrl2 | ctrl1 ) ? ... Exactly the same selection condition is detected.
EXAMPLE-2: [1] there are two equal conditional expressions within the same statement => no violation.
always @( * )
begin
if ( ctrl1 | ctrl2 )
...
else if ( ctrl1 | ctrl2 )
end
MESSAGE-2
'always' construct has {OutputsCount} outputs. The number of signal outputs
from one 'always' construct should be limited to {OUTPUTS_MAX} at most.
Number of 'always' construct outputs exceeds recommended one. The number of
MESSAGE-3 signal outputs from one 'always' construct should be
{OUTPUTS_RECOMMENDED} or less, if possible.
Number of 'always' construct outputs exceeds maximum recommended one. The
MESSAGE-4 number of signal outputs from one 'always' construct should be limited to
{OUTPUTS_MAX} at most.
It is not recommended to describe too many output signals in a single always construct. If
possible, five or less is recommended. If such restriction cannot be kept the number of outputs
should be limited to 15 at most. However, it is not problematic to describe any number of
(numerous) descriptions within the same always construct without any logic or signals which
generate the same logic.
PROBLEM
DESCRIPTION RTL descriptions must be checked when unintended simulation results are obtained. If the output
signal structure of each always construct is understood, descriptions that consider the circuit
structure facilitate checking of the signal flow by proceeding with the debugging while monitoring
it.
LEVEL RECOMMENDATION 3
Checker counts the number of signals assigned (with blocking or non-blocking assignment type)
in the synthesized 'always' construct:
– if COUNT_OUTPUT_NUM = “1”
– if number is greater than OUTPUTS_RECOMMENDED => violation
(message-1);
– if number is greater than OUTPUTS_MAX => violation (message-2);
– if COUNT_OUTPUT_NUM = “0”
– if number is greater than OUTPUTS_RECOMMENDED => violation (message-3);
– if number is greater than OUTPUTS_MAX => violation (message-4)
Context:
CHECKER – for edge-controlled always, signal is treated as output if it is:
BEHAVIOR – output port of a module
– read before assignment
– read in another process
– for level-controlled always, signal is treated as output if it is:
– output port of a module
– read in another process and it is an assignment with logic or inside a statement
Note-1: when vector is assigned only bits treated as output are counted.
Note-2: bits of vector defined as outputs are compacted to slices if they are consecutive and
every slice is counted as separate output.
Note-3: values of parameters OUTPUTS_RECOMMENDED and OUTPUTS_MAX are
defined in configuration file (default values are 5 and 15 respectively).
module top(clk,d1,d2,d3,in1,in2,in3,in4,q1,q2,q3);
input clk,d2,d3,in1,in2,in3,in4;
input [1:0] d1;
output reg [1:0] q1;
output reg q2,q3;
reg tmp1,tmp2,tmp3,sel,en; 'alw ays' construct has 3 outputs. The number of signal outputs from
one 'alw ays' construct should be 2 or less, if possible.
always @( posedge clk )
begin
q1 <= d1; //module output
q2 <= en ? d2 : d3; //module output
en <= sel ? tmp1 : tmp2; //signal is read before assignment
end
endmodule
LEVEL RECOMMENDATION 3
STARC_VLOG 2.6.2.1
RULE NAME Do not describe more than one if or case in one always construct
Do not describe more than one 'if' statement or 'case' statement in a single
'always' block
DETAIL-1 'if' statement in the 'always' block
MESSAGE
DETAIL-2 'if' statement in the same 'always' block
DETAIL-3 'case' statement in the 'always' block
DETAIL-4 'case' statement in the same 'always' block
PROBLEM Following example describes a complex 'always' statement:
DESCRIPTION always @( SEL or X_IN or Z_IN) begin
if( SEL ) b lock (1)
TMP_STORAGE = X_IN & Z_IN;
else
TMP_STORAGE = X_IN | Z_IN; b lock (2)
LO_B = TMP_STORAGE[31];
if( TMP_STORAGE[7:0] == 8'b00001111 ) b lock (3)
Z_REG = 1'b0;
else
Z_REG = 1'b1; b lock (4)
if( LO_B == 1'b1 && Z_REG == 1'b0 )
X_REG = 1'b1;
else b lock (5)
X_REG = 1'b0;
R_REG = TMP_STORAGE[30:0];
end
This description mixes several 'if' constructs and the following is a set of "minor" disadvantages:
– relationships between the signals are not clear
– debugging efficiency is extremely low
– it is very easy to make a mistake
And the following is a possible and very important mistake:
– unnecessary priority circuit can be generated. The reason is:
– 'always' block contains description of the sequential process. Signal assigned at
block (2) and block (3) are used in the conditional expression if the 'if' statement at
the block (4) => blocks (2) and (3) have to be executed before block (4). It is
evidently, that execution order is unimportant for (2) and (3). But a priority circuit
may be generated to maintain such parallel operations described within a
sequential block.
Therefore, descriptions using multiple 'if' or 'case' statements must not be used in order to avoid
the problems described above. It is much better to write the same code using separate blocks:
assign LO_B = TMP_STORAGE[31];
b lock (2)
always @( SEL or X_IN or Z_IN ) begin
if( SEL )
TMP_STORAGE = X_IN & Z_IN; b lock (5)
else
TMP_STORAGE = X_IN | Z_IN; b lock (1)
end
LEVEL RULE
Checker restricts usage of more than one 'if'/'case' statement in the single 'always' block:
– following descriptions violate the rule:
– two or more 'if' statements in the same scope
– two or more 'case' statements in the same scope
CHECKER – 'if' and 'case' in the same scope
BEHAVIOR – the following descriptions do not violate the rule:
– one 'if' inside an 'if'/'case' branch
– one 'case' inside an 'if'/'case' branch
Note: in case of violation first 'detail' is displayed without the word "same" (1, 3), whereas all
following – with word "same" (2, 4)
EXAMPLE-1: [1] 'always' block contains multiple (3) if statements in the same scope => violation;
[2] 1st 'if' statement at global scope of the 'always' block contains embedded 'if' => no violation (it is
single within scope of the 1st 'if')
Do not describe more than one 'if' statement or 'case' statement in a
single 'alw ays' block
always @( SEL or X_IN or Z_IN) begin
if( SEL ) 'if' statement in the 'alw ays' block
TMP_STORAGE = X_IN & Z_IN;
if( X_IN == 1'b1 )
INTERNAL = 1'b1;
else begin
TMP_STORAGE = X_IN | Z_IN;
INTERNAL = 1'b1;
end
LO_B = TMP_STORAGE[31] ^ INTERNAL;
if( TMP_STORAGE[7:0] == 8'b00001111 )
Z_REG = 1'b0;
else
Z_REG = 1'b1;
'if' statement in the same 'alw ays' block
if( LO_B == 1'b1 && Z_REG == 1'b0 )
X_REG = 1'b1;
else 'if' statement in the same 'alw ays' block
X_REG = 1'b0;
R_REG = TMP_STORAGE[30:0];
end
EXAMPLE-2: [1] 'always' block contains both 'if' statement and 'case' statement in the same scope => violation;
[2] 1st 'case' branch contains embedded 'if' => no violation (it is single within scope of the 1st 'case'
branch)
Checker verifies signals assigned in the synthesized always block or mapped to an output/inout
CHECKER of task, called from this always block:
BEHAVIOR
– if any of signals is defined in sensitivity list of current always block => violation
EXAMPLE-1: [1] sensitivity list signal is assigned in the always block => violation
always @( in1, in2, in3, tmp ) begin
Sensitivity list of the 'alw ays' block contains signals w hich w ere
out1 = in1 & in2 & in3; assigned in the same 'alw ays' block.
tmp = in1 ^ in2 ^ in3;
EXAMPLE-2: [1] signal bit is included in sensitivity list another bit of the same signal is assigned in the always
block => no violation
end
STARC_VLOG 2.7.1.3
RULE NAME if statement in combinational circuit ends with else (not with else if)
When describing combinational circuits using 'always' construct, 'else' item
MESSAGE should be used at the end of the 'if' statement to avoid generation of erroneous
latches.
When combinational circuit is described with an 'always' construct, it is recommended to use
PROBLEM 'else' item at end of 'if statement. It helps to avoid generation of latches.
DESCRIPTION
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] 'always' statement contains 'if' statement without 'else' item (latch is inferred) => violation
always @( DATA or G or DATA ) begin When describing combinational circuits using 'alw ays' construct,
if( G ) 'else' item should be used at the end of the 'if' statement to avoid
Q = DATA;
generation of erroneous latches.
end
EXAMPLE-2: [1] combinational 'always' contains 'if'-'else if' statement => violation; [2] 'else if' branch contains
embedded 'if' statement without an 'else' item => violation
STARC_VLOG 2.7.2.1
RULE NAME
Reduce conditional expressions of if statement with the same
contents
Branches of the 'if' statement contain {NumberOfBranches} equivalent
subexpressions: “{Subexpression}”. Reduce the comparison logic to clearly
MESSAGE designate comparison priorities.
DETAIL Duplicated subexpression: “{Subexpression}”
Conditional expressions with the same contents generate compare circuits for each conditional
expression. Typically, they are optimized during the structuring process of logic synthesis, but
PROBLEM size of initially synthesized circuits is quite big and performance drops. Conditional expressions
DESCRIPTION with same contents should be avoided.
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] if statement contains branch that will never be executed => violation.
if ( ctrl ) 'if' statement contains branches that w ill not be executed. Avoid
describing such conditions.
q = data1;
else if ( ~ctrl )
q = ~data1;
CHECKER Checker verifies condition branches of 'if', 'case', 'casex', 'casez' statements:
BEHAVIOR – if there is no statement in this branch => violation.
EXAMPLE-2: [1] there is no statement in one of the 'case' branches => violation
case ( sel ) 'case' statement contains condition expression(s) w ith null
2'b00 : q = d1; statements. Missing statements in any condition expression of 'if' or
2'b01 : q = d2; 'case' statement may cause mistakes in coding other condition
2'b10 : ;
2'b11 : q = d3; expressions.
default : q = 1'bx;
STARC_VLOG 2.7.3.1
RULE NAME
The number of nests for if-if and else if is best at five or less. The
number of nests for if-if and else if should be 10 at most
'if' operator is nested {NestedCount} times. It is recommended to use nesting
{RECOMMENDED_NESTING_LEVEL} or less time(s) to avoid generation of
MESSAGE-1 complicated prioritized logic and decrease overall circuit size. When nesting
cannot be avoided, it should be limited to {MAX_NESTING_LEVEL} time(s) at
most.
'if'-'else if'-... conditions chain contains {NestedCount} branches. It is
recommended to use {RECOMMENDED_NESTING_LEVEL} or fewer branch(es) to
MESSAGE-2 improve readability of the description and decrease possibility of nesting
mistakes. When nesting cannot be avoided, it should be limited to
{MAX_NESTING_LEVEL} time(s) at most.
Within a conditional expression of an if statement, a combinational circuit is predictable. As the
number of nests in an if statement increases, prioritized logic is added to this circuit automatically
by logic synthesis. Therefore, when an if statement is too deep, the generated prioritized logic
PROBLEM becomes complicated and overall circuit size increases significantly. As practice shows, nesting
DESCRIPTION should be limited to seven levels. When deep nesting cannot be avoided number of levels should
be 15 at most.
LEVEL RECOMMENDATION 3
Checker scans 'if' statements recursively from the top level to bottom and calculate the number
of:
– cascaded 'if'-'if' nests (at the same level chain with most depth is chosen)
– if calculated number for current 'if' statement is greater than
RECOMMENDED_NESTING_LEVEL => violation (message-1) (lower level "if-if"
CHECKER statements are not scanned more)
BEHAVIOR
– parallel 'else'-'if' nests (from single level only)
– if calculated number for current 'if' statement is greater than
RECOMMENDED_NESTING_LEVEL => violation (message-2)
Note: values of parameters RECOMMENDED_NESTING_LEVEL and MAX_NESTING_LEVEL
are defined in configuration file (default values are 7 and 15 respectively)
EXAMPLE-1: [1] number of nested 'if' statements is greater then RECOMMENDED_NESTING_LEVEL (value of
the parameter is set to 2 to simplify the example) => violation (message-1);
[2] there are two chains of nested statements the longest one is chosen;
'if' operator is nested 4 times. It is recommended to use nesting 2 or
if( ... )
begin less time(s) to avoid generation of complicated prioritized logic and
if( ... ) begin // 2nd nested decrease overall circuit size. When nesting cannot be avoided, it
if( ... ) // 3rd nested should be limited to 15 time(s) at most.
end
if( ... ) begin // 2nd nested
if( ... ) // 3rd nested
if( ... ) // 4th nested
end
end
EXAMPLE-1: [1] 'if' branch which contains only 'if' statement is detected;
[2] NM_NESTED = 3; NM_TRANSFORMED = 2 => violation.
res1 <= c & d; This 'if' statement should be merged w ith the upper level branch.
EXAMPLE-2: [1] 'if' branch statement which contains only 'if' statement is detected;
[2] but assignment is also detected within current branch => no violation.
if ( a ) begin
if ( c )
res1 <= a | b;
res1 <= a & b;
end
STARC_VLOG 2.7.4.3
RULE NAME Do not use fork-join in RTL descriptions (Verilog only)
'always' statement contains {ForkJoinBlocksCount} 'fork-join' block(s). 'fork-join'
MESSAGE-1 blocks cannot be used in RTL descriptions.
DETAIL 'fork-join' block detected.
'task' statement contains {ForkJoinBlocksCount} 'fork-join' block(s). 'fork-join'
MESSAGE-2 blocks cannot be used in RTL descriptions.
DETAIL 'fork-join' block detected.
There are sequential (begin-end) and parallel (fork-join) blocks in Verilog-HDL. But logic
PROBLEM synthesize tools support only sequential blocks, so do not use fork-join statement.
DESCRIPTION
LEVEL RULE
EXAMPLE-1: [1] always block contains embedded fork-join statements => violation (message-1)
always @( in1 or in2 )
'alw ays' statement contains 2 'fork-join' block(s). 'fork-join' blocks
begin : seq_exec cannot be used in RTL descriptions.
fork : sequential_fork
'fork-join' block detected.
#5 temp1 = 2;
fork : to_invoke_next_sequential
join
begin : sequential_zone_invoke_from_parallel
end
join
end
fork
... 'fork-join' block detected.
join
endtask
STARC_VLOG 2.8.1.3
RULE NAME Avoid the overlapping of case items
Case statement contains {TotalOverlapCount} overlapped case clause(s). Avoid
MESSAGE the overlapping of case items.
DETAIL '{CaseItem}' is overlapped.
Since the case statement compares from the top, overlapping values are permitted. When there
are overlapping values of clauses, the first selection expression is executed first. If there are
duplications in the case statements, the logic synthesis tool synthesizes priority circuits with a
similar priority as the if statement, but if there are no overlaps in the branch conditions, then a
circuit that compares values in parallel is synthesized. Logic synthesis tools automatically judge
branch overlaps, but it is also possible to clearly define that there are no overlaps of directives as
PROBLEM
the comment ”//synopsys parallel_case”. If coding is limited so that values do not overlap in case
DESCRIPTION
statements, "//synopsys parallel_case" can be used to gain advantages in area and speed.
However, if using parallel_case when values overlap, the RTL simulation result and the
simulation result of logic gates generated by logic synthesis differ. Therefore, it should never be
done.
LEVEL RECOMMENDATION 1
CHECKER 1) Checker verifies case statements:
BEHAVIOR
– if there is a duplication of case items:
– if the length of selection expression is 'n' and some of the case items have length
'm':
– 'm' < 'n'
– if the lowest 'm' bits of case items with length 'n' are duplicated by case
items with length 'm' and all the rest bits are '0' => violation
– 'm' > 'n'
– if the the lowest 'n' bits of case items with length 'm' are duplicated by
case items with length 'n' => violation
2) Checker verifies casex statements:
– if there is duplication of case items that do not contain don't care conditions ('x' or '?'):
– if the length of selection expression is 'n' and some of the case items have length
'm':
– 'm' < 'n'
– if the lowest 'm' bits of case items with length 'n' are duplicated by case
items with length 'm' and all the rest bits are '0' => violation
– 'm' > 'n'
– if the the lowest 'n' bits of case items with length 'm' are duplicated by
case items with length 'n' => violation
3) Checker verifies casez statements:
– if there is a duplication or overlapping of case items:
– if the length of selection expression is 'n' and some of the case items have length
'm':
– 'm' < 'n'
– if the lowest 'm' bits of case items with length 'n' are duplicated or
EXAMPLE-3: [1] casez statement contains 'x' in one of the items, but no overlapping in such situation => no
violation
casez ( sel )
4'b0001 : out1 = 2'b00;
4'b0010 : out1 = 2'b01;
4'b0100 : out1 = 2'b10;
4'bxxxx : out1 = 2'b11;
default : out1 = 2'bxx;
endcase
EXAMPLE-4: [1] casex statement has overlapped items, that contains don't care value ('?') => no violation
casex ( sel )
4'b0001 : out1 = 2'b00;
4'b0010 : out1 = 2'b01;
4'b0100 : out1 = 2'b10;
4'b???? : out1 = 2'b11;
default : out1 = 2'bxx;
endcase
EXAMPLE-1: [1] case statement do not contain default clause => violation.
case ( sel ) Alw ays add 'default' clauses.
4'b0001 : out1 = 2'b00;
4'b0010 : out1 = 2'b01;
4'b0100 : out1 = 2'b10;
4'b1000 : out1 = 2'b11;
endcase
Checker detects case, casex, casez statements and calculates bit width of selection expression:
– if bit width of case selection expression cannot be defined (part-selection with variable
index is used) => violation (message-1),
note: all branches of this case statement are checked for presence of another case
statements;
Checker collects bit widths of case items:
– if all items has equal bit width and it is different from bit width of the selection expression
=> violation (message-2)
– if there are case item(s) with different bit widths => violation (message-3)
– if there is at least one case item, bit width of which can be defined only at elaboration-
CHECKER time:
BEHAVIOR – if bit widths of all 'case' items can be defined only at elaboration-time only
elaboration-time message is issued
– if bit widths of some 'case' items can be defined at compilation-time, whereas
another items of this 'case' can be defined only at elaboration-time:
– compilation-time violation for elaboration-time items (message-3 + detail-3)
– compilation-time violation for compilation-time items (message-3 + detail-1)
and elaboration-time check are scheduled for them
Note-1: if the width can not be calculated (case item is a part-selection with variable index)
detail-2 is used.
Note-2: bit widths of decimal constants are defined by their values. Violation is displayed only if
constant width is greater than required (narrower decimal constants are allowed).
EXAMPLE-2: [1] bit width of case selection expression is different from bit widths of case items => violation
(message-3)
[2] first case item bit width can be defined at the compilation stage => detail-1
[3] second case item bit width can not be defined at the compilation stage (parametrized) =>
detail-3
STARC_VLOG 2.8.2.1
RULE NAME
As a rule of thumb, divide large tables if they have more than 32
I/Os. (input: 20, output: 12)
'case' statement defines a table with “{InputCount}” inputs and “{OutputCount}”
outputs. It is recommended to limit the table size to
MESSAGE
{RECOMMENDED_INPUT_COUNT} inputs and
{RECOMMENDED_OUTPUT_COUNT} outputs.
A table is correspond to each 'case' statement. The size of a 'case' statement table is determined
by the number of inputs. When the number of inputs grows, table size grows correspondingly.
Large tables cause size increasing and speed decreasing of generated circuit.
However, output count still should be considered. If the number of outputs increases and every
logic is not very similar, area may be increased. In the case of a small table, which has five or
fewer clauses or four or fewer inputs, the output number is not necessary to consider, but for
other cases attention should be paid to the number of outputs.
Therefore, specifying 'case' statements with a large bit width of inputs and outputs causes the
synthesis run time to increase and may further worsen the synthesis results. It is recommended
that the 'case' statement has up to 32 bits including input and output.
'case' statement with large number of inputs may be simplified by dividing the statement into
smaller ones and using 'if' statement. Consider following description example (let's assumes that
recommended number of inputs is equal to 4, to simplify the example):
// initial description
case ( data )
8'b00000001 : code =0;
8'b00000010 : code =1;
8'b00000100 : code =2;
8'b00001000 : code =3;
PROBLEM 8'b00010000 : code =4;
DESCRIPTION 8'b00100000 : code =5;
8'b01000000 : code =6;
8'b10000000 : code =7;
endcase
//simplified description
if ( data [7:4] == 4'b0000 )
case ( data[3:0] )
4'b0001 : code =0;
4'b0010 : code =1;
4'b0100 : code =2;
4'b1000 : code =3;
endcase;
else if ( data [3:0] == 4'b0000 )
case ( data[7:4] )
4'b0001 : code =4;
4'b0010 : code =5;
4'b0100 : code =6;
4'b1000 : code =7;
endcase;
LEVEL RECOMMENDATION 3
CHECKER Checker detects case, casex, casez statements:
BEHAVIOR
– if number of case clauses is greater than SMALL_CASE_CLAUSE_COUNT => checker
counts NI – number of inputs(*):
– (*) number of inputs is defined by number of different signals in case selection
expression (each bit in multiple-bit signals is considered as separate input),
note: if 'case' items are variable NI is defined taking those signals into account;
... Detected 'case' statement defines table w ith “32” inputs and “1”
outputs. Recommended is limit table size to 20 inputs and 12 outputs.
case ( sel )
endcase
...
case ( sel )
endcase
EXAMPLE-1: [1] number of case items is greater than value specified with MAX_CASE_ITEM_EXPRESSIONS
(the value is set to 4 to simplify an example) => violation (message)
case (data) Case statement contains 8 case item expressions. Avoid using case
8'b00000001 : code =0; statements w ith more than 4 case item expressions.
8'b00000010 : code =1;
8'b00000100 : code =2;
8'b00001000 : code =3;
8'b00010000 : code =4;
8'b00100000 : code =5;
8'b01000000 : code =6;
8'b10000000 : code =7;
endcase
STARC_VLOG 2.8.3.1
The don't-care condition is defined by using 'x' as the default
RULE NAME clause (only for default clauses, the extensive use of don't-care is
recommended)
It is recommended to specify 'x' to the output of the 'default' clause. "Don't-care"
condition allows optimization and size of the circuit will be decreased more than
MESSAGE setting a determined value.
DETAIL Signal "{SignalName}" is assigned with determined value.
The 'default' clause is executed if the selection expression specified by the case statement does
not match to any item. Constant value may be specified as the default assignment. But if the
unknown value ’x’ is assigned to the output in the 'default' clause, it is considered as “don’t-care”
PROBLEM and a synthesis tool selects the best assignment (either '0' or '1') to the output during the
DESCRIPTION optimization. Therefore, setting a non-determined value can usually decrease the size of the
generated circuit.
LEVEL RECOMMENDATION 3
EXAMPLE-1: [1] 'case' statement has signal assignment in the default clause;
[2] signal is assigned with non-'x' value => violation
always @(...) It is recommended to specify 'x' to the output of the 'default' clause.
case (sel) "Don't-care" condition allow s optimization and size of the circuit w ill be
4'b0001: res = data1;
decreased more than setting a determined value.
4'b0010: res = data2;
4'b0100: res = data3;
4'b1000: res = data4;
default: res = 1'b0; Signal "res" is assigned w ith determined value.
endcase
EXAMPLE-2: [1] 'case' statement has signal assignment in the default clause;
[2] signal is assigned with non-'x' value;
[3] 'case' is full and optimization is performed => no violation
always @(...)
case (sel)
2'b00: res = data1;
LEVEL RECOMMENDATION 1
always @( ... )
case( sel )
...
default : tmp = 1'bx;
endcase
Don't care 'x' condition is assigned to signal “tmp”.
always @( tmp )
if( tmp == 1'b1 ) Conditional expression in the 'if' uses signal “tmp” that is assigned
...
else w ith don't care 'x' condition. It is recommended to avoid such
... descriptions because after the logic synthesis is completed, it is
unknow n w hether it becomes '0' or '1'.
EXAMPLE-2: [1] 'case' statement assigns 'x'-es in the 'default' clause to an output of the "task_case" task;
[2] task "task_case" returns the value to the variable "tmp" that is also an input of the "task_if" task;
[3] task "task_if" uses this input in conditional expression of the 'if' statement => violation (detail-2).
task task_if;
input t_in1;
...
begin
if( t_in1 == 2'b00 )
... Conditional expression in the 'if' uses signal “tmp” that is assigned
end w ith don't care 'x' condition. It is recommended to avoid such
endtask descriptions because after the logic synthesis is completed, it is
unknow n w hether it becomes '0' or '1'.
always @( ... )
begin
task_case ( ..., tmp );
task_if ( tmp, ... )
end
tmp = res; Conditional expression in the 'if' uses signal “tmp” that is assigned
if( tmp == 1'b1 )
w ith don't care 'x' condition. It is recommended to avoid such
...
else descriptions because after the logic synthesis is completed, it is
... unknow n w hether it becomes '0' or '1'.
case( sel )
...
default : tmp_1 = 1'bx;
endcase
always @( tmp )
CHECKER Checker verifies case, casex, casez statements which contain default clause
BEHAVIOR – if default clause is not the last item => violation.
EXAMPLE-1: [1] case statement contain default clause but it is not the last item => violation.
DETAIL-1
Signal “{DrivenSignalName}” is driven by another signal
“{DriverSignalName}” that is assigned with don't care 'x' condition.
DETAIL-2 Don't care 'x' condition is assigned to signal “{SignalName}”.
When unknowns are generated because of don't care ('x') usage in RTL description simulation, it
is treated as a bug in a design. If signal to which a don't care condition is assigned is used for a
selection expression of a 'case' statement it is recommended to add default clause which assigns
'x' values. In such case 'x' value is propagated and it is easy to find bug. If the default clause
PROBLEM either assign fixed value or does not exist then it is difficult to find bug.
DESCRIPTION
Signals to which 'x' is assigned in the 'default' clause of a 'case' statement should not be used in
a selection expression of a 'case' statement if there is no don't care default clause.
LEVEL RECOMMENDATION 1
EXAMPLE-2: [1] signal "sel" is used in the selection expression of 'case' statement;
[2] the signal is driven by don't care value from function => violation (detail-1 + detail-2).
function res;
...
begin 'x' is assigned to signal “res” w hich is a driver to the signal “tmp”
case( f_sel )
...
default : res = 1'bx;
endcase
end
DETAIL-1
Signal “{DrivenSignalName}” is driven by another signal
“{DriverSignalName}” that is assigned with don't care 'x' condition.
DETAIL-2 Don't care 'x' condition is assigned to signal “{SignalName}”.
'x' values are regarded in 'casex' statement as don't care values (either '0' or '1'). Using the signal
to which a don't care condition is assigned for selection expression of a 'casex' statement may
lead to the differences between RTL and gate-level simulation. And it is also difficult to find bug in
PROBLEM such situation even if 'casex' statement has don't care 'default' clause.
DESCRIPTION Signals to which 'x' is assigned in the 'default' clause of a 'case' statement should not be used in
a selection expression of a 'casex' statement.
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] signal “sel_2” is used in the selection expression of 'casex' statement;
[2] signal “sel_2” is driven by signal “tmp” witch is driven by don't care value within default clause
of 'case' statement => violation (detail-1 + detail-2).
always @( ... )
case( sel_1 )
...
default tmp <= 'bx; Don't care 'x' condition is assigned to signal “tmp”.
STARC_VLOG 2.8.4.3
RULE NAME
It is best to avoid using casex statements and casez statements
(Verilog only)
MESSAGE Avoid using 'casex' and 'casez' statements.
With a casex statement or a casez statement, the value indicated by ’x’ (by 'z' for casez) of the
branch conditions is defined as don’t-care. Don’t-care indicates that it does not matter whether
the value is ’1’ or ’0’. Using don't-care condition in case items should be performed with great
PROBLEM
attention because may easily lead to overlapping or duplication of items and as a result to
DESCRIPTION
worsening the circuit quality. So It is best to avoid using casex statements and casez statements.
LEVEL RECOMMENDATION 3
LEVEL RECOMMENDATION 1
CHECKER Checker detects 'casex' statements:
BEHAVIOR
– if there are duplications or overlapping of case items that contain don't-care conditions
('x', 'z' or '?') => violation (message-1):
– If the length of a case item is not equal to the length of the selection expression –
the case item is either truncated of filled with zeroes ('0') to the length of the
selection expression. Thus, an unexpected duplication or overlapping may occur.
Example:
parameter MASK1 = 5'b100x1;
parameter MASK2 = 3'd3;
...
casex ( A[3:0] )
MASK1 : ...
4'b0x11 : ...
MASK2 : ...
...
endcase
After parameter substitution, items will virtually look like this:
casex ( A[3:0] )
5'b100x1 : ... // will be truncated to 4'b00x1
4'b0x11 : ...
3'b011 : ... // will be extended to 4'b0011
...
endcase
After normalization to 4 bits, items will actually look like this (overlapping occurs):
casex ( A[3:0] )
4'b00x1 : ... // 5'b100x1 truncated to 4 bits
4'b0x11 : ...
4'b0011 : ... // 3'b011 extended to 4 bits
... Casex statement contains 2 overlapped case clause(s). Use 'do not
care' condition carefully to avoid the duplication of case items.
casex ( sel )
4'bxx00: ...
4'bx001: ...
4'bx011: ... '4'bxx00' is overlapped.
4'bx100: ...
default: ...
endcase
'4'bx100' is overlapped.
... Casex statement contains items that may cause the generation of
additional logic that decreases circuit quality. Describe priority logic
casex ( sel )
w ith triangular form of 'do not care' conditions in case items.
6'bxxxx00: ...
6'bxxx011: ...
6'bxx0111: ...
6'bx0111x: ...
default : ...
endcase
...
casex ( sel )
6'bxxxxx0: ...
6'bxxx0x1: ...
6'bxx01x1: ...
6'b0x11x1: ...
6'b1x1101: ...
6'b101111: ...
default : ...
endcase
STARC_VLOG 2.8.5.1
Do not force parallel_case in a case statement directive that
RULE NAME depends on
a particular logic synthesis tool (Verilog only)
MESSAGE
Do not force 'parallel_case' directives that depend on particular logic synthesis
tool. RTL and post-synthesis simulation results may differ.
In Verilog-HDL syntax, case statements are processed in order from the top line by a sequential
process. If there are no overlaps in the clause described in the case statement, the logic
synthesis tool interprets the values to be parallel and generates a circuit with no priority. If there
is a duplicated value of clauses, the values are interpreted as a sequential process and a circuit
with a priority is generated. If Design Compiler directive //synopsys parallel_case is
specified, values will be forcibly treated as parallel case even if there are overlapping values.
PROBLEM Therefore, there is a possibility of the RTL simulation results and gate level simulation results
DESCRIPTION
differing. So it is not recommended to use the directive.
If the circuit is to be operated in parallel, a case statement without overlapping items should be
used. If it is to be operated in priority, process should be described with help of an if-else-if
construction.
LEVEL RECOMMENDATION 1
LEVEL RECOMMENDED 1
EXAMPLE-1: [1] selection expression of case statement is constant (parameter expression) => violation.
...
endcase
EXAMPLE-1: [1] case statement contains variable case clauses => violation;
[2] there are two variable case items: signal is used as case item, expression with signal and
parameter (result of expression is variable).
reg tmp;
parameter tmp_param;
Selection expression of the case statement should not be constant.
always
...
case ( selection )
Case clause expression is not constant: “tmp”.
tmp : ...
tmp & tmp_param : ...
endcase
EXAMPLE-1: [1] logical operation is used in selection expression of case statement => violation
case( sel1 || sel2 )
Do not describe logical operations and arithmetic operations in the
1'b0: out1 = in1; selection expression of a 'case' statement.
1'b1: out1 = in2;
endcase
endcase
EXAMPLE-3: [1] logical and arithmetic operations are used in selection expression => violation
Note: only one message generated for one case statement
endcase
STARC_VLOG 2.8.6.1
When complex nested if statements and case statements co-exist, it
RULE NAME is more advantageous to have fewer conditionals with multiple
matches than fewer matches with multiple conditionals
'case' statement contains multiple 'if' statements with the same structure -
MESSAGE
possibility of generating a redundant and larger circuit exists. Description of one
'if' statement with multiple conditional branches, containing one 'case' statement
per branch, is recommended (state machine description is an exception).
With nesting where 'if' statements and case statements coexist, it is more advantageous to have
fewer 'if' conditionals with multiple matches in 'case' statements. When starting the description,
try to describe using this structure if possible. There is chance that both descriptions (with
multiple 'case' statements and with multiple 'if' statements) will infer the same optimal circuit. But
when describing one 'case' statement, containing 'if' statement with multiple conditional branches
per each item possibility of generating redundant logic increases. However, in cases where
PROBLEM coding in this manner might increase the amount of code, it would result in an increased number
DESCRIPTION of input signals. This could result in worse circuit performance. Circuit structure should be kept in
mind when creating descriptions.
In the case of state machines, following the recommendation lowers readability, thus making
debugging difficult. State machines are an exception to this recommendation; following it also
lowers the quality of results, especially area.
LEVEL RECOMMENDATION 3
CHECKER Checker detects detect 'case', 'casex', casez' statements:
BEHAVIOR
– if statements satisfy following conditions:
– every 'case' item contains only one 'if' statement;
– 'if' statements have same branch structure;
– note: if 'case' statement has 'default' clause:
– if default clause is optimized => the clause is not verified at all;
– default clause is not optimized:
– 'default' contains only 'if' statement with the same structure => the clause
is considered as item;
– otherwise => the clause is not considered;
– number of case items is calculated (CASE_ITEM_COUNT) calculate the number 'if'
branches (IF_BRANCH_COUNT):
– if CASE_ITEM_COUNT belongs to [CASE_ITEM_MIN:CASE_ITEM_MAX] range
and IF_BRANCH_NUM belongs to [IF_BRANCH_MIN:IF_BRANCH_MAX] range
=> violation
– exception: if 'if' statements has parallel structure (exclusive conditions) => such
situations are skipped:
if (A && !B) statement1 else if (B && !A) statement2;
Note: parameters CASE_ITEM_MIN, CASE_ITEM_MAX, IF_BRANCH_MIN, IF_BRANCH_MAX
define ranges (of 'case' items number and 'if' branch number) to be verified by the checker.
Default parameters values:
– CASE_ITEM_MIN = 8;
– CASE_ITEM_MAX = 0;
– IF_BRANCH_MIN = 1;
– IF_BRANCH_MAX = 4.
EXAMPLE-1: [1] every 'case' item contains only one 'if' statement;
[2] every 'if' statement has the same branch structure;
[3] CASE_ITEM_COUNT = 4 ( belongs to [0:4] ), IF_BRANCH_NUM = 3 ( belongs to [1:4] ) =>
violation.
Note: parameters values are default ones except CASE_ITEM_MIN, its value is set to 4 to simplify
the example.
EXAMPLE-2: [1] every 'case' item contains only one 'if' statement;
[2] every 'if' statement has the same branch structure;
[3] 'default' clause contains 'if' statement with same structure, but 'default' is optimized (all possible
values of signal sel are listed within 'case' items);
[3] CASE_ITEM_COUNT = 4 ( does not belong to [0:5] ) => no violation.
Note: parameters values are default ones except CASE_ITEM_MIN, its value is set to 5 to simplify
the example.
case ( sel )
2'b00: if (a) statement1 else statement2;
2'b01: if (a) statement3 else statement4;
2'b10: if (a) statement5 else statement6;
2'b11: if (a) statement7 else statement8;
default: if (a) statement9 else statement10;
endcase
2.9.1 Do not use for statements other than for simple repeating
statements
STARC_VLOG 2.9.1.1
RULE NAME
Do not use for statements other than for simple repeating
statements.
'for' statement infers cascade logic. Such descriptions are dangerous because
MESSAGE logic synthesis tools could create improper balanced tree structure. It is
recommended to avoid 'for' statements other than simple repeating statements.
'for' statement should be used only for simple repeating. When parity check circuit is described,
balanced tree structure is inferred according to the timing constraints. In case when sets of
assignment source and target intersect (see the examples below) cascade logic is generated.
PROBLEM Balanced tree structure would be inferred depending on the timing constraints of the logic
DESCRIPTION synthesis tool, but if this series is too long, it is uncertain whether the tree structure would be
inferred properly.
LEVEL RECOMMENDATION 2
EXAMPLE-1: [1] the set of RHS signals intersects with the set of LHS signals (index from another iteration is
used) => violation
for ( i = 0; i <= 3; i = i + 1 ) 'for' statement infers cascade logic. Such descriptions are dangerous
out[i] = out[i+1]; because logic synthesis tools could create improper balanced tree
structure. It is recommended to avoid 'for' statements other than
simple repeating statements.
EXAMPLE-2: [1] the set of RHS signals intersects with the set of LHS signals (variable itself is used as RHS and
LHS) => violation
for ( i = 0; i <= 3; i = i + 1 ) 'for' statement infers cascade logic. Such descriptions are dangerous
out = out ^ some_sig[i]; because logic synthesis tools could create improper balanced tree
structure. It is recommended to avoid 'for' statements other than
simple repeating statements.
EXAMPLE-3: [1] the set of RHS signals does not intersect with the set of LHS signals => no violation.
for ( i = 0; i <= 7; i = i + 2 ) //loop variable increment is 2 => even bits are in set of LHS
out[i] = out[i+1]; //shift in RHS is 1 => odd bits are in set of RHS
MESSAGE-3
Loop variable is modified within a 'for' statement. It is allowed to modify loop
variable only in the incremental part of the 'for' statement.
'For' statements define loop iteration by numerically increasing the index variable. It is described
by using following form:
for( initialization_expression; conditional_expression; loop_step_expression )
begin
// statement body
end
that should be described carefully to synthesize a good circuit. Following rules should be
considered when describing 'for' statement:
– loop variable should be initialized with a constant in the initialization expression
PROBLEM
DESCRIPTION – loop iteration conditional expression should be comparison with a constant
– loop step increment should be an expression with arithmetic operator operating with
loop variable and constant
– loop variable should be the same in all parts of 'for' statement
– loop variable should not be modified within a 'for' statement body
Using these principles minimize possible problems with synthesis tools, since violation of these
principles leads either to synthesis failure or inappropriate results.
LEVEL RULE
EXAMPLE-2: [1] conditional expression doesn't contains comparison operator => violation (message-1, detail-2);
initial value, condition and increment of the 'for' statement should be
for( i = 0; i + 100; i = i + 1 ) begin constant
ACCUM = ACCUM + i;
end Conditional expression does not contain a comparison operator
EXAMPLE-3: [1] loop variable is compared not with a constant => violation (message-1, detail-3)
initial value, condition and increment of the 'for' statement should be
for( i = 0; i < REG_A; i = i + 1 ) begin constant
ACCUM = ACCUM + i;
end Loop variable must be compared w ith a constant
EXAMPLE-4: [1] loop step expression doesn't contains an arithmetic operator => violation (message-1, detail-4);
[2] loop variable is modified within the loop body => violation (message-3);
[3] loop variable is compared with parameter in the conditional expression => no violation
EXAMPLE-5: [1] loop step expression operates with loop variable and not a constant => violation (message-1,
detail-5)
STARC_VLOG 2.9.2.1
RULE NAME
Do not describe any arithmetic operations other than with loop
variable and constant
Argument of an arithmetic operation inside the loop is not a loop variable or a
MESSAGE constant.
DETAIL {ObjectClass} "{ObjectName}" is not a loop variable or a constant
Consider following code:
for( i = 0; i <= 15; i = i + 1 ) begin
REG_Z[i] = REG_A + REG_B;
end
'for' statement contains an arithmetic operation not with loop variable. Descriptions defined in 'for'
statements are copied for the number of specified loops. Therefore, additional circuits are created
to execute "REG_A + REG_B" 16 times, as defined by the loop => area is increased. Following
code describes arithmetic operation outside 'for' statement:
PROBLEM
DESCRIPTION TMP = REG_A + REG_B;
for( i = 0; i <= 15; i = i + 1 ) begin
REG_Z[i] = TMP;
end
Area increase problem (described above) will not occur if executing an arithmetic operations with
loop variable and constant values only. In general, common statements should be kept outside
'for' statements as much as possible.
LEVEL RULE
Checker scans 'for'-loops and detects an arithmetic operations (+, -, *, /, %, **) within them:
– if any argument of arithmetic operation is not a loop variable or constant => violation
Note-1: violation is generated for whole vector in case of bit-selections and slices with non-
CHECKER
BEHAVIOR constant indexes
Note-2: loop variable is such signal (or signals which comprise a concatenation) that is assigned
in the initialization expression of the 'for' statement (and all upper-level 'for' statements in case of
their nesting).
EXAMPLE-1: [1] 'for' loop contains an arithmetic operation with loop variable and parameter => no violation
parameter INC = 1;
for( i = 0; i < 8; i = i + 1 ) begin
RES[i] = i + INC;
end
EXAMPLE-2: [1] 'for' loop contains an arithmetic operation with signals (neither loop variable nor constant) =>
violation;
[2] different classes "{ObjectClass}" are demonstrated (port and signal)
input [3:0] INP_A; Argument of an arithmetic operation inside the loop is not a loop
reg [3:0] REG_B; variable or a constant.
...
for( i = 0; i < 8; i = i + 1 ) begin
Port "INP_A" is not a loop variable or a constant
RES[i] = INP_A * REG_B;
If logical operation exist within 'for' statement degradation of circuit quality may be avoided by
using 'case' statement in the described way. Also such common expression may be kept outside
'for' statement (see 2.9.2.1 for details).
LEVEL RECOMMENDATION 3
Checker scans for loops and detects expressions, where relational ('>', '<', '>=', '<=') or logical
('&&', '||', '!') operation is used::
– if any argument of this operation is not a loop variable or constant => violation.
Note-1: see rule 2.9.2.1 for loop variable definition.
Note-2: see rule 1.1.1.2 for {ObjectClass} substitution table.
Note-3: {OperationType} is defined by the following table:
CHECKER
BEHAVIOR {OperationType}
logical
relational
logical/relational
reg [8:0] A; Argument of a logical operation inside the loop is not a loop variable or
reg [8:0] B; a constant. Such descriptions should be avoided because they could
lead to decrease of the circuit operation speed.
for( i = 0; i < 8; i = i + 1 ) begin
if ( i <= max_size )
RES[i] = A[i];
end
LEVEL RECOMMENDATION 1
Checker scans 'for' loops for relational or logical operations other than with loop variables and
constants (see 2.9.2.2):
– if it is possible to calculate the range between initial value and iteration condition:
– if the range is greater than LOOP_NUMBER parameter value => violation
CHECKER (message-1);
BEHAVIOR
– if the initial value or the iteration condition are expressions with signals, variables =>
violation (message-2).
Note-1: value of LOOP_NUMBER parameter is defined in configuration file (default value is 10).
Note-2: this checker triggers concurrently with 2.9.2.2.
reg [15:0] A;
for( i = 0; i < 16; i = i + 1 ) The range of the number of loops is 16. When 'for' loop description
begin
infers comparison circuit, it is recommended to limit the loop variable to
if ( i <= B ) up to 10 times to avoid a decrease in circuit quality.
RES[i] = A[i];
end
reg [15:0] A;
if ( i <= B )
RES[i] = A[i];
end
EXAMPLE-2: [1] logical operation detected within 'for' loop;
[2] both arguments of the operation are signals;
[3] range between initial value and iteration can not be calculated => violation (message-2).
Note: LOOP_NUMBER parameter value is set to 5.
LEVEL RULE
Checker scans 'always' statements those infer flip-flops and include 'for' loops:
CHECKER
BEHAVIOR – if asynchronous set/reset condition is used inside the same 'for' loop statement with
synchronous part => violation
EXAMPLE-1: [1] reset part and logic part are in the same 'for' loop => violation.
always @( posedge clk or posedge rst ) Detected use of the asynchronous reset and logic parts in the same
for loop statement. Use for loop statement separately from the reset
for ( i = 0; i <= 3; i = i + 1 )
and the logic parts, because such description may not be supported
begin
if ( rst ) by synthesis tools.
out[i] <= 1'b0;
else 'for' statement includes asynchronous reset and logic parts.
out[i] <= data[i];
end
EXAMPLE-2: [1] separate 'for' loops with reset and logic parts => no violation.
always @( posedge clk or posedge rst )
begin
if ( rst )
for ( i = 0; i <= 3; i = i + 1 ) // separate loop
out[i] <= 1'b0;
else
for ( i = 0; i <= 3; i = i + 1 ) // separate loop
out[i] <= data[i];
end
STARC_VLOG 2.10.1.4
RULE NAME Do not compare with 'x' or 'z'
MESSAGE Comparison operand contains: {ExprValue}. Do not compare with 'x' or 'z'.
Comparison operators may return 1 if the expression is true and 0 if the expression is false. But if
there are any 'x' or 'z' bits in the operands the the result becomes unknown and expression takes
PROBLEM the value 'x'. So do not compare with 'x' or 'z' to get correct comparison results. Moreover,
DESCRIPTION comparison with 'x' is ignored in logic synthesis tools.
LEVEL RULE
Checker scans comparison operators ==, !=, <, <=, >, >= and verifies only expressions that
contain signals on one of the sides (pure constant expressions are optimized at the compilation
CHECKER or elaboration stage):
BEHAVIOR
– if another side contains constants, which includes 'x' or 'z' bits (3'bxxx, 'bz, 2'bx0, etc)
=> violation
EXAMPLE-1: [1] signal is compared with value containing one 'z' bit => violation
if ( tmp == 2'b1z )
Comparison operand contains:2'b1z. Do not compare w ith 'x' or 'z'.
...
EXAMPLE-2: [1] loop variable is compared with 32 bits in length unknown value => violation
for ( i = 0; i <= 'bx; i = i + 1 )
EXAMPLE-2: [1] unknown value is used in assignment in case item => violation
case (sel)
2'b01 : out1 = 2'0x;
2'b10 : out1 = 2'11; An assignment w ith an 'x' in the right-hand side is detected. The
default : out1 = 2'00; results of RTL and post-synthesis simulation may not match.
endcase
Checker scans description for constant operands containing 'x' or 'z' values:
– if pure constant assignment => no violation (see 2.10.1.5)
– if comparison operators (==, !=, <, <=, >, >=) => no violation (see 2.10.1.4)
– if case equality operators (===, !==) => violation
CHECKER
BEHAVIOR – if increment/decrement loop variable => violation
– if non-constant assignment (containing signals in RHS) => violation
Note-1: expressions in initialization assignments are also checked.
Note-2: implicit comparison operators are also considered (it is allowed by Verilog language to
specify pure constant expression in the if condition, case selection expression, ternary condition)
EXAMPLE-1: [1] unknown value is used in the expression assigned in default clause of case statement (second
argument is signal) => violation;
[2] pure constant expression (only one constant) which contains unknown values is assigned =>
no violation;
[3] pure constant expression (constant and parameter) which contains unknown values is
assigned => no violation
parameter p = 3'b101;
reg tmp;
...
case (sel)
1'b0: out1 <= 3'bxxx; Illegal constant: 3'bxxx. Do not use values containing 'x' or 'z'.
1'b1: out1 <= 3'bzzz & p;
default: out1 <= tmp + 3'bxxx;
endcase
EXAMPLE-2: [1] increment loop variable expression contains unknown value => violation
integer i;
for (i = 0; i < 7; i = i + 1'bx)
... Illegal constant: 1'bx. Do not use values containing 'x' or 'z'.
EXAMPLE-3: [1] unknown value is used in the expression in initialization assignment => violation
reg [1:0] tmp1; Illegal constant: 2'b1x. Do not use values containing 'x' or 'z'.
reg [1:0] tmp2 = 2'b1x & tmp1;
EXAMPLE-4: [1] implicit comparison with one bit unknown value => violation
assign out1 = ( 1'bx ) ? in1 : in2 ;
Illegal constant: 1'bx. Do not use values containing 'x' or 'z'.
STARC_VLOG 2.10.3.1
RULE NAME
Clearly match the bit widths of the right side and the left side of
relational operators (Verilog only)
Right side bit width "{RHSWidth}" of relational operator "{OpName}" does not
MESSAGE match to bit width "{LHSWidth}" of the left side. Use equal bit widths to avoid
confusion.
When two operands of different bit lengths are used and one or both of the operands is unsigned,
the smaller operand is zero filled on the most significant bit side to extend to the size of the larger
PROBLEM operand. Such extension may easily lead to mistakes or misunderstanding. Clearly match the bit
DESCRIPTION widths of the right side and the left side of relational operators to avoid any confusions.
LEVEL RECOMMENDATION 2
EXAMPLE-1: [1] argument bit width at the right side do not match to bit width of argument at the left side =>
violation
wire [7:0] W_SLOT_A; Right side bit w idth “6” of relational operator “<” does not match to bit
wire [5:0] W_SLOT_B; w idth “8” of the left side. Use equal bit w idths to avoid confusion.
wire [7:0] W_SLOT_C;
wire [7:0] W_OR;
Checker verifies each assignment ('=', '<=', 'assign') where right-hand-side is expression with bit-
wise operators only:
– bit width of each operand should be the same as bit width of assignment destination:
– if bit width of whole right-hand-side expression is greater than bit width of
assignment target => violation (message-1: {CompareResult} = "greater", detail per
each argument with erroneous bit width)
– if bit width of whole right-hand-side expression is less than bit width of assignment
target => violation (message-1: {CompareResult} = "less", detail per each argument
with erroneous bit width)
CHECKER
BEHAVIOR – if bit width of whole right-hand-side expression is equal to bit width of assignment
target => each argument of the expression is verified if it has less bit width than
assignment destination (message-2 is displayed in case of violation with one detail
per each erroneous argument)
Note-1: this rule can be dependent on parameters or hierarchical references => elaboration-time
checking is required for such cases
Note-2: this checker verifies only cases where right-hand-side is an expression with bit-wise
operators only. This is made intentionally, since checker 2.10.3.3 verifies cases where right-
hand-side is expression of other type (for example, an expression with bit-wise and arithmetical
operators)
Bit-w ise expression w idth "7" is less than bit w idth "8" of the
wire [5:0] W_SLOT_B;
wire [6:0] W_SLOT_C; assignment destination. Match bit w idths exactly w hen using bit-w ise
wire [7:0] W_OR; operators.
EXAMPLE-4: [1] right-hand-side expression contains not only bit-wise operators => no violation of this rule even
for operands with erroneous bit width (this is case for 2.10.3.3)
Checker verifies each assignment ('=', '<=', 'assign') where right-hand-side expression doesn't
belong to the following set:
– pure function call (it is case for 2.1.3.2)
– signal/expression of integer type (it is case for 2.10.4.3)
– expression including bit-wise operators only (it is case for 2.10.3.2)
CHECKER – signal/expression of signed type (it is case for 2.10.6.2)
BEHAVIOR
Checker works for all another cases (bit width of right hand side should be the same as bit width
of assignment destination):
– if bit width of right-hand-side expression is greater than bit width of assignment target =>
violation
Note-1: this rule can be dependent on parameters or hierarchical references => elaboration-time
checking is required for such cases
EXAMPLE-1: [1] right-hand-side doesn't belong to the set (described in the ""checker behavior" section);
[2] right-hand-side is wider than assignment target => violation
wire [7:0] W_SLOT_A; Assignment source bit w idth "9" is greater than destination bit w idth
wire [5:0] W_SLOT_B; "8". Upper bits of the right-hand side w ill be truncated. Match bit
wire [8:0] W_SLOT_C; w idths exactly to improve the readability of the description.
wire [7:0] W_OR;
integer SLOT_A;
integer SLOT_B;
reg [15:0] R_SUM;
LEVEL RECOMMENDATION 2
Checker verifies each assignment ('=', '<=', 'assign') where right-hand-side expression doesn't
belong to the following set:
– pure function call (it is case for 2.1.3.2)
– signal/expression of integer type (it is case for 2.10.4.3)
– expression including bit-wise operators only (it is case for 2.10.3.2)
– signal/expression of signed type (it is case for 2.10.6.2)
CHECKER Checker works for all another cases:
BEHAVIOR
– if bit width of right-hand-side expression is less than bit width of assignment target =>
violation
Note-1: this rule can be dependent on parameters or hierarchical references => elaboration-time
checking is required for such cases.
Note-2: bit widths of decimal constants are defined by their values; violation is issued only for
decimal constants that are wider than RHS of an assignment (narrower decimal constants are
allowed).
EXAMPLE-1: [1] bit width of RHS of continuous assignment is less then LHS => violation
input [3:0] in1; Assignment source bit w idth "2" is less than destination bit w idth "2".
output [3:0] out2; Upper bits of the right-hand side w ill be filled w ith zeroes. Match bit
w idths exactly to improve the readability of the description.
assign out1 = in1[3:2];
EXAMPLE-2: [1] bit width of RHS, described in true condition part of ternary operator, is less then LHS =>
violation
input [3:0] in1; Assignment source bit w idth "4" is less than destination bit w idth "8".
input [7:0] in2; Upper bits of the right-hand side w ill be filled w ith zeroes. Match bit
output [7:0] out;
w idths exactly to improve the readability of the description.
assign out = ( in1 > in2 ) ? in1 : in2;
EXAMPLE-3: [1] bit width of RHS is less then LHS, but pure function call is used => no violation ( 2.1.3.2 )
wire [32:0] a;
wire [32:0] b;
assign b = func( a );
LEVEL RECOMMENDATION 2
EXAMPLE-1: [1] constant without base specifier is a part of RHS of assignment => violation
assign D = ( A ^ 2'b11 ) / 2'16;
Base is not specified for “16”. It is recommended to specify base
format ('d, 'b, 'h, 'o) for all the numeric values.
EXAMPLE-1: [1] constant without bit width specified is used in conditional expression of if statement=> violation
reg in1;
Bit w idth is not specified for the constant: 1.
always @( in1 )
if ( in1 == 'd1 )
out1 = 1'b0;
else
out1 = 1'b1;
EXAMPLE-2: [1] decimal constant without bit width specified is used in conditional expression of if statement,
but compared argument has integer type => no violation
integer in1;
always @( in1 )
if ( in1 == 'd1 )
out1 = 1'b0;
else
out1 = 1'b1;
Checker scans literal constant values defined with base number part:
– if constant bit width does not match to base number part => violation
Length of each digit in the constant is defined by its base:
CHECKER
– hexadecimal: 4 bits per digit
BEHAVIOR
– octal: 3 bits per digit
Note:for decimal constants violation is issued only when specified constant has greater
bit width than base number part
EXAMPLE-1: [1] constant 'b10' bit width matches to base number part 2 => no violation;
[2] constant 'd10' bit width does not match to base number part 2 => violation;
tmp = (in1 ^ 2'b10) + 2'd10 Bit w idth “4” of the value “d10” does not match the bit w idth “2” of
base number part. It is recommended to match bit w idths clearly for all
the constants and parameters unless there is a special reason not to
do so.
EXAMPLE-2: [1] constant 'b0' bit width matches to base number part 4 => violation;
assign out1 = {4'b0, in1} Bit w idth “1” of the value “b0” does not match the bit w idth “4” of base
number part. It is recommended to match bit w idths clearly for all the
constants and parameters unless there is a special reason not to do
so.
STARC_VLOG 2.10.4.1
RULE NAME Do not use data types other than reg, wire and integer
Module "{ModuleName}" uses data types other than reg, wire and integer. It is
MESSAGE not allowed in RTL description.
DETAIL {ObjectClass} "{ObjectName}" has type: {TypeName}.
Synthesis of different data types required special libraries and conversion functions. Moreover, it
is not supported by all synthesis tools. It is recommended to use only reg, wire and integer data
PROBLEM
types to avoid unexpected synthesis results.
DESCRIPTION
LEVEL RULE
module top; Module "top" uses data types other than reg, w ire and integer. It is not
allow ed in RTL description.
time time_signal;
parameter real param1 = 10.32;
Signal "time_signal" has type: time.
...
Parameter "param1" has type: real.
endmodule
EXAMPLE-1: [1] right-hand-side is an expression with integer and literal constant members; [2] right-hand-side is
less than assignment target => violation (message-1);
integer SLOT_A;
integer SLOT_B;
reg [63:0] R_SUM;
Right hand side of the assignment is 32-bit integer that is less than bit
always @( SLOT_A, SLOT_B )
w idth "64" of left hand side. Upper bits of the left hand side w ill be
R_SUM = SLOT_A + SLOT_B + 1; filled w ith zeroes. It is recommended to match bit w idths exactly.
EXAMPLE-2: [1] right-hand-side is an expression with integer and literal constant members; [2] right-hand-side is
wider than assignment target => violation (message-2);
integer SLOT_A; Right hand side of the assignment is 32-bit integer that is greater than
integer SLOT_B;
bit w idth "16" of left hand side. Upper bits of the right hand side w ill
reg [15:0] R_SUM;
be truncated. It is recommended to match bit w idths exactly.
assign R_SUM = SLOT_A + SLOT_B;
integer SLOT_A;
integer SLOT_B;
reg [31:0] R_SUM;
LEVEL RULE
Checker verifies procedural (blocking ( = ) and non-blocking (<=)) assignment statements to the
CHECKER signals of an integer type:
BEHAVIOR
– if right-hand side of this assignment evaluates to negative value => violation
EXAMPLE-1: [1] negative value is assigned to the integer signal => violation
integer int_var;
always @ ( ... )
A negative value is assigned to a variable of 'integer' type: -2.
int_var = -2;
integer int_res;
always @ ( ... )
A negative value is assigned to a variable of 'integer' type: -5.
int_res = p_int + p_sig;
...
CHECKER Checker detects procedural and continuous assignments to signals of unsigned reg/wire type:
BEHAVIOR – if right-hand side of this assignment evaluates to negative value => violation
EXAMPLE-1: [1] negative integer value is assigned to the integer signal of the reg type => violation.
reg tmp;
always @ ( ... )
A negative value “-1” is assigned to a variable of 'reg' or 'w ire' type.
tmp = -1;
wire tmp;
A negative value “-3” is assigned to a variable of 'reg' or 'w ire' type.
assign tmp = 3'sb101;
wire tmp;
STARC_VLOG 2.10.5.3
RULE NAME Do not describe three or more shared arithmetic operations
Arithmetic operation "{Operation}" is used in {BranchCount} conditional
branches. If resource sharing is expected by a logic synthesis tool, circuit speed
MESSAGE may degrade. Do not describe {OperationCount} or more shared arithmetic
operations
DETAIL Operator may be shared
Resources sharing uses the same operators for SEL
multiple operations to reduce the resources necessary
for simultaneous operations. Following is description
where operations are not shared:
if( SEL == 1'b0 )
RES = REG_A + REG_B;
REG _B
+
else MUX
RES = REG_A + REG_C;
+
REG_A RES
Structure at the right side corresponds to case when
each branch operation is executed and operation
result is selected by multiplexer. REG_C
Note, that conditional branches of the 'if' statement are not executed simultaneously.
Consecutively, "+" operator can be shared (operands are placed on the input side of multiplexer
and operators are shared by a single element). SEL
EXAMPLE-1: [1] 'if' statement contains more than two arithmetic operators that may be shared => violation
(default configuration allows two shared operations);
[2] note, that total count of operations is 4, but warning is issued only since 3 operations in the
parallel branches (first branch contains nested 'if' statement with two operations, but they are
issued as one operation within first branch);
EXAMPLE-3: [1] ternary operator contains three operations possible to be shared => violation
Arithmetic operation is used in 3 conditional branches. If resource
assign RES = ( SEL == 3'b111 )? sharing is expected by a logic synthesis tool, circuit speed may
REG_A % REG_B: degrade. Do not describe 3 or more shared arithmetic operations
( SEL == 3'b101 )?
REG_B % REG_D: Operator may be shared
( SEL == 3'b001 )?
REG_B + REG_D:
REG_X % REG_Z;
Operator may be shared
Checker detects continuous assign statements with the ternary operator and scans the right-hand
CHECKER side for arithmetical operators (+, -, *, /, %, **):
BEHAVIOR
– if arithmetic operator is used in different branches of ternary operator => violation
EXAMPLE-1: [1] division is used in both branches of ternary operator => violation
assign ARITH_1 = ( SEL )? A / B - C : C / A + B;
Arithmetic operator "/" is used in multiple conditional branches of a
ternary operator in an 'assign' statement. Some tools do not perform
resource sharing on 'assign' statements. Use 'alw ays' statements
w ith "if-else" descriptions if resource sharing is expected by a logic
synthesis tool.
EXAMPLE-2: [1] division is used in both branches of ternary operator, but operator is specified in an always
block => no violation
always ( SEL, A, B, C )
ARITH_1 = ( SEL )? A / B - C : C / A + B;
STARC_VLOG 2.10.6.1
RULE NAME
Carry-out should be considered for bit widths of signals to which
operation results will be assigned.
Bit width “{DestBitWidth}” of assignment destination takes into account
{CarryBits}-bit carry-out that is possible for assignment source. When it is
MESSAGE
necessary to consider the carry-out, it is recommended to describe carry-out
logic separately from arithmetic expressions.
In arithmetic operations, bit width should be specified correctly keeping carry-out output in mind.
Usually it is not recommended to adjust target width considering possible carry-out. But to avoid
date lost you should describe carry-out logic separate from an arithmetic operation as shown in
the example:
PROBLEM reg a,b,c,res;
DESCRIPTION
assign res = a + b; //result of arithmetic operation
assign c = a & b; //carry-out signal
LEVEL RECOMMENDATION 3
Checker scans assignment expressions which contains arithmetic operator (“+” or ”-”):
– bit-widths of the assignment source (S_BW) and destination (D_BW) are calculated,
then
– source bit width that considers carry overflow is also calculated (SO_BW)
– if ( SO_BW != S_BW ), and
CHECKER
BEHAVIOR – if ( SO_BW == D_BW ) => violation
Note: assignments to be checked:
– continuous ('assign');
– procedural (blocking/non-blocking);
– conditional (?:).
reg a,b; Bit w idth “2” of assignment destination takes into account 1-bit carry-
wire [1:0] res; out that is possible for assignment source. When it is necessary to
assign res = a + b; consider the carry-out, it is recommended to describe carry-out logic
separately from arithmetic expressions.
reg a;
reg [1:0] b,c; Bit w idth “3” of assignment destination takes into account 1-bit carry-
reg d,e,f; out that is possible for assignment source. When it is necessary to
consider the carry-out, it is recommended to describe carry-out logic
wire res1; separately from arithmetic expressions.
wire [2:0] res2;
LEVEL RECOMMENDATION 1
Checker verifies each assignment ('=', '<=', 'assign') where right-hand-side is signed expression
with "+" and "-" operators only:
– bit widths of each operand should be the same and equal to bit width of assignment
destination:
– if bit width of whole right-hand-side expression is greater than bit width of
assignment target => violation (message-1: {CompareResult} = "greater", detail per
each argument with erroneous bit width)
– if bit width of whole right-hand-side expression is less than bit width of assignment
target => violation (message-1: {CompareResult} = "less", detail per each argument
CHECKER with erroneous bit width)
BEHAVIOR – if bit width of whole right-hand-side expression is equal to bit width of assignment
target => each argument of the expression is verified if it has less bit width than
assignment destination (message-2 is displayed in case of violation with one detail
per each erroneous argument)
Note-1: this rule can be dependent on parameters or hierarchical references => elaboration-time
checking is required for such cases
Note-2: this checker verifies only cases where right-hand-side is a signed expression with "+" or
"-" operators only. This is made intentionally, since checker 2.10.3.3 verifies cases where right-
hand-side is expression of other type (for example, an unsigned expression or expression with
another operators)
input signed [7:0] P_1; Signed expression w idth "32" is greater than bit w idth "8" of the
input signed [7:0] P_2 assignment destination. It is necessary to match exactly the bit w idths
output [7:0] OP_Z;
of signed operands and assignment destination.
...
reg signed [3:0] INTRNL; Signed expression arguments have different bit w idth. Match bit
... w idths exactly w hen using signed operations.
assign OP_Z = P_1 - P_2 – INTRNL;
Bit w idth of the argument is "4"
reg arg; Pay extra attention w hen operating signed and unsigned signals. It is
reg dest; recommended to distinguish clearly betw een signed and unsigned
arithmetic operations to avoid problems w ith bit w idth adjusting.
always @( ... )
dest = arg - 1;
reg arg1; Pay extra attention w hen operating signed and unsigned signals. It is
reg signed arg2; recommended to distinguish clearly betw een signed and unsigned
arithmetic operations to avoid problems w ith bit w idth adjusting.
always @( ... )
reg arg1;
integer arg2;
integer dest;
always @( ... )
reg [15:0] a,b,c,d; Multiplier w ith 32-bit output is inferred. It is recommended to use
reg [63:0] res; libraries w ith high performance multipliers or describe them in a logical
assign res = a * b + c * d; operation (w hen multiplier output is greater than 16 bits).
assign c = (a + b) * c;
RULE NAME
Do not use division
- Exception in the case of division by power of 2
MESSAGE-1
Divisor == {ObjectValue}. Do not use division, except in the case of division by
the power of 2.
Divisor expression is not constant. Do not use division, except in the case of
MESSAGE-2
division by the power of 2.
MESSAGE-3
Divisor == {ObjectValue}. Do not use modulus, except in the case of division by
the power of 2.
Divisor expression is not constant. Do not use modulus, except in the case of
MESSAGE-4
division by the power of 2.
Most logic synthesis tools do not support division (/) so do not use division, except in the case of
division by the power of 2 (or you may use your own divider circuit implementation). In case of
PROBLEM division for the power of 2, such as 2, 4, 8, 16, the operation is just a shift operation and therefore
DESCRIPTION division can be used.
LEVEL RULE
assign out1 = in1 / 3; Divisor == 3. Do not use division, except in the case of division by the
pow er of 2.
assign out1 = in1 % (in2 + 2); Divisor expression is not constant. Do not use modulus, except in the
case of division by the pow er of 2.
RULE NAME
Do not describe more than one arithmetic operation in one line
(except for carry-in A+B+CIN(1bit))
{ArithOperCount} arithmetic operators are described within the same expression.
When more than one operation is performed in one expression, arithmetic
MESSAGE operators will be synthesized in a linear fashion. In general, it is not
recommended to describe more than one arithmetic operation in one line (except
for carry-in A+B+CIN(1bit)).
Describing more then one arithmetic operation per single expression may cause 2 and more bits
to carry around the end. Bit width on the two sides of an assignment is different in this case, and
it is not be recommended. Also, when more than one operation is performed in one expression,
arithmetic operators will be created in a linear fashion. To clarify the order of operations, this kind
of operation should be described as one operation per statement.
However, there is an exception to this recommendation. Consider an example below:
PROBLEM reg [1:0] a;
DESCRIPTION
reg [1:0] b;
assign res = a + b + c;
In this case, when the third term is 1 bit, there is no problem because an adder with a carry-in
input is generated.
LEVEL RECOMMENDATION 3
assign res = { a + b + c, d - e };
EXAMPLE-2: [1] two arithmetic operations (“+”) are detected in every two branches of conditional operator;
[2] first branch does not contain one-bit operands => violation-1;
[3] second branch does not contain one-bit operands => violation-2
Note: separate violation per every branch.
EXAMPLE-3: [1] one arithmetic operation (“+”) is detected within subexpression in parentheses => no violation;
[2] two operations (“+” and ”-”) are detected within expression on top level and it does not contain
one-bit operands => violation.
assign res = a * b * (c + d) / 2 – e + f;
STARC_VLOG 2.10.7.1
RULE NAME
Do not use arithmetic operation in the conditional expression of if
statements
An arithmetic operation is detected in the conditional expression of an 'if'
MESSAGE-1
statement. Prefer using intermediate variables to share resources
MESSAGE-2
An arithmetic operation is detected in the conditional expression of an ternary
operator. Prefer using intermediate variables to share resources
Arithmetic operations within conditional expressions of 'if' statements or ternary operators are not
participating in the automatic resource sharing:
always @( INP_A or INP_B or INP_C )
if( INP_A - INP_B > 4'b0101 )
RES = 4'b0000;
else if( INP_A - INP_B - INP_C > 4'b1000 )
RES = 4'b0110;
else
RES = 4'b1111;
end
PROBLEM Intermediate variables should be used in such cases (it is recommended to use 'assign'
DESCRIPTION statement):
assign TMP = INP_A – INP_B;
always @( INP_A or INP_B or INP_C )
if( TMP > 4'b0101 )
RES = 4'b0000;
else if( TMP - INP_C > 4'b1000 )
RES = 4'b0110;
else
RES = 4'b1111;
end
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] arithmetic operation is used in the conditional expression of 'if' statement => violation
always @( A or B or C )
if( A + B > C ) An arithmetic operation is detected in the conditional expression of
RES = 1'b1; an 'if' statement. Prefer using intermediate variables to share
else resources
RES = 1'b0;
EXAMPLE-2: [1] arithmetic operation is used within index expression => no violation (only loop variable and
constant are used)
for( i = 0; i < 31; i = i + 1 )
if( REG_A[i+1] > REG_A[i]) begin
TMP = REG_A[i+1];
REG_A[i+1] = REG_A[i];
REG_A[i] = TMP;
end
STARC_VLOG 2.10.8.1
RULE NAME
Don’t use arithmetic and logical expressions at the right and left
sides of the division or modulus operator
MESSAGE
Do not use arithmetic and logical expressions at the right and left sides of the
division or modulus operator.
Divider and modulus logic is even slower than multipliers; so care should be taken about the bit
width of a divider. If there is a shift operation at the right or left side of the division or modulus
operator, the logic synthesis tool can not determine the bit width. Consequently, a 32-bit divider
might be inferred.
In order to ensure a deterministic divider width, arithmetic and relational operators should not be
used at the right and left sides of the division and modulus operators. Use of logical expressions
cause the divider width to be deterministic. But divider and modulus logic is complicated and
PROBLEM
slow. So you should code divider and modulus logic separately from logical operations.
DESCRIPTION
It should be taken into account that some logic synthesis tools generate an error if the bit width at
the right side of an operator is greater than that of the left side. There are logic synthesis tools
that support resource sharing between division and modulus logic. However, resource sharing is
not achieved unless the bit widths of the right and left sides of an operator and the variable to
which the result is assigned are identical.
LEVEL RULE
1) Checker scans division (/) and modulus (%) operators in a synthesis context:
– context for search
– always processes
– assign (continuous, including assignment in net declaration)
– synthesize task/function
– task/function call arguments
– instance port map
– index of bit-selection
– if arguments (both left and right side) contains any of operators mentioned below =>
violation
– forbidden operations:
CHECKER
BEHAVIOR – arithmetic operations (+, -, *, /, %, **, <<, >>, <<<, >>>)
– logical operations (!, &&, ||, ==, !=, ===, !==)
– relational operations (<, <=, >, >=)
Note: following constructs are not checked:
– initial processes
– parameter definitions
– parameter redefinition (generic map, defparam)
– initialization assignment to reg
– conditional expression of for statements
– index of part-selection
– index of signal declaration
– delay and event control statement expression
EXAMPLE-1: [1] arithmetic operation is used in the left side of division operation => violation
assign res = ( a + b ) / c;
Do not use arithmetic and logical expressions at the right and left
sides of the division or modulus operator.
Checker scans division (/) and modulus (%) operators in a synthesis context:
– context for search (see 2.10.8.1)
– if the left argument is greater than LEFT_ARGUMENT_WIDTH_MAX parameter =>
CHECKER violation
BEHAVIOR Note-1: LEFT_ARGUMENT_WIDTH_MAX parameter (maximum bit width of the dividend) is
defined in the rule configuration (default is 12)
Note-2: if argument's width cannot be defined at the compilation stage – it is checked at the
elaboration stage
EXAMPLE-1: [1] the left argument of division operator is greater than LEFT_ARGUMENT_WIDTH_MAX
parameter (default 12) => violation
reg [15:0] a;
reg [7:0] b; Left side of the division or modulus operator is 16 bits w ide. Keep the
reg [7:0] c; left side of the division or modulus operator w ithin 12 bits.
assign c = a / b;
Checker scans division (/) and modulus (%) operators in a synthesis context:
– context for search (see 2.10.8.1)
– if the right argument is greater than RIGHT_ARGUMENT_WIDTH_MAX parameter =>
violation
CHECKER
BEHAVIOR – if the right argument is a power of 2 its width is not checked
Note-1: RIGHT_ARGUMENT_WIDTH_MAX parameter (maximum bit width of the divisor) is
defined in the rule configuration (default is 8)
Note-2: if the argument width cannot be defined at the compilation stage – it is checked at the
elaboration stage
reg [7:0] a;
reg [7:0] b; Right side of the division or modulus operator is 8 bits w ide. Keep the
reg [7:0] c; right side of the division or modulus operator w ithin 4 bits.
assign c = a % b;
EXAMPLE-2: [1] right argument is greater than RIGHT_ARGUMENT_WIDTH_MAX parameter (default 8) but it
is parameter with value equal to power of 2 => no violation
Note: elaboration phase is required to judge it is no violation
reg [7:0] a;
reg [7:0] c;
parameter [32:0] b = 32;
assign c = a % b;
Checker scans division (/) and modulus (%) operators in a synthesizable context:
– context for search (see 2.10.8.1)
– if left argument is greater than LEFT_ARGUMENT_WIDTH parameter => violation
– if right argument is greater than RIGHT_ARGUMENT_WIDTH parameter => violation
CHECKER – if right argument is a power of 2 its width is not checked
BEHAVIOR Note-1: LEFT_ARGUMENT_WIDTH and RIGHT_ARGUMENT_WIDTH parameters (maximum
bit width of the dividend and divisor) are defined in the rule configuration (default are 12 and 8
respectively)
Note-2: if argument's width can not be defined at the compilation stage – it is checked at the
elaboration stage
EXAMPLE-1: [1] left argument is greater than LEFT_ARGUMENT_WIDTH parameter (default 12) and right
argument is greater than RIGHT_ARGUMENT_WIDTH (default 8) parameter => violation
reg [15:0] a;
reg [15:0] b; Minimize the bit w idths at the right and left sides of the division and
reg [15:0] c; modulus operators. Recommended argument bit w idths: left = 12, right
assign c = a % b; = 8.
EXAMPLE-2: [1] left argument is greater than LEFT_ARGUMENT_WIDTH parameter (default 12) => violation
reg [15:0] a;
reg [3:0] b; Minimize the bit w idths at the right and left sides of the division and
reg [15:0] c; modulus operators. Recommended argument bit w idths: left = 12, right
assign c = a % b; = 8.
STARC_VLOG 3.1.3.2
RULE NAME
The port description order should be clock, reset, input, output,
inout
Module “{ModuleName}” has not desirable order of port declaration. Following
MESSAGE-1 port description order is recommended: {DESIRED_PORT_ORDER}.
DETAIL Port “{PortName}” is {PortType}.
MESSAGE-2 Rule configuration parameter "DESIRED_PORT_ORDER" has improper value.
[INFO] Default value will be used. See help for details.
Defining the port description order according to convention makes it possible to reduce errors
when calling the function library from an upper level. The port description should be in order of
basic control signals such as clock, reset, and enable, then input, output and inout. There is no
PROBLEM particular description order within input, output and inout, but collecting signals according to
DESCRIPTION application whenever possible will contribute to error reduction. It is recommended to describe I/O
ports for the module instantiation in the same order as its module declaration.
LEVEL RECOMMENDATION 2
module ff_rst_syncset ( Module “ff_rst_syncset” has not desirable order of port declaration.
d, Follow ing port description order is recommended: {“clock”, “reset”,
clk, “enable”, “input”, “output”, “inout”}.
rst_x,
set,
en, Port “d” is input.
q);
Port “clk” is clock.
endmodule
EXAMPLE-2: [1] port 'c' is used as enable and clock signal, but clock is earlier in the list so port 'c' is treated as
clock;
[2] port order does not corresponds to parameter DESIRED_PORT_ORDER value ( { “reset”,
“clock”, “enable”, “input”, “output”, “inout”} ) => violation.
Note: no port of 'reset' type, but it does not have any affect (such situation is correct).
module top ( Module “top” has not desirable order of port declaration. Follow ing
c, port description order is recommended: { “reset”, “clock”, “enable”,
set, “input”, “output”, “inout”}.
d1,
d2, Port “c” is clock.
d3,
q1,
q2); Port “set” is set.
assign q1 = c ? d1 : q1;
EXAMPLE-3: [1] port order corresponds to parameter DESIRED_PORT_ORDER value ( {“clock”, “reset”,
“enable”, “input”, “output”, “inout”} ) => no violation.
Note: ports of some types are skipped, but it does not have any affect (such situation is correct).
input clk,d;
output reg q;
endmodule
STARC_VLOG 3.1.4.4
RULE NAME Do not describe multiple assignments in one line
MESSAGE
Multiple statements are described in the single line. Describe one statement per
line to improve RTL description readability.
Describing multiple assignments per line is not recommended from standpoint of readability
(especially comma-separated assignments). But inserting more then one statement in the same
PROBLEM line also makes description difficult to read and to understand. Therefore, it is better to place only
DESCRIPTION one statement per a single line.
LEVEL RECOMMENDATION 3
if ( en ) q = d; else q = 1'bz;
Multiple statements are described in the single line. Describe one
statement per line to improve RTL description readability.
reg a,b; Multiple statements are described in the single line. Describe one
assign a = in1 | in2, b = in1 & in2; statement per line to improve RTL description readability.
LEVEL RECOMMENDATION 3
Checker scans source code in current file for lines which have number of characters greater than
parameter MAX_NUM_OF_CHARACTERS:
CHECKER – when first of such lines is detected => violation
BEHAVIOR Note-1: value of MAX_NUM_OF_CHARACTERS parameter is specified in configuration file
(default value is 110).
Note-2: one warning message is issued per file.
EXAMPLE-1: [1] there is a line which length is greater than MAX_NUM_OF_CHARACTERS parameter in the
file => violation.
Note: MAX_NUM_OF_CHARACTERS parameter value is changed to 50 to simplify the example.
Source file contains line entries that exceed the recommended length
of 50 characters per line.
assign res = ctrl ? data1 : data2; //very long and important comment
STARC_VLOG 3.2.2.4
RULE NAME
File names specified by `include should be made into relative paths
(../include/common.h)
File “{FileName}” is detected in the current directory. Inclusion by simple file
name is necessary when included file exists in the directory specified by +incdir
+<directory_name>. Otherwise, files specified by `include directive should return
MESSAGE-1 to the directory that is one level higher (../one_level_higher/file_to_include).
Executions of simulation and logic synthesis are usually performed in separate
directories and such style allows to distinguish files that are necessary for
particular stage.
Files specified by `include directive should return to the directory that is one
MESSAGE-2
level higher (../one_level_higher/file_to_include). Executions of simulation and
logic synthesis are usually performed in separate directories files that are
necessary for particular stage.
Design data require many files in addition to RTL and test bench files. If these files are all saved
in the same directory, it will become impossible to distinguish between necessary and
unnecessary files. Executions of simulation and logic synthesis are done in separate directories,
that is why it is unsafe if simply using <file_name.h> since another file may be invoked. For the
file specified by `include directive, its path should be described as a relative path, which returns
PROBLEM to the directory that is 1 level higher.
DESCRIPTION In a large scale design, RTL descriptions are stored in predefined locations. With this type of
design, there is a limit in specifying the file using a relative path. In this case, options of each tool
can be used to specify the file name. Specifying location of including files by +incdir+<directory
name> is allowed by most Verilog simulators.
LEVEL RECOMMENDATION 1
Checker detects file inclusion compiler directive and scans filename specified:
– if name (absolute/relative path) does not return to the directory that is one level higher
CHECKER => violation (message-2)
BEHAVIOR
– if filename is simple name (does not have absolute/relative path specified) and file
specified by this name exists in the current directory => violation (message-1)
`include "definitions.h"
File “definitions.h” is detected in the current directory. Inclusion by
simple file name is necessary w hen included file exists in the
directory specified by +incdir+<directory_name>. Otherw ise, files
specified by `include directive should return to the directory that is
one level higher (../one_level_higher/file_to_include). Executions of
simulation and logic synthesis are usually performed in separate
directories and such style allow s to distinguish files that are
necessary for particular stage.
`include "../definitions.h" Files specified by `include directive should return to the directory that
is one level higher (../one_level_higher/file_to_include). Executions of
simulation and logic synthesis are usually performed in separate
directories files that are necessary for particular stage.
CHECKER Checker detects text macro definitions (definitions made with `define directive):
BEHAVIOR – if defined macro text contains any other text macros => violation
EXAMPLE-1: [1] text macro definition contains usage of another macros => violation.
`define delay1 10 Declaration of nested macro “delay1”.
`define delay2 20
Declaration of nested macro “delay1”.
`define delay3 `delay1 + `delay2;
STARC_VLOG 3.2.3.1
RULE NAME
For component instantiations, connect ports by name connections,
not by ordered list
Ordered port connections are used for component instantiation. Prefer named
MESSAGE
port connections to avoid port position mistakes.
The connection of ports by name clearly describes the correlation between the component port
and the connected net name. Such description is easier to understand since it is possible to
match upper net names with the port names. The second is the connection of ports by ordered
PROBLEM
list that describes the net in the port description order of the lower components. It is easer to
DESCRIPTION
describe, but incorrect connections may result. So it is recommended to connect ports by names.
LEVEL RULE
DETAIL-2
Bit width of the connection is "{NetWidth}" while bit width of the port
"{PortName}" is "{PortWidth}"
When bit width of connected net it greater than bit width of component port => upper bits of the
net are truncated. Otherwise, when bit width of the net is less than bit width of component port =>
upper bits of port are filled with zeros. Data can be misaligned or lost.
PROBLEM Descriptions with different bit widths may be made inadvertently – they are implicit and readability
DESCRIPTION of the description drops. Concatenations/part-selections should be used to describe
filling/truncation explicitly.
LEVEL RULE
STARC_VLOG 3.2.4.3
RULE NAME Do not use defparam statements
MESSAGE
Do not use 'defparam' statements. Some logic synthesis tools do not support
'defparam'.
defparam can be used for rewriting parameters by hierarchical parameter names. If a defparam
assignment conflicts with a module instance parameter, the parameter in the module takes the
PROBLEM value specified by the defparam. While defparam has such benefit of replacing the parameter
DESCRIPTION values, it should not be used because some logic synthesis tools do not support defparam.
LEVEL RECOMMENDATION 1
...
STARC_VLOG 3.3.1.1
RULE NAME
The clocks must be able to be controlled directly from external
input ports
Clock input of FF “{FFName}” is not directly controlled from external input port.
MESSAGE The clocks must be able to be controlled directly from external input ports,
otherwise scan insert tool will exclude FF from the scan.
When DFT scan chains are inserted, the most important is to consider structure of the circuit in
such way, that will enable safe scan shift during the scan test.
When clock pin of flip-flop cannot be directly controlled from an external input port, scan chain
insertion tool excludes such flip-flop from the scan chain. Such exclusion disables faults detection
by ATPG tools for any parts for which scans have not been inserted.
FF
PROBLEM COMB_LOGIC Violation FF
DESCRIPTION
CLK
When it is impossible to control the clock signal from an external port, switching circuitry should
be used to enable direct control in the test mode.
LEVEL RULE
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to the
clock pin of each flip-flop:
– if there is a multiplexer that is directly(*)connected to the clock pin of an FF => no
violation (case for 3.3.1.3)
(*)
CHECKER directly or through buffers/inverters
BEHAVIOR
– if there is a situation that is not covered by following rules => violation:
– OR with two inputs is connected to the clock pin (3.3.5.3, 3.3.5.6);
– AND with two inputs is connected to the clock pin (3.3.5.4, 3.3.5.5);
– latch output is connected to the clock pin of FF (3.3.5.7).
EXAMPLE-1: [1] module 'dff' which infers flip-flop with a clock signal controlled from an external input;
[2] module instantiation statements create two named instances:
– the external signal is mapped to the clock signal in instance 'u_dff_1';
– the output of combinational logic is mapped to the clock signal in instance 'u_dff_2' =>
violation.
endmodule
wire clk_gate;
endmodule
Logic
MUX select signal is fixed
to ‘1’ for testing
TST
LEVEL RULE
CHECKER Checker scans the design hierarchy for multiplexers that have output connected to the FF clock
BEHAVIOUR pin:
– if the multiplexer select signal is an output of combinational logic that has at least one
external port connected to the gate ('and', 'or', 'nand', 'nor') before select pin => no
violation;
CLK1
FF
0
CLK2
1
TST
Logic
– if the select pin is controlled directly from external port => no violation;
CLK1
FF
0
CLK2
1
TST
Logic
mux2x1 MUX ( .IN1( CLK1 ), .IN2( CLK2 ), .SEL( ff_out ), .Q( mux_out ));
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
// Multiplexer
module mux2x1( IN1, IN2, SEL, Q );
input SEL;
input IN1,IN2;
Ins tance ''top''. Selection betw een clock systems is not controllable from an
output reg Q;
external port. The single clock system must be selected throughout testing
always @(*) otherw ise it is impossible to insert scan.
if ( SEL)
Q = IN1;
else
Q = IN2;
endmodule
0
CLK1
1
FF
Q2
SEL FF
CLK3
top
S O M E_ S IG
RAND_LOGIC FF
FF
RAND_LOGIC 0
No direct Direct
control control
CLK 1
Direct
PROBLEM control
DESCRIPTION
As it shown on the picture above, if the output of random logic is to be used as a clock,
insert a selector at the final output of the random logic to make it possible to select an
external clock.
LEVEL RECOMMENDATION 1
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to the
clock pin of each flip-flop:
– if there is a multiplexer that is directly(*) connected to the clock pin of an FF and at least
one input is external => no violation
(*)
CHECKER directly or through buffers/inverters
BEHAVIOR
– if there is a situation that is not covered by following rules => violation:
– OR with two inputs is connected to the clock pin (3.3.5.3, 3.3.5.6);
– AND with two inputs is connected to the clock pin (3.3.5.4, 3.3.5.5);
– latch output is connected to the clock pin of FF (3.3.5.7).
EXAMPLE-1: [1] output of random logic multiplexer is connected to clock pin of flip-flop “Q";
[2] both multiplexers inputs are internally generated signals => violation.
FF
D Q
CTRL1
0
CLK 1
CTRL2
SEL
DETAIL
Asynchronous {ControlType} control is not directly controlled from
external input port.
DFT requires paying special attention to the clock systems when inserting scans
(3.3.1.1). Along with clocks, the reset lines should be considered with special care: DFT
requires that there is no reset could be applied during the scan shift (it would cause the
data loss).
FF FF
COMB _LOGIC
PROBLEM
DESCRIPTION Violation
RST
ATPG tools will also not be able to detect faults at reset lines that are not directly
controlled from an external input ports.
LEVEL RULE
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to an
asynchronous control pin(s) of each flip-flop:
– this signal must be directly controlled by an external input port (*) of the design
(*)
– see the rule 3.3.1.1 for details about external input ports
– if signal is not controlled by an external input => violation message is reported (message
CHECKER points on flip-flop signal assignment, detail points on appropriate asynchronous control)
BEHAVIOR
– following is the list of possible strings for the {ControlType} token in the detail
message:
– reset
– set
– set/reset
EXAMPLE-1: [1] module 'dff' which infers a flip-flop with the reset signal controlled from an external input;
[2] module instantiation statements create two named instances:
– the external signal is mapped to the reset signal in instance 'u_dff_1';
– the output of combinational logic is mapped to the reset signal in instance 'u_dff_2' =>
violation.
module dff( clk, rst, data, q );
input clk, data;
output q;
reg q;
wire rst_gate;
dff u_dff_1 ( .clk( clk ), .rst( rst ), .data( data1 ), .q( out1 ) );
dff u_dff_2 ( .clk( clk ), .rst( rst_gate ), .data( data2 ), .q( out2 ) );
endmodule
STARC_VLOG 3.3.2.2
RULE NAME
Do not connect clock pins, reset pins, or tristate outputs to black
boxes
Global {GlControlType} “{GlControlName}” is connected to input of black box
“{BboxName}”. Do not connect clock pins, reset pins or tri-state outputs to black
MESSAGE-1
boxes. Such descriptions could make impossible the insertion of scan chains
and test patterns generation with ATPG tools.
Output of tri-state “{TriStateName}” is connected to input of black box
MESSAGE-2
“{BboxName}”. Do not connect clock pins, reset pins or tri-state outputs to black
boxes. Such descriptions could make impossible the insertion of scan chains
and test patterns generation with ATPG tools.
There are some cases when hard macro library does not exist when LSI design data
are generated. When clock/reset line or output of tri-state buffer is connected to black
box, ATPG tool could fail to insert test scan and generate test patterns.
PROBLEM
DESCRIPTION When black box should be used, it is recommended to generate RTL code wherein only
the inputs and outputs are defined or get a library from the vendor.
LEVEL RECOMMENDATION 3
Checker scans the design hierarchy for black boxes and verifies lines that are mapped to input
pins of each black box:
– if input line is driven by global reset/clock (*) or directly driven (**) by tri-state => violation
is detected and appropriate warning message is displayed:
– message #1 if line is driven by global clock / reset
– following is set of string that are possible for {GlControlType} token: clock /
reset
– message #2 if line is driven by tri-state
– the token {TriStateName} is not displayed if tri-state line is generated
intermediately
(*)
– see 1.4.3.4 for details:
CHECKER
– rules for auto-detection (during the auto-detection, each signal that is connected to
BEHAVIOR
asynchronous control pin of flip-flop is considered as reset signal)
– rules for global reset propagation (global reset propagates through buffers /
inverters / combinational logic / multiplexers data / tri-state inputs)
– rules for displaying info-messages (indicate the list of auto-detected clock or report
about reset signals that are specified with -alint_gclk but could not be found)
(**)
– direct driver means that output of tri-state buffer is connected directly or through
inverters / buffers.
Note: following types of modules are considered as black boxes:
– empty (interface);
– compiled without elab-time data (no -alint_elabchecks switch);
– specified with -alint_blackbox switch.
data
LD OUT2
latch _en BBOX _INSTANCE1
tri-state buffer is
connected
endmodule
Ins tance “top”. Output of tri-state “sst_to_bbox” is connected to
module latch( D, G, Q ); input of black box “BBOX_INSTANCE2”. Do not connect clock pins,
reset pins or tri-state outputs to black boxes. Such descriptions could
input D, G; make impossible the insertion of scan chains and test patterns
output reg Q; generation w ith ATPG tools.
always @( G )
if( G )
Q = D;
endmodule
endmodule
endmodule
Checker scans the design hierarchy for black boxes (see 3.3.2.2) and verifies connections of
their output lines:
– if output line directly drives (*) FF clock/reset or tri-state enable pin => violation is
detected:
– main message #1 is displayed per black box
– detail message #2 is displayed per each erroneously mapped output
– following table defines set of strings that are possible for {ObjectType}-
{PortType} tokens:
{ObjectType} {PortType}
CHECKER
BEHAVIOR clock
FF asynchronous reset
asynchronous set
asynchronous reset
latch
asynchronous set
EXAMPLE-1: [1] consider design hierarchy that is represented on the picture below;
[2] violation message is displayed with 2 details: outputs of black box are connected to clock pin of
FF and enable pin of tri-state buffer.
endmodule
Output of black box is connected to tri-state buffer “out1” enable pin
module dff( D, CLK, Q );
input D, CLK;
output reg Q;
output out1;
output out2;
output out3;
endmodule
STARC_VLOG 3.3.3.1
RULE NAME A clock must not be connected to the D input of a FF
Clock signal(s) “{GlClkSignalNameList}” is connected to the FF “{FFName}” data
MESSAGE input. Such connection may lead to the risk of generating incorrect test pattern
because of the racing problem. Do not connect clock signals to the FF data input.
Inputting a clock into the D pin of a FF runs a tremendous risk of an incorrect test pattern
generation. (ATPG tools generate test patterns performing the simulation with zero delays =>
tremendous risk that racing problem will occur).
PROBLEM
DESCRIPTION When it is impossible to avoid clock connection to the data input, selector circuitry should be
added to switch to external input in the test mode.
LEVEL RULE
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to the
data input of each flip-flop that is detected:
– this signal must not be a clock (*) for the design
(**)
CHECKER – see 1.4.3.4 for definition of clock signal in the design: clock(s) could be directly
BEHAVIOR specified (with -alint_gclk switch) or auto-detected (signal that is connected to
clock pin of flip-flop will be considered as clock)
– if this is clock signal => violation message is reported (it points on flip-flop signal
assignment)
EXAMPLE-1: [1] 'clk' signal is auto-detected as a clock signal (it is connected to the clock pin of FF 'out1');
[2] clock signal propagates through 'and' gate ('clk_gate') and through a multiplexer ('mux_out');
[3] signal 'mux_out' is connected to the data input of FF 'out1' => violation;
[4] signal 'clk_gate' is connected to the set control input of FF 'out1' => no violation;
reg out1;
wire clk_gate;
reg mux_out;
LEVEL RECOMMENDATION 2
Checker scans the design hierarchy for flip-flops and verifies signal that is mapped to an input of
each flip-flop that is detected:
– backward propagation performed from flip-flop data input (see 1.4.3.2 for details
regarding the backward propagation)
– if backward propagation stops at a constant(*) (VDD is '1', GND is '0') => violation
message is reported (message points to 'always' process inferring flip-flop, detail points
to flip-flop signal assignment: {LineType} could be VDD or GND, see Note-1 regarding
CHECKER possible cases for {FFInput} token)
BEHAVIOR
(*)
– following are the notes regarding constants determination:
– direct assignment to the signal or mapping to some input port;
– unmapped signals are supplied with GND;
– signals without drivers are supplied with GND;
Note: possible values for {LineType} are GND and VDD; for {FFInput} are data, clock, enable,
asynchronous reset, asynchronous set, synchronous reset, synchronous set.
EXAMPLE-1: [1] instance of flip-flop has unmapped data input port => violation (note, that unmapped port is
treated as GND)
endmodule
Fixed value is connected to the FF “u_dff_1.q” input port(s).
module top( data, out1 );
input data;
output out1;
endmodule
STARC_VLOG 3.3.5.2
RULE NAME When the output of a FF is used as a clock, switch using a selector
The clock pin of flip-flop "{DrivenFFName}" is driven by the output of another
flip-flop. Such description is not compatible with ATPG tools, because scan
MESSAGE insertion could not be performed. For such kind of circuit it is recommended to
insert a selector to switch to a clock that is input from the outside during testing.
DETAIL Clock pin is driven with the output of flip-flop "{DriverFFHierName}"
In case when output of flip-flop is used as a clock, the clock pin of that flip-flop could not
be controlled directly from an external input port. Such description is not compatible
with scan insertion and it makes impossible faults detection with ATPG tools.
FF
FF FF FF
0
PROBLEM
DESCRIPTION 1
CLK
TST
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to the
CHECKER clock pin of each flip-flop:
BEHAVIOR
– if this signal is output of another flip-flop, it should be connected through selector
EXAMPLE-1: [1] consider design hierarchy that is represented on the picture below;
[2] output of flip-flop is connected to clock pins of two another flip-flops:
– direct connection => violation
– connection through selector => correct
output of FF is
used as a clock
FF
IN1 FF OUT2
CLK
0
CLK_EXT 1 FF
OUT1
TEST
module top( IN1, IN2, IN3, CLK, CLK_EXT, TEST, OUT1, OUT2 );
wire ff1_to_ff2;
wire mux_to_ff3;
endmodule
input D, CLK;
output reg Q;
Ins tance “top.DFF_INSTANCE2”. The clock pin of flip-flop "Q" is
always @( posedge CLK ) driven by the output of another flip-flop. Such description is not
Q <= D; compatible w ith ATPG tools, because scan insertion could not be
performed. For such kind of circuit it is recommended to insert a
endmodule selector to sw itch to a clock that is input from the outside during
testing.
FF
Logic
CLK
FF
CLK
TST_N
FF Clock enable can be
Logic controlled by an external
signal during the scan
LEVEL RECOMMENDATION 1
Checker collects collect external signals and verifies whether these signals are directly (*)
connected to an OR gate that feeds directly(*) clock pin of an FF:
– if other input of OR gate is external => no violation;
– else if other input is internal:
– if it is supplied with AND gate with at least one input connected directly(*) to an
CHECKER external port;
BEHAVIOR – else if there is no such AND gate => violation.
(*)
– for this rule, signal that is directly connected may be connected directly or through
buffers/inverters.
Note-1: OR gates with two inputs only are considered.
Note-2: if an OR gate is driven by an FF then this checker is not regard the situation (for more
details see 3.3.5.6).
input CLK;
input EN1, EN2, D1, D2;
Ins tance “top”. Clock “CLK” passes through the OR gate logic. Internally
output OUT1, OUT2; generated signals, connected to other pins of this OR gate, must be controlled
by an external port via the AND gate.
assign or_clk = bb_out | CLK;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
// BB interface definition
module bb ( input IN1, IN2, output OUT);
endmodule
FF
OUT1
D1
EN1 BB
EN2
CLK
FF
CLK OUT2
D2
input CLK;
input EN_X, D1, D2;
endmodule
input CLK, D;
output reg Q;
endmodule
FF
OUT1
D1
FF
EN_X
CLK
FF
CLK OUT2
D2
CLK FF
Inverted
clock edge
Logic
FF
CLK
CLK FF
TST
FF
Clock enable can be
Logic
controlled by an external
signal during the scan
LEVEL RECOMMENDATION 1
CHECKER Checker collects collect external signals and verifies whether these signals are directly (*)
BEHAVIOR connected to an AND gate that feeds directly(*) clock pin of an FF:
– if other input of AND gate is external => no violation;
– else if other input is internal:
– if it is supplied with OR gate with at least one input connected directly(*) to an
external port;
– else if there is no such OR gate => violation.
(*)
– for this rule, signal that is directly connected may be connected directly or through
EXAMPLE-1: [1] CLK signal is directly connected to an AND gate that feeds directly clock pin of an FF;
[2] the other input of AND gate is supplied with OR gate;
[3] both inputs of OR gate are internally generated (they are outputs of black boxes) => violation.
module top( CLK, IN1, IN2, IN3, IN4, D1, D2, OUT1, OUT2 );
input CLK;
input IN1, IN2, IN3, IN4; Ins tance “top”. Clock “CLK” passes through the AND gate logic. Internally
input D1, D2; generated signals, connected to other pins of this AND gate, must be
controlled by an external port via the OR gate.
output OUT1, OUT2;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
endmodule
endmodule
D1
FF
OUT1
IN1 BB1
IN2
IN3 BB2
IN4
CLK
FF
OUT2
CLK
D2
Inverted
clock edge
LD
CLK FF
SCAN_SEL
LEVEL RECOMMENDATION 2
CHECKER Checker collects collect external signals and verifies whether these signals are directly (*)
BEHAVIOR connected to an AND gate that feeds directly(*) clock pin of an FF:
– if a latch is connected to an AND gate:
– if its input pin is directly(*) driven by an OR gate with one external input => no
violation
EXAMPLE-1: [1] external signal is directly connected to AND gate which feeds FF clock pin;
[2] latch is connected to the other input of AND gate;
[3] latch input pin is driven by OR gate;
[4] OR gate inputs are both internally generated signals => violation.
input CLK;
input IN1, IN2, IN3, IN4, D;
output OUT;
The output of the latch is used for gating w ith clock “CLK”.
assign bb_or = bb1_out | bb2_out;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
//D-latch
module latch( G, D, Q );
input G, D;
output reg Q;
always @(G, D)
if ( G ) Ins tance “top.LD” Latch (“Q”) is used for gating clock line and its output is
Q <= D; not fixed to '1'. Use OR gate w ith external signal fixed to high voltage prior to
the latch to provide clock to the FFs during scan shift.
endmodule
endmodule
endmodule
top
D
IN1 BB1
IN2
LD
FF
IN3 BB1 OUT
IN4
CLK
CLK
EXAMPLE-2: [1] external signal is directly connected to AND gate which feeds FF clock pin;
[2] there is no latch connected to the other AND gate input => no violation.
Note: this is the case for rule 3.3.5.4.
output OUT;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
FF
OUT
D
FF
EN
CLK
top
CLK
CLK
CLK
FF
TST_N
LEVEL RECOMMENDATION 2
Checker collects collect external signals and verifies whether these signals are directly (*)
connected to an OR gate that feeds directly(*) clock pin of an FF:
– if another input of OR gate is driven by FF => violation;
– else if it is driven by an AND gate:
– if one of the inputs of AND gate is driven by FF and another is directly(*) connected
CHECKER to external port => no violation
BEHAVIOUR
– otherwise => violation
– else if other input of OR gate is driven by anything else => situation for 3.3.5.3
(*)
– for this rule, signal that is directly connected may be connected directly or through
buffers/inverters.
Note-1: AND gates with two inputs only are considered.
input CLK,EN_X;
input D;
output OUT; The output of the FF is used for gating w ith clock “CLK”.
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
Ins tance “top.DFF2” Detected FF (“Q”) using for gating clock w ithout output
always @(posedge CLK)
Q <= D; tied to a specific voltage. Use AND gate w ith external signal fixed to low
voltage after the FF to provide clock to the FFs w ithout stopping during scan
endmodule shift.
top
FF FF
EN _X
FF
OUT
CLK
CLK
EXAMPLE-2: [1] external signal is directly connected to OR gate which feeds FF clock pin;
[2] FF is not connected to the other input of OR gate => no violation.
Note: this is the case for rule 3.3.5.3.
input CLK;
input EN1, EN2, D;
output OUT;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
endmodule
D
top
EN1
BB
FF
EN 2 OUT
CLK
CLK
TST
Logic
Latch is gated with an
Logic
internally generated signal
LEVEL RECOMMENDATION 2
Checker collects collect external signals and verifies whether any of these signals is connected
directly (*) to data pin of latch:
– if latch output is connected to the clock pin of FF:
– if the enable input of latch is an external port or it is supplied with OR gate with at
CHECKER least one external signal => no violation;
BEHAVIOUR
– otherwise => violation
(*)
– for this rule, signal that is directly connected may be connected directly or through
buffers/inverters.
Note: OR gates with two inputs only are considered.
EXAMPLE-1: [1] external signal CLK directly connected to data pin of the latch;
[2] latch output is connected to the clock pin of FF;
[3] latch enable input is is supplied with OR gate with internal signals => violation.
input CLK;
input IN1, IN2, IN3, IN4, D;
output OUT;
endmodule
//D flop-flop
module dff( CLK, D, Q );
input CLK, D;
output reg Q;
endmodule
//D-latch
module latch( G, D, Q );
input G, D;
output reg Q;
Ins tance “top”. Clock “CLK” passes through the latch “Q” but the enable
always @(G, D) input is not set to a specific voltage. Use OR gating w ith test signal to tie the
if ( G ) clock pin to '1', to provide continual pass of the clock signal to FFs.
Q <= D;
endmodule
endmodule
endmodule
D
CLK
CLK
FF
LD OUT1
IN1 BB1
IN2
IN3 BB2
IN4 top
EXAMPLE-2: [1] external signal CLK directly connected to data pin of the latch;
[2] latch output is connected to the clock pin of FF;
[3] latch enable input is an external signals => no violation.
input CLK, G;
input D;
output OUT;
endmodule
input CLK, D;
output reg Q;
endmodule
//D-latch
module latch( G, D, Q );
input G, D;
output reg Q;
always @(G, D)
if ( G )
Q <= D;
endmodule
top
CLK D
CLK LD FF
OUT1
STARC_VLOG 3.3.6.1
RULE NAME
When the output of random logic is applied to an asynchronous set
or reset pin, block the propagation of the random logic output
The output of random logic is used as asynchronous control for flip-flop
MESSAGE
“{FFSigName}”. Such circuit structure is unsafe for scan shift during the scan
test. It is recommended to insert a selector at the final output of the random logic
to make it possible to select an external port.
DFT for reset lines requires that they should be structured so that no reset is applied to a FF
during the scan shift, otherwise some data will be lost. It is necessary for the reset lines to be
controlled directly from external input ports (see 3.3.1.4).
If an output from random logic is connected to an asynchronous set or reset pin or gated with a
reset input, you need to ensure the propagation of the random logic output is blocked during
testing to make it possible for the ATPG tool to detect faults in the reset lines.
FF FF
PROBLEM RAND_LOGIC RAND_LOGIC
DESCRIPTION
N o direct
co n trol 0
D irect 1 D irect
reset co n trol co n trol
LEVEL RULE
Checker scans the design hierarchy for flip-flops and verifies the signal that is mapped to the
asynchronous control pin of each flip-flop:
– this signal must be controlled by an external input port (*)
(*)
CHECKER – for this rule, signal that is controlled by an external input port is a signal that is
BEHAVIOR connected directly or through buffers/inverters/MUXes to any external input port of the
design
– if signal is not controlled by an external input port => violation (message points to flip-
flop signal assignment).
module top( ext, tst_x, rst_x, in1, in2, clk, data1, out1 );
input ext;
input tst_x;
input rst_x;
input in1;
input in2;
input clk;
input data1;
output out1;
wire or_out;
dff_r DFF_INSTANCE1 ( .DATA( data1 ), .CLK ( clk ), .RES( mux_out ), .Q( out1 ) );
endmodule
input DATA;
input CLK;
input RES;
output Q;
reg Q;
Q <= DATA;
endmodule
data
ext
in1
in2
FF
0 out1
tst_x 1
rst_x
Normally, clock lines and reset lines are not mixed in a design.
However, there are some rare cases that use circuitry as shown in the CLK
picture. But this type of design is risky and should not be used, even
PROBLEM FF
when no scan is to be inserted.
DESCRIPTION
LEVEL RULE
Checker detects signals that are used simultaneously as clock and reset for FF:
– if such signals are detected => violation (main message per signal declaration +
appropriate detail (detail-2/detail-3) per each connection to FF);
CHECKER – if several signals drive same FF pin (clock/reset) => violation (only one message for all
BEHAVIOR of them + detail-4 per each another driver-signal);
Note: analysis starts from asynchronous control pin of each FF and backward
propagation is performed (propagation rules are the same as for global reset/clock, see
1.4.3.4 ) to detect “forks” that could be connected to clock pin(s) of other/same FF(s).
module top( in1, in2, in3, clk1, clk2, reset, sel, out1, out2 );
input in1;
Instance “top”. Signal “clk1” is used both for clock and reset. Do not
input in2;
input in3; mix clock and reset lines to avoid problems w ith DFT. In such
input clk1; descriptions all lines to w hich clock signal is connected w ill be
input clk2; excluded from scanning.
input reset;
input sel;
output out1;
output out2;
wire mux_to_ff1;
wire mux_to_ff2;
mux MUX_INSTANCE ( .in1( clk1 ), .in2( in2 ), .sel( sel ), .out1( mux_to_ff1 ) );
dff DFF_INSTANCE1 ( .D( in1 ), .CLK( mux_to_ff1 ), .RESET( reset ), .Q( out1 ) );
endmodule
input D;
input CLK;
input RESET; Connection to clock pin of flip-flop “Q” is detected.
output Q;
reg Q;
if ( RESET )
Q <= 1'b0;
Connection to asynchronous control pin of flipflop “Q” is detected.
else
Q <= D;
endmodule
input in1;
input in2;
input sel;
output out1;
endmodule
in2
FF
0 out1
clk1
1
sel
reset
in1
in3
0 FF
out2
1
clk2
Signal “ top.clk1”
Signal “ top.clk1” connected to
connected to MUX
asynchronous reset of
data input “top.dff_instance 2”
input in1; Signal “in1” is used both for clock and reset. Do not mix clock and
input in2;
input clk; reset lines to avoid problems w ith DFT. In such descriptions all lines to
input data1; w hich clock signal is connected w ill be excluded from scanning.
input data2;
Signal “in2” is also used both for clock and reset in the same
output out1;
output out2; connections.
wire and_out;
dff_r DFF_INSTANCE1 ( .D( data2 ), .CLK( clk ), .RESET( and_out ), .Q( out2 ) );
endmodule
input D;
input CLK;
Connection to clock pin of flip-flop “Q” is detected.
output Q;
reg Q;
Q <= D;
endmodule
input D;
input CLK;
input RESET;
output Q;
reg Q;
Q <= 1'b0;
else
Q <= D;
endmodule
in1
FF
out1
in2
data2 FF
out2
clk
PROBLEM FF FF
DESCRIPTION
0
RST
1
TST
LEVEL RULE
Checker scans the design hierarchy for flip-flops that have output of another flip-flop supplied to
their asynchronous control pins:
– backward-propagation is performed from each asynchronous control pin of each flip-flop
to define its driver (See rule 1.4.3.2 for details regarding backward propagation)
– if driver is output of another flip-flop => violation is reported (main message points on
process that infers driven flip-flop, whereas detail message points on assignment of
CHECKER
BEHAVIOR
signal that infers driver flip-flop)
– following is list of possible controls ({ControlName}) for the “detail” violation
message:
– reset
– set
– set/reset
EXAMPLE-1: [1] inverted output of first flip-flop is connected to asynchronous set of second flip-flop
module top (CLK, D, SET, RESET, Q, Qn) ;
input CLK;
input D;
input SET;
input RESET;
output Q;
output Qn;
wire CTRL_from_FF1_out;
wire WIRE_from_FF1_out;
input D;
input CLK;
input SET;
input RESET;
output Q;
reg Q;
output Qn;
if( SET )
Q <= 1'b1; Instance "top.U2". The asynchronous control pin(s) of flip-flop "Q" is
else if( !RESET ) driven by the output of another flip-flop. Insert selector to sw itch to a
Q <= 1'b0; reset signal controlled directly from an external port to avoid
else
malfunctions w ith DFT and ATPG tools.
Q <= D;
assign Qn = ~Q; Asynchronous set pin is driven w ith the output of flip-flop "top.U1.Q"
endmodule
PROBLEM
DESCRIPTION RST RST
LD LD
«L» «L»
RST
LEVEL RULE
Checker scans the design hierarchy for flip-flops that have output of latch supplied to their
asynchronous control pins:
– backward-propagation is performed from each asynchronous control pin of each flip-flop
to define its driver (See rule 1.4.3.2 for details regarding backward propagation)
CHECKER
BEHAVIOR – if driver is output of latch => violation is reported (main message points on process that
infers driven flip-flop, whereas detail message points on assignment of signal that infers
driver latch)
– see 3.3.6.3 for list of possible controls ({ControlName}) for the “detail” violation
message
EXAMPLE-1: [1] latch output is directly connected to asynchronous set input of flip-flop => violation;
[2] note, that output of the same latch is connected to reset input of the same flip-flop, but there is
no violation because backward propagation stops at logic gate 'or' (ORing of multiple
asynchronous controls);
input D;
input CLK;
input RESET;
input SET;
output Q;
reg Q;
output Q1;
reg Q1;
wire CTRL_from_FF_out;
STARC_VLOG 3.3.7.2
RULE NAME
Insert a latch with an inverted clock when transmitting between
asynchronous clocks
Data transfer without using a latch is detected. For structuring a single scan
chain it is recommended to insert a latch with an inverted clock between the
adjacent flip-flops that are in different clock domains.
MESSAGE-1 DETAIL-1 Data is sent by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
DETAIL-2 Data is accepted by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
Multiple clock domains transfer data through a single latch (“{LatchName}”). For
structuring scan chains it is recommended to insert a latch with an inverted clock
between the each pair of adjacent flip-flops that are in different clock domains.
MESSAGE-2 DETAIL-1 Data is sent by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
DETAIL-2 Data is accepted by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
Incorrect enable polarity is used to switch the latch "{LatchName}" to a
transparent state. Polarity should be inverted relatively to the driving flip-flop
from the source clock domain (for structuring a single scan chain it is
recommended to insert a latch with an inverted clock between the adjacent flip-
MESSAGE-3
flops that are in different clock domains).
DETAIL-1 Data is sent by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
DETAIL-2 Data is accepted by the FF “{FFName}” that belongs to the clock domain
“{HierClockName}”.
It is important to handle multiple clock domains with care. An attention to clock skew is important:
during the scan testing it is easy to meet setup-timing requirements because scan clock
frequency is slow, whereas hold-time problems are common.
Potential hold-time problems could be avoided by ensuring that a scan chain consists only of flip-
flops from the same clock domain. If this is not feasible, latch with an inverted clock should be
added between the adjacent flip-flops on a scan chain that are in different clock domains.
FF FF LATCH FF FF
PROBLEM
DESCRIPTION
DOMAIN_1 DOMAIN_2
The data will be held during the high level of clocking signal and transmitted during the low level
of clocking signal (transparent state of the latch). If skew value in the clock line is less than ½ of a
clock cycle, then it is not necessary to ensure the hold.
LEVEL RECOMMENDATION 3
CHECKER Checker scans interconnections between different asynchronous clock domains (see 1.5.1.1 for
BEHAVIOR details about clock domains detection):
FF FF
DOMAIN_1 FF FF
FF FF
DOMAIN_3
DOMAIN_2
– there is a latch, but its edge is not inverted relatively to the edge of the driving flip-
flop from the source domain => message-3 (see correct cases at the figure below);
SOURCE SOURCE
DOMAIN DOMAIN
DRIVING DRIVING
LATCH LATCH
FF FF
Note: details are similar for all cases; also there are special detail messages to indicate origin
clocks of source and target domains (see 1.5.1.1 for details)
EXAMPLE-1: [1] consider sample circuit at the picture below – latch ld_out is properly located between the
asynchronous clock domains DOMAIN_1 and DOMAIN_2, but its enable input is active at the
same clock phase as flip-flops from the DOMAIN_1 => violation (message-3);
[2] note that clocks are auto-detected.
input clk1, clk2, data; Data is sent by the FF "top.ff_out" that belongs to the clock domain "clk1".
output reg out;
"clk1" is the origin clock of the source domain.
reg ff_out, ld_out;
always @( posedge clk1 ) Data is accepted by the FF "top.out" that belongs to the clock domain
ff_out <= data; "clk2".
always @( clk1 or ff_out ) "clk2" is the origin clock of the target domain.
always @( posedge clk2 ) Ins tance "top". Incorrect enable polarity is used to sw itch the latch
out <= ld_out; "ld_out" to a transparent state. Polarity should be inverted relatively to the
driving flip-flop from the source clock domain (for structuring a single
endmodule scan chain it is recommended to insert a latch w ith an inverted clock
betw een the adjacent flip-flops that are in different clock domains).
LATCH
«ld_out»
DOMAIN_1 DOMAIN_2
clk1 clk2
STARC_VLOG 3.3.8.1
RULE NAME
Tristate enable signals should be able to be fixed from an external
input port
Tristate enable input is not directly controlled from external input port. The
MESSAGE tristates must be able to be controlled directly from external input ports,
otherwise ATPG tools will encounter problems.
If tristate design takes DFT into consideration, it must enable direct control of tristate buffers from
PROBLEM outside of the LSI (such description will be correct for ATPG tools).
DESCRIPTION
LEVEL RECOMMENDATION 2
Checker scans the design hierarchy for tristates and verifies the signal that is mapped to an
enable pin of each tristate that is detected:
– this signal must be an external (*) signal for the design
CHECKER (*)
BEHAVIOR – external signal is such signal that can be directly controlled from an external port
(it doesn't pass through any kind of logic except of buffers and inverters)
– if signal is not external => violation message is reported (message points on tristate
signal assignment)
EXAMPLE-1: [1] MUX switches between signals en1 and en2 to control tristate enable signal;
[2] internal signal (MUX out) is connected to the enable signal of tristate => violation;
endmodule
TST
0 0 0 0
1 1 1 1
TST _EN1
TST_EN2
TST_EN3
TST_EN4
PROBLEM In LSIs containing many tristate circuits, it is, as a practical matter, impossible to provide enable
DESCRIPTION signals to all of the tristate elements from outside of the LSI. In such cases, one method that is
used widely to decrease a number of required input pins is designs using decoders to control the
tristate elements internally. This method is considered at the picture below.
TST
0 0 0 0
1 1 1 1
LEVEL RECOMMENDATION 3
CHECKER Checker scans the design hierarchy for tri-state and verify the line that is mapped to the enable
BEHAVIOR control pins:
– allowed cases:
– tri-state enable control pin is driven by an external signal (see 3.3.8.1 for details)
– tri-state enable control pin is driven by an abstract decoder
– all inputs of abstract decoder must be connected directly(*) from an external port
– (*): direct connection in this case means that only buffers and inverters are
allowed – MUX inputs are not allowed)
data
DATA
in3
4
in2
DC_INST EN TS_INST
in1
wire and_out;
wire [3:0] decoder_out;
endmodule
always @( in )
case ( in )
2'b00 : out <= 4'b0001;
2'b01 : out <= 4'b0010;
2'b10 : out <= 4'b0100;
2'b11 : out <= 4'b1000;
default : out <= 4'b0000;
endmodule
endmodule
Checker scan the current module and for each port declared as inout checks its actual mode (in
case of vector – every bit is checked separately):
– if the actual mode is 'unused' or 'input' => no violations
– if the actual mode is 'inout':
– analyzes all local drivers of the 'inout' port and all lines that are driven by the 'inout'
port:
– if one or more local drivers is not a tri-state or if 'inout' port drives non-tri-state
=> violation (message-1 + detail-1 (per each non-tristate driver object) / detail-2
(per each non-tristate driven object));
CHECKER
BEHAVIOR – in any other case checker collects:
– all enable inputs of tristates that drive 'inout' ports (OUTBUF)
– all enable inputs of tristates which are driven (INBUF) by 'inout' port
– OUTBUF and INBUF must be driven by the same external port
(CONTROL) inversely, i.e. this signal should satisfy a following condition:
– if CONTROL drives OUTBUF, !CONTROL should drive INBUF;
– if !CONTROL drives OUTBUF, CONTROL should drive INBUF;
– otherwise => violation (message-2) and the analysis is stopped (for the
currently analyzed 'inout' port).
endmodule
STARC_VLOG 3.4.1.1
RULE NAME
In the design of standard ASICs, gated clocks can be used only in
the top level.
Global clock "{ClkName}" is gated locally. In the design of standard ASICs, the
MESSAGE-1 gated clocks should only be located in the clock generator module at the top
level so as to gate the clocks to each functional block.
One of the most effective approaches to reduce power dissipation is to use gated clocks or
divided clocks. It means clocks could be stopped when they are not needed.
Following figure illustrates the most common method of clock gating – through the use of a latch
and a gate:
FUNCTION BLOCK 1
CLOCK GENERATOR MODULE SET
D Q
EN_1
CLR Q
EN _2 FUNCTION BLOCK 2
SET
D Q
CLK
PROBLEM CLR Q
DESCRIPTION
When the CLK is in its low phase, the latch is transparent (propagation of the control input which
actually indicates whether to gate the clock or not). So, if the control input is high, the output of
the latch is high during the low phase (it remains in this state until the next CLK low phase). In
such situation, AND gate is enabled when the posedge CLK arrives.
In the design of standard ASICs, the gated clocks should only be located in the clock generator
module at the top level so as to gate the clocks to each functional block. When gated clocks are
used at local level, there will be many incorrect cells in the clock tree (when the clock tree is
generated by synthesis tool). Thus, fixing clock skew will be more difficult. Moreover, when gated
clocks are used only in the clock generator module, it becomes easier to insert a DFT circuits.
LEVEL RULE
EXAMPLE-1: [1] sample contains two locally gated submodules => violations;
[2] the figure below illustrates an approach to fix this problem – gated clocks are separated from
another logic and located separately in the clock generator module.
gated_ff GATED_FF_CH_A
(
.RST_X( RST ),
.CLK ( CLK ),
.DI ( wA ),
.EN ( CH_EN1 ),
.DO ( RES[0] )
);
gated_ff GATED_FF_CH_B
(
.RST_X( RST ),
.CLK ( CLK ),
.DI ( wB ),
.EN ( CH_EN2 ),
.DO ( RES[1] )
);
endmodule
input DI;
input RST_X, EN, CLK;
output DO;
reg DO;
Ins tance "cm p.GATED_FF_CH_A". Global clock "cmp.CLK" is gated
reg d_latch; locally. In the design of standard ASICs, the gated clocks should only be
wire gated_clk; located in the clock generator module at the top level so as to gate the
clocks to each functional block.
always @( CLK, EN ) begin
if( CLK )
d_latch = EN; Ins tance "cm p.GATED_FF_CH_B". Global clock "cmp.CLK" is gated
end locally. In the design of standard ASICs, the gated clocks should only be
located in the clock generator module at the top level so as to gate the
assign gated_clk = d_latch & CLK; clocks to each functional block.
endmodule
CH_EN1 CH_EN 1
LOCALLY GATED CH_EN2
MODULE A
MODULE A
CLK
CLOCK
GENERATOR
MODULE
LOCALLY GATED CLK
MODULE B
CH_EN2 MODULE B
STARC_VLOG 3.5.3.3
RULE NAME Standardize file headers
Token "{TokenRegExp}" ({Token}) is not expected according to the grammar
MESSAGE-1 defined by the rule configuration. Possible token(s) to use:
{ExpectedTokenRegExpAndToken}.
MESSAGE-2
Token "{TokenRegExp}" ({Token}) is not expected. End of file header is reached
according to the current grammar defined by the current rule configuration.
Unexpected end of file header. Possible token(s):
MESSAGE-3 {ExpectedTokenRegExpAndToken} according to the grammar defined by the rule
configuration.
MESSAGE-4
File header is missed. It is recommended to add standard header for each file to
improve readability.
Incorrect grammar description. There is a choice between values “{Values}” and
MESSAGE-5
[ERROR] empty set for nonterminal symbol “{SymbolName}”. Use '[ ]' to define optional
values.
MESSAGE-6 Incorrect grammar description. Symbol “{SymbolName}” is not defined as
[ERROR] neither nonterminal symbol nor token.
MESSAGE-7 Incorrect grammar description. Left recursion is detected in description of
[ERROR] nonterminal symbol “{SymbolName}”. Use '{ }' to define repeated values.
Necessary information should be defined within the file header. Define the file, and include when
the file was modified by whom and for what purpose it was created. Following this
recommendation makes it possible to improve readability when the description is reused by
designers other than the original designer.
In the example, the file header, file names, circuit type, function, modifier, originator, and revision
are all defined. Any other sections should also be added when necessary. Readability decreases
if the file headers’ formats differ among designers, so all designers should follow standardized
header format.
Example:
/*-----------------------------------------------------
-- --
-- FILE_NAME : my_circuit.v --
-- --
PROBLEM -- TYPE : circuit --
DESCRIPTION -- --
-- FUNCTION : data decoding with Gray code --
-- --
-- AUTHOR : First_Name Last_Name --
-- --
-- EDIT : Bob --
-- --
-- REV_DATE : 1.0 01/02/08 --
-- 1.1 02/02/08 --
-- --
-- Some detail text about the function of the --
-- circuit, data flow, data transformation, etc. --
-- --
-----------------------------------------------------*/
LEVEL RECOMMENDATION 1
TOKENS = [
“FILE_NAME ::= #FILE NAME#”,
“AUTHOR ::= #AUTHOR#”,
“TYPE_NAME ::= #TYPE#”,
“FUNCTION_NAME ::= #FUNCTION#”,
“EDIT_NAME ::= #EDIT#”,
“REV_DATE_NAME ::= #REV, DATE#”,
“INE ::= #-{3,}#”,
“SEPARATION_CHAR ::= #:#”,
“MARGIN ::= #--#”
]
Note-4: IDENTIFIER, END_LINE – is a hard coded tokens, they cannot be changed by user.
END_LINE – is processed if parameter CONSIDER_END_LINE is active (is equal to '1').
/*-----------------------------------------------------
-- --
-- FILE_NAME : clk_gen.v --
-- --
-- AUTHOR : Robert --
-- --
-- TYPE : CIRCUIT --
-- --
-- EDIT : Bob --
-- --
-- REV_DATE : 1.0 04/01/08 --
-- 1.1 02/02/08 --
-- --
-- clock frequency is defined by parameter --
-- CLK_PERIOD --
-- --
-----------------------------------------------------*/
module clk_gen (...); Unexpected token: "EDIT" (EDIT_NAME). Expected token: "FUNCTION"
... (FUNCTION_NAME). Standardize the format of file header to increase
endmodule the readability of code.
/*-----------------------------------------------------
-- --
-- FILE_NAME : clk_gen.v --
-- --
#configuration
RULE_CFG STARC_VLOG.3.5.3.3
{
GRAMMAR = [
"content ::= LINE content_item LINE",
"content_item ::= cvs_tag LINE
model_name_block LINE
owner_block LINE
file_description",
"cvs_tag ::= FIRST_SYMBOL ID_TAG string",
"model_name_block ::= {FIRST_SYMBOL string}",
"owner_block ::= {empty_line} {FIRST_SYMBOL string [{empty_line}]}
copyright_item {empty_line}",
"copyright_item ::= LINE FIRST_SYMBOL [{LINE}] COPYRIGHT company [LINE]
FIRST_SYMBOL [LINE] ALL RIGHTS RESERVED [LINE]
[FIRST_SYMBOL LINE] {empty_line}",
"company ::= string",
"file_description ::= filename_str empty_line description_str empty_line",
"filename_str ::= FIRST_SYMBOL FILE_NAME string",
"description_str ::= FIRST_SYMBOL DESCRIPTION string",
"string ::= {IDENTIFIER}",
"empty_line ::= FIRST_SYMBOL"
TOKENS = [
"ID_TAG ::= #\$Id:#",
"FILE_NAME ::= #Filename:#",
"DESCRIPTION ::= #Description:#",
"COPYRIGHT ::= #Copyright#",
"ALL ::= #All#",
"RIGHTS ::= #rights#",
"RESERVED ::= #reserved.#",
"LINE ::= #\*{2,}#",
"FIRST_SYMBOL ::= #\*#"
]
}
`timescale 1ns/10ps
...
#configuration
RULE_CFG STARC_VLOG.3.5.3.3
{
GRAMMAR = [
“content ::= LINE content_item LINE”,
“content_item ::= TOKEN_A TOKEN_B TOKEN_C”
]
TOKENS = [
“TOKEN_A ::= #string_A#”,
“TOKEN_C ::= #string_B#”, Incorrect grammar description. Symbol “TOKEN_B” is not defined as
neither nonterminal symbol nor token.
“LINE ::= #\*{2,}#”,
]
}
STARC_VLOG 3.5.6.3
RULE NAME
Describe the I/O ports and declarations in one line and always add
comments
Detected {ObjectType}s declaration that are not followed by a comment. It is
recommended to add comments in the same line per understanding and
readability of the code.
MESSAGE-1 DETAIL-1 {DirectionType} port “{PortName}” does not have corresponding comment in
the same line.
DETAIL-2 {SignalVariable} “{ObjectName}” does not have corresponding comment in
the same line.
Some objects are declared in the single line. It is recommended to write the
declaration of each port in a separate line and follow it with the corresponding
MESSAGE-2 comments in the same line per each declaration in order to improve
understanding and readability of the code.
DETAIL {ObjectTypeObjectNameList} are declared in the single line.
Detected comment(s) written before declaration of {ObjectType}. It is
recommended to declare {ObjectType} followed with comments.
MESSAGE-3
DETAIL Comment is written before declaration. Write each declaration in single line
followed by the comment.
The frequent use of comments improves readability of the source code. As a result, it becomes
easier to understand and maintain the source code, and this in turn leads to improved reuse
efficiency. Recommended volume of comments is generally should to be about 20 to 40% of the
source code.
PROBLEM
DESCRIPTION Comments indicating the purpose and functionality should be added to operators and statements
in the description. Moreover, the I/O port or internal register declarations should be described in
one line for each signal or register, and comments should always be added.
LEVEL RECOMMENDATION 2
module (ctrl, d1, d2, q1, q2); Detected ports declaration that are not follow ed by a comment. It is
recommended to add comments in the same line per understanding
input [1:0] ctrl; and readability of the code.
input d1,d2;
output q1,q2; reg tmp; Input port “ctrl” does have corresponding comment in the same line.
...
Some objects are declared in the single line. It is recommended to
endmodule w rite the declaration of each port in a separate line and follow it w ith
the corresponding comments in the same line per each declaration in
order to improve understanding and readability of the code.
Port(s) “d1, d2, d3, d4” are declared in the single line.
Port(s) “q1, q2”, variable(s) “tmp” are declared in the single line.
EXAMPLE-3: [1] comment is written before nets declaration => violation (message-3);
[2] generate loop variable is declared followed by a comment => no violation.
EXAMPLE-1: [1] two commented strings have characters which ASCII code out of range [0:127] => two violation
STARC_VLOG 4.1.2.3
RULE NAME The number of lines in fork-join should be a maximum of 5
'Fork-join' block has 'fork-join' contents to a maximum of
MESSAGE {MAX_LINES_RECOMMENDED} concurrent branches to avoid simulation speed
slowdown.
'fork-join' statement is a syntax that supports simultaneous execution. When 'fork-join' is used
effectively, improved flexibility in description is possible and this is convenient. However, 'fork-
join' also slows down simulation speed. Moreover, when there are too many assign statements in
PROBLEM
'fork-join' the readability declines. So it is recommended to limit the fork-join contents to a
DESCRIPTION
maximum of five execution lines.
LEVEL RECOMMENDATION 3
EXAMPLE-1: [1] 'fork-join' block contains 4 execution lines which is greater than MAX_LINES_RECOMMENDED
parameter value => violation.
Note: MAX_LINES_RECOMMENDED parameter value is set to 3 to simplify the example.
always @( ... ) begin 'Fork-join' block has 'fork-join' contents to a maximum of 3 concurrent
branches to avoid simulation speed slow dow n.
fork
case ( sel ) //execution line #1
1'b0 : ...;
1'b1 : ...;
default : ...;
endcase
fork //execution line #2
...
join
data1 <= ~tmp1; data2 <= ctrl ? res1 : res2; //execution lines #3 and #4
join
end
STARC_VLOG 4.1.4.1
RULE NAME
Avoid assigning from multiple initial constructs to the same signal
(Verilog only)
Signal "{ObjectName}" is assigned in {AlwaysCount} 'always' constructs. Avoid
assignments to the same signal from multiple 'always' or 'initial' constructs.
MESSAGE-1
DETAIL-1
{AssignmentsCount} assignment(s) to signal "{ObjectName}" in this
description block
Signal "{ObjectName}" is assigned in {InitialCount} 'initial' constructs. Avoid
assignments to the same signal from multiple 'always' or 'initial' constructs.
MESSAGE-2
DETAIL-1
{AssignmentsCount} assignment(s) to signal "{ObjectName}" in this
description block
It is unsafe to assign value to the same signal from multiple 'initial' constructs at the same time –
there is no guarantee what value will be assigned (it depends on simulator being used). Consider
following description:
initial begin
SIM = 1;
#(CLK_PERIOD * 512) SIM = 2;
end
initial begin
#(CLK_PERIOD * 10);
PROBLEM #(LOAD_DELAY);
DESCRIPTION for( i = 0; i < STIMULUS_COUNT; i = i + 1 )
#(A2B_DOMAIN) SIM = SIM * 2;
end
#(CLK_PERIOD * 77 );
end
It is not clear in what order values are assigned to "SIM". Moreover, racing problem tends to
occur (there could be multiple assignment simultaneously). Avoid assignments to the same signal
either from multiple 'initial' or 'always' constructs.
LEVEL RECOMMENDATION 1
EXAMPLE-1: [1] signal "Y" is assigned from the multiple 'always' and 'initial' constructs => violation (message-3)
reg Y; Signal "Y" is assigned in 2 'alw ays' constructs. Avoid assignments to
... the same signal from multiple 'alw ays' or 'initial' constructs.
always @( A or B or C ) begin
Y = A & B & C;
#(PATH_DELAY);
Y = A | B | C; 2 assignment(s) to signal "Y" in this description block
end
always begin
EXAMPLE-1: [1] two different signals assigned in one 'always' description block => violation
Description block assigns 2 signals. Defining one signal inside one
always @( A or B or C ) begin description block makes the pattern definition easier to comprehend.
Y1 = A || B || C;
Y2 = A && B && C; Signal “Y1” is assigned in this description block
end
Signal “Y2” is assigned in this description block
EXAMPLE-2: [1] different bits of the same signal are assigned in one 'initial' description block => no violation
initial begin
Y[0] = A || B || C;
Y[1] = A && B && C;
end
EXAMPLE-3: [1] two different signals assigned in one 'initial' description block => violation;
[2] note, that one of signals is assigned as output of the 'task' statement;
STARC_VLOG 4.1.8.1
RULE NAME Shift the observation point of a signal from an assignment point
Edge-sensitive 'always' process contains assignment(s) that is not delayed from
the referenced signal observation point. It is recommended to delay
MESSAGE assignment(s) of observed signals from the moment of their observation.
DETAIL Blocking assignment without intra-assignment delay is detected.
When signal is shared between the different blocks (simultaneously updated in first one and read
PROBLEM in another one), result becomes simulator-dependent, thus undefined.
DESCRIPTION
LEVEL RECOMMENDATION 1
Checker detects edge-sensitive 'always' processes (each signal in the sensitivity list has an edge
specifier) and scans them for blocking assignment without intra-assignment delay
CHECKER
BEHAVIOR – if RHS of such assignment contains signal => violation
Note: other assignments after first violation is detected are not scanned
Q3 <= DATA;
end
Checker collects list of clock signals (per module) by extracting clocks from:
– flip-flop inferences
– ports/regs/nets with synthesis attribute “(* synthesis, clock *)” specified
Note: since FF inferences are rare in testbench code, clock signal has to be specified somehow.
CHECKER Checker provides support for (* synthesis, clock *) custom non-standard attribute to specify clock
BEHAVIOR signal in testbench. Setting this attribute in Verilog description is up to designer.
Checker then verifies all event control statements:
– any signal in these controls should be a clock signal
– in case of violation, main message is displayed for module and one detail per each non-
clock signal
EXAMPLE-1: [1] all event control expressions are synchronized by clock "SYNC" => no violation;
[2] note: clock "SYNC" is extracted from flip-flop inference;
[3] note: either 'SYNC' or 'negedge/posedge SYNC' are treated as correct clocks;
initial begin
TMP = 0;
...
@( SYNC )
TMP = #DELAY TMP + 1;
...
@( negedge SYNC )
TMP = #DELAY TMP + REG_SUM;
end
EXAMPLE-2: [1] all event control expressions are synchronized by clock "SYNC" => no violation;
[2] note: clock "SYNC" is extracted from port declared with attribute;
always @( SYNC )
RES <= #DELAY DATA;
end
initial begin
TMP = 0;
EXAMPLE-3: [1] module has two clocks: "CLK" and "SYNC" (extracted from the attributes);
[2] 3 event control statements using 2 non-clock signals => violation;
initial begin
#DELAY; Signal "START" is not a clock
@( posedge START );
...
@( RESET or START or CLK );
...
end
endmodule
EXAMPLE-4: [1] module has a clock: "CLK" (extracted from the attribute);
[2] enabled task contains 2 event control statements using 2 non-clock signals => violation;
STARC_VLOG 4.2.3.2
RULE NAME
Do not define output arguments when generating test vectors using
task
Task "{TaskName}" has both timing control(s) and assignment(s) to output(s).
Such description has risk that necessary values will not be delivered to outputs,
because task modifies outputs after the end of its execution only. It is not
MESSAGE recommended to define output task arguments when generating test vectors
using tasks.
The first of {AssignmentsCount} assignment(s) to output argument
DETAIL
"{OutputName}".
Verilog language defines following rules for 'task' statements: input values are transferred to the
task at start of its execution; output values are returned only after the task is complete. This
property of output values makes impossible to generate simulation-time-dependent test vectors
on task outputs:
task GenSequence;
input [1:0] ADDR;
input [7:0] DATA;
output [1:0] A;
output [7:0] DIN;
begin
@( posedge CLK );
A = ADDR; //
DIN = DATA[7:4]; //
@( posedge CLK );
A = ADDR; //
DIN = DATA[3:0]; //
end
endtask
Example above describes the task that generates simulation-time-dependent test vectors (there
are two timing control statement). Changes that will never appear on the task outputs, are
PROBLEM marked with red "// -" comment, whereas changes that will appear on the tasks outputs are
DESCRIPTION marked with green "// -" comment.
Consecutively, in order to avoid the problem described above, task should assigned global
signals only or does not contains timing control statement.
Hint: to generate simulation-time-dependent test vectors with task, do not define outputs, but
assign globally defined signals instead:
reg [1:0] A;
reg [7:0] DIN;
...
task GenSequence;
input [1:0] ADDR;
input [7:0] DATA;
begin
@( posedge CLK );
A = ADDR; //
DIN = DATA[7:4]; //
@( posedge CLK );
A = ADDR; //
DIN = DATA[3:0]; //
end
endtask
EXAMPLE-1: [1] task "GenSequence" has two event control statements and two outputs are defined;
[2] output "A" is assigned once => violation;
[3] output "DIN" is assigned two times (part select is used) => violation
task GenSequence; Task "GenSequence" has both timing control(s) and assignment(s) to
output [1:0] A; output(s). Such description has risk that necessary values w ill not be
output [7:0] DIN; delivered to outputs, because task modifies outputs after the end of
begin its execution only. It is not recommended to define output task
@( posedge CLK ); arguments w hen generating test vectors using tasks.
A = ADDR;
DIN = DATA[7:4];
@( posedge CLK ); The first of 1 assignment(s) to output argument "A".
DIN = DATA[3:0];
end The first of 2 assignment(s) to output argument "DIN".
endtask
EXAMPLE-2: [1] task "GenSequence_1" has two event control statements, delay and two outputs are defined;
[2] output "A" is assigned 2 times => violation;
[3] output "DIN" is assigned once => violation
integer TMP;
Task "GenSequence_1" has both timing control(s) and assignment(s)
...
task GenSequence_1; to output(s). Such description has risk that necessary values w ill not
output [1:0] A; be delivered to outputs, because task modifies outputs after the end
output [7:0] DIN; of its execution only. It is not recommended to define output task
begin arguments w hen generating test vectors using tasks.
A = ADDR + 1;
@( posedge CLK );
TMP = 0; The first of 2 assignment(s) to output argument "A".
#DLY_TRAN;
TMP = 1;
@( posedge CLK );
A = ADDR + 2; The first of 1 assignment(s) to output argument "DIN".
DIN = DATA[3:0];
end
endtask
DETAIL
The first of {ReferencesCount} reference(s) to input argument
"{InputName}".
Verilog language defines following rules for 'task' statements: input values are transferred to the
task at start of its execution only; output values are returned after the task is complete. This
property of input values makes impossible to perform simulation-time-dependent observation of
task inputs:
task GenSequence;
input [1:0] ADDR;
input [7:0] DATA;
begin
A = ADDR; //
DIN = DATA; //
...
@( posedge CLK );
A = ADDR; //
DIN = DATA; //
...
end
endtask
Example above describes the task that observes simulation-time-dependent signals (there are
two timing control statement). Green "// +" comment marks input references that got an actual
value of input signal, whereas red "// -" comment marks input references that got an obsolete
PROBLEM value of input signal. So, it is not always possible to observe the signal values using the task
DESCRIPTION input signal.
Consecutively, in order to avoid the problem described above, task should referenced global
signals only or does not contains timing control statement.
Hint: to observe simulation-time-dependent signals in a task, do not define inputs but observe
globally defined signals instead:
wire [1:0] ADDR;
wire [7:0] DATA;
...
task GenSequence;
begin
A = ADDR; //
DIN = DATA; //
...
@( posedge CLK );
A = ADDR; //
DIN = DATA; //
...
end
endtask
LEVEL RECOMMENDATION 1
CHECKER Checker scans 'task' statements that meet following criteria:
BEHAVIOR
– at least one input is defined
– at least one timing control statement is specified.
Each referenced task input is a rule violation.
Note-1: intra-assignment delay is not timing control in this context.
Note-2: when input argument is vector, reference to its bit / slice is the same that whole vector is
EXAMPLE-1: [1] task "GenSequence_1" has two event control statements and two inputs referenced;
[2] input "ADDR" is referenced once => violation;
[3] input "DATA" is referenced two times => violation
task GenSequence_1; Task "GenSequence_1" has both timing (s) and reference(s) to input
input [1:0] ADDR; argument(s). Such description has risk that necessary values w ill not
input [7:0] DATA; be read from inputs, because inputs are passed to the task only w hen
begin task is called. It is not recommended to define input task arguments
@( posedge CLK );
A = ADDR; w hen regularly observing them inside a task.
DIN = DATA;
@( posedge CLK ); The first of 1 reference(s) to input argument "ADDR".
DIN = DATA;
end The first of 2 reference(s) to input argument "DATA".
endtask
EXAMPLE-2: [1] task "GenSequence_2" has a delay statement and two inputs referenced;
[2] input "ADDR" is referenced two times => violation;
[3] input "DATA" is referenced once => violation
integer TMP; Task "GenSequence_2" has both timing (s) and reference(s) to input
... argument(s). Such description has risk that necessary values w ill not
task GenSequence_2; be read from inputs, because inputs are passed to the task only w hen
input [1:0] ADDR; task is called. It is not recommended to define input task arguments
input [7:0] DATA;
w hen regularly observing them inside a task.
begin
A = ADDR;
DIN = DATA[3:0]; The first of 2 reference(s) to input argument "ADDR".
TMP = 0;
#DLY_TRAN; The first of 1 reference(s) to input argument "DATA".
TMP = 1;
A = ADDR;
end
endtask
Aldec, Inc.
Corporate Headquarters
2260 Corporate Circle
Henderson, NV 89074