synthesis: Synopsys DC

DC (Design Compiler):  This is the synthesis tool from Synopsys, which takes RTL as input and generates a synthesized netlist.


For running synthesis in Design Compiler:
-------------------------------------------------------------------
In synthesis, clk and scan_enable are set as ideal network, so they don't get buffered (they get buffered in PnR). Reset and all other pins are buffered as needed to meet DRC. This reset tree built in DC is again rebuilt in PnR during placement to make sure it meets recovery/removal checks.

steps in DC synthesis are as follows:


1. RTL opt: HDL-Compiler compiles HDL (performs translation and arch opt of design). DC translates HDL desc to components extracted from GTECH(generic tech) and DW(Design Ware) lib called as RTL opt. GTECH consists of basic logic gates and flops, while DW contains complex cells as adder, comparators, etc. these are tech independent.
2. Logic opt: DC then does logic opt. first, it does structuring which adds intermediate variables and logic structures to GTECH netlist. then it does flattening which converts combo logic paths into 2 level SOP rep. At this stage, all intermediate variables and it's associated logic structure are removed.
3. Gate opt: it optimizes and maps GTECH design to specific tech lib (known as target lib). It's constraints driven. It does delay opt, design rule fixing and area opt. Power Compiler used if static/dynamic power opt done.
4. Add DFT: Next Test synthesis is done using DFT Compiler, which integrates test logic into design.
5. Place and Route (PnR): PnR is done next, from which delays can be back annotated to design. DC can then resynthesize to generate better netlist.

Operating condition for any chip is defined via 3 conditions: Process (P), Voltage (V) and Temperature (T). Since these 3 uniquely determine the speed of transistor, we choose a particular PVT corner for running Synthesis. Usually we define 3 PVT corners (below ex is for a design in 250nm). The term max, min, etc refers to delay, so max corner means corner with maximum gate delay, i.e slowest corner.

NOM: P=TYP, V=1.8V, T=25C (TYP) => This is the typical or nominal corner where chip is supposed to run at nominal speed. Here PVT is specified as 1.8V, room temperature and nominal process.
MAX: P=WEAK, V=1.65V, T=150C (WC) => This is the worst case corner, where chip is supposed to run at the slowest speed. Here PVT is specified as 1.65V, high temperature and weak (slow) process. MAX implies this PVT gives you maximum delay (i.e slowest speed). You will note that voltage is -10% below typ. This is generally a safe voltage to choose as voltage is not supposed to fluctuate by more than +/- 10% even in worst case scenarios (as voltages are usually controlled by PMU, which hold voltage levels very tight. Most of the voltage fluctuations happen due to IR drop on and off chip).
MIN: P=STRONG, V=1.95V, T=-40C (BC) => This is the best case corner, where chip is supposed to run at the slowest speed. Here PVT is specified as 1.95V, low temperature and strong (fast) process. MIN implies this PVT gives you minimum delay (i.e fastest speed). Voltage here is usually +10% above typ

Since we want our design to be able to run in worst possible scenario, we choose WC (MAX) corner to synthesize our design. Then, our design is guaranteed to work across all OP conditions.

run DC:


dc_shell-t -2010.03-SP5 => brings up DC shell. dc_shell is shell mode (dc own shell), while dc_shell-t is tcl mode (dc shell which can accept tcl cmd too). dc_shell-xg-t is XG mode, which uses opt mem mgmt to reduce run time.
dc_shell-t -2010.03-SP5 -f ./tcl/top.tcl | tee logs/my.log => runs with cmds in top.tcl and keeps all info printing on screen to my.log
dc_shell-t -2010.03-SP5 -t topo -f ./tcl/top.tcl => To bring dc-shell-t in topo mode. This requires MilkyWay (MW) db. See section in synopsys ICC (PnR_ICC.txt)

When we run in DC shell above, it's a text based shell. We can also have GUI.
Design Vision is GUI for synopsys synthesis env. symbol lib is needed to generate design schematic. To start gui, either run "dc_shell -gui", or from within dc_shell, run "gui_start".
DC family:
1. DC Expert (compile cmd used).
2. DC Ultra(compile cmd used).

Help in DC: type "help" or "cmd_name -help" or "man cmd_name"


setup file for DC:


We have a setup file for DC that DC reads before invoking DC shell. This file is .synopsys_dc.setup and is usually put in the dir from where DC is invoked. This file has search paths, lib path and other variables setup. Note this file can be copied from some other project by using: cp dir1/.synopsys_dc.setup to dir2/.

.synopsys_dc.setup => This file can have all common settings that you want to apply to your design. It can source other tcl files or set parameters for DC. At a minimum, it needs to set search_path, target_library and link library.


set search_path "$search_path /db/pdk/tech45nm/.../synopsys/bin" => adds this path to default path to search for design and lib files

set target_library TECH_W_125_1.6_STDCELLS.db => this lib, which should be present in search path above, is used during compile to gen gate level netlist. worst case (wc) lib chosen, as we try to meet setup for wc corner. taget_library is used by opt engine to map design to, so it should have all stdcells that are required for mapping.

set link_library {* TECH_W_125_1.6_STDCELL.db }  => link_library (or link_path) is a superset of target_library. resolves references. First looks in DC mem (* means DC mem which has design files), then in specified .db (same as target_library files) for matching lib cell name and then any other libraries which are not target for opt, but may be present in design (as Macro, RAM cells). In DC, we don't need Clock cells (i.e buffers, inverters specifically made for clk tree), so in many companies, clk cells are all put in a separate library, so that we don't have to load unnecessary library cells during synthesis.

link library are synopsys .db files (liberty files in db format) and our design are *.ddc/*.db files. We put *, so that on top of liberty files, DC searches in all the designs already loaded in mem (i.e for module named A in top.db, it searches in A.db, before it looks for A in .lib files). If we omit *, it will cause link failures, as hier designs have modules, which it won't be able to find any more.

NOTE: Most lib/db files have file name same as library name within that file. i.e "TECH_W_125_1.6_STDCELL.db" is defined as library within the file "/db/tech45/.../TECH_W_125_1.6_STDCELL.db". "target_library" and "link_library" refers to file names ?? FIXME ??. Also, we can also provide the full path name of the file so that search_path is not needed for finding target and link libraries.

ex: set target_library "/db/tech/.../TECH_W_125_1.6_STDCELLS.db"


NOTE: In PT, we use PnR netlist which has Clk cells, so we add db for clk cells also when running PT.

NOTE: if we have hard IP blocks, then db files for those blocks should be included in link_library, and paths for those should be in search path. That way, we don't have to provide RTL code for that IP. DC sees that cell name in the db file present in any of target and link lib, and on finding them there, it doesn't complain about missing cell.

Ex: sram2048x32 (sram cell). We instantiate "sram2048x32" in RTL file digtop.v and also have a rtl file (sram2048x32.v) for this module. Then, when running DC, we don't analyze and synthesize rtl file "sram2048x32.v" (i.e this verilog file is not provided in list of RTL files). DC looks at module name "sram2048x32" and tries to find this cell in link_library. It finds this "cell (sram2048x32)" stmt in "sram2048x32_W_125_1.65.db" file, which is present in link library.At this point, tool is happy, otherwise it would search for "sram2048x32" module in any of the other rtl files. This is similar to what happens if we instantiate a latch (LATCH10) directly in RTL, then DC looks for that cell in target_library and link_library. It finds them in "TECH_W_125_1.6_STDCELL.db" file as "cell (LATCH01)" and hence doesn't complain, otherwise it would look for LATCH10 module in any of the RTL files being analyzed, and on not finding the module, it would complain.


#symbol_library => defines symbols for schematic viewing of design.
#synthetic_library => to specify any specially licensed DW lib. Std. DW lib are included by default.

NOTE: only .db library can be read in DC. If we have library in .lib format, then we need to convert it to .db using cmds below and then use those.
#read_lib /db/.../rom_W_150_1.65.lib => This file will be read and stored as *.db file in mem. list_libs will now show this lib too as .db
write_lib rom_W_150_1.65.db -f db -o /db/.../rom_W_150_1.65.db => optional. This saves file in path specified so that next time .db file are directly available to be read by DC (saves run time??).

#if we want to do max/min timing using max/min lib, then we need to do as explained in create_views of PnR_ICC.txt.
#list_libs => lists which lib are used as max lib (denoted by M), and which for min lib (denoted by m). We should see all db library, and in which db file they are. dw_foundation.sldb, gtech and standard.sldb lib are also shown with their paths.
#report_lib => reports contents of lib as units, op cond, WLM and cells. Use this to see library units for cap, resistance, etc present in the library.
#which abc.db => shows absoulte path for this .db file that is being used currently.

Difference between target library and link library, and why do we need both?

Target lib are lib that you target for mapping your RTL to gates. These are std cells which are provided as target. DC chooses from amongst this set, a subset of cells to optimize the final mapped design. On the other hand, link lib resolves references in the design by linking the instances, references in the RTL with the link libraries. So, in link lib, we provide target lib plus any IP as memory, PLL, analog blocks etc, which are needed strictly for linking. These IP lib are not needed for optimizing but just for linking (as they contain just 1 lib that we force to link). So, link lib contain target lib + extra macro libs.

So, the question is why do we need both, when we are specifying same libraries in target and link? Reason might be that it's easier for the tool to have different lib settings for "OPTIMIZATION-MAPPING" & "LINKING".That way it knows what to pick for optimizing and mapping, and what to use for strick one to one mapping.


DC script:

Below is a sample DC script that can be used to run synthesis. We start with the top most file known as top.tcl.

top.tcl: this is the main tcl file that is sourced by the DC tool from cmd line. All DC cmds are in this file, and DC starts running cmds from this file until it reaches end of this file. These are the various sections of this script in tcl:


1. Read all RTL files, and link the library of cells/IP.


#source some other files
#NOTE: for source to work, file path has to start with ./ so that it looks for that file in unix dir, else DC will look for that file in it's memory which doesn't have that file, so it will error out.
source ./setup.tcl => In this file set some variables, i.e "set RTL_DIR /db/dir" "set DIG_TOP_LEVEL  digtop" or any other settings

#this is to suppress warnings during analyze/elaborate
suppress_message {"LINT-1" "LINT-2" "LINT-10" "LINT-33" "LINT-8" "LINT-45" "VER-130" }

#read verilog/vhdl/systemVerilog files. DC can also rd in .ddc & .db (snps internal format, .ddc recommended), equation (snps equation format), pla (berkeley espresso PLA format) and st (snps state table format). 2 ways:
1. Analyze and elaborate => analyzes (compiles, checks for erros and creates an intermediate format) and elaborates HDL design, and stores it in snps lib format file for reuse. All subdesigns below the current design are analyzed, and then elaboration performed only at top level. During elaboration, RTL compiler builds data structures, infers registers in design, performs high level HDL optimization, and checks semantics. It translates the design into a technology-independent design (GTECH) from the intermediate files produced during analysis. It replaces  HDL arithmetic operators in the code with DesignWare components and automatically executes the link command, which resolves design references
After elaboration, RTL compiler has internally created data structure for the whole design on which it can perform operations. cmds:

analyze -format verilog|vhdl [list a.v b.v] => on doing analyze, WORK dir created which has .pvl, .syn and .mr file for each verilog module. Runs PRESTO HDL Compiler for RTL files, and then loads all .lib files.
analyze -autoread [list a.v b.v c.vhd] => to auto analyze mix of verilog and vhdl files

elaborate <top level verilog module name, VHDL entity or VHDL configuration> => ex: elaborate digtop => loads gtech.db and standard.sldb from synopsys lib, and link library *_CORE.db and *_CTS.db from user defined lib, and then builds all modules. It infers memory devices (flip flops, and appends _reg to the net name storing the value i.e net <= value), analyzes case stmt (full case[all possible branches specified so combinatorial logic synthesized, else latch synthesized for non full case], parallel case[case items don't overlap, so mux synthesized, else for non-parallel case, priority checking logic synthesized])

2. read_file -f <verilog|vhdl|db/edif> filename => we can also use read_verilog, read_vhdl, read_db and read_edif, instead of specifying file type in read_file. this can be used to read in gate level netlists also that are mapped to a specific tech. This also performs analysis and elaboration on HDL designs written in RTL format, but it elaborates every design read, which is unnecessary. Only top level design needs to be elaborated. read_file is useful if I want to reuse previously synthesized logic in my design.

#We use 1st way shown above: do analyze and elaborate and then set current_design
analyze -format verilog [list "/db/.../global.v" "/db/.../utils.v" ... "/db/.../digtop.v" ]
elaborate      digtop => since digtop is top level module
current_design digtop => current design always needs to be set to top level

#for design references during linking, DC uses the system variables link_library and search_path along with the design attribute local_link_library to resolve design references. link library has library cells (from .lib) as well as subdesigns(modules inside top level module) that the link cmd uses.
link => resolves references. and connects the located references to the design.

#To see the reference names, use the following command:
#get_references AN* => returns coll of instances that refer to AN2, AN3 etc. ex o/p = {U2 U3 U4}
dc_shell> report_cell [get_references AN*]  => shows references for AN2, AN3, etc for cells and the library to which it's linked. At this stage, lib is GTECH and all references are from this GTECH library. so, use * to see all references.
dc_shell> report_cell [get_references *]  => this shows all ref for cells present in top level design. If there is any logic stmt (i.e assign = A&B; etc) in top level, then it gets mapped to GTECH cells as GTECH_OR, GTECH_AND, etc and gets reported too.
Cell                      Reference       Library             Area  Attributes
--------------------------------------------------------------------------------
B_0                       GTECH_BUF       gtech           0.000000  c, u
C29                       *SELECT_OP_2.1_2.1_1            0.000000  s, u
C54                       GTECH_AND2      gtech           0.000000  u
ccd_top                   ccd_top                         4.000000  b, h, n, u
revid_tieoff              TO010           PML30_W_150_1.65_CORE.db  1.750000
--------------------------------------------------------------------------------
Total 42 cells                                            172.500000


2. specify constraints: env constraints (PVT), design constraints(area/max_fanout) & timing constraints(clks/false_paths)

constraints: IMP: all constraints are specified in sdc format. see sdc.txt for details of constraints. 2 set of constraints:
1. env_constraints = i/p driver, o/p load, i/p delay, o/p delay, dont_touch, dont_use
2. design constraints:
   A. design rule const: max_fanout, max_transition, max_cap
   B. optimization constraints:
      I. timing constraints = clks, generated clk, false path, multicycle paths, (if false_paths refer to gate level netlist, then initial mapped netlist needed)
      II. power contraints = max_power
      III. area constraints = max_area


A. environment constraints: as op cond (PVT), load (both i/p and o/p), drive (only on i/p), fanout(only on o/p) and WLM.

#set_operating_conditions: see in PT OCV section for details of this cmd.
set_operating_conditions -max W_150_1.65 -library STD_W_150_1.65_CELL.db (Instead of set_operating_conditions we can also use "set_max_library STD_W_150_1.65_CELL.db) => Here, we are using our max delay library for both setup/hold runs. We can check this by looking in reports/digtop.min_timing.rpt.

FIXME # LBC8/PML30 lib uses 1.8V PCH_D_1 and NCH_D_1 (Lmin=0.6um drawn), cell height=13.6um, 8routing tracks available, with 3,4,5 Layer for metal routing. 1X inv has i/p cap of 6ff. Power is about 0.1uW/gate/Mhz (CV^2f= 6ff*1.8^2*10^6/MHz = 0.15uW/MHz for inx1) FIXME

#WLM: wire load model: used only when design is not in physical mode.
set auto_wire_load_selection true
#set_wire_load_model "6K_3LM" => sets wire load model on current design to something other than the default one set in .lib file. Usually for larger designs, we set WLM manually, since the default WLM may be smaller designs, and so too optimistic.

# Setting enclosed wire load mode. mode may be top|enclosed|segmented
set_wire_load_mode enclosed => Here, multiple WLM are specified for various sub-modules, so for a net which traverses multiple sub-modules, WLM of that higher level module used which completely encompasses the net. When mode is "top", then WLM of top level module used for all nets in design. Since WLM is defined only for top level design above, WLM for lower level sub-modules are chosen as default when mode=enclosed or segmented.

report_design => see in PT OCV section for details of this cmd. shows all libs used, op cond used (PVT from WLM used, etc.

##### DC TOPO flow starts: see in PnR_ICC.txt for details. comment out the WLM portion above for DC-TOPO.

#create MW lib if one doesn't exist already. From next time, we can just open created desgin lib.
create_mw_lib -technology /db/DAYSTAR/design1p0/HDL/Milkyway/gs40.6lm.tf \
    -mw_reference_library "/db/DAYSTAR/design1p0/HDL/Milkyway/pml48MwRefLibs/CORE /db/DAYSTAR/design1p0/HDL/Milkyway/pml48ChamMwRefLibs/CORE" \
    -open my_mw_design_lib
open_mw_lib my_mw_design_lib
set_check_library_options -cell_area -cell_footprint
check_library

#set TLU+ files instead of WLM.
set_tlu_plus_files \
    -max_tluplus /db/DAYSTAR/design1p0/HDL/Milkyway/tlu+/gs40.6lm.maxc_maxvia.wb2tcr.metalfill.spb.nlr.tlup \
    -min_tluplus /db/DAYSTAR/design1p0/HDL/Milkyway/tlu+/gs40.6lm.minc_minvia.wb2tcr.metalfill.spb.nlr.tlup \
    -tech2itf    /db/DAYSTAR/design1p0/HDL/Milkyway/mapping.file
check_tlu_plus_files

######DC-TOPO flow ends

#naming convention for lib objects varies b/w vendors, but for SNPS, it's "[file:]library/cell/[Pin]" (file and pin are optional). Ex: to access AND2 cell: set_dont_touch /usr/designs/Count_16.ddc:Count_16/U1/U5.

#i/p drives
set_driving_cell -lib_cell IV110 [all_inputs] => all i/p ports driven by IV110
#set_drive/set_input_transition

#i/p and o/p loads. (i/p load needed when there is extra load due to wire or extra fanout not captured in input gate cap)
set output_load    [get_attribute [get_lib_pins {"PML30_W_150_1.65_CORE.db/IV110/A"}] capacitance]
set output_load_4x [expr 4 * $output_load]
set_load $output_load_4x [all_outputs] => setting FO=4 load on all o/p pins. (set_load can be used on any net, port)
#NOTE: If we set o/p load to be very high (i.e 1pf), then all o/p ports will get driven by largest INV/BUF as any other logic gates don't have that drive capability to drive such a high load. So, on such ports Isolation buffers may not be needed in PnR flow, as buffers are already there from synthesized netlist (if we do put buffers in PnR flow, then we will have 2 buffers back to back for each port, resulting in area wastage)

global constraints:
-----------
#set_dont_use
set_dont_use PML30_W_150_1.65_CORE.db/LA* => don't use latches from lib
set_dont_use PML30_W_150_1.65_CORE.db/DTB* => don't use D-flops with preseet and clr

#set_dont_touch => prevents specified object (net,instance,etc) from being modified duing optimization.
Ex: set_dont_touch [get_cells {TWA/FF1}] => prevents the specified instance from being modified
Ex: set_dont_touch [get_nets -of_objects [get_cells {TWA/FF1}]] => i/o preserved for that cell.
set_dont_touch scan_inp_iso => prevents module instance from being modified.

B. design constraints: design rule and optimization constraints. For initial synthesis, we only provide env_constraint and not design constraints (as we just need gate mapping for RTL to write our false path file)
----------------
1. design rule constraints: usually provided in .lib. typical constraints are set_max_transition, set_max_fanout, set_max_capacitance. These cosntraints are associated with pins of the cells in lib, but eventually end up constraining nets of design. DC prioritizes these over opt constraints, and tries not to violate them. clk nets and constant nets have design rule fixing disabled by default, scan nets do not. i/p ports of design have max_cap figured out by cells driving i/p port (using set_driving_cell in sdc file), while o/p ports have max_cap figured out by cells driving o/p port (size of cells driving o/p port is picked up based on load on o/p port (using set_load in sdc file). o/p port max_cap is seldom violated because DC picks up right size gate to drive the o/p load. However, i/p port max_cap may be violated if we didn't pick right size buffer to drive heavily loaded pins (as i/p clk pin, reset pin, etc).
NOTE: For bidir pins, it's treated as both i/p and o/p pin, so it has a driver as well as a load. That makes it harder to meet max_cap requirement of external driver if external driving buffer is not chosen properly, while a large cap load is placed on the pin (It may easily meet internal driver max_cap requirement as the tool can size the internal driver appr). It may also fail max_transition, as if max_cap gets violated, then depending on how bad it failed, the external driving buffer may need to extrapolate timing for excess cap load, resulting in max_transition violation. To avoid this, choose appr external driver for bidir pin.
###design rule const:  We don't set any DRC as all these are picked as per .lib

2. opt constraints: opt const for timing provided later during incremental compile.
set_max_area       0

----
#set_fix_multiple_port_nets: sets "fix_multiple_port_nets" attr on the design specified.
#This attribute controls whether compile inserts extra logic into the design to ensure that there are no feedthroughs, or that there are no two output ports connected to the same net at any level of hierarchy. The default is not to add any extra logic into the design to fix such cases. Certain three-state nets cannot be buffered, because this changes the logic functionality of the design.
#-all: insert buffers for o/p directly connected to i/p(-feedthrough), inserts buffers if a driver drives multiple output ports(-outputs) and duplicate logic constants so that constants drive only 1 o/p port
# -buffer_constants: buffers logic constants instead of duplicating them.
set_fix_multiple_port_nets -all -buffer_constants [get_designs *]

#set_isolate_ports: Specifies the ports that are to be isolated from internal fanouts of their driver nets.
#-driver BU140 => BU140 or other size buffer used to isolate. By using -force, we force the driver to be the size specified (i.e BU140 only, no other size allowed), and also force isolation to be done on all ports specified, even if they don't need isolation.
#we don't put isolation cells during synthesis, as we do it during PnR.
#set_isolate_ports -driver BU140 -force [all_inputs]
#set_isolate_ports -driver BU140 -force [all_outputs]

----------------------------
# Uniquify after applying constraints
current_design $DIG_TOP_LEVEL
link
uniquify => NOT necessary, since this step is done as part of compile. Removes multiple-instantiated hierarchy in the current design by creating a unique design for each cell instance. So, if you do get_designs * => it now shows multiple instances of clk_mux with clk_mux_1, clk_mux_2, etc. So, each of these clk_mux_* have the same rtl, but they can now be optimized separately.

#Provide physical info (area, placement, keepout, routing tracks, etc) abt floorplan if in DC-TOPO mode. 3 ways:
1. write_def within ICC, and then import it into DC by using extract_physical_constraints cmd.
ex: extract_physical_constraints {design1.def ... design2.def}
2. write_floorplan cmd in ICC which generates a tcl script, and then read that file using read_floorplan.
ex: read_floorplan -echo criTop.all.fp.tcl => this tcl file is generated by write_floorplan cmd in ICC, and used here in DC.
3. Manually provide physical info. Put these constraints(die area, port locations, macro, keepout, etc) in a tcl file and source it. these constraints are the one that we use in ICC to force the tool to generate desired placement.

##### opt const (speed): clk related info here (set_input_delay, set_output_delay provided during incremental compile)
create_clock -name "spi_clk" -period 50 -waveform     { 2 27 } [get_ports spi_clk] => 20M clk, rising edge at 2ns and falling edge at 27ns.

set_clock_uncertainty 0.5 spi_slk => adds 0.5 units skew to clk to model skew during CTS in PnR.

# generated Clock: NOTE: this cmd sometimes requires the presence of synthesized netlist, as the target pin list may be o/p of flops, etc so, we use this cmd after the initial compile.
create_generated_clock -name "reg_clk" -divide_by 1  -source [get_ports clock_12m] [get_pins clk_rst_gen/pin1] => apply waveform on pin "clk_rst_gen/pin1"

#optional ideal attr => not needed for DC. clk nets are ideal nets by default.
#set_ideal_network -no_propagate {clk1 clk2} => marks a set of ports or pins  in  the  current  design  as sources  of an ideal network. compile command treats all nets, cells, and pins on the transitive fanout of these objects  as ideal (i.e no delay). transition time of the driver is set to 0ns. Propagation  traverses through combinational cells but stops at sequential cells. In  addition  to disabling timing updates and timing optimizations, all cells and nets in the ideal network have the dont_touch attribute  set. "-no_propagate" indicates that the ideal network is not propagated through logic gates (i.e logic gates encountered are treated as non-ideal with non-zero delay). By default, ideal property is propagated thru gates. NOTE: during report_timing, we see transition time on these ports/pins as 0ns, resulting in no "max_transition_time" violations.  
#set_ideal_latency 2 clk1
#set_dont_touch_network [get_clocks *]
#set_propagated_clock [all_clocks]

#set ideal n/w for scan_enable, so that they don't get buffered in DC, will be buffered in PnR
#set_ideal_network -no_propagate {POR_N I_CLK_GEN/POR_N_SYNCED} => NOT needed. POR_N port only goes to 2-3 flops as it gets synced first, then the synced version goes to all flops. We don't set any of these ports to ideal as that will prevent tool from putting buffers on these paths. These paths result in max_cap, max_trnasition viol (not timing viol as async paths aren't checked for timing in DC), so DC will buffer these to prevent those viol. If we do not want to buffer the reset tree in DC, we can use this cmd to prevent buffering in DC, and then buffer it during PnR. However, the sdc file exported to PnR tool should have this cmd removed so that PnR tool can buffer it. Also, no false_path should be set starting from "POR_N_SYNCED" pin as it's a real path. We can set false path starting from "POR_N", but even that's not required

#set_ideal_network -no_propagate I_CLK_GEN/SCANRESET => NOT needed as it feeds in same reset tree.
#set_ideal_network -no_propagate scan_en => this done during scan stitching. Here, scan_en not set to ideal is OK, as this net is not connected to any flop (it's a floating net at this stage, and scan_enable/scan_data pin of all flops is tied to 0 or 1). So, no opt takes place on this net. Later during dft scan stitching step, scan_en gets tied to pin of all flops, that is where we set it to ideal, so that it doesn't get buffered.

# Specify clock gating style => Sets  the  clock-gating  style  for the clock-gate insertion and replacement
#-sequential_cell none | latch => 2 styles. A. latch free ( no latch, just and/or gate, specify none). B. latch based (latch followed by and/or, default)
#-positive_edge_logic {cell list | integrated} => for gating +ve FF inferred from RTL. For latch based, cell list must be AND/NAND (can also specify latch in cell list). For latch-free, cell list must be OR/NOR. integrated => Uses a single special integrated clk gating cell from lib instead  of  the  clock-gating circuitry (i.e latch followed by and/nand). With integrated option, we can say whether enable signal is active low and if clk is inverted within the integrated cell. when using integrated clk gaing cells, setup/hold are specified in lib, so separate -setup/-hold options are not required. Tool identifies clk gating cells in lib by looking for clock_gating_integrated_cell.
For CGP, it's "latch_posedge", and for CGPT, it's "latch_posedge_precontrol".
For CGN, it's "latch_negedge", and for CGNT, it's "latch_negedge_precontrol".
#-negative_edge_logic {cell list} => same as above except that for latch based, cell list must be OR/NOR (can also specify latch in cell list). For latch-free, cell list must be AND/NAND.
#-control_point none | before | after => Final_En = (En | Scan_en). Before or after determines whether to put the OR gate before or after the latch. The  tool  creates  a new  input  port to provide the test signal.  The control points must be hooked up to the design level test_mode  or  scan_enable port using the insert_dft command.
#-control_signal scan_enable | test_mode => Specifies  the test control signal.  If an input port is created and the argument is  scan_enable, the name of the port is determined by the test_scan_enable_port_naming_style variable, while for test_mode, the name of the port is determined  by  the  test_mode_port_naming_style  variable. test_mode signal is the one that is asserted throughout scan testing, while scan_enable signal is asserted only during scan shifting (All FFs have scan_enable  the select line of their internal mux). Ususally it's set to scan_enable.

set_clock_gating_style -control_point       before \
                       -control_signal      scan_enable \
                       -positive_edge_logic integrated \
                       -negative_edge_logic integrated

3. synthesize/compile design (initial stage):


#2 types of compile strategy:
A. top-down: top level design and all it's subdesigns are compiled together. Takes care of interblock dependencies, but not practical for large designs, since all designs must reside in memory at same time.
B. Bottom-up: individual subdesigns are constrained and compiled separately. After successful compilation, the designs are assigned the dont_touch attribute to prevent further changes to them during subsequent compile phases. Then the compiled subdesigns are assembled to compose the designs of the next higher level of the hierarchy, and those designs are compiled iteratively until the top level design is synthesized.

# Initial Compile
#-scan: replaces normal flops with scan version. connects scan pins to tiehi or tielo (doesn't do actual stitching of scan pins here)
#DC uses design rule cost and opt cost to determine cost fn. use -no_design_rule to disable design rule cost (max_tran, max_fo, etc) and -only_design_rule to disable opt rule cost (delay, power, area, etc). hold violations are fixed only if set_fix_hold and set_min_delay is specified for design. otherwise, only max_delay (not min_delay) is part of cost fn. We can reorder priority of design/opt constraints to get new cost fn by using set_cost_priority.
#-gate_clock: enables clk gating opt as per options set by set_clock_gating_style cmd. clk gates inserted are wrapped inside a clk_gating module which has CG* cell.
#-no_autoungroup: all user hier are preserved (i.e ungrouping is disabled). Required, else ungrouping removes hier boundaries and flattens the netlist to optimize across modules. Without this, some hierarchies were being flattened to implement clock gating
compile_ultra -scan -no_design_rule -gate_clock -no_autoungroup

#check_design => checks synthesized design for consistency.
#check_timing
#report_clocks

# reports after compile
set rptfilename [format "%s%s" $mspd_rpt_path $DIG_TOP_LEVEL.initial_area.rpt ]
#redirect => Redirects the output of a command to a file. -append appends o/p to target
redirect $rptfilename {echo "digtop compile.tcl run : [date]"}
redirect -append $rptfilename {report_area -hier} => reports total area for combo & non-combo logic. also reports total no of cells at top level of design (in module digtop, counting 1 for each sub-module and 1 for each stdcell), no. of I/O ports and no of nets (total no. of wire in digtop). -hier reports it for all hier modules. area is taken from area in .lib file (RAM/ROM IP usually have incorrect area, as they aren' scaled in terms of NAND2 equiv size)
redirect -append $rptfilename {report_reference -hier} => reports all references in current instance (if current inst set) or current design (default). It reports all instances in top level module of current design, which has subdesigns(as other modules), as well as some std cells connecting these modules together). -hierarchy option goes thru the hier of sub modules and reports all leaf cell refrences.

#NOTE: we can use above 2 cmds for any netlist to report total number of gates. For ex, to find out total gates in routed netlist, do:
read_verilog ./DIGTOP_routed.v
current_design DIG_TOP  
report_area -hierarchy

#NOTE: no constraints of any sort (i/p, o/p delay, false paths, etc) are applied above, as we just want to get a verilog netlist mapped from RTL. Even clk wasn't required to be declared, as we aren't running any timing on this netlist.
# Initial Compile
-----------------------------------------------------------------------------
# Clean up
# removes unconnected ports from a list of cells or instances, perform link and uniquify before this command
# -blast_buses -> if a bus has an unconnected port, the bus is removed.
#find => Finds a design or library object. -hierarrchy means at any hierarchy of design. Ex: remove_unconnected_ports -blast_buses find( -hierarchy cell, "*")
remove_unconnected_ports -blast_buses [find -hierarchy cell *]

#to ensure name consisitency b/w netlist and other layout tools => define_name_rules and change_names cmd used to convert names. define_name_rules defines our own rules, and change_names applies the change to the netlist for the particular rule. There are already std rules for verilog/vhdl. Sometimes, we keep these cmds in .synopsys_dc.setup, so that they are always applied.
# change_names of ports, cells, and nets in a design. -hierarchy Specifies that all names in the design hierarchy are to be modified. (report_name_rules shows rules_names are sverilog,verilog,verilog_1995 and vhdl). This cmd should always be applied before writing netlist, as naming in the design database file is not Verilog or VHDL compliant.
#report_names => shows effects of change_names w/o making the changes.
change_names -rules verilog -hierarchy => std verilog rule applied to all hier of netlist.

#define_name_rules <rule_name> -map { {{string_to_be_replaced, new_replaced_string}} } -type cell
define_name_rules     reduce_underscores   -map { {{"_$", ""}, {"^_", ""}, {"__", "_"}} } => names a rule which removes trailing underscore, starting underscore and replaces double underscore with a single underscore.
change_names -rules   reduce_underscores   -hierarchy => rule applied

define_name_rules    reduce_case_sensitive   -case_insensitive
change_names -rules  reduce_case_sensitive   -hierarchy -verbose

#not sure ???
apply_mspd_name_rules_noam

------------------------------------------------------------------------------
#DC doesn't automatically saves designs loaded in memory. So, save design before exiting.
#save design using write: saves in .ddc, .v, .vhdl format
#save design using write_milkyway: writes to a milkyway database.
write -format ddc     -hierarchy -output ./netlist/${DIG_TOP_LEVEL}_initial.ddc \ => preferred, .ddc is internal database format
write -format verilog -hierarchy -output ./netlist/${DIG_TOP_LEVEL}_initial.v => verilog format (also supports systemverilog (svim) and VHDL format o/p.

4. synthesize/compile design (incremental stage):


# Apply constraints for func mode, when scan exists
source tcl/case_analysis.tcl => specify which scan related pins need to be tied for func mode. It has these stmt:
#set_case_analysis => Sets  constant  or transitional values to a list of pins or ports and prop thru logic for use by the timing engine. The specified constants or transitional values are valid only during timing analysis and do not alter the  netlist.

set_case_analysis 0 scan_mode_in => we force Scan_mode to 0, as we want to see timing paths b/w diff clocks. false paths take care of bogus paths b/w clock domains. forcing it to 1 will cause all clocks to be the same clock (i.e scan_clk), so, we won't be able to see inter clock paths. If we don't force scan_mode at all, then both scan_mode=0 and scan_mode=1 timing analysis is run.
#set_case_analysis 0 scan_en_in => we should NOT force this to 0, as we want timing for scan shift paths also.

# all constraints for all i/o pins here (opt constraints)
source tcl/constraints.tcl => Put all i/p o/p delays here

#we may want to leave setting i/p delays, so that in PT we can see them as "endpoints not constrained" warning. This helps us to see which all are pins which are going thru meta flop.
set_input_delay 0.2 -clock clk1 [remove_from_collection [all_inputs] [get_port {clk1}]] => sets 0.2 unit delay on all i/p pins (except clk1 port) relative to clk1.
sET_output_delay 0.4 -clock clk1 [remove_from_collection [all_outputs] [get_port {spi_miso}]] => 0.4 delay for all o/p ports except spi_miso

#create generated clocks here since it may refer to pins of flops, etc which may only be present in synthesized netlist
source tcl/gen_clocks.tcl
#all clks treated as div by 4 clk, since very large divided clks will cause longer run time.
#we don't have long delay paths, so even if we define very fast clks as div by 4 clk, we should not see any failing paths for setup. It will screw up hold time calc, as PT treats hold time based on no of clk edges that lies in b/w one setup path.
# Div 4 clk
create_generated_clock -name "clk_1600k"        -divide_by 4  -source [get_ports clkosc] [get_pins Iclk_rst_gen/clk_count_reg_1/Q]
create_generated_clock -name "clk_100k"         -divide_by 4  -source [get_ports clkosc] [get_pins Iclk_rst_gen/clk_count_reg_5/Q]

#ram latch clock (since clk signal, generated as a pulse, may be o/p of flop). We can do div by 1 also.
create_generated_clock -name "clk_latch_reg"    -divide_by 2  -source [get_ports clkosc] [get_pins Iregfile/wr_strobe_spi_sync_reg/Q]

#gated clocks
#create_generated_clock -name "spi_clk_gated"   -divide_by 1  -source [get_ports spi_clk]   [get_pins spi/spi_clk_gate/Q]

# Propagate clocks. NOTE: we don't propagate clk, since we don't have any buffers in DC netlist. clks treated as ideal
#set_propagated_clock [all_clocks]

# Apply false-paths: In false paths, we define false paths
# NOTE: false paths only related to setup timing are checked here. If log report indicates an ERROR in any line, it doesn't take any false path from that line into consideration (i.e it doesn't expand the wildcards to choose paths that match and drop paths that don't exist, however PnR tool does expand the wildcards and choose paths that match and drop paths that don't exist, without reporting any error, so be careful). Hold, async, clk-gating paths aren't checked (unconstrained paths) durng synthesis, however they are checked during PnR. so, we might have to add extra false paths when running PnR. These added paths may give ERROR when synthesis is re run, however we can just ignore such errors. Or instead of adding these extra false paths in DC, we can create a new false path file in PnR, and add this file to existing false path file from DC.
#set_disable_timing [get_cells {test_mode_dmux/*}]

source -echo tcl/false_paths.tcl
#set_false_path -from {POR_N POR_N_SYNCED SCAN_RESET} => Not needed as these cause recovery/removal violations which DC doesn't check for. Only scan_en pin needs to be set to false_path as it causes real timing violation due to large transition time. However if scan_en pin is set to ideal_network, then fasle path not needed for scan_en as transition time=0ns.

# Apply multi-cycle paths
source tcl/multicycle_paths.tcl

# Incremental Compile with high effort
source tcl/compile.tcl
This has:
#here we do design rule and opt rule fixing
#-incremental performs only gate level opt and not logic level opt. Resulting design is same or better than original.
#-map_effort high => default effort is medium. high effort causes restructuring and remapping the logic around critical paths. It changes the starting point, so that local minima problem is reduced. It goes to the extreme, so is very CPU intensive.
compile_ultra  -incremental -scan -area_high_effort_script -gate_clock -no_autoungroup

5. generate reports:


#generate reports:
report_area, report_reference => in area.rpt
report_timing -delay max -max_paths 500 => report setup in max_timing.rpt (this has timing with scan_mode=0, so has all interclock paths)
report_timing -delay min -max_paths 500 => report hold in min_timing.rpt => this report should be clean if no clk_uncertainty is defined. This is because c2q delay for flops is greater than hold requirement of flops, so with ideal clock (no clk delays/buffering anywhere), all flops will pass holdtime req.
check_design, report_clock_gating, report_clocks, check_timing, report_disable_timing => in compile.rpt
report_clock_gating => reports no of registers clk gated vs non-clk gated. It also shows how many CG* cells got added to do clk gating.
report_constraint => lists each constraint, and whether met/violated, also max delay and min delay cost for all path groups. -all_violators only reports violating constraints.

#cleanup netlist and then write netlist
cleanup as done in compile_initial (remove_unonnected_ports, define_name_rules, change_names)
write -format verilog -hierarchy -output ./netlist/digtop.v

6. Insert Scan:


#SCAN: DFT compiler (separate license) is invoked for scan. DFTMAX license is needed for scan compression.
#Insert Scan
set_ideal_network [get_ports scan_en_in] => scan_en_in pin is used during scan shifting (defined in setup.tcl). By setting it as ideal, DFT compiler doesn't buffer the signal as all cells/net on this n/w have "dont_touch" attr set. To buffer it, put driving cell using set_driving_cell on this port, so that DFT Compiler can buffer it appr. In DC, we don't buffer this signal, as we buffer it during PnR. NOTE: if scan_en_in is internal net, we should do this:
set_ideal_network -no_propagate {u_DIA_DIG/u_DMUX_DIG/U5/Y} => We should choose gate o/p pin and not the o/p scan_en net ({u_DIA_DIG/u_DMUX_DIG/scan_en}). Else ideal network is not applied to gate o/p, so that gate has large transition time, so tons of viols.

#set_false_path -from scan_en_in => setting any path flowing thru Scan_en and ending at clk as false. Since we have set scan_en as ideal n/w, we don't need false path for this as transition time=0ns. However if ideal n/w is not set for scan_en, then this takes care of cases where scan_en i/p delay causes any setup/hold violation at clk. If we don't do this, we see paths with scan_en failing as they have high FO and high cap, so large delay and large transition time.  We can NOT take care of this by setting small max_delay for setup and large min_delay for hold, because the high FO will cause it to fail timing nonetheless. NOTE: this is not equiv to setting case analysis for scan_en=0, as that removes scan paths (flop to flop) from any timing analysis. We want to see timing for both scan/non-scan paths.
#IMP NOTE: both false_path and ideal_network for scan_en pin should be removed in EDI (if using sdc constraints generated from DC), since scan_en path is real, as we have clk toggling within a cycle of scan_en toggling in Tetramax patterns, so it better meet timing. We need to run gate sims on teramax patterns to make sure we meet timing.

source tcl/insert_dft.tcl => this file has following lines in it:
#sets all scan configuration details as shown below:
#set test timing variables. leave these at default values if Tetramax is used to gen test patterns.
#set test_default_delay 0
#set test_default_bidir_delay 0
#set test_default_strobe 40
#set test_default_period 100 => default scan period is 10MHz.

######define test protocol using set_dft_signal cmd.
#set_dft_signal=>Specifies the DFT signal types for DRC and DFT insertion.
#-view existing_dft | spec => existing_dft implies that the  specification  refers  to  the existing  usage  of  a port, while spec (the default value) implies that the specification refers to ports that the tool must use during DFT insertion. spec view is prescriptive and specifies actions that must be taken. It indicates that signal n/w doesn't yet exist and insert_dft cmd must add it. An example of this is ScanEn signal (even though ScanEn port exists, the signal n/w is not there, so it's prescriptive). existing_dft view is descriptive and describes an existing signal n/w. An example is system clk that is used as Scan Clk (here clk n/w already exists since system clk is used as scan clk, so descriptive). So, scan_clk, reset, scan_mode are existing_dft as n/w is already there, but SDI, SDO, ScanEn are spec as that n/w needs to be built. view is used for many DFT cmds as set_dft_signal and set_scan_path.
Ex: set_dft_signal -view existing_dft -port A -type ScanEnable => when working with dft inserted design, indicates that port A is used as scan enable. indicates that ScanEnable n/w does exist and should be used. This is NOT true in most designs as n/w never exists for scan_en pin. In this case, tool will create a new port "A" and connect it to scan_en pin of all flops
Ex: set_dft_signal -view spec -port A -type ScanEnable => when preparing a design for dft insertion, specifies that port A  is used as scan enable. indicates that ScanEnable n/w doesn't exist yet. This is true for most designs, so use this for scan_en pin.
#-type specifies signal type, as Reset, constant, SDI, SDO, ScanEn, TestData, TestMode. Constant is a continuously applied value to a port.
#-active_state => Specifies the active states for the following signal types: ScanEnable, Reset, constant, TestMode, etc. active sense high or low

#define clocks, async set/reset, SDI, SDO, SCAN_EN and SCAN_MODE. We don't need to define SCAN_CLK as SCAN_MODE forces clock to scan clk (mux chooses b/w SCAN_CLK or FUNC_CLK), and it is traced all the way to the i/p port (as later during create_test_protocol, we say -infer_clock). We don't define async set/reset as we force them to 0, when scan_mode=1 (in RTL itself).
set_dft_signal -view existing_dft -port scan_mode_in -type Constant -active_state 1  => scan_mode_in pin is used during scan mode and is high throughout scan (defined in setup.tcl). existing_dft states that scan_mode n/w exists so the tool doesn't need to do anything to add the n/w.
set_dft_signal -view spec  -port  spi_mosi       -type ScanDataIn => SDI is spi_mosi
set_dft_signal -view spec  -port  spi_miso       -type ScanDataOut => SDO is spi_miso
set_dft_signal -view spec  -port  scan_en_in     -type ScanEnable  -active_state 1 => SE (for shifting during scan) is scan_en_in, and it needs to be "1" for shifting to take place. If scan_en is an internal pin, then we do:
 set_dft_signal -view spec   -hookup_pin {u_DIG_sub/scan_enable} -type ScanEnable  -active_state 1 => pin may be port of sub-module or o/p pin of a gate as "u_DIG_sub/u_sub2/U5/Y". Preferred to use port of sub-module as gate name may change every time tool is run.
#NOTE: in all cmds above, if above scan ports don't exist, then tool creates new ports.

#if needed, set_dft_signal for scan clk, scan reset and scanmode => NOTE these are "exist" view and not "spec" view
set_dft_signal -view exist -type ScanClock   -port SPI_SCK -timing [list 10 [expr ($SCANCLK_PERIOD/2)+10]] => changed freq of scan clk, so that design runs slower
set_dft_signal -view exist -type Constant    -port SCANRESET      -active_state 1
set_dft_signal -view exist -type Constant    -hookup_pin {u_SPT_DIG/auto/Scan_Mode_reg/Q}  -active_state 1 =>  Preferred to use port of sub-module for hookup_pin as in extreme case, flop name may change every time tool is run.

####do all scan related configuration.
#set_scan_element: excludes seq cells from scan insertion, reducing fault coverage
set_scan_element false [find cell test_mode/scan_mode_out_reg] => default is true which means all  nonviolated  sequential  cells  are replaced with equivalent scan cells. when false, no scan replacement done on objects (objects may be cells[as FF/LAT], hier cells, lib cells, ref, design). Sequential cells violated by dft_drc are not replaced by equivalent scan cells, regardless of their scan_element attribute values.

# Specify scan style: 4 styles: multiplexed_flip_flop, clocked_scan, lssd, scan_enabled_lssd. set_scan_configuration or test_default_scan_style can be used to set scan style.
#set_scan_configuration -style [multiplexed_flip_flop | clocked_scan | lssd |  aux_clock_lssd  | combinational | none] => By default, insert_dft uses the scan style value specified by environment variable test_default_scan_style in your .synopsys_dc.setup file
set_scan_configuration -style multiplexed_flip_flop

#count
set_scan_configuration -chain_count 1 => number of chains that insert_dft is to build. Here's it's 1. If not specified, insert_dft builds the minimum  number of scan chains consistent with clock mixing constraints.

#set_scan_configuration -clock_mixing [no_mix | mix_edges | mix_clocks | mix_clocks_not_edges] => Specifies  whether  insert_dft  can include cells from different clock domains in the same scan chain.
no_mix                 The default; cells must be clocked by the same edge of the same clock.
mix_edges              Cells must be clocked by the same clock, but the clock edges can be different.
mix_clocks_not_edges   Cells must be clocked by the same clock edge, but the clocks can be different.
mix_clocks             Cells can be clocked by different clocks and different clock edges.

set_scan_configuration -clock_mixing mix_clocks => we use mix_clocks even though during scan_mode, we have only 1 clk. Reason is that lockup element can only be added if mix_clocks option is used.

#lockup
set_scan_configuration -add_lockup true => Inserts  lockup  latches (synchronization element) between clock domain  boundaries  on  scan  chains,  when  set  to  true  (the default). If the scan specification  does  not  mix clocks on chains, insert_dft ignores this option.

#lockup_type [latch | flip_flop] => The default lock-up type is a level-sensitive latch.  If you  choose  flip_flop  as  the  lock-up type, an edge-triggered flip-flop is used as  the  synchronization  element.

#set_scan_configuration -internal_clocks [single|none|multi] => An internal clock is defined as an internal signal driven  by  a multiplexer (or multiple input gate) output pin (excludes clk gating cells). Applies  only  to  the  multiplexed flip-flop scan style, and is ignored for other scan styles.  It's used to avoid problems when placing gating logic on the clock lines (which might result in hold issues).
none (the default) - insert_dft does not treat internal clocks as  separate  clocks.   This  is  the default value for internal_clocks option.
single  -  insert_dft treats any internal clocks in the design as separate clocks for the purpose of scan chain architecting.The single value stops at the first buffer or inverter driving the flip-flops clock.
multi - insert_dft treats any internal clocks in the design as separate  clocks  for  the purpose of scan chain architecting. The multi value jumps over any buffers and inverters, stopping at the first multi-input gate driving the flip-flops clock.

set_scan_configuration -internal_clocks multi => for our design, we set it to multi.

#set_scan_link scan_link_name [Wire | Lockup] => Declares  a  scan link for the current design.  Scan links connect scan cells, scan segments, and scan ports within scan chains.  DFT  Compiler supports scan links that are implemented as wires (type Wire) and scanout lock-up latches (type Lockup).
set_scan_link LOCKUP Lockup => we name the scanlink LOCKUP

#set_scan_path specifies scan path.
set_scan_path chain1 => Specifies a name for the scan chain, here it's called chain1

#set_scan_state [unknown|test_ready|scan_existing] => sets the scan state status for the current design. Use this command only on a design that has  been  scan-replaced  using,for example, compile -scan, so that the Q ouputs of scan flip-flops are connected to the scan inputs and the scan enable pins are connected  to logic  zero.   If  there  are  nonscan  elements  in  the  design,  use set_scan_element false to identify them.
unknown=>the  scan  state  of  the  design  is  unknown,
test_ready=>the design is scan-replaced,
scan_existing=>the design is scan-inserted.

set_scan_state test_ready

--- End of scan_constriants.tcl file.

###### configure your design for scan testing by generating test protocol using create_test_protocol. Test protocol files are written in spf (STIL procedure file) which are then input to pattern generation tools as TetraMax, Encounter Test to generate pattern file in STIL format.
#create_test_protocol [-infer_asynch, -infer_clock, -capture_procedure single_clock | multi_clock] => creates a test protocol for the current design based on user specifications which were issued prior to  running  this command.  The   specifications   were  made  using  commands  such  as set_dft_signal, etc. The  create_test_protocol command should be executed before running the dft_drc command because design rule checking requires a test  protocol.
-infer_asynch => Infers asynchronous set and reset signals in the design, and places them at off state  during scan shifting.
-infer_clock => Infers test clock pins from the design, and pulses them during scan shifting.
-capture_procedure [single_clock | multi_clock] => Specifies the capture procedure type.  The multi_clock type creates a protocol file that uses generic  capture  procedures  for all  capture  clocks.   The single_clock type creates a protocol file that uses the legacy 3-vector capture  procedures  for  all capture clocks. The default value is multi_clock.

create_test_protocol -infer_clock => -infer_clock not needed if scan_clock defined above.

####DFT DRC Checking
dft_drc checks for these 3 violations:
--
1. Violations That Prevent Scan Insertion: caused due to 3 cond:
 A. FF clk is uncontrollable. => clk at FF should toggle due to test clk toggling, and clk at FF shoudl be in known state at time=0 (sometimes clk gating causes this issue)
 B. latch is enabled at the beginning of the clock cycle C.
 C. async controls of registers are uncontrollable or are held active. => if set/reset of FF/latch can't be disabled by PI of design.

2. Violations That Prevent Data Capture: caused due to these:
 A. clk used as data i/p to FF,
 B. o/p of black box feeds in clk of reg (clk may or may not fire depending on logic),
 C. src reg launch before dest reg capture,
 D. registered clk gating ckt (caused due to clk gating implemented wrongly)
 E. 3 state contention
 F. clk feeding multiple i/p of same reg (i.e. clk signal feeding into clk pin and async set/reset)

3. Violations That Reduce Fault Coverage:
 A. combo feedback loops (i.e if loops are used as a latch, replace them with a latch)
 B. Clocks That Interact With Register Input
 C. Multiple Clocks That Feed Into Latches and FF. Latches should be transparent, and latches must be enabled by one clock or by a clock ANDed with data derived from sources other than that clock.
 D. black boxes: logic surrounding BB is unobservable or uncontrollable.
 ---
#dft_drc [-pre_dft|-verbose|-coverage_estimate|-sample percentage] => checks the current design against the test design rules of the scan test implementation specified  by  the  set_scan_configuration -style  command. If design rule violations are found, the appropriate messages are  generated. Perform  test  design  rule  checking on a design before performing any other DFT Compiler operations, such as insert_dft, and after creating a valid test protocol.
-pre_dft => Specifies  that  only  pre-DFT  rules (D rules) are checked. By default, for scan-routed designs, post-DFT  rules  are checked; otherwise pre-DFT rules are checked.
-verbose => Controls  the  amount  of detail when displaying violations. every violation instance is displayed.
-coverage_estimate => Generates a test coverage estimate at the  end  of  design  rule checking.
-sample percentage =>  Specifies a sample percent of faults to be considered when estimating test coverage.

dft_drc -verbose => check for violations here, before proceeding. shows black box violations for macro, non-scan flop violation because of set_scan_element being set to false, non-scan flops present in design (flops didn't get replaced by their scan equiv because of set_scan_element being set to false or other issues ). It shows final scan flops and non-scan flops.

#preview_dft => Previews,  but does not implement, scan style, the test points, scan chains, and on-chip clocking control logic to be added  to  the  current design. The command first generates information on the scan  architecture  that  will be implemented.  In the case of a DFTMAX insertion, preview_dft provides information about the  compressor  being  created,and for basic scan, the specific chain information for the design. Next,  the command generates and displays a scan chain design that satisfies scan specifications on the current  design. This design is exactly the scan chain design that is presented to the insert_dft command for synthesis.
preview_dft -show all => Reports  information  for all objects in scan chain design.
preview_dft -test_points all => Reports all test points information, in addition to the  summary report  the preview_dft command produces by default.  The information displayed includes names assigned  to  the  test  points,locations  of  violations  being fixed, names of test mode tags, logic states that enable  the  test  mode,  and  names  of  data sources or sinks for the test points.

# Insert Scan and build the scan chain.
insert_dft => adds internal-scan or boundary-scan circuitry to the  current design. First, the  command  populates  a  flattened  representation  of  the  entire  design. By default, insert_dft performs only scan insertion and routing. Next,  insert_dft architects scan chains into the design. By default, insert_dft constructs as many scan chains as there are clocks  and  edges.   By   setting   the -clock_mixing option, we can control scan chains created. Scan cells are ordered on scan chains based on some criteria. Then the command applies a scan-equivalence process to all cells. The insert_dft command then adds generic disabling logic  where  necessary.   It  finds  and  gates all pins that do not hold the values they require during scan shift.Having  disabled  three-state buses and configured bidirectional ports,insert_dft builds the scan chains. It identifies scan_in and scan_out ports. Finally,  insert_dft  routes  global  signals (including either or both scan enable and test clocks) and applies a default  technology  mapping to  all new generic logic (including disabling logic and multiplexers). It  introduces  dedicated  test  clocks  for  clocked_scan,  lssd,  and aux_clock_lssd scan styles. Typically, at this point, the insert_dft command has  violated  compile design  rules  and  constraints  and now begins minimizing these violations, and optimizing the design.
The insert_dft command automatically updates the test protocol after inserting scan circuitry into the design, and dft_drc can be executed  afterward without rerunning create_test_protocol.

# DFT DRC Checking after insertion
write_test_protocol -output digtop_scan.spf => Writes a test protocol file to file_name specified.
dft_drc -verbose -coverage_estimate => verbose rpt with coverage post scan to make sure no violations. Coverage reported here is inferior than one reported by TetraMax/ET as those are more accurate. Also, scan_reset pin if present is not considered in coverage here, as we never provided scan_reset pin info to the tool. It's just tied to inactive state here.
#test coverage = detected_faults / (total_faults - undetectable_faults) => This is the important one to look at
#fault coverage = detected_faults / (total_faults) => this is always lower than test_coverage as UD faults not included. Not so important one to look at.

#report on scan structure:
report_scan_chain > reports/scan.rpt
report_scan_path -view existing_dft -chain all >> reports/scan.rpt
report_scan_path -view existing_dft -cell all >> reports/scan.rpt

# reports after scan insertion => redirect cmd used to create scan.area/max_timing/min_timing/compile rpts in reports/scan.compile.rpt/timing.rpt files. Then cleanup done, and verilog file wriiten in *_scan.v file.

#we don't run inc compile after scan, as scan cells are only getting stitched, so each Q pin sees a little bit of extra load due to SD pin of next flop. That little extra load causes <0.1ns timing change, so scan timing and func timing are almost same (scan mode is set to 0 for both, scan_enable/shift_enable is not forced). Sometimes, wire from Q to SDI may be significant because may be the next flop in chain is in another block very far away, resulting in large timing violation on such paths in DC (due to large transition time). When we see such paths in DC, we should ignore them as PnR tool will buffer and fix it. NOTE: this scan timing is different that scan timing in PT, as scan timing in PT reflects timing in scan_mode=1. We can run such timing in DC too (by setting scan_mode=1, defining single scan_clk, and setting all i/o delays wrt scan_clk). However, we'll only see hold violations here mostly related to scan_shift_en paths (setup path failures would mostly be same as those of functional paths).

#NOTE: dft compiler adds a mux whenever a functional pin is used as SDO pin. Select pin of mux is tied to ScanEnable pin. "0" input is functional o/p, while "1" i/p is connected to o/p pin of last scan chain. That's why after routing scan chains, we see extra mux in digtop.scan.v compared to digtop.v. We need this as functional flop and SDO flop may not be same flop. compiler may decide to have sdo_out from a different flop than func pin flop. If SDO pin of last scan chain is connected directly to func o/p port, then this mux is not reqd.

-----------------------------------------------------------------
# Write out SDC (synopsys design constraints) script file in functional mode. This script  contains  commands  that can  be  used  with  PrimeTime  or  with  Design Compiler. This sdc file combines all constraints file (user or auto generated) in func mode and so is used in AutoRoute during func mode.
write_sdc sdc/func_constraints.sdc

#count total instances in DC netlist
/home/kagrawal/scripts/count_instances_EDI.tcl => reports all gates in reports/instance_count.rpt

#use exit or quit
exit

#Final log file is in logs/top.log. Lok in this file for any errors/warning.
#Final reports: are in reports dir. Look in
#digtop.after_constrain.rpt => all false path, other constraint errors.
#digtop.compile/area/max/min for reports with no scan.
#digtop.scan.compile/area/max/min for reports with scan.

*******************************************
path groups: Look in PT notes (manually written ones) for more details.
----------
by default, DC/PT group paths based on the clock controlling the endpoint (all paths not associated with a clock are in the default path group). We'll see Path Group with "clock_name" in timing reports.

#control opt of paths: We can create our own path groups so that DC can optimize chosen critical paths.
group_path -name group3 -from in3 -to FF1/D -weight 2.5 => creates group3 path from i/p in3 to FF, and assigns a weight of 2.5 to this path group. default weight is 1 for all paths in a path group. weight can range from 0 to 100.

#opt near critical path: by default, only path with WNS is opt. but by specifying critical range, DC can opt all paths that are within that range.
group_path -critical_range 3 => opt all paths within 3 units of WNS (i.e if WNS = -15, then paths with -12ns and worse are all opt). can also use "set_critical_range 3.0 $current_design".

#opt all paths: create path group for each end point. then DC opt each path group.
set endpoints [add_to_collection [all_outputs] [all_registers -data_pins]] => all o/p ports and D pins of all FF added.
foreach_in_collection endpt $endpoints {
 set pin [get_object_name $endpt]
 group_path -name $pin -to $pin
}

---------------------------
#useful cmds:

#To remove design from DC mem, we can do this (instead of closing and opening DC)
dc_shell> remove_design -all

#Retarting dc shell again. We can read in previous .ddc file generated by using read_ddc cmd. This is helpful when we close dc-shell, but want to open previous design again.
dc_shell> read_ddc netlist/digtop_scan.ddc

#to remove design from dc_shell. can be used once design has been saved, so that we can start a new run without exiting dc_shell
dc_shell> remove_design -all => removes current design as well as all subdesigns from memory

#reporting any net connectivity
report_net -conn -v -nosplit net1 => reports (v for verbose, nosplit to get all in one line) all pins connected to the net and detailed report of cap. useful for High FO nets.

#reporting Fanout for all nets above a certain threhold
report_net_fanout -v -threshold 100 => reports (v for verbose) all nets with FO > 100

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