VC Spyglass
- Details
- Last Updated: Thursday, 08 February 2024 21:36
- Published: Tuesday, 19 December 2023 10:37
- Hits: 893
VC (Verification compiler) Static Spyglass
This is the newer version of Spyglass (as of 2022) which is integrated under Synopsys VC platform. It has native SDC support, with DC/PT cmds supported in VC.
Running VC Spyglass (SG) standalone:
VC SPYGLASS is usually installed in a path like this: /project/tools/synopsys/.../ => We'll refer to this as "$VC_STATIC_HOME"
VC spyglass invoked by typing full path as $VC_STATIC_HOME/bin/vc_static_shell or "vc_static_shell" or "vc_static_shell -gui". The shell version (no gui) brings up "vc_static_shell" where we can enter spyglass cmds. "gui_start" on shell also brings up the gui. Tcl 8.7 is supported in sg_shell.
vc_ststaic_shell -f input.tcl => This runs VC spyglass with script provided. We provide all SG cmds as well as tcl cmds in input.tcl.
Inputs/Outputs to VC SG: VC static shell is used to take input cmds and generate output reports. Verdi is used to navigate RTL, view waveforms, etc, so it's lot comfortable for folks used to Verdi Gui.
- Inputs: VC SG takes input as RTL/netlist and stdcell .lib files (if netlist provided, or if RTL contains stdcells instantiated, only then are .lib files needed). All inputs are provided in std tcl format.
- Project file => .prj files are translated to tcl file in VC SG.
- Constraints => .tcl file. These are std SDC constraints as well as additional non SDC cmds from DC/PT. New cmds related to reset also added. See next section.
- Waiver files => object based tcl files. No more .awl/.swl waiver 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.
VC SG CDC Script
Below is a sample CDC script to run the SG CDC tool. This file is divided in 3 sections => design constraint setup, cdc check and Analyze results.
First invoke the tool and then run the below script (setup.tcl).
- design constraints and settings:
- Since VC SG supports al 3 checks (lint, CDC, RDC), we select which to enable
- #set_app_var enable_lint true; ## enable lint
- set_app_var enable_cdc true; ## enable cdc
- #set_app_var enable_rdc true; ## enable rdc
- set_app_var enable_resetless_analysis true #set cdc var for resetless analysis
- ## read design
- set_app_var search_path <directory_list>; ## define search order of source directories
- set link_library <library_list> ; ## list db technology libraries
- set_app_var vsi_dwroot <path_to_compiled_DW_library>
- read_file -top test <list_of_source_files>; ## this cmd does both analyze and elaborate in single step. Or we can do in 2 steps:
- analyze -format verilog <source_file_list> -vcs {-work WORK -sv=2005 -error=noMPD}
- elaborate <top_module >; ## build and synthesize top design
- ## configure cdc => This says how do we want to run the checker, i.e for CDC, do we want to check for synchronizers, input/output ports, etc.
- configure_unconstrained_ports ……; ## clocks for unconstrained bbox ports
- configure_cdc_nff_sync ……; ## control sync schemes
- configure_cdc_data_sync ……; ## data sync schemes
- configure_cdc_asyncrst_nff_sync ……; ## asynchronous reset control sync schemes
- ## read cdc constraints. SDC cmd format shown later.
- read_sdc common_constraints.sdc ; read_sdc cdc_constraints.sdc ; ## read multiple constraint file
- Since VC SG supports al 3 checks (lint, CDC, RDC), we select which to enable
- Run CDC checks
- #check_lint => runs lint checks
- #check_rdc => runs rdc checks
- check_cdc -type setup|sync|struct. Run each one in separate step
- check_cdc -type setup => Checks for proper clock, reset setup. All setup issues should be resolved before performing other cdc checks. It does following checks:
- SDC: sanity checks SDC/Tcl constraints for CDC
- CLKPROP: Propagates clocks and checks resulting clock structures for CDC
- RESET: Propagates resets and checks resulting reset structures for CDC
- check_cdc -type integ => Checks clock and reset integrity. Ensures that the clocks and resets are properly defined and are free of glitches, race conditions, and other hazards.
- check_cdc -type sync => Checks for proper CDC path synchronization (control, data and async reset CDC paths).
- The 3 configure_cdc_*_sync cmds in "settings" stage above set these cdc checks
- check_cdc -type struct => Checks sync, correlation (or convergence) and glitch. It runs after CDC crossings have been identified.
- check_cdc -type setup => Checks for proper clock, reset setup. All setup issues should be resolved before performing other cdc checks. It does following checks:
- Report Results
- #report_violations => This can be used to report viols for all 3 checks => lint, cdc and rdc. -app {cdc} or -app {rdc} or -app {lint} will report only for that check.
- report_cdc => type -help to get options to use. Reports cdc viols only.
- report_cdc -verbose -limit 0 -file viol.rpt => report all viols and dump into the file viol.rpt. -limit limits viols to be reported to that number. Without any options, report_cdc reports summary of all viols.
- waive_cdc => type -help to get options to use. Options almost same as report_cdc above. -filter option used more often here to waive viols based on certain names. Never set waiver by tag ID (i.e -id). IDs change from run to run
- waive_cdc -stage sync -tag SYNCCDC_UNSYNC_NOSCHEME -filter "SrcObject =~t1/Q && DstObject =~t2/Q"
Type "quit" to quit the tool
Hierarchical flow: Here we run CDc on each block, and then generate an abstract model for each block. That model contains all necessary CDC info, that can be used to identify CDC issues at top level, by just using the Abstracted model of blocks. This saves run time at top level for big designs, which have large blocks in them. We run CDC at top level, in similar way as at block level, except that block levels are not RTL anymore, but Abstract models.
SDC/non-SDC commands for use in CDC constraints:
- SDC cmds => These are std SDC cmds. no difference in syntax.
- create_clock / create_generated_clock => for creating clk and generated clks
- create_clock -name VIRTUAL_CLOCK_0 -period 2.0 => This defines a clock with no ports assigned, implying it's a virtual clock with a period of 2ns, or freq=500MHz. This cmd is used very often in CDC/RDC flow to define virtual clks.
- create_clock -name MY_CLK -period 2.0 CLK_PORT=>Here we define a real clk on one of the clk ports of the design
- To automatically infer clks/reset, we can use the cmd: infer_setup -type [clock|reset] -[full|incremental] (use -help to get the syntax)
- view_clock_tree -clock CLK1 => This is used to view clk tree for CLK1
- set_clock_groups -async => define explicit async relation b/w clks
- set_clock_group -asynchronous -group { VIRTUAL_CLOCK_0 } => Usually virtual clks are defined async to all other clks in design, including other virtual clks. The whole reason we created a virtual clk is so that we can assign that virtual clk to an i/p port, and treat that port signal as coming from an async clk source. CDC tool will then treat this port as being on an async boundary and do all CDC checks.
- set_clock_sense => to disable clk propagation from specified pins
- set_case_analysis / set_mode => defines constant values on pins/ports/nets. set_mode defines active mode of libcell inst (in case cells have multiple modes as scan, etc)
- set_input_delay / set_output_delay => This defines port's relationship to clock, i.e port is driven/captured by which clk. This is very imp cmd, which is needed to determine if a synchronizer is needed on input ports. Ports can also be constrained via attribute cmds discussed later. That is the preferred approach.
- ex: set_input_delay 1 -clock [get_clocks ck_2] [get_ports i_rst_2]
- To automatically configure unconstrained ports, we can use the cmd: configure_unconstrained_ports (use -help to get the syntax)
- create_clock / create_generated_clock => for creating clk and generated clks
- Extended SDC cmds => These are non std SDC cmds. They were added in CDC tool, since we need to define certain things, which are not supported by std SDC cmds
- create_reset => defines reset on pi/port/net object. This is being shown as SDC cmd in Synopsys manual (as of 2023), so it's an SDC cmd now.
- set_reset_sense => similar to set_clock_sense, it is to disable reset propagation from specified pins
- create_static => Defines static assumption on pin/port/net objects (this is when we have quasi-static values => values that don't actively change, but change only once in a while under user control. This means that we control when to change that value, and can afford to wait few cycles to propagate the correct value. This in turn implies that a synchronizer or other CDC checks are NOT needed, as correct value will eventually get propagated)
- attribute cmds: These are attr (or path elements) which are attached to the design objects. They may be attached to different object classes as clock, port, pin, net, cell, design or any other real objects in design. attr are also called as "virtual objects/nodes" as they don't exist in design, but actually map to real objects. We attach these to ports/pins, etc and then start adding properties to these virtual nodes, which in turn apply to real ports/nets etc to which these attr are attched to. These attr are same as what we saw in attribte cmds in "Non SDC attribute section" of "vlsi digital std". However they seem confusing in how they are defined and used over here. First, when we try to report attr of any object, they don't show up in any object attr list. Also, when we try to report all attr in design, they don't show up either. Secondly they don't have any value attached to them. They are simply "exist" or "don't exist" attr.
- define_attribute => creates a virtual path object. Once created, we can attach it to a real object, or may leave it unattached.
- syntax: define_attribute -name <attribute name> -objects <pins_or_ports> => <attr_name> is the logical name of the virtual path object (i.e virtual node). We can either create this "virtual path object" w/o associating it to any real object in design, or may associate it via -objects. Many more options allowed. If -objects option is used, then apply_attribute cmd (defined below) is not allowed, as this cmd already applies the attr to the object.
- apply_attribute => Once we defined an attr above, we can apply it to specific objects in design. This cmd specifies the pins to which the specified virtual nodes are applied. This is only needed when above "define_attribute" cmd is used w/o -objects option.
- syntax: apply_attribute <attribute name> -objects {list of pins} => <attr_name> is the name of attribute element defined by define_attribute. Many more options allowed.
- Misc set_*_attr => Many more attr cmds. All these cmds are of type set_*_attribute, where * refers to objects to which attr attach to, i.e clocks, reset, tag, etc. Or they may refer to extra property that is attached to that attr, i.e combo_att implies combo property is attached to that attr. -add option allows for adding this attr property on top of previous attr properties specified.
- set_clock_attribute => This cmd specifies the attribute name to which the clk constraints is to be attached. Basically it specifies the clk which drives the given virtual node (which is the attr name). So, it's same as "apply_attribute" cmd above, except that it says the clk constraints are being added to this attr.
- syntax: set_clock_attribute <attribute name> -clocks <clk_names> -clock_objects {pin_names} => <attr_name> is the path element or name of attribute to which clk constraints are to be attached. -clocks specifies clk_names, while -clock_objects specifies clk ports. These are mutually exclusive, and only one of these may be used. Many more options allowed.
- ex: define_attribute -name path1; set_clock_attribute path1 -clocks c1; apply_attribute path1 -objects {in1 in2}=> same attr path1 is applied to both clock (c1) and ports (in1 and in2).
- syntax: set_clock_attribute <attribute name> -clocks <clk_names> -clock_objects {pin_names} => <attr_name> is the path element or name of attribute to which clk constraints are to be attached. -clocks specifies clk_names, while -clock_objects specifies clk ports. These are mutually exclusive, and only one of these may be used. Many more options allowed.
- set_reset_attribute => This is same as set_clock_att cmd above, except that it specifies the resets (reset name/pin) which drive the given virtual node. -combo defines a combo logic before the virtual sequential.
- ex: define_attribute -name path1; set_reset_attribute path1 -reset_objects rst1 => Here rst1 pin drives the virtual node "path1". If path1 is attached to some ports, then those ports get driven by this reset pin too.
- set_sync_attribute => Just like clock_attribute cmd above, here sync property is set on the virtual node which is being driven by synchronizers. We specify the synchronizers that drive the given virtual node in this cmd itself.
- syntax: set_sync_attribute <attribute name> -from <clk_names/pin_names> -to <clk_names/pin_names> -sync <active/inactive> -sync_names <list> =>-from/-to specify the synchronizer src/dest clks/pins. -sync active specifies that this synchronizer can synchronize other crossings also, while -inactive means it's meant for only one crossing. -sync_names specifies synchronizer names reaching the virtual node.
- ex: set_sync_attribute async1 -sync active -to vclk1
- syntax: set_sync_attribute <attribute name> -from <clk_names/pin_names> -to <clk_names/pin_names> -sync <active/inactive> -sync_names <list> =>-from/-to specify the synchronizer src/dest clks/pins. -sync active specifies that this synchronizer can synchronize other crossings also, while -inactive means it's meant for only one crossing. -sync_names specifies synchronizer names reaching the virtual node.
- set_connectivity_attribute => Specifies the type of connections between the pins of the blackbox instance.
- set_tag_attribute => applies attr to violation tags. Name and value of attr to change is specified for the given tag.
- set_test_attribute => applies dft related info to given attr. The attr is first attached to given pins/ports and then this cmd is used to attach dft info to those pins/ports. -testbus specifies that defined ports/pins are of type testbus, while -analog specifies they are of type analog.
- set_ignore_attribute => This is used to ignore validation of the design objects on which this attribute is applied
- set_combo_attribute => This cmd is used to attach combinational property to an output port. This helps CDC to analyze and report mismatches.
- ex: apply_attribute path1 -objects in1 -direction input; set_combo_attribute path1 -value yes => applies combo prop to i/p port.
- set_clock_attribute => This cmd specifies the attribute name to which the clk constraints is to be attached. Basically it specifies the clk which drives the given virtual node (which is the attr name). So, it's same as "apply_attribute" cmd above, except that it says the clk constraints are being added to this attr.
- report_attribute =>This is the same cmd that is shown in "Non SDC attribute section" of "vlsi digital std". It reports attr on one or more objects.
- define_attribute => creates a virtual path object. Once created, we can attach it to a real object, or may leave it unattached.
Constraining ports via Attribute method:
Ports can also be constrained via scope-attribute method (by using attribute cmds shown above) instead of set_input_delay. ex below:
- set_constraints_scope -module BBOX2 => constraints below will only to this module BBOX2.
- Constrain i/p Port DAT_1 with real clk => First we define clk on CLK port. Next define a clock attr and associate it with this virtual clk. Finally apply this clk attr to the i/p Data port. This implies that DAT_1 is being driven by clk on port CK_1. Similarly more ports can be constrained.
- create_clock -name my_clock -period 2.0 -add CK_1 => create clk "my_clk" on clock port CK_1
- set_clock_group -asynchronous -group { my_clock ... } -group { ... } => define async relations as needed
- define_attribute -name myclk_attr => define attr
- set_clock_attribute myclk_attr -clocks {my_clock} => apply attr to clk created above. So, it becomes clk attr now
- #set_clock_attribute myclk_attr -clock_objects [get_ports CK_1]; => This is alternative way where we can specify clk attr directly on clk port CK_1. Not sure what's the difference? FIXME
- apply_attribute myclk_attr -objects [get_ports DAT_1]
- Constrain i/p Port DAT_1 with virtual clk =>We create virtual clk, when the port is being driven by a clk that is not an i/p clk to our block. First create virtual clk and define it async to all other clks. Next define a clock attr and associate it with this virtual clk. Finally apply this clk attr to the i/p Data port.
- create_clock -name VIRTUAL_CLOCK_0 -period 2.0 => creates virtual clk
- set_clock_group -asynchronous -group { VIRTUAL_CLOCK_0 } => define async to all other clks
- define_attribute -name VIRTUAL_CLOCK_0_ATTR => define attr
- set_clock_attribute VIRTUAL_CLOCK_0_ATTR -clocks { VIRTUAL_CLOCK_0 } => apply attr to virtual clk created above. So, it becomes clk attr now
- apply_attribute VIRTUAL_CLOCK_0_ATTR -objects { DAT_1 } -add => Now, apply above clk attr to data port. Implies data port is being fired by this clk.
- end_constraints_scope
Constraints: All i/p ports need to be constrained.
- Input clk ports: I/P ports which are clk port, need to have clocks defined,
- Input non-clk ports: All other non-clk input ports need to have one of the below constraints:
- Driving clk specified for i/p ports. 2 ways to do this (assuming create_clk, etc are already done):
- NEWER Style: apply_attribute AUTO_VIRTUAL_CLOCK_1 -objects { IN_PORT1 } -add
- OLDER Style: set_input_delay -clock CLK_1 20 {PORT_1 PORT_2} => set i/p delay of 20ns on i/p ports specified, where they are being clocked by CLK_1, i.e i/p signal arrives 20ns after the rising edge of CLK_1
- I/P port constrained using set_case
- set_case_analysis
- I/P port constrained using static or quasi static value. This is less constraining than set_case, as this says that the value changes once in a while (under user control), and can be either 0 or 1.
- Driving clk specified for i/p ports. 2 ways to do this (assuming create_clk, etc are already done):
- Output ports: Output ports don't need to be constrained as they will be connected to i/p port of some other partition. So, they will be constrained as input ports in the other connected partition. However, when running at partition level, we still constrain it.
- NEWER Style: Here, all of the process is the same as for constraining i/p ports. We define a virtual clk, make it async to all other clks, define and apply a clk attribute on it. Now,before we apply this clk attr to o/p port, we apply a sync attr => "-sync active" on this attr wrt the virtual clk defined. This makes we define apply_attribute asyncOutput -objects [get_ports -quiet OUT_PORT1 -filter {direction == out}] -add
- OLDER Style: set_output_delay -clock CLK_2 5 PORT1 => set o/p delay of 5ns on o/p ports specified, where they are being clocked by CLK_2 on receiving side, i.e o/p signal should arrive 5ns before the rising edge of CLK_2.
and clocks need