Spyglass

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.