Verplex was formal verification tool developed by Verplex in 1998. Cadence acquired it in 2003, and developed it under Conformal family of tools. Conformal family of tools are:

- Conformal LEC: formal verification tool (similar to formality by Synopsys). It has basic to advanced tools starting from Conformal L, Conformal XL to Conformal GXL.
- Conformal Low Power: enables low power equivalence and func checks for isolation cells, level shifter cells, state-retention cells.
- Conformal Constraint Designer
- Conformal Custom
- Conformal ECO Designer (look in eco.txt to see how to use conformal for eco)

Conformal LEC:
--------------
Encounter Conformal (EC) Logical equivalency checker (LEC): verifies RTL, gate or transistor level design
--------------------------------------
4 variants of conformal:
Conformal L (basic LEC), XL (extends to datapath synthesis/layout), GXL (extends to custom logic/memories), LowPower(includes equivalence and functional checks for isolation cells, level shifter cells and state retention cells).

Conformal LEC is 3 step process:
1. Setup mode: Read in golden and revised design and their associated library. Designs can be in verilog/vhdl, while libraries can be as verilog library or as Liberty files. Then we specify constraints and other parameters. All these designs/libraries are translated into conformal primitive gate types, which are: AND, OR, MUX, BUF, XOR, DFF, DLAT, INV, ADD, MUL, SUB, TIE0, etc (about 100 primitives). Most of these primitives are same as those of verilog.

2. Transition from setup to LEC mode: conformal checks various rules during parsing, and reports all of the library and design rule violations that occurred during parsing. Then it flattens and models the Golden and Revised designs and automatically maps the key points.
Key points are defined as Primary Inputs(PI), Primary Outputs(PO), D Flip-Flops(DFF), D Latches(DLAT), Blackboxes(BBOX), TIE-E Gates(E:error gate, created when x-assignment exists in Revised design), TIE-Z Gates(Z:high impedance or floating signals), Cut gates(CUT:artificial gates that break combinational loops).

3. LEC mode: Conformal does mapping of key points and reports unmapped points. Then it compares these mapped points (PO, DFF, DLAT, BBOX, E, Z, CUT but NOT PI) to determine if they are equiv or not. Each Key point may have multiple pins, and when checking for equivalence, all of these pins have to be equiv for that key point to be equiv.
We can also designate mapped points for comparison manually by adding naming rules. 2 ways of comaparison:
A. Hierarchical comparison: if one of the 2 designs is RTL.
B. flattened comaprison: done when both designs are gate level

Mapping is of 2 types: Needs to be set before exiting setup mode. Default is name based mapping.
A. name based (automatic) => 3 name based mapping:
 I. name first mapping: first maps key points with same name, and then remaining key points with mapping algorithm. Any remaining points are identified as unmapped points.
 II. name guide mapping: it does the opposite of name first. It first maps key points with mapping algorithm, and then remaining key points by matching names. Any remaining points are identified as unmapped points.
 III. name only mapping: maps points only if names match. Any key poitns that don't have same name are identified as unmapped points.
B. non-name based: Doesn't involve names. 1 type of non name based mapping:
 I. no name mapping: relies solely on mapping algo to map key points. Any remaining points are identified as unmapped points.

name based mapping is preferred as the name effort (set in the SET MAPPING METHOD command) is high by default and can take care of most changes in delimiters.After name-based mapping is performed, the left over key points will have different names between the Golden and Revised designs. There are several ways you can make their names similar in both designs:
1. Naming rules => Naming rules will be applied in RTL and facilitates in name based mapping with netlist
 2. Renaming rules => Renaming rules are applied when the instance names are different in golden and revised however shares a common pattern.
 3. ADD MAPPED POINTS command => When the number of key points having different names do not have common pattern and are less in number then it is good to manually map those key points using add mapped points command.

Number of key points b/w golden and revised may be different. Tool maps same key points b/w the two. Any kep points still not mapped are classified as unmapped points. Unmapped points are classified into 3 types (each type may have key points from DFF/DLAT, E, Z, etc):
1. Extra unmapped points (E): key points that are present in only one of the designs,Golden or Revised. This E is different than E of key points which stands for Error key points.
2. Unreachable unmapped points (U): key points that do not have an observable point, such as they do not propagate to a primary output or other key points.
3. Not-mapped unmapped key points (shows as Red DOT): key points that are reachable but do not have a corresponding point in the logic fan-in cone of the corresponding design. For complete mapping, there should not be any of these. These will be need to be resolved before running compare. Once we have 0 "Not-mapped" unmapped key points, we should report all unmapped points, and make sure they are expected as either E or U.

Compared points may be equiv, non-equiv, inverted-equiv or aborted. There should be no non-equiv points for a passing design. In the case of aborted compare points, you can change the compare effort to a higher setting. Thus, Conformal can continue the comparison on only the aborted compare points.

NOTE: For the whole design, all PI, PO, flops, latches and BlackBox are mapped. Points that still remain unmapped may be due to spare flops in revised, optimized away flops that are present in RTL but not in revised, BlackBox of antenna diodes in revised, etc. Any other unmapped points will need to be mapped. If they remain unmapped, then that may indicate some real flops missing in revised. Once all points are mapped (except for unmapped points, we set compare points which are PO, flops, latches and BlackBox. If they all match, then designs are equiv, else non-equiv
 
Renaimg rules: Add renaming rules if names don't match, and we want to force the tool to map certain key points.
-------------
add renaming rule d2D '/d$' '/D' => adds a renaming rule "d2D" which renames  small d to capital D.
add renaming rule r1 {"_reg_%d"} {"_reg[@1]"} => maps _reg_1 to _reg[1]
test renaming rule fsm_state_reg_2/N01 => this tests rules against the specified object and shows the renamed result.

Conformal supports 2 types of tcl cmd:
1. native tcl cmd (not as efficient as internal C funstions). entered by typing "tclmode" on cmd line. prompt shows TCL_*>.
ex: TCL_*> set env(RC_VERSION) "RC10.1.200 - v10.10-s202_1" => tcl cmd entered while prompt shows TCL_*.
2. Conformal tcl cmd (which have been tailored for use with Conformal to query the design database. Information retrieved from the design database is referenced by pointers (which are also called object handles in Tcl)). entered by typing "vpxmode" on cmd line. prompt doesn't show TCL_ anymore, so it means it's in vpx mode.

dofile syntax:
------------
1. // comments out rest of the cmd, while /// comments out rest of the line
ex: //read library lib_01.lib \
      lib_02.lib lib03.lib    => here all of the cmd is ignored (1st line as well as second line)
ex: read library lib_01.lib \
    lib_02.lib /// lib03.lib => here only lib03.lib is ignored. Rest of the cmd read lib01 and lib02.

2. Directives: We can enable/disable specified synthesis directives when reading in verilog/vhdl files. All directives by Cadence, synopsys, ambit are enalbled by default
add conformal directives as "infer_latch", "multi_port", "clock_hold", etc in the comment line //.
set directive off synopsys => this disables all synopsys directives found in verilog. We can use "on" to enable directives. If we don't provide vendor name as "synopsys" or other vendor name, then option applies to all vendors.
set directive off => disables all directives
set directive on parallel_case => enables only parallel_case directive since all other directives have been turned off.

Conformal lec run:
----------------
In main dir, we can have startup file .conformal_lec (it can be in installation dir, home dir or current dir) that conformal will execute on startup. The cmd files that are run are called dofiles. dofiles can be used at startup by specifying -dofile option

lec -12.10-s400    -nogui -log ./logs/rtl2gate.log -dofile scripts/rtl2gate.do => without -xl or -gxl, default Conformal L is started.
lec -9.1       -xl -nogui -log ./logs/rtl2gate.log -dofile scripts/rtl2gate.do => -xl needed for running dofile from RC.
lec -13.1-s180 -xl -nogui -log ./logs/rtl2gate.log -tclmode cmd.tcl => here instead of do file, we use tcl file
NOTE: starting from lec -13.1 and upto x.y, all cmds below are not separate (i.e read library), but joined by _ (i.e read_library). However, from 15.x onwards, cmds are back to original way (w/o _).
NOTE: we can start lec in gui mode by omitting -nogui

rtl2gate.do:
----------
0. set system mode setup => optional, as by default it's in setup mode (in later versions, all connected by "_", "set_system_mode setup").
1. Read library: It reads library in liberty format (since liberty files are used during synthesis). It can also read simulation library in verilog format, but only V-1995 format is supported. Simulation libraries should be used for final equiv check, since design verification signoff happens with simulation libraries, and NOT with synthesis libraries.
#-statetable option applies with liberty files, and specifies that library contains state tables.
#-both says read these libraries for both golden and revised. Else put -golden or -revised.
read library -statetable -liberty -pg_pin -both \
        /db/pdk/.../src/MSL270_W_125_2.5_CORE.lib \
        /db/pdk/.../src/MSL270_W_125_2.5_CTS.lib \
        /db/pdk/.../src/edc01024064012_W_125_2.5.lib => if fram or other ip are there

#read library -both -sensitive -Verilog /db/pdkoa/lbc7/2012.05.07/diglib/msl270/verilog/models/*.v => reading simulation library. sensitive means make it case sensitive
#read library -verilog -both lib/*.v fram.v => to read verilog simulation library

#NOTE: sometimes .lib and .v library for cells are not equiv at TI for some of the cells. In such case, first validate that the two libraries are same so that there is mismatch b/w lec and rtl sim resuls. Run these 3 steps to do that in a separate script.
read design -golden -verilog -define TI_functiononly -replace /db/verilog/models/*.v
read design -revised -liberty -append  /db/pdk/.../src/MSL270_W_125_2.5_CORE.lib
validate library => results show all cells and whther they are equiv or not b/w verilog and liberty

2. Read RTL design: Read rtl, elaborate and set top level to digtop
#-lastmod specifies that use the last module found incase of duplicate modules (default is to use the first module found and ignore other duplicate modules)
#-noelab should be used when design contains mixed languages. We want to do elaboration separately, as doing it with the read design cmd might fail to resolve it appr.
#-keep_unreach => unreachable key points are preserved. This is needed when hdl_preserve_unused_registers attribute is true on RTL designs.
#-map or -mapfile option allows designs to be stored in named workdspace isntead of default "work" workspace.
#-rangeconstraint and -configuration only applies to vhdl files. -rangeconstraint causes "dont care" for attributes when a variable is out of range. -configuration causes conformal to link entity/architecture giving configuration higher prority than lastmod.
read design -rangeconstraint -configuration  -vhdl 93 -golden -lastmod -noelab \
                ../../Source/spi_typedefs.vhd \
                ../../Source/spi.vhd   
#read design -verilog top.v -golden => read verilog design separately (-verilog2k for V2001)
#read design -file golden.vc -golden => golden.vc file has all verilog files in it as:
#-y Source/* => all files in this dir read
#golden1.v => other verilog files to be read
NOTE: when using golden.vc, sometimes digtop cannot be reolved as top level module, so we'll need to specify "digtop" and "defines" file separately
#write design => used to wrt out the design in verilog format that was read in. Useful to learn how Conformal parses RTL.
#elaborate design -golden => not needed as design is already elaborated by default.
set root module digtop -golden => here we can set root module to some lower level also, in that case comparison will start from that module. useful during hier comparison.

3. Read Synthesized gate level design, and set top level to digtop (no elaboration needed for gate level design):
read design -verilog -revised -lastmod netlist/digtop.v \
elaborate design -revised
set root module digtop -revised  => here we can set root module to some lower level just as can do it for golden above.

4. reports: rule check report below is a must for any RTL/gate neltist to make sure all of these warnings are OK. When RTL is coded for the first time, running verplex on RTL and reporting rule check is done to find any errors in RTL. These reports are also shown by default.
report rule check -all -verbose -design -golden => this reports all warnings/errors on golden RTL
report rule check -all -verbose -design -revised => this reports all warnings/errors on revised netlist
report design data => to run report of current design info. displays number of design modules, library cells, inputs, outputs, primitives, and one-to-one mapped state points on the Golden and Revised designs
report black box => To see what modules/cells got reported as black box. There should be none

5. set parameters
##add blackbox for IP/Macro. By default, blackboxes are mapped by their module names. To map by instance names instead, use the "SET MAPPING METHOD -nobbox_name_match" command. 3 ways:
A. add notranslate module : run before reading in design or library (before step 1 above). This is used for memories, since here the actual code of module is not parsed, but only dir for I/O ports are parsed and used for blackbox. This saves computer memory from reading and comparing these huge memory modules. ex: add notranslate module -both sshdbw00056025020 => this sram module treated as blackbox for both golden/revised.
B. add black box : run after module has already been read in. Used during hier comp.
C. set undefined cell -black_box : run before reading in design or library. this is useful if module doesn't exist at all. It tells Conformal to treat missing ref as blackbox. First 2 cmds above require code (may be empty code) for module with port declarations (conformal uses input/output dirn), while this one doesn't.
add black box fedc01024064012 -revised => module name and NOT instance name. No hier as it's flat in gate verilog. Ideally we should add black box for both RTL and gate by using option -both.
#add black box /U1/U4 -module -Golden => U4 module inside top level U1 module. If -module not used, then provide instance name

#reports if blackboxes are paired correctly b/w RTL and gate.
report black box -detail => use -detail to get detailed info.

##add net/pin constraint (only needed for scan designs):
add pin constraints 0 scan_en_in -revised => to force scan_en_in to 0 for gate netlist (since scan_en_in not tied to anything in golden RTL). If scan_en_in is not forced to 0, then gate netlist will have all flops which have extra scan_en pin, and when scan_en_in=1, then RTL and gate flop logic will mismatch.
#add pin constraints 0 scan_mode_in -both => This is needed since synthesis adds an extra mux on the output of final scan_out flop to give out diff o/p during scan_mode. However, we should run the tool with this commented out, so that we can be sure that the sdo_out port is the only one that is mismatching. Then we can uncomment this constraint, and run LEC again, which should be clean. Since scan_mode_in is just like any other i/p pin, blindly setting it to 0, may mask real logic problem which might have happened during synthesis.

NOTE: ideally, we should not constrain any pin for scan design. There are 4 possibilities of scan_en and scan_mode combo:
1. scan_en=0, scan_mode=0/1: This is above constrain that we already have. Only mismatch should be SDO out (when se=0, sm=1). For newer designs, tool puts mux at o/p pin SDO whose select pin is tied to se instead of sm. So, for se=0 (sm=x), designs would be lec clean since SDO would be matched for se=0, sm=x. If select pin of mux was tied to sm, then SDO out won't be equiv b/w gate and rtl.

2. scan_en=1, scan_mode=0  : This constrain can be put only for newer designs which don't have scan_en and scan_mode as PI ports. Since Internally scan_en is turned off whenever scan_mode=0 (there's "AND" gate logic), this becomes same as above (se=0,sm=0). Should pass with no mismatches. It's important to check this case as we may have design where during synthesis, we incorrectly set PI pin as se pin (instead of setting o/p of and gate as se pin, where 1 pin is PI and other pin is sm). In that case lec may never catch this bug if we don't check for this constraint (se=1, sm=0). silicon will never work with this bug, as during func run even when sm=0, toggling PI pin will cause se pin of each flop to toggle causing incorrect behaviour.
NOTE: for older designs which have scan_mode and scan_en i/p and o/p pins tied together at top level, we may not be able to run lec to test this case. However, it's already tested, as o/p pin scan_en_out is already tested in case 1 above (se=0, sm=0/1) for LEC as it's PO. So, no way that bug for option 2 can appear for older designs w/o causing LEC mismatch in scenario 1 above.

3. scan_en=1, scan_mode=1  : This will have all flops as non-eq, since flops in rtl do not have se pin, so this case can't be tested.

We should set these 2 cases (1 and 2 above) shown above in separate runs, and make sure they are clean. Just checking for se=0, sm=0 doesn't check all possible logic for scan.

NOTE: In newer designs, we don't have scan_en_in and scan_mode_in as separate PI ports. Since constraints can only be applied to PI pins, we have 2 options to get it to work:
 1. we set root module to the sub-module which has this pin as the i/p pin to that sub-module. Then we can add pin constraint to that pin as it's a PI fo that module. Then we switch back to top level module.
Ex: to set scan_en_in to 0, and make scan_en_out as PO. This makes the design same as older designs where scan_en_in i/p was constrained to 0, while scan_en_out was PO.
 set_root_module  u_dig_test_1 -revised => we provide module name and NOT instance name
 add_pin_constraints 0 test_se -revised => add pin constraint to scan_en pin to that submodule. Do it for other submodules too whose scan_en i/p pin need to be tied to 0 (by setting root module to that submodule).
 set_root_module DIG_TOP -both          => switch back to top level module to do comparison once all sub-module pins have been constrained
 add_primary_output u_DIA_DIG/scan_enable -both => we add "scan_en" o/p of sub-module as PO so that it can be compared. If we do not do this, then "u_DIA_DIG/scan_enable" may become Z(f) pin, which will not be compared. This pin will now show up as PO for key point mapping purpose.

 2. Most of the times, scan_en and scan_mode are o/p pin of submodule (and not i/p pin). They do go as i/p pin to various other sub-modules, but then we have to do add_pin_constraints to i/p pin of each sub-module (at too many places), so, option 1 above may not work efficiently. Instead we can cut o/p ports of such submodules, and make them PI and then constraint them. It achieves the same result as option 1 above, but is much easier.
Ex: same as option 1 where it looks the same as older designs.
 add_primary_input "u_SPT_DIG/auto/Scan_En" -net -cut -both => o/p pin of "auto" module is made as PI. -pin says it's a pin, while -net says it's a net (net is default). -Cut cuts the other original drivers and allow only the newly added primary input as the driver of the net or pin. This is the default. -NOCut does not cut the other original drivers, so new net gets driven by both internal as well as external driver (becomes a wired net). In this ex, "u_SPT_DIG/auto/Scan_En" net becomes a floating net, and all connections to this net, now get driven by PI pin "u_SPT_DIG/auto/Scan_En" which is a new user defined PI.
 add_pin_constraints 0 "u_SPT_DIG/auto/Scan_En"   -both  => as this pin is PI now, we can add constraint now. Note: once a constraint is added on a PI, it doesn't show up as PI anymore, as it's not used for mapping (since it's a constant pin)
 add_primary_output "u_SPT_DIG/auto/Scan_En" -both => we add "scan_en" o/p of sub-module as PO so that it can be compared. This pin will now show up as PO. This pin is defined both as PI and PO. That's OK as bidir ports are also defined that way. Also, it doesn't show up as PI anymore as it's a constrained pin.

add pin equivalences CLK CLK1 -revised => clk in RTL got trnslated as 2 pins CLK and CLK1 in gate. So, CLK1 is declared same as CLK.
add primary input net1 -net -revised => to add net1 inside revised netlist as extra PI to gate netlist
add primary output net2 -revised => to add net2 inside revised netlist as extra PO to gate netlist
add tied signals 0 SO -net -module U1 -revised => to tie floating nets/pins to 0/1
add instance constraints 0 /TOP/U2 => To constrain any internal DFF or DLAT output to Logic-0 or Logic-1
add instance equivalence U1 U2 -Golden => to specify internal equivalence or inverted equivalence between DFFs or D-Latches.
add cut point /U1/net1 -revised => To specify the cut points for breaking combinational feedback loops (conformal automatically cuts the loop when we exit setup mode)

report_pin_constraints -all => This is to verify that only intended constraints are there. Very important to run this.

#set flatten model => this cmd allows you to specify certain conditions for flattening the circuit. Usually applies to revised, when conformal is flattening design, as revised netlist is the one which get these transformations added by synthesis tool. (-latch_fold is the only option that should be needed. all others are optional).
#set flatten model  -map => conformal automatically maps key points when it exits the Setup mode
set flatten model  -gated_clock => when clk gating causes problems during comparison, we use this cmd to remodel latch based clk gaters into mux based feedback ckt to match rtl. adding option "-gated_clock_latch_free" remodels latch free clk gating into mux based feedback ckt. However, for this modeling to be valid, enable signal must be stable while clk is active.
set flatten model -latch_fold => To convert two master/slave D-latches (DLATs) into a single D flip-flop (DFF) gate. NOTE: This important to provide, since most libraries model flops as 2 MS D-latches while in RTL they are FF, so it will give tons of unmapped points when running lec with verilog model library, since DFF in RTL can't map to DLAT in libraries.
set flatten model -latch_transparent => to remodel DLAT (whose clk ports are always enabled) into buffers (transparent latch)
set flatten model -seq_merge => To merge common groups of sequential elements as one sequential element in the clock cone of a DFF or DLAT
set flatten model -all_seq_merge => same as above except that it's for the logic cone. -all_inv_seq_merge is for elements that are inverted.
set flatten model -seq_redundant => To remove seq redundancies, as rst pin of flop anded with Q o/p pin of flop. This redundancy causes non-eq for designs, so important to set this. At TI, verilog models of lib cells have this redundancy (SDB20.v in 33hpa07) in some cells, so we use option "-lib_seq_redundant" to remove redundancy from lib cells. In order to pass lec, we will have to use this option "set flatten model -lib_seq_redundant -seq_transform", run compare (which will show non-eq points), then do "analyze noneq" and agian run compare, which will make designs lec clean.
set flatten model -seq_Constant => To convert a DFF or DLAT to a ZERO/ONE gate if the data port is set to 0/1. adding option "-seq_constant_x_to 0" to -seq_Constant option will optimize flop to constant value 0 when flop is always in "X" state.
set flatten model -loop_as_dlat => To model combinational loop as a DLAT.

#mapping method: needs to be set before exiting setup mode. Default mapping is name-first, with no case sensitivity (use -sensitive to make it case sensitive).
set mapping method -phase => This method maps the key point with an inverted phase. i.e. comapres set logic of gloden to reset logic of revised and vice-versa for inverted-equiv. Phase mapping is recommended when the synthesized netlist has gone through sequential inversion or inverter push.
set mapping method -unreach => To map unreachable points.

#report environment -mapping => reports mapping method used.

set directive off synopsys => turn off synopsys directive

6. set lec mode, compare and report results:
set analyze option -auto
set system mode lec => This starts the mapping b/w golden and revised key points
=> At this point, all key points for golden/revised are reported, and which of these are mapped/not-mapped.
// Warning: Golden and Revised have different numbers of key points: Golden  key points = 5379 Revised key points = 5238
// Mapping key points ... Warning: Golden has 8 unmapped key points
================================================================================
Mapped points: SYSTEM class
--------------------------------------------------------------------------------
Mapped points     PI     PO     DFF    DLAT   Z      BBOX      Total => Z means floating node (TIE-Z)
--------------------------------------------------------------------------------
Golden            205    609    4302   104    7      4         5231 (total golden key points =5231+106+34+8=5379, matches above. see below)
--------------------------------------------------------------------------------
Revised           205    609    4302   104    7      4         5231 (total revised key points =5231+7=5238, matches above. see below)
================================================================================
Unmapped points:
================================================================================
Golden:
--------------------------------------------------------------------------------
Unmapped points   DFF    E         Total => E means Error node (TIE_E)
--------------------------------------------------------------------------------
Unreachable       106    34        140 => unreachable points are OK. Usually spare FF/latch in rtl are unreachable.
Not-mapped        8      0         8   => These Not-mapped points are not OK. These should be 0. Fix these before proceeding
================================================================================
Revised:
--------------------------------------------------------------------------------
Unmapped points   Z         Total
--------------------------------------------------------------------------------
Unreachable       7         7         => unreachable points are OK.
Not-mapped        0         0         => These Not-mapped points are OK. Usually there aren't any of these in revised. These may exist in eco designs, where o/p of some gates may not be used anymore in newer design, but there was no way to delete these.  
================================================================================

For the "Not-mapped" points above, tool will try to remodel and map them, since w/o that mapping, key point mapping is incomplete and LEC can't proceed. Most of the times, tool is able to prove these are unreachable and moves them to "U" category.
 
report unmapped points -summary > reports/summary.rpt => displays list of unmapped poitns. to see if there are any unmapped points. Mapped points can also be reported by using "report mapped points"
report unmapped points -extra => OK to have these
report unmapped points -unreachable => OK to have these
report unmapped points -notmapped => NOT OK to have these in rtl.

add compared points -all => to specify which mapped points conformal compares. default is all. Only mapped points are compared.
compare => starts comparison. shows progression from 0 to 100%.
=> Out of all mapped points, compared points are reported for equiv/non-equiv.
// 5016 compared points added to compare list. => NOTE: not all mapped points (5231) got added to compare list. This is because some mapped points got merged/converted/remodeled to get better matching.
================================================================================
Compared points      PO     DFF    DLAT   BBOX      Total
--------------------------------------------------------------------------------
Equivalent           609    3989   104    2         4704
--------------------------------------------------------------------------------
Abort                0      310    0      2         312 => If there are abort points, tool automatically tries harder until all "compared points" are done comparing.
================================================================================

report compare data -class nonequivalent -class abort -class notcompared >> reports/summary.rpt => view a list of all compare points and their status (equiv or non-equiv). When -class added, then only compare points belonging to that class are shown
#get_compare_points -diff -count => If this is anythnig > 0, then designs aren't equiv. This cmd can be used in tcl mode only.

#optional
#report_unmapped_points -golden  -notype BBox  > unmapped.golden.rpt
#report_unmapped_points -revised -notype BBox  > unmapped.revised.rpt
#reporting floating nets is helpful to find out large current issues.
#report_floating_signals -golden  -all         > floating.golden.rpt
#report_floating_signals -revised -all         > floating.revised.rpt

#below 5 cmds are helpful when we have non-eq points and we want lec to analyze and try again. works only with "-xl" license of lec.
#analyze noneq -verbose
#analyze setup -verbose
#add compare points -all
#compare
#report compare data -class nonequivalent -class abort -class notcompared >> reports/summary.rpt


report verification -verbose >> reports/summary.rpt=> reports a table of all violations as "non std ,modeling options used", "incomplete verifications", "design modifications", "extended checks" and "design ambiguity"
report statistics >> reports/summary.rpt => summarizes mapping and compare stats

exit => to exit tool

-------------
RC Compiler:
-----------
In RC compiler, we write dofile using this cmd:
write_do_lec -revised_design digtop.v -logfile rtl2final.lec.log >  rtl2final.lec.do => tool assumes that design loaded into RC is RTL design. -revised_design specifies gate level netlist. If -golden_design is not specified, RTL design loaded with read_hdl cmd is considered golden and hier comp is done. If -golden_design is specified with gate level netlist, then flat comp done since both are gate level netlists.

NOTE: Even if we don't write out dofile explicitly, RC automatically generates one (after synthesize cmd is run) and puts it in fv/<DIGTOP>/rtl_to_g1.do. This has OVF directives useful for mapping. OVF file is also put in same dir. RC also generates dofile w/o OVF which is in fv/<DIGTOP>/rtl_to_g1_withoutovf.do

Above cmd generates rtl2final.lec.do file. It has following cmds:
0. general setup:
tclmode => prompt shows TCL_*>
vpxmode => prompt doesn't show TCL_ anymore. start entering conformal cmds.

#abort cmd in dofile specifies how to respond to errors. <on | off | exit>
set dofile abort exit => exits the session if any errors in dofile

usage -auto
#log file
set log file logs/rtl2final.lec.log -replace

#oovf file that does transformation for module ports,clk-gaters, etc.
vpx read guide file fv/S1/rtl_to_g1.ovf

set naming rule "_" "" -array_delimiter -golden
set naming rule "%s_reg" -register -golden
set naming rule %L.%s %L[%d].%s %s -instance
set undefined cell black_box -noascend -both => All referenced modules should either be defined or blackboxed. On finding an undefined cell, conformal exits. To prevent it from erroring out, blackbox undefined cells. It's always inserted by write_do_lec cmd. However, avoid this as it can mask a user error.
set undriven signal Z -golden => undriven signal is set to "z" for golden design in auto generated dofile. In RC, undriven signal can be set to 0,1,X,none(default). In LEC, the "none" default setting is translated to "Z" default setting.


1. Read library: It reads library in liberty format (since liberty files are used during synthesis). It can also read simulation library in verilog format, but only V-1995 format is supported.
read library -statetable -liberty -both \ => -ststetable and -liberty are always present in dofile gen by RC
        /db/pdk/lbc7/rev1/diglib/msl270/r3.0.0/synopsys/src/MSL270_W_125_2.5_CORE.lib \
        /db/pdk/lbc7/rev1/diglib/msl270/r3.0.0/synopsys/src/MSL270_W_125_2.5_CTS.lib


2. Read RTL design: Read rtl, elaborate and set top level to digtop. read_hdl in RC gets translated into read desgn
read design -rangeconstraint -configuration  -vhdl 93 -golden -lastmod -noelab \
                ../../Source/spi_typedefs.vhd \
                ../../Source/spi.vhd         
elaborate design -golden
set root module digtop -golden

3. Read Synthesized gate level design, and set top level to digtop :
read design -verilog -revised -lastmod -noelab netlist/digtop.v \
elaborate design -revised => sometimes, elaboration is not needed for gate level design
set root module digtop -revised

4. params/settings
set undefined cell -noascend black_box -both => this cmd always added by RC as it tells to make all undefined cells blackbox. This should NEVER be used in user gen dofile, as it can mask real errors for undefined cells.
report design data
report black box

//analyze and apply OVF Transformations loaded above by reading ovf file
vpx apply guided transformations
vpx report guide information

uniquify -all -nolib
set flatten model -seq_constant -seq_constant_x_to 0 => this added if any of the const 0 or 1 flops, or const latches are optimized in RC.
set flatten model -nodff_to_dlat_zero -nodff_to_dlat_feedback
// set parallel option -threads 4 -license xl
set analyze option -auto

#write out dofile based on all cmds above and then run that dofile. We do hier compare since then it's easy to debug which modules failed.
write hier_compare dofile outputs/hier_rtl2final.lec.do \
        -noexact_pin_match -constraint -usage -replace -run_hier \
        -prepend_string "analyze datapath -module -verbose; usage; analyze datapath -verbose"

#dofile generated above has cmds for comparing each module of design. Only modules that have same input/ouput pins for both revised/golden are considered for hier compariosn. also, modules which have <50 instances in them are skipped for hier comp, since they are easy to be compared at top level. Once hier comp is done for a module and it's equiv, it's blackboxed, and then blackbox model is used when doing hier comp for other module. This dofile has cmds which look like this:
1. comparing one of the sub-modules S1_CLOCK_GATE:
set system mode setup => setup mode
set root module S1_CLOCK_GATE -Golden
set root module S1_CLOCK_GATE -Revised
set module property -instance /I_S1_TIMER/I_S1_CLOCK_GATE -Golden
set module property -instance /I_S1_TIMER/I_S1_CLOCK_GATE -Revised
add pin equivalences XRESET FE_OFN42_xreset_r -hier -Revised => add pin equiv in revised since one pin can have multiple copies.
add ignored inputs I_PIN_YGPIO[5] -Golden => ignore certain i/p pins for golden.
report black box -NOHidden

set system mode lec => lec mode
analyze datapath -module -verbose; usage; analyze datapath -verbose => this string added doing write of dofile.
add compared points -all => adds all PO and state points to compare list
compare -noneq_stop 1 => compare stops on 1st non-equiv point
save hier_compare result
usage

2. blackbox the above module and compare next sub-module. If this sub-module instantiates other sub-modules, then they are blackboxed and compared.
set system mode setup
add black box S1_CONTROL_S2 -module -hier -Golden => blackbox above module
add black box S1_CONTROL_S2 -module -hier -Revised
set root module S1_CONTROL_HUNT -Golden => start with new sub-module
set root module S1_CONTROL_HUNT -Revised
...

3. comapre root module after comparing all sub modules. Root module will blackbox submodules that are directly instantiated in it.
set system mode setup
add black box S1_TIMER_WRAPPER -module -hier -Golden => blackbox the last submodule. All other submodules have been blackboxed.
add black box S1_TIMER_WRAPPER -module -hier -Revised
set root module digtop -Golden => set module to digtop
set root module ditop -Revised
set module property -instance / -Golden
set module property -instance / -Revised
...
save hier_compare result
usage
set system mode setup
report hier_compare result -usage
report hier_compare result -Non_equivalent -usage
report hier_compare result -Abort -usage
report hier_compare result -Uncompared -usage

--------------------
The dofile can be run using any of the 2 cmds below
1. run hier_compare outputs/hier_rtl2final.lec.do
2. dofile outputs/hier_rtl2final.lec.do

#report hier compare results
set system mode lec
tclmode
puts "No of diff points    = [get_compare_points -diff -count]"
if {[get_compare_points -diff -count] > 0} {
    puts "ERROR: Different Key Points detected"
}

vpxmode
exit -force => exits Conformal
--------------------------------

Running LEC for LINT checks:
------------------------
We can run lec for doing LINt checks by running lec in gui mode and doing read design on rtl, and then going to Tools->HDL Rule on gui to see all rule violations

home/kagrawal/> lec -gui -log lec.log -dofile check_rtl.do
NOTE: We can also just run "lec" and then from gui goto "Do Dofile" and select "check_rtl.do" file. This will run the script. Just be sure to do a "reset" before running dofile to load new results.

check_rtl.do has following:
-----------
set directive off synopsys
read library -verilog2k /db/pdkoa/lbc8lv/current/diglib/msl458/PAL/CORE/verilog/*.v /db/pdkoa/lbc8lv/current/diglib/msl458/PAL/CTS/verilog/*.v
set rule handling RTL14 -Ignore -library => ignore certain rules for library cells, as we want to see violations for our RTL code only
set rule handling VLG9.2 -Ignore -library
set rule handling UDP3.2 -Ignore -library
set rule handling DIR6.1 -Ignore -library
set rule handling DIR6.2 -Ignore -library
set rule handling IGN2.1 -Ignore -library
set rule handling IGN3.2 -Ignore -library
set rule handling HRC3.16 -Ignore -library
set rule handling HRC3.10a -Ignore -library

set rule handling RTL1.1 -Ignore -Design -Golden => to ignore certain rules for design (design can be -Golden or -Revised or Both)

read design     ../../rtl/meson_clock_gate.v \        
        ../../rtl/i2c_top.v \
        -Verilog2k -sv -Golden -sensitive -root i2c_top

NOTE: on changing the RTL, we can rerun the design from within gui window by running this on cmd line:
SETUP > reset
SETUP > dofile check_rtl.do

---------------------------------------

Spyglass

SPYGLASS is a synopsys tool which does RTL/GATE linting, CDC and RDC checks. Mostly used on RTL, since there are many other tools for checking GATE level netlist for correctness. The GUI version of spyglass is called "spyglass Explorer". The below section talks about original SPYGLASS tool. As of 2022, Spyglass is integrated under "VC platform" and repackaged as "VC Spyglass" or "VC Static Spyglass" or just "VC Static". VC Spyglass has slightly different syntax, so we'll cover that in a separate section. Below section may not apply anymore, as that original Spyglass is deprecated. But in case you are still running it, you may follow the details below. Else move to "VC Spyglass" section.

SPYGLASS is a PERL source file,that has rule defn and PERL subroutines, if any. Each rule has a number of attributes that decide how the rule will function. some imp attr are rule_name, msg, rule_primitives, etc. Rule primitives are C functions that are present either in SpyGlass core or in a shared library. They perform the real work of checking rules against your design and can be parameterized to produce different checks.


Running Spyglass (SG) standalone:

SPYGLASS is usually installed in a path like this: /project/tools/synopsys/spyglass/N2018.12-SP2-3-T-20191002/SPYGLASS_HOME/ => We'll refer to this as "$SPYGLASS_HOME"

spyglass invoked by typing "spyglass" or "spyglass -gui". The shell version (no gui) brings up "sg_shell" where we can enter spyglass cmds. "gui_start" on sgshell also brings up the gui. Tcl 8.7 is supported in sg_shell.

spyglass -project digtop.prj => This runs spyglass with project file provided. project file is just bunch of cmds for reading all i/p files, setting options and running steps. Otherwise we can start w/o .prj file, and enter everything manually using cmdline or gui.

spyglass -tcl input.tcl -shell => other way of launching SG. We provide all SG cmds as well as tcl cmds in input.tcl. digtop.prj file can be called from within input.tcl via cmd "new_project -force digtop.prj". -shell causes SG shell to be invoked as opposed to gui.

Inputs/Outputs to SG: SG shell is used to tke input cmds and generate output reports. Console SF is used to navigate RTL, view waveforms, etc. In VC Spyglass, Verdi is used isntead of Console SF, so it's lot easier as same Verdi interface is present when traversing design.

  • Inputs: SG takes input as RTL/netlist and stdcell .lib files (if netlist provided, or if RTL contains stdcells instantiated)
    • Project file => .prj file which contains path to design RTL/netlist, stdcell .lib files.
    • Constraints => .sgdc or .sdc file. These are std SDC constraints for clks, IO ports, false_paths, etc. SGDC constraints are SDC constraints, but translated to Spyglass format.
    • Waiver files => .swl or .awl files. These are waivers that apply to Errors/warnings (ones that we want to waive)
  • Outputs: SG provides output reports.
    • Reports => .rpt files which list Lint/CDC/RDC violations.

 
When Spyglass run on design, these steps are run as follows:

  1. Analyze_design => syntax warning/error, basic synthesis warn/error displayed.
  2. Elaborate_design => elab warn shown.
  3. RTL_Rule_checking => all rtl rule checks done (NOT the rules associated with goals).
  4. Synthesize_Design => advanced synthesis done, and warn/error shown.
  5. Structural_read => structural read of design is done, and here rules of goals are run and results displayed. If no goals specified, then no rules checked.

LINT checks:

  1. Checks for basic connectivity issues, sim issues, synth issues, and also for recommended design practice.
  2. Also does functional analysis to identify issues with RTL


CDC/RDC checks:

  1. ensure all flops have clk,
  2. ensure clk and reset tree are free of glitches/races (sgdc file should have at the least clock and resets defined, since sdc file do not have reset defn in them, we need to put reset defn in sgdc)
  3. check all aspects of CDC = metastability, coherency problem on reconvergent crossings, sync resets, etc

 


 

SG Commad file => The project file (digtop.prj) has all cmds. This file is divided in 3 sections => design setup, goal setup and Analyze results.

1. design setup: => all design files (verilog, vhdl etc), constraints file (sdc or sgdc), waiver files (awl), tech/hdl libs (liberty files) read here (This is "Design Setup" icon on gui)

#read i/p files. These can be added using gui "design_setup->add_files" menu. Then use "design_setup->Read Design" menu to read all these files added.
read_file -type sourcelist /db/...Source/digtop_rtl.f => read RTL files using sourcelist
read_file -type verilog /db/design/../sram.v => read verilog file for memory element used in RTL. Usually not needed as model of IP not required for spyglass to do it's checks. It can be treated as a blackbox.
read_file -type gateslib /db/lib/.../STDCELL.lib => read gate liberty files (usually needed for netlists). We can provide .lib or .v files for gates, as both of them have the functionality defined. For Hard IP, we need these lib files too, unless we want them to be treated as blackbox.

#read_file -type sglib /db/lib/.../STDCELL.sglib => this is proprietery SG lib files for gates. It's binary, so can only be read by SG tool. .lib files above can be converted to sglib for faster run times on future runs.
read_file -type sgdc /home/.../spyglass/common_project_constraints.sgdc => read sgdc (spyglass design constraints), similar to sdc with some variations, described later

read_file -type sgdc /home/.../spyglass/digtop.sgdc => constraints file specific to design. For Hard IP, we can either provide .lib file or .sgdc file to include them in CDC/RDC analysis. See later on how to generate abstract sgdc files for IP from within spyglass.
read_file -type awl /home/.../spyglass/common_waivers.awl => awl file is the one generated by tool that should be used for waivers
read_file -type waiver /home/.../spyglass/waivers.swl => read waivers from swl if present

#set options for sdc (optional) => this section is needed if you have sdc file that need to be converted to sgdc (read sdc file via cmds shown later)
set_option sdc2sgdc yes; => To enable translation of SDC to SGDC (SGDC=spyglass design constraints file, which has a different syntax than SDC file).
set_option sdc_generate_cfp yes; => To enable generation of cdc_false_path commands.
set_option support_sdc_style_escaped_name yes; => To allow non-escaped names used in SDC.
set_option sdc2sgdcfile ./output/digtop.sdc2sgdc.out; => To specify name of the translated SGDC file.
set_parameter sdc_domain_mode  sta_compliant; => This is default value. Mentioning here to capture the recommended values for the parameter.
set_parameter sdc_generated_clocks yes; => To have the generated clock definitions translated to clock constraint.
set_parameter enable_generated_clocks yes; => To have the generated clock definitions translated in uncommented format.

constraints:

constraints file = usually constarints file provided in sgdc format. Depending on goal, we may need less/more constraints. Usually for lint, no constraints needed. For CDC/RDC, we need clock and reset defined for I/O ports. We may also define clocks for other I/O ports (i.e clk driving the i/p port, or clk capturing the o/p port), so that the tool knows if a synchronizer is needed for these I/O ports).

Instead of writing constraints in sgdc format, which may be painful, we can reuse sdc constraints file from synthesis or sta runs. If we have sdc file, we can put the cmd below in sgdc file, and it will generate a new sgdc file to be used based on constraints from sdc file.

sample constraints file in sdc:
current_design digtop
sdc_data -file digtop.sdc => read sdc constraints file natively. sgdc file generated for use by spyglass. sdc file doesn't have any reset related info, so we need to provide that and any additional info by manually adding that to sgdc file generated. This sgdc file is generated in file specified via "set sdc2sgdcfile" option above. This generated sgdc file is the one that is used for SG runs.

sdc->sgdc translations (these translations are done internally by SG and translated cmds are put in sgdc file)

  1. create_clock -> clock (no more documentation for clock in spyglass online help manual, it says it's not supported in tcl shell, so very limited documentation). For every create_clock cmd, clock cmd with diff domain as "d0", "d1", etc created. However, all such clocks are still treated as sync, just as in sdc cmds. If duty cycle not specified, then it's assumed to be 50%.
  2. set_input_delay -> input
  3. set_output_delay -> output
  4. set_false_path -> false_path/cdc_false_path.
    1. ex: cdc_false_path -from clk1 -from_type clock -to clk2 -to_type clock,
    2. ex: false_path -from clk1 -to clk2 -type sfp => -type specs where this false path got translated from. here -type sfp implies it got translated from set_false_path sdc cmd.
  5. set_clock_groups -> false_path/cdc_false_path => This cmd specs async behaviour among diff clocks. Very imp to specify this. If no false path b/w clks or clock groups specified, then all clks defined via "clock" considered synchronous. In such a case, CDC runs have no meaning, since there will be no CDC violation (as all clks are considered synchronous). Here false path specified b/w clk groups defined as async or logically/physically exclusive.
    1. ex: set_clock_groups -asynchronous -group clk3 => false_path -from clk1 clk2 -to clk3 -type scg_asynchronous =>  here -type scg_synchronous specs that this false_path cam from sdc cmd "set_clock_groups -asynchronous"

generated sgdc file: (has sgdc cmds in it). This can be auto generated from sdc file above, or can be manually modified.

top.sgdc file:

#top module
current_design digtop => top level module specified

#clk
clock -name "digtop.clkosc" -domain domain3  -edge {0 20} -period 40 => specify all clk pins using this cmd, so that sypglass can analyze clock paths. Here, we specified port name for clk, but if we want to give optional tag name for this clock, it can be done via option "-tag CLK1" (so this clk, clkosc, will now have a tag "CLK1" that can be used instead of "digtop.clkosc" => similar to sdc option "-name CLK1"). NOTE: names can be ports or hier net/pin names (hier names are rep by using . as a separator). Both tag and name specified in sgdc cmd, when name specified in create_clock.

clock -tag "top.mod1.VCLK_1" -domain "top.mod1.clk_domain1" => virtual clk specified (since no -name used, and -tag used). clk can be virtual clock also (instead of a port). Virtual clk can be defined as having a clk waveform. However, since there is no port associated with virtual clk, we have to use "-tag <clk_name>" to give the virtual clk a unique name, with which it will be identified. This clk is identified as virtual clk by the absence of a port name. It is by default considered asynchronous to all other clocks. Even if we don't define a virtual clk, any undefined clk is considered virtual clk.

#reset
reset -name "digtop.n_puc" -value 0 => reset pin with active value=0 (active low), specify all reset pin, so that sypglass can analyze reset paths. reset is assumed to be async reset, unless option "-sync" used, which makes it sync reset.

#for all other i/o ports, we use "input/output" or "abstract_port" cmds. SG reccomends that "abstract_port" cmd should be used instead of input/output cmds. We specify constraints for i/p ports only (i.e driver clock), o/p port constraints are generated automatically by the tool (only for abstract model, explained later), and do not need to be provided. If the driver clock defn is not found (i.e it hasn't been defined via "clock" cmd), then it is assumed to be a virtual clk and hence async to all other clocks.

#input -name "top_1.DMUX" -clock vclk => This specifies that i/p port DMUX in top_1 module is driven by clock named "vclk". Note, vclk is name of clk and not tag of clk (in cmd "clock -name vclk"). clock can be virtual clk too, in which case we specify the tag (clock -tag vclk).
#output -name "out_1" -clock clk_port0 => this specifies o/p ports, with destination clock as "clk_port0" (i.e o/p port finally goes into seq element being driven by clk_port0). clock can be virtual clock too. Usually, "output" cmds not needed. Reason is no matter what is the destination clk for o/p port (sync or async), we always put synchronizers on i/p side of any block. So providing this info serves no purpose, as even if we know the destination clk is async, we don't put any synchronizers on o/p ports of our block.

abstract_port -ports IN1 -scope cdc -combo no -clock clk_1 => i/p port being driven by clk_1.

#abstract_port -ports OUT1 -scope cdc -combo no -clock clk_2=> o/p port being driven by clk_2. NOTE: this is diff than "output" cmd, where name of clk specified destination clk, while "abstract_port" specifies source or origin clk. There is no way to specify destination clk using this cmd (may be ok?? FIXME). However, we never provide o/p port constraints, so no need to  bother about these.

###other constraints

#synchronizers

sync_cell -name synchronizer_2ff => synchronizer cells are used in any design with clk crossing. Either these are provided as lib cells, or are just put directly in design by having multiple flops back to back. This cmd specifies valid synchronizer cells for control crossings. We can specify multiple such cells with optional from/to freq or clk, and tool will make sure that all crossings have one of these lib cells across them. If any other cells besides the list here or "manually inserted back to back flops" are used in design or src/dest freq/clk condition not satisfied, then tool will flag it. NOTE: these sync cells are valid only for ctl crossing, since data crossings do not have sync cells.

sync_cell -name SDF_SYNC_CELL -reset => specify clock domain crossing on reset path be considered as synchronized (i.e reset signal coming in should be sync to dest clk. If it's not, then it should be flagged as CDC ERROR, since inbuilt synchronizer doesn't have any logic to sync reset signal and it's behaviour assumes that reset coming in is sync to dest clk). We specify more such sync_cells for vaious sizes.


reset_synchronizer -name dig_top.q1[5]  -clock LFO_CLK  -reset dig_top.q1[5] -value 0 => used to specify a reset synchronizer signal along with its asserted reset value. -name specs name of sync o/p, -reset is the name of src reset for which "-name <name>" is the synchronizer. -clk is clk of synchronizer. -value 0 specs that 0 is the active assertion value of reset sync (this value is used by SG for de assertion verification purpose)

num_flops -default 2 => specs that min 2 flops shuld be used for multi flop sync for all clk crossings for which num_flops is not specified.

#false path
cdc_false_path -from "I2C_SDA_IN" -to "I2C_SCL_IN"
cdc_false_path -from "I2C_SCL_IN" -to "I2C_SDA_IN"
set_case_analysis -name "digtop.SCANMODE" -value 0 => to run in func mode only. net/pins can be tied to a certain value depending on mode, so that analysis is not done with those toggling. Since scanmode changes clks, CDC analysis can become very noisy, just like STA runs

quasi_static "top.netA[*]" => this is used for signals which are quasi static, i.e they change once in beginning but then assume a static value of 0 or 1. CDC skips verification of such paths, which is what we would want since such signals don't need synchronizers, etc (i.e signals b/w scan and functional, since we control how many cycles to wait to allow values to propagate correctly, so no need to check for synchronizers b/w these signals). wildcards * and ? allowed here. However, when using wildcards, double quotes needed.

cdc_attribute -unrelated "digtop.en_sync[0]"  "digtop.en_sync[1]" "digtop.en_sync[2]" => states that these are unrelated signals

reset_filter_path ..., cdc_filter_coherency => These are used to ignore certain objects in analysis

#below are needed if we do dft related checks. Not needed if we do not want to do dft checks

clock -name "digtop.dft_scan_clk" -domain CLK03  -value rtz -testclock -atspeed => define test/dft clk.

testmode -name dft_mod2.tds_en -value 0 -scanshift => This forces value to 0 in testmode for tds_en signal. -scanshift implies it's only during scan shift and not during entire test mode
noscan -name "n_clkgater_dft.*func_pulse*"

sample waiver file:

waiver file = *.awl => It's an SGDC format file that contains waive constraints
--
waive -rule W415a -msg {signal assigned multiple times :[Hier: ace_dig:i2c*_inst..]} -exact -comment "i2c waived" => these waivers generated by selecting msg to waive and right click "Waive msg to->waiver file". -msg will waive messages which match exactly the same msg content as in {}, so only that particular logic with that rule will be waived. If -msg wasn't there, then all logic matching that rule "W415a" would be waived which would be incorrect. -exact will match */?/etc in -msg {} exactly and not treat them as perl wildcard match (so i2c* matches i2c* in msg, otherwise it would match i2c0, i2c1 etc)

waive -du "WORK.i2c_fsm" -rule "Ar_asyncdeassert01" -msg {Reset signal 'bellatrix_digtop.sync_SOFT_RESET.sync2_q' for 'set' pin of flop 'bellatrix_digtop.addrValid is async} => design unit specified here

----

#Now after finishing constraints and waiver file, we can set some other optional options
#set options general (optional)
set_option top digtop => mandatory if -top is not provided while running "goal setup". spyglass doesn't figure out top level by itself, and will error out.
set_option projectwdir /home/.../results => set project working dir
set_option active_methodology $SPYGLASS_HOME/GuideWare2.0/block/rtl_handoff => we defined active methodology here. Optional, as we use cmd "current_methodology" later.
set_parameter synchronize_cells SYNC2SDFFCQ_F4_DH_85LL => specifies that any synchronizer must use this cell as synchronizer.

methodology: We define active/current methodology for the run in SG using "set_option active_methodology" or "current_methodology". This decides what all set of goals are going to be run. 3 methodology for block are defined by default: initial_rtl, rtl_handoff, netlist_handoff. rtl_handoff is the most common methodology that we use on RTL.

We'll see corresponding dir for each methodology here in $SPYGLASS_HOME/GuideWare2.0/block/rtl_handoff. Within each dir, we'll see subdir for each goal category as cdc, lit, rdc, dft, adv_lint, power, etc. , Within each goal category dir, we have further subdir for final goal as cdc_setup.spq, lint_rtl.spq, etc. These goals are referred as "cdc/cdc_setup" including full dir path. Dir structure can be anything, just the full path for each goal needs to be provided for the goal to be recognized. These final goal files are in internal spq format. Goal is basically a collection of rules. They have syntax as:

=template++++++ //template section that prints whatever you want to show to user as documentation for that goal. It displays on RHS of gui window

CHECK for RTL: This checks for 1. ... etc //This displays on gui window as description

=cut++++++++

-policy=clock-reset //setup cmd to register policy

-enable_mux_sync=all //setup cmd to enable specific parameter

-rules Clock_check10 //This rule is added to this goal, similarly 100's of rules added for each goal

-overloadrules Ac_clockperiod01+severity=Error => changes severity of rule "Ac_clockperiod01" to Error, other default severity for that rule applies

Instead of 3 default methodology, we can define our own custom methodology also. There we can have our own custom goal, each of which can have whatever rules we want to be checked. ex:

current_methodology /home/custom_meth/lint_cdc => methodology is now custom "lint_cdc". Within this dir, we can have similar files as above for custom goals, ex: custom_rtl_lint.spq. then in gui, under goals, it will show as "lint_cdc/custom_rtl_lint" and so on for other goals


2. goal setup: adds setup info for goals, sgdc files, reports. These can be added using gui "goal setup" menu, and selecting required goals.

Main goal categories for rtl_handoff methodology are => lint, adv_lint, constraints, cdc, rdc, power, physical, rtl2netlist and connectivity_verify. Within each goal category are various goals (i.e cdc/cdc_verify).

Within each goal (i.e cdc/cdc_setup_check) are various rules (Ac_report01, etc), which can be enabled/disabled as needed (on gui, right clicking on rules brings up edit window).
#goals to run => we specify separate line for each current_goal, they can also be combined in one using other options in "current_goal" cmd.
> current_methodology $SPYGLASS_HOME/GuideWare2.0/block/rtl_handoff => scope of each goal is confined within scope of current methodology. methodology decides which rules will be run for particular goal, since some rules may only be appr for RTL while some for gate.
> current_goal Design_Read -top digtop => goal = read design and show basic errors. Each goal has a set of rules that's checked against.
> current_goal lint/lint_rtl => lint goal category, etc
> current_goal cdc/cdc_setup_check -top digtop => cdc goal category. specify goal scope. -top is optional, as top is picked from options
> read_file -type awl cdc_waiver.waiver => if no "read_file" specified for each goal separately, then all files specified above are read for all goals. We specify sepaate files, when we need diff waiver files for diff checks
set_goal_option default_waiver_file /home/.../spyglass/common_waivers.awl => picks up default waiver file specified above, on top of cdc waiver file
> current_goal cdc/cdc_verify_struct => another cdc goal

Custom goals: We can define our own custom goals, on top of std goals provided.

define_goal CUSTOM_GOAL_1 -policy { lint } { => this defines custom goal "CUSTOM_GOAL_1" which starts appearing next to all std goals
set_parameter abc def
}


3. analyze results: goals run, and results shown. In gui, click on "Analyze_results" and then "Run goal". It will run all selected goals (i.e cdc/cdc_setup, etc). Results are displayed based on which goal is chosen on top for display. We have to click on each goal, one by one, to see messages for all goals. Bottom half of gui is where it shows shell, violations and waiver tree tab. Click on "violations" tab, and look for "Group By" in the top part of this bottom gui. Select "Goal by severity" to see them arranged by severity (Fatal, error, warning, info). We can group them any way we want by choosing appr option
> run_goal => runs all the goals chosen above. You will see a lot of rules being checked. Creates default dir for results (eg Group_Run/lint_rtl/spyglass_reports/*.rpt, *.log)
> write_report summary > summary.rpt => write_report cmd is optional as reports are written by default. This is needed if want our own non-default file name, paths, etc
> write_report moresimple > simple_summary.rpt

Incremental Mode analysis: A usefule mode if we want to see incremental changes in design compared to previous design (i.e what are the new errors/warnings showing up compared to the older design). This can be selected by choosing "incremental mode" on top of gui.

Scenarios: A scenario is a goal that contains modified settings of a goal. You can create multiple scenarios for a goal where each scenario represents different settings for that goal. For example, you create the scenario, Scenario1, for the connectivity goal in which you change values of some parameters. Similarly, you can create another scenario, Scenario2, for the same connectivity goal in which you can specify certain files, such as VCD or SGDC files. You can run these scenarios like any other goal. The advantage of using scenarios is that you can save different settings (in the form of scenarios) made for a particular goal.


Debug procedure on gui:
A. clicking on Design icon on top, shows all details of design => modules, blackbox, flops, etc
B. clicking on nand gate (or triangle yellow warning icon) in messages will bring up rtl code with corresponding violation on above RTL screen. We can get rtl on any editor by "right click" and then "open editor"
C. waiver file shoukld be enabled for each goal (by clicking waiver, selecting the waiver file, right click->enable_file), else it may not get picked up.
D. reports are by default in digtop/ace_dig_top/lint/lint_turbo_rtl/spyglass_reports/spyglass_violations.rpt, similarly for others.
E. If you see a error or warning msg, and want to look into the schematic for where that error is happening, then click on particular error/warning in bottom window. Now click on + sign to expand it (since errors of particular nature are grouped together). Once you are down to the bottom most where you see only that error, right click, and select "incremental schematic". This will bring up a schematic showing exactly where the issue is. It hides all unrelated logic, so it's very useful to debug this way.


In order for design to be clean, messages should have no error/warning for each goal. We have to go thru each goal, and look at messages. So, there has to be separate waiver file for each goal, as cdc waiver file will be very different than lint waiver file (as cdc messages are lot diff than lint messages)

abstraction:

Until now, we ran CDC/RDC flat on the whole design, i.e we specify all rtl files down to the stdcells. For large designs, we may not want to run CDC/RDC at top SOC level for all of RTL. It's more convenient to run CDC/RDC at lower block level, get it clean, and then generate an abstract model of these blocks in a sgdc file, and then use that abstarct model in higher levels, and finally at the top chip level, so that only logic connecting these blocks will need to be verified for CDC/RDC (internal guts of blocks have already been verified).The same approach is also used for blackbox or IP within a block, so that we only provide an abstract model for these IP (instead of providing full blown RTL models), and use those to run CDC/RDC analysis. This abstract view is a set of SpyGlass design constraints describing the behavior of block ports. This is helpful, since now the full CDC/RDC behaviour of these blackbox is captured via I/O port properties only, and analysis can be done faster.

We don't have to specify any separate cmd for generating abstract sgdc files for any IP. We run SG normally on this IP or lower level block, providing sgdc constraints, waivers, etc. Presence of one of the rules in any of the checks generates abstract constraints. This rule is "Ac_abstract01". This rule is "ON" by default for lint,cdc goals or can be enabled in the gui. This generates sgdc constraints file for block abstraction ($projectdir/<block-name>/cdc_abstract/cdc_abstract/spyglass_reports/abstract_view/cdc/<block_name>.cdc_abstract.sgdc), when SG is finished running CDC/RDC for this block. This abstract sgdc file contains all the info that is needed by SG to perform CDC/RDC analysis. We have to help SG in generating this file, by providing appr constraints on i/p ports which we expect in order for CDC/RDC analysis on these i/p ports to happen correctly. Now, when importing this sgdc file at higher levels, additional rules "Ac_abstrat_validation01, 02" validate the generated sgdc file constraints for correctness at higher levels (i.e checks that whatever is specified at abstract level is valid at higher level of hier). However validation is performed on i/p ports only (and not on o/p ports), when block is instantiated at SoC level. Constraints checked for are constraints specified using clock, reset, abstract_port, quasi_static, set_case_anaysis, num_flops, etc or whatever is specified in sgdc file for this block.

Generated abstract file has these sgdc cmds (NOTE: asbtract_port cmds for both i/p and o/p ports are lot more complex here, as they try to capture all internal functionality of that block):

abstract_port: sgdc cmd "abstract_port" is used on all I/O ports to capture behaviour of the ports. Other sgdc cmds as clock, current_design, set_case_analysis, etc also used to generate the full IP level sgdc file:

#abstract_port => This cmd used for all I/O ports. SG also validates constraints put using this cmd. If it finds inconsistency b/w what it sees on this cmd, vs what it sees in design, it will report an error. options:

-ports <port_name> => name of i/o port. Multiple port names may be specified in single cmd, by separating port names via space

-clock <clk_name> => specifies clock for that port. For both i/p and o/p port, it specifies driving clk (i.e clk of origin flop which drives the i/p or o/p port).

-reset <rst_name> => specifes reset name assigned to port (if port is used as reset pin for block).

-combo <yes|no|unknown> => speciifes if there is combo logic present on i/p or o/p port. default is unknown, which means that reset validation checks should not be performed

-sync <active|inactive> -from <src_clk> -to <dest_clk> -sync_names <net_pin_name_of_sync> => this specs synchronizer properties on ports. active/inactive specs if port is driven by ctl sync or data sync (active=> port is driven by ctl sync that can act as sync en for other data crossings. inactive=> port is driven by data sync that cannot act as sync en for other data crossings). ctl sync means 1 signal passing thru simple synchronizer made up of 2 or more sync flops, while data sync means there is no sync flop b/w 2 clk domains, but instead is a mux whose mux select signal is synchronized, and this ctl sync signal synchronizes the data signals. -from/-to are used only for o/p ports to specify clk reaching to src/dest of synchronizer. -sync_names are used only for o/p ports to specify net/pin names of synchronizer i/p pin (for ctl sync, it's net which is crossing from 1 domain to other domain, while for data sync, it's the select signal of mux before being synchronized)

-related_ports <related_ports> => This is used for ports which do not have synchronizer. Such ports have seq paths to other i/p or o/p ports (just a flop in b/w i/p and o/p ports). Usually valid for o/p ports where related ports are i/p ports

-path_logic <combo|buf|inv> => specs logic from i/p port to inst_pin, or from inst_pin to o/p port, or from i/p port to o/p port

-scope speciifes for what SG product we want to apply this stmt (one of dft, cdc, constraint or base, which are the 4 products offered by SG). 

NOTE: many more options available for this cmd, to enable SG to be able to perform analysis w/o knowing guts of design.

ex: abstract_port -ports {port_in[3]} -scope cdc -combo no -clock VIRTUAL_CLK_1 => This specs that i/p port port_in[3] of this IP is driven by virtual clk named "VIRTUAL_CLK_1". Since virtual clk are usually in their own clk domain, they are async to all other clks. "-combo no" says that there should be no combo logic on this i/p pin path. If at higher level, a combo logic is found, then CDC is denote it as an error. NOTE: i/p port constraints are simple, just specifying the driving clk.

ex: abstract_port -ports out[0] -scope cdc -clock "clk1" -from "VIRTUAL_CLK_1" -to "clk1" -sync active -sync_names "block1.int[0]" => this specs that o/p port out[0] is driven by clk "clk1", and has a synchronizer before this flop which is synchronizing from "virtual_clk" to clk1. The name "VIRTUAL_CLK_1" (defined using "clock -tag VIRTUAL_CLK_1" somewhere else) implies that this clk is vitual and hence async to all other clks. The synchronizer i/p pin is block1.int[0], and it's a ctl sync. NOTE: o/p port constraints are complex, specifying sync etc, but are generated by tool, so not an issue for us.

ex: abstract_port -ports out[2:0] -scope cdc -clock "clk1" -combo yes -related_ports in1[3:0] in2_wrt in3[4] => This specs that o/p ports are driven by "clk1", have combo logic after being driven out of flop, have no sync before the flop, but instead have regular flops and assciated logic b/w them, which finally lead to these i/p ports (in1[3:0] etc). This applies to all o/p ports out[2], out[1] and out[0]. This kind of spec for o/p port is very common in regular designs (as they usually have series of flops from i/p ports to o/p ports all on same clk domain)

Once an abstract sgdc file is generated for the block automatically by SG, we can import that abstract file using this cmd when running SG at higher level:

sgdc -import mod_2flop_synchronizer /.../spyglass_reports/abstract_view/mod_2flop_synchronizer_cdc_abstract.sgdc => here we import auto generated sgdc file for synchronizer IP in block level run. We generate similar sgdc file for block level, which we then import at SoC level. When writing sgdc constraints file for block level, we write constraints for i/p ports using "abstract_port" cmd, and do not write constraints for o/p port. We do this to tell the tool, from which clk domain we expect i/p ports to be driven by. The tool generates block level abstract file, and includes our hand written i/p port constraints, but uses the logic inside the block to derive o/p port constraints. That finaly generates a complete sgdc file with constraints for both i/p and o/p ports. i/p port constraints are usually very simple, as we just need to say from which clk domain we expect the i/p ports to be driven by. The tool does rest of the work at chip level to verify that assumption for i/p ports. It does not validate anything at o/p port (probably because o/p ports eventually enter as i/p ports in other blocks)

Ex of ip abstraction sgdc file: These abstract block's sgdc files are generated automatically by SG when we specify any rules as "Ac_abstract01", etc (We still need to run SG on this block and provide sdc file with basic clock, reset, input, etc defn in it).

ex: async_load_8_1_0_1.sgdc => (for a synchronizer with ctl and data signals). (i/p port = clk_1, reset_n, asyncData[7:0]. asyncCtl. o/p port=DataOut[7:0], CtlOut)

abstract_file -version 5.1.0 -scope cdc
current_design "async_load" -param { DATA_WIDTH=8 RESET_VAL=1 } => specifies parameters of rtl file for which this sgdc file is valid for this synchronizer. These parameter values are used in the name of sgdc file above (i.e _8_1_0_1*) to uniquely specify sgdc files for different parameters, since they may have diff constraints applicable to them.

clock -tag "VIRTUAL_CLK_1" -domain "domain_1"

clock -name clk_1 -domain d0 => NOTE: clk_1 is a port name, and not a tag name
abstract_port -ports reset_n -scope cdc -clock clk_1 => i/p port reset_n driven by clk_1. Same constraints for other set/reset pins, as all are assumed to be already synchronized before getting to this block
abstract_port -ports asyncData -scope cdc -clock VIRTUAL_CLK_1 => i/p ports asyncData[7:0] driven by async clk "VIRTUAL_CLK_1". Note: explicit [7:0] not needed.

abstract_port -ports asyncCtl -combo no -scope cdc -clock VIRTUAL_CLK_1 => i/p ports asyncCtl driven by same async clk "VIRTUAL_CLK_1". Here"-combo no" specs that there can be no combo logic on this path
abstract_port -ports DataOut[7:0] -scope cdc -clock "clk_1" -from "VIRTUAL_CLK_1" -to "clk_1" -sync inactive -sync_names "async_load.asyncCtl" => data o/p port spec as inactive since no synchronizer on data ports. sync_names assigned to i/p Ctl port.
abstract_port -ports Ctlout           -scope cdc -clock "clk_1" -from "VIRTUAL_CLK_1" -to "clk_1" -sync active    -sync_names "async_load.asyncCtl" => Ctl o/p port same as Data o/p port except that it's spec as active, since there is active synchronizer on Ctl port. sync_names is same as above
abstract_block_violation -name SGDCWRN_1 -sev WARNING -count 26 -is_builtin => This is generated by SG for it's internal use. It specs that during abstract block generation for this block, 26 violations of name "SGDCWRN_1" which is inbuilt warnining are generated, whose severity is "Warning".


CDC/RDC violations:

Important violations that should be fixed in design: FIXME = add violations

1.

 ocv => on chip variation:

Regular PT is run across various PVT corners (Process=fast/slow/typ, Voltage =max/min/typ, Temperature=max/min/typ), but that assumes all PVT parameters are same on each die (i.e there is no within die variation). There is large wafer to wafer process variation as different wafers may get slightly different treatment, causing variations from 1 wafer to other.  Some wafers may come out hot (fast), while some wafers may come out cold (slow). Within a single wafer, some dies in the center may see a slightly different process corner than some dies on the edges of wafer. These variations may make transistors faster (due to fast process) or slower (due to slow process). But we know that all these die to die variations are bounded by the slow/fast process corner. All dies are also bounded by voltage and temperature corner, as we don't allow ambient voltage and temperature to be out of these limits when running silicon. So, no matter what the PVT corner is, we are always guaranteed to meet timing.

This assumes that all transistors on a single die are on a single PVT corner. So, when running timing, we treat all gates as either at fast PVT corner or slow PVT corner within a single die, but do not allow for some gates to be fast while some gates to be slow at the same time. However in reality,  within a die, variations may happen (known as OCV), which may cause different delays for different gates on same chip. These differences are not as extreme as die to die variation, but still are large enough at low nm tech to cause paths to fail timing. To allow us to do accurate timing in such scenario, PT allows us to set op cond to ocv mode via "set_operating_conditions" cmd.

set_operating_conditions: 

This cmd is supported in both Synthesis and STA tools by synopsys. It's not an SDC cmd, and as such other tools are not required to support it. Cadence tools don't support it. Also, this cmd options are slightly different between Synthesis and STA tools from Synopsys.

PT can perform 3 types of analysis:
1. single mode(SM) - default: PT uses a single set of delay parameters for the whole circuit, based on one set of process, temperature, and voltage conditions. For launch clk and data path, and capture clk, it uses delays from that one set of PVT.
2. best-case/worst-case mode(BCWC): PrimeTime simultaneously checks the circuit for the two extreme operating conditions, minimum and maximum. For setup checks, it uses maximum delays for all paths. For hold checks, it uses minimum delays for all paths. This mode lets you check both extremes in a single analysis run, thereby reducing overall runtime for a full analysis. Not very useful, as we run both setup/hold across BC and WC PVT in 2 separate single mode runs, so that's more complete than this BCWC run. This doesn't seem to be supported anymore.
3. on chip variation mode(OCV): PrimeTime performs a conservative analysis that allows both minimum and maximum delays to apply to different paths at the same time. For a setup check, it uses maximum delays for the data path and minimum delays for the clock path. For a hold check, it uses minimum delays for the data path and maximum delays for the clock path.

For a single timing path, there are 3 separate delays that are considered = Launch_clk_delay, data_path_delay and capture_clk_delay. To account for the worst case possibility, we assign different delays for setup and hold checks. For setup check, we assign max delay to Launch_clk_path and data_path, while min delay to capture_clk path. For hold checks, we assign min delay to Launch_clk_path and data_path, while max delay to capture_clk path. So, let's see what does PT do for the 3 diff kindof analysis. We write delays in form of max/min. max implies delays for Setup checks, while min specifies delays for hold checks:

  1. SM: Here there's only 1 lib, so both setup and hold path delays are same for a given path. (max,min delay are still taken from one same lib, but min or max below implies whether shortest or longest path considered)
    • Launch clk delay => max/min delay (same)
    • Data path delay => max/min delay (same)
    • Capture clk delay => min/max delay (same)
  2. BCWC: Here there are 2 libs = WC lib and BC lib. WC lib is chosen for all setup path delays, while BC lib is chosen for all hold path delays (WC/BC below implies which lib file is chosen. WC lib chosen for setup, BC for hold)
    • Launch clk delay => max/min delay (WC/BC)
    • Data path delay => max/min delay (WC/BC)
    • Capture clk delay => min/max delay (WC/BC)
  3. OCV: Here there are 2 libs = WC lib and BC lib. For setup path delays, WC lib is chosen for launch clk + data path, while BC lib is chosen for capture clk. In contrast, for hold path delays, BC lib is chosen for launch clk + data path, while WC lib is chosen for capture clk. (setup or hold: WC lib for max delay, BC lib for min delay)
    • Launch clk delay => max/min delay (WC/BC)
    • Data path delay => max/min delay (WC/BC)
    • Capture clk delay => min/max delay (BC/WC)

Clock reconvergence pessimism (CRP)

OCV suffers from clock reconvergence pessimism problem. We can remove this pessimism from slack calc and min time pulse width check. Clock reconvergence pessimism (CRP) is a difference in delay along the common part of the launching and capturing clock paths, under OCV analysis. The most common causes of CRP are reconvergent paths in the clock network, and different min and max delay of cells in the clock network. The shared segment is assumed to have a minimum delay for one path and a maximum delay for the other path. This condition can occur any time that launch and capture clock paths use different delays, most commonly with OCV analysis (see Table 11-4 on page 11-26 of PT documentation). Automated correction of this inaccuracy is called clock reconvergence pessimism removal (CRPR). We need to set above attribute to true (which is set to true by default, so no need to do anything):
set timing_remove_clock_reconvergence_pessimism true

syntax:

set_operating_conditions: options:

-analysis_type => single or bc_wc or on_chip_variation. bc_wc and ocv are collectively referred to as min-max mode as they use min and max conditions in same run. (For PT: we don't have bc_wc option here, just the 1st and 3rd options supported. For DC/Genus, all 3 options supported, but documentation doesn't list "single" as an option, as it's default one if this option is not used)

-library <lib_name>: this speciifes library containing above operating_conditions(W_150_1.65) in it. .lib file may have multiple libraries, but in our case, we just have one library specified at the top of the .lib file [library (STD_W_150_1.65_CELL.db) {]. link_library in .synopsys_dc.setup specifies which .db(.lib) file (/db/.../synopsys/bin/STD_W_150_1.65_CELLS.db) to look for in finding this library. If no lib specofed, then link lib used.

-min/-max <op_cond> => specifies min/max op cond for ocv/bcwc mode. For sm mode, we just specify single op cond directly (withot any option). If op cond not specified at all by using this cmd, then tool uses the default operating condition of the library to which the cell is linked (using link_path). If only max specified then max is used for min also.

-min_library/-max_library <lib_name> => specifies lib that contains min/max op conditions specified above via -min/-max (used in ocv/bcwc mode only). If SM, we use "-library <lib_name>" option to speciify single library containing above operating_condition. link_library specifies which .db(.lib) file (/db/.../synopsys/bin/STD_W_150_1.65_CELLS.db) to look for in finding this library.

-min_phys/-max_phys <resource_name> => specifies resource that contains min/max RC values. This option is only supported in Synthesis tool for Physical runs.

-object_list <object> => This is optional. By default, op cond applies on whole design, but we can also specify diff op cond on diff objects by setting op cond differently for diff objects. This option is for legacy purpose, and not used at all. To specify diff op cond for diff cells, use "set_voltage" cmd.

NOTE: op_cond speciified in.lib files as below. Look in "liberty" section of "vlsi digital standard".

operating_conditions("BCCOM") { process : 0.6 ; temperature : 20 ; voltage : 5.25 ; tree_type : "best_case_tree" ; } => op cond is BCCOM (best case cond).

operating_conditions("WCCOM") { process : 1.3 ; temperature : 150 ; voltage : 1.65; tree_type "worst_case_tree" } => op cond is WCCOM (worst case cond). 

  • ex: set_operating_conditions -min BCCOM -max WCCOM  -analysis_type on_chip_variation =>switches design to ocv mode.Hhere min/max op cond specified. BCCOM used for min delay calc while WCCOM used for max delay calc. No lib specified, so default lib used to check for these op cond. If these op cond not found in default lib, then error is issued. Usually 2 diff lib contain these 2 op cond, so -min_lib and -max_lib also specified.
  • ex: set_operating_conditions -analysis_type on_chip_variation => switches design to ocv mode. default lib used. since min/max conditions not specified, design is using single op cond specified in default lib (so it's essentially running in SM, and NOT OCV)

 

report_design: report_design is used to report op cond defined for current design. This cmd is always run when running STA/Synthesis to make sure all the op cond were picked up correctly.

pt_shell> report_design

Design Attribute                         Value
---------------------------------------------------------------------------
Operating Conditions:
  analysis_type                          on_chip_variation


  operating_condition_min_name           ff_1p1v_-40c_cbest
  process_min                            1
  temperature_min                        -40C
  voltage_min                            1.1
  tree_type_min                          balanced_case

  operating_condition_max_name           ss_0p9v_125c_cworst
  process_max                            3
  temperature_max                        125
  voltage_max                            0.78
  tree_type_max                          balanced_case

Wire Load:                               (use report_wire_load for more information)
  wire_load_mode                         top
  wire_load_model_max                    zwlm ... => similarly for min ...

Design Rules:
  max_capacitance                        -- ... => and lot other param

 

 

--------------
Primetime:
---------------

PrimeTime: gate level STA tool. dynamic analysis requires input vectors and simulating those, so may not capture all possible paths. PT has most of the same timing cmd as used in DC.
--------------
It takes gate level netlist in: .db, .v, .vhdl format
It takes delay info in std delay format (SDF). Both net and cell delay are in this file. This file is optional.
It takes parasitic data (R and C) in std parasitic exchange format (SPEF). Only net delays can be caculated here by using parasitics from SPEF. when SDF not vailable, SDF is generated from SPEF, and used for net delays. It takes cell delays from .lib.
It takes timing constraints in synopsys design constraint (SDC) format

For prelayout timing analysis, cell delay come from .lib and net delay come from wire load models which estimate delays based on estimated cap and res of nets. PT supports use of timing models to represent chip submodules or std cells. Liberty model (.lib) is widely used model that it supports.

Clk/data paths are most common paths that PT analyzes. These paths start at i/p port or clk pin(of seq cell) and end at o/p port or data pin(of seq cell).
4 types of path analyzed: data path, Async paths (on async set/reset pins of flops as recovery/removal checks), clk path (thru Clk tree), clk gating paths. (clk and data paths are combined for data setup/hold checks).

PT automatically creates path groups for these paths (each of these path groups have 2 path types: setup(max) and hold(min)):
1. clk/data path (path group has the name of the clk associated with capture flop/latch, if there are multiple "create_clock" or "create_generated_clock" cmds, then separate path group created for each created/generated clock). Latch may be normal or SR latch. When considering check b/w set/reset pins (non-seq arc), the path group is assigned to the clk, which drives the end_point set/reset pin.
2. clkgating paths (clk_gating_default for paths that end on combinational element used for clk gating, EN pin wrt clk)
3. async paths (async_default for paths that end on asyn set/clr i/p of FF, checks for recovery/removal checks wrt clk). set/clr pins may be driven by o/p of flops, but they are still async wrt capturing clk.
4. default paths (default) that don't fall into any category.
5. none (unconstrained paths).

We can also have user defined path groups. In DC, these path groups affect design opt.

PT cmds:
-------
0. report_path_groups => shows all path groups above.

0. report_timing -from -to : most powerful cmd to see details of a timing path.
---
-from/to can also be -rise_from, -fall_from, -rise_to, -fall_to. -through can be -rise_through, -fall_through.
-path full | full_clock | full_clock_expanded => default is full. use full_clock_expanded to see full clk path.
-delay min|max => min=hold, max=setup (min_max reports both min and max timing)
-nets -cap(or -capacitance) -tran(or -transition_time)=> to show these values in timing reports
-nworst : number of paths to report per endpoint (default=1). We need to use this option when we do report_timing to a particular end point, and want to see all failing paths thru it.
-max_paths : number of paths to report per path group. (default=1)
-exceptions all => reports timing exception that applies to that path (to see why a certain path is unconstrained etc)
-slack_greater_than/-slack_lesser_than => used to show paths within particular slack range
-group {*gating} => shows paths only for that group. Use [get_path_groups *] to get reports for all path groups. Usually we use it when we have multiple clock groups, and we want to see path associated with particular clock, but we don't know the start or end point.
-crosstalk_delta => reports annotated delta delay and delta transition time which are computed duringcrosstalk SI analysis. Using this option does not initiate crosstalk analysis.
-input_pins => Shows input pins in the path report. By default, the report shows only output pins.
#NOTE: for report_timing, default is to show "max" (i.e setup) paths. So, if we want to see hold paths, we have to specify "-delay min" for hold paths (and "-delay max" for setup paths). Use -delay min_max to show both setup and hold arcs in same report.

ex: report_timing=> see options below

-path_type full
-delay_type max
-input_pins
-nets
-slack_lesser_than 0.000
-max_paths 100
-transition_time
-capacitance
-sort_by slack

#async path behaviour in DC vs PT: 2 kinds of async paths:
1. recovery/removal checks: PT performs this check by default, but DC neither analyzes nor opt these paths.
To analyze and opt these paths in DC, use this: set enable_recovery_removal_arcs true
To disable these paths in PT, use this: set timing_disable_recovery_removal_checks true
2. timing paths thru asynchronous pins (i.e paths flowing thru set/reset pins to Q/QZ o/p pin of the flop and then setting up to clk of next flop as D pin, these are clear/preset arcs in .lib file) : by default neither PT nor DC report these paths.
To report these paths in PT, use this: set timing_enable_preset_clear_arcs true (default is false)
To report these paths in DC, use this: -enable_preset_clear_arcs (in report_timing cmd). Even if we have this option, it only allows us to view these paths during reporting, but DC never opt these paths.

We can specify cell names for start/end_point. Then, all paths from all pins of start cell to all pins of end cell are considered. So PT warns about this, if there are any invalid points for start/end_points.
Ex: report_timing -from sync_reg -to tsd_latch => PT warns that of 5 pins in start_point of sync_reg (DTP10 has PREZ,CLK,D,Q,QZ pins), 4 are invalid start points. CLK of DTP10 is the only valid start point. PT also warns that of 4 pins in end_point of tsd_latch (LAB10 has SZ,RZ,Q,QZ pins), 2 are invalid end points. SZ/RZ of LAB10 are the only valid end points. For PT false paths, start point should always be CLK and endpoint should always be D. DC and VDIO don't warn about this, and just ignore the constraint, if it doesn't conform to this. VDIO/ETS reports may show startpoints as Q or D, but when false pathing, we should always write them as from CLK.

#NOTE for recovery/removal paths, use Q of 1st flop as startpoint and CLRZ/PREZ of next flop as end point. For some reason, using CLK of 1st flop as startpoint doesn't work.

#In latch based paths, borrowing occurs if data arrives in the transparency window. See PT doc (page 36-38). So startpoints may be from D, Q or CLK. CLK and Q startpoints are treated as starting from the clk of latch, while D is treated as starting from the D i/p of latch and going thru the latch to Q o/p pin of latch. Note, this behaviour is different when VDIO/ETS is used to report such paths. In VDIO/ETS path from startpoint D is still the same, but paths from CLK and Q startpoints are treated as worst case slack paths from D, CLK or Q.

to report timing for such paths, and see the latch borrowing, use -trace_latch_borrow (otherwise startpoint delay is shown for D, doesn't show the actual path to D)
Ex: report_timing -from ... -to ... -trace_latch_borrow

Ex: of time borrowing path
Point Incr Path
---------------------------------------------------------------
clock spi_stb_clk (rise edge) 55.00 55.00 => start point
...
data arrival time 56.55 => this is data path delay from 1st flop.
---
clock clk_latch_reg (rise edge) 1.00 1.00 => end point
...
Iregfile/tm_bank0_reg_9/C (LAH1B) 3.66 r => this is total delay to clk of latch
time borrowed from endpoint 52.89 56.55 => since data comes much later than rising edge of clk, we borrow the difference (56.55-3.66=52.89) from this latch, so that next path from latch o/p will consider that D->Q delay is 52.89ns.
data required time 56.55
---------------------------------------------------------------
data required time 56.55
data arrival time -56.55
---------------------------------------------------------------
slack (MET) 0.00

Time Borrowing Information
---------------------------------------------------
clk_latch_reg nominal pulse width 100.00 => this is width of clk pulse = clk_period/2
clock latency difference -0.36 => this is reduction of pulse width due to diffeerence in rising and falling edge
library setup time -0.26 => this is setup time of latch (wrt falling edge of clk) which needs to be subtracted, as max time available is reduced by this
---------------------------------------------------
max time borrow 99.37 => final max time available to borrow
actual time borrow 52.89 => actual time borrowed < max available. so timing met
---------------------------------------------------
-------------------

1. report timing to auto detect False paths:
---
By using the report_timing -false command, you can have PrimeTime automatically detect false paths based on the logic configuration of the design.

2. report timing exceptions:
---
report_timing -exceptions all => reports all timing exceptions that apply to all paths. exception may be because of false_path, multicycle path or min/max delay.

3. set_disable_clock_gating_check: to disable clock gating check on specified cell or pin (when pin is spec, clk gating check is disabled only if pin is clk or En). This is needed when we are outputting clock on a dmux pin, and the tool checks for clk gating on these paths, as it thinks other i/p to the OR/AND gate to be the Enable signal trying to setup or hold to clk signal.
ex: set_disable_clock_gating_check {u_DIA_DIG/u_DMUX_DIG/U293 u_DIA_DIG/u_126/A} => disabled clock gating hold/setup checks. We cannot use set_false_path for such paths, as PT will warn about "valid endpoint not found", as it's really not a data path, but a clock gating check.

4. set_disable_timing => disables timing through the specified cells, pins, ports, or timing arcs. It removes the affected objects from timing analysis, rather than removing the timing constraints from the paths (as in "set_false_path"). So, this cmd is more efficient, and can be used when all paths thru a pin are false (instead of using multiple "set_false_path").
NOTE: This cmd is also helpful when we want disable timing b/w 2 async pins of flop such as CLRZ/PREZ. In this case we can't use "set_false_path -from flop1/CLK -to flop2/PREZ", as then the path of flop2/PREZ setting up to flop2/CLK would be false pathed. We need path of flop2/PREZ setting up to flop2/CLRZ would be false pathed which wouldn't be possible using false_path.
set_disable_timing -from CLRZ -to PREZ {get_cells {u_SPT/Ret_reg} => timing arc from CLRZ to PREZ disabled for Ret_reg flop. This timing arc should exist in .lib file for that Flop. This is equiv to:
set_disable_timing [get_timing_arcs -from {u_SPT/Ret_reg/CLRZ} -to {u_SPT/Ret_reg/PREZ}] => this is equiv to one above.
NOTE: to see all timing arcs for a particular lib cell, do:
report_lib -timing MSL445_W_150_1.75_CORE.db { AN210 } => shows all timing arcs from .lib file for AN210 gate. Timing type/sense are specified in .lib file.

Arc Arc Pins
Lib Cell Attributes # Type/Sense From To When
----------------------------------------------------------------------------
AN210 0 positive_unate A Y => from i/p A to o/p Y
1 positive_unate B Y => from i/p B to o/p Y

5. set_false_path: to set false paths which are point to point timing exception. Declaring a path to be false removes all timing constraints from the path. PT still calculates the path delay, but does not report it to be an error. "report_timing" for such path will show "No constrained paths".
NOTE: false paths -to/-from are more strict than report_timing -to/-from.
---
For false paths, -to = I/P port or CLK, -from = O/P port or D
To remove false paths, do: reset_path ...

when we specify wild characters, false paths are expanded.

ex1: set_false_path -from Ireg/reg_0/* -to Ispi/s_reg_*
A single * expands to everything that matches before it hits a "/". So, "Ireg/reg_0/*" expands to pins of reg_0, while "Ispi/s_reg_*" expands to name of cells such as s_reg_0, s_reg_1 and so on. Since we didn't specify "Ispi/s_reg_*/*", it doesn't expand to name of pins on the cell. By specufying just the name of cell, we are asking PT to look at only valid endpoint of cell, which is Din pin of flop. Since reg_0 is a latch, startpoints are all i/p,o/p pins on latch, while end points are just the Din pins of cells, since they are flops. So, this expands to:
set_false_path -from [list [get_pins Ireg/reg_0/C] [get_pins Ireg/reg_0/D] [get_pins Ireg/reg_0/CLRZ] [get_pins Iregreg_0/Q]] -to [list [get_cells Ispi/s_reg_15] [get_cells Ispi/s_reg_14] ...]

ex: set_false_path -from Ireg/reg_0 -to Ispi/s_reg_* => NOTE: only cell name is specified in from list, so only clk and din pins are considered for this cell (which are the only valid startpoints for a ltach). So, this expands to:
set_false_path -from [list [get_cells Ireg/reg_0]] -to [list [get_cells Ispi/s_reg_15] [get_cells Ispi/s_reg_14] ...]

NOTE: So for a flop, we can just specify name of flop as starting point. That means clk of flop. Or, we could specify cell/clk. It means the same thing. cell/Q is invalid start point, though in this case, it refers to the same path. Similarly for destination flop, we can just specify the name of flop as ending pont. That means data_in of flop as ending point. Or, we could specify cell/data_in. cell/clk is invalid end point.

NOTE for PT: even though above style works for PT, when we do report_timing in PT, it warns about invalid start/end points. This is because, when we specify name of cell as startpoint, it checks for all pins on that cell. For a flop such as DTC20, its 5 pins (clk, din, clrz, Q, QZ) that it looks at all starting point of which only clk is valid, remaining 4 are invalid pins. Similarly for end point, it looks at 3 pins (clk, din, clrz) of which only din is valid, remaining 2 are invalid pins.

NOTE for VDIO/ETS: invalid start/endpoint paths will just be ignored in vdio/ets even though constraints.sdc file has it. We may even see invalid start/end points of such paths in vdio/ets timing report, but if we just cut and paste start/end point of such paths from vdio timing report, they may have cell/Q as startpoint, or cell/clk as end point which are invalid. These paths pasted in constraints.sdc file look fine, but don't get imported into vdio. When we do report_path_exceptions in vdio, we may not see the path in vdio. So, very IMPORTANT to remove Q or clk from such paths before putting them in false_path file.

Note: with a transparent latch, there's valid timing path from c2q and d2q as latch is transparent so path depends on whether data or clk comes first. So, when we just specify the cell name for a latch, it considers both cell/clk and cell/Data_in paths for start point.
A phase latch: rising clk path ( from Previous cell to D of latch, from D of latch to next cell and from C of latch to next cell ). falling clk path (from previous cell to latch)

SR latch: It has valid start point from some path to valid end point as SZ or RZ pin. If endpoint is RZ pin, that implies that SZ path is trying to setup to RZ pin. If endpoint is SZ pin, that implies that RZ path is trying to setup to SZ pin. Both setup/hold checks done. NOTE: for setup, data tries to setup in same cycle of clk (as apposed to normal paths, where setup of data is checked for next cycle of clk). This is because, these arcs are classified as nonseq arc(nonseq_setup/hold) since it's data to data arc, while normal setup/hold arcs are classified as seq arc(setup/hold_rising/falling), since they are data to clk arc.

#false path spanning different clk domain:
set_false_path -from [get_clocks I_CLK32K] -to [get_clocks I_CLK5M] => This false paths all paths starting from flops clocked by 32k clk, and going into D pins of flops clocked by 5Mhz clk.

special case of -through: clock can be specified as -from or -to and startpoint or endpoint can be specified as -through. This can be used in cases having muxed clocks. Ex:
pt_shell> report_timing -from [get_clocks ...] -through $startpoint
pt_shell> report_timing -through $endpoint -to [get_clocks ...]

combinational pins can't be path startpoints or endpoints (use -through for these). However with timing_report_always_use_valid_start_end_points variable set to false(default), PT considers these invalid start/end points to be -through points and continues searching. If set to true, it will just ignore these paths. with the exception of clk gating checks.

4. delay cmds:
---
set_input_delay: An input delay is specifying an arrival time at an input port relative to a clock edge from a register. The maximum input delay value should be equal to the length of the longest path to the register data pin, plus the max c2q time (max path delay) of the register. The minimum input delay value should be equal to the length of the shortest path to the register data pin, plus the min c2q time (min path delay) of the register.

set_output_delay: An output delay represents an external timing path from an output port to a register. The maximum output delay value should be equal to the length of the longest path to the register data pin, plus the setup time of the register. The minimum output delay value should be equal to the length of the shortest
path to the register data pin, minus the hold time (since that tells you how much min delay you should need inside your block to meet 0 hold slack).

5. misc cmds:
----
A. report_net U1/SCAN_ENABLE => This reports FO/FI/cap/res for given net. This is helpful to debug reset tree, scan_enable tree or clock tree to see if it has been buffered or not
B. report_ideal_network => This should be run in PT to make sure no n/w is set to ideal. It reports clk pins on all cells, on which it finds clk is set to ideal
C. set_case_analysis => Specifies that a port or pin is at a constant logic value 1 or 0, or is considered with a rising or falling transition. In case of pins, constant propagation is only executed forward. Also, even if these pins are driven by logic values from design, the values set by case_analysis dominate. When case analysis is specified as a constant value, this value is propagated through the network as long as the constant value is a controlling value for the traversed logic (i.e if 1 i/p of NAND2 is 0, then o/p is propagated as 1) . When some port or pin is set to constant, then the path thru that pin is unconstrained path, as it's a constant value on that pin. So, report_timing won't show any timing thru that path. That's why we never set constant value on i/p ports, so that we can have PT time all those paths from i/p ports. So, we have to be very careful when using set_case_analysis as that port/pin may never get timed, so even if it's violating setup/hold timing, it may never get reported. Use set_case_analysis only on scan_mode pin, and then have some other way to time setup/hold path from scan_mode pin. Do not use set_case_analysis on any other pins.
Note: When a logic value is propagated onto a a net, the associated design rule checking (DRC) constraint checks are disabled. However, the max_capacitance DRC check can be performed on driver pins for constant nets by setting timing_enable_max_capacitance_set_case_analysis variable to true. This variable is set to false by default. So, when we do set_case_analysis on scan_en pin, we may not see max_cap/max_tran violations on it, even though it may not be buffered and have large violations.
ex: set_case_analysis rising {U1/U2/A U1/U3/CI} => pins considered only for rise transition (fall transition on these pins is disabled)

D. remove_design -all => used to remove design from memory so that new PT run can be started w/o exiting PT. However it doesn't remove lib from memory. So do this too:
remove_lib -all => This removes all lib from mem. If we do not do this, then previous libs remain mem, so any new libs get added to prev libs. By default, libs added last are the ones that get used for final runs. Check it using report_design.
---------------

In PT, we can temporarily change design, like insert_buffer, size_cell, etc and see the impact on timing. then to import these changes, run characterize_context cmd whichcreates a script that can be used in DC to specify timing condition for resynthesis.

multiple clocks:
we can specify multiple clocks as sync (generated clocks by dividing, etc), async (no relation) or logically exclusive (like clocks coming thru mux, so only one can be active). Use set_clock_groups to define such groups. With multiple clocks, best way to analyze is to set_case_analysis for multiple scenarios.
when using multiple clocks in design, we can specify the relaionship b/w clocks to be sync (default), async (set_clock_groups -async -group {ck1} -group {ck2} => essentially declares a false path b/w 2 clks) or exclusive (set_clock_groups -logically exclusive -group {ck1} -group {ck2} =>essentially declares a false path from ck1 to ck2 and vice versa).

 

-------------
CHECKS:
------------
1. Min pulse width check for clk: Clk pulse should not be too small at reg clk pin, else data may not get captured. Also, if pulse width is too small, clk pulse may not even get propagated. Min pulse width check is specified in lib cell.

2. Unate check: PT keeps track of clk sense. It recognizes the positive or negative sense of the clock signal arriving at each register clock pin. No specific action is necessary to tell PrimeTime the sense of a clock tree that has only buffers and inverters. In this case, the clock signal arriving at the register clock pin is said to be unate.
+ve unate: A clock signal is positive unate if a rising edge at the clock source can only cause a rising edge at the register clock pin, and a falling edge at the clock source can only cause a falling edge at the register clock pin.
-ve unate: Similarly, a clock signal is negative unate if a rising edge at the clock source can only cause a falling edge at the register clock pin, and a falling edge at the clock source can only cause a rising edge at the register clock pin. In other words, the clock signal is inverted.
non unate: A clock signal is not unate if the clock sense is ambiguous as a result of non-unate timing arcs in the clock path. For example, a clock that passes through an XOR gate is not unate because there are non-unate arcs in the gate. The clock sense could be either positive or negative, depending on the state of the other input to the XOR gate

ERRORS and WARNINGS: applies to both PT and ETS
--------------------------
A. check_timing: Shows possible timing problems for design.
-------------------
1. unexpandable_clocks:
--------------------------
Warns if there are sets of clocks for which periods are not expandable with respect to each other. The checking is only done for the related clock domains, such as ones where there is at least one path from one clock domain to the other. This could be because of an incorrectly defined clock period for one or more of the clocks. Another possibility is when asynchronous clocks with unexpandable periods are interacting where they should have been defined in different clock domains.

Generally, for the multiclocks defined, PrimeTime must ensure that the common base period for a set of related clocks is divisible by every clock in the set. The 'unexpandable_clocks' check warns if there are pairs of clocks where the periods
are not expandable with respect to each other.
In the case where the two clock periods differ, PrimeTime calculates a common base period (LCM) between the two clocks and expands both clocks to this common base period until it finds the common edge between the two clocks. If the clocks can not expand to a common base period, the "PTE-053" warning is issued.

The relationship between the clocks within a set is known as "related". This means, the cross-clock domain timing paths require all the clocks in the set to expand to a common base period, but due to differences in the clock period they can not be expanded.

2. unconstrained_endpoints:
--------------------------------
#Warns about unconstrained timing endpoints. This warning identifies timing endpoints (output ports and register data pins) that are not constrained for maximum delay (setup) checks. If the endpoint is a register data pin, it can be constrained by using create_clock for the appropriate clock source. You can constrain output ports using the set_output_delay or set_max_delay commands.
endpoint is unconstrained because of no_capture_clock (create_clock needed on the capture flop clk pin to fix this), dangling_end_point (set_output_delay needed on the o/p pin to fix this), or fanin_of_disabled (paths ending at fanin of disabled timing arc. to fix this, undo disable timing arc)
#startpoint is unconstrained because of no_launch_clock, dangling_start_point or fanout_of_disabled (paths starting from fanout of disabled timing arc)
#In both PT and ETS reports, whenever there is "no clk found" associated with any capture flop, all i/p (D, CLRZ, PREZ) are reported as unconstrained.

3. UITE-216: Object not valid (Important)
-------------------------------
-from , -to in set_false_path, set_multicycle_path, etc is not valid. (see page 200/494)

-from should have objects to be valid timing startpoints (i/p port, bidir port, seq cell, seq cell clk pins, data pin of level sensitive latch, clk or pin that has i/p delay specified). If a clock is specified as the -from object, all primary inputs clocked by that clock and registers clocked by that clock are used as startpoints. If cell is specified, cmd applies to one path startpoint on that cell (for seq cell, it's clk pin, while for latch it's clk as well as data pin).

-to should be valid timing endpoints (o/p ports, bidir ports, seq cell. seq cell data i/p pins, clk or pins that has o/p delay specified). If a clock is specified as the -to object, all primary outputs clocked by that clock and registers clocked by that clock (reg data pins are used as endpoints for each of these registers) are used as endpoints. If cell is specified, cmd applies to one path endpoint on that cell.

4. no_driving_cell: when i/p ports don't have drivers.

5. ideal_clocks: reports not propagated clocks. disabled by default. To enable, do check_timing -include { ideal_clocks }

6. PTE-060. Warning: No clock-gating check is inferred for clock at pins of cell. See solvnet article for details: https://solvnet.synopsys.com/retrieve/015769.html
This is a clock gating check warning, where PT is unable to infer clk gating check for complex gate (as MUX etc). By default, PT infers clk gating checks for simple gates as AND/OR/NAND/NOR only. We need to have PT check for clk gating on these complex gates: 2 options:
A. By doing "set_case_analysis" on one of the i/p of complex gate, we may be able to reduce it to simpler gate, which will allow clk gating check to be inferred.
B. help PT find correct gating relation by issuing clk gating cmds. Consider a mux with gating signal on S pin and clk on A pin,
- set_clock_gating_check -high UMUX/A => says that clk pin on UMUX/A is active high clk, so clk gating signal can only change while clk is low
- set_disable_clock_gating_check UMUX/B => says that other i/p pin of mux is not to be checked for clk gating. This may be needed if we are interested in clk gating check wrt S pin of mux only. Otherwise PT treats both pin B and S as gating pins, and reports worst case gating.

NOTE: Use report_clock_gating_check to see all clk gating checks. For multiple clk signal, use "set_multicycle_path" to get correct clk gating checks for setup/hold. All delay arcs thru clk gating cells are still honored during timing analysis. If we want to disable gating signal to get propagated (since clk gating check ensures that gating signal is clean, so won't cotribute to delay thru gating cell), we may set "timing_clock_gating_propagate_enable false".

7. PTE-052: expanding clocks to common base period. PrimeTime limits the waveform expansion of the smallest period to be no more than 1000 times and the waveform expansion of the largest period to be no more than 101 times. If the largest period is too large, then PT takes largest period as the common base period but still has not expanded the smallest period beyond its limit.In certain situations, this can cause paths between these clocks to be unconstrained.

---------------------------

------------------------------------------
VDIO/ETS vs PT: most of commands same b/w ETS and PT, but slight variations.
-------------------------------------

Commands used in ETS can be used within VDIO.

path groups: In PT, path groups are divided based on clks, but for same clk, all paths are in same path group. However, in ETS, for the same clk, paths are subdivided into 4 groups: in2reg, reg2reg, reg2out, in2out.

In VDIO: report_path_exceptions can be used to see list of all false paths used by VDIO.

report_timing: almost same syntax as in DC.
#-format used to format report. default is -format {instance arc cell delay arrival required}. -format {instance cell arc load slew delay arrival required} typically used. use incr_delay to show inc delay due to noise.
#-max_paths in PT reports paths with -ve slack, whilein ETS, it reports +ve slack paths too. So, use -slack_lesser_than option in PT. Also, max_paths in VDIO reports specified number of worst paths in the design, regardless of the endpoint. Use -max_points instead of max_paths to get worst path for each endpoint only once.
#-nworst Specifies the number of paths to be enumerated for each endpoint. This behaviour is same across PT and VDIO/ETS. By default, only the worst path to each endpoint is reported. However, in VDIO, this option can't be used with -max_paths, as that shows all worst paths, even if ending at the same end point.
#full_clock in ETS reports with clk delay expanded while in PT, it shows clk starting point and adds clk delay upto that point in "clock source latency". so, use full_clock_expanded in PT, so that it expands this clk src latency, and compares to ETS rpts.
PT: report_timing -delay max -path full_clock_expanded -slack_lesser_than 20 -max_paths 500
ETS/VDIO: report_timing -early -path_type full_clock -view func_max -max_points 500 -format {instance cell arc load slew delay arrival required}

---------------

For normal latches, report_timing behaves differently than in DC/PT. see primetime section above for details:
Ex: startpoints may be from D, Q or CLK. For DC/PT, CLK and Q startpoints are treated as starting from the clk of latch, while D is treated as starting from the D i/p of latch and going thru the latch to Q o/p pin of latch. However, in VDIO/ETS path from startpoint D is still the same, but paths from CLK and Q startpoints are treated as worst case slack paths from D, CLK or Q.

------------

 

Linux/Unix cmds: All shell support majority of simple cmds used in scripting. Many of these simple cmds came from unix world, and as such we will refer to them as unix cmds (as ls, cd, mkdir, etc).

The syntax for these unix cmds is something like this:

Syntax: cmd <options prefixed by "-"> <other args for filtering>

  • Options: These unix cmds allow options to be used in the args, which may be specified prefixed by a "-" (i.e ls -a => here "a" is an option that specifies how listing should be done). The purpose of these options is to customize on how these cmds behave.We may combine multiple option in one by using just one "-", i.e ls -a -l -S may be written as ls -alS => here we combined 3 separate options into one. The options may be put in any order, so ls -lSa is same as ls -alS or ls -al -S, etc.
  • Other args: These unix cmds also allow other args such as name of file, etc that might be needed for that particular cmd. Not all cmds need these other args. Wildcards (as *, ?, etc) may also be used (in lieu of full name, etc), which we'll discuss under "regular expression" section. These wildcards are not part of cmd syntax, but rather part of shell. The shell expands these wild cards based on it's rules, and then passes the final expanded form to the unix cmd, which is then executed. However, some options in cmd line may dictate how these wildcards should be treated. POSIX std defines the behaviour of cmds, and all shells try to conform to POSIX std, so these unix cmds behave consistently across most of the shells. Also, quoting mechanism (single quote, double quote, backslash, etc) may hide special characters from being interpreted by shell, so that they are passed untouched to the unix cmd. Read man page of a unix cmd on your system (details below). So, sntax for unit cmds is:

 

There are more than 200 unix cmds supported by major shells. We'll just discuss a few in unix cmds section later (rest available in "advanced bash manual - part 4", see bash section, note some of unix cmds may be bash speciic or csh specific).

very good website: http://www.grymoire.com

Versions: Unix cmds may be implemented differently on different Linux systems. To make it consistent, POSIX defines a standard syntax for unix cmds. All GNU implementation of these Unix cmds follow this standard, by supporting a minimum set of options that those unix cmds will support. Since most Linux systems originate from same Linux kerenl and incorporate lot of basic stuff from gnu.org, they adhere to GNU POSIX standard. However, some vendors start supporting extra options on some of these unix cmds, which are not POSIX standard. These keep on getting added with time, and sometimes they become POSIX standard later on, and newer versions of these cmds start incorporating them. It's impossible to know what variant of unix cmd is supported on your particular system, but knowing the flavor of that Unix cmd can help you a lot to debug why some linux cmd works fine on some machine but not on other.

For any unix cmd, run -V for that cmd on cmdline. If -V is not supported, run "rpm -q <cmd>" on RHEL type OS. Both cmds should work on any Linux distro. That will show version number and other details. It's recommended to always use GNU cmd (downloaded from gnu.org), as that is what is supported on most Linux systems, and most of the documentation on the web refers to GNU implementation of these cmds (even though they may not state it explicitly). Some linux distro may implement their own version of some of these unix cmds, which may be slightly differently, so always check.

Ex: -V: running "grep -V" shows that grep is GNU grep and is version 2.20.

/home/aseth $ grep -V
GNU grep 2.20

Ex: rpm: running "rpm -q grep" shows that grep is version 2.20-3.

/home/aseth $  rpm -q grep
grep-2.20-3.el7.x86_64

If I want to update grep to later version, I can do that by going to gnu.org and downloading the latest grep. I could even download some other flavor of grep instead of GNU grep (i.e Solaris grep) by going to that vendor's website, but as I said, stick to GNU. Do not worry too much even if you are on a older version of a cmd, as most basic features are supported even on very old versions, and suffice for 99.9% of users.

MAN: man stands for manual, and is used to find all the details of any cmd. For ex, to see what "ls" cmd does, and all it's options supported, we can type this on terminal:

  • man ls =>  shows description and all options for "ls" cmd. man can be used for any other utility also such as diff, etc (not just unix cmds)

A kernel doesn't have any user interface. Kernel can only interact with other pgms. Any shell (bash, csh, etc) is a pgm that reads a line of input from you, and then interprets it as one or more commands to manipulate files or run other programs. These cmds may be of 2 types: built in or external. We'll look at both types of cmds:

CMDS: There are tons of Linux/Unix cmds with lots of options, that probably no one can learn. However, I'm listing some common ones that will allow you to get your job done. Of these cmds, grep and find are 2 most powerful cmds used widely, that you should look into. Below is a link to cheatsheet of most used linux cmds.

https://phoenixnap.com/kb/linux-commands-cheat-sheet

I'm also listing imp linux cmds separately in the list below:

1. dir/file cmds:

cd: cd <dir> => change dir to specified dir

  • cd  - => changes to previous working dir
  • ~ corresponds to internal variable $HOME (i.e home dir as /home/ashish). cd ~ is same as cd $HOME. Also ~ followed by user name means home dir of that user. i.e ~rohan means /home/rohan.
  • ~+ corresponds to internal variable $PWD or current working dir. Similarly ~- corresponds to internal variable $OLDPWD or previous working dir. 

mkdir/rmdir: mkdir <dir> => makes new dir. rmdir <dir> => removes the named dir.

  • If -p used then it creates dir if it doesn't already exist (-p is usually used for creating nested dir). ex: mkdir -p dir1/dir2/dir3 =>creates nested dirs dir1/dir2/dir3 instead of creating them one by one (so all 3 dirs creted by just 1 cmd).
  • -m is used to assign dir permissions. ex: mkdir -m 755 dir1 => applies "chmod 755" to dir1 (instead of running a separate chmod cmd on dir1)

pushd: pushd <dir>: (pushd means push dir) => saves current dir on top of dir stack and then cd into dir. This is convenient way to remember previous dir, and then goto that dir using popd.

popd: popd (popd means pop dir) => This pops dir from top of dir stack, and then cd into that dir. pushd and popd

dirs: This prints the dir stack that was formed by doing push cmds

cp: copies files/dirs. syntax: cp [options] src dest.

More details: https://www.tutorialspoint.com/unix_commands/cp.htm

  • copy files: cp src.txt dest.txt => cp file named as src.txt as dest.txt. Even links are followed and the actual files are copied. If you want to just copy the link (i.e preserve the soft link as it is), use -P.
  • copy dir: cp -r src_dir mydir/dest_dir => Here all files from src dir are copied to dest dir, as -r (or -R) means copy recursively. There's no diff b/w -r and -R. Behaviour of cp cmd varies based on whether dest dir exists or not. If the dest_dir doesn’t exist, cp creates it and copies content of src_dir recursively as it is. But if dest_dir exists, then copy of src_dir becomes sub-directory under dest_dir. When -r option is used, all soft links are preserved when copying recursively, i.e links are copied rather than the contents pointed to by the link. This is different behaviour than regular cp cmd without -r option, that copies the contents and not the links. To get same behaviour as regular cp cmd, we have to use -L which dereferences symbolic links. So, use cmd: cp -rL to copy files pointed by the links, when copying recursively.
  • Copy updated files only: cp -u [source] [destination] or cp --update [source] [destination] which will only copy files if the source files are newer than the destination files, or if the destination files do not exist.
  • preserve all attr: This is called "archive" and can be enabled with option "-a". It preserves link, mode, ownership, timestamps and all other attributes.
  • copy hidden files only: If you are wanting to copy hidden files and folders in Linux using the cp command, the first thing people will think of is cp -r .* /dir/ but this will actually match ./ and ../ as well, which will copy all files in the current working directory, and also copy all the files from the parent directory. So to copy only hidden files in Linux, you would want to run cp -r .[a-z,A-Z,0-9]* /dir/ this way it will only match files that start with a . and the next character is a-z, A-Z, or 0-9 and everything after that being a wildcard.

rm: removes files and dirs. To remove dir recursively, use rm -r *. However, sometimes dir can't get removed, because of permission not set correctly in all levels of hier. So, do chmod 777 -R top_dir_name. This sets rwx permissions to 777 in all subdir recursively. Then use rm cmd. An empty dir won't get deleted by rm <dir_name>. Either we need to use rm *dir_name* where we risk deleting other dirs too, or we can just use rmdir <dir_name>.

ls: list all files and dirs in specified dir. If nothing specified, then list for current dir.

  • ls dir1/dir2 => lists all files and dir in dir1/dir2. WE can also put \ at end, it makes no diff. i.e ls dir1/dir2/
  • ls dir1/dir2/* => ls by itself lists all files and dir in given dir, but no contents of subdir within that dir. By using *, we make ls list contents of that subdir too.
  • ls dir1/*my* will list all files and dir which have letters "my" in them. But if there's a dir which has my in it's name, then it will list it's contents too. We may not want that. In such case, we may use option "-d" to list dir only (since contents of most dir are files, so all those will be omitted making it easier to see). ls -d dir1/*my* => lists dir only which have "my" in their name. Other way to list such dir is by using find cmd with mindepth and maxdepth option. Check on "find" cmd details later.
  • ls -l -a => This gives long listing of files (i.e with all details as time, permissions, etc). -a causes all files/dir to be shown (including hidden files/dirs whose names start with ".")
  • ls -S -r => S option causes files to be listed by size (with largest file at top by default). -r option causes files to be listed in reverse, so largest file is at bottom (this is more commonly used). -h causes sizes to be displayed in human readable format (i.e MB, GB, etc).
  • ls -lrt => very commonly used cmd. long lists all files sorted by their timestamp (with latest file at bottom due to -r being used)

readlink: display full file path
ex: readlink -f file1.txt => displays full path of that file (so it's easy to cp and paste)

realpath: expands all symbolic links and resolves references to produce absolute path name:

ex: realpath /home/ash/project/../arm => displays real absolute path = /home/ash/arm


tree: tree -f => displays all dir/files etc in that dir as a tree structure. Easy to see.

less/more: These cmds allow us to read a file from within terminal itself, w/o opening any other pgm as emacs, vi, etc. less is most widely used, as it can do everything that more does. less is one the most used cmds for reading a file (NOT writing as that requires other text editors as vi), so get used to it. The options in less are similar to those in vi test editor cmd (many key bindings are same), so it's comfortable to use if you have used vi editor in the past. 

less file1.txt => shows contents of file.txt within the terminal few lines at a time. Use arrow keys to scroll up/down.

There are many options in less that can customize the file appearance.

less -N -M file1 => -N displays line numbers for each line in file. -M displays filename while the file is open.

Apart from cmd line options above, there are many interactive keystrokes/cmds that we can apply while the file is open. Many of the cmd line options above, work in interactive mode also, so you can apply them anywhere.

-N => When you type "-N", and then hit enter, it will show line numbers for each line in file. Pressing -N again gets rid of the line numbers. If file is very large, it may take a while, before it displays line numbers, so don't assume that the pgm is hung

g / G(-shift+g) =>hitting small "g" takes you to beginning of file while capital G takes you to end of file. If you prefix g with a number then it takes you to that line, i.e 234g takes you to line 234.

^G => hitting ctrl + G key displays the file name. Same as -M option.

 

2. exit => to exit from script. exit with optional number as arg, returns that exit code. So "exit 5" exits withs return code of 5 (failure)

3. input/output cmd: To print on screen or get input from keyboard, bash has multiple cmds. For outputting on screen, 2 cmds: echo and printf. To get input from user, builtin cmd "read". read is specific to bash, but echo and printf are POSIX unix cmds, and supported by most shells. However, behaviour of echo is inconsistent from shell to shell, so printf is prefrred.

echo: echo prints whatever is provided in it's args, terminated by newline (to suppress automatic newline at end, use option -n). However, \n, \t etc within args are printed as is. In order to recognize \n or "newline", use option -e (i.e echo -e "my \t name"). -e recognizes all backslash escaped char. ANSI C quoting may also be used to recognize these special char. ANSI C quoting puts these escape char in form $'\n', so that they are expanded by bash, as newline, tab, etc.

ex: echo me $'\t' name $'\n' => This prints tab and newline correctly. NOTE: everything until the end of line or ; (whichever comes first) is considered part of echo cmd (unless ; is hidden from shell by putting it inside single or double quotes)

printf: similar to C style printf cmd. It can print string to STDOUT by default, or using option "-v <var_name>" causes the o/p of printf to be assigned to var name "var_name"

read: It has lot of options to read from keyboard (read year => reads and stores value in var "year") or from file (read -u FD => to read from file descriptor FD)

ex: echo -n "Enter your gender"; read -n 1 gender; if [ $gender == "M" ] ...; => -n num option says read only "num" characters and return, instead of waiting for newline char

4. alias: allows a string to be an alias or substitute name for a simple cmd. unalias is used to remove an alias.

ex: alias ml="ls -al"

To see what alias is being used for any cmd, use "type" cmd. See in section below.

NOTE: alias are not expanded when shell is not interactive, so scripts using aliases may break. Using shell function is always preferred over using alias.

5. history: displays the history of all cmds run in that shell (with line numbers). A lot of options supported. History expansion is provided similar to csh. This helps to run a cmd quickly, without doing copy/paste or using up/down arrow keys.

NOTE: there are settings in .bashrc (for bash shell) that controls number of history cmds to show (HISTSIZE=100) and max no. of entries to hold in .bash_history file (HISTFILESIZE 2000). Many more settings possible.

!n => run cmd line n from history. ex: !123 => run cmd number 123 from history of cmds

!-n => run cmd n lines back. So, !-2 means run 2nd last cmd in history.

!! => runs last cmd. We can also apend to this cmd, i.e !! | grep "a" => this runs last cmd and searches "a" from o/p of that cmd. other ex: !!2 => appends 2 to last cmd run. So, if last cmd was "ls prog", then this becomes "ls prog2"

!string => run most recent cmd in history that starts with string <string> ex: !ma => runs last cmd that started with letters ma.

!?string? => run most recent cmd in history that has string <string>in it. ex: !?prog1? => runs last cmd that matches pattern "prog1". i.e if 2 cmds were run "make prog1" and "make prog2", then "make prog2" will be run.

What if we don't want to run cmd, but ibstead just display such cmds. For that use :p at the end => tht will display all such cmds w/o running it.

ex: !sudo:p => This will show all cmds starting with word "sudo" w/o executing it.

ex: history | grep <string> => This will searchf= for all cmds with matching string and display it. Here we used pipe and another linux cmd "grep" to filter out results.

6. eval => shell built in cmd. If we set a unix cmd to a variable, then to run that cmd, we need to use eval.

ex: CMD="ls -lrt"; eval $CMD; => If we just type $CMD that will error out.

7. exec: Normally when we run a new pgm, a new process is created. It runs in a new subshell, inheriting env var from it's parent shell. Sometimes, we want to run a new process which has no connection with parent process. In such cases, we can replace the new process with current process .In such cases, exec cmd is used to run the new process. It will replace contents of current process with this binary image of this new process. exec cmd may have 0 or more arguments. If no arguments provided, then exec is only used to redefine the current shell file descriptors. The shell continue after the exec. However if 1 or more arguments provided, then the first arg is taken as cmd, the remaining args are passed as arguments to that cmd. In this case, if there are cmds in a script after the exec cmd, then those cmds will never get executed. In this case, exec never returns as is the case with calling other pgms (since the new pgm has replaced the original pgm).

ex: exec wc -l myfile.txt => runs wc cmd passing "-l myfile.txt" as args to wc

ex: sometimes we see code where we execute a script2 within a shell script1, which sources the same original script1. This looks like a recursive infinite loop, bt can work well when script1 has tcl commands. This script myscript.sh is a bash shell script. Only 1st 3 lines are bash cmds, remaining are pt_shell cmds. On running, this script starts running as bash based on 1st line, ignores 2nd line which is a comment, and runs 3rd line "exec" cmd. That calls a pgm pt_shell which has a source $0 in its arg. pt_shell gets called in a new shell and sources myscript.sh. However, pt_shell is a pgm that can only source tcl files. It sees myscript.sh as a tcl file. So anyline starting with # is treated as comment. So, it ignores first line as comment. It looks at 2nd line, sees contiuation of it on 3rd line (due to \ at end of 2nd line being treated as valid continuation of comment line in tcl), and so considers 2nd line as comment (with 3rd line included in it). Then it moves to 4th line and start reading the file normally. So, here we are able to use the same file as both script and source file.

#!/bin/sh

# \

  exec pt_shell "source $0"

other tcl cmds ....

8. env: Unix has a way of defining a list of strings. These can be assigned a value (in the form name=value). These whole set is called the environment. When shell is invoked, it scans its environment and stores these environment var to pass it to any pgm, that is invoked from within the shell. Whenever any pgm is invoked, shell passes these env var to child processes. Some var are already set by default, as PATH, DISPLAY, SHELL, USER, etc. We can also add new var or modify existing var. Syntax differs slightly b/w bash and csh (more details in bash and csh sections.

csh:

setenv X_ROOT /some/specified/path
setenv XDB    ${X_ROOT}/db
setenv PATH   ${X_ROOT}/bin:${PATH} => PATH env var is unique in sense that we are adding values to PATH w/o deleting the old ones. To append new values, we use :

bash:

X_ROOT=/som/paths => This just defines a var X_ROOT with some value. However, it is not a env var
export X_ROOT => keyword export makes this var an env var, and it's now available to all child process

export X_ROOT=/some/paths => this cmd is equiv to above 2 cmds combined.

using Linux cmd "env" prints all these env var with their values. There are few other uses of env cmd:

1. env is used to run pgms, instead of running them directly. This is useful in cases where we do not want any aliases, shell functions, shell builtin cmds to replace or alter args of any cmd run from within shell. Since env is an external cmd, it has no knowledge of aliases, and simply passes the pgm and it's args to an "exec" call.

ex: env name=value name2=value2 program and args => here pgm and args are preceeded by extra env var whose values are as defined. This runs the cmd "program and args" with an environment formed by extending the current environment with the environment variables and values as shown. This is helpful in cases, where we want just this pgm to have these appened env var, but still leave the env intact for the current shell

ex: env -i <your cmd> => -i ignores environment completely when running the cmd. This is generally useful when creating a new environment (without any existing environment variables) for a new shell. ex: env -i /bin/sh => Here new bash shell is created with environment completely cleared out.

ex: env -u VAR1 => This unsets VAR1 environment variable

2. env is used as first line in scripts. The reason is this => env always searches the PATH for cmd. So, if we provide first line of bash script as #!/bin/bash, it's possible that bash is not in bin dir. Even if bash is in bin, #!bash doesn't work (even though PATH variable has /bin in it). This happens because the first line doesn't search the PATH variable for that bash pgm. To avoid specifying a hardcoded path to bash, we do this:

ex: #!/usr/bin/env bash => Here env being an external program searches PATH for bash pgm, which it finds in /bin/bash, and then runs that pgm called "/bin/bash". NOTE: this still requirs absolute path for env, but env is almost always in "/usr/bin/env" on Linux systems.

NOTE: When Bash invokes an external command, the variable ‘$_’ is set to the full pathname of the command and passed to that command in its environment. 

9. grep: Global Regular Expression Print. Most powerful for searching any pattern in multiple files across dir hier. This cmd is most widely used unix cmd. Lots of options available that you should look into.

detailed usage here: https://www.computerhope.com/unix/ugrep.htm

grep <pattern> file_name => As explained under regular expression section, pattern is Regular expression while filenames are simple glob patterns. By default, grep patterns are BRE, but can be made ERE with -E. To search for any pattern as it is without interpreting it, use -F (this means searching for /a/b#[$"/ef\f will serach for this pattern exactly w/o interpreting any character as special character). Using -F is same as using fgrep (called as fast grep), and using -E is same as egrep (called as extended grep) but usage of fgrep and egrep is deprecated. -r is used to earch recursivel, and is same as using rgrep.(-r doesn't search thru soft links, use -R for that) grep returns names of files that match the given pattern along with the line that matched (separated by :).

grep --color "am(18a)" *.txt => This will search for BRE "am(18a)" as ( ) are not treated as metacharacters (but instead as literals) by default in BRE, so they do not need to be escaped. If we do escape them "am\(18a\)" then they will match "am18a" and anything matching 18a can be recalled later using \1. --color highlights the matched patterns.

grep -E "am\(18a\)" *.txt => This is exactly same as above (w/o the highlight for matched pattern). It will search for ERE "am(18a)" as ( ) are treated as metacharacters (and not as literals) by default in ERE, so they need to be escaped. If we do not escape them "am(18a)" then they will match "am18a" and anything matching 18a can be recalled later using \1.
grep -A 5 -B 4 "anon" *.txt => This will search for "anon" in all files, and then print 5 stmt after and 4 stmt before each matching line.
grep -rl "myname" . => searches for string "myname" in all files of that dir recursively. -l prints file names with a match

grep "name1" */*/*.tcl => This searches for "name1" in all files ending with .tcl extension in dir 2 levels down. If we use recurive option then grep -r "name1" *.tcl doesn't work (It will say doesn't match anything, even though there may be matches in .tcl files).

grep -r "name1" --include="*.tcl" . => With -r option, use option --include="*.tcl" to search only in .tcl files. "." in the end implies search in current dir.

grep -E "^start|^end" *.txt => To find all lines starting with either "start" or "end". Here | is or operator only available in Extended expression, so use -E (though grep "^start\|^end" works too implying | is valid in RE as long as escape char \ is used before it)

zgrep: grep doesn't work on zipped (compressed) files. zgrep is used instead in such cases. Most options remain the same as grep (-r or recursive doesn't work on zgrep).

ex: zgrep "abc" rpt.gz

10. find: find is other very powerful cmd to find any file or subdir in any dir matching a given name. This is very useful where you partially remember name of a file, or you want to find all files with a given file extension, etc. This searches recursively in all subdir starting from a given dir. Lots of options available that you should look into.

detailed usage here: https://www.computerhope.com/unix/ufind.htm

Both dir path and name of file are provided as glob pattern. Quotes are needed when pattern provided for name of file. Without quotes or some other mechanism to escape metacharacters, the patterns would be expanded be shell, which may give incorrect input to the "find" cmd. We want "find" cmd to see the pattern in the name of file, so we use single or double quotes.


find /dir1/dir2 -name file1 -type f => Find files named file1 in or below the directory /dir1/dir2. Here the file name "file1" needs to match exactly, i.e file11 won't match. "-type f" means find only files with given name, while "-type d" means find only dir with given name
find /home/docs/ -name "*driver*" => lists all files starting from dir "docs" that have "driver" in part of their name. This will match my_driver, driver.txt, or any such files

find . -iname "*.Php" => . means start searching from current dir. option -iname ignores case, so test.php, test2.PHP, test3.Php all match

find ./test ! -name "*.php" => ./test means start searching from "test" subdir in current dir. ! does invert match, i.e all files which don't end in .php. Instead of !, we could also use "-not" for invert matching

find ./test -name ".*.txt" -not -name "*.php" -o -name ".*.rpt" => Here we have multiple criteria with -name. However -not means not match .php, while -o means or, so match names with .txt or .rpt

find /home/*/project/*/*/code/ -name "*my_test?_??_.*.txt" => Here we match in multiple dir since * is in dir name. Pattern matching matches my_test1_00_rpt.txt, my_test2_99_.txt, etc.

find -mindepth 2 -maxdepth 3 /home/docs/ -name "*driver*" => This cmd is used to limit search to certain depth, otherwise find serches all the way to leaf dir. Here, it starts search from 2 dir below /home/docs and stops at 3 dir below that, so in essence it searches in only 2 dir at /home/docs/*/*/*driver* and /home/docs/*/*/*/*driver*. "-mindepth 1 -maxdepth 1" is used to search in current dir only without going any deeper.

11. cut: cut text from lines. cut can do most of what we do using scripting languages as perl, sed, etc.

cut -d":" -f2,4 file_in > out_file => This cuts the file using delimiter ":". By default delimiter is TAB (not individual space), so if you have TAB separated text, then you can omit -d.  To cut it by a sinngle space, do -d" ". After cutting, it names the columns as f1, f2, f3, etc that are separated by this delimiter. f2,4 says that print out column 2 and column 4. The output is then printed to out_file.


more file1 | cut -d'=' -f1 | grep REG2 => This cuts each line of file "file1", with delimiter =, and names fields as f1,f2 with = as delim. Then it takes field f1 out and prints it. Then grep prints only those lines that have REG2 in them
ex: CONFIG_REG2.RESERVED = new("RESERVED", 26,..) => for this file, cmd above gives CONFIG_REG2.RESERVED

grep and cut cmds may be combined via pipe to edit multiple files.

ex: grep "assign SDA" tests/I2C/*/test.v =>this may return o/p which is something like as shown below (names of files where pattern was found, along with the line where it matched separated by :) then cut gets file names, and then we checkout those files
tests/I2C/dir1/test.v:assign SDA = 1'b0
tests/I2C/dir2/test.v:assign SDA = 1'b1;

ex: cut -d":" -f1 => If we apply cut cmd to above o/p, then we get f1, which is names of files. Then we can do whatever we want with these files.

ex: grep "assign SDA" tests/I2C/*/test.v | cut -d":" -f1 | xargs cleartool co -nc => The 1st part greps "assign SDA" stmt and lists all the files that have it. Then we use ":" as delimiter, and extract name of files. Then "xargs" cmd takes all the names of files as arguments to cmd "cleartool co -nc". So, this causes all files to be checked out which had that "assign SDA" stmt in them.

ex: grep "assign SDA" tests/I2C/*/test.v | cut -d":" -f1 | xargs sed -i 's/assign SDA/assign #10 SDA/' => replaces "assign SDA" with "assign #10 SDA" using sed to all files that have this line. sed cmd explained later.

ex: more ~/z.txt | tr -s " " | cut -d" " -f2 | less => Here we are cutting by single space. If our text contains multiple spaces, then use "tr" cmd (explained below) to squeeze multiple spaces into one.

12. sort: sort is another very useful cmd to sort lines in a file. It sorts lines alphabetically (not ascii), and then prints o/p on screen. -u sorts them uniquely (i.e if it finds multiple lines with exactly same content, it only prints 1 of them)

ex: : grep Scope /sim/.../violations.txt | sort -u => It looks for "Scope", and then sorts them uniquely. This is very useful to uniqify gate level timing violations coming from cadence simulator.

sort can also be used to sort on specific columns separated by space (instead of from start of line) by using option "-k <col_num>", and can sort numerically on that entry (instead of sorting alphabetically) by using "-n" (sorts from smallest to largest number). -r reverses the sorting order (irrespective of whether it's ascii sorting or numerical sorting)

ex: grep "me" *.txt | sort -n -k 3 > sorted_col3.txt => This sorts the file based on entries in 3rd column and does that numerically. So, if 3rd col has 21, 36,05, 17, then it will sort as 05,17,21,36.

13. tee: used in complex pipes to record some stage o/p (diverts copy of that to the named file).
syntax: tee [ -ai ] file_list
-a => appends o/p to existing file, w/o this file is overwritten.
-i => Ignore interrupts. If you press the Delete key, tee ignores the interrupt signal sent to it and continues processing.


Ex: sort somefile.txt | tee sorted_file.txt | uniq -c | head 12 > top12.txt

14. list: returns list comprised of all the args. braces and backslashes get added as necessary
syntax: list ?arg ... ?arg
ex: list a b "c d e " " f {g h}" => returns this: a b {c d e } { f {g h}}

15. tr: This translates, squeezes or deletes characters. It takes input from STDIN (not a file), and writes to STDOUT. So, we can only use this cmd in a pipe |, or provide the text directly. With tr cmd, -d deletes, -t renaslates and -s squeezes each input sequence of a repeated character that is listed with a single occurrence of that character. This cmd is very useful to use to pipe to other unix cmds, which don't handle multiple spaces.

ex: more ~/z.txt | tr -s " " | less => This truncates multiple spaces in file z.txt with single space. Now, this can be used with "cut cmd" for ex. See in cut cmd section above.  

16. system cmds: These are cmds that show system related info.

ps: process info
ps -ef => lists all running process. /proc/ dir has all process in it as separate dir (with PID name), with files containing details about processes.
ps cmd greps process PID and other details from this /proc/ dir

lsof: list open files

lsof -D dir1/ => This lists all open files in a given dir, and the process which is using them. -D option is needed only if we want to recursively apply it on all the files in the dir. To apply on a single file only "lsof <file>". This is very helful, when you can't delete a file due to "device/resource busy", and ps doesn't show which process is keeping it open. This is reverse of "ps" where it says which process has that file open, and then we can kill that process using kill -9 <pid>.

uname: info about system
~ [538]$ uname -a => prints all system info: kernel name, hostname, kernel-release/version, macine, processor, h/w platform and OS.
Linux lindesk51.dal.design.ti.com 2.6.9-89.0.16.ELxenU #1 SMP Tue Oct 27 04:12:25 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
NOTE: above cmd doesn't show which Linux is used. To find that, do: ls /etc/*rel*. If it shows one of the files as "/etc/redhat-release", then its redhat OS. If it shows "/etc/SuSE-release", then it's SuSE OS. You can see the version number by looking into this file. As an ex for centOS: /etc/centos-release file shows => "CentOS Linux release 7.7 (core)" implying it's version 7.7
Other way to find OS is to run: lsb_release -a => std unix cmd which prints certain LSB (Linux Standard Base) and Distribution information. -a displays all info.

hostname => shows name of the host on which this cmd ran.

who/w: who and w cmds  displays info about all users on that machine. w cmd provides more details than who and also shows what processes they are running.

which: shows the full path of any cmd (i.e path of binary or pgm being executed). This is very useful cmd to see where any pgm is getting executed from.

ex: which ls => /usr/bin/ls => this shows that path to unix cmd "ls" is as shown

file: return the "type" of a file.

ex: file my.png => PNG image data, 1600 x 900, 8-bit/color RGB, non-interlaced

type: indicates how its argument would be interpreted if used as a command. If cd s aliased to something else, it would show that. See args for type cmd.

ex: type cd => returns "cd is a shell builtin"

NOTE: It only seems to work on bash shell, not on csh.

whereis: locate source, executable image, and/or manual pages for a command. this is a superset of "which" cmd, which also shows source of code, manual pages, etc. This is one of the most underrated cmd, and is very helpful

ex: whereis ls
ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz

17. super user or root user cmds:

Whenever Linux is installed, a user with username "root" is created by default, and we set a password for root user at that time. Then we can create additional users, setting their own passwords. Root user is also called superuser, and has write permission to all files in system. / dir is called root dir, and root user has read/write permission to everything under this root dir. The prompt will change to "#" (from "$" in bash or "%" in csh) to indicate that current user is root. If user's name is displayed, then it will show root# for root and ashishb$ for other users.

sudo: super user do. "super user" and "root" are used interchangeably to imply a user who has admin rights. Most cmds for making any changes in Linux system (i.e install new software, etc) are allowed by root user only which has also system privileges. This is done for security reasons. However, since most of the users login into their own account, they can't have root privileges. sudo is the cmd that allows us to achieve that. By typing sudo before any cmd that requires root privileges, we temporarily allow current user to fake as a root user, and allow him to run that cmd. This cmd has many options, details here: https://www.sudo.ws/man/1.8.16/sudo.man.html

ex: sudo yum install tcl => yum install is reserved for root user only, so if any other user tries to run "yum install tcl", it will give "privilege error". However, by appending "sudo" before the cmd, it allows current user to act as root user for this cmd only. It will ask for current user password (NOT the root user password), and on matching password, it runs this cmd w/o issues.

So, sudo allows us to run a privileged cmd w/o logging in as root. This is most preferred way, as we don't have to login as root. So, the question is how is it secure? It's secure because only those users whose username match against names in special file called sudoers (in /etc/sudoers) are allowed to run the sudo cmd, and which cmds they can run is also specified in this file. Others will need to login as root by using su cmd. Other users on system can be granted super user rights by adding their user names to this file, and also specify what cmds that can be allowed to run.

sudo can be used to change user to root (similar to su cmd below):

sudo -i => -i or --login allows us to login as target user. Here, since sudo cmd is used, target user is root. So this allows us to login as root in that teminal, so that we don't have to type sudo cmd all the time. We see prompt change to root# from sanjay#. Now we can type any cmd w/o sudo prefix. This does what su cmd does below. su cmd below to change to root user doesn't work in ubuntu, but this cmd works.

su: switch user. This is similar to sudo cmd, but this is used to switch user from current user to any other user whose account exists on system. However, here we need password of the other user whose a/c we are switching to.

ex: su ashishb => this asks for the password for user "ashishb", and on matching the password, switches to user account "ashishb" from current account. However, this doesn't switch the environment of current user to ashishb env, so cmds as cd, running executables with permissions set to ashishb may not work. To get even the env of new user, we have to do proper login into other user via - or -l, i.e: su - ashishb (or su -l ashishb) => this switches the env to ashishb env

ex: su => su cmd w/o any options switches to root account. That is why sometimes su is abbreviated as "super user". However, we need to know the root password for this. Moreover, just as in sudo, su w/o - sign, doesn't switch the env to root, but when we use "su -", the env of current user switches to root (i.e pwd will print /root instead of /home/ankitk as user's current dir)

Other way to switch to root account is via "sudo -i".

To logout from root, run "exit" or "logout" to return back to your normal user account. "su -" (instead of just su) is preferred way to login as root, since this command simulates a complete root login (running init script, setting env var, etc)

Ubuntu root account:

Root account is setup on most linux distro when installing but is not done for ubuntu based derivatives. This means that you don't get to choose a root password for ubuntu based systems. Actually, the developers of Ubuntu decided to disable the administrative root account by default by not assigning a root password.

Article on enabling root a/c: https://www.computernetworkingnotes.com/linux-tutorials/how-to-enable-and-disable-root-login-in-ubuntu.html

So, when we run su cmd for ubuntu based systems, and provide a password, it will always say "incorrect password". We can enable root account as shown in link above. But using "sudo -i" works too.

CentOS root account:

In CentOS, su cmd works by default as root password is setup during installation. (If on single user system, default user is also assigned as admin, so that user's password is also the root password).  Now we can run any cmd w/o needing to enter "sudo" for any cmd, as we are root user and have all the privileges.

 

misc cmds: These cmds have been explained in other sections of linux, so look over there too for other details.

lsblk: lsblk cmd is explained in "File systems". It allows us to list all devices. 

dd: dd cmd is explained in "File systems". It allows us to copy contents of any device.

printer cmds:

lpr: print to printer
1. lpr -P LKE_4001 file.txt => prints file.txt in non-duplex mode. We can set options, to print it in desired way. for that we provide options with -o
. We can get valid option names for a printer by runnig cmd "lpoptions" on that printer. Different printers have different options
2. lpoptions -p LKE_4001 -l => gives all options for named printer. For ex: for duplex, we see option "Duplex/2-Sided Printing: *None DuplexNoTumble DuplexTumble" meaning option_name is Duplex, and option_value is cauurently set to none, although others values allowed are "DuplexNoTumble" and "DuplexTumble".
3. lpr -PLKE_4001 -p -o Duplex=DuplexNoTumble -o HPwmFontSize=pt30 file.txt => -p is used for pretty printing. default fontsize of pt48 too large, so using pt30
4. lpr -PLKE_4001 -duplex test.txt => instead of above, we can use this as for every printer that can duplex, there exists a -simplex and -duplex queue that simply forces either option

a2ps: converts to ps format
a2ps -s 2 -P LKE_4001 file.txt => prints duplex. use option -Pvoid to print to void printer(displays no. of pages that it's going to use). -f8 prints using font size=8.

enscript:
enscript -BH -r -2 -dLKE_4001 -fCourier7 -DDuplex:true file.txt => prints in a pretty format. alt to a2ps

lpstat: printer statistics
lpstat -d -p => gives names and desc of all printers connected.

misc programs and useful utilities: There are many other useful pgms included in all major linux distro by default.

tar/untar, zip/unzip: these cmds are actually linux pgms to compres/decompress files and dir. First tar is used to put the whole dir into a file (.tar), and then gzip/bzip2 is used to compress that file (.tar.gz). gzip/bzip2 compression doesn't directly work on dir, so we've to use tar. Both gzip and bzip2 compression algo are supported with tar, though gzip is more common. bzip2 has higher compression rate, but takes more time to compress. To get our dir back, we do the reverse: gunzip first and then untar (i.e tar with diff option). The resulting file .tar.gz/.tar.bz or .tgz/.tbz is called a "tarball". .gz is for gzip while .bz or .bz2 is for bzip2

  • Tar and zip: First tar and then zip.
    • tar -cvf file1.tar dir1 => tars dir1 into file1.tar and puts the named tar in current dir. Option -c => create archive, -v=> verbose mode where progress is diplayed on terminal, -f => filename of archive (here it's file1.tar). W/o -f, tar will be created with same name as name of dir being tarred (i.e dir1.tar). We could also create tar of files by providing names of files or isung glob (*, etc). ex: tar -cvf file1.tar dir1 dir2 dir3/file1 file4 => This puts all these in a single tarball. "--exclude=file_name_pattern" switch can be used for each directory or file you want to exclude (so that not all files within a given dir are included in tarball).
    • gzip file1.tar => zips file1.tar into file1.tar.gz and puts it in current dir. .gz file is compressed to about 1/4th the orig size.
    • Both the cmds above can be combined into one by adding "z" option to tar which says zip the file using gzip compression too. -j compresses it using bzip2 compression algorithm. ex: "tar -zcvf archive.tar.gz directory/"
  • Untar and Unzip: First unzip and then untar.
    • gunzip file1.tar.gz => unzips file and creates file1.tar file. If we want to keep existing tar file, and create new untarred file (usually in cases where we don't have write permission for that dir), we can use -c option of gunzip. The -c option will write the unzipped data to stdout and will not remove the original .gz file. We rediect this stdout to a file: ex: gunzip -c file1.tar.gz > ~/file1.tar
    • tar -xvf file1.tar => leaves original tar file intact. extracts all files from the tar file, and keeps them in same dir with dir name=file1. To get content of only desired files, we can provide names of files/dir and only those will be extracted, i.e "tar -xvf file1.tar file1/file2 file1/dir3/file3" => extracts only these files/dir in "file1" extracted dir.
    • Both the cmds above can be combined into one by adding "z" option to tar which says gunzip the file too. ex: "tar -zxvf archive.tar.gz". switch "-C ~/dir2" will extract the archive in ~/dir2 dir.
  • Viewing contents w/o untarring or unzipping: We can extract files above using unzip and untar shown above. However, many times we've to look thru bunch of tar files, and it's not always possible to untar.unzip everything as it takes time and lots of space. We just want to look at contents of tarball or search for patterns in individual files. For this use below options:
    • less file1.tar => This will show all subdir and files inside the tarball. Won't show contectn of files though
    • zgrep -Hna "my*pattern" file1.tar => zgrep will search for given pattern "my*pattern" in individual files of the tarball. -H lists the filenmae that contains the mtach, -n shows the line number while -a treats all files as text files. Unfortunately -H doesn't show the individual filename, but only the tarball name which is not very helpful. "--label=filename" may also be added to zgrep to search only in given files.
    • tar -tvf file1.tar dir1 =>This shows the contents of archive. -t flag specifies that we need to only view the contents of the archive. This is same as using "less" above
    • tar -xOf /dir1/*.tar.gz */logs/syn.*.log => Option -O (NOT zero(0) but capital O) will not extract the files on disk, but will rather extract i to standard o/p (On screen). We can pipe it thru "less" to view the file or search for any pattern using grep. Very helpful option.

openssl: This is a linux pgm to encrypt/decrypt files, openssl supports wide range of ciphers.
openssl aes-128-cbc -e -in file1 -out file1.aes -K -iv 0 => uses aes for encryption (openssl enc -ciphername => openssl ciphername).e=encrypt, d=decrypt, i/p=file1, o/p=file1.aes, -iv specifies actual initialization vector(IV) to use. The cipher modes CBC, CFB, OFB and CTR all need an IV. -iv must be used when only the key is specified using -K, and no password is specified (-k or -pass specifies the password to use). IV should consist of hex digits only. A new, random IV should be created for every encryption of data. Think of the IV as a nonce (number used once) - it's public but random and unpredictable. -nopad disables padding (otherwise encrypted data is larger than i/p data, as engine adds extra bytes to i/p). key is in hex only (-K F01A95...4C => no need to use 0x...)

od: octal dumping pgm. Can also dump hex, decimal or ascii. -a=ascii, -x=hex, -d=decimal, -o=octal. See c_pgm_lang.txt for ASCII codings.
ex: od -a test1.txt (test1.txt has: abcd CR 1234 CR tab CR)
0000000 a b c d nl 1 2 3 4 nl ht nl => shows byte 1 is a, byte 2 is b, byte 5 is newline, byte 11 is tab(ht) and so on.
#NOTE: we can od for an executable file to see what's in there. Usually it's long, so do "head" to see only first few lines
od hello | head

sendmail: email: /usr/sbin/sendmail This email address is being protected from spambots. You need JavaScript enabled to view it.

diff: diff is very important pgm to find out differences b/w 2 text files. It's used very often. However, it's o/p is little cryptic, so "tkdiff" is used which is gui rep of differences. meld (open source) and bc (beyond compare, a proprietary tool) are other gui based diff tools which can diff entire dir recursively.

ex: diff -c file1.txt file2.txt => shows differences in content of file1.txt vs file2.txt. file2.txt is treated as reference for comparison purpose. o/p is little cryptic. To make it more human friendly, use option -c

ex: diff --color -c -i -w file1 file2 => here differences are highlighted in red color. -i ignores cases. -w ignores all white spaces (this is very helpful, where we don't want space differences in different files to be reported as actual diff). there are many other variants of space diff such as -b which ignores changes in amount of white space, -E,(ignores changes due to tab expansion), -Z (ignores white space at line end), -B (ignore blank lines), etc.

ex: diff -qr dir1/dir2 dir3/dir4 => -q only shows if files are different w/o showing actual differences. -r does recursive comparison for any subdir too, for all files in given dir

 

cron/at: Many times, we want to run a script automatically every day or at particular times. This can be easily be done via 2 cmds that are widely supported in Linux OS. However, you will need to install the software, if it isn't included by default.

  • cron: "crond" is the cron daemon (background service) that runs cron jobs.
    • To install, type => sudo yum install cronie (for RPM OS m/c). Then start and enable service using systemctl.
    • To add jobs to cron, we ned to add jobs to crontab file. Open it using crontab -e.
    • Syntax for each cmd is => <time/date to execute> <cmd_to_execute>. There are 5 fields for time/date. 1st field is for inute, 2nd for hour, 3rd for day of month, 4th for month, 5th for day of week.
      • ex: 20 3 * * * /home/run_it.sh => This will run "run_it.sh" script everyday at 3:20am
  • at: Many times, we need to run a job only once in future and never again. at is easier to use in such situations. Also, many times we don't have admin permissions to run cron on other m/c, in those cases at can stll be used. Similar to cron, at has it's daemon, "atd" that runs at jobs.
    • To install, type => sudo yum install at (for RPM OS m/c).
    • Syntax for running a acript at specific time => at <time/date> -f <script_name>
      • ex: at 3:50 -f ~/my_script.csh => This wll run script at 3:50am
    • To use at for running daily jobs, we can use a trick used in other scripts => We run the script using at, and then schedule the same script inside the main script. This way, the script will run once and then reschedule itself to run again after specified time. Ex below makes the script run every 24 hrs.
      • my_script.sh => (Add this line in script) => ./daily/script_daily.csh; echo "$0" | at now + 24 hours
      • chmod 755 my_script.sh
      • ./my_script.sh | at now